@atproto/lexicon 0.7.0 → 0.7.1

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 CHANGED
@@ -1,5 +1,18 @@
1
1
  # @atproto/lexicon
2
2
 
3
+ ## 0.7.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#4955](https://github.com/bluesky-social/atproto/pull/4955) [`20c5cc1`](https://github.com/bluesky-social/atproto/commit/20c5cc187aab538435c669c6e19a2d2f658af5f8) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Use datetime validation utility from `@atproto/syntax`
8
+
9
+ - [#4955](https://github.com/bluesky-social/atproto/pull/4955) [`20c5cc1`](https://github.com/bluesky-social/atproto/commit/20c5cc187aab538435c669c6e19a2d2f658af5f8) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Fix datetime validation that would reject valid atproto datetime strings (e.g. `1985-04-12T23:20:50.1234567890Z` & `1985-04-12T23:20:50.123+01:45`)
10
+
11
+ - [#4955](https://github.com/bluesky-social/atproto/pull/4955) [`20c5cc1`](https://github.com/bluesky-social/atproto/commit/20c5cc187aab538435c669c6e19a2d2f658af5f8) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Improve performances of string validation utilities (and drop use of deprecated functions)
12
+
13
+ - Updated dependencies [[`20c5cc1`](https://github.com/bluesky-social/atproto/commit/20c5cc187aab538435c669c6e19a2d2f658af5f8)]:
14
+ - @atproto/syntax@0.6.1
15
+
3
16
  ## 0.7.0
4
17
 
5
18
  ### Minor Changes
@@ -1,13 +1,13 @@
1
1
  import { ValidationResult } from '../types.js';
2
- export declare function datetime(path: string, value: string): ValidationResult;
3
- export declare function uri(path: string, value: string): ValidationResult;
4
- export declare function atUri(path: string, value: string): ValidationResult;
5
- export declare function did(path: string, value: string): ValidationResult;
6
- export declare function handle(path: string, value: string): ValidationResult;
7
- export declare function atIdentifier(path: string, value: string): ValidationResult;
8
- export declare function nsid(path: string, value: string): ValidationResult;
9
- export declare function cid(path: string, value: string): ValidationResult;
10
- export declare function language(path: string, value: string): ValidationResult;
11
- export declare function tid(path: string, value: string): ValidationResult;
12
- export declare function recordKey(path: string, value: string): ValidationResult;
2
+ export declare const datetime: <V extends string>(path: string, value: V) => ValidationResult<V & (`${string}-${string}-${string}T${string}:${string}:${string}Z` | `${string}-${string}-${string}T${string}:${string}:${string}+${string}:${string}` | `${string}-${string}-${string}T${string}:${string}:${string}-${string}:${string}`)>;
3
+ export declare const uri: <V extends string>(path: string, value: V) => ValidationResult<V & `${string}:${string}`>;
4
+ export declare const atUri: <V extends string>(path: string, value: V) => ValidationResult<V & (`at://did:${string}:${string}` | `at://${string}.${string}` | `at://did:${string}:${string}/${string}.${string}.${string}` | `at://${string}.${string}/${string}.${string}.${string}` | `at://did:${string}:${string}/${string}.${string}.${string}/${string}` | `at://${string}.${string}/${string}.${string}.${string}/${string}` | `at://did:${string}:${string}#/${string}` | `at://${string}.${string}#/${string}` | `at://did:${string}:${string}/${string}.${string}.${string}#/${string}` | `at://${string}.${string}/${string}.${string}.${string}#/${string}` | `at://did:${string}:${string}/${string}.${string}.${string}/${string}#/${string}` | `at://${string}.${string}/${string}.${string}.${string}/${string}#/${string}`)>;
5
+ export declare const did: <V extends string>(path: string, value: V) => ValidationResult<V & `did:${string}:${string}`>;
6
+ export declare const handle: <V extends string>(path: string, value: V) => ValidationResult<V & `${string}.${string}`>;
7
+ export declare const atIdentifier: <V extends string>(path: string, value: V) => ValidationResult<V & (`did:${string}:${string}` | `${string}.${string}`)>;
8
+ export declare const nsid: <V extends string>(path: string, value: V) => ValidationResult<V & `${string}.${string}.${string}`>;
9
+ export declare const cid: <V extends string>(path: string, value: V) => ValidationResult<V>;
10
+ export declare const language: (path: string, value: string) => ValidationResult<string>;
11
+ export declare const tid: <V extends string>(path: string, value: V) => ValidationResult<V>;
12
+ export declare const recordKey: <V extends string>(path: string, value: V) => ValidationResult<V>;
13
13
  //# sourceMappingURL=formats.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"formats.d.ts","sourceRoot":"","sources":["../../src/validators/formats.ts"],"names":[],"mappings":"AAaA,OAAO,EAAmB,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE/D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CActE;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAQjE;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAWnE;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAWjE;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAWpE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAc1E;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAYlE;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAUjE;AAGD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAUtE;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CASjE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAUvE"}
1
+ {"version":3,"file":"formats.d.ts","sourceRoot":"","sources":["../../src/validators/formats.ts"],"names":[],"mappings":"AAaA,OAAO,EAAmB,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE/D,eAAO,MAAM,QAAQ,GA6BjB,CAAC,SAAS,MAAM,QAAQ,MAAM,6QA1BjC,CAAA;AACD,eAAO,MAAM,GAAG,GAyBZ,CAAC,SAAS,MAAM,QAAQ,MAAM,0DAzB6B,CAAA;AAC/D,eAAO,MAAM,KAAK,GAwBd,CAAC,SAAS,MAAM,QAAQ,MAAM,kvBAxB2C,CAAA;AAC7E,eAAO,MAAM,GAAG,GAuBZ,CAAC,SAAS,MAAM,QAAQ,MAAM,8DAvBmC,CAAA;AACrE,eAAO,MAAM,MAAM,GAsBf,CAAC,SAAS,MAAM,QAAQ,MAAM,0DAtB4C,CAAA;AAC9E,eAAO,MAAM,YAAY,GAqBrB,CAAC,SAAS,MAAM,QAAQ,MAAM,wFAlBjC,CAAA;AACD,eAAO,MAAM,IAAI,GAiBb,CAAC,SAAS,MAAM,QAAQ,MAAM,oEAjBsC,CAAA;AACxE,eAAO,MAAM,GAAG,GAgBZ,CAAC,SAAS,MAAM,QAAQ,MAAM,kCAhBqC,CAAA;AACvE,eAAO,MAAM,QAAQ,SAmBX,MAAM,SAAS,MAAM,KAAK,gBAAgB,CAAC,MAAM,CAAC,AAhB3D,CAAA;AACD,eAAO,MAAM,GAAG,GAWZ,CAAC,SAAS,MAAM,QAAQ,MAAM,kCAXmC,CAAA;AACrE,eAAO,MAAM,SAAS,GAUlB,CAAC,SAAS,MAAM,QAAQ,MAAM,kCAPjC,CAAA"}
@@ -1,140 +1,35 @@
1
- import isoDatestringValidator from 'iso-datestring-validator';
2
- const { isValidISODateString } = isoDatestringValidator;
3
1
  import { CID } from 'multiformats/cid';
4
- import { validateLanguage } from '@atproto/common-web';
5
- import { ensureValidAtUri, ensureValidDid, ensureValidHandle, ensureValidRecordKey, isValidNsid, isValidTid, isValidUri, } from '@atproto/syntax';
2
+ import { isAtIdentifierString, isAtUriString, isDatetimeStringLenient, isValidDid, isValidHandle, isValidLanguage, isValidNsid, isValidRecordKey, isValidTid, isValidUri, } from '@atproto/syntax';
6
3
  import { ValidationError } from '../types.js';
7
- export function datetime(path, value) {
8
- try {
9
- if (!isValidISODateString(value)) {
10
- throw new Error();
4
+ export const datetime = createValidator(isDatetimeStringLenient, 'must be an valid atproto datetime (both RFC-3339 and ISO-8601)');
5
+ export const uri = createValidator(isValidUri, 'must be a uri');
6
+ export const atUri = createValidator(isAtUriString, 'must be a valid at-uri');
7
+ export const did = createValidator(isValidDid, 'must be a valid did');
8
+ export const handle = createValidator(isValidHandle, 'must be a valid handle');
9
+ export const atIdentifier = createValidator(isAtIdentifierString, 'must be a valid did or a handle');
10
+ export const nsid = createValidator(isValidNsid, 'must be a valid nsid');
11
+ export const cid = createValidator(isCidString, 'must be a cid string');
12
+ export const language = createValidator(isValidLanguage, 'must be a well-formed BCP 47 language tag');
13
+ export const tid = createValidator(isValidTid, 'must be a valid TID');
14
+ export const recordKey = createValidator(isValidRecordKey, 'must be a valid Record Key');
15
+ function createValidator(assertionFn, errorMessage) {
16
+ return (path, value) => {
17
+ if (assertionFn(value)) {
18
+ return { success: true, value };
11
19
  }
12
- }
13
- catch {
14
- return {
15
- success: false,
16
- error: new ValidationError(`${path} must be an valid atproto datetime (both RFC-3339 and ISO-8601)`),
17
- };
18
- }
19
- return { success: true, value };
20
- }
21
- export function uri(path, value) {
22
- if (!isValidUri(value)) {
23
- return {
24
- success: false,
25
- error: new ValidationError(`${path} must be a uri`),
26
- };
27
- }
28
- return { success: true, value };
29
- }
30
- export function atUri(path, value) {
31
- try {
32
- ensureValidAtUri(value);
33
- }
34
- catch {
35
20
  return {
36
21
  success: false,
37
- error: new ValidationError(`${path} must be a valid at-uri`),
22
+ error: new ValidationError(`${path} ${errorMessage}`),
38
23
  };
39
- }
40
- return { success: true, value };
41
- }
42
- export function did(path, value) {
43
- try {
44
- ensureValidDid(value);
45
- }
46
- catch {
47
- return {
48
- success: false,
49
- error: new ValidationError(`${path} must be a valid did`),
50
- };
51
- }
52
- return { success: true, value };
53
- }
54
- export function handle(path, value) {
55
- try {
56
- ensureValidHandle(value);
57
- }
58
- catch {
59
- return {
60
- success: false,
61
- error: new ValidationError(`${path} must be a valid handle`),
62
- };
63
- }
64
- return { success: true, value };
65
- }
66
- export function atIdentifier(path, value) {
67
- // We can discriminate based on the "did:" prefix
68
- if (value.startsWith('did:')) {
69
- const didResult = did(path, value);
70
- if (didResult.success)
71
- return didResult;
72
- }
73
- else {
74
- const handleResult = handle(path, value);
75
- if (handleResult.success)
76
- return handleResult;
77
- }
78
- return {
79
- success: false,
80
- error: new ValidationError(`${path} must be a valid did or a handle`),
81
- };
82
- }
83
- export function nsid(path, value) {
84
- if (isValidNsid(value)) {
85
- return {
86
- success: true,
87
- value,
88
- };
89
- }
90
- else {
91
- return {
92
- success: false,
93
- error: new ValidationError(`${path} must be a valid nsid`),
94
- };
95
- }
96
- }
97
- export function cid(path, value) {
98
- try {
99
- CID.parse(value);
100
- }
101
- catch {
102
- return {
103
- success: false,
104
- error: new ValidationError(`${path} must be a cid string`),
105
- };
106
- }
107
- return { success: true, value };
108
- }
109
- // The language format validates well-formed BCP 47 language tags: https://www.rfc-editor.org/info/bcp47
110
- export function language(path, value) {
111
- if (validateLanguage(value)) {
112
- return { success: true, value };
113
- }
114
- return {
115
- success: false,
116
- error: new ValidationError(`${path} must be a well-formed BCP 47 language tag`),
117
- };
118
- }
119
- export function tid(path, value) {
120
- if (isValidTid(value)) {
121
- return { success: true, value };
122
- }
123
- return {
124
- success: false,
125
- error: new ValidationError(`${path} must be a valid TID`),
126
24
  };
127
25
  }
128
- export function recordKey(path, value) {
26
+ function isCidString(v) {
129
27
  try {
130
- ensureValidRecordKey(value);
28
+ CID.parse(v);
29
+ return true;
131
30
  }
132
31
  catch {
133
- return {
134
- success: false,
135
- error: new ValidationError(`${path} must be a valid Record Key`),
136
- };
32
+ return false;
137
33
  }
138
- return { success: true, value };
139
34
  }
140
35
  //# sourceMappingURL=formats.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"formats.js","sourceRoot":"","sources":["../../src/validators/formats.ts"],"names":[],"mappings":"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","sourcesContent":["import isoDatestringValidator from 'iso-datestring-validator'\nconst { isValidISODateString } = isoDatestringValidator\nimport { CID } from 'multiformats/cid'\nimport { validateLanguage } from '@atproto/common-web'\nimport {\n ensureValidAtUri,\n ensureValidDid,\n ensureValidHandle,\n ensureValidRecordKey,\n isValidNsid,\n isValidTid,\n isValidUri,\n} from '@atproto/syntax'\nimport { ValidationError, ValidationResult } from '../types.js'\n\nexport function datetime(path: string, value: string): ValidationResult {\n try {\n if (!isValidISODateString(value)) {\n throw new Error()\n }\n } catch {\n return {\n success: false,\n error: new ValidationError(\n `${path} must be an valid atproto datetime (both RFC-3339 and ISO-8601)`,\n ),\n }\n }\n return { success: true, value }\n}\n\nexport function uri(path: string, value: string): ValidationResult {\n if (!isValidUri(value)) {\n return {\n success: false,\n error: new ValidationError(`${path} must be a uri`),\n }\n }\n return { success: true, value }\n}\n\nexport function atUri(path: string, value: string): ValidationResult {\n try {\n ensureValidAtUri(value)\n } catch {\n return {\n success: false,\n error: new ValidationError(`${path} must be a valid at-uri`),\n }\n }\n\n return { success: true, value }\n}\n\nexport function did(path: string, value: string): ValidationResult {\n try {\n ensureValidDid(value)\n } catch {\n return {\n success: false,\n error: new ValidationError(`${path} must be a valid did`),\n }\n }\n\n return { success: true, value }\n}\n\nexport function handle(path: string, value: string): ValidationResult {\n try {\n ensureValidHandle(value)\n } catch {\n return {\n success: false,\n error: new ValidationError(`${path} must be a valid handle`),\n }\n }\n\n return { success: true, value }\n}\n\nexport function atIdentifier(path: string, value: string): ValidationResult {\n // We can discriminate based on the \"did:\" prefix\n if (value.startsWith('did:')) {\n const didResult = did(path, value)\n if (didResult.success) return didResult\n } else {\n const handleResult = handle(path, value)\n if (handleResult.success) return handleResult\n }\n\n return {\n success: false,\n error: new ValidationError(`${path} must be a valid did or a handle`),\n }\n}\n\nexport function nsid(path: string, value: string): ValidationResult {\n if (isValidNsid(value)) {\n return {\n success: true,\n value,\n }\n } else {\n return {\n success: false,\n error: new ValidationError(`${path} must be a valid nsid`),\n }\n }\n}\n\nexport function cid(path: string, value: string): ValidationResult {\n try {\n CID.parse(value)\n } catch {\n return {\n success: false,\n error: new ValidationError(`${path} must be a cid string`),\n }\n }\n return { success: true, value }\n}\n\n// The language format validates well-formed BCP 47 language tags: https://www.rfc-editor.org/info/bcp47\nexport function language(path: string, value: string): ValidationResult {\n if (validateLanguage(value)) {\n return { success: true, value }\n }\n return {\n success: false,\n error: new ValidationError(\n `${path} must be a well-formed BCP 47 language tag`,\n ),\n }\n}\n\nexport function tid(path: string, value: string): ValidationResult {\n if (isValidTid(value)) {\n return { success: true, value }\n }\n\n return {\n success: false,\n error: new ValidationError(`${path} must be a valid TID`),\n }\n}\n\nexport function recordKey(path: string, value: string): ValidationResult {\n try {\n ensureValidRecordKey(value)\n } catch {\n return {\n success: false,\n error: new ValidationError(`${path} must be a valid Record Key`),\n }\n }\n return { success: true, value }\n}\n"]}
1
+ {"version":3,"file":"formats.js","sourceRoot":"","sources":["../../src/validators/formats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,uBAAuB,EACvB,UAAU,EACV,aAAa,EACb,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,UAAU,EACV,UAAU,GACX,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,eAAe,EAAoB,MAAM,aAAa,CAAA;AAE/D,MAAM,CAAC,MAAM,QAAQ,GAAG,eAAe,CACrC,uBAAuB,EACvB,gEAAgE,CACjE,CAAA;AACD,MAAM,CAAC,MAAM,GAAG,GAAG,eAAe,CAAC,UAAU,EAAE,eAAe,CAAC,CAAA;AAC/D,MAAM,CAAC,MAAM,KAAK,GAAG,eAAe,CAAC,aAAa,EAAE,wBAAwB,CAAC,CAAA;AAC7E,MAAM,CAAC,MAAM,GAAG,GAAG,eAAe,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAA;AACrE,MAAM,CAAC,MAAM,MAAM,GAAG,eAAe,CAAC,aAAa,EAAE,wBAAwB,CAAC,CAAA;AAC9E,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CACzC,oBAAoB,EACpB,iCAAiC,CAClC,CAAA;AACD,MAAM,CAAC,MAAM,IAAI,GAAG,eAAe,CAAC,WAAW,EAAE,sBAAsB,CAAC,CAAA;AACxE,MAAM,CAAC,MAAM,GAAG,GAAG,eAAe,CAAC,WAAW,EAAE,sBAAsB,CAAC,CAAA;AACvE,MAAM,CAAC,MAAM,QAAQ,GAAG,eAAe,CACrC,eAAe,EACf,2CAA2C,CAC5C,CAAA;AACD,MAAM,CAAC,MAAM,GAAG,GAAG,eAAe,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAA;AACrE,MAAM,CAAC,MAAM,SAAS,GAAG,eAAe,CACtC,gBAAgB,EAChB,4BAA4B,CAC7B,CAAA;AAYD,SAAS,eAAe,CACtB,WAAuC,EACvC,YAAoB;IAEpB,OAAO,CAAC,IAAY,EAAE,KAAa,EAAoB,EAAE;QACvD,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;QACjC,CAAC;QACD,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,IAAI,eAAe,CAAC,GAAG,IAAI,IAAI,YAAY,EAAE,CAAC;SACtD,CAAA;IACH,CAAC,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,CAAS;IAC5B,IAAI,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACZ,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC","sourcesContent":["import { CID } from 'multiformats/cid'\nimport {\n isAtIdentifierString,\n isAtUriString,\n isDatetimeStringLenient,\n isValidDid,\n isValidHandle,\n isValidLanguage,\n isValidNsid,\n isValidRecordKey,\n isValidTid,\n isValidUri,\n} from '@atproto/syntax'\nimport { ValidationError, ValidationResult } from '../types.js'\n\nexport const datetime = createValidator(\n isDatetimeStringLenient,\n 'must be an valid atproto datetime (both RFC-3339 and ISO-8601)',\n)\nexport const uri = createValidator(isValidUri, 'must be a uri')\nexport const atUri = createValidator(isAtUriString, 'must be a valid at-uri')\nexport const did = createValidator(isValidDid, 'must be a valid did')\nexport const handle = createValidator(isValidHandle, 'must be a valid handle')\nexport const atIdentifier = createValidator(\n isAtIdentifierString,\n 'must be a valid did or a handle',\n)\nexport const nsid = createValidator(isValidNsid, 'must be a valid nsid')\nexport const cid = createValidator(isCidString, 'must be a cid string')\nexport const language = createValidator(\n isValidLanguage,\n 'must be a well-formed BCP 47 language tag',\n)\nexport const tid = createValidator(isValidTid, 'must be a valid TID')\nexport const recordKey = createValidator(\n isValidRecordKey,\n 'must be a valid Record Key',\n)\n\n// Internal helpers\n\nfunction createValidator<T extends string>(\n assertionFn: (value: string) => value is T,\n errorMessage: string,\n): <V extends string>(path: string, value: V) => ValidationResult<V & T>\nfunction createValidator(\n assertionFn: (value: string) => boolean,\n errorMessage: string,\n): (path: string, value: string) => ValidationResult<string>\nfunction createValidator(\n assertionFn: (value: string) => boolean,\n errorMessage: string,\n) {\n return (path: string, value: string): ValidationResult => {\n if (assertionFn(value)) {\n return { success: true, value }\n }\n return {\n success: false,\n error: new ValidationError(`${path} ${errorMessage}`),\n }\n }\n}\n\nfunction isCidString(v: string): v is string {\n try {\n CID.parse(v)\n return true\n } catch {\n return false\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../src/validators/primitives.ts"],"names":[],"mappings":"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","sourcesContent":["import { CID } from 'multiformats/cid'\nimport { graphemeLen, utf8Len } from '@atproto/common-web'\nimport { Lexicons } from '../lexicons.js'\nimport {\n LexBoolean,\n LexBytes,\n LexInteger,\n LexString,\n LexUserType,\n ValidationError,\n ValidationResult,\n} from '../types.js'\nimport * as formats from './formats.js'\n\nexport function validate(\n lexicons: Lexicons,\n path: string,\n def: LexUserType,\n value: unknown,\n): ValidationResult {\n switch (def.type) {\n case 'boolean':\n return boolean(lexicons, path, def, value)\n case 'integer':\n return integer(lexicons, path, def, value)\n case 'string':\n return string(lexicons, path, def, value)\n case 'bytes':\n return bytes(lexicons, path, def, value)\n case 'cid-link':\n return cidLink(lexicons, path, def, value)\n case 'unknown':\n return unknown(lexicons, path, def, value)\n default:\n return {\n success: false,\n error: new ValidationError(`Unexpected lexicon type: ${def.type}`),\n }\n }\n}\n\nfunction boolean(\n lexicons: Lexicons,\n path: string,\n def: LexUserType,\n value: unknown,\n): ValidationResult {\n def = def as LexBoolean\n\n // type\n const type = typeof value\n if (type === 'undefined') {\n if (typeof def.default === 'boolean') {\n return { success: true, value: def.default }\n }\n return {\n success: false,\n error: new ValidationError(`${path} must be a boolean`),\n }\n } else if (type !== 'boolean') {\n return {\n success: false,\n error: new ValidationError(`${path} must be a boolean`),\n }\n }\n\n // const\n if (typeof def.const === 'boolean') {\n if (value !== def.const) {\n return {\n success: false,\n error: new ValidationError(`${path} must be ${def.const}`),\n }\n }\n }\n\n return { success: true, value }\n}\n\nfunction integer(\n lexicons: Lexicons,\n path: string,\n def: LexUserType,\n value: unknown,\n): ValidationResult {\n def = def as LexInteger\n\n // type\n const type = typeof value\n if (type === 'undefined') {\n if (typeof def.default === 'number') {\n return { success: true, value: def.default }\n }\n return {\n success: false,\n error: new ValidationError(`${path} must be an integer`),\n }\n } else if (!Number.isInteger(value)) {\n return {\n success: false,\n error: new ValidationError(`${path} must be an integer`),\n }\n }\n\n // const\n if (typeof def.const === 'number') {\n if (value !== def.const) {\n return {\n success: false,\n error: new ValidationError(`${path} must be ${def.const}`),\n }\n }\n }\n\n // enum\n if (Array.isArray(def.enum)) {\n if (!def.enum.includes(value as number)) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must be one of (${def.enum.join('|')})`,\n ),\n }\n }\n }\n\n // maximum\n if (typeof def.maximum === 'number') {\n if ((value as number) > def.maximum) {\n return {\n success: false,\n error: new ValidationError(\n `${path} can not be greater than ${def.maximum}`,\n ),\n }\n }\n }\n\n // minimum\n if (typeof def.minimum === 'number') {\n if ((value as number) < def.minimum) {\n return {\n success: false,\n error: new ValidationError(\n `${path} can not be less than ${def.minimum}`,\n ),\n }\n }\n }\n\n return { success: true, value }\n}\n\nfunction string(\n lexicons: Lexicons,\n path: string,\n def: LexUserType,\n value: unknown,\n): ValidationResult {\n def = def as LexString\n\n // type\n if (typeof value === 'undefined') {\n if (typeof def.default === 'string') {\n return { success: true, value: def.default }\n }\n return {\n success: false,\n error: new ValidationError(`${path} must be a string`),\n }\n } else if (typeof value !== 'string') {\n return {\n success: false,\n error: new ValidationError(`${path} must be a string`),\n }\n }\n\n // const\n if (typeof def.const === 'string') {\n if (value !== def.const) {\n return {\n success: false,\n error: new ValidationError(`${path} must be ${def.const}`),\n }\n }\n }\n\n // enum\n if (Array.isArray(def.enum)) {\n if (!def.enum.includes(value as string)) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must be one of (${def.enum.join('|')})`,\n ),\n }\n }\n }\n\n // maxLength and minLength\n if (typeof def.minLength === 'number' || typeof def.maxLength === 'number') {\n // If the JavaScript string length * 3 is below the maximum limit,\n // its UTF8 length (which <= .length * 3) will also be below.\n if (typeof def.minLength === 'number' && value.length * 3 < def.minLength) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be shorter than ${def.minLength} characters`,\n ),\n }\n }\n\n // If the JavaScript string length * 3 is within the maximum limit,\n // its UTF8 length (which <= .length * 3) will also be within.\n // When there's no minimal length, this lets us skip the UTF8 length check.\n let canSkipUtf8LenChecks = false\n if (\n typeof def.minLength === 'undefined' &&\n typeof def.maxLength === 'number' &&\n value.length * 3 <= def.maxLength\n ) {\n canSkipUtf8LenChecks = true\n }\n\n if (!canSkipUtf8LenChecks) {\n const len = utf8Len(value)\n\n if (typeof def.maxLength === 'number') {\n if (len > def.maxLength) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be longer than ${def.maxLength} characters`,\n ),\n }\n }\n }\n\n if (typeof def.minLength === 'number') {\n if (len < def.minLength) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be shorter than ${def.minLength} characters`,\n ),\n }\n }\n }\n }\n }\n\n // maxGraphemes and minGraphemes\n if (\n typeof def.maxGraphemes === 'number' ||\n typeof def.minGraphemes === 'number'\n ) {\n let needsMaxGraphemesCheck = false\n let needsMinGraphemesCheck = false\n\n if (typeof def.maxGraphemes === 'number') {\n if (value.length <= def.maxGraphemes) {\n // If the JavaScript string length (UTF-16) is within the maximum limit,\n // its grapheme length (which <= .length) will also be within.\n needsMaxGraphemesCheck = false\n } else {\n needsMaxGraphemesCheck = true\n }\n }\n\n if (typeof def.minGraphemes === 'number') {\n if (value.length < def.minGraphemes) {\n // If the JavaScript string length (UTF-16) is below the minimal limit,\n // its grapheme length (which <= .length) will also be below.\n // Fail early.\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be shorter than ${def.minGraphemes} graphemes`,\n ),\n }\n } else {\n needsMinGraphemesCheck = true\n }\n }\n\n if (needsMaxGraphemesCheck || needsMinGraphemesCheck) {\n const len = graphemeLen(value)\n\n if (typeof def.maxGraphemes === 'number') {\n if (len > def.maxGraphemes) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be longer than ${def.maxGraphemes} graphemes`,\n ),\n }\n }\n }\n\n if (typeof def.minGraphemes === 'number') {\n if (len < def.minGraphemes) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be shorter than ${def.minGraphemes} graphemes`,\n ),\n }\n }\n }\n }\n }\n\n if (typeof def.format === 'string') {\n switch (def.format) {\n case 'datetime':\n return formats.datetime(path, value)\n case 'uri':\n return formats.uri(path, value)\n case 'at-uri':\n return formats.atUri(path, value)\n case 'did':\n return formats.did(path, value)\n case 'handle':\n return formats.handle(path, value)\n case 'at-identifier':\n return formats.atIdentifier(path, value)\n case 'nsid':\n return formats.nsid(path, value)\n case 'cid':\n return formats.cid(path, value)\n case 'language':\n return formats.language(path, value)\n case 'tid':\n return formats.tid(path, value)\n case 'record-key':\n return formats.recordKey(path, value)\n }\n }\n\n return { success: true, value }\n}\n\nfunction bytes(\n lexicons: Lexicons,\n path: string,\n def: LexUserType,\n value: unknown,\n): ValidationResult {\n def = def as LexBytes\n\n if (!value || !(value instanceof Uint8Array)) {\n return {\n success: false,\n error: new ValidationError(`${path} must be a byte array`),\n }\n }\n\n // maxLength\n if (typeof def.maxLength === 'number') {\n if (value.byteLength > def.maxLength) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be larger than ${def.maxLength} bytes`,\n ),\n }\n }\n }\n\n // minLength\n if (typeof def.minLength === 'number') {\n if (value.byteLength < def.minLength) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be smaller than ${def.minLength} bytes`,\n ),\n }\n }\n }\n\n return { success: true, value }\n}\n\nfunction cidLink(\n lexicons: Lexicons,\n path: string,\n def: LexUserType,\n value: unknown,\n): ValidationResult {\n if (CID.asCID(value) === null) {\n return {\n success: false,\n error: new ValidationError(`${path} must be a CID`),\n }\n }\n\n return { success: true, value }\n}\n\nfunction unknown(\n lexicons: Lexicons,\n path: string,\n def: LexUserType,\n value: unknown,\n): ValidationResult {\n // type\n if (!value || typeof value !== 'object') {\n return {\n success: false,\n error: new ValidationError(`${path} must be an object`),\n }\n }\n\n return { success: true, value }\n}\n"]}
1
+ {"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../src/validators/primitives.ts"],"names":[],"mappings":"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","sourcesContent":["import { CID } from 'multiformats/cid'\nimport { graphemeLen, utf8Len } from '@atproto/common-web'\nimport { Lexicons } from '../lexicons.js'\nimport {\n LexBoolean,\n LexBytes,\n LexInteger,\n LexString,\n LexUserType,\n ValidationError,\n ValidationResult,\n} from '../types.js'\nimport * as formats from './formats.js'\n\nexport function validate(\n lexicons: Lexicons,\n path: string,\n def: LexUserType,\n value: unknown,\n): ValidationResult {\n switch (def.type) {\n case 'boolean':\n return boolean(lexicons, path, def, value)\n case 'integer':\n return integer(lexicons, path, def, value)\n case 'string':\n return string(lexicons, path, def, value)\n case 'bytes':\n return bytes(lexicons, path, def, value)\n case 'cid-link':\n return cidLink(lexicons, path, def, value)\n case 'unknown':\n return unknown(lexicons, path, def, value)\n default:\n return {\n success: false,\n error: new ValidationError(`Unexpected lexicon type: ${def.type}`),\n }\n }\n}\n\nfunction boolean(\n lexicons: Lexicons,\n path: string,\n def: LexUserType,\n value: unknown,\n): ValidationResult {\n def = def as LexBoolean\n\n // type\n const type = typeof value\n if (type === 'undefined') {\n if (typeof def.default === 'boolean') {\n return { success: true, value: def.default }\n }\n return {\n success: false,\n error: new ValidationError(`${path} must be a boolean`),\n }\n } else if (type !== 'boolean') {\n return {\n success: false,\n error: new ValidationError(`${path} must be a boolean`),\n }\n }\n\n // const\n if (typeof def.const === 'boolean') {\n if (value !== def.const) {\n return {\n success: false,\n error: new ValidationError(`${path} must be ${def.const}`),\n }\n }\n }\n\n return { success: true, value }\n}\n\nfunction integer(\n lexicons: Lexicons,\n path: string,\n def: LexUserType,\n value: unknown,\n): ValidationResult {\n def = def as LexInteger\n\n // type\n const type = typeof value\n if (type === 'undefined') {\n if (typeof def.default === 'number') {\n return { success: true, value: def.default }\n }\n return {\n success: false,\n error: new ValidationError(`${path} must be an integer`),\n }\n } else if (!Number.isInteger(value)) {\n return {\n success: false,\n error: new ValidationError(`${path} must be an integer`),\n }\n }\n\n // const\n if (typeof def.const === 'number') {\n if (value !== def.const) {\n return {\n success: false,\n error: new ValidationError(`${path} must be ${def.const}`),\n }\n }\n }\n\n // enum\n if (Array.isArray(def.enum)) {\n if (!def.enum.includes(value as number)) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must be one of (${def.enum.join('|')})`,\n ),\n }\n }\n }\n\n // maximum\n if (typeof def.maximum === 'number') {\n if ((value as number) > def.maximum) {\n return {\n success: false,\n error: new ValidationError(\n `${path} can not be greater than ${def.maximum}`,\n ),\n }\n }\n }\n\n // minimum\n if (typeof def.minimum === 'number') {\n if ((value as number) < def.minimum) {\n return {\n success: false,\n error: new ValidationError(\n `${path} can not be less than ${def.minimum}`,\n ),\n }\n }\n }\n\n return { success: true, value }\n}\n\nfunction string(\n lexicons: Lexicons,\n path: string,\n def: LexUserType,\n value: unknown,\n): ValidationResult<string> {\n def = def as LexString\n\n // type\n if (typeof value === 'undefined') {\n if (typeof def.default === 'string') {\n return { success: true, value: def.default }\n }\n return {\n success: false,\n error: new ValidationError(`${path} must be a string`),\n }\n } else if (typeof value !== 'string') {\n return {\n success: false,\n error: new ValidationError(`${path} must be a string`),\n }\n }\n\n // const\n if (typeof def.const === 'string') {\n if (value !== def.const) {\n return {\n success: false,\n error: new ValidationError(`${path} must be ${def.const}`),\n }\n }\n }\n\n // enum\n if (Array.isArray(def.enum)) {\n if (!def.enum.includes(value as string)) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must be one of (${def.enum.join('|')})`,\n ),\n }\n }\n }\n\n // maxLength and minLength\n if (typeof def.minLength === 'number' || typeof def.maxLength === 'number') {\n // If the JavaScript string length * 3 is below the maximum limit,\n // its UTF8 length (which <= .length * 3) will also be below.\n if (typeof def.minLength === 'number' && value.length * 3 < def.minLength) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be shorter than ${def.minLength} characters`,\n ),\n }\n }\n\n // If the JavaScript string length * 3 is within the maximum limit,\n // its UTF8 length (which <= .length * 3) will also be within.\n // When there's no minimal length, this lets us skip the UTF8 length check.\n let canSkipUtf8LenChecks = false\n if (\n typeof def.minLength === 'undefined' &&\n typeof def.maxLength === 'number' &&\n value.length * 3 <= def.maxLength\n ) {\n canSkipUtf8LenChecks = true\n }\n\n if (!canSkipUtf8LenChecks) {\n const len = utf8Len(value)\n\n if (typeof def.maxLength === 'number') {\n if (len > def.maxLength) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be longer than ${def.maxLength} characters`,\n ),\n }\n }\n }\n\n if (typeof def.minLength === 'number') {\n if (len < def.minLength) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be shorter than ${def.minLength} characters`,\n ),\n }\n }\n }\n }\n }\n\n // maxGraphemes and minGraphemes\n if (\n typeof def.maxGraphemes === 'number' ||\n typeof def.minGraphemes === 'number'\n ) {\n let needsMaxGraphemesCheck = false\n let needsMinGraphemesCheck = false\n\n if (typeof def.maxGraphemes === 'number') {\n if (value.length <= def.maxGraphemes) {\n // If the JavaScript string length (UTF-16) is within the maximum limit,\n // its grapheme length (which <= .length) will also be within.\n needsMaxGraphemesCheck = false\n } else {\n needsMaxGraphemesCheck = true\n }\n }\n\n if (typeof def.minGraphemes === 'number') {\n if (value.length < def.minGraphemes) {\n // If the JavaScript string length (UTF-16) is below the minimal limit,\n // its grapheme length (which <= .length) will also be below.\n // Fail early.\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be shorter than ${def.minGraphemes} graphemes`,\n ),\n }\n } else {\n needsMinGraphemesCheck = true\n }\n }\n\n if (needsMaxGraphemesCheck || needsMinGraphemesCheck) {\n const len = graphemeLen(value)\n\n if (typeof def.maxGraphemes === 'number') {\n if (len > def.maxGraphemes) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be longer than ${def.maxGraphemes} graphemes`,\n ),\n }\n }\n }\n\n if (typeof def.minGraphemes === 'number') {\n if (len < def.minGraphemes) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be shorter than ${def.minGraphemes} graphemes`,\n ),\n }\n }\n }\n }\n }\n\n if (typeof def.format === 'string') {\n switch (def.format) {\n case 'datetime':\n return formats.datetime(path, value)\n case 'uri':\n return formats.uri(path, value)\n case 'at-uri':\n return formats.atUri(path, value)\n case 'did':\n return formats.did(path, value)\n case 'handle':\n return formats.handle(path, value)\n case 'at-identifier':\n return formats.atIdentifier(path, value)\n case 'nsid':\n return formats.nsid(path, value)\n case 'cid':\n return formats.cid(path, value)\n case 'language':\n return formats.language(path, value)\n case 'tid':\n return formats.tid(path, value)\n case 'record-key':\n return formats.recordKey(path, value)\n }\n }\n\n return { success: true, value }\n}\n\nfunction bytes(\n lexicons: Lexicons,\n path: string,\n def: LexUserType,\n value: unknown,\n): ValidationResult {\n def = def as LexBytes\n\n if (!value || !(value instanceof Uint8Array)) {\n return {\n success: false,\n error: new ValidationError(`${path} must be a byte array`),\n }\n }\n\n // maxLength\n if (typeof def.maxLength === 'number') {\n if (value.byteLength > def.maxLength) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be larger than ${def.maxLength} bytes`,\n ),\n }\n }\n }\n\n // minLength\n if (typeof def.minLength === 'number') {\n if (value.byteLength < def.minLength) {\n return {\n success: false,\n error: new ValidationError(\n `${path} must not be smaller than ${def.minLength} bytes`,\n ),\n }\n }\n }\n\n return { success: true, value }\n}\n\nfunction cidLink(\n lexicons: Lexicons,\n path: string,\n def: LexUserType,\n value: unknown,\n): ValidationResult {\n if (CID.asCID(value) === null) {\n return {\n success: false,\n error: new ValidationError(`${path} must be a CID`),\n }\n }\n\n return { success: true, value }\n}\n\nfunction unknown(\n lexicons: Lexicons,\n path: string,\n def: LexUserType,\n value: unknown,\n): ValidationResult {\n // type\n if (!value || typeof value !== 'object') {\n return {\n success: false,\n error: new ValidationError(`${path} must be an object`),\n }\n }\n\n return { success: true, value }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/lexicon",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "engines": {
5
5
  "node": ">=22"
6
6
  },
@@ -17,11 +17,10 @@
17
17
  "directory": "packages/lexicon"
18
18
  },
19
19
  "dependencies": {
20
- "iso-datestring-validator": "^2.2.2",
21
20
  "multiformats": "^13.0.0",
22
21
  "zod": "^3.23.8",
23
- "@atproto/common-web": "^0.5.0",
24
- "@atproto/syntax": "^0.6.0"
22
+ "@atproto/syntax": "^0.6.1",
23
+ "@atproto/common-web": "^0.5.0"
25
24
  },
26
25
  "devDependencies": {
27
26
  "jest": "^30.0.0",
@@ -1,157 +1,72 @@
1
- import isoDatestringValidator from 'iso-datestring-validator'
2
- const { isValidISODateString } = isoDatestringValidator
3
1
  import { CID } from 'multiformats/cid'
4
- import { validateLanguage } from '@atproto/common-web'
5
2
  import {
6
- ensureValidAtUri,
7
- ensureValidDid,
8
- ensureValidHandle,
9
- ensureValidRecordKey,
3
+ isAtIdentifierString,
4
+ isAtUriString,
5
+ isDatetimeStringLenient,
6
+ isValidDid,
7
+ isValidHandle,
8
+ isValidLanguage,
10
9
  isValidNsid,
10
+ isValidRecordKey,
11
11
  isValidTid,
12
12
  isValidUri,
13
13
  } from '@atproto/syntax'
14
14
  import { ValidationError, ValidationResult } from '../types.js'
15
15
 
16
- export function datetime(path: string, value: string): ValidationResult {
17
- try {
18
- if (!isValidISODateString(value)) {
19
- throw new Error()
20
- }
21
- } catch {
22
- return {
23
- success: false,
24
- error: new ValidationError(
25
- `${path} must be an valid atproto datetime (both RFC-3339 and ISO-8601)`,
26
- ),
27
- }
28
- }
29
- return { success: true, value }
30
- }
31
-
32
- export function uri(path: string, value: string): ValidationResult {
33
- if (!isValidUri(value)) {
34
- return {
35
- success: false,
36
- error: new ValidationError(`${path} must be a uri`),
37
- }
38
- }
39
- return { success: true, value }
40
- }
41
-
42
- export function atUri(path: string, value: string): ValidationResult {
43
- try {
44
- ensureValidAtUri(value)
45
- } catch {
46
- return {
47
- success: false,
48
- error: new ValidationError(`${path} must be a valid at-uri`),
49
- }
50
- }
51
-
52
- return { success: true, value }
53
- }
54
-
55
- export function did(path: string, value: string): ValidationResult {
56
- try {
57
- ensureValidDid(value)
58
- } catch {
59
- return {
60
- success: false,
61
- error: new ValidationError(`${path} must be a valid did`),
62
- }
63
- }
64
-
65
- return { success: true, value }
66
- }
67
-
68
- export function handle(path: string, value: string): ValidationResult {
69
- try {
70
- ensureValidHandle(value)
71
- } catch {
72
- return {
73
- success: false,
74
- error: new ValidationError(`${path} must be a valid handle`),
75
- }
76
- }
77
-
78
- return { success: true, value }
79
- }
80
-
81
- export function atIdentifier(path: string, value: string): ValidationResult {
82
- // We can discriminate based on the "did:" prefix
83
- if (value.startsWith('did:')) {
84
- const didResult = did(path, value)
85
- if (didResult.success) return didResult
86
- } else {
87
- const handleResult = handle(path, value)
88
- if (handleResult.success) return handleResult
89
- }
90
-
91
- return {
92
- success: false,
93
- error: new ValidationError(`${path} must be a valid did or a handle`),
94
- }
95
- }
96
-
97
- export function nsid(path: string, value: string): ValidationResult {
98
- if (isValidNsid(value)) {
99
- return {
100
- success: true,
101
- value,
102
- }
103
- } else {
104
- return {
105
- success: false,
106
- error: new ValidationError(`${path} must be a valid nsid`),
16
+ export const datetime = createValidator(
17
+ isDatetimeStringLenient,
18
+ 'must be an valid atproto datetime (both RFC-3339 and ISO-8601)',
19
+ )
20
+ export const uri = createValidator(isValidUri, 'must be a uri')
21
+ export const atUri = createValidator(isAtUriString, 'must be a valid at-uri')
22
+ export const did = createValidator(isValidDid, 'must be a valid did')
23
+ export const handle = createValidator(isValidHandle, 'must be a valid handle')
24
+ export const atIdentifier = createValidator(
25
+ isAtIdentifierString,
26
+ 'must be a valid did or a handle',
27
+ )
28
+ export const nsid = createValidator(isValidNsid, 'must be a valid nsid')
29
+ export const cid = createValidator(isCidString, 'must be a cid string')
30
+ export const language = createValidator(
31
+ isValidLanguage,
32
+ 'must be a well-formed BCP 47 language tag',
33
+ )
34
+ export const tid = createValidator(isValidTid, 'must be a valid TID')
35
+ export const recordKey = createValidator(
36
+ isValidRecordKey,
37
+ 'must be a valid Record Key',
38
+ )
39
+
40
+ // Internal helpers
41
+
42
+ function createValidator<T extends string>(
43
+ assertionFn: (value: string) => value is T,
44
+ errorMessage: string,
45
+ ): <V extends string>(path: string, value: V) => ValidationResult<V & T>
46
+ function createValidator(
47
+ assertionFn: (value: string) => boolean,
48
+ errorMessage: string,
49
+ ): (path: string, value: string) => ValidationResult<string>
50
+ function createValidator(
51
+ assertionFn: (value: string) => boolean,
52
+ errorMessage: string,
53
+ ) {
54
+ return (path: string, value: string): ValidationResult => {
55
+ if (assertionFn(value)) {
56
+ return { success: true, value }
107
57
  }
108
- }
109
- }
110
-
111
- export function cid(path: string, value: string): ValidationResult {
112
- try {
113
- CID.parse(value)
114
- } catch {
115
58
  return {
116
59
  success: false,
117
- error: new ValidationError(`${path} must be a cid string`),
60
+ error: new ValidationError(`${path} ${errorMessage}`),
118
61
  }
119
62
  }
120
- return { success: true, value }
121
- }
122
-
123
- // The language format validates well-formed BCP 47 language tags: https://www.rfc-editor.org/info/bcp47
124
- export function language(path: string, value: string): ValidationResult {
125
- if (validateLanguage(value)) {
126
- return { success: true, value }
127
- }
128
- return {
129
- success: false,
130
- error: new ValidationError(
131
- `${path} must be a well-formed BCP 47 language tag`,
132
- ),
133
- }
134
63
  }
135
64
 
136
- export function tid(path: string, value: string): ValidationResult {
137
- if (isValidTid(value)) {
138
- return { success: true, value }
139
- }
140
-
141
- return {
142
- success: false,
143
- error: new ValidationError(`${path} must be a valid TID`),
144
- }
145
- }
146
-
147
- export function recordKey(path: string, value: string): ValidationResult {
65
+ function isCidString(v: string): v is string {
148
66
  try {
149
- ensureValidRecordKey(value)
67
+ CID.parse(v)
68
+ return true
150
69
  } catch {
151
- return {
152
- success: false,
153
- error: new ValidationError(`${path} must be a valid Record Key`),
154
- }
70
+ return false
155
71
  }
156
- return { success: true, value }
157
72
  }
@@ -156,7 +156,7 @@ function string(
156
156
  path: string,
157
157
  def: LexUserType,
158
158
  value: unknown,
159
- ): ValidationResult {
159
+ ): ValidationResult<string> {
160
160
  def = def as LexString
161
161
 
162
162
  // type