@rexezuge/shared 1.0.1 → 1.0.2

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 (2) hide show
  1. package/README.md +61 -0
  2. package/package.json +2 -1
package/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # @rexezuge/shared
2
+
3
+ Pure platform-generic utilities (codecs, time, locale, crypto, `Result`, SSRF policy) for Cloudflare Workers.
4
+
5
+ Zero dependencies. One concept per file; the barrel only re-exports. Business-specific helpers (money, git oids, calendar sync, credential sharding) deliberately stay in their consumer repos.
6
+
7
+ ```bash
8
+ pnpm add @rexezuge/shared
9
+ ```
10
+
11
+ ---
12
+
13
+ ## 1. What's inside
14
+
15
+ | Area | Exports |
16
+ | --- | --- |
17
+ | Byte codecs | `bytesToBase64`, `base64ToBytes` |
18
+ | Time | `SystemClock` / `FixedClock` (injectable `Clock`), `TimestampUtil`, `TimeZoneUtil` + `DEFAULT_TIME_ZONE` |
19
+ | Locale | `LocaleUtil` (`DEFAULT_LOCALE`, `SUPPORTED_LOCALES`, display names), `canonicalizeLanguageTag` |
20
+ | Email | `normalizeEmail`, `isValidEmailFormat`, `MAX_EMAIL_LENGTH` |
21
+ | Identifiers | `UUIDUtil`, `CryptoIdGenerator` / `FixedIdGenerator` (injectable `IdGenerator`) |
22
+ | Crypto + secrets | `CryptoUtil`, `TokenHashUtil`, `passwordFingerprint` |
23
+ | Error handling | `ErrorSanitizationUtil` (operator/client message split), `ok` / `err` / `getOrThrow` / `mapResult` + `Result` |
24
+ | Network policy | `normalizeRemoteUrl`, `resolveRedirectUrl`, `parseAllowedHosts`, `isPrivateOrInternalHost` (+ limits and blocklists) |
25
+ | Pagination | `CursorCodec` (opaque cursors, `Page`) |
26
+ | Subrequest accounting | `SubrequestCounter`, `SUBREQUEST_KINDS`, `subrequestSpend` (Cloudflare's 50-subrequest ceiling) |
27
+
28
+ ## 2. Usage
29
+
30
+ ```ts
31
+ import {
32
+ CryptoIdGenerator,
33
+ CursorCodec,
34
+ ErrorSanitizationUtil,
35
+ normalizeEmail,
36
+ normalizeRemoteUrl,
37
+ ok,
38
+ SYSTEM_CLOCK,
39
+ } from '@rexezuge/shared';
40
+
41
+ normalizeEmail(' USER@Example.COM '); // 'user@example.com'
42
+ normalizeRemoteUrl('https://example.com/hook', { allowedHosts: parseAllowedHosts('example.com') }); // throws RemoteUrlRejectedError on SSRF targets
43
+ CursorCodec.encode({ id: 'abc', createdAt: 123 }); // opaque page cursor
44
+ const now = SYSTEM_CLOCK.now(); // inject FixedClock in tests
45
+ ```
46
+
47
+ Conventions worth knowing:
48
+
49
+ - **Clocks and ID generators are injectable.** Production code takes a `Clock` / `IdGenerator`; tests pass `FixedClock` / `FixedIdGenerator` instead of mocking time or randomness.
50
+ - **`Result` is for expected failures, exceptions for programmer errors.** `getOrThrow` bridges the two at boundaries.
51
+ - **`RemoteUrlPolicy` is fail-closed.** Private/internal hosts, over-long URLs, and excess redirects throw `RemoteUrlRejectedError` rather than fetching.
52
+
53
+ ---
54
+
55
+ ## Verifying this package
56
+
57
+ ```bash
58
+ pnpm --filter @rexezuge/shared exec tsc -p tsconfig.json
59
+ pnpm --filter @rexezuge/shared typecheck
60
+ pnpm --filter @rexezuge/shared test
61
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rexezuge/shared",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -29,6 +29,7 @@
29
29
  "typescript": "6.0.3",
30
30
  "vitest": "4.1.11"
31
31
  },
32
+ "description": "Pure platform-generic utilities (codecs, time, locale, crypto, Result, SSRF policy) for Cloudflare Workers.",
32
33
  "scripts": {
33
34
  "build": "tsc -p tsconfig.json",
34
35
  "typecheck": "tsc -p tsconfig.test.json --noEmit",