hikoutei 0.11.101-dev → 0.11.103-dev
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/cli/adoptFlow.d.ts.map +1 -1
- package/dist/cli/adoptFlow.js +31 -0
- package/dist/cli/adoptFlow.js.map +1 -1
- package/dist/cli/checkpoint.d.ts +38 -52
- package/dist/cli/checkpoint.d.ts.map +1 -1
- package/dist/cli/checkpoint.js +87 -34
- package/dist/cli/checkpoint.js.map +1 -1
- package/dist/cli/envFileWriter.d.ts +42 -8
- package/dist/cli/envFileWriter.d.ts.map +1 -1
- package/dist/cli/envFileWriter.js +60 -30
- package/dist/cli/envFileWriter.js.map +1 -1
- package/dist/cli/errors.d.ts +6 -5
- package/dist/cli/errors.d.ts.map +1 -1
- package/dist/cli/errors.js +6 -5
- package/dist/cli/errors.js.map +1 -1
- package/dist/cli/gcloudRunner.d.ts +22 -5
- package/dist/cli/gcloudRunner.d.ts.map +1 -1
- package/dist/cli/gcloudRunner.js +168 -0
- package/dist/cli/gcloudRunner.js.map +1 -1
- package/dist/cli/keyContract.d.ts +62 -0
- package/dist/cli/keyContract.d.ts.map +1 -0
- package/dist/cli/keyContract.js +24 -0
- package/dist/cli/keyContract.js.map +1 -0
- package/dist/cli/keyMaterial.d.ts +1 -1
- package/dist/cli/keyMaterial.d.ts.map +1 -1
- package/dist/cli/keyMaterial.js +2 -2
- package/dist/cli/keyMaterial.js.map +1 -1
- package/dist/cli/keyProvision.d.ts +22 -44
- package/dist/cli/keyProvision.d.ts.map +1 -1
- package/dist/cli/keyProvision.js +212 -103
- package/dist/cli/keyProvision.js.map +1 -1
- package/dist/cli/setupFlow.d.ts +2 -7
- package/dist/cli/setupFlow.d.ts.map +1 -1
- package/dist/cli/setupFlow.js +301 -55
- package/dist/cli/setupFlow.js.map +1 -1
- package/dist/cli/setupPathCollision.d.ts +11 -3
- package/dist/cli/setupPathCollision.d.ts.map +1 -1
- package/dist/cli/setupPathCollision.js +10 -7
- package/dist/cli/setupPathCollision.js.map +1 -1
- package/dist/cli/setupPaths.d.ts +2 -0
- package/dist/cli/setupPaths.d.ts.map +1 -1
- package/dist/cli/setupPaths.js +9 -0
- package/dist/cli/setupPaths.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/batchBuilder.d.ts +10 -0
- package/dist/sheets/providers/google-sheets-api/model/batchBuilder.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/batchBuilder.js +25 -36
- package/dist/sheets/providers/google-sheets-api/model/batchBuilder.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/planner.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/planner.js +0 -3
- package/dist/sheets/providers/google-sheets-api/model/planner.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/fastAppend.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/fastAppend.js +3 -13
- package/dist/sheets/providers/google-sheets-api/operations/fastAppend.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/rowChecks.js +9 -10
- package/dist/sheets/providers/google-sheets-api/operations/rowChecks.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared service-account key contract for `hikoutei setup`.
|
|
3
|
+
*
|
|
4
|
+
* Dependency-free leaf owning the non-secret key constants and metadata
|
|
5
|
+
* result types shared by the checkpoint module and the key-material reader,
|
|
6
|
+
* so neither imports the other for these names (previously the
|
|
7
|
+
* checkpoint ↔ keyMaterial backedge). Moved verbatim from checkpoint.ts;
|
|
8
|
+
* no behavior change. The checkpoint module path stays stable for existing
|
|
9
|
+
* importers via re-exports.
|
|
10
|
+
*/
|
|
11
|
+
/** Service-account key file permission after setup (owner read/write only). */
|
|
12
|
+
export declare const SERVICE_ACCOUNT_KEY_FILE_MODE = 384;
|
|
13
|
+
/**
|
|
14
|
+
* Restricted format of a service-account key id (`private_key_id`).
|
|
15
|
+
*
|
|
16
|
+
* Google user-managed service-account key ids are 16 lowercase hex digits;
|
|
17
|
+
* the pattern accepts 16-40 hex digits so the setup never rejects a valid
|
|
18
|
+
* key, while still refusing arbitrary payload text. The key id is NOT
|
|
19
|
+
* secret: it is the last segment of the key's IAM resource name
|
|
20
|
+
* (`projects/<project>/serviceAccounts/<email>/keys/<id>`) and is used to
|
|
21
|
+
* match a local key file against the cloud key list during reconciliation.
|
|
22
|
+
*/
|
|
23
|
+
export declare const SERVICE_ACCOUNT_KEY_ID_PATTERN: RegExp;
|
|
24
|
+
/** Validated metadata of a service-account key JSON file. */
|
|
25
|
+
export interface ServiceAccountKeyMetadata {
|
|
26
|
+
readonly projectId: string;
|
|
27
|
+
readonly clientEmail: string;
|
|
28
|
+
/** Non-secret `private_key_id`; matches the last segment of the IAM key resource name. */
|
|
29
|
+
readonly keyId: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Result of reading and validating a service-account key file.
|
|
33
|
+
*
|
|
34
|
+
* Only the descriptor-based secure reader is used; the plain pathname
|
|
35
|
+
* reader was removed because a check-then-read sequence cannot be secured
|
|
36
|
+
* against a mid-read alias swap.
|
|
37
|
+
*/
|
|
38
|
+
export type KeyMetadataResult = {
|
|
39
|
+
readonly status: "ok";
|
|
40
|
+
readonly metadata: ServiceAccountKeyMetadata;
|
|
41
|
+
} | {
|
|
42
|
+
readonly status: "invalid";
|
|
43
|
+
readonly message: string;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Result of the secure, descriptor-based key file read.
|
|
47
|
+
*
|
|
48
|
+
* `absent` means the path does not exist (the caller decides whether a
|
|
49
|
+
* missing key is valid for the current checkpoint status); `invalid` means
|
|
50
|
+
* the path exists but is not a regular file, could not be secured to mode
|
|
51
|
+
* 0600, or does not parse as a service-account key for any project.
|
|
52
|
+
*/
|
|
53
|
+
export type SecureKeyReadResult = {
|
|
54
|
+
readonly status: "absent";
|
|
55
|
+
} | {
|
|
56
|
+
readonly status: "ok";
|
|
57
|
+
readonly metadata: ServiceAccountKeyMetadata;
|
|
58
|
+
} | {
|
|
59
|
+
readonly status: "invalid";
|
|
60
|
+
readonly message: string;
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=keyContract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyContract.d.ts","sourceRoot":"","sources":["../../../../../../src/keyContract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,+EAA+E;AAC/E,eAAO,MAAM,6BAA6B,MAAQ,CAAC;AAEnD;;;;;;;;;GASG;AACH,eAAO,MAAM,8BAA8B,QAAyB,CAAC;AAErE,6DAA6D;AAC7D,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,0FAA0F;IAC1F,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAA;CAAE,GACvE;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAA;CAAE,GACvE;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared service-account key contract for `hikoutei setup`.
|
|
3
|
+
*
|
|
4
|
+
* Dependency-free leaf owning the non-secret key constants and metadata
|
|
5
|
+
* result types shared by the checkpoint module and the key-material reader,
|
|
6
|
+
* so neither imports the other for these names (previously the
|
|
7
|
+
* checkpoint ↔ keyMaterial backedge). Moved verbatim from checkpoint.ts;
|
|
8
|
+
* no behavior change. The checkpoint module path stays stable for existing
|
|
9
|
+
* importers via re-exports.
|
|
10
|
+
*/
|
|
11
|
+
/** Service-account key file permission after setup (owner read/write only). */
|
|
12
|
+
export const SERVICE_ACCOUNT_KEY_FILE_MODE = 0o600;
|
|
13
|
+
/**
|
|
14
|
+
* Restricted format of a service-account key id (`private_key_id`).
|
|
15
|
+
*
|
|
16
|
+
* Google user-managed service-account key ids are 16 lowercase hex digits;
|
|
17
|
+
* the pattern accepts 16-40 hex digits so the setup never rejects a valid
|
|
18
|
+
* key, while still refusing arbitrary payload text. The key id is NOT
|
|
19
|
+
* secret: it is the last segment of the key's IAM resource name
|
|
20
|
+
* (`projects/<project>/serviceAccounts/<email>/keys/<id>`) and is used to
|
|
21
|
+
* match a local key file against the cloud key list during reconciliation.
|
|
22
|
+
*/
|
|
23
|
+
export const SERVICE_ACCOUNT_KEY_ID_PATTERN = /^[0-9a-fA-F]{16,40}$/;
|
|
24
|
+
//# sourceMappingURL=keyContract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyContract.js","sourceRoot":"","sources":["../../../../../../src/keyContract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,+EAA+E;AAC/E,MAAM,CAAC,MAAM,6BAA6B,GAAG,KAAK,CAAC;AAEnD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,sBAAsB,CAAC"}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* the run and never appears in results, messages, the checkpoint, or the
|
|
12
12
|
* `.env` file.
|
|
13
13
|
*/
|
|
14
|
-
import type { KeyMetadataResult, SecureKeyReadResult } from "./
|
|
14
|
+
import type { KeyMetadataResult, SecureKeyReadResult } from "./keyContract.js";
|
|
15
15
|
import { type Stats } from "node:fs";
|
|
16
16
|
/**
|
|
17
17
|
* Parses and validates raw service-account key JSON (no filesystem access).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyMaterial.d.ts","sourceRoot":"","sources":["../../../../../../src/keyMaterial.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"keyMaterial.d.ts","sourceRoot":"","sources":["../../../../../../src/keyMaterial.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAI/E,OAAO,EAQL,KAAK,KAAK,EACX,MAAM,SAAS,CAAC;AAEjB;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,iBAAiB,CAO9F;AAmED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9C,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC;IAC7B,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IACnD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,MAAM,EACf,EAAE,GAAE,SAA4B,GAC/B,mBAAmB,CAOrB;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,6BAA6B,GACrC;IAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAA;CAAE,GAC7B;IACA,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE;QACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;KAC7B,CAAC;CACH,GACC;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D;;;;;;;;;;;GAWG;AACH,wBAAgB,uCAAuC,CACrD,OAAO,EAAE,MAAM,EACf,EAAE,GAAE,SAA4B,GAC/B,6BAA6B,CAO/B"}
|
package/dist/cli/keyMaterial.js
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
* the run and never appears in results, messages, the checkpoint, or the
|
|
12
12
|
* `.env` file.
|
|
13
13
|
*/
|
|
14
|
-
import { SERVICE_ACCOUNT_KEY_FILE_MODE, SERVICE_ACCOUNT_KEY_ID_PATTERN } from "./
|
|
15
|
-
import { noFollowFlag, nonBlockFlag } from "./
|
|
14
|
+
import { SERVICE_ACCOUNT_KEY_FILE_MODE, SERVICE_ACCOUNT_KEY_ID_PATTERN } from "./keyContract.js";
|
|
15
|
+
import { noFollowFlag, nonBlockFlag } from "./setupPaths.js";
|
|
16
16
|
import { createPrivateKey } from "node:crypto";
|
|
17
17
|
import { closeSync, constants, fchmodSync, fstatSync, lstatSync, openSync, readFileSync, } from "node:fs";
|
|
18
18
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyMaterial.js","sourceRoot":"","sources":["../../../../../../src/keyMaterial.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,6BAA6B,EAAE,8BAA8B,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"keyMaterial.js","sourceRoot":"","sources":["../../../../../../src/keyMaterial.ts"],"names":[],"mappings":"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"}
|
|
@@ -59,11 +59,20 @@
|
|
|
59
59
|
* unsafe types or permission failures reject the run without touching
|
|
60
60
|
* foreign entries. The key create runs gcloud with a RELATIVE `key.json`
|
|
61
61
|
* destination from the staging directory as the subprocess working
|
|
62
|
-
* directory (runner `cwd
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
62
|
+
* directory (runner `cwd`, expected identity, and a pinned directory fd),
|
|
63
|
+
* with the staging directory re-verified through a no-follow descriptor
|
|
64
|
+
* immediately before spawn and its identity checked again immediately
|
|
65
|
+
* after spawn, before the result is recorded or staged output is trusted.
|
|
66
|
+
* The isolated Node child (`process.execPath`, parent CWD untouched)
|
|
67
|
+
* compares its `statSync('.')` with `fstatSync(3)` for the inherited pinned
|
|
68
|
+
* fd. A replacement cannot pass by reusing the old inode, and gcloud
|
|
69
|
+
* inherits the verified object-bound CWD — the
|
|
70
|
+
* staging-cwd write window (#673) is closed with portable built-ins, no
|
|
71
|
+
* native binding. The post-spawn identity re-check stays as defense in
|
|
72
|
+
* depth. A transient swap-back (the
|
|
73
|
+
* replacement removed before the post-spawn check) leaves no key in the
|
|
74
|
+
* real directory, so the bounded settlement below ends `uncertain`
|
|
75
|
+
* without ever trusting the foreign directory. The same parent validation runs BEFORE the staged key is ever read during reconciliation: `key.json` is never inspected,
|
|
67
76
|
* opened, chmod'ed, or read unless its deterministic parent is absent or a
|
|
68
77
|
* plain directory verified/secured to 0700 through the no-follow
|
|
69
78
|
* descriptor, and a symlinked or non-directory stage parent fails closed
|
|
@@ -306,8 +315,7 @@ export type KeySettleOutcome = {
|
|
|
306
315
|
*/
|
|
307
316
|
export declare function settleServiceAccountKey(runner: GcloudRunner, executed: PlannedCommand[], input: KeySettleInput): Promise<KeySettleOutcome>;
|
|
308
317
|
/**
|
|
309
|
-
* Creates the deterministic staging directory
|
|
310
|
-
* identity.
|
|
318
|
+
* Creates or secures the deterministic staging directory and pins it open.
|
|
311
319
|
*
|
|
312
320
|
* A pre-existing entry is accepted only when it is a real directory (a
|
|
313
321
|
* crash between the checkpoint write and the create leaves an empty owned
|
|
@@ -317,23 +325,23 @@ export declare function settleServiceAccountKey(runner: GcloudRunner, executed:
|
|
|
317
325
|
* platform supports it (the mode is applied and verified on the open
|
|
318
326
|
* descriptor, never via a check-then-chmod path race), and any unsafe
|
|
319
327
|
* type/permission failure rejects the run without touching foreign
|
|
320
|
-
* entries.
|
|
321
|
-
*
|
|
322
|
-
* pre-existing-directory
|
|
323
|
-
* from the one fresh create).
|
|
328
|
+
* entries. Its open descriptor pins the directory object through process
|
|
329
|
+
* launch, preventing inode reuse from making a replacement appear identical.
|
|
330
|
+
* Exported so tests can exercise the pre-existing-directory path directly.
|
|
324
331
|
*/
|
|
325
332
|
export declare function prepareStageDir(keyPath: string, keyMarker: string): PreparedStageDir;
|
|
326
333
|
/**
|
|
327
334
|
* Result of preparing the deterministic staging directory.
|
|
328
335
|
*
|
|
329
|
-
* `ok` carries
|
|
330
|
-
*
|
|
331
|
-
*
|
|
336
|
+
* `ok` carries a pinned descriptor and its device/inode identity so the
|
|
337
|
+
* subprocess wrapper can verify its working directory against the exact
|
|
338
|
+
* open filesystem object.
|
|
332
339
|
*/
|
|
333
340
|
export type PreparedStageDir = {
|
|
334
341
|
readonly status: "ok";
|
|
335
342
|
readonly dev: number;
|
|
336
343
|
readonly ino: number;
|
|
344
|
+
readonly fd: number;
|
|
337
345
|
} | {
|
|
338
346
|
readonly status: "error";
|
|
339
347
|
readonly error: SetupErrorResult;
|
|
@@ -354,36 +362,6 @@ export interface KeyCleanupFs {
|
|
|
354
362
|
fstatSync(fd: number): Stats;
|
|
355
363
|
closeSync(fd: number): void;
|
|
356
364
|
}
|
|
357
|
-
/**
|
|
358
|
-
* Ownership-bound, crash-resumable staged cleanup, only after a verified
|
|
359
|
-
* installation.
|
|
360
|
-
*
|
|
361
|
-
* The final key path is verified with lstat (never following a symlink) and
|
|
362
|
-
* must be a regular file; a final symlink is refused and the staged
|
|
363
|
-
* credential is retained. Before any deletion the deterministic stage
|
|
364
|
-
* directory is atomically quarantined: renamed to the deterministic private
|
|
365
|
-
* cleanup sibling path derived from the SAME persisted key marker (never an
|
|
366
|
-
* unrecoverable random name), with the device/inode captured before the
|
|
367
|
-
* rename re-verified after it — a source replaced between the capture and
|
|
368
|
-
* the rename fails closed and nothing is deleted. Inside the quarantined
|
|
369
|
-
* 0700 directory the staged entry is re-checked as a regular file with the
|
|
370
|
-
* same device/inode as the no-follow final key immediately before its
|
|
371
|
-
* unlink; any mismatch, foreign, or non-empty entry is preserved (the
|
|
372
|
-
* directory is moved back to the stage path so the user finds the state
|
|
373
|
-
* where the docs say it is). The empty quarantined directory is then
|
|
374
|
-
* rmdir'd. Never recursive-delete.
|
|
375
|
-
*
|
|
376
|
-
* Crash-resume boundaries: a crash-left cleanup directory with the matching
|
|
377
|
-
* staged hardlink is finished (verify against the no-follow final, unlink,
|
|
378
|
-
* rmdir); an empty cleanup directory (crash after the staged unlink) is
|
|
379
|
-
* rmdir'd; an absent stage + cleanup pair means the cleanup already
|
|
380
|
-
* finished (success); both existing at once fails closed. The setup lock is
|
|
381
|
-
* held for the whole run — a second cooperating setup process cannot
|
|
382
|
-
* acquire it concurrently, so no other run can be touching these
|
|
383
|
-
* deterministic paths — and Node offers no literal unlinkat without a raw
|
|
384
|
-
* libuv binding, so this quarantine + post-rename identity design is the
|
|
385
|
-
* permitted boundary for the pathname unlink race.
|
|
386
|
-
*/
|
|
387
365
|
export declare function cleanupOwnedStage(keyPath: string, keyMarker: string, fs?: KeyCleanupFs): SetupErrorResult | null;
|
|
388
366
|
export {};
|
|
389
367
|
//# sourceMappingURL=keyProvision.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyProvision.d.ts","sourceRoot":"","sources":["../../../../../../src/keyProvision.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"keyProvision.d.ts","sourceRoot":"","sources":["../../../../../../src/keyProvision.ts"],"names":[],"mappings":"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"}
|