@evolu/common 8.14.0 → 8.15.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.
- package/dist/src/Crypto.d.ts +2 -1
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Redacted.d.ts +19 -39
- package/dist/src/Redacted.d.ts.map +1 -1
- package/dist/src/Redacted.js +18 -33
- package/dist/src/Type.d.ts +161 -0
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +152 -2
- package/dist/src/WebSocket.d.ts +16 -1
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +14 -2
- package/dist/src/intl/_en.d.ts +5 -1
- package/dist/src/intl/_en.d.ts.map +1 -1
- package/dist/src/intl/_en.js +4 -0
- package/dist/src/intl/ar.d.ts +5 -1
- package/dist/src/intl/ar.d.ts.map +1 -1
- package/dist/src/intl/ar.js +4 -0
- package/dist/src/intl/bn.d.ts +5 -1
- package/dist/src/intl/bn.d.ts.map +1 -1
- package/dist/src/intl/bn.js +4 -0
- package/dist/src/intl/ca.d.ts +5 -1
- package/dist/src/intl/ca.d.ts.map +1 -1
- package/dist/src/intl/ca.js +4 -0
- package/dist/src/intl/cs.d.ts +5 -1
- package/dist/src/intl/cs.d.ts.map +1 -1
- package/dist/src/intl/cs.js +4 -0
- package/dist/src/intl/da.d.ts +5 -1
- package/dist/src/intl/da.d.ts.map +1 -1
- package/dist/src/intl/da.js +4 -0
- package/dist/src/intl/de.d.ts +5 -1
- package/dist/src/intl/de.d.ts.map +1 -1
- package/dist/src/intl/de.js +4 -0
- package/dist/src/intl/el.d.ts +5 -1
- package/dist/src/intl/el.d.ts.map +1 -1
- package/dist/src/intl/el.js +4 -0
- package/dist/src/intl/es.d.ts +5 -1
- package/dist/src/intl/es.d.ts.map +1 -1
- package/dist/src/intl/es.js +4 -0
- package/dist/src/intl/fa.d.ts +5 -1
- package/dist/src/intl/fa.d.ts.map +1 -1
- package/dist/src/intl/fa.js +4 -0
- package/dist/src/intl/fi.d.ts +5 -1
- package/dist/src/intl/fi.d.ts.map +1 -1
- package/dist/src/intl/fi.js +4 -0
- package/dist/src/intl/fil.d.ts +5 -1
- package/dist/src/intl/fil.d.ts.map +1 -1
- package/dist/src/intl/fil.js +4 -0
- package/dist/src/intl/fr.d.ts +5 -1
- package/dist/src/intl/fr.d.ts.map +1 -1
- package/dist/src/intl/fr.js +4 -0
- package/dist/src/intl/he.d.ts +5 -1
- package/dist/src/intl/he.d.ts.map +1 -1
- package/dist/src/intl/he.js +4 -0
- package/dist/src/intl/hi.d.ts +5 -1
- package/dist/src/intl/hi.d.ts.map +1 -1
- package/dist/src/intl/hi.js +4 -0
- package/dist/src/intl/hr.d.ts +5 -1
- package/dist/src/intl/hr.d.ts.map +1 -1
- package/dist/src/intl/hr.js +4 -0
- package/dist/src/intl/hu.d.ts +3 -1
- package/dist/src/intl/hu.d.ts.map +1 -1
- package/dist/src/intl/hu.js +2 -0
- package/dist/src/intl/id.d.ts +5 -1
- package/dist/src/intl/id.d.ts.map +1 -1
- package/dist/src/intl/id.js +4 -0
- package/dist/src/intl/it.d.ts +5 -1
- package/dist/src/intl/it.d.ts.map +1 -1
- package/dist/src/intl/it.js +4 -0
- package/dist/src/intl/ja.d.ts +5 -1
- package/dist/src/intl/ja.d.ts.map +1 -1
- package/dist/src/intl/ja.js +4 -0
- package/dist/src/intl/ko.d.ts +5 -1
- package/dist/src/intl/ko.d.ts.map +1 -1
- package/dist/src/intl/ko.js +4 -0
- package/dist/src/intl/ml.d.ts +5 -1
- package/dist/src/intl/ml.d.ts.map +1 -1
- package/dist/src/intl/ml.js +4 -0
- package/dist/src/intl/mr.d.ts +5 -1
- package/dist/src/intl/mr.d.ts.map +1 -1
- package/dist/src/intl/mr.js +4 -0
- package/dist/src/intl/ms.d.ts +5 -1
- package/dist/src/intl/ms.d.ts.map +1 -1
- package/dist/src/intl/ms.js +4 -0
- package/dist/src/intl/nb.d.ts +3 -1
- package/dist/src/intl/nb.d.ts.map +1 -1
- package/dist/src/intl/nb.js +2 -0
- package/dist/src/intl/nl.d.ts +5 -1
- package/dist/src/intl/nl.d.ts.map +1 -1
- package/dist/src/intl/nl.js +4 -0
- package/dist/src/intl/pa.d.ts +5 -1
- package/dist/src/intl/pa.d.ts.map +1 -1
- package/dist/src/intl/pa.js +4 -0
- package/dist/src/intl/pl.d.ts +4 -0
- package/dist/src/intl/pl.d.ts.map +1 -1
- package/dist/src/intl/pl.js +4 -0
- package/dist/src/intl/pt-BR.d.ts +5 -1
- package/dist/src/intl/pt-BR.d.ts.map +1 -1
- package/dist/src/intl/pt-BR.js +4 -0
- package/dist/src/intl/pt.d.ts +5 -1
- package/dist/src/intl/pt.d.ts.map +1 -1
- package/dist/src/intl/pt.js +4 -0
- package/dist/src/intl/ro.d.ts +5 -1
- package/dist/src/intl/ro.d.ts.map +1 -1
- package/dist/src/intl/ro.js +4 -0
- package/dist/src/intl/sk.d.ts +5 -1
- package/dist/src/intl/sk.d.ts.map +1 -1
- package/dist/src/intl/sk.js +4 -0
- package/dist/src/intl/sl.d.ts +5 -1
- package/dist/src/intl/sl.d.ts.map +1 -1
- package/dist/src/intl/sl.js +4 -0
- package/dist/src/intl/sv.d.ts +5 -1
- package/dist/src/intl/sv.d.ts.map +1 -1
- package/dist/src/intl/sv.js +4 -0
- package/dist/src/intl/sw.d.ts +2 -0
- package/dist/src/intl/sw.d.ts.map +1 -1
- package/dist/src/intl/sw.js +2 -0
- package/dist/src/intl/ta.d.ts +5 -1
- package/dist/src/intl/ta.d.ts.map +1 -1
- package/dist/src/intl/ta.js +4 -0
- package/dist/src/intl/te.d.ts +5 -1
- package/dist/src/intl/te.d.ts.map +1 -1
- package/dist/src/intl/te.js +4 -0
- package/dist/src/intl/th.d.ts +5 -1
- package/dist/src/intl/th.d.ts.map +1 -1
- package/dist/src/intl/th.js +4 -0
- package/dist/src/intl/tr.d.ts +5 -1
- package/dist/src/intl/tr.d.ts.map +1 -1
- package/dist/src/intl/tr.js +4 -0
- package/dist/src/intl/uk.d.ts +5 -1
- package/dist/src/intl/uk.d.ts.map +1 -1
- package/dist/src/intl/uk.js +4 -0
- package/dist/src/intl/ur.d.ts +5 -1
- package/dist/src/intl/ur.d.ts.map +1 -1
- package/dist/src/intl/ur.js +4 -0
- package/dist/src/intl/vi.d.ts +5 -1
- package/dist/src/intl/vi.d.ts.map +1 -1
- package/dist/src/intl/vi.js +4 -0
- package/dist/src/intl/zh-CN.d.ts +5 -1
- package/dist/src/intl/zh-CN.d.ts.map +1 -1
- package/dist/src/intl/zh-CN.js +4 -0
- package/dist/src/intl/zh-TW.d.ts +5 -1
- package/dist/src/intl/zh-TW.d.ts.map +1 -1
- package/dist/src/intl/zh-TW.js +4 -0
- package/dist/src/local-first/Evolu.d.ts +4 -0
- package/dist/src/local-first/Evolu.d.ts.map +1 -1
- package/dist/src/local-first/Evolu.js +6 -1
- package/dist/src/local-first/Schema.d.ts +3 -0
- package/dist/src/local-first/Schema.d.ts.map +1 -1
- package/dist/src/local-first/Schema.js +9 -5
- package/dist/src/local-first/Shared.js +1 -3
- package/package.json +1 -1
- package/src/Crypto.ts +2 -1
- package/src/Redacted.test.ts +231 -0
- package/src/Redacted.ts +36 -47
- package/src/Type.test.ts +166 -0
- package/src/Type.ts +198 -2
- package/src/WebSocket.ts +33 -4
- package/src/intl/_en.ts +10 -0
- package/src/intl/ar.ts +8 -0
- package/src/intl/bn.ts +10 -0
- package/src/intl/ca.ts +10 -0
- package/src/intl/cs.ts +10 -0
- package/src/intl/da.ts +10 -0
- package/src/intl/de.ts +10 -0
- package/src/intl/el.ts +10 -0
- package/src/intl/es.ts +10 -0
- package/src/intl/fa.ts +10 -0
- package/src/intl/fi.ts +10 -0
- package/src/intl/fil.ts +10 -0
- package/src/intl/fr.ts +10 -0
- package/src/intl/he.ts +10 -0
- package/src/intl/hi.ts +10 -0
- package/src/intl/hr.ts +10 -0
- package/src/intl/hu.ts +6 -0
- package/src/intl/id.ts +10 -0
- package/src/intl/intl.test.ts +88 -0
- package/src/intl/it.ts +10 -0
- package/src/intl/ja.ts +10 -0
- package/src/intl/ko.ts +10 -0
- package/src/intl/ml.ts +10 -0
- package/src/intl/mr.ts +10 -0
- package/src/intl/ms.ts +8 -0
- package/src/intl/nb.ts +6 -0
- package/src/intl/nl.ts +10 -0
- package/src/intl/pa.ts +10 -0
- package/src/intl/pl.ts +12 -0
- package/src/intl/pt-BR.ts +10 -0
- package/src/intl/pt.ts +8 -0
- package/src/intl/ro.ts +10 -0
- package/src/intl/sk.ts +8 -0
- package/src/intl/sl.ts +10 -0
- package/src/intl/sv.ts +10 -0
- package/src/intl/sw.ts +4 -0
- package/src/intl/ta.ts +10 -0
- package/src/intl/te.ts +10 -0
- package/src/intl/th.ts +10 -0
- package/src/intl/tr.ts +10 -0
- package/src/intl/uk.ts +10 -0
- package/src/intl/ur.ts +8 -0
- package/src/intl/vi.ts +8 -0
- package/src/intl/zh-CN.ts +10 -0
- package/src/intl/zh-TW.ts +10 -0
- package/src/local-first/Evolu.test.ts +62 -8
- package/src/local-first/Evolu.ts +11 -1
- package/src/local-first/Schema.test.ts +80 -1
- package/src/local-first/Schema.ts +15 -5
- package/src/local-first/Shared.ts +1 -3
package/dist/src/Crypto.d.ts
CHANGED
|
@@ -258,7 +258,8 @@ export declare const createPadmePadding: (length: NonNegativeInt) => Uint8Array;
|
|
|
258
258
|
/**
|
|
259
259
|
* Performs a timing-safe comparison of two Uint8Arrays. Returns true if they
|
|
260
260
|
* are equal, false otherwise. Takes constant time regardless of where the
|
|
261
|
-
* arrays differ.
|
|
261
|
+
* arrays differ. Arrays of different lengths are unequal, and the comparison
|
|
262
|
+
* does not hide their lengths.
|
|
262
263
|
*
|
|
263
264
|
* @group Comparison
|
|
264
265
|
* @see https://nodejs.org/api/crypto.html#cryptotimingsafeequala-b
|
package/dist/src/Crypto.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Crypto.d.ts","sourceRoot":"","sources":["../../src/Crypto.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"Crypto.d.ts","sourceRoot":"","sources":["../../src/Crypto.ts"],"names":[],"mappings":"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"}
|
package/dist/src/Redacted.d.ts
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import type { Brand } from "./Brand.ts";
|
|
7
|
-
import type { Eq } from "./Eq.ts";
|
|
8
7
|
/**
|
|
9
8
|
* A wrapper type that prevents sensitive values from being accidentally exposed
|
|
10
9
|
* through logging, serialization, or inspection.
|
|
@@ -15,13 +14,17 @@ import type { Eq } from "./Eq.ts";
|
|
|
15
14
|
*
|
|
16
15
|
* For type-level distinction between different secrets, use branded types.
|
|
17
16
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* visible in devtools. Symbols can't be used because they don't support custom
|
|
22
|
-
* `toString`.
|
|
17
|
+
* Redacted guards against accidental exposure, such as logs, error reports, and
|
|
18
|
+
* serialized payloads. It does not hide the value from a debugger: DevTools and
|
|
19
|
+
* heap snapshots can still reach it.
|
|
23
20
|
*
|
|
24
|
-
*
|
|
21
|
+
* A structured clone, such as a `postMessage` to a worker, does not copy the
|
|
22
|
+
* hidden value and arrives as an empty object. Reveal the value before posting
|
|
23
|
+
* it, and wrap it again on arrival if the receiver passes it to app code.
|
|
24
|
+
*
|
|
25
|
+
* Implements `Disposable`, so the `using` syntax detaches the value when the
|
|
26
|
+
* scope ends. Disposal does not overwrite the value or release other references
|
|
27
|
+
* to it.
|
|
25
28
|
*
|
|
26
29
|
* ### Example
|
|
27
30
|
*
|
|
@@ -45,7 +48,6 @@ import type { Eq } from "./Eq.ts";
|
|
|
45
48
|
* using redactedKey: RedactedApiKey = createRedacted(apiKey);
|
|
46
49
|
* const fetchUser = (key: RedactedApiKey): ApiKey => revealRedacted(key);
|
|
47
50
|
*
|
|
48
|
-
* // oxlint-disable-next-line typescript/no-base-to-string -- Redacted intentionally implements a safe custom toString.
|
|
49
51
|
* assertEqual(redactedKey.toString(), "<redacted>");
|
|
50
52
|
* assertEqual(
|
|
51
53
|
* JSON.stringify({ apiKey: redactedKey }),
|
|
@@ -61,13 +63,18 @@ import type { Eq } from "./Eq.ts";
|
|
|
61
63
|
* using key = createRedacted(apiKey);
|
|
62
64
|
* return key;
|
|
63
65
|
* })();
|
|
64
|
-
* // Leaving the `using` scope
|
|
66
|
+
* // Leaving the `using` scope detaches the value, so revealing it throws.
|
|
65
67
|
* assertErr(trySync(() => revealRedacted(disposedKey)));
|
|
66
68
|
* ```
|
|
67
69
|
*/
|
|
68
70
|
export interface Redacted<A> extends Brand<"Redacted">, Disposable {
|
|
69
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* The inner type. This is a type-only phantom property. Use it through
|
|
73
|
+
* `typeof redacted.Type`; it does not exist at runtime.
|
|
74
|
+
*/
|
|
70
75
|
readonly Type: A;
|
|
76
|
+
readonly toString: () => "<redacted>";
|
|
77
|
+
readonly toJSON: () => "<redacted>";
|
|
71
78
|
}
|
|
72
79
|
/** Creates a {@link Redacted} wrapper for a sensitive value. */
|
|
73
80
|
export declare const createRedacted: <A>(value: A) => Redacted<A>;
|
|
@@ -77,37 +84,10 @@ export declare const createRedacted: <A>(value: A) => Redacted<A>;
|
|
|
77
84
|
* This is a separate function rather than a method on {@link Redacted} to make
|
|
78
85
|
* access visually explicit and easy to grep in code reviews. Accessing
|
|
79
86
|
* sensitive values should feel intentional, not convenient.
|
|
87
|
+
*
|
|
88
|
+
* Throws when the wrapper was disposed or is a structured clone.
|
|
80
89
|
*/
|
|
81
90
|
export declare const revealRedacted: <A>(redacted: Redacted<A>) => A;
|
|
82
91
|
/** Checks if a value is a {@link Redacted} wrapper. */
|
|
83
92
|
export declare const isRedacted: (value: unknown) => value is Redacted<unknown>;
|
|
84
|
-
/**
|
|
85
|
-
* Creates an {@link Eq} for {@link Redacted} values based on an equality function
|
|
86
|
-
* for the underlying type.
|
|
87
|
-
*
|
|
88
|
-
* ### Example
|
|
89
|
-
*
|
|
90
|
-
* ```ts
|
|
91
|
-
* import {
|
|
92
|
-
* assertFalse,
|
|
93
|
-
* assertTrue,
|
|
94
|
-
* createEqRedacted,
|
|
95
|
-
* createRedacted,
|
|
96
|
-
* eqString,
|
|
97
|
-
* type Brand,
|
|
98
|
-
* } from "@evolu/common";
|
|
99
|
-
*
|
|
100
|
-
* type ApiKey = string & Brand<"ApiKey">;
|
|
101
|
-
* const eqRedactedApiKey = createEqRedacted<ApiKey>(eqString);
|
|
102
|
-
*
|
|
103
|
-
* // Apply brands only after validation or at another trusted boundary.
|
|
104
|
-
* using a = createRedacted("x" as ApiKey);
|
|
105
|
-
* using b = createRedacted("x" as ApiKey);
|
|
106
|
-
* using c = createRedacted("y" as ApiKey);
|
|
107
|
-
*
|
|
108
|
-
* assertTrue(eqRedactedApiKey(a, b));
|
|
109
|
-
* assertFalse(eqRedactedApiKey(a, c));
|
|
110
|
-
* ```
|
|
111
|
-
*/
|
|
112
|
-
export declare const createEqRedacted: <A>(eq: Eq<A>) => Eq<Redacted<A>>;
|
|
113
93
|
//# sourceMappingURL=Redacted.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Redacted.d.ts","sourceRoot":"","sources":["../../src/Redacted.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"Redacted.d.ts","sourceRoot":"","sources":["../../src/Redacted.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC,CAAE,SAAQ,KAAK,CAAC,UAAU,CAAC,EAAE,UAAU;IAChE;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,YAAY,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,YAAY,CAAC;CACrC;AAED,gEAAgE;AAChE,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,CAAC,KAAG,QAAQ,CAAC,CAAC,CAatD,CAAC;AAiBF;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAI,CAAC,YAAY,QAAQ,CAAC,CAAC,CAAC,KAAG,CAGzD,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,UAAU,UAAW,OAAO,KAAG,KAAK,IAAI,QAAQ,CAAC,OAAO,CAG7B,CAAC"}
|
package/dist/src/Redacted.js
CHANGED
|
@@ -6,7 +6,16 @@
|
|
|
6
6
|
import { assert } from "./Assert.js";
|
|
7
7
|
/** Creates a {@link Redacted} wrapper for a sensitive value. */
|
|
8
8
|
export const createRedacted = (value) => {
|
|
9
|
-
|
|
9
|
+
// Symbol.dispose is read here rather than in proto because installPolyfills
|
|
10
|
+
// runs after imported modules are evaluated. An arrow function also keeps a
|
|
11
|
+
// detached dispose method working.
|
|
12
|
+
const redacted = Object.create(proto, {
|
|
13
|
+
[Symbol.dispose]: {
|
|
14
|
+
value: () => {
|
|
15
|
+
registry.delete(redacted);
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
});
|
|
10
19
|
registry.set(redacted, value);
|
|
11
20
|
return redacted;
|
|
12
21
|
};
|
|
@@ -14,11 +23,14 @@ const proto = {
|
|
|
14
23
|
toString: () => redactedString,
|
|
15
24
|
toJSON: () => redactedString,
|
|
16
25
|
[Symbol.for("nodejs.util.inspect.custom")]: () => redactedString,
|
|
17
|
-
[Symbol.dispose]() {
|
|
18
|
-
registry.delete(this);
|
|
19
|
-
},
|
|
20
26
|
};
|
|
21
27
|
const redactedString = "<redacted>";
|
|
28
|
+
// The value lives in a WeakMap, so it is never a property: previews,
|
|
29
|
+
// enumeration, and serialization cannot show it, and it is garbage collected
|
|
30
|
+
// with the wrapper. A private field would show when DevTools expands the
|
|
31
|
+
// object. The wrapper is an object, not a symbol, because a symbol cannot
|
|
32
|
+
// customize toString or toJSON. DevTools can still reach the registry through
|
|
33
|
+
// the scopes of the wrapper's functions.
|
|
22
34
|
const registry = new WeakMap();
|
|
23
35
|
/**
|
|
24
36
|
* Reveals the original value from a {@link Redacted} wrapper.
|
|
@@ -26,6 +38,8 @@ const registry = new WeakMap();
|
|
|
26
38
|
* This is a separate function rather than a method on {@link Redacted} to make
|
|
27
39
|
* access visually explicit and easy to grep in code reviews. Accessing
|
|
28
40
|
* sensitive values should feel intentional, not convenient.
|
|
41
|
+
*
|
|
42
|
+
* Throws when the wrapper was disposed or is a structured clone.
|
|
29
43
|
*/
|
|
30
44
|
export const revealRedacted = (redacted) => {
|
|
31
45
|
assert(registry.has(redacted), "Redacted value was not in registry");
|
|
@@ -35,32 +49,3 @@ export const revealRedacted = (redacted) => {
|
|
|
35
49
|
export const isRedacted = (value) => typeof value === "object" &&
|
|
36
50
|
value !== null &&
|
|
37
51
|
Object.getPrototypeOf(value) === proto;
|
|
38
|
-
/**
|
|
39
|
-
* Creates an {@link Eq} for {@link Redacted} values based on an equality function
|
|
40
|
-
* for the underlying type.
|
|
41
|
-
*
|
|
42
|
-
* ### Example
|
|
43
|
-
*
|
|
44
|
-
* ```ts
|
|
45
|
-
* import {
|
|
46
|
-
* assertFalse,
|
|
47
|
-
* assertTrue,
|
|
48
|
-
* createEqRedacted,
|
|
49
|
-
* createRedacted,
|
|
50
|
-
* eqString,
|
|
51
|
-
* type Brand,
|
|
52
|
-
* } from "@evolu/common";
|
|
53
|
-
*
|
|
54
|
-
* type ApiKey = string & Brand<"ApiKey">;
|
|
55
|
-
* const eqRedactedApiKey = createEqRedacted<ApiKey>(eqString);
|
|
56
|
-
*
|
|
57
|
-
* // Apply brands only after validation or at another trusted boundary.
|
|
58
|
-
* using a = createRedacted("x" as ApiKey);
|
|
59
|
-
* using b = createRedacted("x" as ApiKey);
|
|
60
|
-
* using c = createRedacted("y" as ApiKey);
|
|
61
|
-
*
|
|
62
|
-
* assertTrue(eqRedactedApiKey(a, b));
|
|
63
|
-
* assertFalse(eqRedactedApiKey(a, c));
|
|
64
|
-
* ```
|
|
65
|
-
*/
|
|
66
|
-
export const createEqRedacted = (eq) => (x, y) => eq(revealRedacted(x), revealRedacted(y));
|
package/dist/src/Type.d.ts
CHANGED
|
@@ -3585,6 +3585,61 @@ export interface NameError extends TypeError<"Name"> {
|
|
|
3585
3585
|
*/
|
|
3586
3586
|
export declare const Name: BrandType<BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "UrlSafeString", RegexError<"UrlSafeString">>, "Name", NameError>;
|
|
3587
3587
|
export type Name = typeof Name.Output;
|
|
3588
|
+
/**
|
|
3589
|
+
* Error returned when a string is not a valid {@link Email}.
|
|
3590
|
+
*
|
|
3591
|
+
* @group String
|
|
3592
|
+
*/
|
|
3593
|
+
export interface EmailError extends TypeError<"Email"> {
|
|
3594
|
+
readonly value: string;
|
|
3595
|
+
}
|
|
3596
|
+
/**
|
|
3597
|
+
* Email address as defined by the WHATWG HTML Standard.
|
|
3598
|
+
*
|
|
3599
|
+
* Email accepts a [valid email
|
|
3600
|
+
* address](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address),
|
|
3601
|
+
* the syntax browsers enforce for `<input type="email">`. The HTML Standard
|
|
3602
|
+
* deliberately departs from RFC 5322: it rejects quoted local parts, comments,
|
|
3603
|
+
* IP address literals, and whitespace, and it accepts only ASCII. Use the ASCII
|
|
3604
|
+
* (`xn--`) form of internationalized domains.
|
|
3605
|
+
*
|
|
3606
|
+
* Email does not normalize. The local part is case-sensitive, so different
|
|
3607
|
+
* Email strings can still reach the same mailbox, and only a delivered message
|
|
3608
|
+
* proves that an address exists.
|
|
3609
|
+
*
|
|
3610
|
+
* The HTML Standard limits each domain label to 63 characters but sets no total
|
|
3611
|
+
* length. SMTP limits an address to 254 characters; compose
|
|
3612
|
+
* `maxLength(254)(Email)` when that limit matters.
|
|
3613
|
+
*
|
|
3614
|
+
* ### Example
|
|
3615
|
+
*
|
|
3616
|
+
* ```ts
|
|
3617
|
+
* import {
|
|
3618
|
+
* assertEqual,
|
|
3619
|
+
* assertErr,
|
|
3620
|
+
* assertOk,
|
|
3621
|
+
* Email,
|
|
3622
|
+
* maxLength,
|
|
3623
|
+
* } from "@evolu/common";
|
|
3624
|
+
*
|
|
3625
|
+
* assertOk(Email.fromUnknown("ada@example.com"), "ada@example.com");
|
|
3626
|
+
* assertOk(Email.fromUnknown("Ada@Example.com"), "Ada@Example.com");
|
|
3627
|
+
*
|
|
3628
|
+
* const invalid = Email.fromUnknown("Ada <ada@example.com>");
|
|
3629
|
+
* assertErr(invalid);
|
|
3630
|
+
* assertEqual(invalid.error, {
|
|
3631
|
+
* type: "Email",
|
|
3632
|
+
* value: "Ada <ada@example.com>",
|
|
3633
|
+
* });
|
|
3634
|
+
*
|
|
3635
|
+
* const SmtpEmail = maxLength(254)(Email);
|
|
3636
|
+
* assertErr(SmtpEmail.fromUnknown(`${"a".repeat(251)}@b.c`));
|
|
3637
|
+
* ```
|
|
3638
|
+
*
|
|
3639
|
+
* @group String
|
|
3640
|
+
*/
|
|
3641
|
+
export declare const Email: BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "Email", EmailError>;
|
|
3642
|
+
export type Email = typeof Email.Output;
|
|
3588
3643
|
/**
|
|
3589
3644
|
* Stable valid {@link Name} for tests and internal fixtures.
|
|
3590
3645
|
*
|
|
@@ -3829,6 +3884,112 @@ export declare const idToIdBytes: (value: Id) => IdBytes;
|
|
|
3829
3884
|
* @group String
|
|
3830
3885
|
*/
|
|
3831
3886
|
export declare const idBytesToId: (value: IdBytes) => Id;
|
|
3887
|
+
/**
|
|
3888
|
+
* Error returned when a string is not a canonical {@link Uuid}.
|
|
3889
|
+
*
|
|
3890
|
+
* @group String
|
|
3891
|
+
*/
|
|
3892
|
+
export interface UuidError extends TypeError<"Uuid"> {
|
|
3893
|
+
readonly value: string;
|
|
3894
|
+
}
|
|
3895
|
+
/**
|
|
3896
|
+
* UUID in its canonical lowercase text form, as defined by [RFC
|
|
3897
|
+
* 9562](https://www.rfc-editor.org/rfc/rfc9562).
|
|
3898
|
+
*
|
|
3899
|
+
* Uuid accepts 32 lowercase hexadecimal digits in the 8-4-4-4-12 layout, as
|
|
3900
|
+
* produced by `crypto.randomUUID()`. It accepts every version and variant,
|
|
3901
|
+
* including the Nil and Max UUIDs, so every 128-bit value has exactly one
|
|
3902
|
+
* Uuid.
|
|
3903
|
+
*
|
|
3904
|
+
* RFC 9562 reads UUIDs in any case. Uuid requires lowercase so that equal UUIDs
|
|
3905
|
+
* are equal strings; lowercase text from other sources before validating it.
|
|
3906
|
+
*
|
|
3907
|
+
* Convert a Uuid to an {@link Id} with {@link uuidToId} and back with
|
|
3908
|
+
* {@link idToUuid}.
|
|
3909
|
+
*
|
|
3910
|
+
* ### Example
|
|
3911
|
+
*
|
|
3912
|
+
* ```ts
|
|
3913
|
+
* import { assertEqual, assertErr, assertOk, Uuid } from "@evolu/common";
|
|
3914
|
+
*
|
|
3915
|
+
* const value = "0190a6f4-8c3e-7b2a-9d41-5e6f7a8b9c0d";
|
|
3916
|
+
* assertOk(Uuid.fromUnknown(value), value);
|
|
3917
|
+
*
|
|
3918
|
+
* const uppercase = value.toUpperCase();
|
|
3919
|
+
* const invalid = Uuid.fromUnknown(uppercase);
|
|
3920
|
+
* assertErr(invalid);
|
|
3921
|
+
* assertEqual(invalid.error, { type: "Uuid", value: uppercase });
|
|
3922
|
+
* assertOk(Uuid.fromUnknown(uppercase.toLowerCase()), value);
|
|
3923
|
+
* ```
|
|
3924
|
+
*
|
|
3925
|
+
* @group String
|
|
3926
|
+
*/
|
|
3927
|
+
export declare const Uuid: BrandType<Type<"String", string, string, TypeOfError<"String">, null, TypeOfError<"String">, never, string, true>, "Uuid", UuidError>;
|
|
3928
|
+
export type Uuid = typeof Uuid.Output;
|
|
3929
|
+
/**
|
|
3930
|
+
* Converts a {@link Uuid} to the {@link Id} with the same 16 bytes.
|
|
3931
|
+
*
|
|
3932
|
+
* Use this to store records whose external keys are UUIDs. Unlike
|
|
3933
|
+
* {@link createIdFromString}, the mapping is reversible with {@link idToUuid}, so
|
|
3934
|
+
* the original UUID does not need its own column. A time-based UUID, such as
|
|
3935
|
+
* version 1, 6, or 7, keeps its creation time in the Id.
|
|
3936
|
+
*
|
|
3937
|
+
* ### Example
|
|
3938
|
+
*
|
|
3939
|
+
* ```ts
|
|
3940
|
+
* import {
|
|
3941
|
+
* assertEqual,
|
|
3942
|
+
* assertType,
|
|
3943
|
+
* idToUuid,
|
|
3944
|
+
* Uuid,
|
|
3945
|
+
* uuidToId,
|
|
3946
|
+
* type Brand,
|
|
3947
|
+
* type Id,
|
|
3948
|
+
* } from "@evolu/common";
|
|
3949
|
+
*
|
|
3950
|
+
* const uuid = Uuid.orThrow("0190a6f4-8c3e-7b2a-9d41-5e6f7a8b9c0d");
|
|
3951
|
+
* const todoId = uuidToId<"Todo">(uuid);
|
|
3952
|
+
*
|
|
3953
|
+
* assertEqual(todoId, "AZCm9Iw-eyqdQV5veoucDQ");
|
|
3954
|
+
* assertType<typeof todoId, Id & Brand<"Todo">>();
|
|
3955
|
+
* assertEqual(idToUuid(todoId), uuid);
|
|
3956
|
+
* ```
|
|
3957
|
+
*
|
|
3958
|
+
* @group String
|
|
3959
|
+
*/
|
|
3960
|
+
export declare const uuidToId: <B extends string = never>(value: Uuid, ..._validation: IdBrandValidation<B>) => CreatedId<B>;
|
|
3961
|
+
/**
|
|
3962
|
+
* Converts an {@link Id} to the {@link Uuid} with the same 16 bytes.
|
|
3963
|
+
*
|
|
3964
|
+
* The result is a Uuid of any version or variant, because Ids created by
|
|
3965
|
+
* {@link createId} are random 128-bit values. Ids created by
|
|
3966
|
+
* {@link createIdAsUuidv7} convert to version 7 UUIDs.
|
|
3967
|
+
*
|
|
3968
|
+
* ### Example
|
|
3969
|
+
*
|
|
3970
|
+
* ```ts
|
|
3971
|
+
* import {
|
|
3972
|
+
* assertEqual,
|
|
3973
|
+
* createIdAsUuidv7,
|
|
3974
|
+
* createRandomBytes,
|
|
3975
|
+
* createTime,
|
|
3976
|
+
* idToUuid,
|
|
3977
|
+
* uuidToId,
|
|
3978
|
+
* } from "@evolu/common";
|
|
3979
|
+
*
|
|
3980
|
+
* const id = createIdAsUuidv7({
|
|
3981
|
+
* randomBytes: createRandomBytes(),
|
|
3982
|
+
* time: createTime(),
|
|
3983
|
+
* });
|
|
3984
|
+
* const uuid = idToUuid(id);
|
|
3985
|
+
*
|
|
3986
|
+
* assertEqual(uuid[14], "7");
|
|
3987
|
+
* assertEqual(uuidToId(uuid), id);
|
|
3988
|
+
* ```
|
|
3989
|
+
*
|
|
3990
|
+
* @group String
|
|
3991
|
+
*/
|
|
3992
|
+
export declare const idToUuid: (value: Id) => Uuid;
|
|
3832
3993
|
/**
|
|
3833
3994
|
* Error returned when a string is not a canonical {@link Int64String}.
|
|
3834
3995
|
*
|