@atproto/lex-schema 0.0.8 → 0.0.10
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 +41 -0
- package/LICENSE.txt +1 -1
- package/dist/core/$type.d.ts +11 -0
- package/dist/core/$type.d.ts.map +1 -1
- package/dist/core/$type.js +4 -0
- package/dist/core/$type.js.map +1 -1
- package/dist/core/schema.d.ts +31 -24
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +38 -8
- package/dist/core/schema.js.map +1 -1
- package/dist/core/string-format.d.ts +35 -35
- package/dist/core/string-format.d.ts.map +1 -1
- package/dist/core/string-format.js +49 -91
- package/dist/core/string-format.js.map +1 -1
- package/dist/core/validation-issue.js +1 -1
- package/dist/core/validation-issue.js.map +1 -1
- package/dist/core/validator.d.ts +53 -32
- package/dist/core/validator.d.ts.map +1 -1
- package/dist/core/validator.js +18 -22
- package/dist/core/validator.js.map +1 -1
- package/dist/external.d.ts +0 -85
- package/dist/external.d.ts.map +1 -1
- package/dist/external.js +0 -164
- package/dist/external.js.map +1 -1
- package/dist/helpers.d.ts +10 -5
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +3 -3
- package/dist/helpers.js.map +1 -1
- package/dist/schema/array.d.ts +9 -5
- package/dist/schema/array.d.ts.map +1 -1
- package/dist/schema/array.js +14 -5
- package/dist/schema/array.js.map +1 -1
- package/dist/schema/blob.d.ts +9 -7
- package/dist/schema/blob.d.ts.map +1 -1
- package/dist/schema/blob.js +9 -5
- package/dist/schema/blob.js.map +1 -1
- package/dist/schema/boolean.d.ts +3 -7
- package/dist/schema/boolean.d.ts.map +1 -1
- package/dist/schema/boolean.js +6 -7
- package/dist/schema/boolean.js.map +1 -1
- package/dist/schema/bytes.d.ts +3 -2
- package/dist/schema/bytes.d.ts.map +1 -1
- package/dist/schema/bytes.js +7 -3
- package/dist/schema/bytes.js.map +1 -1
- package/dist/schema/cid.d.ts +10 -8
- package/dist/schema/cid.d.ts.map +1 -1
- package/dist/schema/cid.js +5 -1
- package/dist/schema/cid.js.map +1 -1
- package/dist/schema/custom.d.ts +6 -5
- package/dist/schema/custom.d.ts.map +1 -1
- package/dist/schema/custom.js +10 -4
- package/dist/schema/custom.js.map +1 -1
- package/dist/schema/dict.d.ts +8 -8
- package/dist/schema/dict.d.ts.map +1 -1
- package/dist/schema/dict.js +11 -2
- package/dist/schema/dict.js.map +1 -1
- package/dist/schema/discriminated-union.d.ts +21 -14
- package/dist/schema/discriminated-union.d.ts.map +1 -1
- package/dist/schema/discriminated-union.js +7 -0
- package/dist/schema/discriminated-union.js.map +1 -1
- package/dist/schema/enum.d.ts +7 -9
- package/dist/schema/enum.d.ts.map +1 -1
- package/dist/schema/enum.js +8 -4
- package/dist/schema/enum.js.map +1 -1
- package/dist/schema/integer.d.ts +5 -5
- package/dist/schema/integer.d.ts.map +1 -1
- package/dist/schema/integer.js +9 -5
- package/dist/schema/integer.js.map +1 -1
- package/dist/schema/intersection.d.ts +4 -4
- package/dist/schema/intersection.d.ts.map +1 -1
- package/dist/schema/intersection.js +5 -0
- package/dist/schema/intersection.js.map +1 -1
- package/dist/schema/literal.d.ts +6 -9
- package/dist/schema/literal.d.ts.map +1 -1
- package/dist/schema/literal.js +7 -4
- package/dist/schema/literal.js.map +1 -1
- package/dist/schema/never.d.ts +3 -2
- package/dist/schema/never.d.ts.map +1 -1
- package/dist/schema/never.js +5 -1
- package/dist/schema/never.js.map +1 -1
- package/dist/schema/null.d.ts +4 -3
- package/dist/schema/null.d.ts.map +1 -1
- package/dist/schema/null.js +6 -4
- package/dist/schema/null.js.map +1 -1
- package/dist/schema/nullable.d.ts +6 -5
- package/dist/schema/nullable.d.ts.map +1 -1
- package/dist/schema/nullable.js +9 -5
- package/dist/schema/nullable.js.map +1 -1
- package/dist/schema/object.d.ts +10 -8
- package/dist/schema/object.d.ts.map +1 -1
- package/dist/schema/object.js +11 -3
- package/dist/schema/object.js.map +1 -1
- package/dist/schema/optional.d.ts +7 -5
- package/dist/schema/optional.d.ts.map +1 -1
- package/dist/schema/optional.js +14 -6
- package/dist/schema/optional.js.map +1 -1
- package/dist/schema/params.d.ts +24 -13
- package/dist/schema/params.d.ts.map +1 -1
- package/dist/schema/params.js +47 -25
- package/dist/schema/params.js.map +1 -1
- package/dist/schema/payload.d.ts +12 -9
- package/dist/schema/payload.d.ts.map +1 -1
- package/dist/schema/payload.js +11 -0
- package/dist/schema/payload.js.map +1 -1
- package/dist/schema/permission-set.d.ts +1 -0
- package/dist/schema/permission-set.d.ts.map +1 -1
- package/dist/schema/permission-set.js +5 -0
- package/dist/schema/permission-set.js.map +1 -1
- package/dist/schema/permission.d.ts +6 -5
- package/dist/schema/permission.d.ts.map +1 -1
- package/dist/schema/permission.js +5 -0
- package/dist/schema/permission.js.map +1 -1
- package/dist/schema/procedure.d.ts +2 -1
- package/dist/schema/procedure.d.ts.map +1 -1
- package/dist/schema/procedure.js +5 -0
- package/dist/schema/procedure.js.map +1 -1
- package/dist/schema/query.d.ts +2 -1
- package/dist/schema/query.d.ts.map +1 -1
- package/dist/schema/query.js +5 -0
- package/dist/schema/query.js.map +1 -1
- package/dist/schema/record.d.ts +48 -30
- package/dist/schema/record.d.ts.map +1 -1
- package/dist/schema/record.js +12 -9
- package/dist/schema/record.js.map +1 -1
- package/dist/schema/ref.d.ts +9 -6
- package/dist/schema/ref.d.ts.map +1 -1
- package/dist/schema/ref.js +9 -16
- package/dist/schema/ref.js.map +1 -1
- package/dist/schema/refine.d.ts +4 -4
- package/dist/schema/refine.d.ts.map +1 -1
- package/dist/schema/refine.js.map +1 -1
- package/dist/schema/regexp.d.ts +4 -3
- package/dist/schema/regexp.d.ts.map +1 -1
- package/dist/schema/regexp.js +5 -0
- package/dist/schema/regexp.js.map +1 -1
- package/dist/schema/string.d.ts +7 -8
- package/dist/schema/string.d.ts.map +1 -1
- package/dist/schema/string.js +13 -19
- package/dist/schema/string.js.map +1 -1
- package/dist/schema/subscription.d.ts +2 -1
- package/dist/schema/subscription.d.ts.map +1 -1
- package/dist/schema/subscription.js +5 -0
- package/dist/schema/subscription.js.map +1 -1
- package/dist/schema/token.d.ts +6 -5
- package/dist/schema/token.d.ts.map +1 -1
- package/dist/schema/token.js +5 -0
- package/dist/schema/token.js.map +1 -1
- package/dist/schema/typed-object.d.ts +43 -26
- package/dist/schema/typed-object.d.ts.map +1 -1
- package/dist/schema/typed-object.js +6 -3
- package/dist/schema/typed-object.js.map +1 -1
- package/dist/schema/typed-ref.d.ts +16 -25
- package/dist/schema/typed-ref.d.ts.map +1 -1
- package/dist/schema/typed-ref.js +7 -17
- package/dist/schema/typed-ref.js.map +1 -1
- package/dist/schema/typed-union.d.ts +9 -21
- package/dist/schema/typed-union.d.ts.map +1 -1
- package/dist/schema/typed-union.js +15 -11
- package/dist/schema/typed-union.js.map +1 -1
- package/dist/schema/union.d.ts +6 -6
- package/dist/schema/union.d.ts.map +1 -1
- package/dist/schema/union.js +7 -5
- package/dist/schema/union.js.map +1 -1
- package/dist/schema/unknown-object.d.ts +5 -4
- package/dist/schema/unknown-object.d.ts.map +1 -1
- package/dist/schema/unknown-object.js +5 -1
- package/dist/schema/unknown-object.js.map +1 -1
- package/dist/schema/unknown.d.ts +3 -2
- package/dist/schema/unknown.d.ts.map +1 -1
- package/dist/schema/unknown.js +5 -1
- package/dist/schema/unknown.js.map +1 -1
- package/dist/schema/with-default.d.ts +9 -0
- package/dist/schema/with-default.d.ts.map +1 -0
- package/dist/schema/with-default.js +27 -0
- package/dist/schema/with-default.js.map +1 -0
- package/dist/schema.d.ts +2 -2
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +2 -4
- package/dist/schema.js.map +1 -1
- package/dist/util/assertion-util.d.ts +0 -6
- package/dist/util/assertion-util.d.ts.map +1 -1
- package/dist/util/assertion-util.js +0 -28
- package/dist/util/assertion-util.js.map +1 -1
- package/dist/util/memoize.d.ts +2 -2
- package/dist/util/memoize.d.ts.map +1 -1
- package/dist/util/memoize.js +23 -39
- package/dist/util/memoize.js.map +1 -1
- package/package.json +3 -3
- package/src/core/$type.test.ts +20 -0
- package/src/core/$type.ts +30 -0
- package/src/core/schema.ts +86 -38
- package/src/core/string-format.ts +119 -158
- package/src/core/validation-issue.ts +1 -1
- package/src/core/validator.ts +93 -53
- package/src/external.ts +0 -404
- package/src/helpers.test.ts +22 -21
- package/src/helpers.ts +14 -14
- package/src/schema/array.test.ts +38 -40
- package/src/schema/array.ts +35 -13
- package/src/schema/blob.test.ts +21 -21
- package/src/schema/blob.ts +19 -17
- package/src/schema/boolean.test.ts +9 -8
- package/src/schema/boolean.ts +7 -13
- package/src/schema/bytes.test.ts +13 -13
- package/src/schema/bytes.ts +13 -8
- package/src/schema/cid.test.ts +3 -3
- package/src/schema/cid.ts +15 -13
- package/src/schema/custom.test.ts +26 -26
- package/src/schema/custom.ts +20 -13
- package/src/schema/dict.test.ts +21 -39
- package/src/schema/dict.ts +28 -19
- package/src/schema/discriminated-union.test.ts +128 -128
- package/src/schema/discriminated-union.ts +45 -26
- package/src/schema/enum.test.ts +17 -16
- package/src/schema/enum.ts +16 -16
- package/src/schema/integer.test.ts +22 -21
- package/src/schema/integer.ts +12 -9
- package/src/schema/intersection.test.ts +10 -10
- package/src/schema/intersection.ts +17 -14
- package/src/schema/literal.test.ts +35 -34
- package/src/schema/literal.ts +12 -15
- package/src/schema/never.test.ts +5 -5
- package/src/schema/never.ts +7 -2
- package/src/schema/null.test.ts +3 -3
- package/src/schema/null.ts +9 -9
- package/src/schema/nullable.test.ts +31 -42
- package/src/schema/nullable.ts +17 -9
- package/src/schema/object.test.ts +10 -12
- package/src/schema/object.ts +27 -18
- package/src/schema/optional.test.ts +21 -28
- package/src/schema/optional.ts +27 -10
- package/src/schema/params.test.ts +471 -47
- package/src/schema/params.ts +72 -38
- package/src/schema/payload.test.ts +150 -156
- package/src/schema/payload.ts +35 -19
- package/src/schema/permission-set.test.ts +206 -273
- package/src/schema/permission-set.ts +8 -0
- package/src/schema/permission.test.ts +177 -177
- package/src/schema/permission.ts +13 -5
- package/src/schema/procedure.test.ts +183 -242
- package/src/schema/procedure.ts +18 -5
- package/src/schema/query.test.ts +186 -200
- package/src/schema/query.ts +16 -4
- package/src/schema/record.test.ts +121 -101
- package/src/schema/record.ts +74 -40
- package/src/schema/ref.test.ts +101 -118
- package/src/schema/ref.ts +33 -28
- package/src/schema/refine.test.ts +28 -28
- package/src/schema/refine.ts +23 -20
- package/src/schema/regexp.test.ts +29 -33
- package/src/schema/regexp.ts +11 -7
- package/src/schema/string.test.ts +35 -35
- package/src/schema/string.ts +24 -33
- package/src/schema/subscription.test.ts +259 -387
- package/src/schema/subscription.ts +16 -4
- package/src/schema/token.test.ts +47 -324
- package/src/schema/token.ts +14 -7
- package/src/schema/typed-object.test.ts +98 -81
- package/src/schema/typed-object.ts +68 -33
- package/src/schema/typed-ref.test.ts +206 -234
- package/src/schema/typed-ref.ts +40 -42
- package/src/schema/typed-union.test.ts +40 -64
- package/src/schema/typed-union.ts +36 -58
- package/src/schema/union.test.ts +17 -27
- package/src/schema/union.ts +20 -16
- package/src/schema/unknown-object.test.ts +8 -8
- package/src/schema/unknown-object.ts +9 -7
- package/src/schema/unknown.test.ts +4 -4
- package/src/schema/unknown.ts +7 -5
- package/src/schema/with-default.ts +35 -0
- package/src/schema.ts +2 -6
- package/src/util/assertion-util.ts +0 -39
- package/src/util/memoize.ts +26 -46
- package/dist/schema/_parameters.d.ts +0 -17
- package/dist/schema/_parameters.d.ts.map +0 -1
- package/dist/schema/_parameters.js +0 -20
- package/dist/schema/_parameters.js.map +0 -1
- package/src/schema/_parameters.test.ts +0 -417
- package/src/schema/_parameters.ts +0 -26
package/dist/util/memoize.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare function memoizedOptions<F extends (
|
|
2
|
-
export declare function memoizedTransformer<F extends (
|
|
1
|
+
export declare function memoizedOptions<F extends (...args: any[]) => any>(fn: F): F;
|
|
2
|
+
export declare function memoizedTransformer<F extends (key: any, ...args: any[]) => unknown>(fn: F): F;
|
|
3
3
|
//# sourceMappingURL=memoize.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memoize.d.ts","sourceRoot":"","sources":["../../src/util/memoize.ts"],"names":[],"mappings":"AACA,wBAAgB,eAAe,
|
|
1
|
+
{"version":3,"file":"memoize.d.ts","sourceRoot":"","sources":["../../src/util/memoize.ts"],"names":[],"mappings":"AACA,wBAAgB,eAAe,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAiB3E;AAGD,wBAAgB,mBAAmB,CACjC,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,EAC/C,EAAE,EAAE,CAAC,GAAG,CAAC,CAaV"}
|
package/dist/util/memoize.js
CHANGED
|
@@ -3,50 +3,34 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.memoizedOptions = memoizedOptions;
|
|
4
4
|
exports.memoizedTransformer = memoizedTransformer;
|
|
5
5
|
/*@__NO_SIDE_EFFECTS__*/
|
|
6
|
-
function memoizedOptions(fn
|
|
7
|
-
let
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return fn(options);
|
|
21
|
-
};
|
|
22
|
-
return ((options) => {
|
|
23
|
-
// Non-empty options case
|
|
24
|
-
if (options)
|
|
25
|
-
for (const _ in options)
|
|
26
|
-
return fromCache(options);
|
|
27
|
-
// Empty or missing options case
|
|
28
|
-
return (emptyOptionsValue ??= fn(options));
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
return ((options) => {
|
|
32
|
-
// Non-empty options case
|
|
33
|
-
if (options)
|
|
34
|
-
for (const _ in options)
|
|
35
|
-
return fn(options);
|
|
36
|
-
// Empty or missing options case
|
|
37
|
-
return (emptyOptionsValue ??= fn(options));
|
|
38
|
-
});
|
|
6
|
+
function memoizedOptions(fn) {
|
|
7
|
+
let cache = null;
|
|
8
|
+
return function cached(...args) {
|
|
9
|
+
// Not using the cache if there are args
|
|
10
|
+
if (args.length > 0) {
|
|
11
|
+
return fn(...args);
|
|
12
|
+
}
|
|
13
|
+
if (cache != null) {
|
|
14
|
+
return cache.value;
|
|
15
|
+
}
|
|
16
|
+
const value = fn(...args);
|
|
17
|
+
cache = { value };
|
|
18
|
+
return value;
|
|
19
|
+
};
|
|
39
20
|
}
|
|
40
21
|
/*@__NO_SIDE_EFFECTS__*/
|
|
41
22
|
function memoizedTransformer(fn) {
|
|
42
|
-
|
|
43
|
-
return (
|
|
44
|
-
|
|
23
|
+
let cache;
|
|
24
|
+
return function cached(key, ...args) {
|
|
25
|
+
if (args.length > 0)
|
|
26
|
+
return fn(key, ...args);
|
|
27
|
+
cache ??= new WeakMap();
|
|
28
|
+
const cached = cache.get(key);
|
|
45
29
|
if (cached)
|
|
46
30
|
return cached;
|
|
47
|
-
const result = fn(
|
|
48
|
-
cache.set(
|
|
31
|
+
const result = fn(key, ...args);
|
|
32
|
+
cache.set(key, result);
|
|
49
33
|
return result;
|
|
50
|
-
}
|
|
34
|
+
};
|
|
51
35
|
}
|
|
52
36
|
//# sourceMappingURL=memoize.js.map
|
package/dist/util/memoize.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memoize.js","sourceRoot":"","sources":["../../src/util/memoize.ts"],"names":[],"mappings":";;AACA,
|
|
1
|
+
{"version":3,"file":"memoize.js","sourceRoot":"","sources":["../../src/util/memoize.ts"],"names":[],"mappings":";;AACA,0CAiBC;AAGD,kDAeC;AApCD,wBAAwB;AACxB,SAAgB,eAAe,CAAoC,EAAK;IACtE,IAAI,KAAK,GAAoC,IAAI,CAAA;IAEjD,OAAO,SAAS,MAAM,CAAC,GAAG,IAAW;QACnC,wCAAwC;QACxC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;QACpB,CAAC;QAED,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClB,OAAO,KAAK,CAAC,KAAK,CAAA;QACpB,CAAC;QAED,MAAM,KAAK,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;QACzB,KAAK,GAAG,EAAE,KAAK,EAAE,CAAA;QACjB,OAAO,KAAK,CAAA;IACd,CAAM,CAAA;AACR,CAAC;AAED,wBAAwB;AACxB,SAAgB,mBAAmB,CAEjC,EAAK;IACL,IAAI,KAAqC,CAAA;IAEzC,OAAO,SAAS,MAAM,CAAC,GAAQ,EAAE,GAAG,IAAW;QAC7C,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;QAE5C,KAAK,KAAK,IAAI,OAAO,EAAE,CAAA;QACvB,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAC7B,IAAI,MAAM;YAAE,OAAO,MAAM,CAAA;QACzB,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAkB,CAAA;QAChD,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QACtB,OAAO,MAAM,CAAA;IACf,CAAM,CAAA;AACR,CAAC","sourcesContent":["/*@__NO_SIDE_EFFECTS__*/\nexport function memoizedOptions<F extends (...args: any[]) => any>(fn: F): F {\n let cache: null | { value: ReturnType<F> } = null\n\n return function cached(...args: any[]): ReturnType<F> {\n // Not using the cache if there are args\n if (args.length > 0) {\n return fn(...args)\n }\n\n if (cache != null) {\n return cache.value\n }\n\n const value = fn(...args)\n cache = { value }\n return value\n } as F\n}\n\n/*@__NO_SIDE_EFFECTS__*/\nexport function memoizedTransformer<\n F extends (key: any, ...args: any[]) => unknown,\n>(fn: F): F {\n let cache: WeakMap<object, ReturnType<F>>\n\n return function cached(key: any, ...args: any[]): any {\n if (args.length > 0) return fn(key, ...args)\n\n cache ??= new WeakMap()\n const cached = cache.get(key)\n if (cached) return cached\n const result = fn(key, ...args) as ReturnType<F>\n cache.set(key, result)\n return result\n } as F\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.10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Lexicon schema system for AT Lexicons",
|
|
6
6
|
"keywords": [
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"tslib": "^2.8.1",
|
|
39
|
-
"@atproto/syntax": "0.4.
|
|
40
|
-
"@atproto/lex-data": "0.0.
|
|
39
|
+
"@atproto/syntax": "0.4.3",
|
|
40
|
+
"@atproto/lex-data": "0.0.9"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"vitest": "^4.0.16"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { describe, it } from 'vitest'
|
|
2
|
+
import { LexMap } from '@atproto/lex-data'
|
|
3
|
+
import { Unknown$TypedObject } from './$type.js'
|
|
4
|
+
|
|
5
|
+
describe('Unknown$TypedObject', () => {
|
|
6
|
+
it('allows assigning Unknown$TypedObject to LexMap', () => {
|
|
7
|
+
function expectLexMap(_value: LexMap) {}
|
|
8
|
+
|
|
9
|
+
const someObject = {
|
|
10
|
+
$type: 'some-type',
|
|
11
|
+
} as Unknown$TypedObject
|
|
12
|
+
|
|
13
|
+
expectLexMap(someObject)
|
|
14
|
+
|
|
15
|
+
expectLexMap({
|
|
16
|
+
arr: [someObject],
|
|
17
|
+
val: someObject,
|
|
18
|
+
})
|
|
19
|
+
})
|
|
20
|
+
})
|
package/src/core/$type.ts
CHANGED
|
@@ -28,6 +28,13 @@ export type $Typed<V, T extends string = string> = Simplify<
|
|
|
28
28
|
}
|
|
29
29
|
>
|
|
30
30
|
|
|
31
|
+
export function $typed<V extends { $type?: unknown }, T extends string>(
|
|
32
|
+
value: V,
|
|
33
|
+
$type: T,
|
|
34
|
+
): $Typed<V, T> {
|
|
35
|
+
return value.$type === $type ? (value as $Typed<V, T>) : { ...value, $type }
|
|
36
|
+
}
|
|
37
|
+
|
|
31
38
|
export type $TypedMaybe<V, T extends string = string> = Simplify<
|
|
32
39
|
V & {
|
|
33
40
|
$type?: T
|
|
@@ -35,3 +42,26 @@ export type $TypedMaybe<V, T extends string = string> = Simplify<
|
|
|
35
42
|
>
|
|
36
43
|
|
|
37
44
|
export type Un$Typed<V extends { $type?: string }> = OmitKey<V, '$type'>
|
|
45
|
+
|
|
46
|
+
declare const unknown$TypeSymbol: unique symbol
|
|
47
|
+
export type Unknown$Type = string & { [unknown$TypeSymbol]: true }
|
|
48
|
+
|
|
49
|
+
// In order to prevent places that expect a union of known and unknown $typed
|
|
50
|
+
// objects (like lexicons schema open unions), from accepting an invalid version
|
|
51
|
+
// of the known $typed objects, we need to prevent any other properties from
|
|
52
|
+
// being present.
|
|
53
|
+
//
|
|
54
|
+
// For example, if we expect:
|
|
55
|
+
// ```ts
|
|
56
|
+
// type MyOpenUnion = { $type: 'A'; a: number } | Unknown$TypedObject
|
|
57
|
+
// ```
|
|
58
|
+
// we want to make that that the following is rejected:
|
|
59
|
+
// ```ts
|
|
60
|
+
// { $type: 'A' }
|
|
61
|
+
// ```
|
|
62
|
+
//
|
|
63
|
+
// If we typed `Unknown$TypedObject` as `{ $type: string }`, `{ $type: 'A' }`
|
|
64
|
+
// would be a valid `MyOpenUnion` as it would match the `Unknown$TypedObject`.
|
|
65
|
+
// By using a $type property that uniquely describes unknown values, we ensure
|
|
66
|
+
// that only valid known typed objects, or a type casted value, can be used.
|
|
67
|
+
export type Unknown$TypedObject = { $type: Unknown$Type }
|
package/src/core/schema.ts
CHANGED
|
@@ -1,17 +1,38 @@
|
|
|
1
1
|
import {
|
|
2
|
+
InferInput,
|
|
3
|
+
InferOutput,
|
|
4
|
+
ValidationContext,
|
|
2
5
|
ValidationOptions,
|
|
3
6
|
ValidationResult,
|
|
4
7
|
Validator,
|
|
5
|
-
ValidatorContext,
|
|
6
8
|
} from './validator.js'
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
type ParseOptions = Omit<ValidationOptions, 'mode'>
|
|
11
|
+
type ValidateOptions = Omit<ValidationOptions, 'mode'>
|
|
12
|
+
|
|
13
|
+
export interface SchemaInternals<out TInput = unknown, out TOutput = TInput> {
|
|
14
|
+
/** @internal The inferred validation type */
|
|
15
|
+
input: TInput
|
|
16
|
+
|
|
17
|
+
/** @internal The inferred parse type */
|
|
18
|
+
output: TOutput
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export abstract class Schema<
|
|
22
|
+
out TInput = unknown,
|
|
23
|
+
out TOutput = TInput,
|
|
24
|
+
out TInternals extends SchemaInternals<TInput, TOutput> = SchemaInternals<
|
|
25
|
+
TInput,
|
|
26
|
+
TOutput
|
|
27
|
+
>,
|
|
28
|
+
> implements Validator<TInternals['input'], TInternals['output']>
|
|
29
|
+
{
|
|
30
|
+
declare readonly ['__lex']: TInternals
|
|
10
31
|
|
|
11
32
|
abstract validateInContext(
|
|
12
33
|
input: unknown,
|
|
13
|
-
ctx:
|
|
14
|
-
): ValidationResult
|
|
34
|
+
ctx: ValidationContext,
|
|
35
|
+
): ValidationResult
|
|
15
36
|
|
|
16
37
|
/**
|
|
17
38
|
* @note use {@link check}() instead of {@link assert}() if you encounter a
|
|
@@ -19,8 +40,8 @@ export abstract class Schema<Output = any> implements Validator<Output> {
|
|
|
19
40
|
* will typically arise in generic contexts, where the narrowed type is not
|
|
20
41
|
* needed.
|
|
21
42
|
*/
|
|
22
|
-
assert(input: unknown): asserts input is
|
|
23
|
-
const result =
|
|
43
|
+
assert(input: unknown): asserts input is InferInput<this> {
|
|
44
|
+
const result = ValidationContext.validate(input, this)
|
|
24
45
|
if (!result.success) throw result.reason
|
|
25
46
|
}
|
|
26
47
|
|
|
@@ -37,45 +58,53 @@ export abstract class Schema<Output = any> implements Validator<Output> {
|
|
|
37
58
|
/**
|
|
38
59
|
* Casts the input (by validating it) to the output type if it matches the
|
|
39
60
|
* schema, otherwise throws. This is the same as calling {@link parse}() with
|
|
40
|
-
* `
|
|
61
|
+
* `mode: "validate"`.
|
|
41
62
|
*/
|
|
42
|
-
cast<I>(input: I): I &
|
|
43
|
-
|
|
63
|
+
cast<I>(input: I): I & InferInput<this> {
|
|
64
|
+
const result = ValidationContext.validate(input, this)
|
|
65
|
+
if (result.success) return result.value
|
|
66
|
+
throw result.reason
|
|
44
67
|
}
|
|
45
68
|
|
|
46
|
-
matches(input:
|
|
47
|
-
const result =
|
|
69
|
+
matches<I>(input: I): input is I & InferInput<this> {
|
|
70
|
+
const result = ValidationContext.validate(input, this)
|
|
48
71
|
return result.success
|
|
49
72
|
}
|
|
50
73
|
|
|
51
|
-
ifMatches<I>(input: I): (I &
|
|
74
|
+
ifMatches<I>(input: I): (I & InferInput<this>) | undefined {
|
|
52
75
|
return this.matches(input) ? input : undefined
|
|
53
76
|
}
|
|
54
77
|
|
|
55
|
-
parse<
|
|
56
|
-
input: I,
|
|
57
|
-
options: ValidationOptions & { allowTransform: false },
|
|
58
|
-
): I & Output
|
|
59
|
-
parse(input: unknown, options?: ValidationOptions): Output
|
|
60
|
-
parse(input: unknown, options?: ValidationOptions): Output {
|
|
78
|
+
parse(input: unknown, options?: ParseOptions): InferOutput<this> {
|
|
61
79
|
const result = this.safeParse(input, options)
|
|
62
|
-
if (
|
|
63
|
-
|
|
80
|
+
if (result.success) return result.value
|
|
81
|
+
throw result.reason
|
|
64
82
|
}
|
|
65
83
|
|
|
66
|
-
safeParse<I>(
|
|
67
|
-
input: I,
|
|
68
|
-
options: ValidationOptions & { allowTransform: false },
|
|
69
|
-
): ValidationResult<I & Output>
|
|
70
|
-
safeParse(
|
|
71
|
-
input: unknown,
|
|
72
|
-
options?: ValidationOptions,
|
|
73
|
-
): ValidationResult<Output>
|
|
74
84
|
safeParse(
|
|
75
85
|
input: unknown,
|
|
76
|
-
options?:
|
|
77
|
-
): ValidationResult<
|
|
78
|
-
return
|
|
86
|
+
options?: ParseOptions,
|
|
87
|
+
): ValidationResult<InferOutput<this>> {
|
|
88
|
+
return ValidationContext.validate(input, this, {
|
|
89
|
+
...options,
|
|
90
|
+
mode: 'parse',
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
validate<I>(input: I, options?: ValidateOptions): I & InferInput<this> {
|
|
95
|
+
const result = this.safeValidate(input, options)
|
|
96
|
+
if (result.success) return result.value
|
|
97
|
+
throw result.reason
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
safeValidate<I>(
|
|
101
|
+
input: I,
|
|
102
|
+
options?: ValidateOptions,
|
|
103
|
+
): ValidationResult<I & InferInput<this>> {
|
|
104
|
+
return ValidationContext.validate(input, this, {
|
|
105
|
+
...options,
|
|
106
|
+
mode: 'validate',
|
|
107
|
+
})
|
|
79
108
|
}
|
|
80
109
|
|
|
81
110
|
// @NOTE The built lexicons namespaces will export utility functions that
|
|
@@ -92,26 +121,45 @@ export abstract class Schema<Output = any> implements Validator<Output> {
|
|
|
92
121
|
// - "app.bsky.feed.post.$parse(...)" // calls a utility function created by "lex build"
|
|
93
122
|
// - "app.bsky.feed.defs.postView.$parse(...)" // uses the alias defined below on the schema instance
|
|
94
123
|
|
|
95
|
-
$assert(input: unknown): asserts input is
|
|
124
|
+
$assert(input: unknown): asserts input is InferInput<this> {
|
|
96
125
|
return this.assert(input)
|
|
97
126
|
}
|
|
98
127
|
|
|
99
|
-
$
|
|
128
|
+
$check(input: unknown): void {
|
|
129
|
+
return this.check(input)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
$cast<I>(input: I): I & InferInput<this> {
|
|
133
|
+
return this.cast(input)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
$matches(input: unknown): input is InferInput<this> {
|
|
100
137
|
return this.matches(input)
|
|
101
138
|
}
|
|
102
139
|
|
|
103
|
-
$ifMatches<I>(input: I): (I &
|
|
140
|
+
$ifMatches<I>(input: I): (I & InferInput<this>) | undefined {
|
|
104
141
|
return this.ifMatches(input)
|
|
105
142
|
}
|
|
106
143
|
|
|
107
|
-
$parse(input: unknown, options?:
|
|
144
|
+
$parse(input: unknown, options?: ValidateOptions): InferOutput<this> {
|
|
108
145
|
return this.parse(input, options)
|
|
109
146
|
}
|
|
110
147
|
|
|
111
148
|
$safeParse(
|
|
112
149
|
input: unknown,
|
|
113
|
-
options?:
|
|
114
|
-
): ValidationResult<
|
|
150
|
+
options?: ValidateOptions,
|
|
151
|
+
): ValidationResult<InferOutput<this>> {
|
|
115
152
|
return this.safeParse(input, options)
|
|
116
153
|
}
|
|
154
|
+
|
|
155
|
+
$validate<I>(input: I, options?: ValidateOptions): I & InferInput<this> {
|
|
156
|
+
return this.validate(input, options)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
$safeValidate<I>(
|
|
160
|
+
input: I,
|
|
161
|
+
options?: ValidateOptions,
|
|
162
|
+
): ValidationResult<I & InferInput<this>> {
|
|
163
|
+
return this.safeValidate(input, options)
|
|
164
|
+
}
|
|
117
165
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { validateCidString } from '@atproto/lex-data'
|
|
2
2
|
import {
|
|
3
3
|
AtIdentifierString,
|
|
4
4
|
AtUriString,
|
|
@@ -8,173 +8,134 @@ import {
|
|
|
8
8
|
NsidString,
|
|
9
9
|
RecordKeyString,
|
|
10
10
|
TidString,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
UriString,
|
|
12
|
+
isValidAtIdentifier as isValidAtId,
|
|
13
|
+
isValidAtUri,
|
|
14
|
+
isValidDatetime,
|
|
15
|
+
isValidDid,
|
|
16
|
+
isValidHandle,
|
|
17
|
+
isValidLanguage,
|
|
18
|
+
isValidNsid,
|
|
19
|
+
isValidRecordKey,
|
|
20
|
+
isValidTid,
|
|
21
|
+
isValidUri,
|
|
19
22
|
} from '@atproto/syntax'
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
import { CheckFn } from '../util/assertion-util.js'
|
|
24
|
+
|
|
25
|
+
// Expose all individual string format types and type guards
|
|
26
|
+
|
|
27
|
+
export type { AtIdentifierString }
|
|
28
|
+
export const isAtIdentifierString: CheckFn<AtIdentifierString> = isValidAtId
|
|
29
|
+
|
|
30
|
+
export type { AtUriString }
|
|
31
|
+
export const isAtUriString: CheckFn<AtUriString> = isValidAtUri
|
|
32
|
+
|
|
30
33
|
export type CidString = string
|
|
34
|
+
export const isCidString = ((v) => validateCidString(v)) as CheckFn<CidString>
|
|
35
|
+
|
|
36
|
+
export type { DatetimeString }
|
|
37
|
+
export const isDatetimeString: CheckFn<DatetimeString> = isValidDatetime
|
|
38
|
+
|
|
39
|
+
export type { DidString }
|
|
40
|
+
export const isDidString: CheckFn<DidString> = isValidDid
|
|
41
|
+
|
|
42
|
+
export type { HandleString }
|
|
43
|
+
export const isHandleString: CheckFn<HandleString> = isValidHandle
|
|
44
|
+
|
|
31
45
|
export type LanguageString = string
|
|
32
|
-
export
|
|
46
|
+
export const isLanguageString = isValidLanguage as CheckFn<LanguageString>
|
|
33
47
|
|
|
34
|
-
|
|
35
|
-
export
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
48
|
+
export type { NsidString }
|
|
49
|
+
export const isNsidString: CheckFn<NsidString> = isValidNsid
|
|
50
|
+
|
|
51
|
+
export type { RecordKeyString }
|
|
52
|
+
export const isRecordKeyString: CheckFn<RecordKeyString> = isValidRecordKey
|
|
53
|
+
|
|
54
|
+
export type { TidString }
|
|
55
|
+
export const isTidString: CheckFn<TidString> = isValidTid
|
|
56
|
+
|
|
57
|
+
export type { UriString }
|
|
58
|
+
export const isUriString: CheckFn<UriString> = isValidUri
|
|
59
|
+
|
|
60
|
+
// String format registry (maps format names to their types and type guards)
|
|
61
|
+
|
|
62
|
+
type StringFormats = {
|
|
63
|
+
'at-identifier': AtIdentifierString
|
|
64
|
+
'at-uri': AtUriString
|
|
65
|
+
cid: CidString
|
|
66
|
+
datetime: DatetimeString
|
|
67
|
+
did: DidString
|
|
68
|
+
handle: HandleString
|
|
69
|
+
language: LanguageString
|
|
70
|
+
nsid: NsidString
|
|
71
|
+
'record-key': RecordKeyString
|
|
72
|
+
tid: TidString
|
|
73
|
+
uri: UriString
|
|
39
74
|
}
|
|
40
75
|
|
|
41
|
-
|
|
42
|
-
// infer the narrowed type after calling them.
|
|
76
|
+
export type StringFormat = Extract<keyof StringFormats, string>
|
|
43
77
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
78
|
+
const stringFormatVerifiers: {
|
|
79
|
+
readonly [K in StringFormat]: CheckFn<StringFormats[K]>
|
|
80
|
+
} = /*#__PURE__*/ Object.freeze({
|
|
81
|
+
__proto__: null,
|
|
82
|
+
|
|
83
|
+
'at-identifier': isAtIdentifierString,
|
|
84
|
+
'at-uri': isAtUriString,
|
|
85
|
+
cid: isCidString,
|
|
86
|
+
datetime: isDatetimeString,
|
|
87
|
+
did: isDidString,
|
|
88
|
+
handle: isHandleString,
|
|
89
|
+
language: isLanguageString,
|
|
90
|
+
nsid: isNsidString,
|
|
91
|
+
'record-key': isRecordKeyString,
|
|
92
|
+
tid: isTidString,
|
|
93
|
+
uri: isUriString,
|
|
94
|
+
})
|
|
54
95
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
ensureValidAtIdentifier
|
|
59
|
-
export const assertAtUriString: AssertFn<AtUriString> = ensureValidAtUri
|
|
60
|
-
export const assertCidString: AssertFn<CidString> = ensureValidCidString
|
|
61
|
-
export const assertDatetimeString: AssertFn<DatetimeString> =
|
|
62
|
-
ensureValidDatetime
|
|
63
|
-
export const assertDidString: AssertFn<DidString> = ensureValidDid
|
|
64
|
-
export const assertHandleString: AssertFn<HandleString> = ensureValidHandle
|
|
65
|
-
export const assertLanguageString: AssertFn<LanguageString> =
|
|
66
|
-
createAssertFunction<LanguageString>(
|
|
67
|
-
isLanguageString,
|
|
68
|
-
'Invalid BCP 47 string',
|
|
69
|
-
)
|
|
70
|
-
export const assertNsidString: AssertFn<NsidString> = ensureValidNsid
|
|
71
|
-
export const assertRecordKeyString: AssertFn<RecordKeyString> =
|
|
72
|
-
ensureValidRecordKey
|
|
73
|
-
export const assertTidString: AssertFn<TidString> = ensureValidTid
|
|
74
|
-
export const assertUriString: AssertFn<UriString> =
|
|
75
|
-
createAssertFunction<UriString>(isUriString, 'Invalid URI')
|
|
76
|
-
|
|
77
|
-
export const asAtIdentifierString: CastFn<AtIdentifierString> =
|
|
78
|
-
/*#__PURE__*/ createCastFunction(assertAtIdentifierString)
|
|
79
|
-
export const asAtUriString: CastFn<AtUriString> =
|
|
80
|
-
/*#__PURE__*/ createCastFunction(ensureValidAtUri)
|
|
81
|
-
export const asCidString: CastFn<CidString> =
|
|
82
|
-
/*#__PURE__*/ createCastFunction(ensureValidCidString)
|
|
83
|
-
export const asDatetimeString: CastFn<DatetimeString> =
|
|
84
|
-
/*#__PURE__*/ createCastFunction(ensureValidDatetime)
|
|
85
|
-
export const asDidString: CastFn<DidString> =
|
|
86
|
-
/*#__PURE__*/ createCastFunction(ensureValidDid)
|
|
87
|
-
export const asHandleString: CastFn<HandleString> =
|
|
88
|
-
/*#__PURE__*/ createCastFunction(ensureValidHandle)
|
|
89
|
-
export const asLanguageString: CastFn<LanguageString> =
|
|
90
|
-
/*#__PURE__*/ createCastFunction(assertLanguageString)
|
|
91
|
-
export const asNsidString: CastFn<NsidString> =
|
|
92
|
-
/*#__PURE__*/ createCastFunction(ensureValidNsid)
|
|
93
|
-
export const asRecordKeyString: CastFn<RecordKeyString> =
|
|
94
|
-
/*#__PURE__*/ createCastFunction(ensureValidRecordKey)
|
|
95
|
-
export const asTidString: CastFn<TidString> =
|
|
96
|
-
/*#__PURE__*/ createCastFunction(ensureValidTid)
|
|
97
|
-
export const asUriString: CastFn<UriString> =
|
|
98
|
-
/*#__PURE__*/ createCastFunction(assertUriString)
|
|
99
|
-
|
|
100
|
-
export { isLanguageString }
|
|
101
|
-
export const isAtIdentifierString: CheckFn<AtIdentifierString> =
|
|
102
|
-
/*#__PURE__*/ createCheckFunction(assertAtIdentifierString)
|
|
103
|
-
export const isAtUriString: CheckFn<AtUriString> =
|
|
104
|
-
/*#__PURE__*/ createCheckFunction(assertAtIdentifierString)
|
|
105
|
-
export const isCidString: CheckFn<CidString> =
|
|
106
|
-
/*#__PURE__*/ createCheckFunction(assertCidString)
|
|
107
|
-
export const isDatetimeString: CheckFn<DatetimeString> =
|
|
108
|
-
/*#__PURE__*/ createCheckFunction(assertDatetimeString)
|
|
109
|
-
export const isDidString: CheckFn<DidString> =
|
|
110
|
-
/*#__PURE__*/ createCheckFunction(assertDidString)
|
|
111
|
-
export const isHandleString: CheckFn<HandleString> =
|
|
112
|
-
/*#__PURE__*/ createCheckFunction(assertHandleString)
|
|
113
|
-
export const isNsidString: CheckFn<NsidString> =
|
|
114
|
-
/*#__PURE__*/ createCheckFunction(assertNsidString)
|
|
115
|
-
export const isRecordKeyString: CheckFn<RecordKeyString> =
|
|
116
|
-
/*#__PURE__*/ createCheckFunction(assertRecordKeyString)
|
|
117
|
-
export const isTidString: CheckFn<TidString> =
|
|
118
|
-
/*#__PURE__*/ createCheckFunction(assertTidString)
|
|
119
|
-
|
|
120
|
-
// String formatting types and utilities
|
|
121
|
-
|
|
122
|
-
export const STRING_FORMATS = Object.freeze([
|
|
123
|
-
'datetime',
|
|
124
|
-
'uri',
|
|
125
|
-
'at-uri',
|
|
126
|
-
'did',
|
|
127
|
-
'handle',
|
|
128
|
-
'at-identifier',
|
|
129
|
-
'nsid',
|
|
130
|
-
'cid',
|
|
131
|
-
'language',
|
|
132
|
-
'tid',
|
|
133
|
-
'record-key',
|
|
134
|
-
] as const)
|
|
135
|
-
|
|
136
|
-
export type StringFormat = (typeof STRING_FORMATS)[number]
|
|
137
|
-
|
|
138
|
-
export type InferStringFormat<F> =
|
|
139
|
-
//
|
|
140
|
-
F extends 'datetime'
|
|
141
|
-
? DatetimeString
|
|
142
|
-
: F extends 'uri'
|
|
143
|
-
? UriString
|
|
144
|
-
: F extends 'at-uri'
|
|
145
|
-
? AtUriString
|
|
146
|
-
: F extends 'did'
|
|
147
|
-
? DidString
|
|
148
|
-
: F extends 'handle'
|
|
149
|
-
? HandleString
|
|
150
|
-
: F extends 'at-identifier'
|
|
151
|
-
? AtIdentifierString
|
|
152
|
-
: F extends 'nsid'
|
|
153
|
-
? NsidString
|
|
154
|
-
: // LanguageString | CidString | TidString | RecordKeyString
|
|
155
|
-
string
|
|
156
|
-
|
|
157
|
-
const formatters = /*#__PURE__*/ new Map<StringFormat, (str: string) => void>([
|
|
158
|
-
['at-identifier', assertAtIdentifierString],
|
|
159
|
-
['at-uri', assertAtUriString],
|
|
160
|
-
['cid', assertCidString],
|
|
161
|
-
['datetime', assertDatetimeString],
|
|
162
|
-
['did', assertDidString],
|
|
163
|
-
['handle', assertHandleString],
|
|
164
|
-
['language', assertLanguageString],
|
|
165
|
-
['nsid', assertNsidString],
|
|
166
|
-
['record-key', assertRecordKeyString],
|
|
167
|
-
['tid', assertTidString],
|
|
168
|
-
['uri', assertUriString],
|
|
169
|
-
] as const)
|
|
96
|
+
export type InferStringFormat<F extends StringFormat> = F extends StringFormat
|
|
97
|
+
? StringFormats[F]
|
|
98
|
+
: never
|
|
170
99
|
|
|
171
100
|
/*@__NO_SIDE_EFFECTS__*/
|
|
172
|
-
export function
|
|
173
|
-
input:
|
|
101
|
+
export function isStringFormat<I extends string, F extends StringFormat>(
|
|
102
|
+
input: I,
|
|
174
103
|
format: F,
|
|
175
|
-
):
|
|
176
|
-
const
|
|
177
|
-
if (assertFn) assertFn(input)
|
|
104
|
+
): input is I & StringFormats[F] {
|
|
105
|
+
const formatVerifier = stringFormatVerifiers[format]
|
|
178
106
|
// Fool-proof
|
|
179
|
-
|
|
107
|
+
if (!formatVerifier) throw new TypeError(`Unknown string format: ${format}`)
|
|
108
|
+
|
|
109
|
+
return formatVerifier(input)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
113
|
+
export function assertStringFormat<I extends string, F extends StringFormat>(
|
|
114
|
+
input: I,
|
|
115
|
+
format: F,
|
|
116
|
+
): asserts input is I & StringFormats[F] {
|
|
117
|
+
if (!isStringFormat(input, format)) {
|
|
118
|
+
throw new TypeError(`Invalid string format (${format}): ${input}`)
|
|
119
|
+
}
|
|
180
120
|
}
|
|
121
|
+
|
|
122
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
123
|
+
export function asStringFormat<I extends string, F extends StringFormat>(
|
|
124
|
+
input: I,
|
|
125
|
+
format: F,
|
|
126
|
+
): I & StringFormats[F] {
|
|
127
|
+
assertStringFormat(input, format)
|
|
128
|
+
return input
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
132
|
+
export function ifStringFormat<I extends string, F extends StringFormat>(
|
|
133
|
+
input: I,
|
|
134
|
+
format: F,
|
|
135
|
+
): undefined | (I & StringFormats[F]) {
|
|
136
|
+
return isStringFormat(input, format) ? input : undefined
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export const STRING_FORMATS = /*#__PURE__*/ Object.freeze(
|
|
140
|
+
/*#__PURE__*/ Object.keys(stringFormatVerifiers),
|
|
141
|
+
) as readonly StringFormat[]
|