Skip to content
This repository has been archived by the owner on Jan 6, 2025. It is now read-only.

Commit

Permalink
add Secret (#654)
Browse files Browse the repository at this point in the history
Co-authored-by: Sebastian Lorenz <[email protected]>
  • Loading branch information
jessekelly881 and fubhy authored Dec 14, 2023
1 parent 3c6b714 commit a5950d1
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/unlucky-donuts-admire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect/schema": patch
---

added S.Secret
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2372,6 +2372,23 @@ parse(Duration.decode("6 seconds")); // 6 seconds
parse(Duration.decode("11 seconds")); // 10 seconds
```

### Secret transformations

#### Secret

Converts a `string` into a `Secret`.

```ts
import * as S from "@effect/schema/Schema";
import * as Secret from "effect/Secret";

// $ExpectType Schema<string, Secret>
const schema = S.Secret;

const parse = S.parseSync(schema);
parse("keep it secret, keep it safe"); // Secret
```

### Symbol transformations

#### symbol
Expand Down
43 changes: 43 additions & 0 deletions docs/modules/Schema.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ Added in v1.0.0
- [ReadonlySet transformations](#readonlyset-transformations)
- [readonlySet](#readonlyset)
- [readonlySetFromSelf](#readonlysetfromself)
- [Secret constructors](#secret-constructors)
- [Secret](#secret)
- [SecretFromSelf](#secretfromself)
- [Secret transformations](#secret-transformations)
- [secret](#secret-1)
- [Uint8Array constructors](#uint8array-constructors)
- [Uint8Array](#uint8array)
- [Uint8ArrayFromSelf](#uint8arrayfromself)
Expand Down Expand Up @@ -1230,6 +1235,44 @@ export declare const readonlySetFromSelf: <I, A>(item: Schema<I, A>) => Schema<R
Added in v1.0.0
# Secret constructors
## Secret
A schema that transforms a `string` into a `Secret`.
**Signature**
```ts
export declare const Secret: Schema<string, Secret.Secret>
```
Added in v1.0.0
## SecretFromSelf
**Signature**
```ts
export declare const SecretFromSelf: Schema<Secret.Secret, Secret.Secret>
```
Added in v1.0.0
# Secret transformations
## secret
A combinator that transforms a `string` into a `Secret`.
**Signature**
```ts
export declare const secret: <I, A extends string>(self: Schema<I, A>) => Schema<I, Secret.Secret>
```
Added in v1.0.0
# Uint8Array constructors
## Uint8Array
Expand Down
13 changes: 13 additions & 0 deletions dtslint/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -792,3 +792,16 @@ S.durationFromNanos(S.bigintFromSelf)

// $ExpectType Schema<bigint, Duration>
S.DurationFromNanos

// ---------------------------------------------
// Secret
// ---------------------------------------------

// $ExpectType Schema<string, Secret>
S.Secret

// $ExpectType Schema<Secret, Secret>
S.SecretFromSelf

// $ExpectType Schema<string, Secret>
S.secret(S.string)
53 changes: 53 additions & 0 deletions src/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { pipeArguments } from "effect/Pipeable"
import * as Predicate from "effect/Predicate"
import * as ReadonlyArray from "effect/ReadonlyArray"
import * as Request from "effect/Request"
import * as Secret from "effect/Secret"
import * as S from "effect/String"
import type { Equals, Simplify } from "effect/Types"
import type { Arbitrary } from "./Arbitrary.js"
Expand Down Expand Up @@ -2993,6 +2994,58 @@ export const NonNegativeBigint: Schema<string, bigint> = bigint.pipe(
*/
export const BigintFromNumber: Schema<number, bigint> = bigintFromNumber(number)

// ---------------------------------------------
// Secret
// ---------------------------------------------

/**
* @category Secret constructors
* @since 1.0.0
*/
export const SecretFromSelf: Schema<Secret.Secret> = declare(
[],
struct({}),
() => (u, _, ast) =>
Secret.isSecret(u) ?
ParseResult.succeed(u)
: ParseResult.fail(ParseResult.type(ast, u)),
{
[AST.IdentifierAnnotationId]: "Secret",
[hooks.PrettyHookId]: (): Pretty.Pretty<Secret.Secret> => (secret) => String(secret),
[hooks.ArbitraryHookId]: (): Arbitrary<Secret.Secret> => (fc) =>
fc.string().map((_) => Secret.fromString(_))
}
)

/**
* A combinator that transforms a `string` into a `Secret`.
*
* @category Secret transformations
* @since 1.0.0
*/
export const secret = <I, A extends string>(
self: Schema<I, A>
): Schema<I, Secret.Secret> =>
transform(
self,
SecretFromSelf,
(str) => Secret.fromString(str),
(secret) => Secret.value(secret),
{ strict: false }
)

const _Secret: Schema<string, Secret.Secret> = secret(string)

export {
/**
* A schema that transforms a `string` into a `Secret`.
*
* @category Secret constructors
* @since 1.0.0
*/
_Secret as Secret
}

// ---------------------------------------------
// Duration constructors
// ---------------------------------------------
Expand Down
24 changes: 24 additions & 0 deletions test/Secret/Secret.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as S from "@effect/schema/Schema"
import * as Util from "@effect/schema/test/util"
import { Secret } from "effect"
import { describe, it } from "vitest"

describe("Schema/Secret", () => {
const schema = S.Secret

it("property tests", () => {
Util.roundtrip(schema)
})

it("decoding", () => {
Util.expectParseSuccess(schema, "keep me safe", Secret.fromString("keep me safe"))
})

it("encoding", () => {
Util.expectEncodeSuccess(
schema,
Secret.fromString("keep me safe"),
"keep me safe"
)
})
})
34 changes: 34 additions & 0 deletions test/Secret/SecretFromSelf.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as Pretty from "@effect/schema/Pretty"
import * as S from "@effect/schema/Schema"
import * as Util from "@effect/schema/test/util"
import { Secret } from "effect"
import { describe, expect, it } from "vitest"

describe("Schema/SecretFromSelf", () => {
const schema = S.SecretFromSelf

it("property tests", () => {
Util.roundtrip(schema)
})

it("decoding", () => {
Util.expectParseSuccess(
schema,
Secret.fromString("keep me safe"),
Secret.fromString("keep me safe")
)
})

it("encoding", () => {
Util.expectEncodeSuccess(
schema,
Secret.fromString("keep me safe"),
Secret.fromString("keep me safe")
)
})

it("Pretty", () => {
const pretty = Pretty.to(schema)
expect(pretty(Secret.fromString("keep me safe"))).toEqual(`Secret(<redacted>)`)
})
})

0 comments on commit a5950d1

Please sign in to comment.