@atproto/lex-schema 0.0.10 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/dist/core/$type.d.ts +149 -0
- package/dist/core/$type.d.ts.map +1 -1
- package/dist/core/$type.js +44 -0
- package/dist/core/$type.js.map +1 -1
- package/dist/core/record-key.d.ts +44 -0
- package/dist/core/record-key.d.ts.map +1 -1
- package/dist/core/record-key.js +30 -0
- package/dist/core/record-key.js.map +1 -1
- package/dist/core/result.d.ts +85 -4
- package/dist/core/result.d.ts.map +1 -1
- package/dist/core/result.js +60 -4
- package/dist/core/result.js.map +1 -1
- package/dist/core/schema.d.ts +229 -2
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +197 -4
- package/dist/core/schema.js.map +1 -1
- package/dist/core/string-format.d.ts +244 -11
- package/dist/core/string-format.d.ts.map +1 -1
- package/dist/core/string-format.js +150 -0
- package/dist/core/string-format.js.map +1 -1
- package/dist/core/types.d.ts +90 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/validation-error.d.ts +61 -1
- package/dist/core/validation-error.d.ts.map +1 -1
- package/dist/core/validation-error.js +60 -0
- package/dist/core/validation-error.js.map +1 -1
- package/dist/core/validation-issue.d.ts +61 -0
- package/dist/core/validation-issue.d.ts.map +1 -1
- package/dist/core/validation-issue.js +51 -0
- package/dist/core/validation-issue.js.map +1 -1
- package/dist/core/validator.d.ts +347 -10
- package/dist/core/validator.d.ts.map +1 -1
- package/dist/core/validator.js +184 -3
- package/dist/core/validator.js.map +1 -1
- package/dist/helpers.d.ts +13 -25
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +2 -2
- package/dist/helpers.js.map +1 -1
- package/dist/schema/array.d.ts +45 -0
- package/dist/schema/array.d.ts.map +1 -1
- package/dist/schema/array.js +14 -0
- package/dist/schema/array.js.map +1 -1
- package/dist/schema/blob.d.ts +46 -0
- package/dist/schema/blob.d.ts.map +1 -1
- package/dist/schema/blob.js +39 -0
- package/dist/schema/blob.js.map +1 -1
- package/dist/schema/boolean.d.ts +28 -0
- package/dist/schema/boolean.d.ts.map +1 -1
- package/dist/schema/boolean.js +28 -0
- package/dist/schema/boolean.js.map +1 -1
- package/dist/schema/bytes.d.ts +38 -0
- package/dist/schema/bytes.d.ts.map +1 -1
- package/dist/schema/bytes.js +32 -0
- package/dist/schema/bytes.js.map +1 -1
- package/dist/schema/cid.d.ts +38 -0
- package/dist/schema/cid.d.ts.map +1 -1
- package/dist/schema/cid.js +33 -0
- package/dist/schema/cid.js.map +1 -1
- package/dist/schema/custom.d.ts +66 -1
- package/dist/schema/custom.d.ts.map +1 -1
- package/dist/schema/custom.js +54 -0
- package/dist/schema/custom.js.map +1 -1
- package/dist/schema/dict.d.ts +44 -0
- package/dist/schema/dict.d.ts.map +1 -1
- package/dist/schema/dict.js +44 -0
- package/dist/schema/dict.js.map +1 -1
- package/dist/schema/discriminated-union.d.ts +58 -0
- package/dist/schema/discriminated-union.d.ts.map +1 -1
- package/dist/schema/discriminated-union.js +45 -0
- package/dist/schema/discriminated-union.js.map +1 -1
- package/dist/schema/enum.d.ts +48 -0
- package/dist/schema/enum.d.ts.map +1 -1
- package/dist/schema/enum.js +48 -0
- package/dist/schema/enum.js.map +1 -1
- package/dist/schema/integer.d.ts +42 -0
- package/dist/schema/integer.d.ts.map +1 -1
- package/dist/schema/integer.js +36 -0
- package/dist/schema/integer.js.map +1 -1
- package/dist/schema/intersection.d.ts +54 -0
- package/dist/schema/intersection.d.ts.map +1 -1
- package/dist/schema/intersection.js +49 -0
- package/dist/schema/intersection.js.map +1 -1
- package/dist/schema/literal.d.ts +44 -0
- package/dist/schema/literal.d.ts.map +1 -1
- package/dist/schema/literal.js +44 -0
- package/dist/schema/literal.js.map +1 -1
- package/dist/schema/never.d.ts +42 -0
- package/dist/schema/never.d.ts.map +1 -1
- package/dist/schema/never.js +42 -0
- package/dist/schema/never.js.map +1 -1
- package/dist/schema/null.d.ts +29 -0
- package/dist/schema/null.d.ts.map +1 -1
- package/dist/schema/null.js +29 -0
- package/dist/schema/null.js.map +1 -1
- package/dist/schema/nullable.d.ts +41 -0
- package/dist/schema/nullable.d.ts.map +1 -1
- package/dist/schema/nullable.js +41 -0
- package/dist/schema/nullable.js.map +1 -1
- package/dist/schema/object.d.ts +56 -0
- package/dist/schema/object.d.ts.map +1 -1
- package/dist/schema/object.js +51 -0
- package/dist/schema/object.js.map +1 -1
- package/dist/schema/optional.d.ts +42 -0
- package/dist/schema/optional.d.ts.map +1 -1
- package/dist/schema/optional.js +42 -0
- package/dist/schema/optional.js.map +1 -1
- package/dist/schema/params.d.ts +89 -7
- package/dist/schema/params.d.ts.map +1 -1
- package/dist/schema/params.js +84 -10
- package/dist/schema/params.js.map +1 -1
- package/dist/schema/payload.d.ts +111 -15
- package/dist/schema/payload.d.ts.map +1 -1
- package/dist/schema/payload.js +70 -0
- package/dist/schema/payload.js.map +1 -1
- package/dist/schema/permission-set.d.ts +58 -0
- package/dist/schema/permission-set.d.ts.map +1 -1
- package/dist/schema/permission-set.js +50 -0
- package/dist/schema/permission-set.js.map +1 -1
- package/dist/schema/permission.d.ts +42 -0
- package/dist/schema/permission.d.ts.map +1 -1
- package/dist/schema/permission.js +39 -0
- package/dist/schema/permission.js.map +1 -1
- package/dist/schema/procedure.d.ts +64 -0
- package/dist/schema/procedure.d.ts.map +1 -1
- package/dist/schema/procedure.js +64 -0
- package/dist/schema/procedure.js.map +1 -1
- package/dist/schema/query.d.ts +55 -0
- package/dist/schema/query.d.ts.map +1 -1
- package/dist/schema/query.js +55 -0
- package/dist/schema/query.js.map +1 -1
- package/dist/schema/record.d.ts +63 -8
- package/dist/schema/record.d.ts.map +1 -1
- package/dist/schema/record.js +20 -0
- package/dist/schema/record.js.map +1 -1
- package/dist/schema/ref.d.ts +50 -0
- package/dist/schema/ref.d.ts.map +1 -1
- package/dist/schema/ref.js +17 -0
- package/dist/schema/ref.js.map +1 -1
- package/dist/schema/refine.d.ts +58 -9
- package/dist/schema/refine.d.ts.map +1 -1
- package/dist/schema/refine.js.map +1 -1
- package/dist/schema/regexp.d.ts +44 -0
- package/dist/schema/regexp.d.ts.map +1 -1
- package/dist/schema/regexp.js +44 -0
- package/dist/schema/regexp.js.map +1 -1
- package/dist/schema/string.d.ts +50 -0
- package/dist/schema/string.d.ts.map +1 -1
- package/dist/schema/string.js +41 -0
- package/dist/schema/string.js.map +1 -1
- package/dist/schema/subscription.d.ts +72 -2
- package/dist/schema/subscription.d.ts.map +1 -1
- package/dist/schema/subscription.js +59 -0
- package/dist/schema/subscription.js.map +1 -1
- package/dist/schema/token.d.ts +47 -0
- package/dist/schema/token.d.ts.map +1 -1
- package/dist/schema/token.js +47 -0
- package/dist/schema/token.js.map +1 -1
- package/dist/schema/typed-object.d.ts +62 -8
- package/dist/schema/typed-object.d.ts.map +1 -1
- package/dist/schema/typed-object.js +18 -0
- package/dist/schema/typed-object.js.map +1 -1
- package/dist/schema/typed-ref.d.ts +53 -0
- package/dist/schema/typed-ref.d.ts.map +1 -1
- package/dist/schema/typed-ref.js +15 -0
- package/dist/schema/typed-ref.js.map +1 -1
- package/dist/schema/typed-union.d.ts +50 -1
- package/dist/schema/typed-union.d.ts.map +1 -1
- package/dist/schema/typed-union.js +50 -1
- package/dist/schema/typed-union.js.map +1 -1
- package/dist/schema/union.d.ts +45 -0
- package/dist/schema/union.d.ts.map +1 -1
- package/dist/schema/union.js +40 -0
- package/dist/schema/union.js.map +1 -1
- package/dist/schema/unknown-object.d.ts +34 -0
- package/dist/schema/unknown-object.d.ts.map +1 -1
- package/dist/schema/unknown-object.js +31 -0
- package/dist/schema/unknown-object.js.map +1 -1
- package/dist/schema/unknown.d.ts +33 -0
- package/dist/schema/unknown.d.ts.map +1 -1
- package/dist/schema/unknown.js +33 -0
- package/dist/schema/unknown.js.map +1 -1
- package/dist/schema/with-default.d.ts +44 -0
- package/dist/schema/with-default.d.ts.map +1 -1
- package/dist/schema/with-default.js +44 -0
- package/dist/schema/with-default.js.map +1 -1
- package/package.json +4 -4
- package/src/core/$type.ts +150 -18
- package/src/core/record-key.ts +44 -0
- package/src/core/result.ts +86 -4
- package/src/core/schema.ts +236 -7
- package/src/core/string-format.ts +259 -13
- package/src/core/types.ts +91 -3
- package/src/core/validation-error.ts +60 -0
- package/src/core/validation-issue.ts +65 -0
- package/src/core/validator.ts +351 -10
- package/src/helpers.test.ts +110 -29
- package/src/helpers.ts +14 -14
- package/src/schema/array.test.ts +94 -79
- package/src/schema/array.ts +45 -0
- package/src/schema/blob.ts +46 -0
- package/src/schema/boolean.ts +28 -0
- package/src/schema/bytes.ts +38 -0
- package/src/schema/cid.ts +38 -0
- package/src/schema/custom.ts +66 -1
- package/src/schema/dict.ts +44 -0
- package/src/schema/discriminated-union.ts +58 -0
- package/src/schema/enum.ts +48 -0
- package/src/schema/integer.ts +42 -0
- package/src/schema/intersection.ts +54 -0
- package/src/schema/literal.ts +44 -0
- package/src/schema/never.ts +42 -0
- package/src/schema/null.ts +29 -0
- package/src/schema/nullable.ts +41 -0
- package/src/schema/object.ts +56 -0
- package/src/schema/optional.ts +42 -0
- package/src/schema/params.test.ts +58 -2
- package/src/schema/params.ts +124 -16
- package/src/schema/payload.test.ts +3 -3
- package/src/schema/payload.ts +142 -38
- package/src/schema/permission-set.ts +58 -0
- package/src/schema/permission.ts +42 -0
- package/src/schema/procedure.ts +64 -0
- package/src/schema/query.ts +55 -0
- package/src/schema/record.ts +63 -8
- package/src/schema/ref.ts +50 -0
- package/src/schema/refine.ts +58 -9
- package/src/schema/regexp.ts +44 -0
- package/src/schema/string.ts +50 -0
- package/src/schema/subscription.ts +72 -2
- package/src/schema/token.ts +47 -0
- package/src/schema/typed-object.ts +62 -8
- package/src/schema/typed-ref.ts +53 -0
- package/src/schema/typed-union.ts +55 -2
- package/src/schema/union.ts +45 -0
- package/src/schema/unknown-object.ts +34 -0
- package/src/schema/unknown.ts +33 -0
- package/src/schema/with-default.ts +44 -0
|
@@ -1,8 +1,42 @@
|
|
|
1
1
|
import { LexMap } from '@atproto/lex-data';
|
|
2
2
|
import { Schema, ValidationContext } from '../core.js';
|
|
3
|
+
/**
|
|
4
|
+
* Type alias for a plain object with unknown values.
|
|
5
|
+
*/
|
|
3
6
|
export type UnknownObject = LexMap;
|
|
7
|
+
/**
|
|
8
|
+
* Schema that accepts any plain object without validating its properties.
|
|
9
|
+
*
|
|
10
|
+
* Validates that the input is a plain object (not an array, Date, or other
|
|
11
|
+
* special object type), but does not validate the object's properties.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const schema = new UnknownObjectSchema()
|
|
16
|
+
* schema.validate({ any: 'props' }) // success
|
|
17
|
+
* schema.validate([1, 2, 3]) // fails - arrays not accepted
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
4
20
|
export declare class UnknownObjectSchema extends Schema<UnknownObject> {
|
|
5
21
|
validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationResult<LexMap>;
|
|
6
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates a schema that accepts any plain object.
|
|
25
|
+
*
|
|
26
|
+
* Unlike `l.unknown()` which accepts any value, this validates that the input
|
|
27
|
+
* is specifically a plain object (not an array, null, or primitive).
|
|
28
|
+
*
|
|
29
|
+
* @returns A new {@link UnknownObjectSchema} instance
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* // Accept any object shape
|
|
34
|
+
* const metadataSchema = l.unknownObject()
|
|
35
|
+
*
|
|
36
|
+
* metadataSchema.parse({ foo: 1, bar: 'baz' }) // success
|
|
37
|
+
* metadataSchema.parse([1, 2, 3]) // throws - not a plain object
|
|
38
|
+
* metadataSchema.parse(null) // throws
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
7
41
|
export declare const unknownObject: () => UnknownObjectSchema;
|
|
8
42
|
//# sourceMappingURL=unknown-object.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unknown-object.d.ts","sourceRoot":"","sources":["../../src/schema/unknown-object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAY,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGtD,MAAM,MAAM,aAAa,GAAG,MAAM,CAAA;AAElC,qBAAa,mBAAoB,SAAQ,MAAM,CAAC,aAAa,CAAC;IAC5D,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAOzD;AAED,eAAO,MAAM,aAAa,2BAExB,CAAA"}
|
|
1
|
+
{"version":3,"file":"unknown-object.d.ts","sourceRoot":"","sources":["../../src/schema/unknown-object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAY,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGtD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAA;AAElC;;;;;;;;;;;;GAYG;AACH,qBAAa,mBAAoB,SAAQ,MAAM,CAAC,aAAa,CAAC;IAC5D,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAOzD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,aAAa,2BAExB,CAAA"}
|
|
@@ -4,6 +4,19 @@ exports.unknownObject = exports.UnknownObjectSchema = void 0;
|
|
|
4
4
|
const lex_data_1 = require("@atproto/lex-data");
|
|
5
5
|
const core_js_1 = require("../core.js");
|
|
6
6
|
const memoize_js_1 = require("../util/memoize.js");
|
|
7
|
+
/**
|
|
8
|
+
* Schema that accepts any plain object without validating its properties.
|
|
9
|
+
*
|
|
10
|
+
* Validates that the input is a plain object (not an array, Date, or other
|
|
11
|
+
* special object type), but does not validate the object's properties.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const schema = new UnknownObjectSchema()
|
|
16
|
+
* schema.validate({ any: 'props' }) // success
|
|
17
|
+
* schema.validate([1, 2, 3]) // fails - arrays not accepted
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
7
20
|
class UnknownObjectSchema extends core_js_1.Schema {
|
|
8
21
|
validateInContext(input, ctx) {
|
|
9
22
|
if ((0, lex_data_1.isLexMap)(input)) {
|
|
@@ -13,6 +26,24 @@ class UnknownObjectSchema extends core_js_1.Schema {
|
|
|
13
26
|
}
|
|
14
27
|
}
|
|
15
28
|
exports.UnknownObjectSchema = UnknownObjectSchema;
|
|
29
|
+
/**
|
|
30
|
+
* Creates a schema that accepts any plain object.
|
|
31
|
+
*
|
|
32
|
+
* Unlike `l.unknown()` which accepts any value, this validates that the input
|
|
33
|
+
* is specifically a plain object (not an array, null, or primitive).
|
|
34
|
+
*
|
|
35
|
+
* @returns A new {@link UnknownObjectSchema} instance
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* // Accept any object shape
|
|
40
|
+
* const metadataSchema = l.unknownObject()
|
|
41
|
+
*
|
|
42
|
+
* metadataSchema.parse({ foo: 1, bar: 'baz' }) // success
|
|
43
|
+
* metadataSchema.parse([1, 2, 3]) // throws - not a plain object
|
|
44
|
+
* metadataSchema.parse(null) // throws
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
16
47
|
exports.unknownObject = (0, memoize_js_1.memoizedOptions)(function () {
|
|
17
48
|
return new UnknownObjectSchema();
|
|
18
49
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unknown-object.js","sourceRoot":"","sources":["../../src/schema/unknown-object.ts"],"names":[],"mappings":";;;AAAA,gDAAoD;AACpD,wCAAsD;AACtD,mDAAoD;
|
|
1
|
+
{"version":3,"file":"unknown-object.js","sourceRoot":"","sources":["../../src/schema/unknown-object.ts"],"names":[],"mappings":";;;AAAA,gDAAoD;AACpD,wCAAsD;AACtD,mDAAoD;AAOpD;;;;;;;;;;;;GAYG;AACH,MAAa,mBAAoB,SAAQ,gBAAqB;IAC5D,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,IAAI,IAAA,mBAAQ,EAAC,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC3B,CAAC;QAED,OAAO,GAAG,CAAC,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;IAC/C,CAAC;CACF;AARD,kDAQC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACU,QAAA,aAAa,GAAiB,IAAA,4BAAe,EAAC;IACzD,OAAO,IAAI,mBAAmB,EAAE,CAAA;AAClC,CAAC,CAAC,CAAA","sourcesContent":["import { LexMap, isLexMap } from '@atproto/lex-data'\nimport { Schema, ValidationContext } from '../core.js'\nimport { memoizedOptions } from '../util/memoize.js'\n\n/**\n * Type alias for a plain object with unknown values.\n */\nexport type UnknownObject = LexMap\n\n/**\n * Schema that accepts any plain object without validating its properties.\n *\n * Validates that the input is a plain object (not an array, Date, or other\n * special object type), but does not validate the object's properties.\n *\n * @example\n * ```ts\n * const schema = new UnknownObjectSchema()\n * schema.validate({ any: 'props' }) // success\n * schema.validate([1, 2, 3]) // fails - arrays not accepted\n * ```\n */\nexport class UnknownObjectSchema extends Schema<UnknownObject> {\n validateInContext(input: unknown, ctx: ValidationContext) {\n if (isLexMap(input)) {\n return ctx.success(input)\n }\n\n return ctx.issueInvalidType(input, 'unknown')\n }\n}\n\n/**\n * Creates a schema that accepts any plain object.\n *\n * Unlike `l.unknown()` which accepts any value, this validates that the input\n * is specifically a plain object (not an array, null, or primitive).\n *\n * @returns A new {@link UnknownObjectSchema} instance\n *\n * @example\n * ```ts\n * // Accept any object shape\n * const metadataSchema = l.unknownObject()\n *\n * metadataSchema.parse({ foo: 1, bar: 'baz' }) // success\n * metadataSchema.parse([1, 2, 3]) // throws - not a plain object\n * metadataSchema.parse(null) // throws\n * ```\n */\nexport const unknownObject = /*#__PURE__*/ memoizedOptions(function () {\n return new UnknownObjectSchema()\n})\n"]}
|
package/dist/schema/unknown.d.ts
CHANGED
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
import { Schema, ValidationContext } from '../core.js';
|
|
2
|
+
/**
|
|
3
|
+
* Schema that accepts any value without validation.
|
|
4
|
+
*
|
|
5
|
+
* Passes through any input unchanged. Use sparingly as it bypasses
|
|
6
|
+
* type safety. Useful for dynamic data or when the schema is not
|
|
7
|
+
* known at compile time.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const schema = new UnknownSchema()
|
|
12
|
+
* schema.validate(anything) // always succeeds
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
2
15
|
export declare class UnknownSchema extends Schema<unknown> {
|
|
3
16
|
validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationResult<unknown>;
|
|
4
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Creates an unknown schema that accepts any value.
|
|
20
|
+
*
|
|
21
|
+
* The value passes through without any validation or transformation.
|
|
22
|
+
* Use this when you need to accept arbitrary data.
|
|
23
|
+
*
|
|
24
|
+
* @returns A new {@link UnknownSchema} instance
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* // Accept any value
|
|
29
|
+
* const anyDataSchema = l.unknown()
|
|
30
|
+
*
|
|
31
|
+
* // In an object with a dynamic field
|
|
32
|
+
* const flexibleSchema = l.object({
|
|
33
|
+
* type: l.string(),
|
|
34
|
+
* data: l.unknown(),
|
|
35
|
+
* })
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
5
38
|
export declare const unknown: () => UnknownSchema;
|
|
6
39
|
//# sourceMappingURL=unknown.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unknown.d.ts","sourceRoot":"","sources":["../../src/schema/unknown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGtD,qBAAa,aAAc,SAAQ,MAAM,CAAC,OAAO,CAAC;IAChD,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAGzD;AAED,eAAO,MAAM,OAAO,qBAElB,CAAA"}
|
|
1
|
+
{"version":3,"file":"unknown.d.ts","sourceRoot":"","sources":["../../src/schema/unknown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGtD;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAc,SAAQ,MAAM,CAAC,OAAO,CAAC;IAChD,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAGzD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,OAAO,qBAElB,CAAA"}
|
package/dist/schema/unknown.js
CHANGED
|
@@ -3,12 +3,45 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.unknown = exports.UnknownSchema = void 0;
|
|
4
4
|
const core_js_1 = require("../core.js");
|
|
5
5
|
const memoize_js_1 = require("../util/memoize.js");
|
|
6
|
+
/**
|
|
7
|
+
* Schema that accepts any value without validation.
|
|
8
|
+
*
|
|
9
|
+
* Passes through any input unchanged. Use sparingly as it bypasses
|
|
10
|
+
* type safety. Useful for dynamic data or when the schema is not
|
|
11
|
+
* known at compile time.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const schema = new UnknownSchema()
|
|
16
|
+
* schema.validate(anything) // always succeeds
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
6
19
|
class UnknownSchema extends core_js_1.Schema {
|
|
7
20
|
validateInContext(input, ctx) {
|
|
8
21
|
return ctx.success(input);
|
|
9
22
|
}
|
|
10
23
|
}
|
|
11
24
|
exports.UnknownSchema = UnknownSchema;
|
|
25
|
+
/**
|
|
26
|
+
* Creates an unknown schema that accepts any value.
|
|
27
|
+
*
|
|
28
|
+
* The value passes through without any validation or transformation.
|
|
29
|
+
* Use this when you need to accept arbitrary data.
|
|
30
|
+
*
|
|
31
|
+
* @returns A new {@link UnknownSchema} instance
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* // Accept any value
|
|
36
|
+
* const anyDataSchema = l.unknown()
|
|
37
|
+
*
|
|
38
|
+
* // In an object with a dynamic field
|
|
39
|
+
* const flexibleSchema = l.object({
|
|
40
|
+
* type: l.string(),
|
|
41
|
+
* data: l.unknown(),
|
|
42
|
+
* })
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
12
45
|
exports.unknown = (0, memoize_js_1.memoizedOptions)(function () {
|
|
13
46
|
return new UnknownSchema();
|
|
14
47
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unknown.js","sourceRoot":"","sources":["../../src/schema/unknown.ts"],"names":[],"mappings":";;;AAAA,wCAAsD;AACtD,mDAAoD;AAEpD,MAAa,aAAc,SAAQ,gBAAe;IAChD,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;CACF;AAJD,sCAIC;
|
|
1
|
+
{"version":3,"file":"unknown.js","sourceRoot":"","sources":["../../src/schema/unknown.ts"],"names":[],"mappings":";;;AAAA,wCAAsD;AACtD,mDAAoD;AAEpD;;;;;;;;;;;;GAYG;AACH,MAAa,aAAc,SAAQ,gBAAe;IAChD,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;CACF;AAJD,sCAIC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACU,QAAA,OAAO,GAAiB,IAAA,4BAAe,EAAC;IACnD,OAAO,IAAI,aAAa,EAAE,CAAA;AAC5B,CAAC,CAAC,CAAA","sourcesContent":["import { Schema, ValidationContext } from '../core.js'\nimport { memoizedOptions } from '../util/memoize.js'\n\n/**\n * Schema that accepts any value without validation.\n *\n * Passes through any input unchanged. Use sparingly as it bypasses\n * type safety. Useful for dynamic data or when the schema is not\n * known at compile time.\n *\n * @example\n * ```ts\n * const schema = new UnknownSchema()\n * schema.validate(anything) // always succeeds\n * ```\n */\nexport class UnknownSchema extends Schema<unknown> {\n validateInContext(input: unknown, ctx: ValidationContext) {\n return ctx.success(input)\n }\n}\n\n/**\n * Creates an unknown schema that accepts any value.\n *\n * The value passes through without any validation or transformation.\n * Use this when you need to accept arbitrary data.\n *\n * @returns A new {@link UnknownSchema} instance\n *\n * @example\n * ```ts\n * // Accept any value\n * const anyDataSchema = l.unknown()\n *\n * // In an object with a dynamic field\n * const flexibleSchema = l.object({\n * type: l.string(),\n * data: l.unknown(),\n * })\n * ```\n */\nexport const unknown = /*#__PURE__*/ memoizedOptions(function () {\n return new UnknownSchema()\n})\n"]}
|
|
@@ -1,9 +1,53 @@
|
|
|
1
1
|
import { InferInput, InferOutput, Schema, ValidationContext, Validator } from '../core.js';
|
|
2
|
+
/**
|
|
3
|
+
* Schema wrapper that provides a default value when the input is undefined.
|
|
4
|
+
*
|
|
5
|
+
* In parse mode, when the input is `undefined`, the default value is used
|
|
6
|
+
* instead. In validate mode, undefined values pass through unchanged (the
|
|
7
|
+
* default is not applied).
|
|
8
|
+
*
|
|
9
|
+
* @template TValidator - The wrapped validator type
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* const schema = new WithDefaultSchema(l.integer(), 0)
|
|
14
|
+
* schema.parse(undefined) // 0
|
|
15
|
+
* schema.parse(42) // 42
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
2
18
|
export declare class WithDefaultSchema<const TValidator extends Validator> extends Schema<InferInput<TValidator>, InferOutput<TValidator>> {
|
|
3
19
|
readonly validator: TValidator;
|
|
4
20
|
readonly defaultValue: InferInput<TValidator>;
|
|
5
21
|
constructor(validator: TValidator, defaultValue: InferInput<TValidator>);
|
|
6
22
|
validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationResult<InferInput<TValidator>>;
|
|
7
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Creates a schema that applies a default value when the input is undefined.
|
|
26
|
+
*
|
|
27
|
+
* Commonly used with `optional()` to provide fallback values for missing
|
|
28
|
+
* properties. The default value is validated against the schema.
|
|
29
|
+
*
|
|
30
|
+
* @param validator - The validator for the value
|
|
31
|
+
* @param defaultValue - The default value to use when input is undefined
|
|
32
|
+
* @returns A new {@link WithDefaultSchema} instance
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* // Integer with default
|
|
37
|
+
* const countSchema = l.withDefault(l.integer(), 0)
|
|
38
|
+
* countSchema.parse(undefined) // 0
|
|
39
|
+
* countSchema.parse(5) // 5
|
|
40
|
+
*
|
|
41
|
+
* // Commonly combined with optional in objects
|
|
42
|
+
* const settingsSchema = l.object({
|
|
43
|
+
* theme: l.optional(l.withDefault(l.string(), 'light')),
|
|
44
|
+
* pageSize: l.optional(l.withDefault(l.integer(), 25)),
|
|
45
|
+
* })
|
|
46
|
+
* settingsSchema.parse({}) // { theme: 'light', pageSize: 25 }
|
|
47
|
+
*
|
|
48
|
+
* // Boolean with default
|
|
49
|
+
* const enabledSchema = l.withDefault(l.boolean(), false)
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
8
52
|
export declare function withDefault<const TValidator extends Validator>(validator: TValidator, defaultValue: InferInput<TValidator>): WithDefaultSchema<TValidator>;
|
|
9
53
|
//# sourceMappingURL=with-default.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-default.d.ts","sourceRoot":"","sources":["../../src/schema/with-default.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,EACX,MAAM,EACN,iBAAiB,EACjB,SAAS,EACV,MAAM,YAAY,CAAA;AAEnB,qBAAa,iBAAiB,CAC5B,KAAK,CAAC,UAAU,SAAS,SAAS,CAClC,SAAQ,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IAE7D,QAAQ,CAAC,SAAS,EAAE,UAAU;IAC9B,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,UAAU,CAAC;gBADpC,SAAS,EAAE,UAAU,EACrB,YAAY,EAAE,UAAU,CAAC,UAAU,CAAC;IAK/C,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CASzD;AAED,wBAAgB,WAAW,CAAC,KAAK,CAAC,UAAU,SAAS,SAAS,EAC5D,SAAS,EAAE,UAAU,EACrB,YAAY,EAAE,UAAU,CAAC,UAAU,CAAC,iCAGrC"}
|
|
1
|
+
{"version":3,"file":"with-default.d.ts","sourceRoot":"","sources":["../../src/schema/with-default.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,EACX,MAAM,EACN,iBAAiB,EACjB,SAAS,EACV,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,iBAAiB,CAC5B,KAAK,CAAC,UAAU,SAAS,SAAS,CAClC,SAAQ,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IAE7D,QAAQ,CAAC,SAAS,EAAE,UAAU;IAC9B,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,UAAU,CAAC;gBADpC,SAAS,EAAE,UAAU,EACrB,YAAY,EAAE,UAAU,CAAC,UAAU,CAAC;IAK/C,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CASzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,WAAW,CAAC,KAAK,CAAC,UAAU,SAAS,SAAS,EAC5D,SAAS,EAAE,UAAU,EACrB,YAAY,EAAE,UAAU,CAAC,UAAU,CAAC,iCAGrC"}
|
|
@@ -3,6 +3,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.WithDefaultSchema = void 0;
|
|
4
4
|
exports.withDefault = withDefault;
|
|
5
5
|
const core_js_1 = require("../core.js");
|
|
6
|
+
/**
|
|
7
|
+
* Schema wrapper that provides a default value when the input is undefined.
|
|
8
|
+
*
|
|
9
|
+
* In parse mode, when the input is `undefined`, the default value is used
|
|
10
|
+
* instead. In validate mode, undefined values pass through unchanged (the
|
|
11
|
+
* default is not applied).
|
|
12
|
+
*
|
|
13
|
+
* @template TValidator - The wrapped validator type
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const schema = new WithDefaultSchema(l.integer(), 0)
|
|
18
|
+
* schema.parse(undefined) // 0
|
|
19
|
+
* schema.parse(42) // 42
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
6
22
|
class WithDefaultSchema extends core_js_1.Schema {
|
|
7
23
|
validator;
|
|
8
24
|
defaultValue;
|
|
@@ -21,6 +37,34 @@ class WithDefaultSchema extends core_js_1.Schema {
|
|
|
21
37
|
}
|
|
22
38
|
}
|
|
23
39
|
exports.WithDefaultSchema = WithDefaultSchema;
|
|
40
|
+
/**
|
|
41
|
+
* Creates a schema that applies a default value when the input is undefined.
|
|
42
|
+
*
|
|
43
|
+
* Commonly used with `optional()` to provide fallback values for missing
|
|
44
|
+
* properties. The default value is validated against the schema.
|
|
45
|
+
*
|
|
46
|
+
* @param validator - The validator for the value
|
|
47
|
+
* @param defaultValue - The default value to use when input is undefined
|
|
48
|
+
* @returns A new {@link WithDefaultSchema} instance
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* // Integer with default
|
|
53
|
+
* const countSchema = l.withDefault(l.integer(), 0)
|
|
54
|
+
* countSchema.parse(undefined) // 0
|
|
55
|
+
* countSchema.parse(5) // 5
|
|
56
|
+
*
|
|
57
|
+
* // Commonly combined with optional in objects
|
|
58
|
+
* const settingsSchema = l.object({
|
|
59
|
+
* theme: l.optional(l.withDefault(l.string(), 'light')),
|
|
60
|
+
* pageSize: l.optional(l.withDefault(l.integer(), 25)),
|
|
61
|
+
* })
|
|
62
|
+
* settingsSchema.parse({}) // { theme: 'light', pageSize: 25 }
|
|
63
|
+
*
|
|
64
|
+
* // Boolean with default
|
|
65
|
+
* const enabledSchema = l.withDefault(l.boolean(), false)
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
24
68
|
function withDefault(validator, defaultValue) {
|
|
25
69
|
return new WithDefaultSchema(validator, defaultValue);
|
|
26
70
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-default.js","sourceRoot":"","sources":["../../src/schema/with-default.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"with-default.js","sourceRoot":"","sources":["../../src/schema/with-default.ts"],"names":[],"mappings":";;;AAyEA,kCAKC;AA9ED,wCAMmB;AAEnB;;;;;;;;;;;;;;;GAeG;AACH,MAAa,iBAEX,SAAQ,gBAAuD;IAEpD;IACA;IAFX,YACW,SAAqB,EACrB,YAAoC;QAE7C,KAAK,EAAE,CAAA;QAHE,cAAS,GAAT,SAAS,CAAY;QACrB,iBAAY,GAAZ,YAAY,CAAwB;IAG/C,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,kEAAkE;QAClE,iCAAiC;QACjC,IAAI,KAAK,KAAK,SAAS,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC3D,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;QACxD,CAAC;QAED,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;IAC5C,CAAC;CACF;AAnBD,8CAmBC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,SAAgB,WAAW,CACzB,SAAqB,EACrB,YAAoC;IAEpC,OAAO,IAAI,iBAAiB,CAAa,SAAS,EAAE,YAAY,CAAC,CAAA;AACnE,CAAC","sourcesContent":["import {\n InferInput,\n InferOutput,\n Schema,\n ValidationContext,\n Validator,\n} from '../core.js'\n\n/**\n * Schema wrapper that provides a default value when the input is undefined.\n *\n * In parse mode, when the input is `undefined`, the default value is used\n * instead. In validate mode, undefined values pass through unchanged (the\n * default is not applied).\n *\n * @template TValidator - The wrapped validator type\n *\n * @example\n * ```ts\n * const schema = new WithDefaultSchema(l.integer(), 0)\n * schema.parse(undefined) // 0\n * schema.parse(42) // 42\n * ```\n */\nexport class WithDefaultSchema<\n const TValidator extends Validator,\n> extends Schema<InferInput<TValidator>, InferOutput<TValidator>> {\n constructor(\n readonly validator: TValidator,\n readonly defaultValue: InferInput<TValidator>,\n ) {\n super()\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n // When in a validation context, the output should not be altered,\n // so we don't apply the default.\n if (input === undefined && ctx.options.mode !== 'validate') {\n return ctx.validate(this.defaultValue, this.validator)\n }\n\n return ctx.validate(input, this.validator)\n }\n}\n\n/**\n * Creates a schema that applies a default value when the input is undefined.\n *\n * Commonly used with `optional()` to provide fallback values for missing\n * properties. The default value is validated against the schema.\n *\n * @param validator - The validator for the value\n * @param defaultValue - The default value to use when input is undefined\n * @returns A new {@link WithDefaultSchema} instance\n *\n * @example\n * ```ts\n * // Integer with default\n * const countSchema = l.withDefault(l.integer(), 0)\n * countSchema.parse(undefined) // 0\n * countSchema.parse(5) // 5\n *\n * // Commonly combined with optional in objects\n * const settingsSchema = l.object({\n * theme: l.optional(l.withDefault(l.string(), 'light')),\n * pageSize: l.optional(l.withDefault(l.integer(), 25)),\n * })\n * settingsSchema.parse({}) // { theme: 'light', pageSize: 25 }\n *\n * // Boolean with default\n * const enabledSchema = l.withDefault(l.boolean(), false)\n * ```\n */\nexport function withDefault<const TValidator extends Validator>(\n validator: TValidator,\n defaultValue: InferInput<TValidator>,\n) {\n return new WithDefaultSchema<TValidator>(validator, defaultValue)\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/lex-schema",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Lexicon schema system for AT Lexicons",
|
|
6
6
|
"keywords": [
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
"types": "./dist/index.d.ts",
|
|
32
32
|
"browser": "./dist/index.js",
|
|
33
33
|
"import": "./dist/index.js",
|
|
34
|
-
"
|
|
34
|
+
"default": "./dist/index.js"
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"tslib": "^2.8.1",
|
|
39
|
-
"@atproto/syntax": "0.4.3",
|
|
40
|
-
"@atproto/lex-data": "0.0.
|
|
39
|
+
"@atproto/syntax": "^0.4.3",
|
|
40
|
+
"@atproto/lex-data": "^0.0.11"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"vitest": "^4.0.16"
|
package/src/core/$type.ts
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
import { NsidString } from './string-format.js'
|
|
2
2
|
import { OmitKey, Simplify } from './types.js'
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Constructs the `$type` string type for a given NSID and hash.
|
|
6
|
+
*
|
|
7
|
+
* The `$type` value identifies a schema definition within a lexicon:
|
|
8
|
+
* - For "main" definitions: just the NSID (e.g., `'app.bsky.feed.post'`)
|
|
9
|
+
* - For named definitions: NSID + hash + name (e.g., `'app.bsky.feed.defs#postView'`)
|
|
10
|
+
*
|
|
11
|
+
* @typeParam N - The NSID string type
|
|
12
|
+
* @typeParam H - The hash/definition name (use `'main'` for the main definition)
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* type MainType = $Type<'app.bsky.feed.post', 'main'>
|
|
17
|
+
* // Result: 'app.bsky.feed.post'
|
|
18
|
+
*
|
|
19
|
+
* type DefType = $Type<'app.bsky.feed.defs', 'postView'>
|
|
20
|
+
* // Result: 'app.bsky.feed.defs#postView'
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
4
23
|
export type $Type<
|
|
5
24
|
N extends NsidString = NsidString,
|
|
6
25
|
H extends string = string,
|
|
@@ -12,8 +31,41 @@ export type $Type<
|
|
|
12
31
|
: `${N}#${H}`
|
|
13
32
|
: never
|
|
14
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Extracts the `$type` string type from an object type.
|
|
36
|
+
*
|
|
37
|
+
* @typeParam O - An object type with an optional `$type` property
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* type Post = { $type: 'app.bsky.feed.post'; text: string }
|
|
42
|
+
* type PostType = $TypeOf<Post>
|
|
43
|
+
* // Result: 'app.bsky.feed.post'
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
15
46
|
export type $TypeOf<O extends { $type?: string }> = NonNullable<O['$type']>
|
|
16
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Constructs a `$type` string value from an NSID and definition name.
|
|
50
|
+
*
|
|
51
|
+
* For the "main" definition, returns just the NSID. For named definitions,
|
|
52
|
+
* returns the NSID followed by `#` and the definition name.
|
|
53
|
+
*
|
|
54
|
+
* @typeParam N - The NSID string type
|
|
55
|
+
* @typeParam H - The definition name type
|
|
56
|
+
* @param nsid - The NSID of the lexicon
|
|
57
|
+
* @param hash - The definition name within the lexicon (use `'main'` for the main definition)
|
|
58
|
+
* @returns The constructed `$type` string
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* $type('app.bsky.feed.post', 'main')
|
|
63
|
+
* // Returns: 'app.bsky.feed.post'
|
|
64
|
+
*
|
|
65
|
+
* $type('app.bsky.feed.defs', 'postView')
|
|
66
|
+
* // Returns: 'app.bsky.feed.defs#postView'
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
17
69
|
/*@__NO_SIDE_EFFECTS__*/
|
|
18
70
|
export function $type<N extends NsidString, H extends string>(
|
|
19
71
|
nsid: N,
|
|
@@ -22,12 +74,50 @@ export function $type<N extends NsidString, H extends string>(
|
|
|
22
74
|
return (hash === 'main' ? nsid : `${nsid}#${hash}`) as $Type<N, H>
|
|
23
75
|
}
|
|
24
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Represents an object with a required `$type` property.
|
|
79
|
+
*
|
|
80
|
+
* This type adds a `$type` property to an existing object type, useful for
|
|
81
|
+
* representing typed AT Protocol objects.
|
|
82
|
+
*
|
|
83
|
+
* @typeParam V - The base object type
|
|
84
|
+
* @typeParam T - The `$type` string literal type
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* type Post = $Typed<{ text: string; createdAt: string }, 'app.bsky.feed.post'>
|
|
89
|
+
* // Result: { $type: 'app.bsky.feed.post'; text: string; createdAt: string }
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
25
92
|
export type $Typed<V, T extends string = string> = Simplify<
|
|
26
93
|
V & {
|
|
27
94
|
$type: T
|
|
28
95
|
}
|
|
29
96
|
>
|
|
30
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Ensures an object has the specified `$type` property.
|
|
100
|
+
*
|
|
101
|
+
* If the object already has the correct `$type`, returns it unchanged.
|
|
102
|
+
* Otherwise, creates a new object with the `$type` property added.
|
|
103
|
+
*
|
|
104
|
+
* @typeParam V - The object type (may already have `$type`)
|
|
105
|
+
* @typeParam T - The expected `$type` string
|
|
106
|
+
* @param value - The object to add `$type` to
|
|
107
|
+
* @param $type - The `$type` value to ensure
|
|
108
|
+
* @returns The object with the `$type` property
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* const post = $typed({ text: 'hello' }, 'app.bsky.feed.post')
|
|
113
|
+
* // Result: { $type: 'app.bsky.feed.post', text: 'hello' }
|
|
114
|
+
*
|
|
115
|
+
* // If already typed, returns same object
|
|
116
|
+
* const typed = { $type: 'app.bsky.feed.post', text: 'hello' }
|
|
117
|
+
* const same = $typed(typed, 'app.bsky.feed.post')
|
|
118
|
+
* console.log(typed === same) // true
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
31
121
|
export function $typed<V extends { $type?: unknown }, T extends string>(
|
|
32
122
|
value: V,
|
|
33
123
|
$type: T,
|
|
@@ -35,33 +125,75 @@ export function $typed<V extends { $type?: unknown }, T extends string>(
|
|
|
35
125
|
return value.$type === $type ? (value as $Typed<V, T>) : { ...value, $type }
|
|
36
126
|
}
|
|
37
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Represents an object with an optional `$type` property.
|
|
130
|
+
*
|
|
131
|
+
* This is used for objects that may or may not have type information,
|
|
132
|
+
* such as input parameters that accept both typed and untyped values.
|
|
133
|
+
*
|
|
134
|
+
* @typeParam V - The base object type
|
|
135
|
+
* @typeParam T - The optional `$type` string literal type
|
|
136
|
+
*/
|
|
38
137
|
export type $TypedMaybe<V, T extends string = string> = Simplify<
|
|
39
138
|
V & {
|
|
40
139
|
$type?: T
|
|
41
140
|
}
|
|
42
141
|
>
|
|
43
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Removes the `$type` property from an object type.
|
|
145
|
+
*
|
|
146
|
+
* Useful for extracting the "content" of a typed object without the type marker.
|
|
147
|
+
*
|
|
148
|
+
* @typeParam V - An object type with an optional `$type` property
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```typescript
|
|
152
|
+
* type Post = { $type: 'app.bsky.feed.post'; text: string }
|
|
153
|
+
* type PostContent = Un$Typed<Post>
|
|
154
|
+
* // Result: { text: string }
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
44
157
|
export type Un$Typed<V extends { $type?: string }> = OmitKey<V, '$type'>
|
|
45
158
|
|
|
159
|
+
/**
|
|
160
|
+
* Unique symbol for branding unknown `$type` strings.
|
|
161
|
+
* @internal
|
|
162
|
+
*/
|
|
46
163
|
declare const unknown$TypeSymbol: unique symbol
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Represents an unknown or unrecognized `$type` string.
|
|
167
|
+
*
|
|
168
|
+
* This branded type is used in union types to distinguish between
|
|
169
|
+
* known typed objects and unknown typed objects (from open unions).
|
|
170
|
+
* The branding prevents accidentally matching known `$type` values.
|
|
171
|
+
*/
|
|
47
172
|
export type Unknown$Type = string & { [unknown$TypeSymbol]: true }
|
|
48
173
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
174
|
+
/**
|
|
175
|
+
* Represents an object with an unknown `$type` value.
|
|
176
|
+
*
|
|
177
|
+
* This type is used in open union schemas to represent typed objects that
|
|
178
|
+
* don't match any of the known types. The {@link Unknown$Type} branding ensures
|
|
179
|
+
* that invalid instances of known types don't accidentally match this type.
|
|
180
|
+
*
|
|
181
|
+
* For example, in an open union like:
|
|
182
|
+
* ```typescript
|
|
183
|
+
* type MyOpenUnion = { $type: 'A'; a: number } | Unknown$TypedObject
|
|
184
|
+
* ```
|
|
185
|
+
*
|
|
186
|
+
* A value `{ $type: 'A' }` (missing the required `a` property) will NOT match
|
|
187
|
+
* `Unknown$TypedObject` because `'A'` is not assignable to `Unknown$Type`.
|
|
188
|
+
* This ensures that malformed instances of known types are properly rejected.
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```typescript
|
|
192
|
+
* // This represents any typed object we don't recognize
|
|
193
|
+
* const unknownTyped: Unknown$TypedObject = {
|
|
194
|
+
* $type: 'some.unknown.type' as Unknown$Type,
|
|
195
|
+
* // ... arbitrary properties
|
|
196
|
+
* }
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
67
199
|
export type Unknown$TypedObject = { $type: Unknown$Type }
|
package/src/core/record-key.ts
CHANGED
|
@@ -1,7 +1,36 @@
|
|
|
1
1
|
import { isValidRecordKey } from '@atproto/syntax'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* The valid record key constraint types in a lexicon definition.
|
|
5
|
+
*
|
|
6
|
+
* - `'any'` - Accepts any valid record key
|
|
7
|
+
* - `'nsid'` - Record key must be a valid NSID
|
|
8
|
+
* - `'tid'` - Record key must be a valid TID
|
|
9
|
+
* - `'literal:...'` - Record key must be the exact specified value
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const constraint: LexiconRecordKey = 'tid'
|
|
14
|
+
* const literalConstraint: LexiconRecordKey = 'literal:self'
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
3
17
|
export type LexiconRecordKey = 'any' | 'nsid' | 'tid' | `literal:${string}`
|
|
4
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Type guard that checks if a value is a valid lexicon record key constraint.
|
|
21
|
+
*
|
|
22
|
+
* @typeParam T - The input type
|
|
23
|
+
* @param key - The value to check
|
|
24
|
+
* @returns `true` if the value is a valid record key constraint
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* if (isLexiconRecordKey(value)) {
|
|
29
|
+
* // value is typed as LexiconRecordKey
|
|
30
|
+
* console.log('Valid constraint:', value)
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
5
34
|
/*@__NO_SIDE_EFFECTS__*/
|
|
6
35
|
export function isLexiconRecordKey<T>(key: T): key is T & LexiconRecordKey {
|
|
7
36
|
return (
|
|
@@ -15,6 +44,21 @@ export function isLexiconRecordKey<T>(key: T): key is T & LexiconRecordKey {
|
|
|
15
44
|
)
|
|
16
45
|
}
|
|
17
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Validates and returns a value as a lexicon record key constraint, throwing if invalid.
|
|
49
|
+
*
|
|
50
|
+
* @param key - The value to validate
|
|
51
|
+
* @returns The value typed as {@link LexiconRecordKey}
|
|
52
|
+
* @throws {Error} If the value is not a valid record key constraint
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const constraint = asLexiconRecordKey('tid')
|
|
57
|
+
* // constraint is typed as LexiconRecordKey
|
|
58
|
+
*
|
|
59
|
+
* asLexiconRecordKey('invalid') // throws Error
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
18
62
|
/*@__NO_SIDE_EFFECTS__*/
|
|
19
63
|
export function asLexiconRecordKey(key: unknown): LexiconRecordKey {
|
|
20
64
|
if (isLexiconRecordKey(key)) return key
|