@haverstack/core 0.8.0 → 0.10.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 (65) hide show
  1. package/README.md +30 -14
  2. package/dist/access.d.ts +20 -7
  3. package/dist/access.d.ts.map +1 -1
  4. package/dist/access.js +37 -16
  5. package/dist/access.js.map +1 -1
  6. package/dist/adapter-entry.d.ts +12 -0
  7. package/dist/adapter-entry.d.ts.map +1 -0
  8. package/dist/adapter-entry.js +11 -0
  9. package/dist/adapter-entry.js.map +1 -0
  10. package/dist/attachment-download.d.ts +75 -0
  11. package/dist/attachment-download.d.ts.map +1 -0
  12. package/dist/attachment-download.js +128 -0
  13. package/dist/attachment-download.js.map +1 -0
  14. package/dist/auth.d.ts +88 -0
  15. package/dist/auth.d.ts.map +1 -0
  16. package/dist/auth.js +145 -0
  17. package/dist/auth.js.map +1 -0
  18. package/dist/combine.d.ts.map +1 -1
  19. package/dist/combine.js +20 -3
  20. package/dist/combine.js.map +1 -1
  21. package/dist/did-entry.d.ts +12 -0
  22. package/dist/did-entry.d.ts.map +1 -0
  23. package/dist/did-entry.js +16 -0
  24. package/dist/did-entry.js.map +1 -0
  25. package/dist/did.d.ts +51 -0
  26. package/dist/did.d.ts.map +1 -0
  27. package/dist/did.js +153 -0
  28. package/dist/did.js.map +1 -0
  29. package/dist/id.d.ts +18 -6
  30. package/dist/id.d.ts.map +1 -1
  31. package/dist/id.js +39 -10
  32. package/dist/id.js.map +1 -1
  33. package/dist/index.d.ts +15 -10
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +14 -9
  36. package/dist/index.js.map +1 -1
  37. package/dist/merge.d.ts +11 -0
  38. package/dist/merge.d.ts.map +1 -0
  39. package/dist/merge.js +38 -0
  40. package/dist/merge.js.map +1 -0
  41. package/dist/schema.d.ts +31 -9
  42. package/dist/schema.d.ts.map +1 -1
  43. package/dist/schema.js +134 -11
  44. package/dist/schema.js.map +1 -1
  45. package/dist/stack.d.ts +850 -152
  46. package/dist/stack.d.ts.map +1 -1
  47. package/dist/stack.js +2017 -365
  48. package/dist/stack.js.map +1 -1
  49. package/dist/testing.d.ts +85 -23
  50. package/dist/testing.d.ts.map +1 -1
  51. package/dist/testing.js +261 -19
  52. package/dist/testing.js.map +1 -1
  53. package/dist/types.d.ts +281 -31
  54. package/dist/types.d.ts.map +1 -1
  55. package/dist/types.js +14 -0
  56. package/dist/types.js.map +1 -1
  57. package/dist/validate.d.ts +26 -0
  58. package/dist/validate.d.ts.map +1 -1
  59. package/dist/validate.js +51 -1
  60. package/dist/validate.js.map +1 -1
  61. package/dist/wire-entry.d.ts +17 -0
  62. package/dist/wire-entry.d.ts.map +1 -0
  63. package/dist/wire-entry.js +24 -0
  64. package/dist/wire-entry.js.map +1 -0
  65. package/package.json +13 -1
package/dist/auth.js ADDED
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Stack — Authentication handshake primitives
3
+ * -------------------------------------------------------
4
+ * The challenge–response handshake proves a client holds the key behind a
5
+ * DID, so a server can issue it a bearer token without an out-of-band
6
+ * secret handoff. See docs/spec/wire-format.md § Authentication.
7
+ *
8
+ * What lives here is the half both sides must agree on byte for byte: the
9
+ * payload that gets signed. A client builds it to sign; a server builds it
10
+ * to verify. Two implementations of "the same string" would diverge on the
11
+ * first ambiguity, and the failure mode is a signature that verifies
12
+ * against a payload nobody meant — so there is one constructor, exported,
13
+ * the same way the attachment content-type policy is shared rather than
14
+ * re-derived.
15
+ *
16
+ * Core verifies signatures; it does not run a server. Nonce storage,
17
+ * single-use enforcement and token issuance are the server's.
18
+ */
19
+ import { isValidDid, signWithDid, verifyDidSignature } from './did.js';
20
+ // -------------------------------------------------------
21
+ // Errors
22
+ // -------------------------------------------------------
23
+ /**
24
+ * Malformed input to a handshake primitive — a bad origin, DID, or nonce,
25
+ * caught locally before anything is signed or verified. Outside the
26
+ * StackError hierarchy, like InvalidDidError: no Stack operation has begun,
27
+ * so there is no wire code or status to carry (docs/spec/wire-format.md
28
+ * § The taxonomy root).
29
+ */
30
+ export class InvalidAuthChallengeError extends Error {
31
+ constructor(message = '') {
32
+ super(message || 'Invalid authentication challenge.');
33
+ this.name = 'InvalidAuthChallengeError';
34
+ }
35
+ }
36
+ // -------------------------------------------------------
37
+ // The signed payload
38
+ // -------------------------------------------------------
39
+ /**
40
+ * Domain-separation tag. Version it rather than the payload's shape: a
41
+ * future signing primitive picks its own tag, so no signature made for one
42
+ * purpose can ever verify as another.
43
+ */
44
+ export const AUTH_PAYLOAD_LABEL = 'haverstack-auth-v1';
45
+ /**
46
+ * A server-issued nonce is opaque, but not arbitrary — it lands in a
47
+ * newline-delimited payload, so the charset is what keeps a nonce from
48
+ * spanning fields. base64url, hex and UUID all satisfy it.
49
+ */
50
+ const NONCE_FORMAT = /^[A-Za-z0-9_-]+$/;
51
+ /**
52
+ * Reduce a URL to the origin form the payload uses: scheme, host and a
53
+ * non-default port. A client derives it from the URL it dialed; a server
54
+ * MUST derive it from its own configured public origin rather than from a
55
+ * request header, which a client controls.
56
+ */
57
+ export const authOriginFromUrl = (url) => {
58
+ let parsed;
59
+ try {
60
+ parsed = new URL(url);
61
+ }
62
+ catch {
63
+ throw new InvalidAuthChallengeError(`Not a valid URL: "${url}"`);
64
+ }
65
+ // Opaque origins ("null") come from schemes with no host to bind to —
66
+ // there is nothing for a signature to be scoped by.
67
+ if (parsed.origin === 'null') {
68
+ throw new InvalidAuthChallengeError(`URL has no origin to bind a signature to: "${url}"`);
69
+ }
70
+ return parsed.origin;
71
+ };
72
+ /**
73
+ * Build the exact bytes a client signs and a server verifies.
74
+ *
75
+ * The origin is in the payload because the nonce alone doesn't scope a
76
+ * signature to a server: one that a client connects to can fetch a
77
+ * challenge from the client's real stack, pass that nonce along, and
78
+ * redeem the returned signature as a token. Signing the origin the client
79
+ * believes it is talking to makes such a signature verify nowhere else.
80
+ */
81
+ export const buildAuthChallengePayload = (challenge) => {
82
+ const origin = authOriginFromUrl(challenge.origin);
83
+ if (!isValidDid(challenge.did)) {
84
+ throw new InvalidAuthChallengeError(`Not a valid DID: "${challenge.did}"`);
85
+ }
86
+ if (!NONCE_FORMAT.test(challenge.nonce)) {
87
+ throw new InvalidAuthChallengeError('Nonce must be a non-empty string of unreserved base64url characters.');
88
+ }
89
+ return new TextEncoder().encode(`${AUTH_PAYLOAD_LABEL}\n${origin}\n${challenge.did}\n${challenge.nonce}`);
90
+ };
91
+ // -------------------------------------------------------
92
+ // Sign / verify
93
+ // -------------------------------------------------------
94
+ /** Sign a challenge with the private key behind its DID. */
95
+ export const signAuthChallenge = async (privateKey, challenge) => signWithDid(privateKey, buildAuthChallengePayload(challenge));
96
+ /**
97
+ * Verify a challenge signature. Answers only "this signature was made by
98
+ * the key behind this DID, for this origin and nonce" — whether the nonce
99
+ * was ever issued, is unexpired, and has not already been spent is the
100
+ * server's to track, and all three matter.
101
+ */
102
+ export const verifyAuthChallenge = async (challenge, signature) => {
103
+ const payload = buildAuthChallengePayload(challenge);
104
+ try {
105
+ return await verifyDidSignature(challenge.did, signature, payload);
106
+ }
107
+ catch {
108
+ // A DID whose key can't be decoded verifies nothing — a false answer,
109
+ // not an exceptional one, since the caller asked whether it verifies.
110
+ return false;
111
+ }
112
+ };
113
+ /**
114
+ * Build a credential from a keypair, for callers holding key material in
115
+ * process and wanting no ceremony. Anything else implements DidCredential
116
+ * directly.
117
+ */
118
+ export const didCredentialFromKeypair = (keypair) => ({
119
+ did: keypair.did,
120
+ sign: (payload) => signWithDid(keypair.privateKey, payload),
121
+ });
122
+ // -------------------------------------------------------
123
+ // base64url — how a signature travels in JSON
124
+ // -------------------------------------------------------
125
+ export const base64urlEncode = (bytes) => {
126
+ let binary = '';
127
+ for (const byte of bytes)
128
+ binary += String.fromCharCode(byte);
129
+ return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
130
+ };
131
+ export const base64urlDecode = (encoded) => {
132
+ if (!NONCE_FORMAT.test(encoded)) {
133
+ throw new InvalidAuthChallengeError('Not valid base64url.');
134
+ }
135
+ const padded = encoded.replace(/-/g, '+').replace(/_/g, '/');
136
+ let binary;
137
+ try {
138
+ binary = atob(padded);
139
+ }
140
+ catch {
141
+ throw new InvalidAuthChallengeError('Not valid base64url.');
142
+ }
143
+ return Uint8Array.from(binary, (char) => char.charCodeAt(0));
144
+ };
145
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"combine.d.ts","sourceRoot":"","sources":["../src/combine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAErF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,gBAAgB,CAAC;CACxB,GAAG,YAAY,CA0Cf"}
1
+ {"version":3,"file":"combine.d.ts","sourceRoot":"","sources":["../src/combine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAErF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,gBAAgB,CAAC;CACxB,GAAG,YAAY,CA8Df"}
package/dist/combine.js CHANGED
@@ -18,20 +18,37 @@ export function combineAdapters(parts) {
18
18
  },
19
19
  createRecord: (r) => parts.record.createRecord(r),
20
20
  getRecord: (id) => parts.record.getRecord(id),
21
- updateRecord: (id, changes) => parts.record.updateRecord(id, changes),
21
+ patchContent: (id, patch, opts) => parts.record.patchContent(id, patch, opts),
22
22
  deleteRecord: (id, opts) => parts.record.deleteRecord(id, opts),
23
+ undeleteRecord: (id, opts) => parts.record.undeleteRecord(id, opts),
23
24
  queryRecords: (q) => parts.record.queryRecords(q),
24
- associate: (id, assoc) => parts.record.associate(id, assoc),
25
- dissociate: (id, assoc) => parts.record.dissociate(id, assoc),
25
+ associate: (id, assoc, opts) => parts.record.associate(id, assoc, opts),
26
+ dissociate: (id, assoc, opts) => parts.record.dissociate(id, assoc, opts),
27
+ setPermissions: (id, permissions, opts) => parts.record.setPermissions(id, permissions, opts),
26
28
  getVersions: (id) => parts.record.getVersions(id),
27
29
  getVersion: (id, v) => parts.record.getVersion(id, v),
28
30
  saveVersion: (id, v) => parts.record.saveVersion(id, v),
31
+ restoreVersion: (id, v, opts) => parts.record.restoreVersion(id, v, opts),
32
+ commitMigration: (id, toTypeId, content, opts) => parts.record.commitMigration(id, toTypeId, content, opts),
29
33
  saveType: (t) => parts.record.saveType(t),
30
34
  getType: (id) => parts.record.getType(id),
31
35
  listTypes: () => parts.record.listTypes(),
36
+ // Conditionally spread so an unimplemented optional capability stays
37
+ // absent on the combined adapter, rather than silently becoming
38
+ // "supported" via a wrapper that forwards to a missing method.
39
+ ...(parts.record.deleteUnreferencedAttachmentRecords && {
40
+ deleteUnreferencedAttachmentRecords: (fileId, metadataTypeId) => parts.record.deleteUnreferencedAttachmentRecords(fileId, metadataTypeId),
41
+ }),
42
+ // StackAdapter.putAttachmentWithMetadata is deliberately never
43
+ // synthesized here: glued backends have no shared transaction to honor
44
+ // its atomicity promise (docs/spec/adapters.md § Interface split).
45
+ // Stack.putAttachment() falls back to bytes-then-create().
32
46
  putAttachment: (data) => parts.blob.putAttachment(data),
33
47
  getAttachment: (id) => parts.blob.getAttachment(id),
34
48
  deleteAttachment: (id) => parts.blob.deleteAttachment(id),
49
+ ...(parts.blob.listFiles && {
50
+ listFiles: () => parts.blob.listFiles(),
51
+ }),
35
52
  async flush() {
36
53
  await parts.record.flush?.();
37
54
  await parts.blob.flush?.();
@@ -1 +1 @@
1
- {"version":3,"file":"combine.js","sourceRoot":"","sources":["../src/combine.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,KAG/B;IACC,OAAO;QACL,IAAI,YAAY;YACd,OAAO,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC;QACnC,CAAC;QACD,IAAI,aAAa;YACf,OAAO,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC;QACpC,CAAC;QACD,IAAI,QAAQ;YACV,OAAO,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC/B,CAAC;QAED,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;QACjD,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7C,YAAY,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC;QACrE,YAAY,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,IAAI,CAAC;QAC/D,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;QAEjD,SAAS,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC;QAC3D,UAAU,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,KAAK,CAAC;QAE7D,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;QACjD,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;QACrD,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC;QAEvD,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzC,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACzC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE;QAEzC,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;QACvD,aAAa,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;QACnD,gBAAgB,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAEzD,KAAK,CAAC,KAAK;YACT,MAAM,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;YAC7B,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;QAC7B,CAAC;QACD,KAAK,CAAC,KAAK;YACT,MAAM,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;YAC7B,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"combine.js","sourceRoot":"","sources":["../src/combine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @haverstack/core/did
3
+ * -------------------------------------------------------
4
+ * Key generation, custody and signing for did:key — the mandatory-floor
5
+ * DID method (see docs/spec/identity.md). Audience: apps at first-run
6
+ * keygen and key custody, and protocol implementers verifying signatures.
7
+ */
8
+ export { InvalidDidError, generateDidKeypair, verifyDidSignature } from './did.js';
9
+ export type { DidKeypair } from './did.js';
10
+ export { isValidDid } from './did.js';
11
+ export { signWithDid, exportDidPrivateKeyJwk, importDidPrivateKeyJwk } from './did.js';
12
+ //# sourceMappingURL=did-entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"did-entry.d.ts","sourceRoot":"","sources":["../src/did-entry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACnF,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAKtC,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @haverstack/core/did
3
+ * -------------------------------------------------------
4
+ * Key generation, custody and signing for did:key — the mandatory-floor
5
+ * DID method (see docs/spec/identity.md). Audience: apps at first-run
6
+ * keygen and key custody, and protocol implementers verifying signatures.
7
+ */
8
+ export { InvalidDidError, generateDidKeypair, verifyDidSignature } from './did.js';
9
+ // No in-repo caller: haverstack/server#54 validates ENTITY_ID as a DID at
10
+ // server startup.
11
+ export { isValidDid } from './did.js';
12
+ // No in-repo caller: root README.md § Key custody documents
13
+ // exportDidPrivateKeyJwk() -> store -> importDidPrivateKeyJwk() ->
14
+ // signWithDid() as the key-custody journey an app follows.
15
+ export { signWithDid, exportDidPrivateKeyJwk, importDidPrivateKeyJwk } from './did.js';
16
+ //# sourceMappingURL=did-entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"did-entry.js","sourceRoot":"","sources":["../src/did-entry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGnF,0EAA0E;AAC1E,kBAAkB;AAClB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,4DAA4D;AAC5D,mEAAmE;AACnE,2DAA2D;AAC3D,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC"}
package/dist/did.d.ts ADDED
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Stack — Decentralized Identifiers
3
+ * -------------------------------------------------------
4
+ * entityId values are DID strings (see docs/spec/identity.md). did:key —
5
+ * an Ed25519 public key, multicodec + multibase(base58btc) encoded — is the
6
+ * mandatory floor: zero infrastructure, zero resolution, verifiable by
7
+ * anyone from the string alone. Other methods (did:web, did:plc, ...) are
8
+ * valid entityId values too, but this module only knows how to mint and
9
+ * verify did:key.
10
+ *
11
+ * Uses Web Crypto (crypto.subtle) exclusively — no dependency, works in
12
+ * Node (>=22.5, matching the rest of core's floor), browsers, and Deno.
13
+ */
14
+ export declare class InvalidDidError extends Error {
15
+ constructor(message?: string);
16
+ }
17
+ export type DidKeypair = {
18
+ /** e.g. "did:key:z6Mk..." */
19
+ did: string;
20
+ publicKey: CryptoKey;
21
+ privateKey: CryptoKey;
22
+ };
23
+ /** Generate a fresh Ed25519 keypair and derive its did:key. */
24
+ export declare const generateDidKeypair: () => Promise<DidKeypair>;
25
+ /** Derive a did:key string from an Ed25519 CryptoKey. */
26
+ export declare const didFromPublicKey: (publicKey: CryptoKey) => Promise<string>;
27
+ /**
28
+ * Parse a did:key string and return its raw Ed25519 public key bytes, or
29
+ * null if it isn't a well-formed Ed25519 did:key (wrong prefix, bad base58,
30
+ * wrong multicodec, wrong length).
31
+ */
32
+ export declare const parseDidKey: (did: string) => Uint8Array | null;
33
+ /** Whether a string is a well-formed Ed25519 did:key. */
34
+ export declare const isValidDidKey: (value: string) => boolean;
35
+ /** Import the Ed25519 public key encoded in a did:key, for verification. */
36
+ export declare const publicKeyFromDidKey: (did: string) => Promise<CryptoKey>;
37
+ /**
38
+ * Whether a string has the generic W3C DID Core syntax (did:<method>:<id>)
39
+ * — any method, not just did:key. Use isValidDidKey() to additionally
40
+ * require the did:key method and a well-formed Ed25519 key.
41
+ */
42
+ export declare const isValidDid: (value: string) => boolean;
43
+ export declare const signWithDid: (privateKey: CryptoKey, data: Uint8Array) => Promise<Uint8Array>;
44
+ /**
45
+ * Verify a signature was produced by the private key behind a did:key.
46
+ * Requires no lookup — the public key is decoded from the DID itself.
47
+ */
48
+ export declare const verifyDidSignature: (did: string, signature: Uint8Array, data: Uint8Array) => Promise<boolean>;
49
+ export declare const exportDidPrivateKeyJwk: (privateKey: CryptoKey) => Promise<JsonWebKey>;
50
+ export declare const importDidPrivateKeyJwk: (jwk: JsonWebKey) => Promise<CryptoKey>;
51
+ //# sourceMappingURL=did.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"did.d.ts","sourceRoot":"","sources":["../src/did.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,SAAK;CAIzB;AA4DD,MAAM,MAAM,UAAU,GAAG;IACvB,6BAA6B;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,kBAAkB,QAAa,OAAO,CAAC,UAAU,CAM7D,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,gBAAgB,GAAU,WAAW,SAAS,KAAG,OAAO,CAAC,MAAM,CAM3E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,UAAU,GAAG,IAoBtD,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,OAAsC,CAAC;AAErF,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,SAAS,CAIxE,CAAC;AASF;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,OAAyC,CAAC;AAMrF,eAAO,MAAM,WAAW,GAAU,YAAY,SAAS,EAAE,MAAM,UAAU,KAAG,OAAO,CAAC,UAAU,CACP,CAAC;AAExF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAC7B,KAAK,MAAM,EACX,WAAW,UAAU,EACrB,MAAM,UAAU,KACf,OAAO,CAAC,OAAO,CAQjB,CAAC;AAWF,eAAO,MAAM,sBAAsB,GAAU,YAAY,SAAS,KAAG,OAAO,CAAC,UAAU,CAC3C,CAAC;AAE7C,eAAO,MAAM,sBAAsB,GAAU,KAAK,UAAU,KAAG,OAAO,CAAC,SAAS,CAChB,CAAC"}
package/dist/did.js ADDED
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Stack — Decentralized Identifiers
3
+ * -------------------------------------------------------
4
+ * entityId values are DID strings (see docs/spec/identity.md). did:key —
5
+ * an Ed25519 public key, multicodec + multibase(base58btc) encoded — is the
6
+ * mandatory floor: zero infrastructure, zero resolution, verifiable by
7
+ * anyone from the string alone. Other methods (did:web, did:plc, ...) are
8
+ * valid entityId values too, but this module only knows how to mint and
9
+ * verify did:key.
10
+ *
11
+ * Uses Web Crypto (crypto.subtle) exclusively — no dependency, works in
12
+ * Node (>=22.5, matching the rest of core's floor), browsers, and Deno.
13
+ */
14
+ // -------------------------------------------------------
15
+ // Errors
16
+ // -------------------------------------------------------
17
+ export class InvalidDidError extends Error {
18
+ constructor(message = '') {
19
+ super(message || 'Invalid DID.');
20
+ this.name = 'InvalidDidError';
21
+ }
22
+ }
23
+ // -------------------------------------------------------
24
+ // base58btc (Bitcoin alphabet) — no leading-zero-safe library dependency
25
+ // -------------------------------------------------------
26
+ const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
27
+ const base58btcEncode = (bytes) => {
28
+ let value = 0n;
29
+ for (const byte of bytes)
30
+ value = (value << 8n) | BigInt(byte);
31
+ let out = '';
32
+ while (value > 0n) {
33
+ const remainder = value % 58n;
34
+ value /= 58n;
35
+ out = BASE58_ALPHABET[Number(remainder)] + out;
36
+ }
37
+ for (const byte of bytes) {
38
+ if (byte !== 0)
39
+ break;
40
+ out = '1' + out;
41
+ }
42
+ return out;
43
+ };
44
+ const base58btcDecode = (encoded) => {
45
+ let value = 0n;
46
+ for (const char of encoded) {
47
+ const digit = BASE58_ALPHABET.indexOf(char);
48
+ if (digit === -1) {
49
+ throw new InvalidDidError(`Invalid base58 character: "${char}"`);
50
+ }
51
+ value = value * 58n + BigInt(digit);
52
+ }
53
+ const bytes = [];
54
+ while (value > 0n) {
55
+ bytes.unshift(Number(value & 0xffn));
56
+ value >>= 8n;
57
+ }
58
+ for (const char of encoded) {
59
+ if (char !== '1')
60
+ break;
61
+ bytes.unshift(0);
62
+ }
63
+ return new Uint8Array(bytes);
64
+ };
65
+ // -------------------------------------------------------
66
+ // did:key (Ed25519)
67
+ // -------------------------------------------------------
68
+ /** Multicodec varint prefix for "ed25519-pub" (code 0xed). */
69
+ const ED25519_MULTICODEC_PREFIX = new Uint8Array([0xed, 0x01]);
70
+ const ED25519_RAW_KEY_LENGTH = 32;
71
+ const DID_KEY_PREFIX = 'did:key:z';
72
+ /** Generate a fresh Ed25519 keypair and derive its did:key. */
73
+ export const generateDidKeypair = async () => {
74
+ const { publicKey, privateKey } = (await crypto.subtle.generateKey('Ed25519', true, [
75
+ 'sign',
76
+ 'verify',
77
+ ]));
78
+ return { did: await didFromPublicKey(publicKey), publicKey, privateKey };
79
+ };
80
+ /** Derive a did:key string from an Ed25519 CryptoKey. */
81
+ export const didFromPublicKey = async (publicKey) => {
82
+ const raw = new Uint8Array(await crypto.subtle.exportKey('raw', publicKey));
83
+ const prefixed = new Uint8Array(ED25519_MULTICODEC_PREFIX.length + raw.length);
84
+ prefixed.set(ED25519_MULTICODEC_PREFIX, 0);
85
+ prefixed.set(raw, ED25519_MULTICODEC_PREFIX.length);
86
+ return DID_KEY_PREFIX + base58btcEncode(prefixed);
87
+ };
88
+ /**
89
+ * Parse a did:key string and return its raw Ed25519 public key bytes, or
90
+ * null if it isn't a well-formed Ed25519 did:key (wrong prefix, bad base58,
91
+ * wrong multicodec, wrong length).
92
+ */
93
+ export const parseDidKey = (did) => {
94
+ if (!did.startsWith(DID_KEY_PREFIX))
95
+ return null;
96
+ let decoded;
97
+ try {
98
+ decoded = base58btcDecode(did.slice(DID_KEY_PREFIX.length));
99
+ }
100
+ catch {
101
+ return null;
102
+ }
103
+ const expectedLength = ED25519_MULTICODEC_PREFIX.length + ED25519_RAW_KEY_LENGTH;
104
+ if (decoded.length !== expectedLength ||
105
+ decoded[0] !== ED25519_MULTICODEC_PREFIX[0] ||
106
+ decoded[1] !== ED25519_MULTICODEC_PREFIX[1]) {
107
+ return null;
108
+ }
109
+ return decoded.slice(ED25519_MULTICODEC_PREFIX.length);
110
+ };
111
+ /** Whether a string is a well-formed Ed25519 did:key. */
112
+ export const isValidDidKey = (value) => parseDidKey(value) !== null;
113
+ /** Import the Ed25519 public key encoded in a did:key, for verification. */
114
+ export const publicKeyFromDidKey = async (did) => {
115
+ const raw = parseDidKey(did);
116
+ if (!raw)
117
+ throw new InvalidDidError(`Not a valid did:key: "${did}"`);
118
+ return crypto.subtle.importKey('raw', new Uint8Array(raw), 'Ed25519', true, ['verify']);
119
+ };
120
+ // -------------------------------------------------------
121
+ // Generic DID syntax (any method)
122
+ // -------------------------------------------------------
123
+ // did-core ABNF, simplified: "did:" method-name ":" method-specific-id
124
+ const GENERIC_DID_FORMAT = /^did:[a-z0-9]+:[A-Za-z0-9._:%-]+$/;
125
+ /**
126
+ * Whether a string has the generic W3C DID Core syntax (did:<method>:<id>)
127
+ * — any method, not just did:key. Use isValidDidKey() to additionally
128
+ * require the did:key method and a well-formed Ed25519 key.
129
+ */
130
+ export const isValidDid = (value) => GENERIC_DID_FORMAT.test(value);
131
+ // -------------------------------------------------------
132
+ // Sign / verify
133
+ // -------------------------------------------------------
134
+ export const signWithDid = async (privateKey, data) => new Uint8Array(await crypto.subtle.sign('Ed25519', privateKey, new Uint8Array(data)));
135
+ /**
136
+ * Verify a signature was produced by the private key behind a did:key.
137
+ * Requires no lookup — the public key is decoded from the DID itself.
138
+ */
139
+ export const verifyDidSignature = async (did, signature, data) => {
140
+ const publicKey = await publicKeyFromDidKey(did);
141
+ return crypto.subtle.verify('Ed25519', publicKey, new Uint8Array(signature), new Uint8Array(data));
142
+ };
143
+ // -------------------------------------------------------
144
+ // Private-key export/import
145
+ // -------------------------------------------------------
146
+ //
147
+ // Core never stores a private key itself — these exist so callers can
148
+ // persist the key material returned by generateDidKeypair() (encrypted key
149
+ // backup, OS keychain, etc.) and reconstruct it on a later run. Where that
150
+ // key lives is an app/UX concern, not this library's.
151
+ export const exportDidPrivateKeyJwk = async (privateKey) => crypto.subtle.exportKey('jwk', privateKey);
152
+ export const importDidPrivateKeyJwk = async (jwk) => crypto.subtle.importKey('jwk', jwk, 'Ed25519', true, ['sign']);
153
+ //# sourceMappingURL=did.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"did.js","sourceRoot":"","sources":["../src/did.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,0DAA0D;AAC1D,SAAS;AACT,0DAA0D;AAE1D,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAO,GAAG,EAAE;QACtB,KAAK,CAAC,OAAO,IAAI,cAAc,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,0DAA0D;AAC1D,yEAAyE;AACzE,0DAA0D;AAE1D,MAAM,eAAe,GAAG,4DAA4D,CAAC;AAErF,MAAM,eAAe,GAAG,CAAC,KAAiB,EAAU,EAAE;IACpD,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,KAAK,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAE/D,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,OAAO,KAAK,GAAG,EAAE,EAAE,CAAC;QAClB,MAAM,SAAS,GAAG,KAAK,GAAG,GAAG,CAAC;QAC9B,KAAK,IAAI,GAAG,CAAC;QACb,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,GAAG,CAAC;IACjD,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,CAAC;YAAE,MAAM;QACtB,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IAClB,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,OAAe,EAAc,EAAE;IACtD,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACjB,MAAM,IAAI,eAAe,CAAC,8BAA8B,IAAI,GAAG,CAAC,CAAC;QACnE,CAAC;QACD,KAAK,GAAG,KAAK,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,OAAO,KAAK,GAAG,EAAE,EAAE,CAAC;QAClB,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC;QACrC,KAAK,KAAK,EAAE,CAAC;IACf,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,IAAI,KAAK,GAAG;YAAE,MAAM;QACxB,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;IAED,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC,CAAC;AAEF,0DAA0D;AAC1D,oBAAoB;AACpB,0DAA0D;AAE1D,8DAA8D;AAC9D,MAAM,yBAAyB,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AAC/D,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAClC,MAAM,cAAc,GAAG,WAAW,CAAC;AASnC,+DAA+D;AAC/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,IAAyB,EAAE;IAChE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,EAAE;QAClF,MAAM;QACN,QAAQ;KACT,CAAC,CAAkB,CAAC;IACrB,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;AAC3E,CAAC,CAAC;AAEF,yDAAyD;AACzD,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,SAAoB,EAAmB,EAAE;IAC9E,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAC5E,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,yBAAyB,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/E,QAAQ,CAAC,GAAG,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAC;IAC3C,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,yBAAyB,CAAC,MAAM,CAAC,CAAC;IACpD,OAAO,cAAc,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;AACpD,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAW,EAAqB,EAAE;IAC5D,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,cAAc,CAAC;QAAE,OAAO,IAAI,CAAC;IAEjD,IAAI,OAAmB,CAAC;IACxB,IAAI,CAAC;QACH,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,cAAc,GAAG,yBAAyB,CAAC,MAAM,GAAG,sBAAsB,CAAC;IACjF,IACE,OAAO,CAAC,MAAM,KAAK,cAAc;QACjC,OAAO,CAAC,CAAC,CAAC,KAAK,yBAAyB,CAAC,CAAC,CAAC;QAC3C,OAAO,CAAC,CAAC,CAAC,KAAK,yBAAyB,CAAC,CAAC,CAAC,EAC3C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC;AACzD,CAAC,CAAC;AAEF,yDAAyD;AACzD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;AAErF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EAAE,GAAW,EAAsB,EAAE;IAC3E,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,eAAe,CAAC,yBAAyB,GAAG,GAAG,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC1F,CAAC,CAAC;AAEF,0DAA0D;AAC1D,kCAAkC;AAClC,0DAA0D;AAE1D,uEAAuE;AACvE,MAAM,kBAAkB,GAAG,mCAAmC,CAAC;AAE/D;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAErF,0DAA0D;AAC1D,gBAAgB;AAChB,0DAA0D;AAE1D,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,UAAqB,EAAE,IAAgB,EAAuB,EAAE,CAChG,IAAI,UAAU,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAExF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACrC,GAAW,EACX,SAAqB,EACrB,IAAgB,EACE,EAAE;IACpB,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,GAAG,CAAC,CAAC;IACjD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CACzB,SAAS,EACT,SAAS,EACT,IAAI,UAAU,CAAC,SAAS,CAAC,EACzB,IAAI,UAAU,CAAC,IAAI,CAAC,CACrB,CAAC;AACJ,CAAC,CAAC;AAEF,0DAA0D;AAC1D,4BAA4B;AAC5B,0DAA0D;AAC1D,EAAE;AACF,sEAAsE;AACtE,2EAA2E;AAC3E,2EAA2E;AAC3E,sDAAsD;AAEtD,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EAAE,UAAqB,EAAuB,EAAE,CACzF,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;AAE7C,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EAAE,GAAe,EAAsB,EAAE,CAClF,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC"}
package/dist/id.d.ts CHANGED
@@ -22,15 +22,27 @@ export declare const crockford32Encode: (n: number) => string;
22
22
  export declare const crockford32Decode: (s: string) => number;
23
23
  export declare const _setLastNowId: (chars: string) => void;
24
24
  export declare const _setLastRandChars: (chars: string) => void;
25
+ export declare const _setLastTimestamp: (timestamp: number) => void;
26
+ /** Resets all module-level generator state. For test isolation only. */
27
+ export declare const _resetIdState: () => void;
25
28
  /**
26
- * Generate a new Stack record ID.
27
- *
28
- * IDs are time-sortable: lexicographic order matches creation order.
29
- * Same-millisecond IDs are monotonically incremented to preserve order
30
- * and avoid collisions. Throws IdGenerationOverflowError if more than
31
- * BASE^RAND_SUFFIX_LENGTH (32^3 = 32,768) IDs are generated in one millisecond.
29
+ * Generate a new Stack record ID. Time-sortable: lexicographic order
30
+ * matches creation order, with same-millisecond IDs monotonically
31
+ * incremented. Throws IdGenerationOverflowError past 32^3 IDs in one
32
+ * millisecond.
32
33
  *
33
34
  * @param timestamp - Override the timestamp (ms since epoch). Defaults to Date.now().
34
35
  */
35
36
  export declare const generateId: (timestamp?: number) => string;
37
+ /**
38
+ * Check whether a string has the shape of a Stack record ID: exactly
39
+ * 12 lowercase Crockford base-32 characters. Does not check whether the
40
+ * ID actually exists — see Stack.create()'s duplicate check for that.
41
+ */
42
+ export declare const isValidIdFormat: (id: string) => boolean;
43
+ /**
44
+ * Extract the timestamp (ms since epoch) encoded in an ID's prefix.
45
+ * Only meaningful for IDs that pass isValidIdFormat().
46
+ */
47
+ export declare const idTimestamp: (id: string) => number;
36
48
  //# sourceMappingURL=id.d.ts.map
package/dist/id.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,eAAO,MAAM,IAAI,QAAoB,CAAC;AAGtC,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAUpC,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,OAAO,SAAK;CAIzB;AAED,qBAAa,yBAA0B,SAAQ,iBAAiB;gBAClD,OAAO,SAAK;CAIzB;AAMD,eAAO,MAAM,iBAAiB,GAAI,GAAG,MAAM,KAAG,MAiB7C,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,GAAG,MAAM,KAAG,MAe7C,CAAC;AAoCF,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,IAK7C,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,OAAO,MAAM,KAAG,IAKjD,CAAC;AAMF;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU,GAAI,YAAW,MAAmB,KAAG,MAQ3D,CAAC"}
1
+ {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,eAAO,MAAM,IAAI,QAAoB,CAAC;AAGtC,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAcpC,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,OAAO,SAAK;CAIzB;AAED,qBAAa,yBAA0B,SAAQ,iBAAiB;gBAClD,OAAO,SAAK;CAIzB;AAMD,eAAO,MAAM,iBAAiB,GAAI,GAAG,MAAM,KAAG,MAiB7C,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,GAAG,MAAM,KAAG,MAe7C,CAAC;AAoCF,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,IAK7C,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,OAAO,MAAM,KAAG,IAKjD,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,WAAW,MAAM,KAAG,IAErD,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,aAAa,QAAO,IAIhC,CAAC;AAMF;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,GAAI,YAAW,MAAmB,KAAG,MAU3D,CAAC;AASF;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,IAAI,MAAM,KAAG,OAA6B,CAAC;AAE3E;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,IAAI,MAAM,KAAG,MACa,CAAC"}
package/dist/id.js CHANGED
@@ -17,6 +17,10 @@ export const RAND_SUFFIX_LENGTH = 3;
17
17
  // Module-level state for monotonicity within the same millisecond
18
18
  let lastNowId = '';
19
19
  let lastRandChars = '';
20
+ // Tracks the highest timestamp an ID has been minted for, so a backward
21
+ // clock step (NTP correction, suspend/resume) can't produce an ID that
22
+ // sorts before ones already generated in this process.
23
+ let lastTimestamp = 0;
20
24
  // -------------------------------------------------------
21
25
  // Errors
22
26
  // -------------------------------------------------------
@@ -74,15 +78,15 @@ const pad = (chars, length) => chars.padStart(length, CHARACTERS[0]);
74
78
  * Works in Node (>=19), browsers, Deno, and Bun.
75
79
  */
76
80
  const generateRandChars = () => {
77
- const max = Math.pow(BASE, RAND_SUFFIX_LENGTH) - 1;
81
+ const modulus = Math.pow(BASE, RAND_SUFFIX_LENGTH);
78
82
  const arr = new Uint32Array(1);
79
83
  // Rejection sampling to avoid modulo bias
80
84
  let value;
81
85
  do {
82
86
  crypto.getRandomValues(arr);
83
87
  value = arr[0];
84
- } while (value > Math.floor(0xffffffff / max) * max);
85
- return pad(crockford32Encode(value % max), RAND_SUFFIX_LENGTH);
88
+ } while (value > Math.floor(0xffffffff / modulus) * modulus);
89
+ return pad(crockford32Encode(value % modulus), RAND_SUFFIX_LENGTH);
86
90
  };
87
91
  const incrementRandChars = (randChars) => {
88
92
  const next = crockford32Encode(crockford32Decode(randChars) + 1);
@@ -106,24 +110,49 @@ export const _setLastRandChars = (chars) => {
106
110
  }
107
111
  lastRandChars = chars;
108
112
  };
113
+ export const _setLastTimestamp = (timestamp) => {
114
+ lastTimestamp = timestamp;
115
+ };
116
+ /** Resets all module-level generator state. For test isolation only. */
117
+ export const _resetIdState = () => {
118
+ lastNowId = '';
119
+ lastRandChars = '';
120
+ lastTimestamp = 0;
121
+ };
109
122
  // -------------------------------------------------------
110
123
  // Public API
111
124
  // -------------------------------------------------------
112
125
  /**
113
- * Generate a new Stack record ID.
114
- *
115
- * IDs are time-sortable: lexicographic order matches creation order.
116
- * Same-millisecond IDs are monotonically incremented to preserve order
117
- * and avoid collisions. Throws IdGenerationOverflowError if more than
118
- * BASE^RAND_SUFFIX_LENGTH (32^3 = 32,768) IDs are generated in one millisecond.
126
+ * Generate a new Stack record ID. Time-sortable: lexicographic order
127
+ * matches creation order, with same-millisecond IDs monotonically
128
+ * incremented. Throws IdGenerationOverflowError past 32^3 IDs in one
129
+ * millisecond.
119
130
  *
120
131
  * @param timestamp - Override the timestamp (ms since epoch). Defaults to Date.now().
121
132
  */
122
133
  export const generateId = (timestamp = Date.now()) => {
123
- const nowId = pad(crockford32Encode(timestamp), MIN_TIMESTAMP_LENGTH);
134
+ const effectiveTimestamp = Math.max(timestamp, lastTimestamp);
135
+ const nowId = pad(crockford32Encode(effectiveTimestamp), MIN_TIMESTAMP_LENGTH);
124
136
  const randChars = nowId !== lastNowId ? generateRandChars() : incrementRandChars(lastRandChars);
137
+ lastTimestamp = effectiveTimestamp;
125
138
  lastNowId = nowId;
126
139
  lastRandChars = randChars;
127
140
  return nowId + randChars;
128
141
  };
142
+ // -------------------------------------------------------
143
+ // Format validation
144
+ // -------------------------------------------------------
145
+ const ID_LENGTH = MIN_TIMESTAMP_LENGTH + RAND_SUFFIX_LENGTH;
146
+ const ID_FORMAT = new RegExp(`^[${CHARACTERS}]{${ID_LENGTH}}$`);
147
+ /**
148
+ * Check whether a string has the shape of a Stack record ID: exactly
149
+ * 12 lowercase Crockford base-32 characters. Does not check whether the
150
+ * ID actually exists — see Stack.create()'s duplicate check for that.
151
+ */
152
+ export const isValidIdFormat = (id) => ID_FORMAT.test(id);
153
+ /**
154
+ * Extract the timestamp (ms since epoch) encoded in an ID's prefix.
155
+ * Only meaningful for IDs that pass isValidIdFormat().
156
+ */
157
+ export const idTimestamp = (id) => crockford32Decode(id.slice(0, MIN_TIMESTAMP_LENGTH));
129
158
  //# sourceMappingURL=id.js.map
package/dist/id.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"id.js","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"id.js","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":"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"}