@atproto/lex-schema 0.0.19 → 0.1.0-next.0

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.
Files changed (124) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/core/$type.js +2 -6
  3. package/dist/core/$type.js.map +1 -1
  4. package/dist/core/record-key.js +4 -8
  5. package/dist/core/record-key.js.map +1 -1
  6. package/dist/core/result.js +6 -14
  7. package/dist/core/result.js.map +1 -1
  8. package/dist/core/schema.js +16 -20
  9. package/dist/core/schema.js.map +1 -1
  10. package/dist/core/standard-schema.js +5 -10
  11. package/dist/core/standard-schema.js.map +1 -1
  12. package/dist/core/string-format.d.ts.map +1 -1
  13. package/dist/core/string-format.js +37 -61
  14. package/dist/core/string-format.js.map +1 -1
  15. package/dist/core/types.js +1 -2
  16. package/dist/core/validation-error.js +14 -25
  17. package/dist/core/validation-error.js.map +1 -1
  18. package/dist/core/validation-issue.js +13 -41
  19. package/dist/core/validation-issue.js.map +1 -1
  20. package/dist/core/validator.js +19 -28
  21. package/dist/core/validator.js.map +1 -1
  22. package/dist/core.js +9 -12
  23. package/dist/core.js.map +1 -1
  24. package/dist/external.js +3 -6
  25. package/dist/external.js.map +1 -1
  26. package/dist/helpers.js +5 -9
  27. package/dist/helpers.js.map +1 -1
  28. package/dist/index.js +3 -7
  29. package/dist/index.js.map +1 -1
  30. package/dist/schema/array.js +5 -11
  31. package/dist/schema/array.js.map +1 -1
  32. package/dist/schema/blob.js +10 -17
  33. package/dist/schema/blob.js.map +1 -1
  34. package/dist/schema/boolean.js +8 -9
  35. package/dist/schema/boolean.js.map +1 -1
  36. package/dist/schema/bytes.js +7 -12
  37. package/dist/schema/bytes.js.map +1 -1
  38. package/dist/schema/cid.js +7 -12
  39. package/dist/schema/cid.js.map +1 -1
  40. package/dist/schema/custom.js +5 -13
  41. package/dist/schema/custom.js.map +1 -1
  42. package/dist/schema/dict.js +6 -13
  43. package/dist/schema/dict.js.map +1 -1
  44. package/dist/schema/discriminated-union.js +10 -18
  45. package/dist/schema/discriminated-union.js.map +1 -1
  46. package/dist/schema/enum.js +6 -11
  47. package/dist/schema/enum.js.map +1 -1
  48. package/dist/schema/integer.js +5 -10
  49. package/dist/schema/integer.js.map +1 -1
  50. package/dist/schema/intersection.js +4 -11
  51. package/dist/schema/intersection.js.map +1 -1
  52. package/dist/schema/lex-map.js +13 -14
  53. package/dist/schema/lex-map.js.map +1 -1
  54. package/dist/schema/lex-value.js +11 -12
  55. package/dist/schema/lex-value.js.map +1 -1
  56. package/dist/schema/literal.js +4 -10
  57. package/dist/schema/literal.js.map +1 -1
  58. package/dist/schema/never.js +8 -9
  59. package/dist/schema/never.js.map +1 -1
  60. package/dist/schema/null.js +9 -10
  61. package/dist/schema/null.js.map +1 -1
  62. package/dist/schema/nullable.js +5 -10
  63. package/dist/schema/nullable.js.map +1 -1
  64. package/dist/schema/object.js +8 -14
  65. package/dist/schema/object.js.map +1 -1
  66. package/dist/schema/optional.js +5 -10
  67. package/dist/schema/optional.js.map +1 -1
  68. package/dist/schema/params.js +39 -44
  69. package/dist/schema/params.js.map +1 -1
  70. package/dist/schema/payload.js +5 -13
  71. package/dist/schema/payload.js.map +1 -1
  72. package/dist/schema/permission-set.js +2 -10
  73. package/dist/schema/permission-set.js.map +1 -1
  74. package/dist/schema/permission.js +2 -9
  75. package/dist/schema/permission.js.map +1 -1
  76. package/dist/schema/procedure.js +3 -13
  77. package/dist/schema/procedure.js.map +1 -1
  78. package/dist/schema/query.js +3 -12
  79. package/dist/schema/query.js.map +1 -1
  80. package/dist/schema/record.js +15 -24
  81. package/dist/schema/record.js.map +1 -1
  82. package/dist/schema/ref.js +4 -9
  83. package/dist/schema/ref.js.map +1 -1
  84. package/dist/schema/refine.js +3 -6
  85. package/dist/schema/refine.js.map +1 -1
  86. package/dist/schema/regexp.js +4 -11
  87. package/dist/schema/regexp.js.map +1 -1
  88. package/dist/schema/string.js +15 -26
  89. package/dist/schema/string.js.map +1 -1
  90. package/dist/schema/subscription.js +3 -12
  91. package/dist/schema/subscription.js.map +1 -1
  92. package/dist/schema/token.js +5 -11
  93. package/dist/schema/token.js.map +1 -1
  94. package/dist/schema/typed-object.js +11 -18
  95. package/dist/schema/typed-object.js.map +1 -1
  96. package/dist/schema/typed-ref.js +4 -9
  97. package/dist/schema/typed-ref.js.map +1 -1
  98. package/dist/schema/typed-union.js +8 -15
  99. package/dist/schema/typed-union.js.map +1 -1
  100. package/dist/schema/union.js +5 -11
  101. package/dist/schema/union.js.map +1 -1
  102. package/dist/schema/unknown.js +8 -9
  103. package/dist/schema/unknown.js.map +1 -1
  104. package/dist/schema/with-default.js +4 -11
  105. package/dist/schema/with-default.js.map +1 -1
  106. package/dist/schema.js +38 -41
  107. package/dist/schema.js.map +1 -1
  108. package/dist/util/array-agg.js +1 -4
  109. package/dist/util/array-agg.js.map +1 -1
  110. package/dist/util/assertion-util.js +1 -2
  111. package/dist/util/if-any.js +1 -2
  112. package/dist/util/lazy-property.js +1 -4
  113. package/dist/util/lazy-property.js.map +1 -1
  114. package/dist/util/memoize.js +2 -6
  115. package/dist/util/memoize.js.map +1 -1
  116. package/package.json +7 -8
  117. package/src/core/string-format.ts +2 -1
  118. package/src/core/validation-issue.ts +1 -1
  119. package/src/helpers.test.ts +52 -52
  120. package/src/schema/record.test.ts +2 -2
  121. package/src/schema/ref.test.ts +1 -1
  122. package/src/schema/string.test.ts +6 -6
  123. package/src/schema/subscription.test.ts +4 -4
  124. package/src/schema/typed-object.test.ts +2 -2
@@ -1,15 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.STRING_FORMATS = exports.isUriString = exports.isTidString = exports.isRecordKeyString = exports.isNsidString = exports.isLanguageString = exports.isHandleString = exports.isDidString = exports.isCidString = exports.isAtUriString = exports.ifAtUriString = exports.assertAtUriString = exports.asAtUriString = exports.toDatetimeString = exports.currentDatetimeString = exports.isDatetimeString = exports.ifDatetimeString = exports.assertDatetimeString = exports.asDatetimeString = exports.isHandleIdentifier = exports.isDidIdentifier = exports.isAtIdentifierString = exports.ifAtIdentifierString = exports.assertAtIdentifierString = exports.asAtIdentifierString = void 0;
4
- exports.isDatetimeStringLenient = isDatetimeStringLenient;
5
- exports.isAtUriStringLenient = isAtUriStringLenient;
6
- exports.isStringFormat = isStringFormat;
7
- exports.assertStringFormat = assertStringFormat;
8
- exports.asStringFormat = asStringFormat;
9
- exports.ifStringFormat = ifStringFormat;
10
- const iso_datestring_validator_1 = require("iso-datestring-validator");
11
- const lex_data_1 = require("@atproto/lex-data");
12
- const syntax_1 = require("@atproto/syntax");
1
+ import isoDatestringValidator from 'iso-datestring-validator';
2
+ const { isValidISODateString } = isoDatestringValidator;
3
+ import { validateCidString } from '@atproto/lex-data';
4
+ import { isAtIdentifierString, isAtUriString, isDatetimeString, isValidDid, isValidHandle, isValidLanguage, isValidNsid, isValidRecordKey, isValidTid, isValidUri, } from '@atproto/syntax';
13
5
  // -----------------------------------------------------------------------------
14
6
  // Individual string format types and type guards
15
7
  // -----------------------------------------------------------------------------
@@ -17,33 +9,23 @@ const syntax_1 = require("@atproto/syntax");
17
9
  // documentation for types and utilities that are already well-defined there.
18
10
  // @TODO rework other string formats in @atproto/syntax to follow this pattern
19
11
  // and re-export here, e.g. language tags, NSIDs, record keys, etc.
20
- var syntax_2 = require("@atproto/syntax");
21
- Object.defineProperty(exports, "asAtIdentifierString", { enumerable: true, get: function () { return syntax_2.asAtIdentifierString; } });
22
- Object.defineProperty(exports, "assertAtIdentifierString", { enumerable: true, get: function () { return syntax_2.assertAtIdentifierString; } });
23
- Object.defineProperty(exports, "ifAtIdentifierString", { enumerable: true, get: function () { return syntax_2.ifAtIdentifierString; } });
24
- Object.defineProperty(exports, "isAtIdentifierString", { enumerable: true, get: function () { return syntax_2.isAtIdentifierString; } });
12
+ export { asAtIdentifierString, assertAtIdentifierString, ifAtIdentifierString, isAtIdentifierString, } from '@atproto/syntax';
25
13
  // AtIdentifierString utilities
26
- var syntax_3 = require("@atproto/syntax");
27
- Object.defineProperty(exports, "isDidIdentifier", { enumerable: true, get: function () { return syntax_3.isDidIdentifier; } });
28
- Object.defineProperty(exports, "isHandleIdentifier", { enumerable: true, get: function () { return syntax_3.isHandleIdentifier; } });
29
- var syntax_4 = require("@atproto/syntax");
30
- Object.defineProperty(exports, "asDatetimeString", { enumerable: true, get: function () { return syntax_4.asDatetimeString; } });
31
- Object.defineProperty(exports, "assertDatetimeString", { enumerable: true, get: function () { return syntax_4.assertDatetimeString; } });
32
- Object.defineProperty(exports, "ifDatetimeString", { enumerable: true, get: function () { return syntax_4.ifDatetimeString; } });
33
- Object.defineProperty(exports, "isDatetimeString", { enumerable: true, get: function () { return syntax_4.isDatetimeString; } });
14
+ export { isDidIdentifier, isHandleIdentifier } from '@atproto/syntax';
15
+ export { asDatetimeString, assertDatetimeString, ifDatetimeString, isDatetimeString, } from '@atproto/syntax';
34
16
  /**
35
17
  * Matches any ISO-ish datetime string. This is a more lenient check than
36
18
  * the strict {@link isDatetimeString} guard, which only allows datetimes that
37
19
  * fully conform to the AT Protocol specification (e.g. must include timezone).
38
20
  */
39
- function isDatetimeStringLenient(input) {
21
+ export function isDatetimeStringLenient(input) {
40
22
  // @NOTE the returned type assertion is inaccurate wrt. the DatetimeString
41
23
  // type definition. A more accurate solution would be to use a branded type
42
24
  // instead of a template literal for the "datetime" format
43
25
  if (typeof input !== 'string')
44
26
  return false;
45
27
  try {
46
- return (0, iso_datestring_validator_1.isValidISODateString)(input);
28
+ return isValidISODateString(input);
47
29
  }
48
30
  catch {
49
31
  // @NOTE isValidISODateString throws on some inputs
@@ -51,22 +33,16 @@ function isDatetimeStringLenient(input) {
51
33
  }
52
34
  }
53
35
  // DatetimeString utilities
54
- var syntax_5 = require("@atproto/syntax");
55
- Object.defineProperty(exports, "currentDatetimeString", { enumerable: true, get: function () { return syntax_5.currentDatetimeString; } });
56
- Object.defineProperty(exports, "toDatetimeString", { enumerable: true, get: function () { return syntax_5.toDatetimeString; } });
57
- var syntax_6 = require("@atproto/syntax");
58
- Object.defineProperty(exports, "asAtUriString", { enumerable: true, get: function () { return syntax_6.asAtUriString; } });
59
- Object.defineProperty(exports, "assertAtUriString", { enumerable: true, get: function () { return syntax_6.assertAtUriString; } });
60
- Object.defineProperty(exports, "ifAtUriString", { enumerable: true, get: function () { return syntax_6.ifAtUriString; } });
61
- Object.defineProperty(exports, "isAtUriString", { enumerable: true, get: function () { return syntax_6.isAtUriString; } });
36
+ export { currentDatetimeString, toDatetimeString } from '@atproto/syntax';
37
+ export { asAtUriString, assertAtUriString, ifAtUriString, isAtUriString, } from '@atproto/syntax';
62
38
  /**
63
39
  * Lenient version of {@link isAtUriString} that does not enforce the validity
64
40
  * of the record key (rkey) path component (if present).
65
41
  *
66
42
  * @see {@link isAtUriString}
67
43
  */
68
- function isAtUriStringLenient(input) {
69
- return (0, syntax_1.isAtUriString)(input, { strict: false });
44
+ export function isAtUriStringLenient(input) {
45
+ return isAtUriString(input, { strict: false });
70
46
  }
71
47
  /**
72
48
  * Type guard that checks if a value is a valid CID string.
@@ -74,69 +50,69 @@ function isAtUriStringLenient(input) {
74
50
  * @param value - The value to check
75
51
  * @returns `true` if the value is a valid CID string
76
52
  */
77
- exports.isCidString = ((v) => (0, lex_data_1.validateCidString)(v));
53
+ export const isCidString = ((v) => validateCidString(v));
78
54
  /**
79
55
  * Type guard that checks if a value is a valid DID string.
80
56
  *
81
57
  * @param value - The value to check
82
58
  * @returns `true` if the value is a valid DID string
83
59
  */
84
- exports.isDidString = syntax_1.isValidDid;
60
+ export const isDidString = isValidDid;
85
61
  /**
86
62
  * Type guard that checks if a value is a valid handle string.
87
63
  *
88
64
  * @param value - The value to check
89
65
  * @returns `true` if the value is a valid handle string
90
66
  */
91
- exports.isHandleString = syntax_1.isValidHandle;
67
+ export const isHandleString = isValidHandle;
92
68
  /**
93
69
  * Type guard that checks if a value is a valid BCP-47 language tag.
94
70
  *
95
71
  * @param value - The value to check
96
72
  * @returns `true` if the value is a valid language string
97
73
  */
98
- exports.isLanguageString = syntax_1.isValidLanguage;
74
+ export const isLanguageString = isValidLanguage;
99
75
  /**
100
76
  * Type guard that checks if a value is a valid NSID string.
101
77
  *
102
78
  * @param value - The value to check
103
79
  * @returns `true` if the value is a valid NSID string
104
80
  */
105
- exports.isNsidString = syntax_1.isValidNsid;
81
+ export const isNsidString = isValidNsid;
106
82
  /**
107
83
  * Type guard that checks if a value is a valid record key string.
108
84
  *
109
85
  * @param value - The value to check
110
86
  * @returns `true` if the value is a valid record key string
111
87
  */
112
- exports.isRecordKeyString = syntax_1.isValidRecordKey;
88
+ export const isRecordKeyString = isValidRecordKey;
113
89
  /**
114
90
  * Type guard that checks if a value is a valid TID string.
115
91
  *
116
92
  * @param value - The value to check
117
93
  * @returns `true` if the value is a valid TID string
118
94
  */
119
- exports.isTidString = syntax_1.isValidTid;
95
+ export const isTidString = isValidTid;
120
96
  /**
121
97
  * Type guard that checks if a value is a valid URI string.
122
98
  *
123
99
  * @param value - The value to check
124
100
  * @returns `true` if the value is a valid URI string
125
101
  */
126
- exports.isUriString = syntax_1.isValidUri;
102
+ export const isUriString = isValidUri;
127
103
  const stringFormatVerifiers = /*#__PURE__*/ Object.freeze({
128
104
  __proto__: null,
129
- 'at-identifier': [syntax_1.isAtIdentifierString],
130
- 'at-uri': [syntax_1.isAtUriString, isAtUriStringLenient],
131
- cid: [exports.isCidString],
132
- datetime: [syntax_1.isDatetimeString, isDatetimeStringLenient],
133
- did: [exports.isDidString],
134
- handle: [exports.isHandleString],
135
- language: [exports.isLanguageString],
136
- nsid: [exports.isNsidString],
137
- 'record-key': [exports.isRecordKeyString],
138
- tid: [exports.isTidString],
139
- uri: [exports.isUriString],
105
+ 'at-identifier': [isAtIdentifierString],
106
+ 'at-uri': [isAtUriString, isAtUriStringLenient],
107
+ cid: [isCidString],
108
+ datetime: [isDatetimeString, isDatetimeStringLenient],
109
+ did: [isDidString],
110
+ handle: [isHandleString],
111
+ language: [isLanguageString],
112
+ nsid: [isNsidString],
113
+ 'record-key': [isRecordKeyString],
114
+ tid: [isTidString],
115
+ uri: [isUriString],
140
116
  });
141
117
  /**
142
118
  * Type guard that checks if a string matches a specific format.
@@ -157,7 +133,7 @@ const stringFormatVerifiers = /*#__PURE__*/ Object.freeze({
157
133
  * ```
158
134
  */
159
135
  /*@__NO_SIDE_EFFECTS__*/
160
- function isStringFormat(input, format, options) {
136
+ export function isStringFormat(input, format, options) {
161
137
  const formatVerifier = stringFormatVerifiers[format];
162
138
  // Fool-proof
163
139
  if (!formatVerifier)
@@ -183,7 +159,7 @@ function isStringFormat(input, format, options) {
183
159
  * ```
184
160
  */
185
161
  /*@__NO_SIDE_EFFECTS__*/
186
- function assertStringFormat(input, format, options) {
162
+ export function assertStringFormat(input, format, options) {
187
163
  if (!isStringFormat(input, format, options)) {
188
164
  throw new TypeError(`Invalid string format (${format}): ${input}`);
189
165
  }
@@ -207,7 +183,7 @@ function assertStringFormat(input, format, options) {
207
183
  * ```
208
184
  */
209
185
  /*@__NO_SIDE_EFFECTS__*/
210
- function asStringFormat(input, format, options) {
186
+ export function asStringFormat(input, format, options) {
211
187
  assertStringFormat(input, format, options);
212
188
  return input;
213
189
  }
@@ -232,7 +208,7 @@ function asStringFormat(input, format, options) {
232
208
  * ```
233
209
  */
234
210
  /*@__NO_SIDE_EFFECTS__*/
235
- function ifStringFormat(input, format, options) {
211
+ export function ifStringFormat(input, format, options) {
236
212
  return isStringFormat(input, format, options) ? input : undefined;
237
213
  }
238
214
  /**
@@ -245,6 +221,6 @@ function ifStringFormat(input, format, options) {
245
221
  * }
246
222
  * ```
247
223
  */
248
- exports.STRING_FORMATS = Object.freeze(
224
+ export const STRING_FORMATS = /*#__PURE__*/ Object.freeze(
249
225
  /*#__PURE__*/ Object.keys(stringFormatVerifiers));
250
226
  //# sourceMappingURL=string-format.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"string-format.js","sourceRoot":"","sources":["../../src/core/string-format.ts"],"names":[],"mappings":"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","sourcesContent":["import { isValidISODateString } from 'iso-datestring-validator'\nimport { validateCidString } from '@atproto/lex-data'\nimport {\n AtIdentifierString,\n AtUriString,\n DatetimeString,\n DidString,\n HandleString,\n NsidString,\n RecordKeyString,\n TidString,\n UriString,\n isAtIdentifierString,\n isAtUriString,\n isDatetimeString,\n isValidDid,\n isValidHandle,\n isValidLanguage,\n isValidNsid,\n isValidRecordKey,\n isValidTid,\n isValidUri,\n} from '@atproto/syntax'\nimport { CheckFn } from '../util/assertion-util.js'\n\n// -----------------------------------------------------------------------------\n// Individual string format types and type guards\n// -----------------------------------------------------------------------------\n\n// Re-exporting from @atproto/syntax without modification to preserve types and\n// documentation for types and utilities that are already well-defined there.\n// @TODO rework other string formats in @atproto/syntax to follow this pattern\n// and re-export here, e.g. language tags, NSIDs, record keys, etc.\n\nexport {\n type AtIdentifierString,\n asAtIdentifierString,\n assertAtIdentifierString,\n ifAtIdentifierString,\n isAtIdentifierString,\n} from '@atproto/syntax'\n\n// AtIdentifierString utilities\nexport { isDidIdentifier, isHandleIdentifier } from '@atproto/syntax'\n\nexport {\n type DatetimeString,\n asDatetimeString,\n assertDatetimeString,\n ifDatetimeString,\n isDatetimeString,\n} from '@atproto/syntax'\n\n/**\n * Matches any ISO-ish datetime string. This is a more lenient check than\n * the strict {@link isDatetimeString} guard, which only allows datetimes that\n * fully conform to the AT Protocol specification (e.g. must include timezone).\n */\nexport function isDatetimeStringLenient<I>(\n input: I,\n): input is I & DatetimeString {\n // @NOTE the returned type assertion is inaccurate wrt. the DatetimeString\n // type definition. A more accurate solution would be to use a branded type\n // instead of a template literal for the \"datetime\" format\n if (typeof input !== 'string') return false\n try {\n return isValidISODateString(input)\n } catch {\n // @NOTE isValidISODateString throws on some inputs\n return false\n }\n}\n\n// DatetimeString utilities\nexport { currentDatetimeString, toDatetimeString } from '@atproto/syntax'\n\nexport {\n type AtUriString,\n asAtUriString,\n assertAtUriString,\n ifAtUriString,\n isAtUriString,\n} from '@atproto/syntax'\n\n/**\n * Lenient version of {@link isAtUriString} that does not enforce the validity\n * of the record key (rkey) path component (if present).\n *\n * @see {@link isAtUriString}\n */\nexport function isAtUriStringLenient<I>(input: I): input is I & AtUriString {\n return isAtUriString(input, { strict: false })\n}\n\n/**\n * Type guard that checks if a value is a valid CID string.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid CID string\n */\nexport const isCidString = ((v) => validateCidString(v)) as CheckFn<CidString>\n/**\n * A Content Identifier (CID) string.\n *\n * CIDs are self-describing content addresses used to identify data by its hash.\n *\n * @example `\"bafyreig...\"`\n */\nexport type CidString = string\n\n/**\n * Type guard that checks if a value is a valid DID string.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid DID string\n */\nexport const isDidString: CheckFn<DidString> = isValidDid\nexport type {\n /**\n * A Decentralized Identifier (DID) string.\n *\n * DIDs are globally unique identifiers that don't require a central authority.\n *\n * @example `\"did:plc:1234abcd...\"` or `\"did:web:example.com\"`\n */\n DidString,\n}\n\n/**\n * Type guard that checks if a value is a valid handle string.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid handle string\n */\nexport const isHandleString: CheckFn<HandleString> = isValidHandle\nexport type {\n /**\n * A handle string - a human-readable identifier for users.\n *\n * @example `\"alice.bsky.social\"` or `\"bob.example.com\"`\n */\n HandleString,\n}\n\n/**\n * Type guard that checks if a value is a valid BCP-47 language tag.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid language string\n */\nexport const isLanguageString = isValidLanguage as CheckFn<LanguageString>\n/**\n * A BCP-47 language tag string.\n *\n * @example `\"en\"`, `\"en-US\"`, `\"zh-Hans\"`\n */\nexport type LanguageString = string\n\n/**\n * Type guard that checks if a value is a valid NSID string.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid NSID string\n */\nexport const isNsidString: CheckFn<NsidString> = isValidNsid\nexport type {\n /**\n * A Namespaced Identifier (NSID) string identifying a lexicon.\n *\n * NSIDs use reverse-domain notation to identify schemas.\n *\n * @example `\"app.bsky.feed.post\"`, `\"com.atproto.repo.createRecord\"`\n */\n NsidString,\n}\n\n/**\n * Type guard that checks if a value is a valid record key string.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid record key string\n */\nexport const isRecordKeyString: CheckFn<RecordKeyString> = isValidRecordKey\nexport type {\n /**\n * A record key string identifying a record within a collection.\n *\n * @example `\"3k2...\"` (TID format) or `\"self\"` (literal key)\n */\n RecordKeyString,\n}\n\n/**\n * Type guard that checks if a value is a valid TID string.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid TID string\n */\nexport const isTidString: CheckFn<TidString> = isValidTid\nexport type {\n /**\n * A Timestamp Identifier (TID) string.\n *\n * TIDs are time-based identifiers used for record keys.\n *\n * @example `\"3k2...\"`\n */\n TidString,\n}\n\n/**\n * Type guard that checks if a value is a valid URI string.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid URI string\n */\nexport const isUriString: CheckFn<UriString> = isValidUri\nexport type {\n /**\n * A standard URI string.\n *\n * @example `\"https://example.com/path\"`\n */\n UriString,\n}\n\n// -----------------------------------------------------------------------------\n// String format registry\n// -----------------------------------------------------------------------------\n\ntype StringFormats = {\n 'at-identifier': AtIdentifierString\n 'at-uri': AtUriString\n cid: CidString\n datetime: DatetimeString\n did: DidString\n handle: HandleString\n language: LanguageString\n nsid: NsidString\n 'record-key': RecordKeyString\n tid: TidString\n uri: UriString\n}\n\n/**\n * Union type of all valid string format names.\n */\nexport type StringFormat = Extract<keyof StringFormats, string>\n\nconst stringFormatVerifiers: {\n readonly [K in StringFormat]: readonly [\n strict: CheckFn<StringFormats[K]>,\n lenient?: CheckFn<StringFormats[K]>,\n ]\n} = /*#__PURE__*/ Object.freeze({\n __proto__: null,\n\n 'at-identifier': [isAtIdentifierString],\n 'at-uri': [isAtUriString, isAtUriStringLenient],\n cid: [isCidString],\n datetime: [isDatetimeString, isDatetimeStringLenient],\n did: [isDidString],\n handle: [isHandleString],\n language: [isLanguageString],\n nsid: [isNsidString],\n 'record-key': [isRecordKeyString],\n tid: [isTidString],\n uri: [isUriString],\n})\n\nexport type StringFormatValidationOptions = {\n /**\n * Allows to be more lenient in validation by using a \"lenient\" verification\n * function, if available. The behavior of the lenient verifier depends on the\n * specific format, but generally it may allow for a wider range of valid\n * inputs, including values that are not compliant with the AT Protocol\n * specification.\n *\n * @default true\n */\n strict?: boolean\n}\n\n/**\n * Infers the string type for a given format name.\n *\n * @typeParam F - The format name\n *\n * @example\n * ```typescript\n * type Did = InferStringFormat<'did'>\n * // Result: DidString\n * ```\n */\nexport type InferStringFormat<F extends StringFormat> = F extends StringFormat\n ? StringFormats[F]\n : never\n\n/**\n * Type guard that checks if a string matches a specific format.\n *\n * @typeParam I - The input string type\n * @typeParam F - The format to check\n * @param input - The string to validate\n * @param format - The format name to validate against\n * @returns `true` if the string matches the format\n *\n * @example\n * ```typescript\n * const value: string = 'did:plc:1234...'\n * if (isStringFormat(value, 'did')) {\n * // value is typed as DidString\n * console.log('Valid DID:', value)\n * }\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isStringFormat<I extends string, F extends StringFormat>(\n input: I,\n format: F,\n options?: StringFormatValidationOptions,\n): input is I & StringFormats[F] {\n const formatVerifier = stringFormatVerifiers[format]\n // Fool-proof\n if (!formatVerifier) throw new TypeError(`Unknown string format: ${format}`)\n\n const check: CheckFn<StringFormats[F]> =\n options?.strict === false && formatVerifier.length > 1\n ? formatVerifier[1]!\n : formatVerifier[0]\n\n return check(input)\n}\n\n/**\n * Asserts that a string matches a specific format, throwing if invalid.\n *\n * @typeParam I - The input string type\n * @typeParam F - The format to check\n * @param input - The string to validate\n * @param format - The format name to validate against\n * @throws {TypeError} If the string doesn't match the format\n *\n * @example\n * ```typescript\n * assertStringFormat(value, 'handle')\n * // value is now typed as HandleString\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function assertStringFormat<I extends string, F extends StringFormat>(\n input: I,\n format: F,\n options?: StringFormatValidationOptions,\n): asserts input is I & StringFormats[F] {\n if (!isStringFormat(input, format, options)) {\n throw new TypeError(`Invalid string format (${format}): ${input}`)\n }\n}\n\n/**\n * Validates and returns a string as the specified format type, throwing if invalid.\n *\n * This is useful when you need to convert a string to a format type in an expression.\n *\n * @typeParam I - The input string type\n * @typeParam F - The format to validate against\n * @param input - The string to validate\n * @param format - The format name to validate against\n * @returns The input typed as the format type\n * @throws {TypeError} If the string doesn't match the format\n *\n * @example\n * ```typescript\n * const did = asStringFormat(userInput, 'did')\n * // did is typed as DidString\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function asStringFormat<I extends string, F extends StringFormat>(\n input: I,\n format: F,\n options?: StringFormatValidationOptions,\n): I & StringFormats[F] {\n assertStringFormat(input, format, options)\n return input\n}\n\n/**\n * Returns the string as the format type if valid, otherwise returns `undefined`.\n *\n * This is useful for optional validation where you want to handle invalid values\n * without throwing.\n *\n * @typeParam I - The input string type\n * @typeParam F - The format to validate against\n * @param input - The string to validate\n * @param format - The format name to validate against\n * @returns The typed string if valid, otherwise `undefined`\n *\n * @example\n * ```typescript\n * const did = ifStringFormat(maybeInvalid, 'did')\n * if (did) {\n * // did is typed as DidString\n * }\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function ifStringFormat<I extends string, F extends StringFormat>(\n input: I,\n format: F,\n options?: StringFormatValidationOptions,\n): undefined | (I & StringFormats[F]) {\n return isStringFormat(input, format, options) ? input : undefined\n}\n\n/**\n * Array of all valid string format names.\n *\n * @example\n * ```typescript\n * for (const format of STRING_FORMATS) {\n * console.log(format) // 'at-identifier', 'at-uri', 'cid', ...\n * }\n * ```\n */\nexport const STRING_FORMATS = /*#__PURE__*/ Object.freeze(\n /*#__PURE__*/ Object.keys(stringFormatVerifiers),\n) as readonly StringFormat[]\n"]}
1
+ {"version":3,"file":"string-format.js","sourceRoot":"","sources":["../../src/core/string-format.ts"],"names":[],"mappings":"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","sourcesContent":["import isoDatestringValidator from 'iso-datestring-validator'\nconst { isValidISODateString } = isoDatestringValidator\nimport { validateCidString } from '@atproto/lex-data'\nimport {\n AtIdentifierString,\n AtUriString,\n DatetimeString,\n DidString,\n HandleString,\n NsidString,\n RecordKeyString,\n TidString,\n UriString,\n isAtIdentifierString,\n isAtUriString,\n isDatetimeString,\n isValidDid,\n isValidHandle,\n isValidLanguage,\n isValidNsid,\n isValidRecordKey,\n isValidTid,\n isValidUri,\n} from '@atproto/syntax'\nimport { CheckFn } from '../util/assertion-util.js'\n\n// -----------------------------------------------------------------------------\n// Individual string format types and type guards\n// -----------------------------------------------------------------------------\n\n// Re-exporting from @atproto/syntax without modification to preserve types and\n// documentation for types and utilities that are already well-defined there.\n// @TODO rework other string formats in @atproto/syntax to follow this pattern\n// and re-export here, e.g. language tags, NSIDs, record keys, etc.\n\nexport {\n type AtIdentifierString,\n asAtIdentifierString,\n assertAtIdentifierString,\n ifAtIdentifierString,\n isAtIdentifierString,\n} from '@atproto/syntax'\n\n// AtIdentifierString utilities\nexport { isDidIdentifier, isHandleIdentifier } from '@atproto/syntax'\n\nexport {\n type DatetimeString,\n asDatetimeString,\n assertDatetimeString,\n ifDatetimeString,\n isDatetimeString,\n} from '@atproto/syntax'\n\n/**\n * Matches any ISO-ish datetime string. This is a more lenient check than\n * the strict {@link isDatetimeString} guard, which only allows datetimes that\n * fully conform to the AT Protocol specification (e.g. must include timezone).\n */\nexport function isDatetimeStringLenient<I>(\n input: I,\n): input is I & DatetimeString {\n // @NOTE the returned type assertion is inaccurate wrt. the DatetimeString\n // type definition. A more accurate solution would be to use a branded type\n // instead of a template literal for the \"datetime\" format\n if (typeof input !== 'string') return false\n try {\n return isValidISODateString(input)\n } catch {\n // @NOTE isValidISODateString throws on some inputs\n return false\n }\n}\n\n// DatetimeString utilities\nexport { currentDatetimeString, toDatetimeString } from '@atproto/syntax'\n\nexport {\n type AtUriString,\n asAtUriString,\n assertAtUriString,\n ifAtUriString,\n isAtUriString,\n} from '@atproto/syntax'\n\n/**\n * Lenient version of {@link isAtUriString} that does not enforce the validity\n * of the record key (rkey) path component (if present).\n *\n * @see {@link isAtUriString}\n */\nexport function isAtUriStringLenient<I>(input: I): input is I & AtUriString {\n return isAtUriString(input, { strict: false })\n}\n\n/**\n * Type guard that checks if a value is a valid CID string.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid CID string\n */\nexport const isCidString = ((v) => validateCidString(v)) as CheckFn<CidString>\n/**\n * A Content Identifier (CID) string.\n *\n * CIDs are self-describing content addresses used to identify data by its hash.\n *\n * @example `\"bafyreig...\"`\n */\nexport type CidString = string\n\n/**\n * Type guard that checks if a value is a valid DID string.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid DID string\n */\nexport const isDidString: CheckFn<DidString> = isValidDid\nexport type {\n /**\n * A Decentralized Identifier (DID) string.\n *\n * DIDs are globally unique identifiers that don't require a central authority.\n *\n * @example `\"did:plc:1234abcd...\"` or `\"did:web:example.com\"`\n */\n DidString,\n}\n\n/**\n * Type guard that checks if a value is a valid handle string.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid handle string\n */\nexport const isHandleString: CheckFn<HandleString> = isValidHandle\nexport type {\n /**\n * A handle string - a human-readable identifier for users.\n *\n * @example `\"alice.bsky.social\"` or `\"bob.example.com\"`\n */\n HandleString,\n}\n\n/**\n * Type guard that checks if a value is a valid BCP-47 language tag.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid language string\n */\nexport const isLanguageString = isValidLanguage as CheckFn<LanguageString>\n/**\n * A BCP-47 language tag string.\n *\n * @example `\"en\"`, `\"en-US\"`, `\"zh-Hans\"`\n */\nexport type LanguageString = string\n\n/**\n * Type guard that checks if a value is a valid NSID string.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid NSID string\n */\nexport const isNsidString: CheckFn<NsidString> = isValidNsid\nexport type {\n /**\n * A Namespaced Identifier (NSID) string identifying a lexicon.\n *\n * NSIDs use reverse-domain notation to identify schemas.\n *\n * @example `\"app.bsky.feed.post\"`, `\"com.atproto.repo.createRecord\"`\n */\n NsidString,\n}\n\n/**\n * Type guard that checks if a value is a valid record key string.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid record key string\n */\nexport const isRecordKeyString: CheckFn<RecordKeyString> = isValidRecordKey\nexport type {\n /**\n * A record key string identifying a record within a collection.\n *\n * @example `\"3k2...\"` (TID format) or `\"self\"` (literal key)\n */\n RecordKeyString,\n}\n\n/**\n * Type guard that checks if a value is a valid TID string.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid TID string\n */\nexport const isTidString: CheckFn<TidString> = isValidTid\nexport type {\n /**\n * A Timestamp Identifier (TID) string.\n *\n * TIDs are time-based identifiers used for record keys.\n *\n * @example `\"3k2...\"`\n */\n TidString,\n}\n\n/**\n * Type guard that checks if a value is a valid URI string.\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid URI string\n */\nexport const isUriString: CheckFn<UriString> = isValidUri\nexport type {\n /**\n * A standard URI string.\n *\n * @example `\"https://example.com/path\"`\n */\n UriString,\n}\n\n// -----------------------------------------------------------------------------\n// String format registry\n// -----------------------------------------------------------------------------\n\ntype StringFormats = {\n 'at-identifier': AtIdentifierString\n 'at-uri': AtUriString\n cid: CidString\n datetime: DatetimeString\n did: DidString\n handle: HandleString\n language: LanguageString\n nsid: NsidString\n 'record-key': RecordKeyString\n tid: TidString\n uri: UriString\n}\n\n/**\n * Union type of all valid string format names.\n */\nexport type StringFormat = Extract<keyof StringFormats, string>\n\nconst stringFormatVerifiers: {\n readonly [K in StringFormat]: readonly [\n strict: CheckFn<StringFormats[K]>,\n lenient?: CheckFn<StringFormats[K]>,\n ]\n} = /*#__PURE__*/ Object.freeze({\n __proto__: null,\n\n 'at-identifier': [isAtIdentifierString],\n 'at-uri': [isAtUriString, isAtUriStringLenient],\n cid: [isCidString],\n datetime: [isDatetimeString, isDatetimeStringLenient],\n did: [isDidString],\n handle: [isHandleString],\n language: [isLanguageString],\n nsid: [isNsidString],\n 'record-key': [isRecordKeyString],\n tid: [isTidString],\n uri: [isUriString],\n})\n\nexport type StringFormatValidationOptions = {\n /**\n * Allows to be more lenient in validation by using a \"lenient\" verification\n * function, if available. The behavior of the lenient verifier depends on the\n * specific format, but generally it may allow for a wider range of valid\n * inputs, including values that are not compliant with the AT Protocol\n * specification.\n *\n * @default true\n */\n strict?: boolean\n}\n\n/**\n * Infers the string type for a given format name.\n *\n * @typeParam F - The format name\n *\n * @example\n * ```typescript\n * type Did = InferStringFormat<'did'>\n * // Result: DidString\n * ```\n */\nexport type InferStringFormat<F extends StringFormat> = F extends StringFormat\n ? StringFormats[F]\n : never\n\n/**\n * Type guard that checks if a string matches a specific format.\n *\n * @typeParam I - The input string type\n * @typeParam F - The format to check\n * @param input - The string to validate\n * @param format - The format name to validate against\n * @returns `true` if the string matches the format\n *\n * @example\n * ```typescript\n * const value: string = 'did:plc:1234...'\n * if (isStringFormat(value, 'did')) {\n * // value is typed as DidString\n * console.log('Valid DID:', value)\n * }\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isStringFormat<I extends string, F extends StringFormat>(\n input: I,\n format: F,\n options?: StringFormatValidationOptions,\n): input is I & StringFormats[F] {\n const formatVerifier = stringFormatVerifiers[format]\n // Fool-proof\n if (!formatVerifier) throw new TypeError(`Unknown string format: ${format}`)\n\n const check: CheckFn<StringFormats[F]> =\n options?.strict === false && formatVerifier.length > 1\n ? formatVerifier[1]!\n : formatVerifier[0]\n\n return check(input)\n}\n\n/**\n * Asserts that a string matches a specific format, throwing if invalid.\n *\n * @typeParam I - The input string type\n * @typeParam F - The format to check\n * @param input - The string to validate\n * @param format - The format name to validate against\n * @throws {TypeError} If the string doesn't match the format\n *\n * @example\n * ```typescript\n * assertStringFormat(value, 'handle')\n * // value is now typed as HandleString\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function assertStringFormat<I extends string, F extends StringFormat>(\n input: I,\n format: F,\n options?: StringFormatValidationOptions,\n): asserts input is I & StringFormats[F] {\n if (!isStringFormat(input, format, options)) {\n throw new TypeError(`Invalid string format (${format}): ${input}`)\n }\n}\n\n/**\n * Validates and returns a string as the specified format type, throwing if invalid.\n *\n * This is useful when you need to convert a string to a format type in an expression.\n *\n * @typeParam I - The input string type\n * @typeParam F - The format to validate against\n * @param input - The string to validate\n * @param format - The format name to validate against\n * @returns The input typed as the format type\n * @throws {TypeError} If the string doesn't match the format\n *\n * @example\n * ```typescript\n * const did = asStringFormat(userInput, 'did')\n * // did is typed as DidString\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function asStringFormat<I extends string, F extends StringFormat>(\n input: I,\n format: F,\n options?: StringFormatValidationOptions,\n): I & StringFormats[F] {\n assertStringFormat(input, format, options)\n return input\n}\n\n/**\n * Returns the string as the format type if valid, otherwise returns `undefined`.\n *\n * This is useful for optional validation where you want to handle invalid values\n * without throwing.\n *\n * @typeParam I - The input string type\n * @typeParam F - The format to validate against\n * @param input - The string to validate\n * @param format - The format name to validate against\n * @returns The typed string if valid, otherwise `undefined`\n *\n * @example\n * ```typescript\n * const did = ifStringFormat(maybeInvalid, 'did')\n * if (did) {\n * // did is typed as DidString\n * }\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function ifStringFormat<I extends string, F extends StringFormat>(\n input: I,\n format: F,\n options?: StringFormatValidationOptions,\n): undefined | (I & StringFormats[F]) {\n return isStringFormat(input, format, options) ? input : undefined\n}\n\n/**\n * Array of all valid string format names.\n *\n * @example\n * ```typescript\n * for (const format of STRING_FORMATS) {\n * console.log(format) // 'at-identifier', 'at-uri', 'cid', ...\n * }\n * ```\n */\nexport const STRING_FORMATS = /*#__PURE__*/ Object.freeze(\n /*#__PURE__*/ Object.keys(stringFormatVerifiers),\n) as readonly StringFormat[]\n"]}
@@ -1,3 +1,2 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
3
2
  //# sourceMappingURL=types.js.map
@@ -1,10 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LexValidationError = void 0;
4
- const lex_data_1 = require("@atproto/lex-data");
5
- const array_agg_js_1 = require("../util/array-agg.js");
6
- const result_js_1 = require("./result.js");
7
- const validation_issue_js_1 = require("./validation-issue.js");
1
+ import { LexError } from '@atproto/lex-data';
2
+ import { arrayAgg } from '../util/array-agg.js';
3
+ import { failureReason } from './result.js';
4
+ import { IssueInvalidType, IssueInvalidValue, } from './validation-issue.js';
8
5
  /**
9
6
  * Error thrown when validation fails.
10
7
  *
@@ -32,15 +29,7 @@ const validation_issue_js_1 = require("./validation-issue.js");
32
29
  * directly as a failure reason in validation results, avoiding the need for
33
30
  * wrapping it in an additional object.
34
31
  */
35
- class LexValidationError extends lex_data_1.LexError {
36
- name = 'LexValidationError';
37
- /**
38
- * The list of validation issues that caused this error.
39
- *
40
- * Issues are aggregated when possible (e.g., multiple invalid type issues
41
- * at the same path are combined into a single issue listing all expected types).
42
- */
43
- issues;
32
+ export class LexValidationError extends LexError {
44
33
  /**
45
34
  * Creates a new validation error from a list of issues.
46
35
  *
@@ -53,10 +42,11 @@ class LexValidationError extends lex_data_1.LexError {
53
42
  constructor(issues, options) {
54
43
  const issuesAgg = aggregateIssues(issues);
55
44
  super('InvalidRequest', issuesAgg.join(', '), options);
45
+ this.name = 'LexValidationError';
46
+ /** @see {ResultFailure.success} */
47
+ this.success = false;
56
48
  this.issues = issuesAgg;
57
49
  }
58
- /** @see {ResultFailure.success} */
59
- success = false;
60
50
  /** @see {ResultFailure.reason} */
61
51
  get reason() {
62
52
  return this;
@@ -91,15 +81,14 @@ class LexValidationError extends lex_data_1.LexError {
91
81
  */
92
82
  static fromFailures(failures) {
93
83
  if (failures.length === 1)
94
- return (0, result_js_1.failureReason)(failures[0]);
84
+ return failureReason(failures[0]);
95
85
  const issues = failures.flatMap(extractFailureIssues);
96
86
  return new LexValidationError(issues, {
97
87
  // Keep the original errors as the cause chain
98
- cause: failures.map(result_js_1.failureReason),
88
+ cause: failures.map(failureReason),
99
89
  });
100
90
  }
101
91
  }
102
- exports.LexValidationError = LexValidationError;
103
92
  function extractFailureIssues(result) {
104
93
  return result.reason.issues;
105
94
  }
@@ -111,12 +100,12 @@ function aggregateIssues(issues) {
111
100
  return issues;
112
101
  return [
113
102
  // Aggregate invalid_type with identical paths
114
- ...(0, array_agg_js_1.arrayAgg)(issues.filter((issue) => issue instanceof validation_issue_js_1.IssueInvalidType), (a, b) => comparePropertyPaths(a.path, b.path), (issues) => new validation_issue_js_1.IssueInvalidType(issues[0].path, issues[0].input, Array.from(new Set(issues.flatMap((iss) => iss.expected))))),
103
+ ...arrayAgg(issues.filter((issue) => issue instanceof IssueInvalidType), (a, b) => comparePropertyPaths(a.path, b.path), (issues) => new IssueInvalidType(issues[0].path, issues[0].input, Array.from(new Set(issues.flatMap((iss) => iss.expected))))),
115
104
  // Aggregate invalid_value with identical paths
116
- ...(0, array_agg_js_1.arrayAgg)(issues.filter((issue) => issue instanceof validation_issue_js_1.IssueInvalidValue), (a, b) => comparePropertyPaths(a.path, b.path), (issues) => new validation_issue_js_1.IssueInvalidValue(issues[0].path, issues[0].input, Array.from(new Set(issues.flatMap((iss) => iss.values))))),
105
+ ...arrayAgg(issues.filter((issue) => issue instanceof IssueInvalidValue), (a, b) => comparePropertyPaths(a.path, b.path), (issues) => new IssueInvalidValue(issues[0].path, issues[0].input, Array.from(new Set(issues.flatMap((iss) => iss.values))))),
117
106
  // Pass through other issues
118
- ...issues.filter((issue) => !(issue instanceof validation_issue_js_1.IssueInvalidType) &&
119
- !(issue instanceof validation_issue_js_1.IssueInvalidValue)),
107
+ ...issues.filter((issue) => !(issue instanceof IssueInvalidType) &&
108
+ !(issue instanceof IssueInvalidValue)),
120
109
  ];
121
110
  }
122
111
  /*@__NO_SIDE_EFFECTS__*/
@@ -1 +1 @@
1
- {"version":3,"file":"validation-error.js","sourceRoot":"","sources":["../../src/core/validation-error.ts"],"names":[],"mappings":"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","sourcesContent":["import { LexError } from '@atproto/lex-data'\nimport { arrayAgg } from '../util/array-agg.js'\nimport { ResultFailure, failureReason } from './result.js'\nimport {\n Issue,\n IssueInvalidType,\n IssueInvalidValue,\n} from './validation-issue.js'\n\n/**\n * Error thrown when validation fails.\n *\n * Contains detailed information about all validation issues encountered,\n * including the path to each invalid value and descriptions of what was\n * expected vs what was received.\n *\n * Extends {@link LexError} with the error name \"InvalidRequest\" for\n * consistency with the AT Protocol error handling conventions.\n *\n * @example\n * ```typescript\n * const error = new LexValidationError([\n * new IssueInvalidType(['user', 'age'], 'hello', ['number'])\n * ])\n * console.log(error.message)\n * // \"Expected integer value type (got \"some-string\") at $.user.age\"\n *\n * console.log(error.issues.length) // 1\n * console.log(error.toJSON())\n * // { error: 'InvalidRequest', message: '...', issues: [...] }\n * ```\n *\n * @note this class implements {@link ResultFailure} to allow it to be used\n * directly as a failure reason in validation results, avoiding the need for\n * wrapping it in an additional object.\n */\nexport class LexValidationError\n extends LexError<'InvalidRequest'>\n implements ResultFailure<LexValidationError>\n{\n name = 'LexValidationError'\n\n /**\n * The list of validation issues that caused this error.\n *\n * Issues are aggregated when possible (e.g., multiple invalid type issues\n * at the same path are combined into a single issue listing all expected types).\n */\n readonly issues: readonly Issue[]\n\n /**\n * Creates a new validation error from a list of issues.\n *\n * Issues are automatically aggregated to combine related issues at the same\n * path (e.g., multiple type expectations from a union schema).\n *\n * @param issues - The validation issues that caused this error\n * @param options - Standard Error options (e.g., `cause`)\n */\n constructor(issues: Issue[], options?: ErrorOptions) {\n const issuesAgg = aggregateIssues(issues)\n super('InvalidRequest', issuesAgg.join(', '), options)\n this.issues = issuesAgg\n }\n\n /** @see {ResultFailure.success} */\n readonly success = false as const\n\n /** @see {ResultFailure.reason} */\n get reason() {\n return this\n }\n\n /**\n * Converts the error to a JSON-serializable object.\n *\n * @returns An object containing the error details and issues details\n */\n override toJSON() {\n return {\n ...super.toJSON(),\n issues: this.issues.map((issue) => issue.toJSON()),\n }\n }\n\n /**\n * Creates a validation error by combining multiple validation failures.\n *\n * This is useful when validating against multiple possible schemas (e.g., unions)\n * and all branches fail. The resulting error contains issues from all failures.\n *\n * @param failures - The validation failures to combine\n * @returns A single validation error containing all issues from the failures\n *\n * @example\n * ```typescript\n * const failures = schemas.map(s => s.safeValidate(data)).filter(r => !r.success)\n * if (failures.length === schemas.length) {\n * throw LexValidationError.fromFailures(failures)\n * }\n * ```\n */\n static fromFailures(\n failures: readonly ResultFailure<LexValidationError>[],\n ): LexValidationError {\n if (failures.length === 1) return failureReason(failures[0])\n const issues = failures.flatMap(extractFailureIssues)\n return new LexValidationError(issues, {\n // Keep the original errors as the cause chain\n cause: failures.map(failureReason),\n })\n }\n}\n\nfunction extractFailureIssues(result: ResultFailure<LexValidationError>) {\n return result.reason.issues\n}\n\nfunction aggregateIssues(issues: Issue[]): Issue[] {\n // Quick path for common cases\n if (issues.length <= 1) return issues\n if (issues.length === 2 && issues[0].code !== issues[1].code) return issues\n\n return [\n // Aggregate invalid_type with identical paths\n ...arrayAgg(\n issues.filter((issue) => issue instanceof IssueInvalidType),\n (a, b) => comparePropertyPaths(a.path, b.path),\n (issues) =>\n new IssueInvalidType(\n issues[0].path,\n issues[0].input,\n Array.from(new Set(issues.flatMap((iss) => iss.expected))),\n ),\n ),\n // Aggregate invalid_value with identical paths\n ...arrayAgg(\n issues.filter((issue) => issue instanceof IssueInvalidValue),\n (a, b) => comparePropertyPaths(a.path, b.path),\n (issues) =>\n new IssueInvalidValue(\n issues[0].path,\n issues[0].input,\n Array.from(new Set(issues.flatMap((iss) => iss.values))),\n ),\n ),\n // Pass through other issues\n ...issues.filter(\n (issue) =>\n !(issue instanceof IssueInvalidType) &&\n !(issue instanceof IssueInvalidValue),\n ),\n ]\n}\n\n/*@__NO_SIDE_EFFECTS__*/\nfunction comparePropertyPaths(\n a: readonly PropertyKey[],\n b: readonly PropertyKey[],\n) {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false\n }\n return true\n}\n"]}
1
+ {"version":3,"file":"validation-error.js","sourceRoot":"","sources":["../../src/core/validation-error.ts"],"names":[],"mappings":"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","sourcesContent":["import { LexError } from '@atproto/lex-data'\nimport { arrayAgg } from '../util/array-agg.js'\nimport { ResultFailure, failureReason } from './result.js'\nimport {\n Issue,\n IssueInvalidType,\n IssueInvalidValue,\n} from './validation-issue.js'\n\n/**\n * Error thrown when validation fails.\n *\n * Contains detailed information about all validation issues encountered,\n * including the path to each invalid value and descriptions of what was\n * expected vs what was received.\n *\n * Extends {@link LexError} with the error name \"InvalidRequest\" for\n * consistency with the AT Protocol error handling conventions.\n *\n * @example\n * ```typescript\n * const error = new LexValidationError([\n * new IssueInvalidType(['user', 'age'], 'hello', ['number'])\n * ])\n * console.log(error.message)\n * // \"Expected integer value type (got \"some-string\") at $.user.age\"\n *\n * console.log(error.issues.length) // 1\n * console.log(error.toJSON())\n * // { error: 'InvalidRequest', message: '...', issues: [...] }\n * ```\n *\n * @note this class implements {@link ResultFailure} to allow it to be used\n * directly as a failure reason in validation results, avoiding the need for\n * wrapping it in an additional object.\n */\nexport class LexValidationError\n extends LexError<'InvalidRequest'>\n implements ResultFailure<LexValidationError>\n{\n name = 'LexValidationError'\n\n /**\n * The list of validation issues that caused this error.\n *\n * Issues are aggregated when possible (e.g., multiple invalid type issues\n * at the same path are combined into a single issue listing all expected types).\n */\n readonly issues: readonly Issue[]\n\n /**\n * Creates a new validation error from a list of issues.\n *\n * Issues are automatically aggregated to combine related issues at the same\n * path (e.g., multiple type expectations from a union schema).\n *\n * @param issues - The validation issues that caused this error\n * @param options - Standard Error options (e.g., `cause`)\n */\n constructor(issues: Issue[], options?: ErrorOptions) {\n const issuesAgg = aggregateIssues(issues)\n super('InvalidRequest', issuesAgg.join(', '), options)\n this.issues = issuesAgg\n }\n\n /** @see {ResultFailure.success} */\n readonly success = false as const\n\n /** @see {ResultFailure.reason} */\n get reason() {\n return this\n }\n\n /**\n * Converts the error to a JSON-serializable object.\n *\n * @returns An object containing the error details and issues details\n */\n override toJSON() {\n return {\n ...super.toJSON(),\n issues: this.issues.map((issue) => issue.toJSON()),\n }\n }\n\n /**\n * Creates a validation error by combining multiple validation failures.\n *\n * This is useful when validating against multiple possible schemas (e.g., unions)\n * and all branches fail. The resulting error contains issues from all failures.\n *\n * @param failures - The validation failures to combine\n * @returns A single validation error containing all issues from the failures\n *\n * @example\n * ```typescript\n * const failures = schemas.map(s => s.safeValidate(data)).filter(r => !r.success)\n * if (failures.length === schemas.length) {\n * throw LexValidationError.fromFailures(failures)\n * }\n * ```\n */\n static fromFailures(\n failures: readonly ResultFailure<LexValidationError>[],\n ): LexValidationError {\n if (failures.length === 1) return failureReason(failures[0])\n const issues = failures.flatMap(extractFailureIssues)\n return new LexValidationError(issues, {\n // Keep the original errors as the cause chain\n cause: failures.map(failureReason),\n })\n }\n}\n\nfunction extractFailureIssues(result: ResultFailure<LexValidationError>) {\n return result.reason.issues\n}\n\nfunction aggregateIssues(issues: Issue[]): Issue[] {\n // Quick path for common cases\n if (issues.length <= 1) return issues\n if (issues.length === 2 && issues[0].code !== issues[1].code) return issues\n\n return [\n // Aggregate invalid_type with identical paths\n ...arrayAgg(\n issues.filter((issue) => issue instanceof IssueInvalidType),\n (a, b) => comparePropertyPaths(a.path, b.path),\n (issues) =>\n new IssueInvalidType(\n issues[0].path,\n issues[0].input,\n Array.from(new Set(issues.flatMap((iss) => iss.expected))),\n ),\n ),\n // Aggregate invalid_value with identical paths\n ...arrayAgg(\n issues.filter((issue) => issue instanceof IssueInvalidValue),\n (a, b) => comparePropertyPaths(a.path, b.path),\n (issues) =>\n new IssueInvalidValue(\n issues[0].path,\n issues[0].input,\n Array.from(new Set(issues.flatMap((iss) => iss.values))),\n ),\n ),\n // Pass through other issues\n ...issues.filter(\n (issue) =>\n !(issue instanceof IssueInvalidType) &&\n !(issue instanceof IssueInvalidValue),\n ),\n ]\n}\n\n/*@__NO_SIDE_EFFECTS__*/\nfunction comparePropertyPaths(\n a: readonly PropertyKey[],\n b: readonly PropertyKey[],\n) {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false\n }\n return true\n}\n"]}
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.IssueTooSmall = exports.IssueTooBig = exports.IssueRequiredKey = exports.IssueInvalidValue = exports.IssueInvalidType = exports.IssueInvalidFormat = exports.IssueCustom = exports.Issue = void 0;
4
- const lex_data_1 = require("@atproto/lex-data");
5
- const STRING_PREVIEW_MAX_LENGTH = 48;
1
+ import { ifCid, isLegacyBlobRef, isPlainObject } from '@atproto/lex-data';
2
+ const STRING_PREVIEW_MAX_LENGTH = 256;
6
3
  const STRING_PREVIEW_TRUNCATED_SUFFIX = '…';
7
4
  /**
8
5
  * Abstract base class for all validation issues.
@@ -16,10 +13,7 @@ const STRING_PREVIEW_TRUNCATED_SUFFIX = '…';
16
13
  * the {@link message} property for human-readable error messages (that don't
17
14
  * contain the error path)
18
15
  */
19
- class Issue {
20
- code;
21
- path;
22
- input;
16
+ export class Issue {
23
17
  constructor(code, path, input) {
24
18
  this.code = code;
25
19
  this.path = path;
@@ -44,16 +38,12 @@ class Issue {
44
38
  };
45
39
  }
46
40
  }
47
- exports.Issue = Issue;
48
41
  /**
49
42
  * A custom validation issue with a user-defined message.
50
43
  *
51
44
  * Use this for validation rules that don't fit into the standard issue categories.
52
45
  */
53
- class IssueCustom extends Issue {
54
- path;
55
- input;
56
- message;
46
+ export class IssueCustom extends Issue {
57
47
  constructor(path, input, message) {
58
48
  super('custom', path, input);
59
49
  this.path = path;
@@ -61,15 +51,12 @@ class IssueCustom extends Issue {
61
51
  this.message = message;
62
52
  }
63
53
  }
64
- exports.IssueCustom = IssueCustom;
65
54
  /**
66
55
  * Issue for string values that don't match an expected format.
67
56
  *
68
57
  * Used for AT Protocol specific formats like DID, handle, NSID, AT-URI, etc.
69
58
  */
70
- class IssueInvalidFormat extends Issue {
71
- format;
72
- detail;
59
+ export class IssueInvalidFormat extends Issue {
73
60
  constructor(path, input, format, detail) {
74
61
  super('invalid_format', path, input);
75
62
  this.format = format;
@@ -104,15 +91,13 @@ class IssueInvalidFormat extends Issue {
104
91
  };
105
92
  }
106
93
  }
107
- exports.IssueInvalidFormat = IssueInvalidFormat;
108
94
  /**
109
95
  * Issue for values that have an unexpected type.
110
96
  *
111
97
  * This is one of the most common validation issues, occurring when the
112
98
  * runtime type of a value doesn't match the expected schema type.
113
99
  */
114
- class IssueInvalidType extends Issue {
115
- expected;
100
+ export class IssueInvalidType extends Issue {
116
101
  constructor(path, input, expected) {
117
102
  super('invalid_type', path, input);
118
103
  this.expected = expected;
@@ -127,15 +112,13 @@ class IssueInvalidType extends Issue {
127
112
  };
128
113
  }
129
114
  }
130
- exports.IssueInvalidType = IssueInvalidType;
131
115
  /**
132
116
  * Issue for values that don't match any of the expected literal values.
133
117
  *
134
118
  * Used when a value must be one of a specific set of allowed values
135
119
  * (e.g., enum-like constraints).
136
120
  */
137
- class IssueInvalidValue extends Issue {
138
- values;
121
+ export class IssueInvalidValue extends Issue {
139
122
  constructor(path, input, values) {
140
123
  super('invalid_value', path, input);
141
124
  this.values = values;
@@ -150,12 +133,10 @@ class IssueInvalidValue extends Issue {
150
133
  };
151
134
  }
152
135
  }
153
- exports.IssueInvalidValue = IssueInvalidValue;
154
136
  /**
155
137
  * Issue for missing required object properties.
156
138
  */
157
- class IssueRequiredKey extends Issue {
158
- key;
139
+ export class IssueRequiredKey extends Issue {
159
140
  constructor(path, input, key) {
160
141
  super('required_key', path, input);
161
142
  this.key = key;
@@ -170,14 +151,10 @@ class IssueRequiredKey extends Issue {
170
151
  };
171
152
  }
172
153
  }
173
- exports.IssueRequiredKey = IssueRequiredKey;
174
154
  /**
175
155
  * Issue for values that exceed a maximum constraint.
176
156
  */
177
- class IssueTooBig extends Issue {
178
- maximum;
179
- type;
180
- actual;
157
+ export class IssueTooBig extends Issue {
181
158
  constructor(path, input, maximum, type, actual) {
182
159
  super('too_big', path, input);
183
160
  this.maximum = maximum;
@@ -195,14 +172,10 @@ class IssueTooBig extends Issue {
195
172
  };
196
173
  }
197
174
  }
198
- exports.IssueTooBig = IssueTooBig;
199
175
  /**
200
176
  * Issue for values that are below a minimum constraint.
201
177
  */
202
- class IssueTooSmall extends Issue {
203
- minimum;
204
- type;
205
- actual;
178
+ export class IssueTooSmall extends Issue {
206
179
  constructor(path, input, minimum, type, actual) {
207
180
  super('too_small', path, input);
208
181
  this.minimum = minimum;
@@ -220,7 +193,6 @@ class IssueTooSmall extends Issue {
220
193
  };
221
194
  }
222
195
  }
223
- exports.IssueTooSmall = IssueTooSmall;
224
196
  // -----------------------------------------------------------------------------
225
197
  // Helper functions for formatting error messages
226
198
  // -----------------------------------------------------------------------------
@@ -271,12 +243,12 @@ function stringifyValue(value) {
271
243
  if (Array.isArray(value)) {
272
244
  return `[${stringifyArray(value, stringifyValue)}]`;
273
245
  }
274
- if ((0, lex_data_1.isPlainObject)(value)) {
246
+ if (isPlainObject(value)) {
275
247
  return `{${stringifyArray(Object.entries(value), stringifyObjectEntry)}}`;
276
248
  }
277
- if ((0, lex_data_1.ifCid)(value))
249
+ if (ifCid(value))
278
250
  return 'cid';
279
- if ((0, lex_data_1.isLegacyBlobRef)(value))
251
+ if (isLegacyBlobRef(value))
280
252
  return 'legacy-blob';
281
253
  if (value instanceof Date)
282
254
  return 'date';