@cortexkit/antigravity-auth-core 2.2.1 → 3.0.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.
- package/README.md +24 -2
- package/dist/abort-forwarding.d.ts +3 -0
- package/dist/abort-forwarding.d.ts.map +1 -0
- package/dist/abort-forwarding.js +19 -0
- package/dist/abort-forwarding.js.map +1 -0
- package/dist/account-identity.d.ts +52 -0
- package/dist/account-identity.d.ts.map +1 -0
- package/dist/account-identity.js +66 -0
- package/dist/account-identity.js.map +1 -0
- package/dist/account-manager.d.ts +228 -43
- package/dist/account-manager.d.ts.map +1 -1
- package/dist/account-manager.js +942 -903
- package/dist/account-manager.js.map +1 -1
- package/dist/account-migration.d.ts +309 -0
- package/dist/account-migration.d.ts.map +1 -0
- package/dist/account-migration.js +2282 -0
- package/dist/account-migration.js.map +1 -0
- package/dist/account-repository-codecs.d.ts +82 -0
- package/dist/account-repository-codecs.d.ts.map +1 -0
- package/dist/account-repository-codecs.js +609 -0
- package/dist/account-repository-codecs.js.map +1 -0
- package/dist/account-repository-types.d.ts +831 -0
- package/dist/account-repository-types.d.ts.map +1 -0
- package/dist/account-repository-types.js +137 -0
- package/dist/account-repository-types.js.map +1 -0
- package/dist/account-repository.d.ts +442 -0
- package/dist/account-repository.d.ts.map +1 -0
- package/dist/account-repository.js +2253 -0
- package/dist/account-repository.js.map +1 -0
- package/dist/account-selector.d.ts +470 -0
- package/dist/account-selector.d.ts.map +1 -0
- package/dist/account-selector.js +1383 -0
- package/dist/account-selector.js.map +1 -0
- package/dist/account-storage.d.ts.map +1 -1
- package/dist/account-storage.js +5 -0
- package/dist/account-storage.js.map +1 -1
- package/dist/agy-transport.d.ts.map +1 -1
- package/dist/agy-transport.js +21 -35
- package/dist/agy-transport.js.map +1 -1
- package/dist/antigravity-command-menu.d.ts +171 -0
- package/dist/antigravity-command-menu.d.ts.map +1 -0
- package/dist/antigravity-command-menu.js +523 -0
- package/dist/antigravity-command-menu.js.map +1 -0
- package/dist/atomic-write.d.ts +18 -1
- package/dist/atomic-write.d.ts.map +1 -1
- package/dist/atomic-write.js +15 -3
- package/dist/atomic-write.js.map +1 -1
- package/dist/common-auth-embedded/NOTICE.txt +21 -0
- package/dist/common-auth-embedded/auth-menu/accounts.d.ts +97 -0
- package/dist/common-auth-embedded/auth-menu/accounts.js +387 -0
- package/dist/common-auth-embedded/auth-menu/ansi.d.ts +26 -0
- package/dist/common-auth-embedded/auth-menu/ansi.js +98 -0
- package/dist/common-auth-embedded/auth-menu/confirm.d.ts +7 -0
- package/dist/common-auth-embedded/auth-menu/confirm.js +21 -0
- package/dist/common-auth-embedded/auth-menu/doctor.d.ts +52 -0
- package/dist/common-auth-embedded/auth-menu/doctor.js +81 -0
- package/dist/common-auth-embedded/auth-menu/index.d.ts +17 -0
- package/dist/common-auth-embedded/auth-menu/index.js +12 -0
- package/dist/common-auth-embedded/auth-menu/login.d.ts +55 -0
- package/dist/common-auth-embedded/auth-menu/login.js +83 -0
- package/dist/common-auth-embedded/auth-menu/menu.d.ts +59 -0
- package/dist/common-auth-embedded/auth-menu/menu.js +73 -0
- package/dist/common-auth-embedded/auth-menu/opencode-v1.d.ts +49 -0
- package/dist/common-auth-embedded/auth-menu/opencode-v1.js +47 -0
- package/dist/common-auth-embedded/auth-menu/select.d.ts +21 -0
- package/dist/common-auth-embedded/auth-menu/select.js +159 -0
- package/dist/common-auth-embedded/auth-menu/terminal.d.ts +43 -0
- package/dist/common-auth-embedded/auth-menu/terminal.js +19 -0
- package/dist/common-auth-embedded/claustrum/consumer.d.ts +102 -0
- package/dist/common-auth-embedded/claustrum/consumer.js +298 -0
- package/dist/common-auth-embedded/claustrum/custody.d.ts +175 -0
- package/dist/common-auth-embedded/claustrum/custody.js +354 -0
- package/dist/common-auth-embedded/claustrum/enrollment.d.ts +158 -0
- package/dist/common-auth-embedded/claustrum/enrollment.js +759 -0
- package/dist/common-auth-embedded/claustrum/errors.d.ts +16 -0
- package/dist/common-auth-embedded/claustrum/errors.js +8 -0
- package/dist/common-auth-embedded/claustrum/host-slot.d.ts +39 -0
- package/dist/common-auth-embedded/claustrum/host-slot.js +72 -0
- package/dist/common-auth-embedded/claustrum/index.d.ts +18 -0
- package/dist/common-auth-embedded/claustrum/index.js +22 -0
- package/dist/common-auth-embedded/claustrum/interlock.d.ts +27 -0
- package/dist/common-auth-embedded/claustrum/interlock.js +29 -0
- package/dist/common-auth-embedded/claustrum/roster.d.ts +208 -0
- package/dist/common-auth-embedded/claustrum/roster.js +536 -0
- package/dist/common-auth-embedded/commands/builtins.d.ts +71 -0
- package/dist/common-auth-embedded/commands/builtins.js +534 -0
- package/dist/common-auth-embedded/commands/index.d.ts +10 -0
- package/dist/common-auth-embedded/commands/index.js +5 -0
- package/dist/common-auth-embedded/commands/menu.d.ts +61 -0
- package/dist/common-auth-embedded/commands/menu.js +300 -0
- package/dist/common-auth-embedded/commands/model.d.ts +238 -0
- package/dist/common-auth-embedded/commands/model.js +16 -0
- package/dist/common-auth-embedded/commands/pi.d.ts +23 -0
- package/dist/common-auth-embedded/commands/pi.js +206 -0
- package/dist/common-auth-embedded/commands/seam.d.ts +72 -0
- package/dist/common-auth-embedded/commands/seam.js +301 -0
- package/dist/common-auth-embedded/fs/atomic-write.d.ts +20 -0
- package/dist/common-auth-embedded/fs/atomic-write.js +80 -0
- package/dist/common-auth-embedded/fs/index.d.ts +7 -0
- package/dist/common-auth-embedded/fs/index.js +6 -0
- package/dist/common-auth-embedded/fs/lock-constants.d.ts +14 -0
- package/dist/common-auth-embedded/fs/lock-constants.js +14 -0
- package/dist/common-auth-embedded/fs/refresh-file-lock.d.ts +33 -0
- package/dist/common-auth-embedded/fs/refresh-file-lock.js +501 -0
- package/dist/common-auth-embedded/fs/with-lock.d.ts +33 -0
- package/dist/common-auth-embedded/fs/with-lock.js +48 -0
- package/dist/common-auth-embedded/logger/capture-sink.d.ts +14 -0
- package/dist/common-auth-embedded/logger/capture-sink.js +13 -0
- package/dist/common-auth-embedded/logger/engine.d.ts +100 -0
- package/dist/common-auth-embedded/logger/engine.js +246 -0
- package/dist/common-auth-embedded/logger/index.d.ts +6 -0
- package/dist/common-auth-embedded/logger/index.js +3 -0
- package/dist/common-auth-embedded/logger/redact.d.ts +11 -0
- package/dist/common-auth-embedded/logger/redact.js +83 -0
- package/dist/common-auth-embedded/pi-slot/index.d.ts +3 -0
- package/dist/common-auth-embedded/pi-slot/index.js +2 -0
- package/dist/common-auth-embedded/pi-slot/lock.js +212 -0
- package/dist/common-auth-embedded/pi-slot/slot.d.ts +49 -0
- package/dist/common-auth-embedded/pi-slot/slot.js +383 -0
- package/dist/common-auth-embedded/quota/codec.d.ts +11 -0
- package/dist/common-auth-embedded/quota/codec.js +12 -0
- package/dist/common-auth-embedded/quota/format.d.ts +46 -0
- package/dist/common-auth-embedded/quota/format.js +138 -0
- package/dist/common-auth-embedded/quota/index.d.ts +10 -0
- package/dist/common-auth-embedded/quota/index.js +5 -0
- package/dist/common-auth-embedded/quota/map.d.ts +63 -0
- package/dist/common-auth-embedded/quota/map.js +105 -0
- package/dist/common-auth-embedded/quota/merge.d.ts +48 -0
- package/dist/common-auth-embedded/quota/merge.js +162 -0
- package/dist/common-auth-embedded/quota/projection.d.ts +64 -0
- package/dist/common-auth-embedded/quota/projection.js +134 -0
- package/dist/common-auth-embedded/routing/admission.d.ts +93 -0
- package/dist/common-auth-embedded/routing/admission.js +142 -0
- package/dist/common-auth-embedded/routing/index.d.ts +8 -0
- package/dist/common-auth-embedded/routing/index.js +4 -0
- package/dist/common-auth-embedded/routing/ordered.d.ts +47 -0
- package/dist/common-auth-embedded/routing/ordered.js +58 -0
- package/dist/common-auth-embedded/routing/pins.d.ts +22 -0
- package/dist/common-auth-embedded/routing/pins.js +34 -0
- package/dist/common-auth-embedded/routing/sticky.d.ts +158 -0
- package/dist/common-auth-embedded/routing/sticky.js +339 -0
- package/dist/common-auth-embedded/source-output.json +1090 -0
- package/dist/common-auth-embedded/store/attribution.d.ts +28 -0
- package/dist/common-auth-embedded/store/attribution.js +60 -0
- package/dist/common-auth-embedded/store/errors.d.ts +55 -0
- package/dist/common-auth-embedded/store/errors.js +38 -0
- package/dist/common-auth-embedded/store/hooks.d.ts +12 -0
- package/dist/common-auth-embedded/store/hooks.js +34 -0
- package/dist/common-auth-embedded/store/identity.d.ts +39 -0
- package/dist/common-auth-embedded/store/identity.js +79 -0
- package/dist/common-auth-embedded/store/index.d.ts +21 -0
- package/dist/common-auth-embedded/store/index.js +7 -0
- package/dist/common-auth-embedded/store/mutate.d.ts +189 -0
- package/dist/common-auth-embedded/store/mutate.js +500 -0
- package/dist/common-auth-embedded/store/pool.d.ts +196 -0
- package/dist/common-auth-embedded/store/pool.js +120 -0
- package/dist/common-auth-embedded/store/provider-state.d.ts +131 -0
- package/dist/common-auth-embedded/store/provider-state.js +226 -0
- package/dist/common-auth-embedded/store/publication.d.ts +47 -0
- package/dist/common-auth-embedded/store/publication.js +304 -0
- package/dist/common-auth-embedded/store/pull.d.ts +36 -0
- package/dist/common-auth-embedded/store/pull.js +143 -0
- package/dist/common-auth-embedded/store/refresh-lock.d.ts +63 -0
- package/dist/common-auth-embedded/store/refresh-lock.js +136 -0
- package/dist/common-auth-embedded/store/refresh.d.ts +72 -0
- package/dist/common-auth-embedded/store/refresh.js +225 -0
- package/dist/common-auth-embedded/store/reserved.js +13 -0
- package/dist/common-auth-embedded/store/rows.d.ts +313 -0
- package/dist/common-auth-embedded/store/rows.js +1258 -0
- package/dist/common-auth-embedded/store/runtime.d.ts +36 -0
- package/dist/common-auth-embedded/store/runtime.js +68 -0
- package/dist/common-auth-embedded/store/schema.d.ts +443 -0
- package/dist/common-auth-embedded/store/schema.js +754 -0
- package/dist/common-auth-embedded/store/settings.d.ts +63 -0
- package/dist/common-auth-embedded/store/settings.js +120 -0
- package/dist/common-auth-embedded/store/torn.d.ts +78 -0
- package/dist/common-auth-embedded/store/torn.js +294 -0
- package/dist/common-auth-embedded/util/any-signal.js +42 -0
- package/dist/common-auth-runtime.d.ts +73 -0
- package/dist/common-auth-runtime.d.ts.map +1 -0
- package/dist/common-auth-runtime.js +65 -0
- package/dist/common-auth-runtime.js.map +1 -0
- package/dist/credential-redaction.d.ts +13 -0
- package/dist/credential-redaction.d.ts.map +1 -0
- package/dist/credential-redaction.js +230 -0
- package/dist/credential-redaction.js.map +1 -0
- package/dist/fetch-timeout.d.ts +4 -2
- package/dist/fetch-timeout.d.ts.map +1 -1
- package/dist/fetch-timeout.js +121 -14
- package/dist/fetch-timeout.js.map +1 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/quota-manager.d.ts.map +1 -1
- package/dist/quota-manager.js +35 -10
- package/dist/quota-manager.js.map +1 -1
- package/dist/quota-presentation.d.ts +10 -0
- package/dist/quota-presentation.d.ts.map +1 -0
- package/dist/quota-presentation.js +60 -0
- package/dist/quota-presentation.js.map +1 -0
- package/dist/quota-types.d.ts +2 -0
- package/dist/quota-types.d.ts.map +1 -1
- package/dist/rotation.d.ts +8 -0
- package/dist/rotation.d.ts.map +1 -1
- package/dist/rotation.js +24 -0
- package/dist/rotation.js.map +1 -1
- package/dist/transform/claude.d.ts +7 -3
- package/dist/transform/claude.d.ts.map +1 -1
- package/dist/transform/claude.js +6 -2
- package/dist/transform/claude.js.map +1 -1
- package/dist/transform/types.d.ts +1 -1
- package/dist/transform/types.d.ts.map +1 -1
- package/dist/vault-account-source.d.ts +183 -0
- package/dist/vault-account-source.d.ts.map +1 -0
- package/dist/vault-account-source.js +296 -0
- package/dist/vault-account-source.js.map +1 -0
- package/dist/vault-enrollment-authority.d.ts +16 -0
- package/dist/vault-enrollment-authority.d.ts.map +1 -0
- package/dist/vault-enrollment-authority.js +19 -0
- package/dist/vault-enrollment-authority.js.map +1 -0
- package/dist/vault-family.d.ts +11 -0
- package/dist/vault-family.d.ts.map +1 -0
- package/dist/vault-family.js +24 -0
- package/dist/vault-family.js.map +1 -0
- package/dist/vault-provider-state.d.ts +162 -0
- package/dist/vault-provider-state.d.ts.map +1 -0
- package/dist/vault-provider-state.js +422 -0
- package/dist/vault-provider-state.js.map +1 -0
- package/package.json +39 -2
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-state file ("sidecar") for vault accounts: non-credential
|
|
3
|
+
* Antigravity metadata (label, usage, cooldowns, verification, tier,
|
|
4
|
+
* fingerprint, quota) keyed by the account identity the vault asserted, with
|
|
5
|
+
* the route, credential and record version that last wrote it.
|
|
6
|
+
*
|
|
7
|
+
* The roster (the Claustrum library's non-secret list of vault accounts this
|
|
8
|
+
* host may route to) keeps only the fields the library defines and drops any
|
|
9
|
+
* other field when it rewrites the file, so Antigravity's own state lives in
|
|
10
|
+
* this separate file. Keying by asserted account means a different account
|
|
11
|
+
* inherits nothing, while the same account keeps its state across token
|
|
12
|
+
* refreshes. The file never holds a bearer, refresh or enrollment secret, a
|
|
13
|
+
* receipt or a project (a vault send's project comes from the receipt
|
|
14
|
+
* Claustrum serves for that send attempt); such input is refused, not
|
|
15
|
+
* stripped. The fingerprint `sessionToken` is locally generated tracking
|
|
16
|
+
* metadata, not a credential, and is kept.
|
|
17
|
+
*
|
|
18
|
+
* A write holds the roster lock as an ownership guard (the roster is not
|
|
19
|
+
* rewritten), then this file's lock, re-checks the roster binding and asks the
|
|
20
|
+
* vault for a fresh receipt for the same version, and re-asserts both locks
|
|
21
|
+
* just before the atomic rename.
|
|
22
|
+
*
|
|
23
|
+
* A write must carry the record version its observation was served under.
|
|
24
|
+
* Once the vault serves a newer record version, even for the same account,
|
|
25
|
+
* that write is refused and the observation (usage, quota) is dropped; it is
|
|
26
|
+
* never re-attributed to the newer version.
|
|
27
|
+
*/
|
|
28
|
+
import type { JsonObject, ProviderMetadata, QuotaState } from './account-repository-types.ts';
|
|
29
|
+
import type { CommonAuthFsModule } from './common-auth-runtime.ts';
|
|
30
|
+
import type { VaultClaustrumPort } from './vault-account-source.ts';
|
|
31
|
+
export declare const VAULT_PROVIDER_STATE_SCHEMA_VERSION = 1;
|
|
32
|
+
/**
|
|
33
|
+
* File lock (`./fs` `withLock`) a commit holds on the state file, so two
|
|
34
|
+
* writers cannot interleave their read and rename.
|
|
35
|
+
*/
|
|
36
|
+
export declare const VAULT_PROVIDER_STATE_LOCK: Readonly<{
|
|
37
|
+
name: "antigravity-vault-state";
|
|
38
|
+
ttlMs: 10000;
|
|
39
|
+
timeoutMs: 10000;
|
|
40
|
+
renew: true;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* The `./fs` lock and atomic-write functions `commitVaultProviderState`
|
|
44
|
+
* uses.
|
|
45
|
+
*/
|
|
46
|
+
export type AntigravityVaultStateFs = Pick<CommonAuthFsModule, 'withLock' | 'writeJsonAtomic'>;
|
|
47
|
+
/**
|
|
48
|
+
* The `./claustrum` functions `commitVaultProviderState` uses: the roster write
|
|
49
|
+
* lock as an ownership guard and the decline check.
|
|
50
|
+
*/
|
|
51
|
+
export type VaultRosterGuardModule = Pick<VaultClaustrumPort, 'mutateVaultRoster' | 'isDeclined'>;
|
|
52
|
+
/**
|
|
53
|
+
* Non-secret facts tying an observation (usage, quota) to the send attempt
|
|
54
|
+
* that produced it: the selected route, the credential id and asserted
|
|
55
|
+
* account, and the record version Claustrum served. Carries no token and no
|
|
56
|
+
* project.
|
|
57
|
+
*/
|
|
58
|
+
export interface VaultStateAttribution {
|
|
59
|
+
readonly routeId: string;
|
|
60
|
+
readonly credentialId: string;
|
|
61
|
+
readonly accountIdentity: string;
|
|
62
|
+
readonly recordVersion: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Provider metadata a vault account may keep. The project fields are left
|
|
66
|
+
* out because a send's project comes only from the receipt Claustrum serves
|
|
67
|
+
* for that attempt, and
|
|
68
|
+
* `enabled` because the roster owns whether an account routes.
|
|
69
|
+
*/
|
|
70
|
+
export type VaultProviderMetadata = Omit<ProviderMetadata, 'projectId' | 'managedProjectId' | 'enabled'>;
|
|
71
|
+
/**
|
|
72
|
+
* The route, credential and served record version of the send whose
|
|
73
|
+
* observation last wrote this state. Kept as a record only; never counted or
|
|
74
|
+
* compared as a local version number.
|
|
75
|
+
*/
|
|
76
|
+
export interface VaultStateProvenance {
|
|
77
|
+
readonly routeId: string;
|
|
78
|
+
readonly credentialId: string;
|
|
79
|
+
readonly recordVersion: number;
|
|
80
|
+
}
|
|
81
|
+
export interface VaultAccountState {
|
|
82
|
+
readonly observed: VaultStateProvenance;
|
|
83
|
+
readonly metadata?: VaultProviderMetadata;
|
|
84
|
+
readonly quota?: QuotaState;
|
|
85
|
+
readonly extensions?: JsonObject;
|
|
86
|
+
}
|
|
87
|
+
export interface VaultProviderStateFile {
|
|
88
|
+
readonly schemaVersion: typeof VAULT_PROVIDER_STATE_SCHEMA_VERSION;
|
|
89
|
+
readonly accounts: Readonly<Record<string, VaultAccountState>>;
|
|
90
|
+
readonly extensions?: JsonObject;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* What an update asks to store for the account. `observed` is not part of it:
|
|
94
|
+
* `commitVaultProviderState` sets it from the attribution.
|
|
95
|
+
*/
|
|
96
|
+
export interface VaultAccountStateValue {
|
|
97
|
+
metadata?: VaultProviderMetadata;
|
|
98
|
+
quota?: QuotaState;
|
|
99
|
+
extensions?: JsonObject;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Computes the account's next state from its current one. The function must
|
|
103
|
+
* be synchronous and must not start another commit. Return `undefined` to
|
|
104
|
+
* leave the state as it is and `null` to remove the account's entry.
|
|
105
|
+
*/
|
|
106
|
+
export type AntigravityVaultStateUpdate = (current: VaultAccountState | undefined) => VaultAccountStateValue | null | undefined;
|
|
107
|
+
export type VaultProviderStateCommitResult = {
|
|
108
|
+
status: 'written';
|
|
109
|
+
state: VaultAccountState;
|
|
110
|
+
} | {
|
|
111
|
+
status: 'cleared';
|
|
112
|
+
} | {
|
|
113
|
+
status: 'unchanged';
|
|
114
|
+
state?: VaultAccountState;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* The write failed part-way; the file may or may not hold the new state.
|
|
118
|
+
* The write is not retried. `state` is what a reload of the file found,
|
|
119
|
+
* when the reload could read it.
|
|
120
|
+
*/
|
|
121
|
+
| {
|
|
122
|
+
status: 'uncertain';
|
|
123
|
+
error: unknown;
|
|
124
|
+
state?: VaultAccountState;
|
|
125
|
+
};
|
|
126
|
+
export type VaultProviderStateFailureKind = 'invalid-attribution' | 'binding-stale' | 'malformed' | 'newer-schema' | 'credential-material' | 'project-field' | 'invalid-update';
|
|
127
|
+
/**
|
|
128
|
+
* A refused read or commit. Messages name the field path or step that was
|
|
129
|
+
* refused, never the stored value.
|
|
130
|
+
*/
|
|
131
|
+
export declare class VaultProviderStateError extends Error {
|
|
132
|
+
readonly kind: VaultProviderStateFailureKind;
|
|
133
|
+
constructor(kind: VaultProviderStateFailureKind, message: string);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Reads a sidecar value. A newer schema, an unknown field, a credential or a
|
|
137
|
+
* project anywhere in it is refused; nothing is silently dropped.
|
|
138
|
+
*/
|
|
139
|
+
export declare function decodeVaultProviderState(raw: unknown): VaultProviderStateFile;
|
|
140
|
+
export declare function encodeVaultProviderState(file: VaultProviderStateFile): JsonObject;
|
|
141
|
+
/** Reads the sidecar; a missing file is an empty one, anything unreadable is refused. */
|
|
142
|
+
export declare function readVaultProviderState(statePath: string): Promise<VaultProviderStateFile>;
|
|
143
|
+
/** The stored state of one asserted account, if any. */
|
|
144
|
+
export declare function vaultAccountState(file: VaultProviderStateFile, accountIdentity: string): VaultAccountState | undefined;
|
|
145
|
+
export interface CommitVaultProviderStateInput {
|
|
146
|
+
claustrum: VaultRosterGuardModule;
|
|
147
|
+
fs: AntigravityVaultStateFs;
|
|
148
|
+
rosterPath: string;
|
|
149
|
+
statePath: string;
|
|
150
|
+
attribution: VaultStateAttribution;
|
|
151
|
+
/**
|
|
152
|
+
* Fresh proof, while the roster write lock and the state-file lock are both
|
|
153
|
+
* held, that custody is still active, the host's stored credential record
|
|
154
|
+
* is still not a real login, and the vault still serves the attributed
|
|
155
|
+
* credential, account and record version. Throws to refuse. Must not use
|
|
156
|
+
* or keep the proving receipt's token or project.
|
|
157
|
+
*/
|
|
158
|
+
verify: (attribution: VaultStateAttribution) => Promise<void>;
|
|
159
|
+
update: AntigravityVaultStateUpdate;
|
|
160
|
+
}
|
|
161
|
+
export declare function commitVaultProviderState(input: CommitVaultProviderStateInput): Promise<VaultProviderStateCommitResult>;
|
|
162
|
+
//# sourceMappingURL=vault-provider-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault-provider-state.d.ts","sourceRoot":"","sources":["../src/vault-provider-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-state file ("sidecar") for vault accounts: non-credential
|
|
3
|
+
* Antigravity metadata (label, usage, cooldowns, verification, tier,
|
|
4
|
+
* fingerprint, quota) keyed by the account identity the vault asserted, with
|
|
5
|
+
* the route, credential and record version that last wrote it.
|
|
6
|
+
*
|
|
7
|
+
* The roster (the Claustrum library's non-secret list of vault accounts this
|
|
8
|
+
* host may route to) keeps only the fields the library defines and drops any
|
|
9
|
+
* other field when it rewrites the file, so Antigravity's own state lives in
|
|
10
|
+
* this separate file. Keying by asserted account means a different account
|
|
11
|
+
* inherits nothing, while the same account keeps its state across token
|
|
12
|
+
* refreshes. The file never holds a bearer, refresh or enrollment secret, a
|
|
13
|
+
* receipt or a project (a vault send's project comes from the receipt
|
|
14
|
+
* Claustrum serves for that send attempt); such input is refused, not
|
|
15
|
+
* stripped. The fingerprint `sessionToken` is locally generated tracking
|
|
16
|
+
* metadata, not a credential, and is kept.
|
|
17
|
+
*
|
|
18
|
+
* A write holds the roster lock as an ownership guard (the roster is not
|
|
19
|
+
* rewritten), then this file's lock, re-checks the roster binding and asks the
|
|
20
|
+
* vault for a fresh receipt for the same version, and re-asserts both locks
|
|
21
|
+
* just before the atomic rename.
|
|
22
|
+
*
|
|
23
|
+
* A write must carry the record version its observation was served under.
|
|
24
|
+
* Once the vault serves a newer record version, even for the same account,
|
|
25
|
+
* that write is refused and the observation (usage, quota) is dropped; it is
|
|
26
|
+
* never re-attributed to the newer version.
|
|
27
|
+
*/
|
|
28
|
+
import { readFile } from 'node:fs/promises';
|
|
29
|
+
import { AccountCodecError, decodeProviderMetadata, decodeQuotaState, encodeProviderMetadata, encodeQuotaState, } from "./account-repository-codecs.js";
|
|
30
|
+
export const VAULT_PROVIDER_STATE_SCHEMA_VERSION = 1;
|
|
31
|
+
/**
|
|
32
|
+
* File lock (`./fs` `withLock`) a commit holds on the state file, so two
|
|
33
|
+
* writers cannot interleave their read and rename.
|
|
34
|
+
*/
|
|
35
|
+
export const VAULT_PROVIDER_STATE_LOCK = Object.freeze({
|
|
36
|
+
name: 'antigravity-vault-state',
|
|
37
|
+
ttlMs: 10_000,
|
|
38
|
+
timeoutMs: 10_000,
|
|
39
|
+
renew: true,
|
|
40
|
+
});
|
|
41
|
+
/**
|
|
42
|
+
* A refused read or commit. Messages name the field path or step that was
|
|
43
|
+
* refused, never the stored value.
|
|
44
|
+
*/
|
|
45
|
+
export class VaultProviderStateError extends Error {
|
|
46
|
+
kind;
|
|
47
|
+
constructor(kind, message) {
|
|
48
|
+
super(message);
|
|
49
|
+
this.name = 'VaultProviderStateError';
|
|
50
|
+
this.kind = kind;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Validation
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
function isRecord(value) {
|
|
57
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
58
|
+
}
|
|
59
|
+
function isNonEmpty(value) {
|
|
60
|
+
return typeof value === 'string' && value.trim().length > 0;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Key names refused anywhere in the file because they hold credentials. Keys
|
|
64
|
+
* are compared lower-case with punctuation removed, so `access_token`,
|
|
65
|
+
* `accessToken` and `access-token` all match `accesstoken`.
|
|
66
|
+
*/
|
|
67
|
+
const CREDENTIAL_KEYS = new Set([
|
|
68
|
+
'access',
|
|
69
|
+
'accesstoken',
|
|
70
|
+
'refresh',
|
|
71
|
+
'refreshtoken',
|
|
72
|
+
'idtoken',
|
|
73
|
+
'token',
|
|
74
|
+
'bearer',
|
|
75
|
+
'authorization',
|
|
76
|
+
'apikey',
|
|
77
|
+
'key',
|
|
78
|
+
'secret',
|
|
79
|
+
'clientsecret',
|
|
80
|
+
'password',
|
|
81
|
+
'enrollmenttoken',
|
|
82
|
+
'cookie',
|
|
83
|
+
'receipt',
|
|
84
|
+
]);
|
|
85
|
+
/**
|
|
86
|
+
* String values refused anywhere in the file: those starting like a Google
|
|
87
|
+
* access token (`ya29.`), a Google refresh token (`1//`) or an Authorization
|
|
88
|
+
* header (`Bearer `).
|
|
89
|
+
*/
|
|
90
|
+
const CREDENTIAL_VALUE = /^(?:ya29\.|1\/\/|bearer\s)/i;
|
|
91
|
+
const PROJECT_KEYS = new Set(['projectid', 'managedprojectid', 'project']);
|
|
92
|
+
function normalizedKey(key) {
|
|
93
|
+
return key.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* True for `metadata.fingerprint.sessionToken` and for the same field in each
|
|
97
|
+
* `metadata.fingerprintHistory` entry: the one token-named field the file may
|
|
98
|
+
* keep, because it is local tracking metadata.
|
|
99
|
+
*/
|
|
100
|
+
function isFingerprintSessionToken(path) {
|
|
101
|
+
const n = path.length;
|
|
102
|
+
if (path[n - 1] !== 'sessionToken' || path[n - 2] !== 'fingerprint')
|
|
103
|
+
return false;
|
|
104
|
+
if (n === 3 && path[0] === 'metadata')
|
|
105
|
+
return true;
|
|
106
|
+
return n === 5 && path[0] === 'metadata' && path[1] === 'fingerprintHistory';
|
|
107
|
+
}
|
|
108
|
+
function scanForSecrets(value, path) {
|
|
109
|
+
if (typeof value === 'string') {
|
|
110
|
+
if (CREDENTIAL_VALUE.test(value.trim()) && !isFingerprintSessionToken(path))
|
|
111
|
+
throw new VaultProviderStateError('credential-material', `${path.join('.')} holds credential material`);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (Array.isArray(value)) {
|
|
115
|
+
for (const [index, item] of value.entries())
|
|
116
|
+
scanForSecrets(item, [...path, `${index}`]);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (!isRecord(value))
|
|
120
|
+
return;
|
|
121
|
+
for (const [key, item] of Object.entries(value)) {
|
|
122
|
+
const next = [...path, key];
|
|
123
|
+
const name = normalizedKey(key);
|
|
124
|
+
if (CREDENTIAL_KEYS.has(name) && !isFingerprintSessionToken(next))
|
|
125
|
+
throw new VaultProviderStateError('credential-material', `${next.join('.')} is a credential field`);
|
|
126
|
+
if (name === 'sessiontoken' && !isFingerprintSessionToken(next))
|
|
127
|
+
throw new VaultProviderStateError('credential-material', `${next.join('.')} is a credential field`);
|
|
128
|
+
if (PROJECT_KEYS.has(name))
|
|
129
|
+
throw new VaultProviderStateError('project-field', `${next.join('.')} would persist an Antigravity project`);
|
|
130
|
+
scanForSecrets(item, next);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function decodeProvenance(raw, path) {
|
|
134
|
+
if (!isRecord(raw) ||
|
|
135
|
+
Object.keys(raw).some((key) => !['routeId', 'credentialId', 'recordVersion'].includes(key)) ||
|
|
136
|
+
!isNonEmpty(raw.routeId) ||
|
|
137
|
+
!isNonEmpty(raw.credentialId) ||
|
|
138
|
+
typeof raw.recordVersion !== 'number' ||
|
|
139
|
+
!Number.isSafeInteger(raw.recordVersion) ||
|
|
140
|
+
raw.recordVersion < 0)
|
|
141
|
+
throw new VaultProviderStateError('malformed', `${path} is not a valid provenance`);
|
|
142
|
+
return Object.freeze({
|
|
143
|
+
routeId: raw.routeId,
|
|
144
|
+
credentialId: raw.credentialId,
|
|
145
|
+
recordVersion: raw.recordVersion,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function codecRefusal(error, path) {
|
|
149
|
+
if (error instanceof AccountCodecError)
|
|
150
|
+
throw new VaultProviderStateError('malformed', `${path}: ${error.problem} at ${error.path}`);
|
|
151
|
+
throw error;
|
|
152
|
+
}
|
|
153
|
+
function decodeExtensions(raw, path) {
|
|
154
|
+
if (raw === undefined)
|
|
155
|
+
return undefined;
|
|
156
|
+
if (!isRecord(raw))
|
|
157
|
+
throw new VaultProviderStateError('malformed', `${path} must be an object`);
|
|
158
|
+
return JSON.parse(JSON.stringify(raw));
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Decodes the parts of an account entry an update may set: `metadata`,
|
|
162
|
+
* `quota` and `extensions` (never `observed`). `stored` is the JSON form read
|
|
163
|
+
* from the file; `typed` is the in-memory form an update returns, which is
|
|
164
|
+
* encoded first so both pass the same codec checks.
|
|
165
|
+
*/
|
|
166
|
+
function decodeValue(raw, path, form) {
|
|
167
|
+
if (!isRecord(raw))
|
|
168
|
+
throw new VaultProviderStateError('malformed', `${path} must be an object`);
|
|
169
|
+
for (const key of Object.keys(raw))
|
|
170
|
+
if (!['metadata', 'quota', 'extensions'].includes(key))
|
|
171
|
+
throw new VaultProviderStateError('malformed', `${path} has an unknown field`);
|
|
172
|
+
scanForSecrets(raw, []);
|
|
173
|
+
const value = {};
|
|
174
|
+
if (raw.metadata !== undefined) {
|
|
175
|
+
try {
|
|
176
|
+
value.metadata = decodeProviderMetadata(form === 'typed'
|
|
177
|
+
? encodeProviderMetadata(raw.metadata)
|
|
178
|
+
: raw.metadata);
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
codecRefusal(error, `${path}.metadata`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (raw.quota !== undefined) {
|
|
185
|
+
try {
|
|
186
|
+
value.quota = decodeQuotaState(form === 'typed'
|
|
187
|
+
? encodeQuotaState(raw.quota)
|
|
188
|
+
: raw.quota);
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
codecRefusal(error, `${path}.quota`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const extensions = decodeExtensions(raw.extensions, `${path}.extensions`);
|
|
195
|
+
if (extensions)
|
|
196
|
+
value.extensions = extensions;
|
|
197
|
+
return value;
|
|
198
|
+
}
|
|
199
|
+
function decodeAccount(raw, path) {
|
|
200
|
+
if (!isRecord(raw))
|
|
201
|
+
throw new VaultProviderStateError('malformed', `${path} must be an object`);
|
|
202
|
+
const { observed, ...rest } = raw;
|
|
203
|
+
return Object.freeze({
|
|
204
|
+
observed: decodeProvenance(observed, `${path}.observed`),
|
|
205
|
+
...decodeValue(rest, path, 'stored'),
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Reads a sidecar value. A newer schema, an unknown field, a credential or a
|
|
210
|
+
* project anywhere in it is refused; nothing is silently dropped.
|
|
211
|
+
*/
|
|
212
|
+
export function decodeVaultProviderState(raw) {
|
|
213
|
+
if (!isRecord(raw) || typeof raw.schemaVersion !== 'number')
|
|
214
|
+
throw new VaultProviderStateError('malformed', 'state file is malformed');
|
|
215
|
+
if (raw.schemaVersion > VAULT_PROVIDER_STATE_SCHEMA_VERSION)
|
|
216
|
+
throw new VaultProviderStateError('newer-schema', 'state file was written by a newer version');
|
|
217
|
+
if (raw.schemaVersion !== VAULT_PROVIDER_STATE_SCHEMA_VERSION)
|
|
218
|
+
throw new VaultProviderStateError('malformed', 'state file version is invalid');
|
|
219
|
+
for (const key of Object.keys(raw))
|
|
220
|
+
if (!['schemaVersion', 'accounts', 'extensions'].includes(key))
|
|
221
|
+
throw new VaultProviderStateError('malformed', 'state file has an unknown field');
|
|
222
|
+
if (!isRecord(raw.accounts))
|
|
223
|
+
throw new VaultProviderStateError('malformed', 'accounts must be an object');
|
|
224
|
+
const accounts = {};
|
|
225
|
+
for (const [identity, entry] of Object.entries(raw.accounts)) {
|
|
226
|
+
if (!isNonEmpty(identity))
|
|
227
|
+
throw new VaultProviderStateError('malformed', 'blank account identity');
|
|
228
|
+
accounts[identity] = decodeAccount(entry, 'accounts[]');
|
|
229
|
+
}
|
|
230
|
+
const extensions = decodeExtensions(raw.extensions, 'extensions');
|
|
231
|
+
return Object.freeze({
|
|
232
|
+
schemaVersion: VAULT_PROVIDER_STATE_SCHEMA_VERSION,
|
|
233
|
+
accounts: Object.freeze(accounts),
|
|
234
|
+
...(extensions && { extensions }),
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
function encodeAccount(state) {
|
|
238
|
+
const out = {
|
|
239
|
+
observed: {
|
|
240
|
+
routeId: state.observed.routeId,
|
|
241
|
+
credentialId: state.observed.credentialId,
|
|
242
|
+
recordVersion: state.observed.recordVersion,
|
|
243
|
+
},
|
|
244
|
+
};
|
|
245
|
+
if (state.metadata)
|
|
246
|
+
out.metadata = encodeProviderMetadata(state.metadata);
|
|
247
|
+
if (state.quota)
|
|
248
|
+
out.quota = encodeQuotaState(state.quota);
|
|
249
|
+
if (state.extensions)
|
|
250
|
+
out.extensions = state.extensions;
|
|
251
|
+
return out;
|
|
252
|
+
}
|
|
253
|
+
export function encodeVaultProviderState(file) {
|
|
254
|
+
const accounts = {};
|
|
255
|
+
for (const [identity, state] of Object.entries(file.accounts))
|
|
256
|
+
accounts[identity] = encodeAccount(state);
|
|
257
|
+
const out = {
|
|
258
|
+
schemaVersion: VAULT_PROVIDER_STATE_SCHEMA_VERSION,
|
|
259
|
+
accounts,
|
|
260
|
+
};
|
|
261
|
+
if (file.extensions)
|
|
262
|
+
out.extensions = file.extensions;
|
|
263
|
+
// Decoding what is about to be written enforces the same refusals on writes.
|
|
264
|
+
decodeVaultProviderState(out);
|
|
265
|
+
return out;
|
|
266
|
+
}
|
|
267
|
+
const EMPTY_FILE = Object.freeze({
|
|
268
|
+
schemaVersion: VAULT_PROVIDER_STATE_SCHEMA_VERSION,
|
|
269
|
+
accounts: Object.freeze({}),
|
|
270
|
+
});
|
|
271
|
+
/** Reads the sidecar; a missing file is an empty one, anything unreadable is refused. */
|
|
272
|
+
export async function readVaultProviderState(statePath) {
|
|
273
|
+
let text;
|
|
274
|
+
try {
|
|
275
|
+
text = await readFile(statePath, 'utf8');
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
if (isRecord(error) && error.code === 'ENOENT')
|
|
279
|
+
return EMPTY_FILE;
|
|
280
|
+
throw error;
|
|
281
|
+
}
|
|
282
|
+
let raw;
|
|
283
|
+
try {
|
|
284
|
+
raw = JSON.parse(text);
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
throw new VaultProviderStateError('malformed', 'state file is not JSON');
|
|
288
|
+
}
|
|
289
|
+
return decodeVaultProviderState(raw);
|
|
290
|
+
}
|
|
291
|
+
/** The stored state of one asserted account, if any. */
|
|
292
|
+
export function vaultAccountState(file, accountIdentity) {
|
|
293
|
+
return Object.hasOwn(file.accounts, accountIdentity)
|
|
294
|
+
? file.accounts[accountIdentity]
|
|
295
|
+
: undefined;
|
|
296
|
+
}
|
|
297
|
+
// ---------------------------------------------------------------------------
|
|
298
|
+
// Commit
|
|
299
|
+
// ---------------------------------------------------------------------------
|
|
300
|
+
const ATTRIBUTION_FIELDS = [
|
|
301
|
+
'accountIdentity',
|
|
302
|
+
'credentialId',
|
|
303
|
+
'recordVersion',
|
|
304
|
+
'routeId',
|
|
305
|
+
];
|
|
306
|
+
/**
|
|
307
|
+
* Copies an attribution after checking it is a plain object with exactly the
|
|
308
|
+
* four own data fields, non-blank strings and a non-negative integer version
|
|
309
|
+
* (a boolean, string or fraction is refused). Later checks use only the copy,
|
|
310
|
+
* so a getter or a later mutation cannot move the fence.
|
|
311
|
+
*/
|
|
312
|
+
function pinAttribution(raw) {
|
|
313
|
+
const invalid = () => new VaultProviderStateError('invalid-attribution', 'state commit needs exactly a route, credential, asserted account and record version');
|
|
314
|
+
if (!isRecord(raw) || Object.getPrototypeOf(raw) !== Object.prototype)
|
|
315
|
+
throw invalid();
|
|
316
|
+
const keys = Reflect.ownKeys(raw);
|
|
317
|
+
if (keys.length !== ATTRIBUTION_FIELDS.length ||
|
|
318
|
+
!ATTRIBUTION_FIELDS.every((key) => {
|
|
319
|
+
const field = Object.getOwnPropertyDescriptor(raw, key);
|
|
320
|
+
return field !== undefined && 'value' in field && field.enumerable;
|
|
321
|
+
}))
|
|
322
|
+
throw invalid();
|
|
323
|
+
const { routeId, credentialId, accountIdentity, recordVersion } = raw;
|
|
324
|
+
if (!isNonEmpty(routeId) ||
|
|
325
|
+
!isNonEmpty(credentialId) ||
|
|
326
|
+
!isNonEmpty(accountIdentity) ||
|
|
327
|
+
typeof recordVersion !== 'number' ||
|
|
328
|
+
!Number.isSafeInteger(recordVersion) ||
|
|
329
|
+
recordVersion < 0)
|
|
330
|
+
throw invalid();
|
|
331
|
+
return Object.freeze({
|
|
332
|
+
routeId,
|
|
333
|
+
credentialId,
|
|
334
|
+
accountIdentity,
|
|
335
|
+
recordVersion,
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* The roster must still route the attributed credential to the attributed
|
|
340
|
+
* account: the row exists, is enabled, active and not declined, and is
|
|
341
|
+
* neither stale nor unclaimed. A removed account is never brought back by a
|
|
342
|
+
* state write.
|
|
343
|
+
*/
|
|
344
|
+
function assertRosterBinding(roster, attribution, claustrum) {
|
|
345
|
+
const row = roster?.rows.find((entry) => entry.routeId === attribution.routeId);
|
|
346
|
+
if (!roster ||
|
|
347
|
+
!row?.enabled ||
|
|
348
|
+
row.state !== 'active' ||
|
|
349
|
+
row.stale === true ||
|
|
350
|
+
row.unclaimed === true ||
|
|
351
|
+
row.credentialId !== attribution.credentialId ||
|
|
352
|
+
row.accountIdentity !== attribution.accountIdentity ||
|
|
353
|
+
claustrum.isDeclined(roster.declined, attribution.credentialId, attribution.accountIdentity))
|
|
354
|
+
throw new VaultProviderStateError('binding-stale', 'the vault route no longer serves the attributed credential and account');
|
|
355
|
+
}
|
|
356
|
+
export async function commitVaultProviderState(input) {
|
|
357
|
+
const { claustrum, fs, statePath } = input;
|
|
358
|
+
const attribution = pinAttribution(input.attribution);
|
|
359
|
+
const identity = attribution.accountIdentity;
|
|
360
|
+
return claustrum.mutateVaultRoster(input.rosterPath, async (roster, rosterLock) => {
|
|
361
|
+
assertRosterBinding(roster, attribution, claustrum);
|
|
362
|
+
const result = await fs.withLock(statePath, VAULT_PROVIDER_STATE_LOCK, async (stateLock) => {
|
|
363
|
+
await input.verify(attribution);
|
|
364
|
+
const file = await readVaultProviderState(statePath);
|
|
365
|
+
const current = vaultAccountState(file, identity);
|
|
366
|
+
const requested = input.update(current);
|
|
367
|
+
if (isRecord(requested) &&
|
|
368
|
+
typeof requested.then === 'function')
|
|
369
|
+
throw new VaultProviderStateError('invalid-update', 'a state update must be synchronous');
|
|
370
|
+
if (requested === undefined)
|
|
371
|
+
return current
|
|
372
|
+
? { status: 'unchanged', state: current }
|
|
373
|
+
: { status: 'unchanged' };
|
|
374
|
+
const accounts = {
|
|
375
|
+
...file.accounts,
|
|
376
|
+
};
|
|
377
|
+
let next;
|
|
378
|
+
if (requested === null) {
|
|
379
|
+
if (!current)
|
|
380
|
+
return { status: 'unchanged' };
|
|
381
|
+
delete accounts[identity];
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
next = Object.freeze({
|
|
385
|
+
observed: Object.freeze({
|
|
386
|
+
routeId: attribution.routeId,
|
|
387
|
+
credentialId: attribution.credentialId,
|
|
388
|
+
recordVersion: attribution.recordVersion,
|
|
389
|
+
}),
|
|
390
|
+
...decodeValue(requested, 'update', 'typed'),
|
|
391
|
+
});
|
|
392
|
+
accounts[identity] = next;
|
|
393
|
+
}
|
|
394
|
+
const encoded = encodeVaultProviderState({ ...file, accounts });
|
|
395
|
+
try {
|
|
396
|
+
await fs.writeJsonAtomic(statePath, encoded, {
|
|
397
|
+
beforeRename: async () => {
|
|
398
|
+
await rosterLock.assertOwned();
|
|
399
|
+
await stateLock.assertOwned();
|
|
400
|
+
},
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
catch (error) {
|
|
404
|
+
let reloaded;
|
|
405
|
+
try {
|
|
406
|
+
reloaded = vaultAccountState(await readVaultProviderState(statePath), identity);
|
|
407
|
+
}
|
|
408
|
+
catch {
|
|
409
|
+
reloaded = undefined;
|
|
410
|
+
}
|
|
411
|
+
return reloaded
|
|
412
|
+
? { status: 'uncertain', error, state: reloaded }
|
|
413
|
+
: { status: 'uncertain', error };
|
|
414
|
+
}
|
|
415
|
+
return next
|
|
416
|
+
? { status: 'written', state: next }
|
|
417
|
+
: { status: 'cleared' };
|
|
418
|
+
});
|
|
419
|
+
return { result };
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=vault-provider-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault-provider-state.js","sourceRoot":"","sources":["../src/vault-provider-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAE3C,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,gCAAgC,CAAA;AAUvC,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC,CAAA;AAEpD;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,MAAM,CAAC;IACrD,IAAI,EAAE,yBAAyB;IAC/B,KAAK,EAAE,MAAM;IACb,SAAS,EAAE,MAAM;IACjB,KAAK,EAAE,IAAI;CACZ,CAAC,CAAA;AA2GF;;;GAGG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IACvC,IAAI,CAA+B;IAE5C,YAAY,IAAmC,EAAE,OAAe;QAC9D,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAA;QACrC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;CACF;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7E,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;AAC7D,CAAC;AAED;;;;GAIG;AACH,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,QAAQ;IACR,aAAa;IACb,SAAS;IACT,cAAc;IACd,SAAS;IACT,OAAO;IACP,QAAQ;IACR,eAAe;IACf,QAAQ;IACR,KAAK;IACL,QAAQ;IACR,cAAc;IACd,UAAU;IACV,iBAAiB;IACjB,QAAQ;IACR,SAAS;CACV,CAAC,CAAA;AAEF;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,6BAA6B,CAAA;AAEtD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,kBAAkB,EAAE,SAAS,CAAC,CAAC,CAAA;AAE1E,SAAS,aAAa,CAAC,GAAW;IAChC,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;AACpD,CAAC;AAED;;;;GAIG;AACH,SAAS,yBAAyB,CAAC,IAAuB;IACxD,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAA;IACrB,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,cAAc,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,aAAa;QACjE,OAAO,KAAK,CAAA;IACd,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU;QAAE,OAAO,IAAI,CAAA;IAClD,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,oBAAoB,CAAA;AAC9E,CAAC;AAED,SAAS,cAAc,CAAC,KAAc,EAAE,IAAc;IACpD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC;YACzE,MAAM,IAAI,uBAAuB,CAC/B,qBAAqB,EACrB,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,4BAA4B,CAC9C,CAAA;QACH,OAAM;IACR,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE;YACzC,cAAc,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAA;QAC7C,OAAM;IACR,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAM;IAC5B,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,CAAA;QAC3B,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;QAC/B,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC;YAC/D,MAAM,IAAI,uBAAuB,CAC/B,qBAAqB,EACrB,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,wBAAwB,CAC1C,CAAA;QACH,IAAI,IAAI,KAAK,cAAc,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC;YAC7D,MAAM,IAAI,uBAAuB,CAC/B,qBAAqB,EACrB,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,wBAAwB,CAC1C,CAAA;QACH,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;YACxB,MAAM,IAAI,uBAAuB,CAC/B,eAAe,EACf,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,uCAAuC,CACzD,CAAA;QACH,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IAC5B,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAY,EAAE,IAAY;IAClD,IACE,CAAC,QAAQ,CAAC,GAAG,CAAC;QACd,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CACnB,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CACrE;QACD,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC;QACxB,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC;QAC7B,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ;QACrC,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,aAAa,CAAC;QACxC,GAAG,CAAC,aAAa,GAAG,CAAC;QAErB,MAAM,IAAI,uBAAuB,CAC/B,WAAW,EACX,GAAG,IAAI,4BAA4B,CACpC,CAAA;IACH,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,aAAa,EAAE,GAAG,CAAC,aAAa;KACjC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,KAAc,EAAE,IAAY;IAChD,IAAI,KAAK,YAAY,iBAAiB;QACpC,MAAM,IAAI,uBAAuB,CAC/B,WAAW,EACX,GAAG,IAAI,KAAK,KAAK,CAAC,OAAO,OAAO,KAAK,CAAC,IAAI,EAAE,CAC7C,CAAA;IACH,MAAM,KAAK,CAAA;AACb,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAY,EAAE,IAAY;IAClD,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACvC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAChB,MAAM,IAAI,uBAAuB,CAAC,WAAW,EAAE,GAAG,IAAI,oBAAoB,CAAC,CAAA;IAC7E,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAe,CAAA;AACtD,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAClB,GAAY,EACZ,IAAY,EACZ,IAAwB;IAExB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAChB,MAAM,IAAI,uBAAuB,CAAC,WAAW,EAAE,GAAG,IAAI,oBAAoB,CAAC,CAAA;IAC7E,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QAChC,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;YACpD,MAAM,IAAI,uBAAuB,CAC/B,WAAW,EACX,GAAG,IAAI,uBAAuB,CAC/B,CAAA;IACL,cAAc,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;IACvB,MAAM,KAAK,GAA2B,EAAE,CAAA;IACxC,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,KAAK,CAAC,QAAQ,GAAG,sBAAsB,CACrC,IAAI,KAAK,OAAO;gBACd,CAAC,CAAC,sBAAsB,CAAC,GAAG,CAAC,QAA4B,CAAC;gBAC1D,CAAC,CAAC,GAAG,CAAC,QAAQ,CACjB,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,YAAY,CAAC,KAAK,EAAE,GAAG,IAAI,WAAW,CAAC,CAAA;QACzC,CAAC;IACH,CAAC;IACD,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,KAAK,CAAC,KAAK,GAAG,gBAAgB,CAC5B,IAAI,KAAK,OAAO;gBACd,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAmB,CAAC;gBAC3C,CAAC,CAAC,GAAG,CAAC,KAAK,CACd,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,YAAY,CAAC,KAAK,EAAE,GAAG,IAAI,QAAQ,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IACD,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,IAAI,aAAa,CAAC,CAAA;IACzE,IAAI,UAAU;QAAE,KAAK,CAAC,UAAU,GAAG,UAAU,CAAA;IAC7C,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,aAAa,CAAC,GAAY,EAAE,IAAY;IAC/C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAChB,MAAM,IAAI,uBAAuB,CAAC,WAAW,EAAE,GAAG,IAAI,oBAAoB,CAAC,CAAA;IAC7E,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,CAAA;IACjC,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,QAAQ,EAAE,gBAAgB,CAAC,QAAQ,EAAE,GAAG,IAAI,WAAW,CAAC;QACxD,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC;KACrC,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAY;IACnD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ;QACzD,MAAM,IAAI,uBAAuB,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAA;IAC3E,IAAI,GAAG,CAAC,aAAa,GAAG,mCAAmC;QACzD,MAAM,IAAI,uBAAuB,CAC/B,cAAc,EACd,2CAA2C,CAC5C,CAAA;IACH,IAAI,GAAG,CAAC,aAAa,KAAK,mCAAmC;QAC3D,MAAM,IAAI,uBAAuB,CAC/B,WAAW,EACX,+BAA+B,CAChC,CAAA;IACH,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QAChC,IAAI,CAAC,CAAC,eAAe,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;YAC5D,MAAM,IAAI,uBAAuB,CAC/B,WAAW,EACX,iCAAiC,CAClC,CAAA;IACL,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzB,MAAM,IAAI,uBAAuB,CAAC,WAAW,EAAE,4BAA4B,CAAC,CAAA;IAC9E,MAAM,QAAQ,GAAsC,EAAE,CAAA;IACtD,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7D,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YACvB,MAAM,IAAI,uBAAuB,CAAC,WAAW,EAAE,wBAAwB,CAAC,CAAA;QAC1E,QAAQ,CAAC,QAAQ,CAAC,GAAG,aAAa,CAAC,KAAK,EAAE,YAAY,CAAC,CAAA;IACzD,CAAC;IACD,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;IACjE,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,aAAa,EAAE,mCAAmC;QAClD,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;QACjC,GAAG,CAAC,UAAU,IAAI,EAAE,UAAU,EAAE,CAAC;KAClC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAwB;IAC7C,MAAM,GAAG,GAAe;QACtB,QAAQ,EAAE;YACR,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,OAAO;YAC/B,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,YAAY;YACzC,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAC,aAAa;SAC5C;KACF,CAAA;IACD,IAAI,KAAK,CAAC,QAAQ;QAAE,GAAG,CAAC,QAAQ,GAAG,sBAAsB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IACzE,IAAI,KAAK,CAAC,KAAK;QAAE,GAAG,CAAC,KAAK,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAC1D,IAAI,KAAK,CAAC,UAAU;QAAE,GAAG,CAAC,UAAU,GAAG,KAAK,CAAC,UAAuB,CAAA;IACpE,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,IAA4B;IAE5B,MAAM,QAAQ,GAAe,EAAE,CAAA;IAC/B,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC3D,QAAQ,CAAC,QAAQ,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAA;IAC3C,MAAM,GAAG,GAAe;QACtB,aAAa,EAAE,mCAAmC;QAClD,QAAQ;KACT,CAAA;IACD,IAAI,IAAI,CAAC,UAAU;QAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAA;IACrD,6EAA6E;IAC7E,wBAAwB,CAAC,GAAG,CAAC,CAAA;IAC7B,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,MAAM,UAAU,GAA2B,MAAM,CAAC,MAAM,CAAC;IACvD,aAAa,EAAE,mCAAmC;IAClD,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;CAC5B,CAAC,CAAA;AAEF,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,SAAiB;IAEjB,IAAI,IAAY,CAAA;IAChB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,UAAU,CAAA;QACjE,MAAM,KAAK,CAAA;IACb,CAAC;IACD,IAAI,GAAY,CAAA;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,uBAAuB,CAAC,WAAW,EAAE,wBAAwB,CAAC,CAAA;IAC1E,CAAC;IACD,OAAO,wBAAwB,CAAC,GAAG,CAAC,CAAA;AACtC,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,iBAAiB,CAC/B,IAA4B,EAC5B,eAAuB;IAEvB,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC;QAClD,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;QAChC,CAAC,CAAC,SAAS,CAAA;AACf,CAAC;AAED,8EAA8E;AAC9E,SAAS;AACT,8EAA8E;AAE9E,MAAM,kBAAkB,GAAG;IACzB,iBAAiB;IACjB,cAAc;IACd,eAAe;IACf,SAAS;CACD,CAAA;AAEV;;;;;GAKG;AACH,SAAS,cAAc,CAAC,GAAY;IAClC,MAAM,OAAO,GAAG,GAAG,EAAE,CACnB,IAAI,uBAAuB,CACzB,qBAAqB,EACrB,qFAAqF,CACtF,CAAA;IACH,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,SAAS;QACnE,MAAM,OAAO,EAAE,CAAA;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACjC,IACE,IAAI,CAAC,MAAM,KAAK,kBAAkB,CAAC,MAAM;QACzC,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YAChC,MAAM,KAAK,GAAG,MAAM,CAAC,wBAAwB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;YACvD,OAAO,KAAK,KAAK,SAAS,IAAI,OAAO,IAAI,KAAK,IAAI,KAAK,CAAC,UAAU,CAAA;QACpE,CAAC,CAAC;QAEF,MAAM,OAAO,EAAE,CAAA;IACjB,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,GAAG,GAAG,CAAA;IACrE,IACE,CAAC,UAAU,CAAC,OAAO,CAAC;QACpB,CAAC,UAAU,CAAC,YAAY,CAAC;QACzB,CAAC,UAAU,CAAC,eAAe,CAAC;QAC5B,OAAO,aAAa,KAAK,QAAQ;QACjC,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC;QACpC,aAAa,GAAG,CAAC;QAEjB,MAAM,OAAO,EAAE,CAAA;IACjB,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,OAAO;QACP,YAAY;QACZ,eAAe;QACf,aAAa;KACd,CAAC,CAAA;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAC1B,MAA+B,EAC/B,WAAkC,EAClC,SAAiC;IAEjC,MAAM,GAAG,GAAG,MAAM,EAAE,IAAI,CAAC,IAAI,CAC3B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,WAAW,CAAC,OAAO,CACjD,CAAA;IACD,IACE,CAAC,MAAM;QACP,CAAC,GAAG,EAAE,OAAO;QACb,GAAG,CAAC,KAAK,KAAK,QAAQ;QACtB,GAAG,CAAC,KAAK,KAAK,IAAI;QAClB,GAAG,CAAC,SAAS,KAAK,IAAI;QACtB,GAAG,CAAC,YAAY,KAAK,WAAW,CAAC,YAAY;QAC7C,GAAG,CAAC,eAAe,KAAK,WAAW,CAAC,eAAe;QACnD,SAAS,CAAC,UAAU,CAClB,MAAM,CAAC,QAAQ,EACf,WAAW,CAAC,YAAY,EACxB,WAAW,CAAC,eAAe,CAC5B;QAED,MAAM,IAAI,uBAAuB,CAC/B,eAAe,EACf,wEAAwE,CACzE,CAAA;AACL,CAAC;AAmBD,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,KAAoC;IAEpC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;IAC1C,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;IACrD,MAAM,QAAQ,GAAG,WAAW,CAAC,eAAe,CAAA;IAC5C,OAAO,SAAS,CAAC,iBAAiB,CAChC,KAAK,CAAC,UAAU,EAChB,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE;QAC3B,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,CAAA;QACnD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAC9B,SAAS,EACT,yBAAyB,EACzB,KAAK,EAAE,SAAS,EAA2C,EAAE;YAC3D,MAAM,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;YAC/B,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC,SAAS,CAAC,CAAA;YACpD,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;YACjD,MAAM,SAAS,GAAY,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YAChD,IACE,QAAQ,CAAC,SAAS,CAAC;gBACnB,OAAQ,SAAgC,CAAC,IAAI,KAAK,UAAU;gBAE5D,MAAM,IAAI,uBAAuB,CAC/B,gBAAgB,EAChB,oCAAoC,CACrC,CAAA;YACH,IAAI,SAAS,KAAK,SAAS;gBACzB,OAAO,OAAO;oBACZ,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE;oBACzC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;YAC7B,MAAM,QAAQ,GAAsC;gBAClD,GAAG,IAAI,CAAC,QAAQ;aACjB,CAAA;YACD,IAAI,IAAmC,CAAA;YACvC,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBACvB,IAAI,CAAC,OAAO;oBAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;gBAC5C,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAA;YAC3B,CAAC;iBAAM,CAAC;gBACN,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;oBACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC;wBACtB,OAAO,EAAE,WAAW,CAAC,OAAO;wBAC5B,YAAY,EAAE,WAAW,CAAC,YAAY;wBACtC,aAAa,EAAE,WAAW,CAAC,aAAa;qBACzC,CAAC;oBACF,GAAG,WAAW,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC;iBAC7C,CAAC,CAAA;gBACF,QAAQ,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAA;YAC3B,CAAC;YACD,MAAM,OAAO,GAAG,wBAAwB,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;YAC/D,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,eAAe,CAAC,SAAS,EAAE,OAAO,EAAE;oBAC3C,YAAY,EAAE,KAAK,IAAI,EAAE;wBACvB,MAAM,UAAU,CAAC,WAAW,EAAE,CAAA;wBAC9B,MAAM,SAAS,CAAC,WAAW,EAAE,CAAA;oBAC/B,CAAC;iBACF,CAAC,CAAA;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,QAAuC,CAAA;gBAC3C,IAAI,CAAC;oBACH,QAAQ,GAAG,iBAAiB,CAC1B,MAAM,sBAAsB,CAAC,SAAS,CAAC,EACvC,QAAQ,CACT,CAAA;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,QAAQ,GAAG,SAAS,CAAA;gBACtB,CAAC;gBACD,OAAO,QAAQ;oBACb,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE;oBACjD,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAA;YACpC,CAAC;YACD,OAAO,IAAI;gBACT,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE;gBACpC,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;QAC3B,CAAC,CACF,CAAA;QACD,OAAO,EAAE,MAAM,EAAE,CAAA;IACnB,CAAC,CACF,CAAA;AACH,CAAC"}
|