@ratelkey/burrow-sdk 0.1.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 (58) hide show
  1. package/README.md +108 -0
  2. package/dist/cjs/Burrow.js +30 -0
  3. package/dist/cjs/Burrow.js.map +1 -0
  4. package/dist/cjs/BurrowClient.js +110 -0
  5. package/dist/cjs/BurrowClient.js.map +1 -0
  6. package/dist/cjs/Errors.js +80 -0
  7. package/dist/cjs/Errors.js.map +1 -0
  8. package/dist/cjs/Identity.js +274 -0
  9. package/dist/cjs/Identity.js.map +1 -0
  10. package/dist/cjs/Model.js +143 -0
  11. package/dist/cjs/Model.js.map +1 -0
  12. package/dist/cjs/Signer.js +42 -0
  13. package/dist/cjs/Signer.js.map +1 -0
  14. package/dist/cjs/Tls.js +85 -0
  15. package/dist/cjs/Tls.js.map +1 -0
  16. package/dist/cjs/Transport.js +198 -0
  17. package/dist/cjs/Transport.js.map +1 -0
  18. package/dist/cjs/index.js +28 -0
  19. package/dist/cjs/index.js.map +1 -0
  20. package/dist/cjs/package.json +3 -0
  21. package/dist/esm/Burrow.d.ts +59 -0
  22. package/dist/esm/Burrow.d.ts.map +1 -0
  23. package/dist/esm/Burrow.js +27 -0
  24. package/dist/esm/Burrow.js.map +1 -0
  25. package/dist/esm/BurrowClient.d.ts +40 -0
  26. package/dist/esm/BurrowClient.d.ts.map +1 -0
  27. package/dist/esm/BurrowClient.js +106 -0
  28. package/dist/esm/BurrowClient.js.map +1 -0
  29. package/dist/esm/Errors.d.ts +57 -0
  30. package/dist/esm/Errors.d.ts.map +1 -0
  31. package/dist/esm/Errors.js +67 -0
  32. package/dist/esm/Errors.js.map +1 -0
  33. package/dist/esm/Identity.d.ts +62 -0
  34. package/dist/esm/Identity.d.ts.map +1 -0
  35. package/dist/esm/Identity.js +269 -0
  36. package/dist/esm/Identity.js.map +1 -0
  37. package/dist/esm/Model.d.ts +75 -0
  38. package/dist/esm/Model.d.ts.map +1 -0
  39. package/dist/esm/Model.js +137 -0
  40. package/dist/esm/Model.js.map +1 -0
  41. package/dist/esm/Signer.d.ts +19 -0
  42. package/dist/esm/Signer.d.ts.map +1 -0
  43. package/dist/esm/Signer.js +39 -0
  44. package/dist/esm/Signer.js.map +1 -0
  45. package/dist/esm/Tls.d.ts +71 -0
  46. package/dist/esm/Tls.d.ts.map +1 -0
  47. package/dist/esm/Tls.js +79 -0
  48. package/dist/esm/Tls.js.map +1 -0
  49. package/dist/esm/Transport.d.ts +29 -0
  50. package/dist/esm/Transport.d.ts.map +1 -0
  51. package/dist/esm/Transport.js +195 -0
  52. package/dist/esm/Transport.js.map +1 -0
  53. package/dist/esm/index.d.ts +9 -0
  54. package/dist/esm/index.d.ts.map +1 -0
  55. package/dist/esm/index.js +6 -0
  56. package/dist/esm/index.js.map +1 -0
  57. package/dist/esm/package.json +3 -0
  58. package/package.json +1 -0
package/README.md ADDED
@@ -0,0 +1,108 @@
1
+ # Burrow SDK for Node.js
2
+
3
+ Read secrets from a self-hosted [RatelKey](https://ratelkey.com) Burrow with a machine identity.
4
+
5
+ This is the Node.js SDK. It lives under `tools/SDKs/<language>/`, one directory per language; each SDK is a
6
+ standalone, independently-published artifact that speaks the same signed machine data-plane protocol. Its API
7
+ mirrors the Kotlin/JVM SDK one-for-one, so a Burrow reads the same way in either language.
8
+
9
+ ## What it does
10
+
11
+ A machine authenticates to a Burrow with a per-request **Ed25519 signature** — no session, no long-lived
12
+ bearer token. The private key is generated on the machine during bootstrap and never leaves it. This SDK
13
+ signs each read the same way the `ratel` CLI does, so a machine bootstrapped once works with both.
14
+
15
+ - Single and structured secrets, and individual fields of a structured secret.
16
+ - The machine's own access map (which projects/environments it can read).
17
+ - Trust-on-first-use certificate pinning for the default self-signed Burrow (shared pin store with the CLI),
18
+ or standard CA trust for a Burrow on a real domain.
19
+
20
+ ## Requirements
21
+
22
+ - Node 18.17+ (native Ed25519 in `node:crypto`, no crypto dependency).
23
+ - Zero runtime dependencies. Ships ESM and CommonJS, with TypeScript types.
24
+
25
+ ## Bootstrap a machine
26
+
27
+ From the Burrow dashboard, open **Machines → Add machine** and run the one-line install on the target host.
28
+ It generates the keypair locally, registers the public key, and writes the identity to
29
+ `~/.burrow/burrows/<slug>/identity.json`. Grant the machine access to the projects/environments it needs.
30
+
31
+ ## Quick start
32
+
33
+ ```ts
34
+ import { Burrow } from "@ratelkey/burrow-sdk";
35
+
36
+ // The single machine identity on this host (under ~/.burrow, or $BURROW_HOME).
37
+ const burrow = Burrow();
38
+
39
+ // A single-value secret:
40
+ const apiKey = (await burrow.getSecret("payments/prod/API_KEY")).value;
41
+
42
+ // A structured secret — one read, projected locally (no re-fetch):
43
+ const db = await burrow.getSecret("payments/prod/DATABASE");
44
+ const all = db.toMap(); // every field as name → value
45
+ const host = db.getField("host"); // one field
46
+ const [user, pass] = db.getFields("username", "password"); // in order — destructures
47
+
48
+ // What this machine can read:
49
+ for (const p of await burrow.listProjects()) console.log(`${p.project}: ${p.categories}`);
50
+ ```
51
+
52
+ Resolving the identity and loading its key are synchronous; only the reads themselves are async.
53
+
54
+ Point it at a specific identity by selector or path:
55
+
56
+ ```ts
57
+ Burrow("burrow-a1b2c3d4e5f60718"); // slug / name / machine id / URL
58
+ Burrow("/home/you/.burrow/burrows/burrow-a1b2c3d4e5f60718"); // path (a burrow dir or identity.json)
59
+ ```
60
+
61
+ ## Without `~/.burrow`
62
+
63
+ For an app that manages its own key material:
64
+
65
+ ```ts
66
+ const burrow = Burrow.connect({
67
+ burrowUrl: "https://burrow.internal:12010",
68
+ machineId: "…",
69
+ privateKeyPem: process.env.BURROW_MACHINE_KEY, // PKCS#8 PEM
70
+ });
71
+ ```
72
+
73
+ ## Certificate trust
74
+
75
+ Burrows serve HTTPS self-signed by default, so the SDK pins the Burrow's **public key** rather than
76
+ disabling verification. The key, not the certificate: a Burrow that adds a custom domain or renews its
77
+ certificate is still the same Burrow, and pinning the certificate would refuse it.
78
+
79
+ - `TlsMode.Pinned` (default) — trust-on-first-use; pins on first contact, refuses a changed key. Kept beside
80
+ that Burrow's identity at `~/.burrow/burrows/<slug>/known_cert`, shared with the CLI.
81
+ - `TlsMode.PinnedTo("aa:bb:…")` — pin to a known fingerprint (the SHA-256 the Burrow shows in its network
82
+ settings). No first-use trust.
83
+ - `TlsMode.SystemTrust` — standard CA + hostname verification, for a Burrow on a custom domain or Let's
84
+ Encrypt.
85
+
86
+ The handshake completes and the pin is checked before the HTTP request is written, so a mismatched
87
+ certificate never sees the signed request.
88
+
89
+ ```ts
90
+ import { Burrow, TlsMode } from "@ratelkey/burrow-sdk";
91
+
92
+ const burrow = Burrow(null, { tls: TlsMode.SystemTrust });
93
+ ```
94
+
95
+ ## Errors
96
+
97
+ Every failure is a `BurrowException`: `BurrowAuthException` (401), `BurrowForbiddenException` (403, no grant),
98
+ `BurrowNotFoundException` (404), `BurrowServerException` (5xx), `BurrowCertificateException` (pin mismatch),
99
+ `BurrowTransportException` (unreachable / unparsable), `BurrowIdentityException` (no/ambiguous/invalid
100
+ identity), plus two projection errors on the result handle — `SecretShapeException` (e.g. `.value` on a
101
+ structured secret) and `FieldNotFoundException`. The message carries the Burrow's own reason.
102
+
103
+ ## Build
104
+
105
+ ```
106
+ npm install
107
+ npm run build
108
+ ```
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Burrow = exports.DEFAULT_CLIENT_TAG = exports.SDK_VERSION = void 0;
4
+ const BurrowClient_js_1 = require("./BurrowClient.js");
5
+ const Identity_js_1 = require("./Identity.js");
6
+ const Tls_js_1 = require("./Tls.js");
7
+ /** The SDK version, reported in the `Ratel-Client` header for the Burrow's audit trail. */
8
+ exports.SDK_VERSION = "0.1.0";
9
+ /** The default `Ratel-Client` tag. It contains "sdk", so the Burrow classifies reads as the SDK channel. */
10
+ exports.DEFAULT_CLIENT_TAG = `ratel-sdk-node/${exports.SDK_VERSION}`;
11
+ /**
12
+ * Open a client. `target` is one of:
13
+ * - omitted — the single identity on this host (under `~/.burrow`, or `$BURROW_HOME`);
14
+ * - a selector — a burrow slug, name, machine id, or URL;
15
+ * - a filesystem path — a burrow identity directory or an `identity.json` file.
16
+ */
17
+ function open(target, options = {}) {
18
+ const id = Identity_js_1.Identities.select(target);
19
+ return new BurrowClient_js_1.DefaultBurrowClient(id.burrowUrl, id.machineId, id.loadPrivateKey(), options.clientTag ?? exports.DEFAULT_CLIENT_TAG, options.tls ?? Tls_js_1.TlsMode.Pinned, id.directory);
20
+ }
21
+ /**
22
+ * Connect with an explicit identity — for an app that manages its own key material rather than reading the
23
+ * `~/.burrow` file.
24
+ */
25
+ function connect(options) {
26
+ const key = (0, Identity_js_1.parseEd25519PrivateKey)(options.privateKeyPem, "provided PEM");
27
+ return new BurrowClient_js_1.DefaultBurrowClient(options.burrowUrl, options.machineId, key, options.clientTag ?? exports.DEFAULT_CLIENT_TAG, options.tls ?? Tls_js_1.TlsMode.Pinned, options.pinStoreDir ?? null);
28
+ }
29
+ exports.Burrow = Object.assign(open, { DEFAULT_CLIENT_TAG: exports.DEFAULT_CLIENT_TAG, connect });
30
+ //# sourceMappingURL=Burrow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Burrow.js","sourceRoot":"","sources":["../../src/Burrow.ts"],"names":[],"mappings":";;;AAAA,uDAA2E;AAC3E,+CAAmE;AACnE,qCAAmC;AAEnC,2FAA2F;AAC9E,QAAA,WAAW,GAAG,OAAO,CAAC;AAEnC,4GAA4G;AAC/F,QAAA,kBAAkB,GAAG,kBAAkB,mBAAW,EAAE,CAAC;AA2BlE;;;;;GAKG;AACH,SAAS,IAAI,CAAC,MAAsB,EAAE,UAAyB,EAAE;IAC/D,MAAM,EAAE,GAAG,wBAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrC,OAAO,IAAI,qCAAmB,CAC5B,EAAE,CAAC,SAAS,EACZ,EAAE,CAAC,SAAS,EACZ,EAAE,CAAC,cAAc,EAAE,EACnB,OAAO,CAAC,SAAS,IAAI,0BAAkB,EACvC,OAAO,CAAC,GAAG,IAAI,gBAAO,CAAC,MAAM,EAC7B,EAAE,CAAC,SAAS,CACb,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CAAC,OAAuB;IACtC,MAAM,GAAG,GAAG,IAAA,oCAAsB,EAAC,OAAO,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;IAC1E,OAAO,IAAI,qCAAmB,CAC5B,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,SAAS,EACjB,GAAG,EACH,OAAO,CAAC,SAAS,IAAI,0BAAkB,EACvC,OAAO,CAAC,GAAG,IAAI,gBAAO,CAAC,MAAM,EAC7B,OAAO,CAAC,WAAW,IAAI,IAAI,CAC5B,CAAC;AACJ,CAAC;AAiCY,QAAA,MAAM,GAAkB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,kBAAkB,EAAlB,0BAAkB,EAAE,OAAO,EAAE,CAAC,CAAC"}
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DefaultBurrowClient = void 0;
4
+ const Errors_js_1 = require("./Errors.js");
5
+ const Model_js_1 = require("./Model.js");
6
+ const Signer_js_1 = require("./Signer.js");
7
+ const Transport_js_1 = require("./Transport.js");
8
+ /** The default {@link BurrowClient}: signs each request and talks to the Burrow over the pinned transport. */
9
+ class DefaultBurrowClient {
10
+ burrowUrl;
11
+ machineId;
12
+ key;
13
+ clientTag;
14
+ now;
15
+ transport;
16
+ constructor(burrowUrl, machineId, key, clientTag, tls,
17
+ /** Where this Burrow's pinned key is kept — its identity directory. Null for a caller that has none. */
18
+ pinStoreDir, now = Date.now) {
19
+ this.burrowUrl = burrowUrl;
20
+ this.machineId = machineId;
21
+ this.key = key;
22
+ this.clientTag = clientTag;
23
+ this.now = now;
24
+ this.transport = new Transport_js_1.Transport(burrowUrl, tls, pinStoreDir);
25
+ }
26
+ async getSecret(coordinate) {
27
+ const c = Model_js_1.SecretCoordinate.parse(coordinate);
28
+ if (c.project.length === 0 || c.environment.length === 0 || c.name.length === 0) {
29
+ throw new TypeError(`secret coordinate must be 'project/environment/NAME', got '${coordinate}'`);
30
+ }
31
+ const body = await this.signedGet("secret.read", [c.project, c.environment, c.name], `/v1/machine/secrets/${encode(c.project)}/${encode(c.environment)}/${encode(c.name)}`);
32
+ return parseSecret(body);
33
+ }
34
+ async listSecrets() {
35
+ const body = await this.signedGet("secrets.list", [], "/v1/machine/secrets");
36
+ const dto = decode(body);
37
+ const secrets = dto["secrets"];
38
+ if (!Array.isArray(secrets))
39
+ return [];
40
+ return secrets.filter((s) => typeof s === "string").map((s) => Model_js_1.SecretCoordinate.parse(s));
41
+ }
42
+ async listProjects() {
43
+ const body = await this.signedGet("projects.list", [], "/v1/machine/projects");
44
+ const dto = decode(body);
45
+ const projects = dto["projects"];
46
+ if (!Array.isArray(projects))
47
+ return [];
48
+ return projects.map((p) => {
49
+ const o = (p ?? {});
50
+ const categories = o["categories"];
51
+ return new Model_js_1.ProjectAccess(typeof o["project"] === "string" ? o["project"] : "", Array.isArray(categories) ? categories.filter((c) => typeof c === "string") : []);
52
+ });
53
+ }
54
+ signedGet(action, resource, path) {
55
+ const headers = Signer_js_1.MachineSigner.sign(this.machineId, this.key, action, resource, this.clientTag, this.now());
56
+ return this.transport.get(path, headers);
57
+ }
58
+ }
59
+ exports.DefaultBurrowClient = DefaultBurrowClient;
60
+ /**
61
+ * The read response. `value`/`version` are present for a single value, `fields` for a whole structured
62
+ * secret. Mirrors the Burrow's MachineSecretView / MachineStructuredView; unknown keys are ignored.
63
+ */
64
+ function parseSecret(body) {
65
+ const dto = decode(body);
66
+ const name = typeof dto["name"] === "string" ? dto["name"] : "";
67
+ const rawFields = dto["fields"];
68
+ if (Array.isArray(rawFields)) {
69
+ const fields = new Map();
70
+ for (const raw of rawFields) {
71
+ const f = (raw ?? {});
72
+ const fieldName = typeof f["name"] === "string" ? f["name"] : "";
73
+ fields.set(fieldName, {
74
+ name: fieldName,
75
+ value: typeof f["value"] === "string" ? f["value"] : "",
76
+ type: typeof f["type"] === "string" ? f["type"] : "",
77
+ });
78
+ }
79
+ return Model_js_1.Secret.structured(name, fields);
80
+ }
81
+ return Model_js_1.Secret.single(name, typeof dto["value"] === "string" ? dto["value"] : "", typeof dto["type"] === "string" ? dto["type"] : "", typeof dto["version"] === "number" ? dto["version"] : 0);
82
+ }
83
+ function decode(body) {
84
+ let parsed;
85
+ try {
86
+ parsed = JSON.parse(body);
87
+ }
88
+ catch (e) {
89
+ throw new Errors_js_1.BurrowTransportException(`decoding burrow response: ${e instanceof Error ? e.message : String(e)}`, { cause: e });
90
+ }
91
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
92
+ throw new Errors_js_1.BurrowTransportException("decoding burrow response: expected a JSON object");
93
+ }
94
+ return parsed;
95
+ }
96
+ /**
97
+ * Percent-encode one URL path segment (RFC 3986 unreserved set), so a coordinate reaches the Burrow intact
98
+ * and decodes back to the exact value the signature covers. `encodeURIComponent` leaves `!'()*` unescaped,
99
+ * which is why this is spelled out.
100
+ */
101
+ function encode(s) {
102
+ let out = "";
103
+ for (const b of Buffer.from(s, "utf8")) {
104
+ const ch = String.fromCharCode(b);
105
+ out += UNRESERVED.test(ch) ? ch : `%${b.toString(16).toUpperCase().padStart(2, "0")}`;
106
+ }
107
+ return out;
108
+ }
109
+ const UNRESERVED = /^[A-Za-z0-9\-._~]$/;
110
+ //# sourceMappingURL=BurrowClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BurrowClient.js","sourceRoot":"","sources":["../../src/BurrowClient.ts"],"names":[],"mappings":";;;AACA,2CAAuD;AACvD,yCAAuF;AACvF,2CAA4C;AAE5C,iDAA2C;AA2B3C,8GAA8G;AAC9G,MAAa,mBAAmB;IAInB;IACA;IACQ;IACA;IAIA;IAVF,SAAS,CAAY;IAEtC,YACW,SAAiB,EACjB,SAAiB,EACT,GAAc,EACd,SAAiB,EAClC,GAAY;IACZ,wGAAwG;IACxG,WAA0B,EACT,MAAoB,IAAI,CAAC,GAAG;QAPpC,cAAS,GAAT,SAAS,CAAQ;QACjB,cAAS,GAAT,SAAS,CAAQ;QACT,QAAG,GAAH,GAAG,CAAW;QACd,cAAS,GAAT,SAAS,CAAQ;QAIjB,QAAG,GAAH,GAAG,CAAyB;QAE7C,IAAI,CAAC,SAAS,GAAG,IAAI,wBAAS,CAAC,SAAS,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,UAAkB;QAChC,MAAM,CAAC,GAAG,2BAAgB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChF,MAAM,IAAI,SAAS,CAAC,8DAA8D,UAAU,GAAG,CAAC,CAAC;QACnG,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAC/B,aAAa,EACb,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,EAClC,uBAAuB,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CACtF,CAAC;QACF,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,EAAE,EAAE,qBAAqB,CAAC,CAAC;QAC7E,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QACzB,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;QAC/B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YAAE,OAAO,EAAE,CAAC;QACvC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,2BAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACzG,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,EAAE,EAAE,sBAAsB,CAAC,CAAC;QAC/E,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QACzB,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,OAAO,EAAE,CAAC;QACxC,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE;YACjC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAA4B,CAAC;YAC/C,MAAM,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC;YACnC,OAAO,IAAI,wBAAa,CACtB,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,EACpD,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAC9F,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,SAAS,CAAC,MAAc,EAAE,QAAkB,EAAE,IAAY;QAChE,MAAM,OAAO,GAAG,yBAAa,CAAC,IAAI,CAChC,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,GAAG,EACR,MAAM,EACN,QAAQ,EACR,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,GAAG,EAAE,CACX,CAAC;QACF,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;CACF;AA/DD,kDA+DC;AAED;;;GAGG;AACH,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAChE,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;QAC9C,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAA4B,CAAC;YACjD,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE;gBACpB,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;gBACvD,IAAI,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;aACrD,CAAC,CAAC;QACL,CAAC;QACD,OAAO,iBAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,iBAAM,CAAC,MAAM,CAClB,IAAI,EACJ,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EACpD,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAClD,OAAO,GAAG,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CACxD,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CAAC,IAAY;IAC1B,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,oCAAwB,CAChC,6BAA6B,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EACzE,EAAE,KAAK,EAAE,CAAC,EAAE,CACb,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,MAAM,IAAI,oCAAwB,CAAC,kDAAkD,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,MAAiC,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,SAAS,MAAM,CAAC,CAAS;IACvB,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC;QACvC,MAAM,EAAE,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;IACxF,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,GAAG,oBAAoB,CAAC"}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FieldNotFoundException = exports.SecretShapeException = exports.BurrowIdentityException = exports.BurrowTransportException = exports.BurrowCertificateException = exports.BurrowServerException = exports.BurrowNotFoundException = exports.BurrowForbiddenException = exports.BurrowAuthException = exports.BurrowException = void 0;
4
+ /**
5
+ * Base type for every error the SDK raises. Catch this to handle any Burrow failure uniformly.
6
+ *
7
+ * The names mirror the Kotlin SDK's exception hierarchy one-for-one, so a failure means the same thing and
8
+ * is documented the same way in every language we ship.
9
+ */
10
+ class BurrowException extends Error {
11
+ constructor(message, options) {
12
+ super(message, options);
13
+ // `new.target` is the concrete subclass, so every error reports its own name without each subclass
14
+ // having to restate it.
15
+ this.name = new.target.name;
16
+ }
17
+ }
18
+ exports.BurrowException = BurrowException;
19
+ /**
20
+ * The Burrow rejected the signed request (HTTP 401). Every authentication failure collapses to one reason:
21
+ * an unknown or disabled machine, a bad signature, a replayed nonce, or a clock skew past the freshness
22
+ * window. The message is the Burrow's own verbatim reason.
23
+ */
24
+ class BurrowAuthException extends BurrowException {
25
+ }
26
+ exports.BurrowAuthException = BurrowAuthException;
27
+ /** The machine authenticated but holds no grant for the requested project/environment (HTTP 403). */
28
+ class BurrowForbiddenException extends BurrowException {
29
+ }
30
+ exports.BurrowForbiddenException = BurrowForbiddenException;
31
+ /** The requested project, environment, secret, or field does not exist (HTTP 404). */
32
+ class BurrowNotFoundException extends BurrowException {
33
+ }
34
+ exports.BurrowNotFoundException = BurrowNotFoundException;
35
+ /** The Burrow failed to serve the request (HTTP 5xx) — e.g. server-side decryption failed. */
36
+ class BurrowServerException extends BurrowException {
37
+ status;
38
+ constructor(status, message) {
39
+ super(message);
40
+ this.status = status;
41
+ }
42
+ }
43
+ exports.BurrowServerException = BurrowServerException;
44
+ /**
45
+ * The Burrow's TLS certificate did not match the pinned one. Either the Burrow's certificate was re-issued
46
+ * (remove its entry from the pin store and retry) or the connection is being intercepted.
47
+ */
48
+ class BurrowCertificateException extends BurrowException {
49
+ }
50
+ exports.BurrowCertificateException = BurrowCertificateException;
51
+ /** The Burrow could not be reached, or its response could not be parsed. */
52
+ class BurrowTransportException extends BurrowException {
53
+ }
54
+ exports.BurrowTransportException = BurrowTransportException;
55
+ /**
56
+ * The machine identity could not be resolved or loaded: no identity on this host, an ambiguous selector, a
57
+ * missing or invalid private key, or a malformed identity file.
58
+ */
59
+ class BurrowIdentityException extends BurrowException {
60
+ }
61
+ exports.BurrowIdentityException = BurrowIdentityException;
62
+ /**
63
+ * A projection didn't match the secret's shape — `Secret.value` on a structured secret, or
64
+ * `Secret.toMap()` / `Secret.getField()` / `Secret.getFields()` on a single-value one.
65
+ */
66
+ class SecretShapeException extends BurrowException {
67
+ }
68
+ exports.SecretShapeException = SecretShapeException;
69
+ /** A requested field is not present in a structured secret. */
70
+ class FieldNotFoundException extends BurrowException {
71
+ secret;
72
+ field;
73
+ constructor(secret, field, available) {
74
+ super(`no field '${field}' in '${secret}' (has: ${[...available].sort().join(", ")})`);
75
+ this.secret = secret;
76
+ this.field = field;
77
+ }
78
+ }
79
+ exports.FieldNotFoundException = FieldNotFoundException;
80
+ //# sourceMappingURL=Errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Errors.js","sourceRoot":"","sources":["../../src/Errors.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,MAAa,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,mGAAmG;QACnG,wBAAwB;QACxB,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;IAC9B,CAAC;CACF;AAPD,0CAOC;AAED;;;;GAIG;AACH,MAAa,mBAAoB,SAAQ,eAAe;CAAG;AAA3D,kDAA2D;AAE3D,qGAAqG;AACrG,MAAa,wBAAyB,SAAQ,eAAe;CAAG;AAAhE,4DAAgE;AAEhE,sFAAsF;AACtF,MAAa,uBAAwB,SAAQ,eAAe;CAAG;AAA/D,0DAA+D;AAE/D,8FAA8F;AAC9F,MAAa,qBAAsB,SAAQ,eAAe;IAE7C;IADX,YACW,MAAc,EACvB,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAHN,WAAM,GAAN,MAAM,CAAQ;IAIzB,CAAC;CACF;AAPD,sDAOC;AAED;;;GAGG;AACH,MAAa,0BAA2B,SAAQ,eAAe;CAAG;AAAlE,gEAAkE;AAElE,4EAA4E;AAC5E,MAAa,wBAAyB,SAAQ,eAAe;CAAG;AAAhE,4DAAgE;AAEhE;;;GAGG;AACH,MAAa,uBAAwB,SAAQ,eAAe;CAAG;AAA/D,0DAA+D;AAE/D;;;GAGG;AACH,MAAa,oBAAqB,SAAQ,eAAe;CAAG;AAA5D,oDAA4D;AAE5D,+DAA+D;AAC/D,MAAa,sBAAuB,SAAQ,eAAe;IAE9C;IACA;IAFX,YACW,MAAc,EACd,KAAa,EACtB,SAA2B;QAE3B,KAAK,CAAC,aAAa,KAAK,SAAS,MAAM,WAAW,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAJ9E,WAAM,GAAN,MAAM,CAAQ;QACd,UAAK,GAAL,KAAK,CAAQ;IAIxB,CAAC;CACF;AARD,wDAQC"}
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Identities = exports.MachineIdentity = void 0;
4
+ exports.parseEd25519PrivateKey = parseEd25519PrivateKey;
5
+ const node_crypto_1 = require("node:crypto");
6
+ const node_fs_1 = require("node:fs");
7
+ const node_os_1 = require("node:os");
8
+ const node_path_1 = require("node:path");
9
+ const Errors_js_1 = require("./Errors.js");
10
+ /**
11
+ * A machine identity for one Burrow — the record the `curl | sh` bootstrap writes to
12
+ * `~/.burrow/burrows/<slug>/identity.json`, plus a reference to the Ed25519 private key it generated. One
13
+ * identity per Burrow; a client acts as exactly one of them.
14
+ *
15
+ * The private key never leaves the machine: it stays in the referenced PEM file and only signs requests.
16
+ */
17
+ class MachineIdentity {
18
+ burrowUrl;
19
+ machineId;
20
+ privateKeyPath;
21
+ slug;
22
+ burrowName;
23
+ name;
24
+ constructor(burrowUrl, machineId, privateKeyPath, slug = "", burrowName = "", name = "") {
25
+ this.burrowUrl = burrowUrl;
26
+ this.machineId = machineId;
27
+ this.privateKeyPath = privateKeyPath;
28
+ this.slug = slug;
29
+ this.burrowName = burrowName;
30
+ this.name = name;
31
+ }
32
+ /** The Burrow's shown label, falling back to slug, then the URL host. */
33
+ get label() {
34
+ return (blankTo(this.burrowName, blankTo(this.slug, blankTo(hostOf(this.burrowUrl), "(unnamed burrow)"))));
35
+ }
36
+ /**
37
+ * The directory this identity lives in — `<home>/burrows/<slug>/`, where its pinned key sits beside it.
38
+ *
39
+ * Derived from `privateKeyPath` rather than recorded, because identity.json does not carry it: the
40
+ * bootstrap writes the key as `<dir>/identity.pem`, so the parent IS the directory.
41
+ *
42
+ * @internal
43
+ */
44
+ get directory() {
45
+ return (0, node_path_1.dirname)(this.privateKeyPath);
46
+ }
47
+ /** @internal */
48
+ matches(selector) {
49
+ const s = selector.trim();
50
+ return (eq(s, this.burrowName) ||
51
+ eq(s, this.slug) ||
52
+ eq(s, this.machineId) ||
53
+ eq(s, this.burrowUrl) ||
54
+ eq(s, this.label));
55
+ }
56
+ /** Load and parse the Ed25519 private key (PKCS#8 PEM) this identity references. */
57
+ loadPrivateKey() {
58
+ let pem;
59
+ try {
60
+ pem = (0, node_fs_1.readFileSync)(this.privateKeyPath, "utf8");
61
+ }
62
+ catch (e) {
63
+ throw new Errors_js_1.BurrowIdentityException(`reading private key ${this.privateKeyPath}: ${messageOf(e)}`, { cause: e });
64
+ }
65
+ return parseEd25519PrivateKey(pem, this.privateKeyPath);
66
+ }
67
+ /**
68
+ * Read one identity record. The three fields the bootstrap always writes are required; the rest are
69
+ * display metadata that a hand-written file may omit.
70
+ */
71
+ /** @internal */
72
+ static fromJson(raw) {
73
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
74
+ throw new Errors_js_1.BurrowIdentityException("identity is not a JSON object");
75
+ }
76
+ const o = raw;
77
+ return new MachineIdentity(required(o, "burrowUrl"), required(o, "machineId"), required(o, "privateKeyPath"), optional(o, "slug"), optional(o, "burrowName"), optional(o, "name"));
78
+ }
79
+ }
80
+ exports.MachineIdentity = MachineIdentity;
81
+ /** Discovers and resolves the machine identities the bootstrap writes under `~/.burrow`. */
82
+ exports.Identities = {
83
+ /** The identity root: `$BURROW_HOME` if set, else `~/.burrow`. */
84
+ home() {
85
+ const env = process.env["BURROW_HOME"];
86
+ if (env !== undefined && env.trim().length > 0)
87
+ return env;
88
+ return (0, node_path_1.join)((0, node_os_1.homedir)(), ".burrow");
89
+ },
90
+ /**
91
+ * Every identity under `<home>/burrows/<slug>/identity.json`, sorted by label then machine id.
92
+ * Directories without a readable, well-formed identity.json are skipped.
93
+ */
94
+ discover(home = exports.Identities.home()) {
95
+ const burrows = (0, node_path_1.join)(home, "burrows");
96
+ if (!isDirectory(burrows))
97
+ return [];
98
+ let entries;
99
+ try {
100
+ entries = (0, node_fs_1.readdirSync)(burrows);
101
+ }
102
+ catch {
103
+ return [];
104
+ }
105
+ const found = [];
106
+ for (const entry of entries) {
107
+ const dir = (0, node_path_1.join)(burrows, entry);
108
+ if (!isDirectory(dir))
109
+ continue;
110
+ const file = (0, node_path_1.join)(dir, "identity.json");
111
+ if (!(0, node_fs_1.existsSync)(file))
112
+ continue;
113
+ try {
114
+ found.push(MachineIdentity.fromJson(JSON.parse((0, node_fs_1.readFileSync)(file, "utf8"))));
115
+ }
116
+ catch {
117
+ // A half-written or foreign file is not this host's identity; skip it rather than fail discovery.
118
+ }
119
+ }
120
+ // Ordinal, not locale-aware: the order has to be the same on every host that reads the same identities.
121
+ return found.sort((a, b) => ordinal(a.label.toLowerCase(), b.label.toLowerCase()) || ordinal(a.machineId, b.machineId));
122
+ },
123
+ /**
124
+ * Resolve the identity a client should act as. A single identity on file resolves automatically; with
125
+ * several, `selector` (a burrow name, slug, machine id, or URL) must disambiguate.
126
+ */
127
+ resolve(selector, home = exports.Identities.home()) {
128
+ const ids = exports.Identities.discover(home);
129
+ if (ids.length === 0) {
130
+ throw new Errors_js_1.BurrowIdentityException(`no Burrow identities under ${(0, node_path_1.join)(home, "burrows")}. Bootstrap this machine into a Burrow ` +
131
+ "first (its Machines page, Add machine).");
132
+ }
133
+ if (selector === undefined || selector === null || selector.trim().length === 0) {
134
+ const only = ids[0];
135
+ if (ids.length === 1 && only !== undefined)
136
+ return only;
137
+ throw new Errors_js_1.BurrowIdentityException(`this machine holds ${ids.length} Burrow identities; select one by name, slug, or machine id. ` +
138
+ `Known: ${ids.map((i) => i.label).join(", ")}`);
139
+ }
140
+ const matched = ids.filter((i) => i.matches(selector));
141
+ const first = matched[0];
142
+ if (matched.length === 1 && first !== undefined)
143
+ return first;
144
+ if (matched.length === 0) {
145
+ throw new Errors_js_1.BurrowIdentityException(`no Burrow identity matches "${selector}". Known: ${ids.map((i) => i.label).join(", ")}`);
146
+ }
147
+ throw new Errors_js_1.BurrowIdentityException(`"${selector}" matches more than one identity; select by machine id.`);
148
+ },
149
+ /**
150
+ * Resolve `target` to an identity for `Burrow`: null/undefined → the single identity (`resolve`); a
151
+ * filesystem path (a burrow directory or an identity.json) → load it directly; anything else → a selector
152
+ * (`resolve`). A URL (contains `://`) is always treated as a selector, never a path.
153
+ */
154
+ select(target, home = exports.Identities.home()) {
155
+ if (target === undefined || target === null || target.trim().length === 0) {
156
+ return exports.Identities.resolve(null, home);
157
+ }
158
+ if (!target.includes("://") && looksLikePath(target))
159
+ return loadFromPath(expandUser(target));
160
+ return exports.Identities.resolve(target, home);
161
+ },
162
+ };
163
+ /** Parse an Ed25519 private key from a PKCS#8 PEM string (what `openssl genpkey -algorithm ed25519` writes). */
164
+ function parseEd25519PrivateKey(pem, source) {
165
+ const der = pemBody(pem);
166
+ if (der === null)
167
+ throw new Errors_js_1.BurrowIdentityException(`no PEM private-key block in ${source}`);
168
+ let key;
169
+ try {
170
+ // DER + pkcs8 explicitly, so a SEC1 or PKCS#1 body fails here rather than being silently accepted.
171
+ key = (0, node_crypto_1.createPrivateKey)({ key: der, format: "der", type: "pkcs8" });
172
+ }
173
+ catch (e) {
174
+ throw new Errors_js_1.BurrowIdentityException(`parsing Ed25519 private key in ${source}: ${messageOf(e)}`, { cause: e });
175
+ }
176
+ if (key.asymmetricKeyType !== "ed25519") {
177
+ throw new Errors_js_1.BurrowIdentityException(`parsing Ed25519 private key in ${source}: key is ${key.asymmetricKeyType ?? "of an unknown type"}, not Ed25519`);
178
+ }
179
+ return key;
180
+ }
181
+ /** Strip the PEM armor and base64-decode the body. Null when there is no PEM block. */
182
+ function pemBody(pem) {
183
+ const begin = pem.indexOf("-----BEGIN");
184
+ if (begin < 0)
185
+ return null;
186
+ const afterBeginLine = pem.indexOf("\n", begin);
187
+ if (afterBeginLine < 0)
188
+ return null;
189
+ const end = pem.indexOf("-----END", afterBeginLine + 1);
190
+ if (end < 0)
191
+ return null;
192
+ const base64 = pem.slice(afterBeginLine + 1, end).replace(/\s/g, "");
193
+ try {
194
+ return Buffer.from(base64, "base64");
195
+ }
196
+ catch {
197
+ return null;
198
+ }
199
+ }
200
+ /** The host[:port] of a URL, for a display-only label fallback. */
201
+ function hostOf(url) {
202
+ let s = url;
203
+ const scheme = s.indexOf("://");
204
+ if (scheme >= 0)
205
+ s = s.slice(scheme + 3);
206
+ const slash = s.indexOf("/");
207
+ if (slash >= 0)
208
+ s = s.slice(0, slash);
209
+ return s;
210
+ }
211
+ function looksLikePath(s) {
212
+ if (s.startsWith("/") || s.startsWith("~") || s.startsWith("./") || s.startsWith("../"))
213
+ return true;
214
+ if (s.endsWith(".json"))
215
+ return true;
216
+ if ((0, node_path_1.isAbsolute)(s))
217
+ return true;
218
+ try {
219
+ return (0, node_fs_1.existsSync)(s);
220
+ }
221
+ catch {
222
+ return false;
223
+ }
224
+ }
225
+ function expandUser(s) {
226
+ if (!s.startsWith("~"))
227
+ return s;
228
+ return (0, node_path_1.join)((0, node_os_1.homedir)(), s.slice(1).replace(/^\//, ""));
229
+ }
230
+ function loadFromPath(path) {
231
+ const file = isDirectory(path) ? (0, node_path_1.join)(path, "identity.json") : path;
232
+ if (!(0, node_fs_1.existsSync)(file))
233
+ throw new Errors_js_1.BurrowIdentityException(`no identity file at ${file}`);
234
+ try {
235
+ return MachineIdentity.fromJson(JSON.parse((0, node_fs_1.readFileSync)(file, "utf8")));
236
+ }
237
+ catch (e) {
238
+ throw new Errors_js_1.BurrowIdentityException(`failed to parse identity file ${file}: ${messageOf(e)}`, {
239
+ cause: e,
240
+ });
241
+ }
242
+ }
243
+ function isDirectory(path) {
244
+ try {
245
+ return (0, node_fs_1.statSync)(path).isDirectory();
246
+ }
247
+ catch {
248
+ return false;
249
+ }
250
+ }
251
+ function required(o, key) {
252
+ const v = o[key];
253
+ if (typeof v !== "string" || v.length === 0) {
254
+ throw new Errors_js_1.BurrowIdentityException(`identity is missing '${key}'`);
255
+ }
256
+ return v;
257
+ }
258
+ function optional(o, key) {
259
+ const v = o[key];
260
+ return typeof v === "string" ? v : "";
261
+ }
262
+ function blankTo(value, fallback) {
263
+ return value.trim().length > 0 ? value : fallback;
264
+ }
265
+ function eq(a, b) {
266
+ return a.toLowerCase() === b.toLowerCase();
267
+ }
268
+ function ordinal(a, b) {
269
+ return a < b ? -1 : a > b ? 1 : 0;
270
+ }
271
+ function messageOf(e) {
272
+ return e instanceof Error ? e.message : String(e);
273
+ }
274
+ //# sourceMappingURL=Identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Identity.js","sourceRoot":"","sources":["../../src/Identity.ts"],"names":[],"mappings":"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"}