@rexezuge/shared 0.0.0-stage → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/dist/Base64.d.ts +52 -0
  3. package/dist/Base64.d.ts.map +1 -0
  4. package/dist/Base64.js +81 -0
  5. package/dist/Base64.js.map +1 -0
  6. package/dist/Clock.d.ts +56 -0
  7. package/dist/Clock.d.ts.map +1 -0
  8. package/dist/Clock.js +59 -0
  9. package/dist/Clock.js.map +1 -0
  10. package/dist/CryptoUtil.d.ts +79 -0
  11. package/dist/CryptoUtil.d.ts.map +1 -0
  12. package/dist/CryptoUtil.js +97 -0
  13. package/dist/CryptoUtil.js.map +1 -0
  14. package/dist/CursorCodec.d.ts +61 -0
  15. package/dist/CursorCodec.d.ts.map +1 -0
  16. package/dist/CursorCodec.js +60 -0
  17. package/dist/CursorCodec.js.map +1 -0
  18. package/dist/EmailUtil.d.ts +29 -0
  19. package/dist/EmailUtil.d.ts.map +1 -0
  20. package/dist/EmailUtil.js +31 -0
  21. package/dist/EmailUtil.js.map +1 -0
  22. package/dist/ErrorSanitizationUtil.d.ts +69 -0
  23. package/dist/ErrorSanitizationUtil.d.ts.map +1 -0
  24. package/dist/ErrorSanitizationUtil.js +98 -0
  25. package/dist/ErrorSanitizationUtil.js.map +1 -0
  26. package/dist/IdGenerator.d.ts +27 -0
  27. package/dist/IdGenerator.d.ts.map +1 -0
  28. package/dist/IdGenerator.js +28 -0
  29. package/dist/IdGenerator.js.map +1 -0
  30. package/dist/Identity.d.ts +36 -0
  31. package/dist/Identity.d.ts.map +1 -0
  32. package/dist/Identity.js +39 -0
  33. package/dist/Identity.js.map +1 -0
  34. package/dist/LanguageTag.d.ts +25 -0
  35. package/dist/LanguageTag.d.ts.map +1 -0
  36. package/dist/LanguageTag.js +29 -0
  37. package/dist/LanguageTag.js.map +1 -0
  38. package/dist/LocaleUtil.d.ts +35 -0
  39. package/dist/LocaleUtil.d.ts.map +1 -0
  40. package/dist/LocaleUtil.js +97 -0
  41. package/dist/LocaleUtil.js.map +1 -0
  42. package/dist/PasswordFingerprint.d.ts +30 -0
  43. package/dist/PasswordFingerprint.d.ts.map +1 -0
  44. package/dist/PasswordFingerprint.js +33 -0
  45. package/dist/PasswordFingerprint.js.map +1 -0
  46. package/dist/RemoteUrlPolicy.d.ts +121 -0
  47. package/dist/RemoteUrlPolicy.d.ts.map +1 -0
  48. package/dist/RemoteUrlPolicy.js +339 -0
  49. package/dist/RemoteUrlPolicy.js.map +1 -0
  50. package/dist/Result.d.ts +32 -0
  51. package/dist/Result.d.ts.map +1 -0
  52. package/dist/Result.js +19 -0
  53. package/dist/Result.js.map +1 -0
  54. package/dist/SubrequestMeter.d.ts +204 -0
  55. package/dist/SubrequestMeter.d.ts.map +1 -0
  56. package/dist/SubrequestMeter.js +169 -0
  57. package/dist/SubrequestMeter.js.map +1 -0
  58. package/dist/TimeZoneUtil.d.ts +47 -0
  59. package/dist/TimeZoneUtil.d.ts.map +1 -0
  60. package/dist/TimeZoneUtil.js +101 -0
  61. package/dist/TimeZoneUtil.js.map +1 -0
  62. package/dist/TimestampUtil.d.ts +53 -0
  63. package/dist/TimestampUtil.d.ts.map +1 -0
  64. package/dist/TimestampUtil.js +69 -0
  65. package/dist/TimestampUtil.js.map +1 -0
  66. package/dist/TokenHashUtil.d.ts +34 -0
  67. package/dist/TokenHashUtil.d.ts.map +1 -0
  68. package/dist/TokenHashUtil.js +37 -0
  69. package/dist/TokenHashUtil.js.map +1 -0
  70. package/dist/UUIDUtil.d.ts +70 -0
  71. package/dist/UUIDUtil.d.ts.map +1 -0
  72. package/dist/UUIDUtil.js +79 -0
  73. package/dist/UUIDUtil.js.map +1 -0
  74. package/dist/index.d.ts +38 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +42 -0
  77. package/dist/index.js.map +1 -0
  78. package/package.json +34 -3
  79. package/README.md +0 -3
@@ -0,0 +1,69 @@
1
+ import { SYSTEM_CLOCK } from './Clock';
2
+ /**
3
+ * Unix timestamps, in seconds and milliseconds.
4
+ *
5
+ * ## Provenance
6
+ *
7
+ * Converged from all nine `TimestampUtil.ts` copies. They fall into three
8
+ * shapes: Durable-DAV's minimal two-method set (`getCurrentUnixTimestampInSeconds`
9
+ * + `addDays`) with a deliberate "seconds everywhere" argument; AWS's compact set
10
+ * plus an **injectable `Clock`** on the current-time readers; and the full
11
+ * ChordDHT/Mail-Otter set (`…InMilliseconds`, `addMinutes`, `addHours`,
12
+ * `subtractMinutes`, `subtractDays`, `convertIso…`) reading `Date.now()` directly.
13
+ *
14
+ * ## Design decisions
15
+ *
16
+ * - The **full method set** is kept: the union of the three shapes loses nothing
17
+ * and each method exists because at least two repos independently reached for
18
+ * it.
19
+ * - The current-time reads go through an **injectable `Clock`** defaulting to
20
+ * `SYSTEM_CLOCK` (AWS's shape). Reading the clock through one seam lets a test
21
+ * pin "now" without racing `Date.now()`, and a caller cannot accidentally store
22
+ * milliseconds in a column compared against seconds.
23
+ * - Seconds is the storage unit (Durable-DAV's argument): where millisecond
24
+ * precision is genuinely wanted — ordering within a single pass — reach for
25
+ * `…InMilliseconds` (or `clock.now()`) explicitly, so the unit is visible at the
26
+ * call site. `add*`/`subtract*` operate on the **second** unit and are pure
27
+ * calendar arithmetic, never `Date` arithmetic, so they cannot pick up a
28
+ * timezone or a DST transition.
29
+ */
30
+ class TimestampUtil {
31
+ /**
32
+ * Now, in whole milliseconds.
33
+ *
34
+ * @param clock Inject a `FixedClock` to pin "now" in a test; production leaves
35
+ * it defaulted.
36
+ */
37
+ static getCurrentUnixTimestampInMilliseconds(clock = SYSTEM_CLOCK) {
38
+ return clock.now();
39
+ }
40
+ /**
41
+ * Now, in whole seconds. The default storage unit.
42
+ *
43
+ * @param clock Inject a `FixedClock` to pin "now" in a test; production leaves
44
+ * it defaulted.
45
+ */
46
+ static getCurrentUnixTimestampInSeconds(clock = SYSTEM_CLOCK) {
47
+ return Math.floor(clock.now() / 1000);
48
+ }
49
+ static addMinutes(timestamp, minutes) {
50
+ return timestamp + minutes * 60;
51
+ }
52
+ static addHours(timestamp, hours) {
53
+ return timestamp + hours * 60 * 60;
54
+ }
55
+ static addDays(timestamp, days) {
56
+ return timestamp + days * 60 * 60 * 24;
57
+ }
58
+ static subtractMinutes(timestamp, minutes) {
59
+ return timestamp - minutes * 60;
60
+ }
61
+ static subtractDays(timestamp, days) {
62
+ return timestamp - days * 60 * 60 * 24;
63
+ }
64
+ static convertIsoToUnixTimestampInSeconds(isoString) {
65
+ return Math.floor(new Date(isoString).getTime() / 1000);
66
+ }
67
+ }
68
+ export { TimestampUtil };
69
+ //# sourceMappingURL=TimestampUtil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimestampUtil.js","sourceRoot":"","sources":["../src/TimestampUtil.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAc,MAAM,SAAS,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,aAAa;IACjB;;;;;OAKG;IACI,MAAM,CAAC,qCAAqC,CAAC,QAAe,YAAY;QAC7E,OAAO,KAAK,CAAC,GAAG,EAAE,CAAC;IACrB,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,gCAAgC,CAAC,QAAe,YAAY;QACxE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IACxC,CAAC;IAEM,MAAM,CAAC,UAAU,CAAC,SAAiB,EAAE,OAAe;QACzD,OAAO,SAAS,GAAG,OAAO,GAAG,EAAE,CAAC;IAClC,CAAC;IAEM,MAAM,CAAC,QAAQ,CAAC,SAAiB,EAAE,KAAa;QACrD,OAAO,SAAS,GAAG,KAAK,GAAG,EAAE,GAAG,EAAE,CAAC;IACrC,CAAC;IAEM,MAAM,CAAC,OAAO,CAAC,SAAiB,EAAE,IAAY;QACnD,OAAO,SAAS,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACzC,CAAC;IAEM,MAAM,CAAC,eAAe,CAAC,SAAiB,EAAE,OAAe;QAC9D,OAAO,SAAS,GAAG,OAAO,GAAG,EAAE,CAAC;IAClC,CAAC;IAEM,MAAM,CAAC,YAAY,CAAC,SAAiB,EAAE,IAAY;QACxD,OAAO,SAAS,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACzC,CAAC;IAEM,MAAM,CAAC,kCAAkC,CAAC,SAAiB;QAChE,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1D,CAAC;CACF;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * The one-place hash for API / personal access tokens.
3
+ *
4
+ * ## Provenance
5
+ *
6
+ * Taken from AWS-AccessBridge's `TokenHashUtil.ts` — the only repo that factored
7
+ * token hashing behind a named helper (as opposed to calling `CryptoUtil.sha256Hex`
8
+ * inline, as Edge-Git does).
9
+ *
10
+ * A PAT is ~244 random bits from two UUIDs, so a plain SHA-256 hex digest is the
11
+ * right storage form: the input is not dictionary-searchable, so no salt or
12
+ * password KDF is needed, and the digest is indexable. Binding the digest for
13
+ * storage means a D1 read or backup no longer carries a live credential.
14
+ *
15
+ * ## Design decisions
16
+ *
17
+ * - `sha256Hex` **delegates to `CryptoUtil.sha256Hex`** rather than reimplementing
18
+ * the digest loop. AWS carried its own copy only because its `CryptoUtil` did
19
+ * not yet exist to delegate to; the kit's does, and a second SHA-256
20
+ * implementation is exactly the drift this package removes.
21
+ * - **No timing-safe compare is shipped.** The brief says to keep an
22
+ * HMAC/TimingSafe helper "if present"; none of the source repos carries one —
23
+ * token verification compares two SHA-256 *hex strings*, and nothing in the
24
+ * repos does it in constant time. Rather than invent a security primitive here
25
+ * that has no provenance, the helper is left out; a verifier that must compare a
26
+ * presented token's digest against a stored one does the byte-wise, length-
27
+ * independent compare itself (a `crypto.subtle`-backed constant-time compare
28
+ * belongs with the caller's chosen error mapping).
29
+ */
30
+ declare class TokenHashUtil {
31
+ static sha256Hex(token: string): Promise<string>;
32
+ }
33
+ export { TokenHashUtil };
34
+ //# sourceMappingURL=TokenHashUtil.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenHashUtil.d.ts","sourceRoot":"","sources":["../src/TokenHashUtil.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,cAAM,aAAa;WACG,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAG9D;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { CryptoUtil } from './CryptoUtil';
2
+ /**
3
+ * The one-place hash for API / personal access tokens.
4
+ *
5
+ * ## Provenance
6
+ *
7
+ * Taken from AWS-AccessBridge's `TokenHashUtil.ts` — the only repo that factored
8
+ * token hashing behind a named helper (as opposed to calling `CryptoUtil.sha256Hex`
9
+ * inline, as Edge-Git does).
10
+ *
11
+ * A PAT is ~244 random bits from two UUIDs, so a plain SHA-256 hex digest is the
12
+ * right storage form: the input is not dictionary-searchable, so no salt or
13
+ * password KDF is needed, and the digest is indexable. Binding the digest for
14
+ * storage means a D1 read or backup no longer carries a live credential.
15
+ *
16
+ * ## Design decisions
17
+ *
18
+ * - `sha256Hex` **delegates to `CryptoUtil.sha256Hex`** rather than reimplementing
19
+ * the digest loop. AWS carried its own copy only because its `CryptoUtil` did
20
+ * not yet exist to delegate to; the kit's does, and a second SHA-256
21
+ * implementation is exactly the drift this package removes.
22
+ * - **No timing-safe compare is shipped.** The brief says to keep an
23
+ * HMAC/TimingSafe helper "if present"; none of the source repos carries one —
24
+ * token verification compares two SHA-256 *hex strings*, and nothing in the
25
+ * repos does it in constant time. Rather than invent a security primitive here
26
+ * that has no provenance, the helper is left out; a verifier that must compare a
27
+ * presented token's digest against a stored one does the byte-wise, length-
28
+ * independent compare itself (a `crypto.subtle`-backed constant-time compare
29
+ * belongs with the caller's chosen error mapping).
30
+ */
31
+ class TokenHashUtil {
32
+ static async sha256Hex(token) {
33
+ return CryptoUtil.sha256Hex(token);
34
+ }
35
+ }
36
+ export { TokenHashUtil };
37
+ //# sourceMappingURL=TokenHashUtil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenHashUtil.js","sourceRoot":"","sources":["../src/TokenHashUtil.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,aAAa;IACV,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,KAAa;QACzC,OAAO,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;CACF;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Primary keys.
3
+ *
4
+ * ## Provenance
5
+ *
6
+ * Converged from `UUIDUtil.ts` in Durable-DAV, AWS-AccessBridge, Edge-Git,
7
+ * Mail-Otter (a re-export of the DAV form under the name `UIDUtility`), the
8
+ * Router, CalDAV-Bridge, Mail-Meow and Edge-Sonic. Four carried the bare
9
+ * `getRandomUUID`; Edge-Git and AWS added `getRandomUUIDNoDash`; Edge-Sonic added
10
+ * the derived `deterministicId`. ChordDHT-Tracker has no UUIDUtil (its ids go
11
+ * through `IdGenerator`).
12
+ *
13
+ * ## Design decision
14
+ *
15
+ * The whole requirement for a row whose id never appears on the wire is a v4 UUID
16
+ * in canonical dashed form, so `getRandomUUID` is the base. `getRandomUUIDNoDash`
17
+ * is kept from the AWS/Edge-Git form (two repos independently needed the compact
18
+ * spelling). `deterministicId` is Edge-Sonic's and is the single most valuable
19
+ * member — see its doc comment for why length-prefixing the parts is load-bearing.
20
+ */
21
+ declare class UUIDUtil {
22
+ static getRandomUUID(): string;
23
+ /**
24
+ * The canonical form with the dashes removed, for a context that wants a
25
+ * compact, dash-free hex-ish token.
26
+ */
27
+ static getRandomUUIDNoDash(): string;
28
+ /**
29
+ * A UUID-shaped id derived from a namespace and its parts, stable across runs.
30
+ *
31
+ * ### Why this exists
32
+ *
33
+ * **Because "create this" is not idempotent.** A Cloudflare Workflow step is
34
+ * cached by name and may be retried, so an import that mints a fresh id per
35
+ * attempt writes the *same row twice* on every retry — and a user who pressed
36
+ * the button three times finds four copies. `getRandomUUID` is right for the
37
+ * path where each create really is a new row, and wrong for an import, where a
38
+ * retried step is the *same* row.
39
+ *
40
+ * So an imported row's id is a function of `(namespace, ...parts)`: a retry
41
+ * resolves the same id, the write rewrites it, and the outcome does not depend
42
+ * on how many times the step ran.
43
+ *
44
+ * ### SHA-256, and why not MD5
45
+ *
46
+ * MD5 exists in one repo for a token scheme that specifies it, but this is a
47
+ * collision question with a consequence: two different inputs sharing an id
48
+ * means one overwrites the other, and MD5's collision resistance is not
49
+ * something to lean on when `crypto.subtle` is available. 128 bits of SHA-256
50
+ * is used, in canonical dashed form so the value is a UUID by inspection rather
51
+ * than 32 hex characters used as one.
52
+ *
53
+ * ### Every part is **length-prefixed**, because a separator proves nothing
54
+ *
55
+ * The obvious implementation joins the parts with a delimiter, and the obvious
56
+ * claim is that the delimiter cannot appear inside a part. That claim is
57
+ * **false**: joining `[ns, a, b]` and joining `[ns, a\u0000b]` both produce the
58
+ * same string, so a delimiter — *any* delimiter — is forgeable by choosing a
59
+ * part containing it. Two different inputs then hash to one id, and one
60
+ * overwrites the other.
61
+ *
62
+ * So each part contributes its **length** before its bytes: `3:ns1:a1:b`. That
63
+ * encoding is injective, because the length is recoverable from the bytes
64
+ * themselves — there is exactly one way to parse it — so no choice of parts
65
+ * produces the same string.
66
+ */
67
+ static deterministicId(namespace: string, ...parts: readonly string[]): Promise<string>;
68
+ }
69
+ export { UUIDUtil };
70
+ //# sourceMappingURL=UUIDUtil.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UUIDUtil.d.ts","sourceRoot":"","sources":["../src/UUIDUtil.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,cAAM,QAAQ;WACE,aAAa,IAAI,MAAM;IAIrC;;;OAGG;WACW,mBAAmB,IAAI,MAAM;IAI3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAsCG;WACiB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAMrG;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Primary keys.
3
+ *
4
+ * ## Provenance
5
+ *
6
+ * Converged from `UUIDUtil.ts` in Durable-DAV, AWS-AccessBridge, Edge-Git,
7
+ * Mail-Otter (a re-export of the DAV form under the name `UIDUtility`), the
8
+ * Router, CalDAV-Bridge, Mail-Meow and Edge-Sonic. Four carried the bare
9
+ * `getRandomUUID`; Edge-Git and AWS added `getRandomUUIDNoDash`; Edge-Sonic added
10
+ * the derived `deterministicId`. ChordDHT-Tracker has no UUIDUtil (its ids go
11
+ * through `IdGenerator`).
12
+ *
13
+ * ## Design decision
14
+ *
15
+ * The whole requirement for a row whose id never appears on the wire is a v4 UUID
16
+ * in canonical dashed form, so `getRandomUUID` is the base. `getRandomUUIDNoDash`
17
+ * is kept from the AWS/Edge-Git form (two repos independently needed the compact
18
+ * spelling). `deterministicId` is Edge-Sonic's and is the single most valuable
19
+ * member — see its doc comment for why length-prefixing the parts is load-bearing.
20
+ */
21
+ class UUIDUtil {
22
+ static getRandomUUID() {
23
+ return crypto.randomUUID();
24
+ }
25
+ /**
26
+ * The canonical form with the dashes removed, for a context that wants a
27
+ * compact, dash-free hex-ish token.
28
+ */
29
+ static getRandomUUIDNoDash() {
30
+ return crypto.randomUUID().replaceAll('-', '');
31
+ }
32
+ /**
33
+ * A UUID-shaped id derived from a namespace and its parts, stable across runs.
34
+ *
35
+ * ### Why this exists
36
+ *
37
+ * **Because "create this" is not idempotent.** A Cloudflare Workflow step is
38
+ * cached by name and may be retried, so an import that mints a fresh id per
39
+ * attempt writes the *same row twice* on every retry — and a user who pressed
40
+ * the button three times finds four copies. `getRandomUUID` is right for the
41
+ * path where each create really is a new row, and wrong for an import, where a
42
+ * retried step is the *same* row.
43
+ *
44
+ * So an imported row's id is a function of `(namespace, ...parts)`: a retry
45
+ * resolves the same id, the write rewrites it, and the outcome does not depend
46
+ * on how many times the step ran.
47
+ *
48
+ * ### SHA-256, and why not MD5
49
+ *
50
+ * MD5 exists in one repo for a token scheme that specifies it, but this is a
51
+ * collision question with a consequence: two different inputs sharing an id
52
+ * means one overwrites the other, and MD5's collision resistance is not
53
+ * something to lean on when `crypto.subtle` is available. 128 bits of SHA-256
54
+ * is used, in canonical dashed form so the value is a UUID by inspection rather
55
+ * than 32 hex characters used as one.
56
+ *
57
+ * ### Every part is **length-prefixed**, because a separator proves nothing
58
+ *
59
+ * The obvious implementation joins the parts with a delimiter, and the obvious
60
+ * claim is that the delimiter cannot appear inside a part. That claim is
61
+ * **false**: joining `[ns, a, b]` and joining `[ns, a\u0000b]` both produce the
62
+ * same string, so a delimiter — *any* delimiter — is forgeable by choosing a
63
+ * part containing it. Two different inputs then hash to one id, and one
64
+ * overwrites the other.
65
+ *
66
+ * So each part contributes its **length** before its bytes: `3:ns1:a1:b`. That
67
+ * encoding is injective, because the length is recoverable from the bytes
68
+ * themselves — there is exactly one way to parse it — so no choice of parts
69
+ * produces the same string.
70
+ */
71
+ static async deterministicId(namespace, ...parts) {
72
+ const payload = [namespace, ...parts].map((part) => `${part.length}:${part}`).join('');
73
+ const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(payload));
74
+ const hex = Array.from(new Uint8Array(digest).slice(0, 16), (byte) => byte.toString(16).padStart(2, '0')).join('');
75
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
76
+ }
77
+ }
78
+ export { UUIDUtil };
79
+ //# sourceMappingURL=UUIDUtil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UUIDUtil.js","sourceRoot":"","sources":["../src/UUIDUtil.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,QAAQ;IACL,MAAM,CAAC,aAAa;QACzB,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,mBAAmB;QAC/B,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACjD,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAsCG;IACI,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,SAAiB,EAAE,GAAG,KAAwB;QAChF,MAAM,OAAO,GAAG,CAAC,SAAS,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QACxF,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAU,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3H,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;IACjH,CAAC;CACF;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * `@rexezuge/shared` — the converged, platform-generic utilities distilled from
3
+ * the nine Rexezuge Cloudflare Worker monorepos. One concept per file; this barrel
4
+ * only re-exports. Business-specific helpers (money, git oids, calendar sync,
5
+ * credential sharding, …) are deliberately left in their consumer repos.
6
+ *
7
+ * `isValidEmailFormat` / `MAX_EMAIL_LENGTH` are defined in `Identity.ts` and
8
+ * re-exported by `EmailUtil.ts`; the barrel sources each name **once** (from
9
+ * `EmailUtil`, the one-stop email surface) so an `export *` merge cannot silently
10
+ * drop them to ambiguity.
11
+ */
12
+ export { bytesToBase64, base64ToBytes } from './Base64';
13
+ export { SystemClock, FixedClock, SYSTEM_CLOCK } from './Clock';
14
+ export type { Clock } from './Clock';
15
+ export { TimestampUtil } from './TimestampUtil';
16
+ export { TimeZoneUtil, DEFAULT_TIME_ZONE } from './TimeZoneUtil';
17
+ export { LocaleUtil, DEFAULT_LOCALE, SUPPORTED_LOCALES, LOCALE_DISPLAY_NAMES } from './LocaleUtil';
18
+ export type { SupportedLocale } from './LocaleUtil';
19
+ export { canonicalizeLanguageTag } from './LanguageTag';
20
+ export type { LanguageTag } from './LanguageTag';
21
+ export { normalizeEmail, isValidEmailFormat, MAX_EMAIL_LENGTH } from './EmailUtil';
22
+ export { EMAIL_FORMAT_RE } from './Identity';
23
+ export { UUIDUtil } from './UUIDUtil';
24
+ export { CryptoIdGenerator, FixedIdGenerator } from './IdGenerator';
25
+ export type { IdGenerator } from './IdGenerator';
26
+ export { CryptoUtil } from './CryptoUtil';
27
+ export { ErrorSanitizationUtil } from './ErrorSanitizationUtil';
28
+ export { err, getOrThrow, isOk, mapResult, ok } from './Result';
29
+ export type { Err, Ok, Result } from './Result';
30
+ export { normalizeRemoteUrl, resolveRedirectUrl, parseAllowedHosts, isPrivateOrInternalHost, stripBrackets, stripTrailingDot, RemoteUrlRejectedError, MAX_REMOTE_URL_LENGTH, MAX_REDIRECTS, BLOCKED_HOST_SUFFIXES, BLOCKED_HOSTNAMES, } from './RemoteUrlPolicy';
31
+ export type { UrlPolicyOptions } from './RemoteUrlPolicy';
32
+ export { CursorCodec } from './CursorCodec';
33
+ export type { Page } from './CursorCodec';
34
+ export { SubrequestCounter, UNMETERED_SUBREQUESTS, SUBREQUEST_KINDS, subrequestSpend, NO_SUBREQUESTS_SPENT } from './SubrequestMeter';
35
+ export type { SubrequestMeter, SubrequestKind, SubrequestSpend } from './SubrequestMeter';
36
+ export { passwordFingerprint } from './PasswordFingerprint';
37
+ export { TokenHashUtil } from './TokenHashUtil';
38
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,YAAY,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGjE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACnG,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGjD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG7C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACpE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGjD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAChE,YAAY,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGhD,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACvB,aAAa,EACb,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,EACrB,aAAa,EACb,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAG1C,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACtI,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAG1F,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAG5D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,42 @@
1
+ /**
2
+ * `@rexezuge/shared` — the converged, platform-generic utilities distilled from
3
+ * the nine Rexezuge Cloudflare Worker monorepos. One concept per file; this barrel
4
+ * only re-exports. Business-specific helpers (money, git oids, calendar sync,
5
+ * credential sharding, …) are deliberately left in their consumer repos.
6
+ *
7
+ * `isValidEmailFormat` / `MAX_EMAIL_LENGTH` are defined in `Identity.ts` and
8
+ * re-exported by `EmailUtil.ts`; the barrel sources each name **once** (from
9
+ * `EmailUtil`, the one-stop email surface) so an `export *` merge cannot silently
10
+ * drop them to ambiguity.
11
+ */
12
+ // Byte codecs.
13
+ export { bytesToBase64, base64ToBytes } from './Base64';
14
+ // Time.
15
+ export { SystemClock, FixedClock, SYSTEM_CLOCK } from './Clock';
16
+ export { TimestampUtil } from './TimestampUtil';
17
+ export { TimeZoneUtil, DEFAULT_TIME_ZONE } from './TimeZoneUtil';
18
+ // Locale.
19
+ export { LocaleUtil, DEFAULT_LOCALE, SUPPORTED_LOCALES, LOCALE_DISPLAY_NAMES } from './LocaleUtil';
20
+ export { canonicalizeLanguageTag } from './LanguageTag';
21
+ // Identity + email.
22
+ export { normalizeEmail, isValidEmailFormat, MAX_EMAIL_LENGTH } from './EmailUtil';
23
+ export { EMAIL_FORMAT_RE } from './Identity';
24
+ // Identifiers.
25
+ export { UUIDUtil } from './UUIDUtil';
26
+ export { CryptoIdGenerator, FixedIdGenerator } from './IdGenerator';
27
+ // Crypto + secrets.
28
+ export { CryptoUtil } from './CryptoUtil';
29
+ // Error handling.
30
+ export { ErrorSanitizationUtil } from './ErrorSanitizationUtil';
31
+ export { err, getOrThrow, isOk, mapResult, ok } from './Result';
32
+ // Network policy.
33
+ export { normalizeRemoteUrl, resolveRedirectUrl, parseAllowedHosts, isPrivateOrInternalHost, stripBrackets, stripTrailingDot, RemoteUrlRejectedError, MAX_REMOTE_URL_LENGTH, MAX_REDIRECTS, BLOCKED_HOST_SUFFIXES, BLOCKED_HOSTNAMES, } from './RemoteUrlPolicy';
34
+ // Pagination.
35
+ export { CursorCodec } from './CursorCodec';
36
+ // Cloudflare subrequest accounting.
37
+ export { SubrequestCounter, UNMETERED_SUBREQUESTS, SUBREQUEST_KINDS, subrequestSpend, NO_SUBREQUESTS_SPENT } from './SubrequestMeter';
38
+ // Auth-side memo helper.
39
+ export { passwordFingerprint } from './PasswordFingerprint';
40
+ // Token hashing.
41
+ export { TokenHashUtil } from './TokenHashUtil';
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAe;AACf,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAExD,QAAQ;AACR,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEhE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEjE,UAAU;AACV,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEnG,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAGxD,oBAAoB;AACpB,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAe;AACf,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGpE,oBAAoB;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,kBAAkB;AAClB,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAGhE,kBAAkB;AAClB,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACvB,aAAa,EACb,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,EACrB,aAAa,EACb,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAG3B,cAAc;AACd,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,oCAAoC;AACpC,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAGtI,yBAAyB;AACzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,iBAAiB;AACjB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,37 @@
1
1
  {
2
2
  "name": "@rexezuge/shared",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "1.0.1",
4
+ "private": false,
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/Rexezuge-CloudflareWorkers/SDK.git",
9
+ "directory": "packages/shared"
10
+ },
11
+ "type": "module",
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "default": "./dist/index.js"
18
+ },
19
+ "./*": {
20
+ "types": "./dist/*.d.ts",
21
+ "default": "./dist/*.js"
22
+ }
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "devDependencies": {
28
+ "@types/node": "26.6.4",
29
+ "typescript": "6.0.3",
30
+ "vitest": "4.1.11"
31
+ },
32
+ "scripts": {
33
+ "build": "tsc -p tsconfig.json",
34
+ "typecheck": "tsc -p tsconfig.test.json --noEmit",
35
+ "test": "vitest run"
36
+ }
6
37
  }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.