@atproto/syntax 0.5.3 → 0.6.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 (53) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/at-identifier.js +15 -23
  3. package/dist/at-identifier.js.map +1 -1
  4. package/dist/aturi.d.ts.map +1 -1
  5. package/dist/aturi.js +30 -32
  6. package/dist/aturi.js.map +1 -1
  7. package/dist/aturi_validation.d.ts +137 -4
  8. package/dist/aturi_validation.d.ts.map +1 -1
  9. package/dist/aturi_validation.js +172 -102
  10. package/dist/aturi_validation.js.map +1 -1
  11. package/dist/datetime.d.ts +5 -0
  12. package/dist/datetime.d.ts.map +1 -1
  13. package/dist/datetime.js +52 -38
  14. package/dist/datetime.js.map +1 -1
  15. package/dist/did.js +4 -11
  16. package/dist/did.js.map +1 -1
  17. package/dist/handle.js +13 -26
  18. package/dist/handle.js.map +1 -1
  19. package/dist/index.js +10 -13
  20. package/dist/index.js.map +1 -1
  21. package/dist/language.js +2 -6
  22. package/dist/language.js.map +1 -1
  23. package/dist/lib/result.d.ts +12 -0
  24. package/dist/lib/result.d.ts.map +1 -0
  25. package/dist/lib/result.js +7 -0
  26. package/dist/lib/result.js.map +1 -0
  27. package/dist/nsid.d.ts +3 -10
  28. package/dist/nsid.d.ts.map +1 -1
  29. package/dist/nsid.js +23 -82
  30. package/dist/nsid.js.map +1 -1
  31. package/dist/recordkey.js +3 -9
  32. package/dist/recordkey.js.map +1 -1
  33. package/dist/tid.js +3 -9
  34. package/dist/tid.js.map +1 -1
  35. package/dist/uri.js +1 -4
  36. package/dist/uri.js.map +1 -1
  37. package/package.json +12 -4
  38. package/src/aturi.ts +13 -7
  39. package/src/aturi_validation.ts +279 -110
  40. package/src/datetime.ts +41 -8
  41. package/src/lib/result.ts +11 -0
  42. package/src/nsid.ts +20 -56
  43. package/tests/aturi-string.test.ts +72 -40
  44. package/tests/aturi.test.ts +5 -5
  45. package/tests/datetime.test.ts +23 -1
  46. package/tests/did.test.ts +5 -1
  47. package/tests/handle.test.ts +1 -1
  48. package/tests/language.test.ts +1 -1
  49. package/tests/nsid.test.ts +1 -1
  50. package/tests/recordkey.test.ts +1 -1
  51. package/tests/tid.test.ts +1 -1
  52. package/tsconfig.build.tsbuildinfo +1 -1
  53. /package/{benchmark.js → benchmark.cjs} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @atproto/syntax
2
2
 
3
+ ## 0.6.0-next.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#4929](https://github.com/bluesky-social/atproto/pull/4929) [`bb7491c`](https://github.com/bluesky-social/atproto/commit/bb7491c29e06181e1d2f8cf6eb454f9bb8ab961b) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Drop support for Node.js 18 and 20. Node.js 22 is now the minimum supported version. Docker images now use Node.js 24.
8
+
9
+ - [#4943](https://github.com/bluesky-social/atproto/pull/4943) [`07ae5d4`](https://github.com/bluesky-social/atproto/commit/07ae5d4452df51e045e0239da7a04cf0bc154028) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Convert to pure ESM. All packages now ship `"type": "module"` with ES module output and Node16 module resolution.
10
+
11
+ Node.js 22's `require()` compatibility layer can still load these packages in CommonJS code.
12
+
13
+ - [#4930](https://github.com/bluesky-social/atproto/pull/4930) [`042df15`](https://github.com/bluesky-social/atproto/commit/042df15087c0e62cd1e715fcbf58852fab875af9) Thanks [@devinivy](https://github.com/devinivy)! - Build with TypeScript 6.0. Emitted `.d.ts` files now use TypeScript 6's stricter `Uint8Array<ArrayBuffer>` typing in places where Web/Node APIs require buffer-backed (not shared-memory) byte arrays. Consumers compiling against these types on older TypeScript should see no runtime impact, but may need to widen or cast in spots that previously relied on `Uint8Array` defaulting to `<ArrayBufferLike>`.
14
+
15
+ Internal: tsconfig `moduleResolution: "node"` is silenced via `ignoreDeprecations: "6.0"` for now; the proper migration to `node16`/`bundler` resolution is deferred.
16
+
17
+ ## 0.5.4
18
+
19
+ ### Patch Changes
20
+
21
+ - [#4806](https://github.com/bluesky-social/atproto/pull/4806) [`26d793a`](https://github.com/bluesky-social/atproto/commit/26d793af95a6fb3a50f9b2a97187d8ac4fecf676) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Avoid trailing slashes when stringifying an AtUri
22
+
23
+ - [#4806](https://github.com/bluesky-social/atproto/pull/4806) [`26d793a`](https://github.com/bluesky-social/atproto/commit/26d793af95a6fb3a50f9b2a97187d8ac4fecf676) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Align implementation of `ensureValidAtUri` and `ensureValidAtUriRegex`: consistently apply length and fragment charset restrictions
24
+
25
+ - [#4806](https://github.com/bluesky-social/atproto/pull/4806) [`26d793a`](https://github.com/bluesky-social/atproto/commit/26d793af95a6fb3a50f9b2a97187d8ac4fecf676) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Improve performances of `AtUriString` validation
26
+
27
+ - [#4760](https://github.com/bluesky-social/atproto/pull/4760) [`55d06de`](https://github.com/bluesky-social/atproto/commit/55d06de80a1506908a04ed5c0834986cb5783797) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Fixes a bug where `normalizeDatetime` would return different results for the same input depending on the timezone of the machine it was run on. This caused tests to fail when run in different environments. The fix consists of attempting more consistent parsing strategies first (appending "Z" or " UTC" to the input) before falling back to parsing "as is", which can yield different results depending on the local timezone. The function's documentation has also been updated to reflect this behavior.
28
+
29
+ - [#4806](https://github.com/bluesky-social/atproto/pull/4806) [`26d793a`](https://github.com/bluesky-social/atproto/commit/26d793af95a6fb3a50f9b2a97187d8ac4fecf676) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add missing fragment to `AtUriString` template literal type
30
+
3
31
  ## 0.5.3
4
32
 
5
33
  ### Patch Changes
@@ -1,21 +1,11 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isHandleIdentifier = isHandleIdentifier;
4
- exports.isDidIdentifier = isDidIdentifier;
5
- exports.assertAtIdentifierString = assertAtIdentifierString;
6
- exports.ensureValidAtIdentifier = assertAtIdentifierString;
7
- exports.asAtIdentifierString = asAtIdentifierString;
8
- exports.isAtIdentifierString = isAtIdentifierString;
9
- exports.isValidAtIdentifier = isAtIdentifierString;
10
- exports.ifAtIdentifierString = ifAtIdentifierString;
11
- const did_js_1 = require("./did.js");
12
- const handle_js_1 = require("./handle.js");
1
+ import { ensureValidDidRegex, isValidDid } from './did.js';
2
+ import { InvalidHandleError, ensureValidHandleRegex, isValidHandle, } from './handle.js';
13
3
  /**
14
4
  * Discriminates {@link HandleString} from a valid {@link AtIdentifierString}.
15
5
  *
16
6
  * @return `true` if the identifier is a handle, `false` otherwise
17
7
  */
18
- function isHandleIdentifier(id) {
8
+ export function isHandleIdentifier(id) {
19
9
  return !isDidIdentifier(id);
20
10
  }
21
11
  /**
@@ -23,7 +13,7 @@ function isHandleIdentifier(id) {
23
13
  *
24
14
  * @return `true` if the identifier is a DID, `false` otherwise
25
15
  */
26
- function isDidIdentifier(id) {
16
+ export function isDidIdentifier(id) {
27
17
  return id.startsWith('did:');
28
18
  }
29
19
  /**
@@ -33,20 +23,20 @@ function isDidIdentifier(id) {
33
23
  * @throws InvalidHandleError if the input string does not meet the atproto 'datetime' format requirements.
34
24
  * @see {@link AtIdentifierString}
35
25
  */
36
- function assertAtIdentifierString(input) {
26
+ export function assertAtIdentifierString(input) {
37
27
  try {
38
28
  if (!input || typeof input !== 'string') {
39
29
  throw new TypeError('Identifier must be a non-empty string');
40
30
  }
41
31
  else if (input.startsWith('did:')) {
42
- (0, did_js_1.ensureValidDidRegex)(input);
32
+ ensureValidDidRegex(input);
43
33
  }
44
34
  else {
45
- (0, handle_js_1.ensureValidHandleRegex)(input);
35
+ ensureValidHandleRegex(input);
46
36
  }
47
37
  }
48
38
  catch (cause) {
49
- throw new handle_js_1.InvalidHandleError('Invalid DID or handle', { cause });
39
+ throw new InvalidHandleError('Invalid DID or handle', { cause });
50
40
  }
51
41
  }
52
42
  /**
@@ -56,7 +46,7 @@ function assertAtIdentifierString(input) {
56
46
  * @throws InvalidHandleError if the input string does not meet the atproto 'at-identifier' format requirements.
57
47
  * @see {@link AtIdentifierString}
58
48
  */
59
- function asAtIdentifierString(input) {
49
+ export function asAtIdentifierString(input) {
60
50
  assertAtIdentifierString(input);
61
51
  return input;
62
52
  }
@@ -67,15 +57,15 @@ function asAtIdentifierString(input) {
67
57
  * @returns `true` if the value is a valid AT identifier
68
58
  * @see {@link AtIdentifierString}
69
59
  */
70
- function isAtIdentifierString(input) {
60
+ export function isAtIdentifierString(input) {
71
61
  if (!input || typeof input !== 'string') {
72
62
  return false;
73
63
  }
74
64
  else if (input.startsWith('did:')) {
75
- return (0, did_js_1.isValidDid)(input);
65
+ return isValidDid(input);
76
66
  }
77
67
  else {
78
- return (0, handle_js_1.isValidHandle)(input);
68
+ return isValidHandle(input);
79
69
  }
80
70
  }
81
71
  /**
@@ -84,7 +74,9 @@ function isAtIdentifierString(input) {
84
74
  *
85
75
  * @see {@link AtIdentifierString}
86
76
  */
87
- function ifAtIdentifierString(input) {
77
+ export function ifAtIdentifierString(input) {
88
78
  return isAtIdentifierString(input) ? input : undefined;
89
79
  }
80
+ // Legacy exports (should we deprecate these ?)
81
+ export { assertAtIdentifierString as ensureValidAtIdentifier, isAtIdentifierString as isValidAtIdentifier, };
90
82
  //# sourceMappingURL=at-identifier.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"at-identifier.js","sourceRoot":"","sources":["../src/at-identifier.ts"],"names":[],"mappings":";;AAoBA,gDAEC;AAOD,0CAEC;AASD,4DAcC;AA+C6B,2DAAuB;AAtCrD,oDAGC;AASD,oDAUC;AAiByB,mDAAmB;AAT7C,oDAIC;AAjGD,qCAAqE;AACrE,2CAKoB;AASpB;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,EAAsB;IACvD,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC,CAAA;AAC7B,CAAC;AAED;;;;GAIG;AACH,SAAgB,eAAe,CAAC,EAAsB;IACpD,OAAO,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;AAC9B,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,wBAAwB,CACtC,KAAQ;IAER,IAAI,CAAC;QACH,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACxC,MAAM,IAAI,SAAS,CAAC,uCAAuC,CAAC,CAAA;QAC9D,CAAC;aAAM,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,IAAA,4BAAmB,EAAC,KAAK,CAAC,CAAA;QAC5B,CAAC;aAAM,CAAC;YACN,IAAA,kCAAsB,EAAC,KAAK,CAAC,CAAA;QAC/B,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,8BAAkB,CAAC,uBAAuB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;IAClE,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,oBAAoB,CAAI,KAAQ;IAC9C,wBAAwB,CAAC,KAAK,CAAC,CAAA;IAC/B,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,oBAAoB,CAClC,KAAQ;IAER,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,KAAK,CAAA;IACd,CAAC;SAAM,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,OAAO,IAAA,mBAAU,EAAC,KAAK,CAAC,CAAA;IAC1B,CAAC;SAAM,CAAC;QACN,OAAO,IAAA,yBAAa,EAAC,KAAK,CAAC,CAAA;IAC7B,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAgB,oBAAoB,CAClC,KAAQ;IAER,OAAO,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AACxD,CAAC","sourcesContent":["import { DidString, ensureValidDidRegex, isValidDid } from './did.js'\nimport {\n HandleString,\n InvalidHandleError,\n ensureValidHandleRegex,\n isValidHandle,\n} from './handle.js'\n\n/**\n * An \"at-identifier\" string - either a {@link DidString} or a {@link HandleString}\n *\n * @example `\"did:plc:1234...\"`, `\"did:web:example.com\"` or `\"alice.bsky.social\"`\n */\nexport type AtIdentifierString = DidString | HandleString\n\n/**\n * Discriminates {@link HandleString} from a valid {@link AtIdentifierString}.\n *\n * @return `true` if the identifier is a handle, `false` otherwise\n */\nexport function isHandleIdentifier(id: AtIdentifierString): id is HandleString {\n return !isDidIdentifier(id)\n}\n\n/**\n * Discriminates {@link DidString} from a valid {@link AtIdentifierString}.\n *\n * @return `true` if the identifier is a DID, `false` otherwise\n */\nexport function isDidIdentifier(id: AtIdentifierString): id is DidString {\n return id.startsWith('did:')\n}\n\n/**\n * Validates that a string is a valid {@link AtIdentifierString} format string,\n * throwing an error if it is not.\n *\n * @throws InvalidHandleError if the input string does not meet the atproto 'datetime' format requirements.\n * @see {@link AtIdentifierString}\n */\nexport function assertAtIdentifierString<I>(\n input: I,\n): asserts input is I & AtIdentifierString {\n try {\n if (!input || typeof input !== 'string') {\n throw new TypeError('Identifier must be a non-empty string')\n } else if (input.startsWith('did:')) {\n ensureValidDidRegex(input)\n } else {\n ensureValidHandleRegex(input)\n }\n } catch (cause) {\n throw new InvalidHandleError('Invalid DID or handle', { cause })\n }\n}\n\n/**\n * Casts a string to a {@link AtIdentifierString} if it is a valid at-identifier\n * string, throwing an error if it is not.\n *\n * @throws InvalidHandleError if the input string does not meet the atproto 'at-identifier' format requirements.\n * @see {@link AtIdentifierString}\n */\nexport function asAtIdentifierString<I>(input: I): I & AtIdentifierString {\n assertAtIdentifierString(input)\n return input\n}\n\n/**\n * Type guard that checks if a value is a valid AT identifier (DID or handle).\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid AT identifier\n * @see {@link AtIdentifierString}\n */\nexport function isAtIdentifierString<I>(\n input: I,\n): input is I & AtIdentifierString {\n if (!input || typeof input !== 'string') {\n return false\n } else if (input.startsWith('did:')) {\n return isValidDid(input)\n } else {\n return isValidHandle(input)\n }\n}\n\n/**\n * Returns the input if it is a valid {@link AtIdentifierString} format string, or\n * `undefined` if it is not.\n *\n * @see {@link AtIdentifierString}\n */\nexport function ifAtIdentifierString<I>(\n input: I,\n): undefined | (I & AtIdentifierString) {\n return isAtIdentifierString(input) ? input : undefined\n}\n\n// Legacy exports (should we deprecate these ?)\nexport {\n assertAtIdentifierString as ensureValidAtIdentifier,\n isAtIdentifierString as isValidAtIdentifier,\n}\n"]}
1
+ {"version":3,"file":"at-identifier.js","sourceRoot":"","sources":["../src/at-identifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,mBAAmB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrE,OAAO,EAEL,kBAAkB,EAClB,sBAAsB,EACtB,aAAa,GACd,MAAM,aAAa,CAAA;AASpB;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAsB;IACvD,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC,CAAA;AAC7B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,EAAsB;IACpD,OAAO,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;AAC9B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CACtC,KAAQ;IAER,IAAI,CAAC;QACH,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACxC,MAAM,IAAI,SAAS,CAAC,uCAAuC,CAAC,CAAA;QAC9D,CAAC;aAAM,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,mBAAmB,CAAC,KAAK,CAAC,CAAA;QAC5B,CAAC;aAAM,CAAC;YACN,sBAAsB,CAAC,KAAK,CAAC,CAAA;QAC/B,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,kBAAkB,CAAC,uBAAuB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;IAClE,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAI,KAAQ;IAC9C,wBAAwB,CAAC,KAAK,CAAC,CAAA;IAC/B,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAQ;IAER,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,KAAK,CAAA;IACd,CAAC;SAAM,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAA;IAC1B,CAAC;SAAM,CAAC;QACN,OAAO,aAAa,CAAC,KAAK,CAAC,CAAA;IAC7B,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAQ;IAER,OAAO,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AACxD,CAAC;AAED,+CAA+C;AAC/C,OAAO,EACL,wBAAwB,IAAI,uBAAuB,EACnD,oBAAoB,IAAI,mBAAmB,GAC5C,CAAA","sourcesContent":["import { DidString, ensureValidDidRegex, isValidDid } from './did.js'\nimport {\n HandleString,\n InvalidHandleError,\n ensureValidHandleRegex,\n isValidHandle,\n} from './handle.js'\n\n/**\n * An \"at-identifier\" string - either a {@link DidString} or a {@link HandleString}\n *\n * @example `\"did:plc:1234...\"`, `\"did:web:example.com\"` or `\"alice.bsky.social\"`\n */\nexport type AtIdentifierString = DidString | HandleString\n\n/**\n * Discriminates {@link HandleString} from a valid {@link AtIdentifierString}.\n *\n * @return `true` if the identifier is a handle, `false` otherwise\n */\nexport function isHandleIdentifier(id: AtIdentifierString): id is HandleString {\n return !isDidIdentifier(id)\n}\n\n/**\n * Discriminates {@link DidString} from a valid {@link AtIdentifierString}.\n *\n * @return `true` if the identifier is a DID, `false` otherwise\n */\nexport function isDidIdentifier(id: AtIdentifierString): id is DidString {\n return id.startsWith('did:')\n}\n\n/**\n * Validates that a string is a valid {@link AtIdentifierString} format string,\n * throwing an error if it is not.\n *\n * @throws InvalidHandleError if the input string does not meet the atproto 'datetime' format requirements.\n * @see {@link AtIdentifierString}\n */\nexport function assertAtIdentifierString<I>(\n input: I,\n): asserts input is I & AtIdentifierString {\n try {\n if (!input || typeof input !== 'string') {\n throw new TypeError('Identifier must be a non-empty string')\n } else if (input.startsWith('did:')) {\n ensureValidDidRegex(input)\n } else {\n ensureValidHandleRegex(input)\n }\n } catch (cause) {\n throw new InvalidHandleError('Invalid DID or handle', { cause })\n }\n}\n\n/**\n * Casts a string to a {@link AtIdentifierString} if it is a valid at-identifier\n * string, throwing an error if it is not.\n *\n * @throws InvalidHandleError if the input string does not meet the atproto 'at-identifier' format requirements.\n * @see {@link AtIdentifierString}\n */\nexport function asAtIdentifierString<I>(input: I): I & AtIdentifierString {\n assertAtIdentifierString(input)\n return input\n}\n\n/**\n * Type guard that checks if a value is a valid AT identifier (DID or handle).\n *\n * @param value - The value to check\n * @returns `true` if the value is a valid AT identifier\n * @see {@link AtIdentifierString}\n */\nexport function isAtIdentifierString<I>(\n input: I,\n): input is I & AtIdentifierString {\n if (!input || typeof input !== 'string') {\n return false\n } else if (input.startsWith('did:')) {\n return isValidDid(input)\n } else {\n return isValidHandle(input)\n }\n}\n\n/**\n * Returns the input if it is a valid {@link AtIdentifierString} format string, or\n * `undefined` if it is not.\n *\n * @see {@link AtIdentifierString}\n */\nexport function ifAtIdentifierString<I>(\n input: I,\n): undefined | (I & AtIdentifierString) {\n return isAtIdentifierString(input) ? input : undefined\n}\n\n// Legacy exports (should we deprecate these ?)\nexport {\n assertAtIdentifierString as ensureValidAtIdentifier,\n isAtIdentifierString as isValidAtIdentifier,\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"aturi.d.ts","sourceRoot":"","sources":["../src/aturi.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAGnB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,EAAE,SAAS,EAAmB,MAAM,UAAU,CAAA;AACrD,OAAO,EAAE,UAAU,EAAmB,MAAM,WAAW,CAAA;AACvD,OAAO,EAAE,eAAe,EAAwB,MAAM,gBAAgB,CAAA;AAEtE,cAAc,uBAAuB,CAAA;AAGrC,YAAY,EACV,kBAAkB,EAClB,WAAW,EACX,SAAS,EACT,UAAU,EACV,eAAe,GAChB,CAAA;AAED,eAAO,MAAM,aAAa,QAEyE,CAAA;AAInG,qBAAa,KAAK;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,kBAAkB,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,eAAe,CAAA;gBAEjB,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK;IAgB9C,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;IAOnE,IAAI,QAAQ,WAEX;IAED,IAAI,MAAM,gEAET;IAED,IAAI,GAAG,IAAI,SAAS,CAInB;IAED,IAAI,QAAQ,IAAI,kBAAkB,CAEjC;IAED,IAAI,QAAQ,CAAC,CAAC,EAAE,MAAM,EAGrB;IAED,IAAI,MAAM,IAII,MAAM,CAFnB;IAED,IAAI,MAAM,CAAC,CAAC,EAAE,MAAM,EAEnB;IAED,IAAI,UAAU,IAUI,MAAM,CARvB;IAED,IAAI,cAAc,IAAI,UAAU,CAI/B;IAED,IAAI,UAAU,CAAC,CAAC,EAAE,MAAM,EAGvB;IAED,qBAAqB,CAAC,CAAC,EAAE,MAAM;IAM/B,IAAI,IAAI,IAUI,MAAM,CARjB;IAED,IAAI,QAAQ,IAAI,eAAe,CAI9B;IAED,IAAI,IAAI,CAAC,CAAC,EAAE,MAAM,EAGjB;IAED,eAAe,CAAC,CAAC,EAAE,MAAM;IAOzB,IAAI,IAAI,gBAEP;IAED,QAAQ,IAAI,WAAW;CAexB"}
1
+ {"version":3,"file":"aturi.d.ts","sourceRoot":"","sources":["../src/aturi.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAGnB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,EAAE,SAAS,EAAmB,MAAM,UAAU,CAAA;AACrD,OAAO,EAAE,UAAU,EAAmB,MAAM,WAAW,CAAA;AACvD,OAAO,EAAE,eAAe,EAAwB,MAAM,gBAAgB,CAAA;AAEtE,cAAc,uBAAuB,CAAA;AAGrC,YAAY,EACV,kBAAkB,EAClB,WAAW,EACX,SAAS,EACT,UAAU,EACV,eAAe,GAChB,CAAA;AAED,eAAO,MAAM,aAAa,QAEyE,CAAA;AAInG,qBAAa,KAAK;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,kBAAkB,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,eAAe,CAAA;gBAEjB,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK;IAgB9C,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;IAOnE,IAAI,QAAQ,WAEX;IAED,IAAI,MAAM,gEAET;IAED,IAAI,GAAG,IAAI,SAAS,CAInB;IAED,IAAI,QAAQ,IAAI,kBAAkB,CAEjC;IAED,IAAI,QAAQ,CAAC,CAAC,EAAE,MAAM,EAGrB;IAED,IAAI,MAAM,IAII,MAAM,CAFnB;IAED,IAAI,MAAM,CAAC,CAAC,EAAE,MAAM,EAEnB;IAED,IAAI,UAAU,IAUI,MAAM,CARvB;IAED,IAAI,cAAc,IAAI,UAAU,CAI/B;IAED,IAAI,UAAU,CAAC,CAAC,EAAE,MAAM,EAGvB;IAED,qBAAqB,CAAC,CAAC,EAAE,MAAM;IAM/B,IAAI,IAAI,IAUI,MAAM,CARjB;IAED,IAAI,QAAQ,IAAI,eAAe,CAI9B;IAED,IAAI,IAAI,CAAC,CAAC,EAAE,MAAM,EAGjB;IAED,eAAe,CAAC,CAAC,EAAE,MAAM;IAOzB,IAAI,IAAI,gBAEP;IAED,QAAQ,IAAI,WAAW;CAqBxB"}
package/dist/aturi.js CHANGED
@@ -1,29 +1,21 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AtUri = exports.ATP_URI_REGEX = void 0;
4
- const tslib_1 = require("tslib");
5
- const at_identifier_js_1 = require("./at-identifier.js");
6
- const did_js_1 = require("./did.js");
7
- const nsid_js_1 = require("./nsid.js");
8
- const recordkey_js_1 = require("./recordkey.js");
9
- tslib_1.__exportStar(require("./aturi_validation.js"), exports);
10
- exports.ATP_URI_REGEX =
1
+ import { ensureValidAtIdentifier, isDidIdentifier, } from './at-identifier.js';
2
+ import { InvalidDidError } from './did.js';
3
+ import { ensureValidNsid } from './nsid.js';
4
+ import { ensureValidRecordKey } from './recordkey.js';
5
+ export * from './aturi_validation.js';
6
+ export const ATP_URI_REGEX =
11
7
  // proto- --did-------------- --name---------------- --path---- --query-- --hash--
12
8
  /^(at:\/\/)?((?:did:[a-z0-9:%-]+)|(?:[a-z0-9][a-z0-9.:-]*))(\/[^?#\s]*)?(\?[^#\s]+)?(#[^\s]+)?$/i;
13
9
  // --path----- --query-- --hash--
14
10
  const RELATIVE_REGEX = /^(\/[^?#\s]*)?(\?[^#\s]+)?(#[^\s]+)?$/i;
15
- class AtUri {
16
- hash;
17
- host;
18
- pathname;
19
- searchParams;
11
+ export class AtUri {
20
12
  constructor(uri, base) {
21
13
  const parsed = base !== undefined
22
14
  ? typeof base === 'string'
23
15
  ? Object.assign(parse(base), parseRelative(uri))
24
16
  : Object.assign({ host: base.host }, parseRelative(uri))
25
17
  : parse(uri);
26
- (0, at_identifier_js_1.ensureValidAtIdentifier)(parsed.host);
18
+ ensureValidAtIdentifier(parsed.host);
27
19
  this.hash = parsed.hash ?? '';
28
20
  this.host = parsed.host;
29
21
  this.pathname = parsed.pathname ?? '';
@@ -45,15 +37,15 @@ class AtUri {
45
37
  }
46
38
  get did() {
47
39
  const { host } = this;
48
- if ((0, at_identifier_js_1.isDidIdentifier)(host))
40
+ if (isDidIdentifier(host))
49
41
  return host;
50
- throw new did_js_1.InvalidDidError(`AtUri "${this}" does not have a DID hostname`);
42
+ throw new InvalidDidError(`AtUri "${this}" does not have a DID hostname`);
51
43
  }
52
44
  get hostname() {
53
45
  return this.host;
54
46
  }
55
47
  set hostname(v) {
56
- (0, at_identifier_js_1.ensureValidAtIdentifier)(v);
48
+ ensureValidAtIdentifier(v);
57
49
  this.host = v;
58
50
  }
59
51
  get search() {
@@ -67,11 +59,11 @@ class AtUri {
67
59
  }
68
60
  get collectionSafe() {
69
61
  const { collection } = this;
70
- (0, nsid_js_1.ensureValidNsid)(collection);
62
+ ensureValidNsid(collection);
71
63
  return collection;
72
64
  }
73
65
  set collection(v) {
74
- (0, nsid_js_1.ensureValidNsid)(v);
66
+ ensureValidNsid(v);
75
67
  this.unsafelySetCollection(v);
76
68
  }
77
69
  unsafelySetCollection(v) {
@@ -84,11 +76,11 @@ class AtUri {
84
76
  }
85
77
  get rkeySafe() {
86
78
  const { rkey } = this;
87
- (0, recordkey_js_1.ensureValidRecordKey)(rkey);
79
+ ensureValidRecordKey(rkey);
88
80
  return rkey;
89
81
  }
90
82
  set rkey(v) {
91
- (0, recordkey_js_1.ensureValidRecordKey)(v);
83
+ ensureValidRecordKey(v);
92
84
  this.unsafelySetRkey(v);
93
85
  }
94
86
  unsafelySetRkey(v) {
@@ -101,24 +93,30 @@ class AtUri {
101
93
  return this.toString();
102
94
  }
103
95
  toString() {
104
- let path = this.pathname || '/';
105
- if (!path.startsWith('/')) {
106
- path = `/${path}`;
96
+ let pathname = this.pathname;
97
+ if (pathname && !pathname.startsWith('/')) {
98
+ pathname = `/${pathname}`;
99
+ }
100
+ while (pathname.endsWith('/')) {
101
+ pathname = pathname.slice(0, -1);
107
102
  }
108
103
  let qs = '';
109
104
  if (this.searchParams.size) {
110
105
  qs = `?${this.searchParams.toString()}`;
111
106
  }
112
- let hash = this.hash;
113
- if (hash && !hash.startsWith('#')) {
114
- hash = `#${hash}`;
107
+ // @NOTE We keep the hash as-is, even if it doesn't start with a '/'.
108
+ let fragment = this.hash;
109
+ if (fragment === '#') {
110
+ fragment = '';
111
+ }
112
+ else if (fragment && !fragment.startsWith('#')) {
113
+ fragment = `#${fragment}`;
115
114
  }
116
- return `at://${this.host}${path}${qs}${hash}`;
115
+ return `at://${this.host}${pathname}${qs}${fragment}`;
117
116
  }
118
117
  }
119
- exports.AtUri = AtUri;
120
118
  function parse(str) {
121
- const match = str.match(exports.ATP_URI_REGEX);
119
+ const match = str.match(ATP_URI_REGEX);
122
120
  if (!match) {
123
121
  throw new Error(`Invalid AT uri: ${str}`);
124
122
  }
package/dist/aturi.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"aturi.js","sourceRoot":"","sources":["../src/aturi.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AtIdentifierString,\n ensureValidAtIdentifier,\n isDidIdentifier,\n} from './at-identifier.js'\nimport { AtUriString } from './aturi_validation.js'\nimport { DidString, InvalidDidError } from './did.js'\nimport { NsidString, ensureValidNsid } from './nsid.js'\nimport { RecordKeyString, ensureValidRecordKey } from './recordkey.js'\n\nexport * from './aturi_validation.js'\n\n// Re-export types used in public interface\nexport type {\n AtIdentifierString,\n AtUriString,\n DidString,\n NsidString,\n RecordKeyString,\n}\n\nexport const ATP_URI_REGEX =\n // proto- --did-------------- --name---------------- --path---- --query-- --hash--\n /^(at:\\/\\/)?((?:did:[a-z0-9:%-]+)|(?:[a-z0-9][a-z0-9.:-]*))(\\/[^?#\\s]*)?(\\?[^#\\s]+)?(#[^\\s]+)?$/i\n// --path----- --query-- --hash--\nconst RELATIVE_REGEX = /^(\\/[^?#\\s]*)?(\\?[^#\\s]+)?(#[^\\s]+)?$/i\n\nexport class AtUri {\n hash: string\n host: AtIdentifierString\n pathname: string\n searchParams: URLSearchParams\n\n constructor(uri: string, base?: string | AtUri) {\n const parsed =\n base !== undefined\n ? typeof base === 'string'\n ? Object.assign(parse(base), parseRelative(uri))\n : Object.assign({ host: base.host }, parseRelative(uri))\n : parse(uri)\n\n ensureValidAtIdentifier(parsed.host)\n\n this.hash = parsed.hash ?? ''\n this.host = parsed.host\n this.pathname = parsed.pathname ?? ''\n this.searchParams = parsed.searchParams\n }\n\n static make(handleOrDid: string, collection?: string, rkey?: string) {\n let str = handleOrDid\n if (collection) str += '/' + collection\n if (rkey) str += '/' + rkey\n return new AtUri(str)\n }\n\n get protocol() {\n return 'at:'\n }\n\n get origin() {\n return `at://${this.host}` as const\n }\n\n get did(): DidString {\n const { host } = this\n if (isDidIdentifier(host)) return host\n throw new InvalidDidError(`AtUri \"${this}\" does not have a DID hostname`)\n }\n\n get hostname(): AtIdentifierString {\n return this.host\n }\n\n set hostname(v: string) {\n ensureValidAtIdentifier(v)\n this.host = v\n }\n\n get search() {\n return this.searchParams.toString()\n }\n\n set search(v: string) {\n this.searchParams = new URLSearchParams(v)\n }\n\n get collection() {\n return this.pathname.split('/').filter(Boolean)[0] || ''\n }\n\n get collectionSafe(): NsidString {\n const { collection } = this\n ensureValidNsid(collection)\n return collection\n }\n\n set collection(v: string) {\n ensureValidNsid(v)\n this.unsafelySetCollection(v)\n }\n\n unsafelySetCollection(v: string) {\n const parts = this.pathname.split('/').filter(Boolean)\n parts[0] = v\n this.pathname = parts.join('/')\n }\n\n get rkey() {\n return this.pathname.split('/').filter(Boolean)[1] || ''\n }\n\n get rkeySafe(): RecordKeyString {\n const { rkey } = this\n ensureValidRecordKey(rkey)\n return rkey\n }\n\n set rkey(v: string) {\n ensureValidRecordKey(v)\n this.unsafelySetRkey(v)\n }\n\n unsafelySetRkey(v: string) {\n const parts = this.pathname.split('/').filter(Boolean)\n parts[0] ||= 'undefined'\n parts[1] = v\n this.pathname = parts.join('/')\n }\n\n get href() {\n return this.toString()\n }\n\n toString(): AtUriString {\n let path = this.pathname || '/'\n if (!path.startsWith('/')) {\n path = `/${path}`\n }\n let qs = ''\n if (this.searchParams.size) {\n qs = `?${this.searchParams.toString()}`\n }\n let hash = this.hash\n if (hash && !hash.startsWith('#')) {\n hash = `#${hash}`\n }\n return `at://${this.host}${path}${qs}${hash}` as AtUriString\n }\n}\n\nfunction parse(str: string) {\n const match = str.match(ATP_URI_REGEX) as null | {\n 0: string\n 1: string | undefined // proto\n 2: string // host\n 3: string | undefined // path\n 4: string | undefined // query\n 5: string | undefined // hash\n }\n\n if (!match) {\n throw new Error(`Invalid AT uri: ${str}`)\n }\n\n return {\n host: match[2],\n hash: match[5],\n pathname: match[3],\n searchParams: new URLSearchParams(match[4]),\n }\n}\n\nfunction parseRelative(str: string) {\n const match = str.match(RELATIVE_REGEX) as null | {\n 0: string\n 1: string | undefined // path\n 2: string | undefined // query\n 3: string | undefined // hash\n }\n\n if (!match) {\n throw new Error(`Invalid path: ${str}`)\n }\n\n return {\n hash: match[3],\n pathname: match[1],\n searchParams: new URLSearchParams(match[2]),\n }\n}\n"]}
1
+ {"version":3,"file":"aturi.js","sourceRoot":"","sources":["../src/aturi.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AtIdentifierString,\n ensureValidAtIdentifier,\n isDidIdentifier,\n} from './at-identifier.js'\nimport { AtUriString } from './aturi_validation.js'\nimport { DidString, InvalidDidError } from './did.js'\nimport { NsidString, ensureValidNsid } from './nsid.js'\nimport { RecordKeyString, ensureValidRecordKey } from './recordkey.js'\n\nexport * from './aturi_validation.js'\n\n// Re-export types used in public interface\nexport type {\n AtIdentifierString,\n AtUriString,\n DidString,\n NsidString,\n RecordKeyString,\n}\n\nexport const ATP_URI_REGEX =\n // proto- --did-------------- --name---------------- --path---- --query-- --hash--\n /^(at:\\/\\/)?((?:did:[a-z0-9:%-]+)|(?:[a-z0-9][a-z0-9.:-]*))(\\/[^?#\\s]*)?(\\?[^#\\s]+)?(#[^\\s]+)?$/i\n// --path----- --query-- --hash--\nconst RELATIVE_REGEX = /^(\\/[^?#\\s]*)?(\\?[^#\\s]+)?(#[^\\s]+)?$/i\n\nexport class AtUri {\n hash: string\n host: AtIdentifierString\n pathname: string\n searchParams: URLSearchParams\n\n constructor(uri: string, base?: string | AtUri) {\n const parsed =\n base !== undefined\n ? typeof base === 'string'\n ? Object.assign(parse(base), parseRelative(uri))\n : Object.assign({ host: base.host }, parseRelative(uri))\n : parse(uri)\n\n ensureValidAtIdentifier(parsed.host)\n\n this.hash = parsed.hash ?? ''\n this.host = parsed.host\n this.pathname = parsed.pathname ?? ''\n this.searchParams = parsed.searchParams\n }\n\n static make(handleOrDid: string, collection?: string, rkey?: string) {\n let str = handleOrDid\n if (collection) str += '/' + collection\n if (rkey) str += '/' + rkey\n return new AtUri(str)\n }\n\n get protocol() {\n return 'at:'\n }\n\n get origin() {\n return `at://${this.host}` as const\n }\n\n get did(): DidString {\n const { host } = this\n if (isDidIdentifier(host)) return host\n throw new InvalidDidError(`AtUri \"${this}\" does not have a DID hostname`)\n }\n\n get hostname(): AtIdentifierString {\n return this.host\n }\n\n set hostname(v: string) {\n ensureValidAtIdentifier(v)\n this.host = v\n }\n\n get search() {\n return this.searchParams.toString()\n }\n\n set search(v: string) {\n this.searchParams = new URLSearchParams(v)\n }\n\n get collection() {\n return this.pathname.split('/').filter(Boolean)[0] || ''\n }\n\n get collectionSafe(): NsidString {\n const { collection } = this\n ensureValidNsid(collection)\n return collection\n }\n\n set collection(v: string) {\n ensureValidNsid(v)\n this.unsafelySetCollection(v)\n }\n\n unsafelySetCollection(v: string) {\n const parts = this.pathname.split('/').filter(Boolean)\n parts[0] = v\n this.pathname = parts.join('/')\n }\n\n get rkey() {\n return this.pathname.split('/').filter(Boolean)[1] || ''\n }\n\n get rkeySafe(): RecordKeyString {\n const { rkey } = this\n ensureValidRecordKey(rkey)\n return rkey\n }\n\n set rkey(v: string) {\n ensureValidRecordKey(v)\n this.unsafelySetRkey(v)\n }\n\n unsafelySetRkey(v: string) {\n const parts = this.pathname.split('/').filter(Boolean)\n parts[0] ||= 'undefined'\n parts[1] = v\n this.pathname = parts.join('/')\n }\n\n get href() {\n return this.toString()\n }\n\n toString(): AtUriString {\n let pathname = this.pathname\n if (pathname && !pathname.startsWith('/')) {\n pathname = `/${pathname}`\n }\n while (pathname.endsWith('/')) {\n pathname = pathname.slice(0, -1)\n }\n let qs = ''\n if (this.searchParams.size) {\n qs = `?${this.searchParams.toString()}`\n }\n // @NOTE We keep the hash as-is, even if it doesn't start with a '/'.\n let fragment = this.hash\n if (fragment === '#') {\n fragment = ''\n } else if (fragment && !fragment.startsWith('#')) {\n fragment = `#${fragment}`\n }\n return `at://${this.host}${pathname}${qs}${fragment}` as AtUriString\n }\n}\n\nfunction parse(str: string) {\n const match = str.match(ATP_URI_REGEX) as null | {\n 0: string\n 1: string | undefined // proto\n 2: string // host\n 3: string | undefined // path\n 4: string | undefined // query\n 5: string | undefined // hash\n }\n\n if (!match) {\n throw new Error(`Invalid AT uri: ${str}`)\n }\n\n return {\n host: match[2],\n hash: match[5],\n pathname: match[3],\n searchParams: new URLSearchParams(match[4]),\n }\n}\n\nfunction parseRelative(str: string) {\n const match = str.match(RELATIVE_REGEX) as null | {\n 0: string\n 1: string | undefined // path\n 2: string | undefined // query\n 3: string | undefined // hash\n }\n\n if (!match) {\n throw new Error(`Invalid path: ${str}`)\n }\n\n return {\n hash: match[3],\n pathname: match[1],\n searchParams: new URLSearchParams(match[2]),\n }\n}\n"]}
@@ -1,7 +1,140 @@
1
1
  import { AtIdentifierString } from './at-identifier.js';
2
+ import { Result } from './lib/result.js';
2
3
  import { NsidString } from './nsid.js';
3
- export type AtUriString = `at://${AtIdentifierString}` | `at://${AtIdentifierString}/${NsidString}` | `at://${AtIdentifierString}/${NsidString}/${string}`;
4
- export declare function ensureValidAtUri<I extends string>(input: I): asserts input is I & AtUriString;
5
- export declare function ensureValidAtUriRegex<I extends string>(input: I): asserts input is I & AtUriString;
6
- export declare function isValidAtUri<I extends string>(input: I): input is I & AtUriString;
4
+ export type AtUriStringBase = `at://${AtIdentifierString}` | `at://${AtIdentifierString}/${NsidString}` | `at://${AtIdentifierString}/${NsidString}/${string}`;
5
+ export type AtUriStringFragment = `#/${string}`;
6
+ /**
7
+ * A URI string as used to point at resources in the AT Protocol
8
+ *
9
+ * The full, general structure of an AT URI is:
10
+ *
11
+ * ```bnf
12
+ * AT-URI = "at://" AUTHORITY [ PATH ] [ "?" QUERY ] [ "#" FRAGMENT ]
13
+ * ```
14
+ *
15
+ * The authority part of the URI can be either a handle or a DID, indicating the
16
+ * identity associated with the repository. In current atproto Lexicon use, the
17
+ * query and fragment parts are not yet supported, and only a fixed pattern of
18
+ * paths are allowed:
19
+ *
20
+ * ```bnf
21
+ * AT-URI = "at://" AUTHORITY [ "/" COLLECTION [ "/" RKEY ] ]
22
+ *
23
+ * AUTHORITY = HANDLE | DID
24
+ * COLLECTION = NSID
25
+ * RKEY = RECORD-KEY
26
+ * ```
27
+ *
28
+ * The authority section is required, and should be normalized.
29
+ *
30
+ * AT URI strings must respect the following syntax (as prescribed by the AT
31
+ * protocol specification):
32
+ *
33
+ * - The overall URI is restricted to a subset of ASCII characters
34
+ * - For reference below, the set of unreserved characters, as defined in [RFC-3986](https://www.rfc-editor.org/rfc/rfc3986), includes alphanumeric (`A-Za-z0-9`), period, hyphen, underscore, and tilde (`.-_~`)
35
+ * - Maximum overall length is 8 kilobytes (which may be shortened in the future)
36
+ * - Hex-encoding of characters is permitted (but in practice not necessary and should be avoided to keep the URI normalized and human-readable)
37
+ * - The URI scheme is `at`, and an authority part preceded with double slashes is always required. AT URIs always start with `at://`.
38
+ * - An authority section is required and must be non-empty. the authority can be either an atproto Handle, or a DID meeting the restrictions for use with atproto. The authority part can *not* be interpreted as a host:port pair, because of the use of colon characters (`:`) in DIDs. Colons and unreserved characters should not be escaped in DIDs, but other reserved characters (including `#`, `/`, `$`, `&`, `@`) must be escaped.
39
+ * - Note that none of the current "blessed" DID methods for atproto allow these characters in DID identifiers
40
+ * - An optional path section may follow the authority. The path may contain multiple segments separated by a single slash (`/`). Generic URI path normalization rules may be used.
41
+ * - An optional query part is allowed, following generic URI syntax restrictions
42
+ * - An optional fragment part is allowed, using JSON Path syntax
43
+ *
44
+ * @example "at://did:plc:ewvi7nxzyoun6zhxrhs64oiz/app.bsky.actor.profile/self"
45
+ *
46
+ * @see {@link https://atproto.com/specs/at-uri-scheme AT protocol - AT URI Scheme}
47
+ */
48
+ export type AtUriString = AtUriStringBase | `${AtUriStringBase}${AtUriStringFragment}`;
49
+ /**
50
+ * Type guard that checks if a value is a valid {@link AtUriString}
51
+ *
52
+ * @see {@link AtUriString}
53
+ */
54
+ export declare function isAtUriString<I>(input: I, options?: Omit<ParseAtUriStringOptions, 'detailed'>): input is I & AtUriString;
55
+ /**
56
+ * Returns the input if it is a valid {@link AtUriString} format string, or
57
+ * `undefined` if it is not.
58
+ *
59
+ * @see {@link AtUriString}
60
+ */
61
+ export declare function ifAtUriString<I>(input: I, options?: Omit<ParseAtUriStringOptions, 'detailed'>): undefined | (I & AtUriString);
62
+ /**
63
+ * Casts a string to an {@link AtUriString} if it is a valid AT URI format
64
+ * string, throwing an error if it is not.
65
+ *
66
+ * @throws InvalidAtUriError if the input string does not meet the atproto AT URI format requirements.
67
+ * @see {@link AtUriString}
68
+ */
69
+ export declare function asAtUriString<I>(input: I, options?: ParseAtUriStringOptions): I & AtUriString;
70
+ /**
71
+ * Assert the validity of an {@link AtUriString}, throwing an error if the
72
+ * {@link input} is not a valid AT URI.
73
+ *
74
+ * @throws InvalidAtUriError if the {@link input} is not a valid {@link AtUriString}
75
+ */
76
+ export declare function assertAtUriString<I>(input: I, options?: ParseAtUriStringOptions): asserts input is I & AtUriString;
77
+ /**
78
+ * Assert the **non-strict** validity of an {@link AtUriString}, throwing a
79
+ * detailed error if the {@link input} is not a valid AT URI.
80
+ *
81
+ * @throws InvalidAtUriError if the {@link input} is not a valid {@link AtUriString}
82
+ * @deprecated use {@link assertAtUriString} with `{ strict: false }` option instead
83
+ */
84
+ export declare function ensureValidAtUri<I>(input: I): asserts input is I & AtUriString;
85
+ /**
86
+ * Assert the (non-strict!) validity of an {@link AtUriString}, throwing an
87
+ * error if the {@link input} is not a valid AT URI.
88
+ *
89
+ * @throws InvalidAtUriError if the {@link input} is not a valid {@link AtUriString}
90
+ * @deprecated use {@link assertAtUriString} with `{ strict: false }` option instead
91
+ */
92
+ export declare function ensureValidAtUriRegex<I>(input: I): asserts input is I & AtUriString;
93
+ /**
94
+ * Type guard that checks if a value is a valid {@link AtUriString} format
95
+ * string, without enforcing strict record key validation. This is useful for
96
+ * cases where you want to allow a wider range of valid ATURIs, such as when
97
+ * validating user input or when the record key is not relevant.
98
+ *
99
+ * @deprecated use {@link isAtUriString} with `{ strict: false }` option instead
100
+ */
101
+ export declare function isValidAtUri<I>(input: I): input is I & AtUriString;
102
+ export declare class InvalidAtUriError extends Error {
103
+ }
104
+ export type ParseAtUriStringOptions = {
105
+ /**
106
+ * If true, the parser will enforce that the record key (rkey) part of the URI
107
+ * is a valid record key (validated by {@link isValidRecordKey}). If false,
108
+ * any non-empty string of allowed chars will be accepted as a record key.
109
+ *
110
+ * @default true
111
+ */
112
+ strict?: boolean;
113
+ /**
114
+ * If true, the parser will return detailed error messages for why a string is
115
+ * not a valid AT URI. This option has no effect on the behavior of
116
+ * {@link isAtUriString}, which will always return false for invalid strings
117
+ * regardless of this option.
118
+ *
119
+ * @default false
120
+ */
121
+ detailed?: boolean;
122
+ };
123
+ export type AtUriParts = {
124
+ authority: AtIdentifierString;
125
+ query?: string;
126
+ hash?: string;
127
+ } & ({
128
+ collection?: NsidString;
129
+ rkey?: undefined;
130
+ } | {
131
+ collection: NsidString;
132
+ rkey?: string;
133
+ });
134
+ /**
135
+ * Parses a valid {@link AtUriString} into a {@link AtUriParts} object, or
136
+ * returns a failure with a detailed error message if the string is not a valid
137
+ * {@link AtUriString}.
138
+ */
139
+ export declare function parseAtUriString(input: unknown, options?: ParseAtUriStringOptions): Result<AtUriParts>;
7
140
  //# sourceMappingURL=aturi_validation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"aturi_validation.d.ts","sourceRoot":"","sources":["../src/aturi_validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA2B,MAAM,oBAAoB,CAAA;AAGhF,OAAO,EAAE,UAAU,EAAe,MAAM,WAAW,CAAA;AAEnD,MAAM,MAAM,WAAW,GACnB,QAAQ,kBAAkB,EAAE,GAC5B,QAAQ,kBAAkB,IAAI,UAAU,EAAE,GAC1C,QAAQ,kBAAkB,IAAI,UAAU,IAAI,MAAM,EAAE,CAAA;AAgBxD,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAC/C,KAAK,EAAE,CAAC,GACP,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,WAAW,CAiFlC;AAED,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,EACpD,KAAK,EAAE,CAAC,GACP,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,WAAW,CA4BlC;AAED,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC3C,KAAK,EAAE,CAAC,GACP,KAAK,IAAI,CAAC,GAAG,WAAW,CAQ1B"}
1
+ {"version":3,"file":"aturi_validation.d.ts","sourceRoot":"","sources":["../src/aturi_validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAwB,MAAM,oBAAoB,CAAA;AAC7E,OAAO,EAAE,MAAM,EAAoB,MAAM,iBAAiB,CAAA;AAC1D,OAAO,EAAE,UAAU,EAAe,MAAM,WAAW,CAAA;AAGnD,MAAM,MAAM,eAAe,GACvB,QAAQ,kBAAkB,EAAE,GAC5B,QAAQ,kBAAkB,IAAI,UAAU,EAAE,GAC1C,QAAQ,kBAAkB,IAAI,UAAU,IAAI,MAAM,EAAE,CAAA;AAExD,MAAM,MAAM,mBAAmB,GAAG,KAAK,MAAM,EAAE,CAAA;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,MAAM,MAAM,WAAW,GACnB,eAAe,GACf,GAAG,eAAe,GAAG,mBAAmB,EAAE,CAAA;AAE9C;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAC7B,KAAK,EAAE,CAAC,EACR,OAAO,CAAC,EAAE,IAAI,CAAC,uBAAuB,EAAE,UAAU,CAAC,GAClD,KAAK,IAAI,CAAC,GAAG,WAAW,CAE1B;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAC7B,KAAK,EAAE,CAAC,EACR,OAAO,CAAC,EAAE,IAAI,CAAC,uBAAuB,EAAE,UAAU,CAAC,GAClD,SAAS,GAAG,CAAC,CAAC,GAAG,WAAW,CAAC,CAE/B;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAC7B,KAAK,EAAE,CAAC,EACR,OAAO,CAAC,EAAE,uBAAuB,GAChC,CAAC,GAAG,WAAW,CAGjB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,KAAK,EAAE,CAAC,EACR,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,WAAW,CASlC;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,KAAK,EAAE,CAAC,GACP,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,WAAW,CAElC;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,KAAK,EAAE,CAAC,GACP,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,WAAW,CAElC;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,WAAW,CAElE;AAED,qBAAa,iBAAkB,SAAQ,KAAK;CAAG;AAE/C,MAAM,MAAM,uBAAuB,GAAG;IACpC;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,kBAAkB,CAAA;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,GAAG,CACA;IAAE,UAAU,CAAC,EAAE,UAAU,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,CAAA;CAAE,GAC7C;IAAE,UAAU,EAAE,UAAU,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAC5C,CAAA;AAMD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,uBAAuB,GAChC,MAAM,CAAC,UAAU,CAAC,CAsFpB"}