@dbx-tools/appkit 0.9.58 → 0.9.60
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 +28 -1
- package/index.ts +4 -1
- package/lib/index.d.ts +4 -1
- package/lib/index.js +4 -2
- package/lib/src/_cache-storage.js +3 -2
- package/lib/src/child-process.d.ts +39 -0
- package/lib/src/child-process.js +128 -0
- package/lib/src/provision.js +6 -15
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +15 -6
- package/src/_cache-storage.ts +4 -1
- package/src/child-process.ts +157 -0
- package/src/provision.ts +11 -19
package/README.md
CHANGED
|
@@ -256,6 +256,33 @@ hard-code registered names or casts at every call site. A missing required
|
|
|
256
256
|
plugin throws AppKit's `ConfigurationError`, naming both the caller and the
|
|
257
257
|
plugin to register.
|
|
258
258
|
|
|
259
|
+
## Supervise AppKit Subprocesses
|
|
260
|
+
|
|
261
|
+
`AppKitChildProcess` starts a long-running sibling process through
|
|
262
|
+
`@dbx-tools/core/exec` and owns its shutdown escalation. Its spawn tuple accepts
|
|
263
|
+
core exec options, including line handlers and optional output capture.
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
import { AppKitChildProcess } from "@dbx-tools/appkit/child-process";
|
|
267
|
+
|
|
268
|
+
const worker = new AppKitChildProcess([
|
|
269
|
+
"bun",
|
|
270
|
+
["run", "worker.ts"],
|
|
271
|
+
{
|
|
272
|
+
stdout: { onLine: (line) => logger.info(line), capture: false },
|
|
273
|
+
stderr: { onLine: (line) => logger.error(line), capture: false },
|
|
274
|
+
},
|
|
275
|
+
]);
|
|
276
|
+
|
|
277
|
+
worker.start();
|
|
278
|
+
this.context.onLifecycle("shutdown", () => worker.shutdown());
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
`shutdown()` is idempotent. It sends `SIGTERM`, waits seven seconds, then sends
|
|
282
|
+
`SIGKILL` and waits one more second. Override those signals or timeouts in the
|
|
283
|
+
constructor's second argument. A detached POSIX child is signaled as a process
|
|
284
|
+
group so descendants do not survive their AppKit owner.
|
|
285
|
+
|
|
259
286
|
## Provision Lakebase Cache Schema
|
|
260
287
|
|
|
261
288
|
`provision.provisionCacheSchema()` grants the AppKit cache schema in Lakebase to
|
|
@@ -340,5 +367,5 @@ is shared. `@dbx-tools/appkit-mastra` exposes this as its `genieIdentity` option
|
|
|
340
367
|
| `identity` | OBO-vs-service-principal request identity: modes, resolution, and the forwarded headers. |
|
|
341
368
|
|
|
342
369
|
The shell-facing wrapper for auto-config is
|
|
343
|
-
[`@dbx-tools/cli
|
|
370
|
+
[`@dbx-tools/cli/appkit`](../../cli/dbx-tools). Higher-level agent composition
|
|
344
371
|
is in [`@dbx-tools/appkit-mastra`](../appkit-mastra).
|
package/index.ts
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
|
|
5
5
|
export const PACKAGE_IDENTIFIER = "@dbx-tools/appkit";
|
|
6
|
-
export const PACKAGE_VERSION = "0.9.
|
|
6
|
+
export const PACKAGE_VERSION = "0.9.60";
|
|
7
7
|
export * as appkit from "./src/appkit.ts";
|
|
8
8
|
export * as brandContext from "./src/brand-context.ts";
|
|
9
9
|
export * as bundle from "./src/bundle.ts";
|
|
10
|
+
export * as childProcess from "./src/child-process.ts";
|
|
10
11
|
export * as databricks from "./src/databricks.ts";
|
|
11
12
|
export * as identity from "./src/identity.ts";
|
|
12
13
|
export * as interceptor from "./src/interceptor.ts";
|
|
@@ -21,6 +22,8 @@ export * as toolkitEntries from "./src/toolkit-entries.ts";
|
|
|
21
22
|
export type { AutoConfigureMode, CreateAppConfig, ExecutionContextLike, WorkspaceClientLike } from "./src/appkit.ts";
|
|
22
23
|
export { bundleAppResourceSchema, flattenAppYamlEnv, flattenAppEnv, getBundlePath } from "./src/bundle.ts";
|
|
23
24
|
export type { BundleValidateJson, ConfigFile, ConfigMapValue, ConfigSource, ResolveConfigValueOptions } from "./src/bundle.ts";
|
|
25
|
+
export { AppKitChildProcess } from "./src/child-process.ts";
|
|
26
|
+
export type { AppKitSpawnArgs, AppKitChildProcessOptions } from "./src/child-process.ts";
|
|
24
27
|
export type { ContextLike } from "./src/databricks.ts";
|
|
25
28
|
export { ACCESS_TOKEN_HEADER, USER_ID_HEADER, USER_EMAIL_HEADER, IDENTITY_MODES, DEFAULT_IDENTITY_MODE } from "./src/identity.ts";
|
|
26
29
|
export type { IdentityMode, HeaderBearing } from "./src/identity.ts";
|
package/lib/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export declare const PACKAGE_IDENTIFIER = "@dbx-tools/appkit";
|
|
2
|
-
export declare const PACKAGE_VERSION = "0.9.
|
|
2
|
+
export declare const PACKAGE_VERSION = "0.9.60";
|
|
3
3
|
export * as appkit from "./src/appkit.ts";
|
|
4
4
|
export * as brandContext from "./src/brand-context.ts";
|
|
5
5
|
export * as bundle from "./src/bundle.ts";
|
|
6
|
+
export * as childProcess from "./src/child-process.ts";
|
|
6
7
|
export * as databricks from "./src/databricks.ts";
|
|
7
8
|
export * as identity from "./src/identity.ts";
|
|
8
9
|
export * as interceptor from "./src/interceptor.ts";
|
|
@@ -17,6 +18,8 @@ export * as toolkitEntries from "./src/toolkit-entries.ts";
|
|
|
17
18
|
export type { AutoConfigureMode, CreateAppConfig, ExecutionContextLike, WorkspaceClientLike } from "./src/appkit.ts";
|
|
18
19
|
export { bundleAppResourceSchema, flattenAppYamlEnv, flattenAppEnv, getBundlePath } from "./src/bundle.ts";
|
|
19
20
|
export type { BundleValidateJson, ConfigFile, ConfigMapValue, ConfigSource, ResolveConfigValueOptions } from "./src/bundle.ts";
|
|
21
|
+
export { AppKitChildProcess } from "./src/child-process.ts";
|
|
22
|
+
export type { AppKitSpawnArgs, AppKitChildProcessOptions } from "./src/child-process.ts";
|
|
20
23
|
export type { ContextLike } from "./src/databricks.ts";
|
|
21
24
|
export { ACCESS_TOKEN_HEADER, USER_ID_HEADER, USER_EMAIL_HEADER, IDENTITY_MODES, DEFAULT_IDENTITY_MODE } from "./src/identity.ts";
|
|
22
25
|
export type { IdentityMode, HeaderBearing } from "./src/identity.ts";
|
package/lib/index.js
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
// Regenerated from the exporting modules in ./src.
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
export const PACKAGE_IDENTIFIER = "@dbx-tools/appkit";
|
|
5
|
-
export const PACKAGE_VERSION = "0.9.
|
|
5
|
+
export const PACKAGE_VERSION = "0.9.60";
|
|
6
6
|
export * as appkit from "./src/appkit.js";
|
|
7
7
|
export * as brandContext from "./src/brand-context.js";
|
|
8
8
|
export * as bundle from "./src/bundle.js";
|
|
9
|
+
export * as childProcess from "./src/child-process.js";
|
|
9
10
|
export * as databricks from "./src/databricks.js";
|
|
10
11
|
export * as identity from "./src/identity.js";
|
|
11
12
|
export * as interceptor from "./src/interceptor.js";
|
|
@@ -18,8 +19,9 @@ export * as provision from "./src/provision.js";
|
|
|
18
19
|
export * as toolProvider from "./src/tool-provider.js";
|
|
19
20
|
export * as toolkitEntries from "./src/toolkit-entries.js";
|
|
20
21
|
export { bundleAppResourceSchema, flattenAppYamlEnv, flattenAppEnv, getBundlePath } from "./src/bundle.js";
|
|
22
|
+
export { AppKitChildProcess } from "./src/child-process.js";
|
|
21
23
|
export { ACCESS_TOKEN_HEADER, USER_ID_HEADER, USER_EMAIL_HEADER, IDENTITY_MODES, DEFAULT_IDENTITY_MODE } from "./src/identity.js";
|
|
22
24
|
export { LifecycleBridgePlugin, lifecycleBridge } from "./src/interceptor.js";
|
|
23
25
|
export { SSL_MODES } from "./src/pgaddress.js";
|
|
24
26
|
export { ToolRegistryPlugin } from "./src/tool-provider.js";
|
|
25
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
27
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxtQkFBbUIsQ0FBQztBQUN0RCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDO0FBQ3hDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLFlBQVksTUFBTSx3QkFBd0IsQ0FBQztBQUN2RCxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxZQUFZLE1BQU0sd0JBQXdCLENBQUM7QUFDdkQsT0FBTyxLQUFLLFVBQVUsTUFBTSxxQkFBcUIsQ0FBQztBQUNsRCxPQUFPLEtBQUssUUFBUSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxXQUFXLE1BQU0sc0JBQXNCLENBQUM7QUFDcEQsT0FBTyxLQUFLLGdCQUFnQixNQUFNLDRCQUE0QixDQUFDO0FBQy9ELE9BQU8sS0FBSyxTQUFTLE1BQU0sb0JBQW9CLENBQUM7QUFDaEQsT0FBTyxLQUFLLFNBQVMsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEtBQUssZUFBZSxNQUFNLDJCQUEyQixDQUFDO0FBQzdELE9BQU8sS0FBSyxjQUFjLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxLQUFLLFNBQVMsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEtBQUssWUFBWSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxjQUFjLE1BQU0sMEJBQTBCLENBQUM7QUFFM0QsT0FBTyxFQUFFLHVCQUF1QixFQUFFLGlCQUFpQixFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUUzRyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUc1RCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsY0FBYyxFQUFFLGlCQUFpQixFQUFFLGNBQWMsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRWxJLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxlQUFlLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUk5RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFJL0MsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBHRU5FUkFURUQgYnkgcHJvamVuIHdhdGNoIC0gRE8gTk9UIEVESVQuXG4vLyBSZWdlbmVyYXRlZCBmcm9tIHRoZSBleHBvcnRpbmcgbW9kdWxlcyBpbiAuL3NyYy5cbi8vIEhhbmQgZWRpdHMgYXJlIG92ZXJ3cml0dGVuIG9uIHRoZSBuZXh0IHdhdGNoOyB0aGlzIGZpbGUgaXMgcmVhZC1vbmx5LlxuXG5leHBvcnQgY29uc3QgUEFDS0FHRV9JREVOVElGSUVSID0gXCJAZGJ4LXRvb2xzL2FwcGtpdFwiO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9IFwiMC45LjYwXCI7XG5leHBvcnQgKiBhcyBhcHBraXQgZnJvbSBcIi4vc3JjL2FwcGtpdC50c1wiO1xuZXhwb3J0ICogYXMgYnJhbmRDb250ZXh0IGZyb20gXCIuL3NyYy9icmFuZC1jb250ZXh0LnRzXCI7XG5leHBvcnQgKiBhcyBidW5kbGUgZnJvbSBcIi4vc3JjL2J1bmRsZS50c1wiO1xuZXhwb3J0ICogYXMgY2hpbGRQcm9jZXNzIGZyb20gXCIuL3NyYy9jaGlsZC1wcm9jZXNzLnRzXCI7XG5leHBvcnQgKiBhcyBkYXRhYnJpY2tzIGZyb20gXCIuL3NyYy9kYXRhYnJpY2tzLnRzXCI7XG5leHBvcnQgKiBhcyBpZGVudGl0eSBmcm9tIFwiLi9zcmMvaWRlbnRpdHkudHNcIjtcbmV4cG9ydCAqIGFzIGludGVyY2VwdG9yIGZyb20gXCIuL3NyYy9pbnRlcmNlcHRvci50c1wiO1xuZXhwb3J0ICogYXMgbGFrZWJhc2VSZXNvbHZlciBmcm9tIFwiLi9zcmMvbGFrZWJhc2UtcmVzb2x2ZXIudHNcIjtcbmV4cG9ydCAqIGFzIG1pZ3JhdGlvbiBmcm9tIFwiLi9zcmMvbWlncmF0aW9uLnRzXCI7XG5leHBvcnQgKiBhcyBwZ2FkZHJlc3MgZnJvbSBcIi4vc3JjL3BnYWRkcmVzcy50c1wiO1xuZXhwb3J0ICogYXMgcGx1Z2luRXhlY3V0aW9uIGZyb20gXCIuL3NyYy9wbHVnaW4tZXhlY3V0aW9uLnRzXCI7XG5leHBvcnQgKiBhcyBwbHVnaW5SZWdpc3RyeSBmcm9tIFwiLi9zcmMvcGx1Z2luLXJlZ2lzdHJ5LnRzXCI7XG5leHBvcnQgKiBhcyBwcm92aXNpb24gZnJvbSBcIi4vc3JjL3Byb3Zpc2lvbi50c1wiO1xuZXhwb3J0ICogYXMgdG9vbFByb3ZpZGVyIGZyb20gXCIuL3NyYy90b29sLXByb3ZpZGVyLnRzXCI7XG5leHBvcnQgKiBhcyB0b29sa2l0RW50cmllcyBmcm9tIFwiLi9zcmMvdG9vbGtpdC1lbnRyaWVzLnRzXCI7XG5leHBvcnQgdHlwZSB7IEF1dG9Db25maWd1cmVNb2RlLCBDcmVhdGVBcHBDb25maWcsIEV4ZWN1dGlvbkNvbnRleHRMaWtlLCBXb3Jrc3BhY2VDbGllbnRMaWtlIH0gZnJvbSBcIi4vc3JjL2FwcGtpdC50c1wiO1xuZXhwb3J0IHsgYnVuZGxlQXBwUmVzb3VyY2VTY2hlbWEsIGZsYXR0ZW5BcHBZYW1sRW52LCBmbGF0dGVuQXBwRW52LCBnZXRCdW5kbGVQYXRoIH0gZnJvbSBcIi4vc3JjL2J1bmRsZS50c1wiO1xuZXhwb3J0IHR5cGUgeyBCdW5kbGVWYWxpZGF0ZUpzb24sIENvbmZpZ0ZpbGUsIENvbmZpZ01hcFZhbHVlLCBDb25maWdTb3VyY2UsIFJlc29sdmVDb25maWdWYWx1ZU9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvYnVuZGxlLnRzXCI7XG5leHBvcnQgeyBBcHBLaXRDaGlsZFByb2Nlc3MgfSBmcm9tIFwiLi9zcmMvY2hpbGQtcHJvY2Vzcy50c1wiO1xuZXhwb3J0IHR5cGUgeyBBcHBLaXRTcGF3bkFyZ3MsIEFwcEtpdENoaWxkUHJvY2Vzc09wdGlvbnMgfSBmcm9tIFwiLi9zcmMvY2hpbGQtcHJvY2Vzcy50c1wiO1xuZXhwb3J0IHR5cGUgeyBDb250ZXh0TGlrZSB9IGZyb20gXCIuL3NyYy9kYXRhYnJpY2tzLnRzXCI7XG5leHBvcnQgeyBBQ0NFU1NfVE9LRU5fSEVBREVSLCBVU0VSX0lEX0hFQURFUiwgVVNFUl9FTUFJTF9IRUFERVIsIElERU5USVRZX01PREVTLCBERUZBVUxUX0lERU5USVRZX01PREUgfSBmcm9tIFwiLi9zcmMvaWRlbnRpdHkudHNcIjtcbmV4cG9ydCB0eXBlIHsgSWRlbnRpdHlNb2RlLCBIZWFkZXJCZWFyaW5nIH0gZnJvbSBcIi4vc3JjL2lkZW50aXR5LnRzXCI7XG5leHBvcnQgeyBMaWZlY3ljbGVCcmlkZ2VQbHVnaW4sIGxpZmVjeWNsZUJyaWRnZSB9IGZyb20gXCIuL3NyYy9pbnRlcmNlcHRvci50c1wiO1xuZXhwb3J0IHR5cGUgeyBMaWZlY3ljbGVFdmVudCwgTGlmZWN5Y2xlSGFuZGxlciwgUmVzb2x2ZWRBcHBFbnYsIEJpbmRhYmxlUHJvY2VzcywgSW50ZXJjZXB0b3JDb250ZXh0LCBJbnRlcmNlcHRvciwgSW50ZXJjZXB0b3JSdW50aW1lIH0gZnJvbSBcIi4vc3JjL2ludGVyY2VwdG9yLnRzXCI7XG5leHBvcnQgdHlwZSB7IExha2ViYXNlUmVzb2x2ZXJJbnB1dHMsIExha2ViYXNlQ29ubmVjdGlvbiB9IGZyb20gXCIuL3NyYy9sYWtlYmFzZS1yZXNvbHZlci50c1wiO1xuZXhwb3J0IHR5cGUgeyBPd25lcnNoaXBNaWdyYXRpb25FcnJvck9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvbWlncmF0aW9uLnRzXCI7XG5leHBvcnQgeyBTU0xfTU9ERVMgfSBmcm9tIFwiLi9zcmMvcGdhZGRyZXNzLnRzXCI7XG5leHBvcnQgdHlwZSB7IFNzbE1vZGUsIFBhcnNlZEFkZHJlc3MsIExha2ViYXNlQ29ubmVjdGlvbklucHV0cyB9IGZyb20gXCIuL3NyYy9wZ2FkZHJlc3MudHNcIjtcbmV4cG9ydCB0eXBlIHsgUnVuUGx1Z2luRXhlY3V0aW9uT3B0aW9ucyB9IGZyb20gXCIuL3NyYy9wbHVnaW4tZXhlY3V0aW9uLnRzXCI7XG5leHBvcnQgdHlwZSB7IFBsdWdpbkNvbnRleHRMaWtlIH0gZnJvbSBcIi4vc3JjL3BsdWdpbi1yZWdpc3RyeS50c1wiO1xuZXhwb3J0IHsgVG9vbFJlZ2lzdHJ5UGx1Z2luIH0gZnJvbSBcIi4vc3JjL3Rvb2wtcHJvdmlkZXIudHNcIjtcbiJdfQ==
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import { createRequire } from "node:module";
|
|
17
17
|
import { dirname, join } from "node:path";
|
|
18
18
|
import { createLakebasePool, getWorkspaceClient } from "@databricks/appkit";
|
|
19
|
+
import { postgresConnectionOptions } from "@dbx-tools/postgres";
|
|
19
20
|
import { errorUtils, hash, log } from "@dbx-tools/shared-core";
|
|
20
21
|
import { handleOwnershipMigrationError } from "./migration.js";
|
|
21
22
|
const logger = log.logger("cache-storage");
|
|
@@ -128,7 +129,7 @@ export async function createSoftPersistentStorage(cache) {
|
|
|
128
129
|
}
|
|
129
130
|
let pool;
|
|
130
131
|
try {
|
|
131
|
-
const createdPool = createLakebasePool({ workspaceClient: getWorkspaceClient({}) });
|
|
132
|
+
const createdPool = createLakebasePool(postgresConnectionOptions({ workspaceClient: getWorkspaceClient({}) }));
|
|
132
133
|
pool = createdPool;
|
|
133
134
|
const storage = new PersistentStorage(cache ?? {}, createdPool);
|
|
134
135
|
softenInitialize(storage, () => tableOwnedByAnotherRole(storage, createdPool));
|
|
@@ -150,4 +151,4 @@ export async function createSoftPersistentStorage(cache) {
|
|
|
150
151
|
return undefined;
|
|
151
152
|
}
|
|
152
153
|
}
|
|
153
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2NhY2hlLXN0b3JhZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvX2NhY2hlLXN0b3JhZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFFSCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzFDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBb0IsTUFBTSxvQkFBb0IsQ0FBQztBQUM5RixPQUFPLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMvRCxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUvRCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBa0IzQyxJQUFJLHFCQUFxQixHQUFvRCxJQUFJLENBQUM7QUFFbEY7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLHFCQUFxQjtJQUNuQyxJQUFJLHFCQUFxQixLQUFLLElBQUksRUFBRSxDQUFDO1FBQ25DLE9BQU8scUJBQXFCLENBQUM7SUFDL0IsQ0FBQztJQUNELElBQUksQ0FBQztRQUNILE1BQU0sT0FBTyxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQy9DLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FDckIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxFQUM5Qyw2QkFBNkIsQ0FDOUIsQ0FBQztRQUNGLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxpQkFDTyxDQUFDO1FBQzNDLElBQUksT0FBTyxNQUFNLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDakMsTUFBTSxDQUFDLEtBQUssQ0FBQywyREFBMkQsQ0FBQyxDQUFDO1lBQzFFLHFCQUFxQixHQUFHLFNBQVMsQ0FBQztZQUNsQyxPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDO1FBQ0QscUJBQXFCLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsTUFBTSxDQUFDLEtBQUssQ0FBQywrREFBK0QsRUFBRTtZQUM1RSxLQUFLLEVBQUUsVUFBVSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUM7U0FDcEMsQ0FBQyxDQUFDO1FBQ0gscUJBQXFCLEdBQUcsU0FBUyxDQUFDO1FBQ2xDLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsS0FBSyxVQUFVLHVCQUF1QixDQUNwQyxPQUE4QixFQUM5QixJQUFrQjtJQUVsQixJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDNUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUM3Qjs7O3lFQUdxRSxFQUNyRSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUN4QyxDQUFDO0lBQ0YsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssS0FBSyxLQUFLO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDbEQsTUFBTSxDQUFDLElBQUksQ0FBQyxtRUFBbUUsRUFBRTtRQUMvRSxNQUFNLEVBQUUsT0FBTyxDQUFDLFVBQVU7UUFDMUIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxTQUFTO0tBQ3pCLENBQUMsQ0FBQztJQUNILE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVELGlGQUFpRjtBQUNqRixNQUFNLFVBQVUsZ0JBQWdCLENBQzlCLE9BQThCLEVBQzlCLGNBQXVDO0lBRXZDLE1BQU0sa0JBQWtCLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDNUQsSUFBSSxlQUEwQyxDQUFDO0lBRS9DLE9BQU8sQ0FBQyxVQUFVLEdBQUcsS0FBSyxJQUFJLEVBQUU7UUFDOUIsSUFBSSxPQUFPLENBQUMsV0FBVztZQUFFLE9BQU87UUFDaEMsZUFBZSxLQUFLLENBQUMsS0FBSyxJQUFJLEVBQUU7WUFDOUIsSUFBSSxDQUFDO2dCQUNILElBQUksQ0FBQyxDQUFDLE1BQU0sY0FBYyxFQUFFLEVBQUUsQ0FBQztvQkFBRSxNQUFNLGtCQUFrQixFQUFFLENBQUM7WUFDOUQsQ0FBQztZQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7Z0JBQ2IsSUFDRSxDQUFDLDZCQUE2QixDQUFDLEdBQUcsRUFBRTtvQkFDbEMsS0FBSyxFQUFFLGVBQWU7b0JBQ3RCLE1BQU07b0JBQ04sS0FBSyxFQUFFLG1DQUFtQztpQkFDM0MsQ0FBQyxFQUNGLENBQUM7b0JBQ0QsTUFBTSxHQUFHLENBQUM7Z0JBQ1osQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ0wsSUFBSSxDQUFDO1lBQ0gsTUFBTSxlQUFlLENBQUM7WUFDdEIsT0FBTyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7UUFDN0IsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixlQUFlLEdBQUcsU0FBUyxDQUFDO1lBQzVCLE1BQU0sR0FBRyxDQUFDO1FBQ1osQ0FBQztJQUNILENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRCxtRkFBbUY7QUFDbkYsTUFBTSxDQUFDLEtBQUssVUFBVSxZQUFZLENBQUMsT0FBOEI7SUFDL0QsTUFBTSxHQUFHLEdBQUcseUJBQXlCLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDO0lBQ2pELElBQUksQ0FBQztRQUNILE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUNwRSxNQUFNLE1BQU0sR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEMsSUFBSSxNQUFNLEVBQUUsS0FBSyxLQUFLLEdBQUcsRUFBRSxDQUFDO1lBQzFCLE1BQU0sSUFBSSxLQUFLLENBQUMscURBQXFELENBQUMsQ0FBQztRQUN6RSxDQUFDO0lBQ0gsQ0FBQztZQUFTLENBQUM7UUFDVCxNQUFNLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ25ELENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsMkJBQTJCLENBQy9DLEtBQThCO0lBRTlCLE1BQU0saUJBQWlCLEdBQUcscUJBQXFCLEVBQUUsQ0FBQztJQUNsRCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUN2QixPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQsSUFBSSxJQUE4QixDQUFDO0lBQ25DLElBQUksQ0FBQztRQUNILE1BQU0sV0FBVyxHQUFHLGtCQUFrQixDQUFDLEVBQUUsZUFBZSxFQUFFLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNwRixJQUFJLEdBQUcsV0FBVyxDQUFDO1FBQ25CLE1BQU0sT0FBTyxHQUFHLElBQUksaUJBQWlCLENBQUMsS0FBSyxJQUFJLEVBQUUsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUNoRSxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsdUJBQXVCLENBQUMsT0FBTyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDL0UsSUFBSSxDQUFDLENBQUMsTUFBTSxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ25DLE1BQU0sT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUMsQ0FBQztZQUN0QyxPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDO1FBQ0QsTUFBTSxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDM0IsTUFBTSxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDNUIsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDYixNQUFNLENBQUMsS0FBSyxDQUFDLG1DQUFtQyxFQUFFO1lBQ2hELEtBQUssRUFBRSxVQUFVLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQztTQUNwQyxDQUFDLENBQUM7UUFDSCxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsTUFBTSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ25DLENBQUM7UUFDRCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU29mdC1mYWlsIExha2ViYXNlIGNhY2hlIHN0b3JhZ2UgZm9yIEFwcEtpdCdzIHBlcnNpc3RlbnQgY2FjaGUuXG4gKlxuICogQXBwS2l0J3MgYFBlcnNpc3RlbnRTdG9yYWdlLmluaXRpYWxpemUoKWAgcnVucyBEREwgbWlncmF0aW9ucyBhbmQgdGhyb3dzIG9uXG4gKiBhbnkgc3RlcCBmYWlsdXJlLiBXaXRoIGBjYWNoZS5zdHJpY3RQZXJzaXN0ZW5jZTogdHJ1ZWAgdGhhdCB0aHJvdyBtYWtlc1xuICogYENhY2hlTWFuYWdlcmAgc2lsZW50bHkgZGlzYWJsZSB0aGUgY2FjaGUuIFRoaXMgd3JhcHMgdGhlIHNhbWUgc3RvcmFnZSxcbiAqIHN0aWxsIHJ1bnMgaXRzIG1pZ3JhdGlvbnMsIGJ1dCBsb2dzIGEgZmFpbGVkIHN0ZXAgaW5zdGVhZCBvZiB0aHJvd2luZyBzbyBhXG4gKiB1c2FibGUgdGFibGUga2VlcHMgc2VydmluZy5cbiAqXG4gKiBgUGVyc2lzdGVudFN0b3JhZ2VgIGlzIG5vdCBvbiBBcHBLaXQncyBwdWJsaWMgZXhwb3J0IG1hcC4gVGhlIGRlZXAgbG9hZCBpc1xuICogbGF6eSBhbmQgYmVzdC1lZmZvcnQ6IGlmIHRoZSBpbnN0YWxsZWQgQXBwS2l0IGxheW91dCBjaGFuZ2VzLCB0aGlzIHJldHVybnNcbiAqIGB1bmRlZmluZWRgIGFuZCBgY3JlYXRlQXBwYCBsZWF2ZXMgQXBwS2l0IG9uIGl0cyBkZWZhdWx0IGNhY2hlIHBhdGguXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCB7IGRpcm5hbWUsIGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBjcmVhdGVMYWtlYmFzZVBvb2wsIGdldFdvcmtzcGFjZUNsaWVudCwgdHlwZSBDYWNoZUNvbmZpZyB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7IGVycm9yVXRpbHMsIGhhc2gsIGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBoYW5kbGVPd25lcnNoaXBNaWdyYXRpb25FcnJvciB9IGZyb20gXCIuL21pZ3JhdGlvbi50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwiY2FjaGUtc3RvcmFnZVwiKTtcblxudHlwZSBMYWtlYmFzZVBvb2wgPSBSZXR1cm5UeXBlPHR5cGVvZiBjcmVhdGVMYWtlYmFzZVBvb2w+O1xudHlwZSBDYWNoZVN0b3JhZ2UgPSBOb25OdWxsYWJsZTxDYWNoZUNvbmZpZ1tcInN0b3JhZ2VcIl0+O1xuXG4vKiogQXBwS2l0J3MgaW50ZXJuYWwgcGVyc2lzdGVudCBzdG9yYWdlIHN1cmZhY2UuICovXG5leHBvcnQgdHlwZSBQZXJzaXN0ZW50U3RvcmFnZUJhc2UgPSBDYWNoZVN0b3JhZ2UgJiB7XG4gIGluaXRpYWxpemUoKTogUHJvbWlzZTx2b2lkPjtcbiAgaW5pdGlhbGl6ZWQ6IGJvb2xlYW47XG4gIHNjaGVtYU5hbWU/OiBzdHJpbmc7XG4gIHRhYmxlTmFtZT86IHN0cmluZztcbn07XG5cbnR5cGUgUGVyc2lzdGVudFN0b3JhZ2VDb25zdHJ1Y3RvciA9IG5ldyAoXG4gIGNvbmZpZzogQ2FjaGVDb25maWcsXG4gIHBvb2w6IExha2ViYXNlUG9vbCxcbikgPT4gUGVyc2lzdGVudFN0b3JhZ2VCYXNlO1xuXG5sZXQgcGVyc2lzdGVudFN0b3JhZ2VDdG9yOiBQZXJzaXN0ZW50U3RvcmFnZUNvbnN0cnVjdG9yIHwgdW5kZWZpbmVkIHwgbnVsbCA9IG51bGw7XG5cbi8qKlxuICogTGF6aWx5IHJlc29sdmUgQXBwS2l0J3MgaW50ZXJuYWwgYFBlcnNpc3RlbnRTdG9yYWdlYCBjb25zdHJ1Y3Rvci4gYG51bGxgXG4gKiBtZWFucyBub3QgYXR0ZW1wdGVkIHlldDsgYHVuZGVmaW5lZGAgbWVhbnMgdGhlIGxvb2t1cCBhbHJlYWR5IGZhaWxlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvYWRQZXJzaXN0ZW50U3RvcmFnZSgpOiBQZXJzaXN0ZW50U3RvcmFnZUNvbnN0cnVjdG9yIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHBlcnNpc3RlbnRTdG9yYWdlQ3RvciAhPT0gbnVsbCkge1xuICAgIHJldHVybiBwZXJzaXN0ZW50U3RvcmFnZUN0b3I7XG4gIH1cbiAgdHJ5IHtcbiAgICBjb25zdCByZXF1aXJlID0gY3JlYXRlUmVxdWlyZShpbXBvcnQubWV0YS51cmwpO1xuICAgIGNvbnN0IG1vZHVsZVBhdGggPSBqb2luKFxuICAgICAgZGlybmFtZShyZXF1aXJlLnJlc29sdmUoXCJAZGF0YWJyaWNrcy9hcHBraXRcIikpLFxuICAgICAgXCJjYWNoZS9zdG9yYWdlL3BlcnNpc3RlbnQuanNcIixcbiAgICApO1xuICAgIGNvbnN0IGxvYWRlZCA9IHJlcXVpcmUobW9kdWxlUGF0aCkuUGVyc2lzdGVudFN0b3JhZ2UgYXNcbiAgICAgIFBlcnNpc3RlbnRTdG9yYWdlQ29uc3RydWN0b3IgfCB1bmRlZmluZWQ7XG4gICAgaWYgKHR5cGVvZiBsb2FkZWQgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgbG9nZ2VyLmRlYnVnKFwic29mdCBwZXJzaXN0ZW50IGNhY2hlIHNraXBwZWQgKFBlcnNpc3RlbnRTdG9yYWdlIG1pc3NpbmcpXCIpO1xuICAgICAgcGVyc2lzdGVudFN0b3JhZ2VDdG9yID0gdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcGVyc2lzdGVudFN0b3JhZ2VDdG9yID0gbG9hZGVkO1xuICAgIHJldHVybiBsb2FkZWQ7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci5kZWJ1ZyhcInNvZnQgcGVyc2lzdGVudCBjYWNoZSBza2lwcGVkIChQZXJzaXN0ZW50U3RvcmFnZSB1bmF2YWlsYWJsZSlcIiwge1xuICAgICAgZXJyb3I6IGVycm9yVXRpbHMuZXJyb3JNZXNzYWdlKGVyciksXG4gICAgfSk7XG4gICAgcGVyc2lzdGVudFN0b3JhZ2VDdG9yID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBXaGV0aGVyIGFuIGV4aXN0aW5nIGNhY2hlIHRhYmxlIGJlbG9uZ3MgdG8gYW5vdGhlciByb2xlLlxuICpcbiAqIFBvc3RncmVTUUwgYWxsb3dzIGdyYW50ZWQgcmVhZHMvd3JpdGVzIGJ1dCByZXNlcnZlcyBpbmRleCBEREwgZm9yIHRoZSB0YWJsZVxuICogb3duZXIuIFNraXAgQXBwS2l0IG1pZ3JhdGlvbnMgaW4gdGhhdCBjYXNlOyB7QGxpbmsgcHJvYmVTdG9yYWdlfSBzdGlsbCBwcm92ZXNcbiAqIHRoZSBleGlzdGluZyB0YWJsZSBjYW4gc2VydmUgdGhlIGNhY2hlIGJlZm9yZSBpdCBpcyBhY2NlcHRlZC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gdGFibGVPd25lZEJ5QW5vdGhlclJvbGUoXG4gIHN0b3JhZ2U6IFBlcnNpc3RlbnRTdG9yYWdlQmFzZSxcbiAgcG9vbDogTGFrZWJhc2VQb29sLFxuKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGlmICghc3RvcmFnZS5zY2hlbWFOYW1lIHx8ICFzdG9yYWdlLnRhYmxlTmFtZSkgcmV0dXJuIGZhbHNlO1xuICBjb25zdCByZXN1bHQgPSBhd2FpdCBwb29sLnF1ZXJ5KFxuICAgIGBTRUxFQ1QgcGdfZ2V0X3VzZXJieWlkKGMucmVsb3duZXIpID0gY3VycmVudF91c2VyIEFTIG93bmVkXG4gICAgIEZST00gcGdfY2xhc3MgY1xuICAgICBKT0lOIHBnX25hbWVzcGFjZSBuIE9OIG4ub2lkID0gYy5yZWxuYW1lc3BhY2VcbiAgICAgV0hFUkUgbi5uc3BuYW1lID0gJDEgQU5EIGMucmVsbmFtZSA9ICQyIEFORCBjLnJlbGtpbmQgSU4gKCdyJywgJ3AnKWAsXG4gICAgW3N0b3JhZ2Uuc2NoZW1hTmFtZSwgc3RvcmFnZS50YWJsZU5hbWVdLFxuICApO1xuICBpZiAocmVzdWx0LnJvd3NbMF0/Lm93bmVkICE9PSBmYWxzZSkgcmV0dXJuIGZhbHNlO1xuICBsb2dnZXIud2FybihcInBlcnNpc3RlbnQgY2FjaGUgbWlncmF0aW9ucyBza2lwcGVkICh0YWJsZSBvd25lZCBieSBhbm90aGVyIHJvbGUpXCIsIHtcbiAgICBzY2hlbWE6IHN0b3JhZ2Uuc2NoZW1hTmFtZSxcbiAgICB0YWJsZTogc3RvcmFnZS50YWJsZU5hbWUsXG4gIH0pO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqIFNvZnRlbiBgaW5pdGlhbGl6ZSgpYCBzbyBhbiBvd25lcnNoaXAtb25seSBtaWdyYXRpb24gZmFpbHVyZSBpcyBub3QgZmF0YWwuICovXG5leHBvcnQgZnVuY3Rpb24gc29mdGVuSW5pdGlhbGl6ZShcbiAgc3RvcmFnZTogUGVyc2lzdGVudFN0b3JhZ2VCYXNlLFxuICBza2lwTWlncmF0aW9ucz86ICgpID0+IFByb21pc2U8Ym9vbGVhbj4sXG4pOiB2b2lkIHtcbiAgY29uc3Qgb3JpZ2luYWxJbml0aWFsaXplID0gc3RvcmFnZS5pbml0aWFsaXplLmJpbmQoc3RvcmFnZSk7XG4gIGxldCBzb2Z0SW5pdFByb21pc2U6IFByb21pc2U8dm9pZD4gfCB1bmRlZmluZWQ7XG5cbiAgc3RvcmFnZS5pbml0aWFsaXplID0gYXN5bmMgKCkgPT4ge1xuICAgIGlmIChzdG9yYWdlLmluaXRpYWxpemVkKSByZXR1cm47XG4gICAgc29mdEluaXRQcm9taXNlID8/PSAoYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCEoYXdhaXQgc2tpcE1pZ3JhdGlvbnM/LigpKSkgYXdhaXQgb3JpZ2luYWxJbml0aWFsaXplKCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFoYW5kbGVPd25lcnNoaXBNaWdyYXRpb25FcnJvcihlcnIsIHtcbiAgICAgICAgICAgIHNjb3BlOiBcImNhY2hlLXN0b3JhZ2VcIixcbiAgICAgICAgICAgIGxvZ2dlcixcbiAgICAgICAgICAgIGV2ZW50OiBcInBlcnNpc3RlbnQgY2FjaGUgbWlncmF0aW9uIGZhaWxlZFwiLFxuICAgICAgICAgIH0pXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pKCk7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHNvZnRJbml0UHJvbWlzZTtcbiAgICAgIHN0b3JhZ2UuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgc29mdEluaXRQcm9taXNlID0gdW5kZWZpbmVkO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfTtcbn1cblxuLyoqIFZlcmlmeSB0aGUgbWlncmF0ZWQgY2FjaGUgdGFibGUgY2FuIHNlcnZlIHRoZSByZWFkcyBhbmQgd3JpdGVzIEFwcEtpdCBuZWVkcy4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwcm9iZVN0b3JhZ2Uoc3RvcmFnZTogUGVyc2lzdGVudFN0b3JhZ2VCYXNlKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGtleSA9IGBkYngtdG9vbHM6Y2FjaGUtcHJvYmU6JHtoYXNoLmlkKCl9YDtcbiAgdHJ5IHtcbiAgICBhd2FpdCBzdG9yYWdlLnNldChrZXksIHsgdmFsdWU6IGtleSwgZXhwaXJ5OiBEYXRlLm5vdygpICsgNjBfMDAwIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0b3JhZ2UuZ2V0KGtleSk7XG4gICAgaWYgKHJlc3VsdD8udmFsdWUgIT09IGtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwicGVyc2lzdGVudCBjYWNoZSBwcm9iZSByZXR1cm5lZCBhbiB1bmV4cGVjdGVkIHZhbHVlXCIpO1xuICAgIH1cbiAgfSBmaW5hbGx5IHtcbiAgICBhd2FpdCBzdG9yYWdlLmRlbGV0ZShrZXkpLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gIH1cbn1cblxuLyoqXG4gKiBCdWlsZCBhIHNvZnQtZmFpbCBMYWtlYmFzZSBjYWNoZSBzdG9yYWdlIHdoZW4gYSBwb29sIGNhbiBiZSBjcmVhdGVkIGFuZFxuICogQXBwS2l0J3MgUGVyc2lzdGVudFN0b3JhZ2UgY2FuIGJlIGxvYWRlZC4gUmV0dXJucyBgdW5kZWZpbmVkYCBvdGhlcndpc2Ugc29cbiAqIEFwcEtpdCBjYW4gZmFsbCB0aHJvdWdoIHRvIGl0cyBub3JtYWwgY2FjaGUgcGF0aC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVNvZnRQZXJzaXN0ZW50U3RvcmFnZShcbiAgY2FjaGU6IENhY2hlQ29uZmlnIHwgdW5kZWZpbmVkLFxuKTogUHJvbWlzZTxDYWNoZVN0b3JhZ2UgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgUGVyc2lzdGVudFN0b3JhZ2UgPSBsb2FkUGVyc2lzdGVudFN0b3JhZ2UoKTtcbiAgaWYgKCFQZXJzaXN0ZW50U3RvcmFnZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBsZXQgcG9vbDogTGFrZWJhc2VQb29sIHwgdW5kZWZpbmVkO1xuICB0cnkge1xuICAgIGNvbnN0IGNyZWF0ZWRQb29sID0gY3JlYXRlTGFrZWJhc2VQb29sKHsgd29ya3NwYWNlQ2xpZW50OiBnZXRXb3Jrc3BhY2VDbGllbnQoe30pIH0pO1xuICAgIHBvb2wgPSBjcmVhdGVkUG9vbDtcbiAgICBjb25zdCBzdG9yYWdlID0gbmV3IFBlcnNpc3RlbnRTdG9yYWdlKGNhY2hlID8/IHt9LCBjcmVhdGVkUG9vbCk7XG4gICAgc29mdGVuSW5pdGlhbGl6ZShzdG9yYWdlLCAoKSA9PiB0YWJsZU93bmVkQnlBbm90aGVyUm9sZShzdG9yYWdlLCBjcmVhdGVkUG9vbCkpO1xuICAgIGlmICghKGF3YWl0IHN0b3JhZ2UuaGVhbHRoQ2hlY2soKSkpIHtcbiAgICAgIGF3YWl0IHN0b3JhZ2UuY2xvc2UoKS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBhd2FpdCBzdG9yYWdlLmluaXRpYWxpemUoKTtcbiAgICBhd2FpdCBwcm9iZVN0b3JhZ2Uoc3RvcmFnZSk7XG4gICAgcmV0dXJuIHN0b3JhZ2U7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci5kZWJ1ZyhcInNvZnQgcGVyc2lzdGVudCBjYWNoZSB1bmF2YWlsYWJsZVwiLCB7XG4gICAgICBlcnJvcjogZXJyb3JVdGlscy5lcnJvck1lc3NhZ2UoZXJyKSxcbiAgICB9KTtcbiAgICBpZiAocG9vbCkge1xuICAgICAgYXdhaXQgcG9vbC5lbmQoKS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cbiJdfQ==
|
|
154
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2NhY2hlLXN0b3JhZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvX2NhY2hlLXN0b3JhZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFFSCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzFDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBb0IsTUFBTSxvQkFBb0IsQ0FBQztBQUM5RixPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMvRCxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUvRCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBa0IzQyxJQUFJLHFCQUFxQixHQUFvRCxJQUFJLENBQUM7QUFFbEY7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLHFCQUFxQjtJQUNuQyxJQUFJLHFCQUFxQixLQUFLLElBQUksRUFBRSxDQUFDO1FBQ25DLE9BQU8scUJBQXFCLENBQUM7SUFDL0IsQ0FBQztJQUNELElBQUksQ0FBQztRQUNILE1BQU0sT0FBTyxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQy9DLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FDckIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxFQUM5Qyw2QkFBNkIsQ0FDOUIsQ0FBQztRQUNGLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxpQkFDTyxDQUFDO1FBQzNDLElBQUksT0FBTyxN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O1lBQ25DLE1BQU0sT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUMsQ0FBQztZQUN0QyxPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDO1FBQ0QsTUFBTSxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDM0IsTUFBTSxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDNUIsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDYixNQUFNLENBQUMsS0FBSyxDQUFDLG1DQUFtQyxFQUFFO1lBQ2hELEtBQUssRUFBRSxVQUFVLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQztTQUNwQyxDQUFDLENBQUM7UUFDSCxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsTUFBTSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ25DLENBQUM7UUFDRCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU29mdC1mYWlsIExha2ViYXNlIGNhY2hlIHN0b3JhZ2UgZm9yIEFwcEtpdCdzIHBlcnNpc3RlbnQgY2FjaGUuXG4gKlxuICogQXBwS2l0J3MgYFBlcnNpc3RlbnRTdG9yYWdlLmluaXRpYWxpemUoKWAgcnVucyBEREwgbWlncmF0aW9ucyBhbmQgdGhyb3dzIG9uXG4gKiBhbnkgc3RlcCBmYWlsdXJlLiBXaXRoIGBjYWNoZS5zdHJpY3RQZXJzaXN0ZW5jZTogdHJ1ZWAgdGhhdCB0aHJvdyBtYWtlc1xuICogYENhY2hlTWFuYWdlcmAgc2lsZW50bHkgZGlzYWJsZSB0aGUgY2FjaGUuIFRoaXMgd3JhcHMgdGhlIHNhbWUgc3RvcmFnZSxcbiAqIHN0aWxsIHJ1bnMgaXRzIG1pZ3JhdGlvbnMsIGJ1dCBsb2dzIGEgZmFpbGVkIHN0ZXAgaW5zdGVhZCBvZiB0aHJvd2luZyBzbyBhXG4gKiB1c2FibGUgdGFibGUga2VlcHMgc2VydmluZy5cbiAqXG4gKiBgUGVyc2lzdGVudFN0b3JhZ2VgIGlzIG5vdCBvbiBBcHBLaXQncyBwdWJsaWMgZXhwb3J0IG1hcC4gVGhlIGRlZXAgbG9hZCBpc1xuICogbGF6eSBhbmQgYmVzdC1lZmZvcnQ6IGlmIHRoZSBpbnN0YWxsZWQgQXBwS2l0IGxheW91dCBjaGFuZ2VzLCB0aGlzIHJldHVybnNcbiAqIGB1bmRlZmluZWRgIGFuZCBgY3JlYXRlQXBwYCBsZWF2ZXMgQXBwS2l0IG9uIGl0cyBkZWZhdWx0IGNhY2hlIHBhdGguXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCB7IGRpcm5hbWUsIGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBjcmVhdGVMYWtlYmFzZVBvb2wsIGdldFdvcmtzcGFjZUNsaWVudCwgdHlwZSBDYWNoZUNvbmZpZyB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7IHBvc3RncmVzQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tIFwiQGRieC10b29scy9wb3N0Z3Jlc1wiO1xuaW1wb3J0IHsgZXJyb3JVdGlscywgaGFzaCwgbG9nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IGhhbmRsZU93bmVyc2hpcE1pZ3JhdGlvbkVycm9yIH0gZnJvbSBcIi4vbWlncmF0aW9uLnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJjYWNoZS1zdG9yYWdlXCIpO1xuXG50eXBlIExha2ViYXNlUG9vbCA9IFJldHVyblR5cGU8dHlwZW9mIGNyZWF0ZUxha2ViYXNlUG9vbD47XG50eXBlIENhY2hlU3RvcmFnZSA9IE5vbk51bGxhYmxlPENhY2hlQ29uZmlnW1wic3RvcmFnZVwiXT47XG5cbi8qKiBBcHBLaXQncyBpbnRlcm5hbCBwZXJzaXN0ZW50IHN0b3JhZ2Ugc3VyZmFjZS4gKi9cbmV4cG9ydCB0eXBlIFBlcnNpc3RlbnRTdG9yYWdlQmFzZSA9IENhY2hlU3RvcmFnZSAmIHtcbiAgaW5pdGlhbGl6ZSgpOiBQcm9taXNlPHZvaWQ+O1xuICBpbml0aWFsaXplZDogYm9vbGVhbjtcbiAgc2NoZW1hTmFtZT86IHN0cmluZztcbiAgdGFibGVOYW1lPzogc3RyaW5nO1xufTtcblxudHlwZSBQZXJzaXN0ZW50U3RvcmFnZUNvbnN0cnVjdG9yID0gbmV3IChcbiAgY29uZmlnOiBDYWNoZUNvbmZpZyxcbiAgcG9vbDogTGFrZWJhc2VQb29sLFxuKSA9PiBQZXJzaXN0ZW50U3RvcmFnZUJhc2U7XG5cbmxldCBwZXJzaXN0ZW50U3RvcmFnZUN0b3I6IFBlcnNpc3RlbnRTdG9yYWdlQ29uc3RydWN0b3IgfCB1bmRlZmluZWQgfCBudWxsID0gbnVsbDtcblxuLyoqXG4gKiBMYXppbHkgcmVzb2x2ZSBBcHBLaXQncyBpbnRlcm5hbCBgUGVyc2lzdGVudFN0b3JhZ2VgIGNvbnN0cnVjdG9yLiBgbnVsbGBcbiAqIG1lYW5zIG5vdCBhdHRlbXB0ZWQgeWV0OyBgdW5kZWZpbmVkYCBtZWFucyB0aGUgbG9va3VwIGFscmVhZHkgZmFpbGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZFBlcnNpc3RlbnRTdG9yYWdlKCk6IFBlcnNpc3RlbnRTdG9yYWdlQ29uc3RydWN0b3IgfCB1bmRlZmluZWQge1xuICBpZiAocGVyc2lzdGVudFN0b3JhZ2VDdG9yICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIHBlcnNpc3RlbnRTdG9yYWdlQ3RvcjtcbiAgfVxuICB0cnkge1xuICAgIGNvbnN0IHJlcXVpcmUgPSBjcmVhdGVSZXF1aXJlKGltcG9ydC5tZXRhLnVybCk7XG4gICAgY29uc3QgbW9kdWxlUGF0aCA9IGpvaW4oXG4gICAgICBkaXJuYW1lKHJlcXVpcmUucmVzb2x2ZShcIkBkYXRhYnJpY2tzL2FwcGtpdFwiKSksXG4gICAgICBcImNhY2hlL3N0b3JhZ2UvcGVyc2lzdGVudC5qc1wiLFxuICAgICk7XG4gICAgY29uc3QgbG9hZGVkID0gcmVxdWlyZShtb2R1bGVQYXRoKS5QZXJzaXN0ZW50U3RvcmFnZSBhc1xuICAgICAgUGVyc2lzdGVudFN0b3JhZ2VDb25zdHJ1Y3RvciB8IHVuZGVmaW5lZDtcbiAgICBpZiAodHlwZW9mIGxvYWRlZCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICBsb2dnZXIuZGVidWcoXCJzb2Z0IHBlcnNpc3RlbnQgY2FjaGUgc2tpcHBlZCAoUGVyc2lzdGVudFN0b3JhZ2UgbWlzc2luZylcIik7XG4gICAgICBwZXJzaXN0ZW50U3RvcmFnZUN0b3IgPSB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBwZXJzaXN0ZW50U3RvcmFnZUN0b3IgPSBsb2FkZWQ7XG4gICAgcmV0dXJuIGxvYWRlZDtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwic29mdCBwZXJzaXN0ZW50IGNhY2hlIHNraXBwZWQgKFBlcnNpc3RlbnRTdG9yYWdlIHVuYXZhaWxhYmxlKVwiLCB7XG4gICAgICBlcnJvcjogZXJyb3JVdGlscy5lcnJvck1lc3NhZ2UoZXJyKSxcbiAgICB9KTtcbiAgICBwZXJzaXN0ZW50U3RvcmFnZUN0b3IgPSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vKipcbiAqIFdoZXRoZXIgYW4gZXhpc3RpbmcgY2FjaGUgdGFibGUgYmVsb25ncyB0byBhbm90aGVyIHJvbGUuXG4gKlxuICogUG9zdGdyZVNRTCBhbGxvd3MgZ3JhbnRlZCByZWFkcy93cml0ZXMgYnV0IHJlc2VydmVzIGluZGV4IERETCBmb3IgdGhlIHRhYmxlXG4gKiBvd25lci4gU2tpcCBBcHBLaXQgbWlncmF0aW9ucyBpbiB0aGF0IGNhc2U7IHtAbGluayBwcm9iZVN0b3JhZ2V9IHN0aWxsIHByb3Zlc1xuICogdGhlIGV4aXN0aW5nIHRhYmxlIGNhbiBzZXJ2ZSB0aGUgY2FjaGUgYmVmb3JlIGl0IGlzIGFjY2VwdGVkLlxuICovXG5hc3luYyBmdW5jdGlvbiB0YWJsZU93bmVkQnlBbm90aGVyUm9sZShcbiAgc3RvcmFnZTogUGVyc2lzdGVudFN0b3JhZ2VCYXNlLFxuICBwb29sOiBMYWtlYmFzZVBvb2wsXG4pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgaWYgKCFzdG9yYWdlLnNjaGVtYU5hbWUgfHwgIXN0b3JhZ2UudGFibGVOYW1lKSByZXR1cm4gZmFsc2U7XG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBvb2wucXVlcnkoXG4gICAgYFNFTEVDVCBwZ19nZXRfdXNlcmJ5aWQoYy5yZWxvd25lcikgPSBjdXJyZW50X3VzZXIgQVMgb3duZWRcbiAgICAgRlJPTSBwZ19jbGFzcyBjXG4gICAgIEpPSU4gcGdfbmFtZXNwYWNlIG4gT04gbi5vaWQgPSBjLnJlbG5hbWVzcGFjZVxuICAgICBXSEVSRSBuLm5zcG5hbWUgPSAkMSBBTkQgYy5yZWxuYW1lID0gJDIgQU5EIGMucmVsa2luZCBJTiAoJ3InLCAncCcpYCxcbiAgICBbc3RvcmFnZS5zY2hlbWFOYW1lLCBzdG9yYWdlLnRhYmxlTmFtZV0sXG4gICk7XG4gIGlmIChyZXN1bHQucm93c1swXT8ub3duZWQgIT09IGZhbHNlKSByZXR1cm4gZmFsc2U7XG4gIGxvZ2dlci53YXJuKFwicGVyc2lzdGVudCBjYWNoZSBtaWdyYXRpb25zIHNraXBwZWQgKHRhYmxlIG93bmVkIGJ5IGFub3RoZXIgcm9sZSlcIiwge1xuICAgIHNjaGVtYTogc3RvcmFnZS5zY2hlbWFOYW1lLFxuICAgIHRhYmxlOiBzdG9yYWdlLnRhYmxlTmFtZSxcbiAgfSk7XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKiogU29mdGVuIGBpbml0aWFsaXplKClgIHNvIGFuIG93bmVyc2hpcC1vbmx5IG1pZ3JhdGlvbiBmYWlsdXJlIGlzIG5vdCBmYXRhbC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzb2Z0ZW5Jbml0aWFsaXplKFxuICBzdG9yYWdlOiBQZXJzaXN0ZW50U3RvcmFnZUJhc2UsXG4gIHNraXBNaWdyYXRpb25zPzogKCkgPT4gUHJvbWlzZTxib29sZWFuPixcbik6IHZvaWQge1xuICBjb25zdCBvcmlnaW5hbEluaXRpYWxpemUgPSBzdG9yYWdlLmluaXRpYWxpemUuYmluZChzdG9yYWdlKTtcbiAgbGV0IHNvZnRJbml0UHJvbWlzZTogUHJvbWlzZTx2b2lkPiB8IHVuZGVmaW5lZDtcblxuICBzdG9yYWdlLmluaXRpYWxpemUgPSBhc3luYyAoKSA9PiB7XG4gICAgaWYgKHN0b3JhZ2UuaW5pdGlhbGl6ZWQpIHJldHVybjtcbiAgICBzb2Z0SW5pdFByb21pc2UgPz89IChhc3luYyAoKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoIShhd2FpdCBza2lwTWlncmF0aW9ucz8uKCkpKSBhd2FpdCBvcmlnaW5hbEluaXRpYWxpemUoKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIWhhbmRsZU93bmVyc2hpcE1pZ3JhdGlvbkVycm9yKGVyciwge1xuICAgICAgICAgICAgc2NvcGU6IFwiY2FjaGUtc3RvcmFnZVwiLFxuICAgICAgICAgICAgbG9nZ2VyLFxuICAgICAgICAgICAgZXZlbnQ6IFwicGVyc2lzdGVudCBjYWNoZSBtaWdyYXRpb24gZmFpbGVkXCIsXG4gICAgICAgICAgfSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSkoKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgc29mdEluaXRQcm9taXNlO1xuICAgICAgc3RvcmFnZS5pbml0aWFsaXplZCA9IHRydWU7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBzb2Z0SW5pdFByb21pc2UgPSB1bmRlZmluZWQ7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9O1xufVxuXG4vKiogVmVyaWZ5IHRoZSBtaWdyYXRlZCBjYWNoZSB0YWJsZSBjYW4gc2VydmUgdGhlIHJlYWRzIGFuZCB3cml0ZXMgQXBwS2l0IG5lZWRzLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHByb2JlU3RvcmFnZShzdG9yYWdlOiBQZXJzaXN0ZW50U3RvcmFnZUJhc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3Qga2V5ID0gYGRieC10b29sczpjYWNoZS1wcm9iZToke2hhc2guaWQoKX1gO1xuICB0cnkge1xuICAgIGF3YWl0IHN0b3JhZ2Uuc2V0KGtleSwgeyB2YWx1ZToga2V5LCBleHBpcnk6IERhdGUubm93KCkgKyA2MF8wMDAgfSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3RvcmFnZS5nZXQoa2V5KTtcbiAgICBpZiAocmVzdWx0Py52YWx1ZSAhPT0ga2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJwZXJzaXN0ZW50IGNhY2hlIHByb2JlIHJldHVybmVkIGFuIHVuZXhwZWN0ZWQgdmFsdWVcIik7XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIGF3YWl0IHN0b3JhZ2UuZGVsZXRlKGtleSkuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcbiAgfVxufVxuXG4vKipcbiAqIEJ1aWxkIGEgc29mdC1mYWlsIExha2ViYXNlIGNhY2hlIHN0b3JhZ2Ugd2hlbiBhIHBvb2wgY2FuIGJlIGNyZWF0ZWQgYW5kXG4gKiBBcHBLaXQncyBQZXJzaXN0ZW50U3RvcmFnZSBjYW4gYmUgbG9hZGVkLiBSZXR1cm5zIGB1bmRlZmluZWRgIG90aGVyd2lzZSBzb1xuICogQXBwS2l0IGNhbiBmYWxsIHRocm91Z2ggdG8gaXRzIG5vcm1hbCBjYWNoZSBwYXRoLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlU29mdFBlcnNpc3RlbnRTdG9yYWdlKFxuICBjYWNoZTogQ2FjaGVDb25maWcgfCB1bmRlZmluZWQsXG4pOiBQcm9taXNlPENhY2hlU3RvcmFnZSB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCBQZXJzaXN0ZW50U3RvcmFnZSA9IGxvYWRQZXJzaXN0ZW50U3RvcmFnZSgpO1xuICBpZiAoIVBlcnNpc3RlbnRTdG9yYWdlKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGxldCBwb29sOiBMYWtlYmFzZVBvb2wgfCB1bmRlZmluZWQ7XG4gIHRyeSB7XG4gICAgY29uc3QgY3JlYXRlZFBvb2wgPSBjcmVhdGVMYWtlYmFzZVBvb2woXG4gICAgICBwb3N0Z3Jlc0Nvbm5lY3Rpb25PcHRpb25zKHsgd29ya3NwYWNlQ2xpZW50OiBnZXRXb3Jrc3BhY2VDbGllbnQoe30pIH0pLFxuICAgICk7XG4gICAgcG9vbCA9IGNyZWF0ZWRQb29sO1xuICAgIGNvbnN0IHN0b3JhZ2UgPSBuZXcgUGVyc2lzdGVudFN0b3JhZ2UoY2FjaGUgPz8ge30sIGNyZWF0ZWRQb29sKTtcbiAgICBzb2Z0ZW5Jbml0aWFsaXplKHN0b3JhZ2UsICgpID0+IHRhYmxlT3duZWRCeUFub3RoZXJSb2xlKHN0b3JhZ2UsIGNyZWF0ZWRQb29sKSk7XG4gICAgaWYgKCEoYXdhaXQgc3RvcmFnZS5oZWFsdGhDaGVjaygpKSkge1xuICAgICAgYXdhaXQgc3RvcmFnZS5jbG9zZSgpLmNhdGNoKCgpID0+IHt9KTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGF3YWl0IHN0b3JhZ2UuaW5pdGlhbGl6ZSgpO1xuICAgIGF3YWl0IHByb2JlU3RvcmFnZShzdG9yYWdlKTtcbiAgICByZXR1cm4gc3RvcmFnZTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwic29mdCBwZXJzaXN0ZW50IGNhY2hlIHVuYXZhaWxhYmxlXCIsIHtcbiAgICAgIGVycm9yOiBlcnJvclV0aWxzLmVycm9yTWVzc2FnZShlcnIpLFxuICAgIH0pO1xuICAgIGlmIChwb29sKSB7XG4gICAgICBhd2FpdCBwb29sLmVuZCgpLmNhdGNoKCgpID0+IHt9KTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AppKit child-process lifecycle built on `@dbx-tools/core/exec`.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import * as exec from "@dbx-tools/core/exec";
|
|
7
|
+
/** Spawn arguments accepted by {@link AppKitChildProcess}. */
|
|
8
|
+
export type AppKitSpawnArgs = exec.SpawnArgs<exec.ExecOptions>;
|
|
9
|
+
/** Graceful and forced shutdown policy for an AppKit child process. */
|
|
10
|
+
export interface AppKitChildProcessOptions {
|
|
11
|
+
/** Signal sent when shutdown starts. Defaults to `SIGTERM`. */
|
|
12
|
+
gracefulSignal?: NodeJS.Signals;
|
|
13
|
+
/** Time to wait after the graceful signal. Defaults to 7 seconds. */
|
|
14
|
+
gracefulTimeoutMs?: number;
|
|
15
|
+
/** Signal sent when graceful shutdown times out. Defaults to `SIGKILL`. */
|
|
16
|
+
forceSignal?: NodeJS.Signals;
|
|
17
|
+
/** Time to wait after the force signal. Defaults to 1 second. */
|
|
18
|
+
forceTimeoutMs?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Start and stop one AppKit-owned subprocess.
|
|
22
|
+
*
|
|
23
|
+
* The spawn arguments use {@link exec.ExecOptions}, including core exec's
|
|
24
|
+
* stdin, output capture, line handlers, exit checking, and trim policy.
|
|
25
|
+
* Shutdown is idempotent and escalates from the graceful signal to the force
|
|
26
|
+
* signal when the child does not exit within the configured timeouts.
|
|
27
|
+
*/
|
|
28
|
+
export declare class AppKitChildProcess {
|
|
29
|
+
#private;
|
|
30
|
+
constructor(spawnArgs: AppKitSpawnArgs, options?: AppKitChildProcessOptions);
|
|
31
|
+
/** Current child handle, or `undefined` when no child is running. */
|
|
32
|
+
get process(): exec.ChildProcessResult | undefined;
|
|
33
|
+
/** Whether the current child has not reported an exit code or signal. */
|
|
34
|
+
get running(): boolean;
|
|
35
|
+
/** Start the configured child process. */
|
|
36
|
+
start(): exec.ChildProcessResult;
|
|
37
|
+
/** Stop the child once, escalating when graceful shutdown times out. */
|
|
38
|
+
shutdown(): Promise<void>;
|
|
39
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AppKit child-process lifecycle built on `@dbx-tools/core/exec`.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import * as exec from "@dbx-tools/core/exec";
|
|
7
|
+
/**
|
|
8
|
+
* Start and stop one AppKit-owned subprocess.
|
|
9
|
+
*
|
|
10
|
+
* The spawn arguments use {@link exec.ExecOptions}, including core exec's
|
|
11
|
+
* stdin, output capture, line handlers, exit checking, and trim policy.
|
|
12
|
+
* Shutdown is idempotent and escalates from the graceful signal to the force
|
|
13
|
+
* signal when the child does not exit within the configured timeouts.
|
|
14
|
+
*/
|
|
15
|
+
export class AppKitChildProcess {
|
|
16
|
+
#spawnArgs;
|
|
17
|
+
#options;
|
|
18
|
+
#detached;
|
|
19
|
+
#child;
|
|
20
|
+
#shutdownPromise;
|
|
21
|
+
constructor(spawnArgs, options = {}) {
|
|
22
|
+
this.#spawnArgs = spawnArgs;
|
|
23
|
+
this.#options = {
|
|
24
|
+
gracefulSignal: options.gracefulSignal ?? "SIGTERM",
|
|
25
|
+
gracefulTimeoutMs: options.gracefulTimeoutMs ?? 7_000,
|
|
26
|
+
forceSignal: options.forceSignal ?? "SIGKILL",
|
|
27
|
+
forceTimeoutMs: options.forceTimeoutMs ?? 1_000,
|
|
28
|
+
};
|
|
29
|
+
this.#detached = spawnOptions(spawnArgs)?.detached === true;
|
|
30
|
+
}
|
|
31
|
+
/** Current child handle, or `undefined` when no child is running. */
|
|
32
|
+
get process() {
|
|
33
|
+
return this.#child;
|
|
34
|
+
}
|
|
35
|
+
/** Whether the current child has not reported an exit code or signal. */
|
|
36
|
+
get running() {
|
|
37
|
+
return this.#child !== undefined && !hasExited(this.#child);
|
|
38
|
+
}
|
|
39
|
+
/** Start the configured child process. */
|
|
40
|
+
start() {
|
|
41
|
+
if (this.running)
|
|
42
|
+
throw new Error("Child process is already running");
|
|
43
|
+
if (this.#shutdownPromise) {
|
|
44
|
+
throw new Error("Child process is shutting down or has been shut down");
|
|
45
|
+
}
|
|
46
|
+
const child = exec.spawn(...this.#spawnArgs);
|
|
47
|
+
this.#child = child;
|
|
48
|
+
void child.once("close", () => {
|
|
49
|
+
if (this.#child === child)
|
|
50
|
+
this.#child = undefined;
|
|
51
|
+
});
|
|
52
|
+
return child;
|
|
53
|
+
}
|
|
54
|
+
/** Stop the child once, escalating when graceful shutdown times out. */
|
|
55
|
+
shutdown() {
|
|
56
|
+
this.#shutdownPromise ??= this.#performShutdown();
|
|
57
|
+
return this.#shutdownPromise;
|
|
58
|
+
}
|
|
59
|
+
async #performShutdown() {
|
|
60
|
+
const child = this.#child;
|
|
61
|
+
if (!child || hasExited(child)) {
|
|
62
|
+
this.#child = undefined;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
signalChild(child, this.#options.gracefulSignal, this.#detached);
|
|
66
|
+
if (await waitForExit(child, this.#options.gracefulTimeoutMs)) {
|
|
67
|
+
if (this.#child === child)
|
|
68
|
+
this.#child = undefined;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
signalChild(child, this.#options.forceSignal, this.#detached);
|
|
72
|
+
if (!(await waitForExit(child, this.#options.forceTimeoutMs))) {
|
|
73
|
+
throw new Error(`Child process ${child.pid ?? "<unknown>"} did not terminate`);
|
|
74
|
+
}
|
|
75
|
+
if (this.#child === child)
|
|
76
|
+
this.#child = undefined;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function spawnOptions(args) {
|
|
80
|
+
const value = args.at(-1);
|
|
81
|
+
return isExecOptions(value) ? value : undefined;
|
|
82
|
+
}
|
|
83
|
+
function isExecOptions(value) {
|
|
84
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
85
|
+
}
|
|
86
|
+
function hasExited(child) {
|
|
87
|
+
return child.exitCode !== null || child.signalCode !== null;
|
|
88
|
+
}
|
|
89
|
+
function signalChild(child, signal, detached) {
|
|
90
|
+
if (detached && process.platform !== "win32" && child.pid) {
|
|
91
|
+
try {
|
|
92
|
+
process.kill(-child.pid, signal);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Fall back to the direct child when the process group already exited.
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
child.kill(signal);
|
|
100
|
+
}
|
|
101
|
+
function waitForExit(child, timeoutMs) {
|
|
102
|
+
if (hasExited(child))
|
|
103
|
+
return Promise.resolve(true);
|
|
104
|
+
return new Promise((resolve) => {
|
|
105
|
+
let timer;
|
|
106
|
+
let settled = false;
|
|
107
|
+
const finish = (exited) => {
|
|
108
|
+
if (settled)
|
|
109
|
+
return;
|
|
110
|
+
settled = true;
|
|
111
|
+
if (timer)
|
|
112
|
+
clearTimeout(timer);
|
|
113
|
+
void child.off("exit", onExit);
|
|
114
|
+
void child.off("error", onError);
|
|
115
|
+
resolve(exited);
|
|
116
|
+
};
|
|
117
|
+
const onExit = () => finish(true);
|
|
118
|
+
const onError = () => finish(true);
|
|
119
|
+
void child.once("exit", onExit);
|
|
120
|
+
void child.once("error", onError);
|
|
121
|
+
if (hasExited(child)) {
|
|
122
|
+
finish(true);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
timer = setTimeout(() => finish(false), timeoutMs);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hpbGQtcHJvY2Vzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jaGlsZC1wcm9jZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFDSCxPQUFPLEtBQUssSUFBSSxNQUFNLHNCQUFzQixDQUFDO0FBaUI3Qzs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxPQUFPLGtCQUFrQjtJQUNwQixVQUFVLENBQWtCO0lBQzVCLFFBQVEsQ0FBc0M7SUFDOUMsU0FBUyxDQUFVO0lBRTVCLE1BQU0sQ0FBMkI7SUFDakMsZ0JBQWdCLENBQWlCO0lBRWpDLFlBQVksU0FBMEIsRUFBRSxVQUFxQyxFQUFFO1FBQzdFLElBQUksQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDO1FBQzVCLElBQUksQ0FBQyxRQUFRLEdBQUc7WUFDZCxjQUFjLEVBQUUsT0FBTyxDQUFDLGNBQWMsSUFBSSxTQUFTO1lBQ25ELGlCQUFpQixFQUFFLE9BQU8sQ0FBQyxpQkFBaUIsSUFBSSxLQUFLO1lBQ3JELFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVyxJQUFJLFNBQVM7WUFDN0MsY0FBYyxFQUFFLE9BQU8sQ0FBQyxjQUFjLElBQUksS0FBSztTQUNoRCxDQUFDO1FBQ0YsSUFBSSxDQUFDLFNBQVMsR0FBRyxZQUFZLENBQUMsU0FBUyxDQUFDLEVBQUUsUUFBUSxLQUFLLElBQUksQ0FBQztJQUM5RCxDQUFDO0lBRUQscUVBQXFFO0lBQ3JFLElBQUksT0FBTztRQUNULE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUNyQixDQUFDO0lBRUQseUVBQXlFO0lBQ3pFLElBQUksT0FBTztRQUNULE9BQU8sSUFBSSxDQUFDLE1BQU0sS0FBSyxTQUFTLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzlELENBQUM7SUFFRCwwQ0FBMEM7SUFDMUMsS0FBSztRQUNILElBQUksSUFBSSxDQUFDLE9BQU87WUFBRSxNQUFNLElBQUks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RUFBRSxNQUFNLENBQUMsQ0FBQztRQUNoQyxLQUFLLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ2xDLElBQUksU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDckIsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2IsT0FBTztRQUNULENBQUM7UUFDRCxLQUFLLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUNyRCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEFwcEtpdCBjaGlsZC1wcm9jZXNzIGxpZmVjeWNsZSBidWlsdCBvbiBgQGRieC10b29scy9jb3JlL2V4ZWNgLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuaW1wb3J0ICogYXMgZXhlYyBmcm9tIFwiQGRieC10b29scy9jb3JlL2V4ZWNcIjtcblxuLyoqIFNwYXduIGFyZ3VtZW50cyBhY2NlcHRlZCBieSB7QGxpbmsgQXBwS2l0Q2hpbGRQcm9jZXNzfS4gKi9cbmV4cG9ydCB0eXBlIEFwcEtpdFNwYXduQXJncyA9IGV4ZWMuU3Bhd25BcmdzPGV4ZWMuRXhlY09wdGlvbnM+O1xuXG4vKiogR3JhY2VmdWwgYW5kIGZvcmNlZCBzaHV0ZG93biBwb2xpY3kgZm9yIGFuIEFwcEtpdCBjaGlsZCBwcm9jZXNzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcHBLaXRDaGlsZFByb2Nlc3NPcHRpb25zIHtcbiAgLyoqIFNpZ25hbCBzZW50IHdoZW4gc2h1dGRvd24gc3RhcnRzLiBEZWZhdWx0cyB0byBgU0lHVEVSTWAuICovXG4gIGdyYWNlZnVsU2lnbmFsPzogTm9kZUpTLlNpZ25hbHM7XG4gIC8qKiBUaW1lIHRvIHdhaXQgYWZ0ZXIgdGhlIGdyYWNlZnVsIHNpZ25hbC4gRGVmYXVsdHMgdG8gNyBzZWNvbmRzLiAqL1xuICBncmFjZWZ1bFRpbWVvdXRNcz86IG51bWJlcjtcbiAgLyoqIFNpZ25hbCBzZW50IHdoZW4gZ3JhY2VmdWwgc2h1dGRvd24gdGltZXMgb3V0LiBEZWZhdWx0cyB0byBgU0lHS0lMTGAuICovXG4gIGZvcmNlU2lnbmFsPzogTm9kZUpTLlNpZ25hbHM7XG4gIC8qKiBUaW1lIHRvIHdhaXQgYWZ0ZXIgdGhlIGZvcmNlIHNpZ25hbC4gRGVmYXVsdHMgdG8gMSBzZWNvbmQuICovXG4gIGZvcmNlVGltZW91dE1zPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIFN0YXJ0IGFuZCBzdG9wIG9uZSBBcHBLaXQtb3duZWQgc3VicHJvY2Vzcy5cbiAqXG4gKiBUaGUgc3Bhd24gYXJndW1lbnRzIHVzZSB7QGxpbmsgZXhlYy5FeGVjT3B0aW9uc30sIGluY2x1ZGluZyBjb3JlIGV4ZWMnc1xuICogc3RkaW4sIG91dHB1dCBjYXB0dXJlLCBsaW5lIGhhbmRsZXJzLCBleGl0IGNoZWNraW5nLCBhbmQgdHJpbSBwb2xpY3kuXG4gKiBTaHV0ZG93biBpcyBpZGVtcG90ZW50IGFuZCBlc2NhbGF0ZXMgZnJvbSB0aGUgZ3JhY2VmdWwgc2lnbmFsIHRvIHRoZSBmb3JjZVxuICogc2lnbmFsIHdoZW4gdGhlIGNoaWxkIGRvZXMgbm90IGV4aXQgd2l0aGluIHRoZSBjb25maWd1cmVkIHRpbWVvdXRzLlxuICovXG5leHBvcnQgY2xhc3MgQXBwS2l0Q2hpbGRQcm9jZXNzIHtcbiAgcmVhZG9ubHkgI3NwYXduQXJnczogQXBwS2l0U3Bhd25BcmdzO1xuICByZWFkb25seSAjb3B0aW9uczogUmVxdWlyZWQ8QXBwS2l0Q2hpbGRQcm9jZXNzT3B0aW9ucz47XG4gIHJlYWRvbmx5ICNkZXRhY2hlZDogYm9vbGVhbjtcblxuICAjY2hpbGQ/OiBleGVjLkNoaWxkUHJvY2Vzc1Jlc3VsdDtcbiAgI3NodXRkb3duUHJvbWlzZT86IFByb21pc2U8dm9pZD47XG5cbiAgY29uc3RydWN0b3Ioc3Bhd25BcmdzOiBBcHBLaXRTcGF3bkFyZ3MsIG9wdGlvbnM6IEFwcEtpdENoaWxkUHJvY2Vzc09wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMuI3NwYXduQXJncyA9IHNwYXduQXJncztcbiAgICB0aGlzLiNvcHRpb25zID0ge1xuICAgICAgZ3JhY2VmdWxTaWduYWw6IG9wdGlvbnMuZ3JhY2VmdWxTaWduYWwgPz8gXCJTSUdURVJNXCIsXG4gICAgICBncmFjZWZ1bFRpbWVvdXRNczogb3B0aW9ucy5ncmFjZWZ1bFRpbWVvdXRNcyA/PyA3XzAwMCxcbiAgICAgIGZvcmNlU2lnbmFsOiBvcHRpb25zLmZvcmNlU2lnbmFsID8/IFwiU0lHS0lMTFwiLFxuICAgICAgZm9yY2VUaW1lb3V0TXM6IG9wdGlvbnMuZm9yY2VUaW1lb3V0TXMgPz8gMV8wMDAsXG4gICAgfTtcbiAgICB0aGlzLiNkZXRhY2hlZCA9IHNwYXduT3B0aW9ucyhzcGF3bkFyZ3MpPy5kZXRhY2hlZCA9PT0gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBDdXJyZW50IGNoaWxkIGhhbmRsZSwgb3IgYHVuZGVmaW5lZGAgd2hlbiBubyBjaGlsZCBpcyBydW5uaW5nLiAqL1xuICBnZXQgcHJvY2VzcygpOiBleGVjLkNoaWxkUHJvY2Vzc1Jlc3VsdCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuI2NoaWxkO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgdGhlIGN1cnJlbnQgY2hpbGQgaGFzIG5vdCByZXBvcnRlZCBhbiBleGl0IGNvZGUgb3Igc2lnbmFsLiAqL1xuICBnZXQgcnVubmluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy4jY2hpbGQgIT09IHVuZGVmaW5lZCAmJiAhaGFzRXhpdGVkKHRoaXMuI2NoaWxkKTtcbiAgfVxuXG4gIC8qKiBTdGFydCB0aGUgY29uZmlndXJlZCBjaGlsZCBwcm9jZXNzLiAqL1xuICBzdGFydCgpOiBleGVjLkNoaWxkUHJvY2Vzc1Jlc3VsdCB7XG4gICAgaWYgKHRoaXMucnVubmluZykgdGhyb3cgbmV3IEVycm9yKFwiQ2hpbGQgcHJvY2VzcyBpcyBhbHJlYWR5IHJ1bm5pbmdcIik7XG4gICAgaWYgKHRoaXMuI3NodXRkb3duUHJvbWlzZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2hpbGQgcHJvY2VzcyBpcyBzaHV0dGluZyBkb3duIG9yIGhhcyBiZWVuIHNodXQgZG93blwiKTtcbiAgICB9XG5cbiAgICBjb25zdCBjaGlsZCA9IGV4ZWMuc3Bhd24oLi4udGhpcy4jc3Bhd25BcmdzKTtcbiAgICB0aGlzLiNjaGlsZCA9IGNoaWxkO1xuICAgIHZvaWQgY2hpbGQub25jZShcImNsb3NlXCIsICgpID0+IHtcbiAgICAgIGlmICh0aGlzLiNjaGlsZCA9PT0gY2hpbGQpIHRoaXMuI2NoaWxkID0gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIHJldHVybiBjaGlsZDtcbiAgfVxuXG4gIC8qKiBTdG9wIHRoZSBjaGlsZCBvbmNlLCBlc2NhbGF0aW5nIHdoZW4gZ3JhY2VmdWwgc2h1dGRvd24gdGltZXMgb3V0LiAqL1xuICBzaHV0ZG93bigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLiNzaHV0ZG93blByb21pc2UgPz89IHRoaXMuI3BlcmZvcm1TaHV0ZG93bigpO1xuICAgIHJldHVybiB0aGlzLiNzaHV0ZG93blByb21pc2U7XG4gIH1cblxuICBhc3luYyAjcGVyZm9ybVNodXRkb3duKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNoaWxkID0gdGhpcy4jY2hpbGQ7XG4gICAgaWYgKCFjaGlsZCB8fCBoYXNFeGl0ZWQoY2hpbGQpKSB7XG4gICAgICB0aGlzLiNjaGlsZCA9IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzaWduYWxDaGlsZChjaGlsZCwgdGhpcy4jb3B0aW9ucy5ncmFjZWZ1bFNpZ25hbCwgdGhpcy4jZGV0YWNoZWQpO1xuICAgIGlmIChhd2FpdCB3YWl0Rm9yRXhpdChjaGlsZCwgdGhpcy4jb3B0aW9ucy5ncmFjZWZ1bFRpbWVvdXRNcykpIHtcbiAgICAgIGlmICh0aGlzLiNjaGlsZCA9PT0gY2hpbGQpIHRoaXMuI2NoaWxkID0gdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHNpZ25hbENoaWxkKGNoaWxkLCB0aGlzLiNvcHRpb25zLmZvcmNlU2lnbmFsLCB0aGlzLiNkZXRhY2hlZCk7XG4gICAgaWYgKCEoYXdhaXQgd2FpdEZvckV4aXQoY2hpbGQsIHRoaXMuI29wdGlvbnMuZm9yY2VUaW1lb3V0TXMpKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDaGlsZCBwcm9jZXNzICR7Y2hpbGQucGlkID8/IFwiPHVua25vd24+XCJ9IGRpZCBub3QgdGVybWluYXRlYCk7XG4gICAgfVxuICAgIGlmICh0aGlzLiNjaGlsZCA9PT0gY2hpbGQpIHRoaXMuI2NoaWxkID0gdW5kZWZpbmVkO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNwYXduT3B0aW9ucyhhcmdzOiBBcHBLaXRTcGF3bkFyZ3MpOiBleGVjLkV4ZWNPcHRpb25zIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgdmFsdWUgPSBhcmdzLmF0KC0xKTtcbiAgcmV0dXJuIGlzRXhlY09wdGlvbnModmFsdWUpID8gdmFsdWUgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGlzRXhlY09wdGlvbnModmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBleGVjLkV4ZWNPcHRpb25zIHtcbiAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG59XG5cbmZ1bmN0aW9uIGhhc0V4aXRlZChjaGlsZDogZXhlYy5DaGlsZFByb2Nlc3NSZXN1bHQpOiBib29sZWFuIHtcbiAgcmV0dXJuIGNoaWxkLmV4aXRDb2RlICE9PSBudWxsIHx8IGNoaWxkLnNpZ25hbENvZGUgIT09IG51bGw7XG59XG5cbmZ1bmN0aW9uIHNpZ25hbENoaWxkKFxuICBjaGlsZDogZXhlYy5DaGlsZFByb2Nlc3NSZXN1bHQsXG4gIHNpZ25hbDogTm9kZUpTLlNpZ25hbHMsXG4gIGRldGFjaGVkOiBib29sZWFuLFxuKTogdm9pZCB7XG4gIGlmIChkZXRhY2hlZCAmJiBwcm9jZXNzLnBsYXRmb3JtICE9PSBcIndpbjMyXCIgJiYgY2hpbGQucGlkKSB7XG4gICAgdHJ5IHtcbiAgICAgIHByb2Nlc3Mua2lsbCgtY2hpbGQucGlkLCBzaWduYWwpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gRmFsbCBiYWNrIHRvIHRoZSBkaXJlY3QgY2hpbGQgd2hlbiB0aGUgcHJvY2VzcyBncm91cCBhbHJlYWR5IGV4aXRlZC5cbiAgICB9XG4gIH1cbiAgY2hpbGQua2lsbChzaWduYWwpO1xufVxuXG5mdW5jdGlvbiB3YWl0Rm9yRXhpdChjaGlsZDogZXhlYy5DaGlsZFByb2Nlc3NSZXN1bHQsIHRpbWVvdXRNczogbnVtYmVyKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGlmIChoYXNFeGl0ZWQoY2hpbGQpKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRydWUpO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIGxldCB0aW1lcjogTm9kZUpTLlRpbWVvdXQgfCB1bmRlZmluZWQ7XG4gICAgbGV0IHNldHRsZWQgPSBmYWxzZTtcblxuICAgIGNvbnN0IGZpbmlzaCA9IChleGl0ZWQ6IGJvb2xlYW4pID0+IHtcbiAgICAgIGlmIChzZXR0bGVkKSByZXR1cm47XG4gICAgICBzZXR0bGVkID0gdHJ1ZTtcbiAgICAgIGlmICh0aW1lcikgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIHZvaWQgY2hpbGQub2ZmKFwiZXhpdFwiLCBvbkV4aXQpO1xuICAgICAgdm9pZCBjaGlsZC5vZmYoXCJlcnJvclwiLCBvbkVycm9yKTtcbiAgICAgIHJlc29sdmUoZXhpdGVkKTtcbiAgICB9O1xuICAgIGNvbnN0IG9uRXhpdCA9ICgpID0+IGZpbmlzaCh0cnVlKTtcbiAgICBjb25zdCBvbkVycm9yID0gKCkgPT4gZmluaXNoKHRydWUpO1xuXG4gICAgdm9pZCBjaGlsZC5vbmNlKFwiZXhpdFwiLCBvbkV4aXQpO1xuICAgIHZvaWQgY2hpbGQub25jZShcImVycm9yXCIsIG9uRXJyb3IpO1xuICAgIGlmIChoYXNFeGl0ZWQoY2hpbGQpKSB7XG4gICAgICBmaW5pc2godHJ1ZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiBmaW5pc2goZmFsc2UpLCB0aW1lb3V0TXMpO1xuICB9KTtcbn1cbiJdfQ==
|
package/lib/src/provision.js
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import { createLakebasePool, getWorkspaceClient, ValidationError } from "@databricks/appkit";
|
|
24
24
|
import { configUtils } from "@dbx-tools/core";
|
|
25
|
+
import { postgresConnectionOptions, quotePostgresIdentifier } from "@dbx-tools/postgres";
|
|
25
26
|
import { errorUtils, log } from "@dbx-tools/shared-core";
|
|
26
27
|
const defaultLogger = log.logger("provision");
|
|
27
28
|
/** AppKit persistent-cache schema (see AppKit's `PersistentStorage`). */
|
|
@@ -38,16 +39,6 @@ const ROLE_PATTERN = /^[A-Za-z0-9._@+-]{1,255}$/;
|
|
|
38
39
|
*/
|
|
39
40
|
const CONNECT_TIMEOUT_MS = 10_000;
|
|
40
41
|
const STATEMENT_TIMEOUT_MS = 15_000;
|
|
41
|
-
/**
|
|
42
|
-
* Quote a Postgres identifier: wrap in double quotes and double any embedded
|
|
43
|
-
* quote. Schema and role names are identifiers, and Postgres does not accept a
|
|
44
|
-
* bind parameter in an identifier position, so quoting is the only defense
|
|
45
|
-
* available for these statements. Lakebase role names are usually emails
|
|
46
|
-
* (`user@host`), which must be quoted to be a valid identifier at all.
|
|
47
|
-
*/
|
|
48
|
-
function quoteIdent(ident) {
|
|
49
|
-
return `"${ident.replace(/"/g, '""')}"`;
|
|
50
|
-
}
|
|
51
42
|
/**
|
|
52
43
|
* Idempotent grants that make the (already-existing) AppKit cache schema fully
|
|
53
44
|
* usable by `role`. The `ALTER DEFAULT PRIVILEGES` lines cover the cache table
|
|
@@ -60,8 +51,8 @@ export function cacheGrantStatements(role) {
|
|
|
60
51
|
if (!ROLE_PATTERN.test(role)) {
|
|
61
52
|
throw ValidationError.invalidValue("role", role, "a Postgres role name");
|
|
62
53
|
}
|
|
63
|
-
const schema =
|
|
64
|
-
const target =
|
|
54
|
+
const schema = quotePostgresIdentifier(CACHE_SCHEMA);
|
|
55
|
+
const target = quotePostgresIdentifier(role);
|
|
65
56
|
return [
|
|
66
57
|
`GRANT USAGE, CREATE ON SCHEMA ${schema} TO ${target}`,
|
|
67
58
|
`GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA ${schema} TO ${target}`,
|
|
@@ -103,12 +94,12 @@ export async function provisionCacheSchema(role, logger = defaultLogger) {
|
|
|
103
94
|
// returns a fresh default-auth client - literally `new WorkspaceClient({})`,
|
|
104
95
|
// but built against the SDK version AppKit's `createLakebasePool` expects
|
|
105
96
|
// (importing the SDK class directly here pulls a newer, type-incompatible copy).
|
|
106
|
-
const pool = createLakebasePool({
|
|
97
|
+
const pool = createLakebasePool(postgresConnectionOptions({
|
|
107
98
|
user: role,
|
|
108
99
|
workspaceClient: getWorkspaceClient({}),
|
|
109
100
|
connectionTimeoutMillis: CONNECT_TIMEOUT_MS,
|
|
110
101
|
statement_timeout: STATEMENT_TIMEOUT_MS,
|
|
111
|
-
});
|
|
102
|
+
}));
|
|
112
103
|
try {
|
|
113
104
|
const found = await pool.query("SELECT 1 FROM information_schema.schemata WHERE schema_name = $1", [CACHE_SCHEMA]);
|
|
114
105
|
if (found.rowCount === 0) {
|
|
@@ -130,4 +121,4 @@ export async function provisionCacheSchema(role, logger = defaultLogger) {
|
|
|
130
121
|
await pool.end().catch(() => { });
|
|
131
122
|
}
|
|
132
123
|
}
|
|
133
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlzaW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Byb3Zpc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJHO0FBRUgsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGtCQUFrQixFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzdGLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRXpELE1BQU0sYUFBYSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFFOUMseUVBQXlFO0FBQ3pFLE1BQU0sWUFBWSxHQUFHLFFBQVEsQ0FBQztBQUU5Qjs7O0dBR0c7QUFDSCxNQUFNLFlBQVksR0FBRywyQkFBMkIsQ0FBQztBQUVqRDs7OztHQUlHO0FBQ0gsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUM7QUFDbEMsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUM7QUFFcEM7Ozs7OztHQU1HO0FBQ0gsU0FBUyxVQUFVLENBQUMsS0FBYTtJQUMvQixPQUFPLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQztBQUMxQyxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxJQUFZO0lBQy9DLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDN0IsTUFBTSxlQUFlLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsc0JBQXNCLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBQ0QsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ3hDLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNoQyxPQUFPO1FBQ0wsaUNBQWlDLE1BQU0sT0FBTyxNQUFNLEVBQUU7UUFDdEQsZ0RBQWdELE1BQU0sT0FBTyxNQUFNLEVBQUU7UUFDckUsbURBQW1ELE1BQU0sT0FBTyxNQUFNLEVBQUU7UUFDeEUsc0NBQXNDLE1BQU0sMkJBQTJCLE1BQU0sRUFBRTtRQUMvRSxzQ0FBc0MsTUFBTSw4QkFBOEIsTUFBTSxFQUFFO0tBQ25GLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxvQkFBb0IsQ0FDeEMsSUFBd0IsRUFDeEIsU0FBcUIsYUFBYTtJQUVsQyxJQUFJLFdBQVcsQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLENBQUM7UUFDckMsTUFBTSxDQUFDLEtBQUssQ0FBQywyREFBMkQsQ0FBQyxDQUFDO1FBQzFFLE9BQU87SUFDVCxDQUFDO0lBQ0QsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ1YsTUFBTSxDQUFDLElBQUksQ0FBQyxxRUFBcUUsQ0FBQyxDQUFDO1FBQ25GLE9BQU87SUFDVCxDQUFDO0lBQ0QsZ0VBQWdFO0lBQ2hFLDJFQUEyRTtJQUMzRSw4RUFBOEU7SUFDOUUsNkVBQTZFO0lBQzdFLDBFQUEwRTtJQUMxRSxpRkFBaUY7SUFDakYsTUFBTSxJQUFJLEdBQUcsa0JBQWtCLENBQUM7UUFDOUIsSUFBSSxFQUFFLElBQUk7UUFDVixlQUFlLEVBQUUsa0JBQWtCLENBQUMsRUFBRSxDQUFDO1FBQ3ZDLHVCQUF1QixFQUFFLGtCQUFrQjtRQUMzQyxpQkFBaUIsRUFBRSxvQkFBb0I7S0FDeEMsQ0FBQyxDQUFDO0lBQ0gsSUFBSSxDQUFDO1FBQ0gsTUFBTSxLQUFLLEdBQUcsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUM1QixrRUFBa0UsRUFDbEUsQ0FBQyxZQUFZLENBQUMsQ0FDZixDQUFDO1FBQ0YsSUFBSSxLQUFLLENBQUMsUUFBUSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3pCLE1BQU0sQ0FBQyxLQUFLLENBQUMsaURBQWlELEVBQUUsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztZQUMxRixPQUFPO1FBQ1QsQ0FBQztRQUNELEtBQUssTUFBTSxHQUFHLElBQUksb0JBQW9CLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUM3QyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEIsQ0FBQztRQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsOEJBQThCLEVBQUUsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDOUUsQ0FBQztJQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDYixNQUFNLENBQUMsSUFBSSxDQUFDLGdEQUFnRCxFQUFFO1lBQzVELE1BQU0sRUFBRSxZQUFZO1lBQ3BCLEtBQUssRUFBRSxVQUFVLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQztTQUNwQyxDQUFDLENBQUM7SUFDTCxDQUFDO1lBQVMsQ0FBQztRQUNULE1BQU0sSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUMsQ0FBQztJQUNuQyxDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTGFrZWJhc2UgY2FjaGUtc2NoZW1hIGdyYW50IGZpeC11cC5cbiAqXG4gKiBBcHBLaXQncyBwZXJzaXN0ZW50IGNhY2hlIChgQ2FjaGVNYW5hZ2VyYCAtPiBgUGVyc2lzdGVudFN0b3JhZ2VgKSB1c2VzIGFcbiAqIHNjaGVtYSBgYXBwa2l0YCBhbmQgYSB0YWJsZSBgYXBwa2l0LmFwcGtpdF9jYWNoZV9lbnRyaWVzYC4gV2hlbiB0aGUgY29ubmVjdGluZ1xuICogRGF0YWJyaWNrcyBpZGVudGl0eSBsYWNrcyBwcml2aWxlZ2VzIG9uIHRoYXQgc2NoZW1hLCB0aGUgY2FjaGUgbWlncmF0aW9uXG4gKiB0aHJvd3MsIGFuZCBiZWNhdXNlIEFwcEtpdCBpcyB0eXBpY2FsbHkgcnVuIHdpdGggYGNhY2hlLnN0cmljdFBlcnNpc3RlbmNlOlxuICogdHJ1ZWAsIHRoZSBjYWNoZSBpcyBzaWxlbnRseSBzd2l0Y2hlZCB0byBhIGRpc2FibGVkIGluLW1lbW9yeSBzdHViIC0gc28gZXZlcnlcbiAqIHBlcnNpc3RlbnQgcmVhZCAoY2hhcnQgbG9uZy1wb2xsLCBoaXN0b3J5LCBldGMuKSBtaXNzZXMgYW5kIDQwNHMuXG4gKlxuICogVGhpcyBncmFudHMgdGhlIGNvbm5lY3Rpbmcgcm9sZSBmdWxsIHJpZ2h0cyBvbiB0aGUgY2FjaGUgc2NoZW1hLCBidXQgb25seSB3aGVuXG4gKiB0aGUgc2NoZW1hIEFMUkVBRFkgRVhJU1RTIC0gaXQgbmV2ZXIgY3JlYXRlcyB0aGUgc2NoZW1hIGl0c2VsZi4gUnVuIGZyb20gYVxuICogTE9DQUwgaWRlbnRpdHkgdGhhdCBvd25zIHRoZSBzY2hlbWEgKG9yIGhvbGRzIGdyYW50IG9wdGlvbiBvbiBpdCk7IGl0IGlzXG4gKiBza2lwcGVkIGluc2lkZSBhIERhdGFicmlja3MgQXBwLCB3aGVyZSB0aGUgYXBwIFNQIGNhbm5vdCBncmFudCBhbmQgaXRzXG4gKiBQb3N0Z3JlcyByb2xlIGRvZXMgbm90IGV4aXN0IHVudGlsIGl0cyBmaXJzdCBjb25uZWN0aW9uLlxuICpcbiAqIE11c3QgcnVuIEFGVEVSIHtAbGluayBhcHBseUxha2ViYXNlVG9FbnZ9IGhhcyB3cml0dGVuIHRoZSByZXNvbHZlZCBjb25uZWN0aW9uXG4gKiB0byBgcHJvY2Vzcy5lbnZgIChzbyBgY3JlYXRlTGFrZWJhc2VQb29sYCBwaWNrcyB1cCBob3N0IC8gZGF0YWJhc2UgLyBlbmRwb2ludClcbiAqIGFuZCBCRUZPUkUgYGNyZWF0ZUFwcGAgaW5pdGlhbGl6ZXMgdGhlIGNhY2hlLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBjcmVhdGVMYWtlYmFzZVBvb2wsIGdldFdvcmtzcGFjZUNsaWVudCwgVmFsaWRhdGlvbkVycm9yIH0gZnJvbSBcIkBkYXRhYnJpY2tzL2FwcGtpdFwiO1xuaW1wb3J0IHsgY29uZmlnVXRpbHMgfSBmcm9tIFwiQGRieC10b29scy9jb3JlXCI7XG5pbXBvcnQgeyBlcnJvclV0aWxzLCBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuXG5jb25zdCBkZWZhdWx0TG9nZ2VyID0gbG9nLmxvZ2dlcihcInByb3Zpc2lvblwiKTtcblxuLyoqIEFwcEtpdCBwZXJzaXN0ZW50LWNhY2hlIHNjaGVtYSAoc2VlIEFwcEtpdCdzIGBQZXJzaXN0ZW50U3RvcmFnZWApLiAqL1xuY29uc3QgQ0FDSEVfU0NIRU1BID0gXCJhcHBraXRcIjtcblxuLyoqXG4gKiBDaGFyYWN0ZXJzIGEgTGFrZWJhc2UgUG9zdGdyZXMgcm9sZSBjYW4gbGVnaXRpbWF0ZWx5IGNvbnRhaW46IHdvcmtzcGFjZVxuICogaWRlbnRpdGllcyBhcmUgZW1haWxzLCBzZXJ2aWNlIHByaW5jaXBhbHMgYXJlIFVVSURzLlxuICovXG5jb25zdCBST0xFX1BBVFRFUk4gPSAvXltBLVphLXowLTkuX0ArLV17MSwyNTV9JC87XG5cbi8qKlxuICogUHJvdmlzaW9uaW5nIHJ1bnMgYXQgYm9vdCBhcyB0aGUgbG9jYWwgZGV2ZWxvcGVyIGlkZW50aXR5LCBiZWZvcmUgYW55IHBsdWdpblxuICogZXhpc3RzLCBzbyBpdCBpcyBvdXRzaWRlIEFwcEtpdCdzIGludGVyY2VwdG9yIGNoYWluIGFuZCBpbmhlcml0cyBubyB0aW1lb3V0XG4gKiBmcm9tIGl0LiBCb3RoIGJvdW5kcyBhcmUgZXhwbGljaXQgZm9yIHRoYXQgcmVhc29uLlxuICovXG5jb25zdCBDT05ORUNUX1RJTUVPVVRfTVMgPSAxMF8wMDA7XG5jb25zdCBTVEFURU1FTlRfVElNRU9VVF9NUyA9IDE1XzAwMDtcblxuLyoqXG4gKiBRdW90ZSBhIFBvc3RncmVzIGlkZW50aWZpZXI6IHdyYXAgaW4gZG91YmxlIHF1b3RlcyBhbmQgZG91YmxlIGFueSBlbWJlZGRlZFxuICogcXVvdGUuIFNjaGVtYSBhbmQgcm9sZSBuYW1lcyBhcmUgaWRlbnRpZmllcnMsIGFuZCBQb3N0Z3JlcyBkb2VzIG5vdCBhY2NlcHQgYVxuICogYmluZCBwYXJhbWV0ZXIgaW4gYW4gaWRlbnRpZmllciBwb3NpdGlvbiwgc28gcXVvdGluZyBpcyB0aGUgb25seSBkZWZlbnNlXG4gKiBhdmFpbGFibGUgZm9yIHRoZXNlIHN0YXRlbWVudHMuIExha2ViYXNlIHJvbGUgbmFtZXMgYXJlIHVzdWFsbHkgZW1haWxzXG4gKiAoYHVzZXJAaG9zdGApLCB3aGljaCBtdXN0IGJlIHF1b3RlZCB0byBiZSBhIHZhbGlkIGlkZW50aWZpZXIgYXQgYWxsLlxuICovXG5mdW5jdGlvbiBxdW90ZUlkZW50KGlkZW50OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYFwiJHtpZGVudC5yZXBsYWNlKC9cIi9nLCAnXCJcIicpfVwiYDtcbn1cblxuLyoqXG4gKiBJZGVtcG90ZW50IGdyYW50cyB0aGF0IG1ha2UgdGhlIChhbHJlYWR5LWV4aXN0aW5nKSBBcHBLaXQgY2FjaGUgc2NoZW1hIGZ1bGx5XG4gKiB1c2FibGUgYnkgYHJvbGVgLiBUaGUgYEFMVEVSIERFRkFVTFQgUFJJVklMRUdFU2AgbGluZXMgY292ZXIgdGhlIGNhY2hlIHRhYmxlXG4gKiB3aGVuZXZlciB0aGUgc2NoZW1hIG93bmVyIGNyZWF0ZXMgaXQgbGF0ZXIuXG4gKlxuICogVGhyb3dzIGEge0BsaW5rIFZhbGlkYXRpb25FcnJvcn0gd2hlbiBgcm9sZWAgaXMgbm90IGEgcGxhdXNpYmxlIFBvc3RncmVzIHJvbGVcbiAqIG5hbWUsIHNpbmNlIHRoZSB2YWx1ZSBsYW5kcyBpbiBhbiBpZGVudGlmaWVyIHBvc2l0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FjaGVHcmFudFN0YXRlbWVudHMocm9sZTogc3RyaW5nKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICBpZiAoIVJPTEVfUEFUVEVSTi50ZXN0KHJvbGUpKSB7XG4gICAgdGhyb3cgVmFsaWRhdGlvbkVycm9yLmludmFsaWRWYWx1ZShcInJvbGVcIiwgcm9sZSwgXCJhIFBvc3RncmVzIHJvbGUgbmFtZVwiKTtcbiAgfVxuICBjb25zdCBzY2hlbWEgPSBxdW90ZUlkZW50KENBQ0hFX1NDSEVNQSk7XG4gIGNvbnN0IHRhcmdldCA9IHF1b3RlSWRlbnQocm9sZSk7XG4gIHJldHVybiBbXG4gICAgYEdSQU5UIFVTQUdFLCBDUkVBVEUgT04gU0NIRU1BICR7c2NoZW1hfSBUTyAke3RhcmdldH1gLFxuICAgIGBHUkFOVCBBTEwgUFJJVklMRUdFUyBPTiBBTEwgVEFCTEVTIElOIFNDSEVNQSAke3NjaGVtYX0gVE8gJHt0YXJnZXR9YCxcbiAgICBgR1JBTlQgQUxMIFBSSVZJTEVHRVMgT04gQUxMIFNFUVVFTkNFUyBJTiBTQ0hFTUEgJHtzY2hlbWF9IFRPICR7dGFyZ2V0fWAsXG4gICAgYEFMVEVSIERFRkFVTFQgUFJJVklMRUdFUyBJTiBTQ0hFTUEgJHtzY2hlbWF9IEdSQU5UIEFMTCBPTiBUQUJMRVMgVE8gJHt0YXJnZXR9YCxcbiAgICBgQUxURVIgREVGQVVMVCBQUklWSUxFR0VTIElOIFNDSEVNQSAke3NjaGVtYX0gR1JBTlQgQUxMIE9OIFNFUVVFTkNFUyBUTyAke3RhcmdldH1gLFxuICBdO1xufVxuXG4vKipcbiAqIEdyYW50IGByb2xlYCByaWdodHMgb24gdGhlIEFwcEtpdCBjYWNoZSBzY2hlbWEsIGJ1dCBvbmx5IHdoZW4gdGhhdCBzY2hlbWFcbiAqIGFscmVhZHkgZXhpc3RzLlxuICpcbiAqIE5vLW9wcyBpbnNpZGUgYSBEYXRhYnJpY2tzIEFwcCBlbnYsIHdoZW4gYHJvbGVgIGlzIHVuZGVmaW5lZCwgb3Igd2hlbiB0aGVcbiAqIHNjaGVtYSBpcyBhYnNlbnQuIEJlc3QtZWZmb3J0IG90aGVyd2lzZTogYW55IGZhaWx1cmUgKGUuZy4gdGhlIGxvY2FsIGlkZW50aXR5XG4gKiBkb2Vzbid0IG93biB0aGUgc2NoZW1hKSBpcyBsb2dnZWQgYW5kIHN3YWxsb3dlZCBzbyBpdCBuZXZlciBibG9ja3Mgc3RhcnR1cCAtXG4gKiBhIGRpc2FibGVkIGNhY2hlIGlzIGRlZ3JhZGVkLCBub3QgZmF0YWwuXG4gKlxuICogQHBhcmFtIHJvbGUgLSBQb3N0Z3JlcyByb2xlIHRvIGdyYW50IHRvIGFuZCBjb25uZWN0IGFzICh0aGUgcmVzb2x2ZWRcbiAqICAgd29ya3NwYWNlLWNsaWVudCBpZGVudGl0eSk7IHNraXBzIHdoZW4gdW5kZWZpbmVkLlxuICogQHBhcmFtIGxvZ2dlciAtIExvZ2dlciB0byByZXBvcnQgcHJvZ3Jlc3Mgb24uIERlZmF1bHRzIHRvIHRoaXMgbW9kdWxlJ3MuXG4gKlxuICogQGV4YW1wbGVcbiAqIGltcG9ydCB7IHByb3Zpc2lvbiB9IGZyb20gXCJAZGJ4LXRvb2xzL2FwcGtpdFwiO1xuICpcbiAqIGF3YWl0IHByb3Zpc2lvbi5wcm92aXNpb25DYWNoZVNjaGVtYShcImFwcC1zZXJ2aWNlLXByaW5jaXBhbEBkYXRhYnJpY2tzLmNvbVwiKTtcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHByb3Zpc2lvbkNhY2hlU2NoZW1hKFxuICByb2xlOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIGxvZ2dlcjogbG9nLkxvZ2dlciA9IGRlZmF1bHRMb2dnZXIsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKGNvbmZpZ1V0aWxzLmlzRGF0YWJyaWNrc0FwcEVudigpKSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwiYXV0b3BnOiBza2lwIGNhY2hlIHByb3Zpc2lvbmluZyAoaW5zaWRlIGEgRGF0YWJyaWNrcyBBcHApXCIpO1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoIXJvbGUpIHtcbiAgICBsb2dnZXIud2FybihcImF1dG9wZzogc2tpcCBjYWNoZSBwcm92aXNpb25pbmcgKGNvdWxkIG5vdCByZXNvbHZlIGNvbm5lY3Rpbmcgcm9sZSlcIik7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIFBhc3MgYHVzZXJgIGV4cGxpY2l0bHk6IGF1dG9wZyByZXNvbHZlcyB0aGUgY29ubmVjdGlvbiB0YXJnZXRcbiAgLy8gKGhvc3QvZGF0YWJhc2UvZW5kcG9pbnQpIGJ1dCBub3QgdGhlIGlkZW50aXR5LCBzbyBgY3JlYXRlTGFrZWJhc2VQb29sYCdzXG4gIC8vIHN5bmNocm9ub3VzIHVzZXJuYW1lIGxvb2t1cCB3b3VsZCBvdGhlcndpc2UgdGhyb3cuIGBnZXRXb3Jrc3BhY2VDbGllbnQoe30pYFxuICAvLyByZXR1cm5zIGEgZnJlc2ggZGVmYXVsdC1hdXRoIGNsaWVudCAtIGxpdGVyYWxseSBgbmV3IFdvcmtzcGFjZUNsaWVudCh7fSlgLFxuICAvLyBidXQgYnVpbHQgYWdhaW5zdCB0aGUgU0RLIHZlcnNpb24gQXBwS2l0J3MgYGNyZWF0ZUxha2ViYXNlUG9vbGAgZXhwZWN0c1xuICAvLyAoaW1wb3J0aW5nIHRoZSBTREsgY2xhc3MgZGlyZWN0bHkgaGVyZSBwdWxscyBhIG5ld2VyLCB0eXBlLWluY29tcGF0aWJsZSBjb3B5KS5cbiAgY29uc3QgcG9vbCA9IGNyZWF0ZUxha2ViYXNlUG9vbCh7XG4gICAgdXNlcjogcm9sZSxcbiAgICB3b3Jrc3BhY2VDbGllbnQ6IGdldFdvcmtzcGFjZUNsaWVudCh7fSksXG4gICAgY29ubmVjdGlvblRpbWVvdXRNaWxsaXM6IENPTk5FQ1RfVElNRU9VVF9NUyxcbiAgICBzdGF0ZW1lbnRfdGltZW91dDogU1RBVEVNRU5UX1RJTUVPVVRfTVMsXG4gIH0pO1xuICB0cnkge1xuICAgIGNvbnN0IGZvdW5kID0gYXdhaXQgcG9vbC5xdWVyeShcbiAgICAgIFwiU0VMRUNUIDEgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEuc2NoZW1hdGEgV0hFUkUgc2NoZW1hX25hbWUgPSAkMVwiLFxuICAgICAgW0NBQ0hFX1NDSEVNQV0sXG4gICAgKTtcbiAgICBpZiAoZm91bmQucm93Q291bnQgPT09IDApIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcImF1dG9wZzogc2tpcCBjYWNoZSBwcm92aXNpb25pbmcgKHNjaGVtYSBhYnNlbnQpXCIsIHsgc2NoZW1hOiBDQUNIRV9TQ0hFTUEgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvciAoY29uc3Qgc3FsIG9mIGNhY2hlR3JhbnRTdGF0ZW1lbnRzKHJvbGUpKSB7XG4gICAgICBhd2FpdCBwb29sLnF1ZXJ5KHNxbCk7XG4gICAgfVxuICAgIGxvZ2dlci5pbmZvKFwiYXV0b3BnOiBncmFudGVkIGNhY2hlIHNjaGVtYVwiLCB7IHNjaGVtYTogQ0FDSEVfU0NIRU1BLCByb2xlIH0pO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2dnZXIud2FybihcImF1dG9wZzogY2FjaGUgcHJvdmlzaW9uaW5nIGZhaWxlZCAoY29udGludWluZylcIiwge1xuICAgICAgc2NoZW1hOiBDQUNIRV9TQ0hFTUEsXG4gICAgICBlcnJvcjogZXJyb3JVdGlscy5lcnJvck1lc3NhZ2UoZXJyKSxcbiAgICB9KTtcbiAgfSBmaW5hbGx5IHtcbiAgICBhd2FpdCBwb29sLmVuZCgpLmNhdGNoKCgpID0+IHt9KTtcbiAgfVxufVxuIl19
|
|
124
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlzaW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Byb3Zpc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJHO0FBRUgsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGtCQUFrQixFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzdGLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM5QyxPQUFPLEVBQUUseUJBQXlCLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN6RixPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRXpELE1BQU0sYUFBYSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFFOUMseUVBQXlFO0FBQ3pFLE1BQU0sWUFBWSxHQUFHLFFBQVEsQ0FBQztBQUU5Qjs7O0dBR0c7QUFDSCxNQUFNLFlBQVksR0FBRywyQkFBMkIsQ0FBQztBQUVqRDs7OztHQUlHO0FBQ0gsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUM7QUFDbEMsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUM7QUFFcEM7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxJQUFZO0lBQy9DLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDN0IsTUFBTSxlQUFlLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsc0JBQXNCLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBQ0QsTUFBTSxNQUFNLEdBQUcsdUJBQXVCLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDckQsTUFBTSxNQUFNLEdBQUcsdUJBQXVCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDN0MsT0FBTztRQUNMLGlDQUFpQyxNQUFNLE9BQU8sTUFBTSxFQUFFO1FBQ3RELGdEQUFnRCxNQUFNLE9BQU8sTUFBTSxFQUFFO1FBQ3JFLG1EQUFtRCxNQUFNLE9BQU8sTUFBTSxFQUFFO1FBQ3hFLHNDQUFzQyxNQUFNLDJCQUEyQixNQUFNLEVBQUU7UUFDL0Usc0NBQXNDLE1BQU0sOEJBQThCLE1BQU0sRUFBRTtLQUNuRixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsb0JBQW9CLENBQ3hDLElBQXdCLEVBQ3hCLFNBQXFCLGFBQWE7SUFFbEMsSUFBSSxXQUFXLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxDQUFDO1FBQ3JDLE1BQU0sQ0FBQyxLQUFLLENBQUMsMkRBQTJELENBQUMsQ0FBQztRQUMxRSxPQUFPO0lBQ1QsQ0FBQztJQUNELElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNWLE1BQU0sQ0FBQyxJQUFJLENBQUMscUVBQXFFLENBQUMsQ0FBQztRQUNuRixPQUFPO0lBQ1QsQ0FBQztJQUNELGdFQUFnRTtJQUNoRSwyRUFBMkU7SUFDM0UsOEVBQThFO0lBQzlFLDZFQUE2RTtJQUM3RSwwRUFBMEU7SUFDMUUsaUZBQWlGO0lBQ2pGLE1BQU0sSUFBSSxHQUFHLGtCQUFrQixDQUM3Qix5QkFBeUIsQ0FBQztRQUN4QixJQUFJLEVBQUUsSUFBSTtRQUNWLGVBQWUsRUFBRSxrQkFBa0IsQ0FBQyxFQUFFLENBQUM7UUFDdkMsdUJBQXVCLEVBQUUsa0JBQWtCO1FBQzNDLGlCQUFpQixFQUFFLG9CQUFvQjtLQUN4QyxDQUFDLENBQ0gsQ0FBQztJQUNGLElBQUksQ0FBQztRQUNILE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FDNUIsa0VBQWtFLEVBQ2xFLENBQUMsWUFBWSxDQUFDLENBQ2YsQ0FBQztRQUNGLElBQUksS0FBSyxDQUFDLFFBQVEsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN6QixNQUFNLENBQUMsS0FBSyxDQUFDLGlEQUFpRCxFQUFFLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7WUFDMUYsT0FBTztRQUNULENBQUM7UUFDRCxLQUFLLE1BQU0sR0FBRyxJQUFJLG9CQUFvQixDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDN0MsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3hCLENBQUM7UUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLDhCQUE4QixFQUFFLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzlFLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsTUFBTSxDQUFDLElBQUksQ0FBQyxnREFBZ0QsRUFBRTtZQUM1RCxNQUFNLEVBQUUsWUFBWTtZQUNwQixLQUFLLEVBQUUsVUFBVSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUM7U0FDcEMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztZQUFTLENBQUM7UUFDVCxNQUFNLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDLENBQUM7SUFDbkMsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIExha2ViYXNlIGNhY2hlLXNjaGVtYSBncmFudCBmaXgtdXAuXG4gKlxuICogQXBwS2l0J3MgcGVyc2lzdGVudCBjYWNoZSAoYENhY2hlTWFuYWdlcmAgLT4gYFBlcnNpc3RlbnRTdG9yYWdlYCkgdXNlcyBhXG4gKiBzY2hlbWEgYGFwcGtpdGAgYW5kIGEgdGFibGUgYGFwcGtpdC5hcHBraXRfY2FjaGVfZW50cmllc2AuIFdoZW4gdGhlIGNvbm5lY3RpbmdcbiAqIERhdGFicmlja3MgaWRlbnRpdHkgbGFja3MgcHJpdmlsZWdlcyBvbiB0aGF0IHNjaGVtYSwgdGhlIGNhY2hlIG1pZ3JhdGlvblxuICogdGhyb3dzLCBhbmQgYmVjYXVzZSBBcHBLaXQgaXMgdHlwaWNhbGx5IHJ1biB3aXRoIGBjYWNoZS5zdHJpY3RQZXJzaXN0ZW5jZTpcbiAqIHRydWVgLCB0aGUgY2FjaGUgaXMgc2lsZW50bHkgc3dpdGNoZWQgdG8gYSBkaXNhYmxlZCBpbi1tZW1vcnkgc3R1YiAtIHNvIGV2ZXJ5XG4gKiBwZXJzaXN0ZW50IHJlYWQgKGNoYXJ0IGxvbmctcG9sbCwgaGlzdG9yeSwgZXRjLikgbWlzc2VzIGFuZCA0MDRzLlxuICpcbiAqIFRoaXMgZ3JhbnRzIHRoZSBjb25uZWN0aW5nIHJvbGUgZnVsbCByaWdodHMgb24gdGhlIGNhY2hlIHNjaGVtYSwgYnV0IG9ubHkgd2hlblxuICogdGhlIHNjaGVtYSBBTFJFQURZIEVYSVNUUyAtIGl0IG5ldmVyIGNyZWF0ZXMgdGhlIHNjaGVtYSBpdHNlbGYuIFJ1biBmcm9tIGFcbiAqIExPQ0FMIGlkZW50aXR5IHRoYXQgb3ducyB0aGUgc2NoZW1hIChvciBob2xkcyBncmFudCBvcHRpb24gb24gaXQpOyBpdCBpc1xuICogc2tpcHBlZCBpbnNpZGUgYSBEYXRhYnJpY2tzIEFwcCwgd2hlcmUgdGhlIGFwcCBTUCBjYW5ub3QgZ3JhbnQgYW5kIGl0c1xuICogUG9zdGdyZXMgcm9sZSBkb2VzIG5vdCBleGlzdCB1bnRpbCBpdHMgZmlyc3QgY29ubmVjdGlvbi5cbiAqXG4gKiBNdXN0IHJ1biBBRlRFUiB7QGxpbmsgYXBwbHlMYWtlYmFzZVRvRW52fSBoYXMgd3JpdHRlbiB0aGUgcmVzb2x2ZWQgY29ubmVjdGlvblxuICogdG8gYHByb2Nlc3MuZW52YCAoc28gYGNyZWF0ZUxha2ViYXNlUG9vbGAgcGlja3MgdXAgaG9zdCAvIGRhdGFiYXNlIC8gZW5kcG9pbnQpXG4gKiBhbmQgQkVGT1JFIGBjcmVhdGVBcHBgIGluaXRpYWxpemVzIHRoZSBjYWNoZS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgY3JlYXRlTGFrZWJhc2VQb29sLCBnZXRXb3Jrc3BhY2VDbGllbnQsIFZhbGlkYXRpb25FcnJvciB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7IGNvbmZpZ1V0aWxzIH0gZnJvbSBcIkBkYngtdG9vbHMvY29yZVwiO1xuaW1wb3J0IHsgcG9zdGdyZXNDb25uZWN0aW9uT3B0aW9ucywgcXVvdGVQb3N0Z3Jlc0lkZW50aWZpZXIgfSBmcm9tIFwiQGRieC10b29scy9wb3N0Z3Jlc1wiO1xuaW1wb3J0IHsgZXJyb3JVdGlscywgbG9nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcblxuY29uc3QgZGVmYXVsdExvZ2dlciA9IGxvZy5sb2dnZXIoXCJwcm92aXNpb25cIik7XG5cbi8qKiBBcHBLaXQgcGVyc2lzdGVudC1jYWNoZSBzY2hlbWEgKHNlZSBBcHBLaXQncyBgUGVyc2lzdGVudFN0b3JhZ2VgKS4gKi9cbmNvbnN0IENBQ0hFX1NDSEVNQSA9IFwiYXBwa2l0XCI7XG5cbi8qKlxuICogQ2hhcmFjdGVycyBhIExha2ViYXNlIFBvc3RncmVzIHJvbGUgY2FuIGxlZ2l0aW1hdGVseSBjb250YWluOiB3b3Jrc3BhY2VcbiAqIGlkZW50aXRpZXMgYXJlIGVtYWlscywgc2VydmljZSBwcmluY2lwYWxzIGFyZSBVVUlEcy5cbiAqL1xuY29uc3QgUk9MRV9QQVRURVJOID0gL15bQS1aYS16MC05Ll9AKy1dezEsMjU1fSQvO1xuXG4vKipcbiAqIFByb3Zpc2lvbmluZyBydW5zIGF0IGJvb3QgYXMgdGhlIGxvY2FsIGRldmVsb3BlciBpZGVudGl0eSwgYmVmb3JlIGFueSBwbHVnaW5cbiAqIGV4aXN0cywgc28gaXQgaXMgb3V0c2lkZSBBcHBLaXQncyBpbnRlcmNlcHRvciBjaGFpbiBhbmQgaW5oZXJpdHMgbm8gdGltZW91dFxuICogZnJvbSBpdC4gQm90aCBib3VuZHMgYXJlIGV4cGxpY2l0IGZvciB0aGF0IHJlYXNvbi5cbiAqL1xuY29uc3QgQ09OTkVDVF9USU1FT1VUX01TID0gMTBfMDAwO1xuY29uc3QgU1RBVEVNRU5UX1RJTUVPVVRfTVMgPSAxNV8wMDA7XG5cbi8qKlxuICogSWRlbXBvdGVudCBncmFudHMgdGhhdCBtYWtlIHRoZSAoYWxyZWFkeS1leGlzdGluZykgQXBwS2l0IGNhY2hlIHNjaGVtYSBmdWxseVxuICogdXNhYmxlIGJ5IGByb2xlYC4gVGhlIGBBTFRFUiBERUZBVUxUIFBSSVZJTEVHRVNgIGxpbmVzIGNvdmVyIHRoZSBjYWNoZSB0YWJsZVxuICogd2hlbmV2ZXIgdGhlIHNjaGVtYSBvd25lciBjcmVhdGVzIGl0IGxhdGVyLlxuICpcbiAqIFRocm93cyBhIHtAbGluayBWYWxpZGF0aW9uRXJyb3J9IHdoZW4gYHJvbGVgIGlzIG5vdCBhIHBsYXVzaWJsZSBQb3N0Z3JlcyByb2xlXG4gKiBuYW1lLCBzaW5jZSB0aGUgdmFsdWUgbGFuZHMgaW4gYW4gaWRlbnRpZmllciBwb3NpdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhY2hlR3JhbnRTdGF0ZW1lbnRzKHJvbGU6IHN0cmluZyk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgaWYgKCFST0xFX1BBVFRFUk4udGVzdChyb2xlKSkge1xuICAgIHRocm93IFZhbGlkYXRpb25FcnJvci5pbnZhbGlkVmFsdWUoXCJyb2xlXCIsIHJvbGUsIFwiYSBQb3N0Z3JlcyByb2xlIG5hbWVcIik7XG4gIH1cbiAgY29uc3Qgc2NoZW1hID0gcXVvdGVQb3N0Z3Jlc0lkZW50aWZpZXIoQ0FDSEVfU0NIRU1BKTtcbiAgY29uc3QgdGFyZ2V0ID0gcXVvdGVQb3N0Z3Jlc0lkZW50aWZpZXIocm9sZSk7XG4gIHJldHVybiBbXG4gICAgYEdSQU5UIFVTQUdFLCBDUkVBVEUgT04gU0NIRU1BICR7c2NoZW1hfSBUTyAke3RhcmdldH1gLFxuICAgIGBHUkFOVCBBTEwgUFJJVklMRUdFUyBPTiBBTEwgVEFCTEVTIElOIFNDSEVNQSAke3NjaGVtYX0gVE8gJHt0YXJnZXR9YCxcbiAgICBgR1JBTlQgQUxMIFBSSVZJTEVHRVMgT04gQUxMIFNFUVVFTkNFUyBJTiBTQ0hFTUEgJHtzY2hlbWF9IFRPICR7dGFyZ2V0fWAsXG4gICAgYEFMVEVSIERFRkFVTFQgUFJJVklMRUdFUyBJTiBTQ0hFTUEgJHtzY2hlbWF9IEdSQU5UIEFMTCBPTiBUQUJMRVMgVE8gJHt0YXJnZXR9YCxcbiAgICBgQUxURVIgREVGQVVMVCBQUklWSUxFR0VTIElOIFNDSEVNQSAke3NjaGVtYX0gR1JBTlQgQUxMIE9OIFNFUVVFTkNFUyBUTyAke3RhcmdldH1gLFxuICBdO1xufVxuXG4vKipcbiAqIEdyYW50IGByb2xlYCByaWdodHMgb24gdGhlIEFwcEtpdCBjYWNoZSBzY2hlbWEsIGJ1dCBvbmx5IHdoZW4gdGhhdCBzY2hlbWFcbiAqIGFscmVhZHkgZXhpc3RzLlxuICpcbiAqIE5vLW9wcyBpbnNpZGUgYSBEYXRhYnJpY2tzIEFwcCBlbnYsIHdoZW4gYHJvbGVgIGlzIHVuZGVmaW5lZCwgb3Igd2hlbiB0aGVcbiAqIHNjaGVtYSBpcyBhYnNlbnQuIEJlc3QtZWZmb3J0IG90aGVyd2lzZTogYW55IGZhaWx1cmUgKGUuZy4gdGhlIGxvY2FsIGlkZW50aXR5XG4gKiBkb2Vzbid0IG93biB0aGUgc2NoZW1hKSBpcyBsb2dnZWQgYW5kIHN3YWxsb3dlZCBzbyBpdCBuZXZlciBibG9ja3Mgc3RhcnR1cCAtXG4gKiBhIGRpc2FibGVkIGNhY2hlIGlzIGRlZ3JhZGVkLCBub3QgZmF0YWwuXG4gKlxuICogQHBhcmFtIHJvbGUgLSBQb3N0Z3JlcyByb2xlIHRvIGdyYW50IHRvIGFuZCBjb25uZWN0IGFzICh0aGUgcmVzb2x2ZWRcbiAqICAgd29ya3NwYWNlLWNsaWVudCBpZGVudGl0eSk7IHNraXBzIHdoZW4gdW5kZWZpbmVkLlxuICogQHBhcmFtIGxvZ2dlciAtIExvZ2dlciB0byByZXBvcnQgcHJvZ3Jlc3Mgb24uIERlZmF1bHRzIHRvIHRoaXMgbW9kdWxlJ3MuXG4gKlxuICogQGV4YW1wbGVcbiAqIGltcG9ydCB7IHByb3Zpc2lvbiB9IGZyb20gXCJAZGJ4LXRvb2xzL2FwcGtpdFwiO1xuICpcbiAqIGF3YWl0IHByb3Zpc2lvbi5wcm92aXNpb25DYWNoZVNjaGVtYShcImFwcC1zZXJ2aWNlLXByaW5jaXBhbEBkYXRhYnJpY2tzLmNvbVwiKTtcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHByb3Zpc2lvbkNhY2hlU2NoZW1hKFxuICByb2xlOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIGxvZ2dlcjogbG9nLkxvZ2dlciA9IGRlZmF1bHRMb2dnZXIsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKGNvbmZpZ1V0aWxzLmlzRGF0YWJyaWNrc0FwcEVudigpKSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwiYXV0b3BnOiBza2lwIGNhY2hlIHByb3Zpc2lvbmluZyAoaW5zaWRlIGEgRGF0YWJyaWNrcyBBcHApXCIpO1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoIXJvbGUpIHtcbiAgICBsb2dnZXIud2FybihcImF1dG9wZzogc2tpcCBjYWNoZSBwcm92aXNpb25pbmcgKGNvdWxkIG5vdCByZXNvbHZlIGNvbm5lY3Rpbmcgcm9sZSlcIik7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIFBhc3MgYHVzZXJgIGV4cGxpY2l0bHk6IGF1dG9wZyByZXNvbHZlcyB0aGUgY29ubmVjdGlvbiB0YXJnZXRcbiAgLy8gKGhvc3QvZGF0YWJhc2UvZW5kcG9pbnQpIGJ1dCBub3QgdGhlIGlkZW50aXR5LCBzbyBgY3JlYXRlTGFrZWJhc2VQb29sYCdzXG4gIC8vIHN5bmNocm9ub3VzIHVzZXJuYW1lIGxvb2t1cCB3b3VsZCBvdGhlcndpc2UgdGhyb3cuIGBnZXRXb3Jrc3BhY2VDbGllbnQoe30pYFxuICAvLyByZXR1cm5zIGEgZnJlc2ggZGVmYXVsdC1hdXRoIGNsaWVudCAtIGxpdGVyYWxseSBgbmV3IFdvcmtzcGFjZUNsaWVudCh7fSlgLFxuICAvLyBidXQgYnVpbHQgYWdhaW5zdCB0aGUgU0RLIHZlcnNpb24gQXBwS2l0J3MgYGNyZWF0ZUxha2ViYXNlUG9vbGAgZXhwZWN0c1xuICAvLyAoaW1wb3J0aW5nIHRoZSBTREsgY2xhc3MgZGlyZWN0bHkgaGVyZSBwdWxscyBhIG5ld2VyLCB0eXBlLWluY29tcGF0aWJsZSBjb3B5KS5cbiAgY29uc3QgcG9vbCA9IGNyZWF0ZUxha2ViYXNlUG9vbChcbiAgICBwb3N0Z3Jlc0Nvbm5lY3Rpb25PcHRpb25zKHtcbiAgICAgIHVzZXI6IHJvbGUsXG4gICAgICB3b3Jrc3BhY2VDbGllbnQ6IGdldFdvcmtzcGFjZUNsaWVudCh7fSksXG4gICAgICBjb25uZWN0aW9uVGltZW91dE1pbGxpczogQ09OTkVDVF9USU1FT1VUX01TLFxuICAgICAgc3RhdGVtZW50X3RpbWVvdXQ6IFNUQVRFTUVOVF9USU1FT1VUX01TLFxuICAgIH0pLFxuICApO1xuICB0cnkge1xuICAgIGNvbnN0IGZvdW5kID0gYXdhaXQgcG9vbC5xdWVyeShcbiAgICAgIFwiU0VMRUNUIDEgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEuc2NoZW1hdGEgV0hFUkUgc2NoZW1hX25hbWUgPSAkMVwiLFxuICAgICAgW0NBQ0hFX1NDSEVNQV0sXG4gICAgKTtcbiAgICBpZiAoZm91bmQucm93Q291bnQgPT09IDApIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcImF1dG9wZzogc2tpcCBjYWNoZSBwcm92aXNpb25pbmcgKHNjaGVtYSBhYnNlbnQpXCIsIHsgc2NoZW1hOiBDQUNIRV9TQ0hFTUEgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvciAoY29uc3Qgc3FsIG9mIGNhY2hlR3JhbnRTdGF0ZW1lbnRzKHJvbGUpKSB7XG4gICAgICBhd2FpdCBwb29sLnF1ZXJ5KHNxbCk7XG4gICAgfVxuICAgIGxvZ2dlci5pbmZvKFwiYXV0b3BnOiBncmFudGVkIGNhY2hlIHNjaGVtYVwiLCB7IHNjaGVtYTogQ0FDSEVfU0NIRU1BLCByb2xlIH0pO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2dnZXIud2FybihcImF1dG9wZzogY2FjaGUgcHJvdmlzaW9uaW5nIGZhaWxlZCAoY29udGludWluZylcIiwge1xuICAgICAgc2NoZW1hOiBDQUNIRV9TQ0hFTUEsXG4gICAgICBlcnJvcjogZXJyb3JVdGlscy5lcnJvck1lc3NhZ2UoZXJyKSxcbiAgICB9KTtcbiAgfSBmaW5hbGx5IHtcbiAgICBhd2FpdCBwb29sLmVuZCgpLmNhdGNoKCgpID0+IHt9KTtcbiAgfVxufVxuIl19
|
package/lib/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/_auto-configure.ts","../src/_cache-storage.ts","../src/appkit.ts","../src/brand-context.ts","../src/bundle.ts","../src/databricks.ts","../src/identity.ts","../src/interceptor.ts","../src/lakebase-resolver.ts","../src/migration.ts","../src/pgaddress.ts","../src/plugin-execution.ts","../src/plugin-registry.ts","../src/provision.ts","../src/tool-provider.ts","../src/toolkit-entries.ts","../index.ts"],"version":"5.9.3"}
|
|
1
|
+
{"root":["../src/_auto-configure.ts","../src/_cache-storage.ts","../src/appkit.ts","../src/brand-context.ts","../src/bundle.ts","../src/child-process.ts","../src/databricks.ts","../src/identity.ts","../src/interceptor.ts","../src/lakebase-resolver.ts","../src/migration.ts","../src/pgaddress.ts","../src/plugin-execution.ts","../src/plugin-registry.ts","../src/provision.ts","../src/tool-provider.ts","../src/toolkit-entries.ts","../index.ts"],"version":"5.9.3"}
|
package/package.json
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@databricks/appkit": "0.81.0",
|
|
23
|
-
"@dbx-tools/projen": "^0.9.
|
|
23
|
+
"@dbx-tools/projen": "^0.9.60",
|
|
24
24
|
"@types/node": "^24.6.0",
|
|
25
25
|
"typescript": "^5.9.3",
|
|
26
26
|
"vitest": "3.2.4"
|
|
@@ -30,10 +30,11 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@databricks/sdk-experimental": "^0.17.0",
|
|
33
|
-
"@dbx-tools/auth": "^0.9.
|
|
34
|
-
"@dbx-tools/core": "^0.9.
|
|
35
|
-
"@dbx-tools/lakebase": "^0.9.
|
|
36
|
-
"@dbx-tools/
|
|
33
|
+
"@dbx-tools/auth": "^0.9.60",
|
|
34
|
+
"@dbx-tools/core": "^0.9.60",
|
|
35
|
+
"@dbx-tools/lakebase": "^0.9.60",
|
|
36
|
+
"@dbx-tools/postgres": "^0.9.60",
|
|
37
|
+
"@dbx-tools/shared-core": "^0.9.60",
|
|
37
38
|
"zod": "4.3.6"
|
|
38
39
|
},
|
|
39
40
|
"main": "./lib/index.js",
|
|
@@ -59,6 +60,10 @@
|
|
|
59
60
|
"types": "./lib/src/bundle.d.ts",
|
|
60
61
|
"default": "./lib/src/bundle.js"
|
|
61
62
|
},
|
|
63
|
+
"./child-process": {
|
|
64
|
+
"types": "./lib/src/child-process.d.ts",
|
|
65
|
+
"default": "./lib/src/child-process.js"
|
|
66
|
+
},
|
|
62
67
|
"./databricks": {
|
|
63
68
|
"types": "./lib/src/databricks.d.ts",
|
|
64
69
|
"default": "./lib/src/databricks.js"
|
|
@@ -106,7 +111,7 @@
|
|
|
106
111
|
"./package.json": "./package.json"
|
|
107
112
|
}
|
|
108
113
|
},
|
|
109
|
-
"version": "0.9.
|
|
114
|
+
"version": "0.9.60",
|
|
110
115
|
"types": "./lib/index.d.ts",
|
|
111
116
|
"dbxToolsConfig": {
|
|
112
117
|
"tags": [
|
|
@@ -131,6 +136,10 @@
|
|
|
131
136
|
"types": "./lib/src/bundle.d.ts",
|
|
132
137
|
"default": "./lib/src/bundle.js"
|
|
133
138
|
},
|
|
139
|
+
"./child-process": {
|
|
140
|
+
"types": "./lib/src/child-process.d.ts",
|
|
141
|
+
"default": "./lib/src/child-process.js"
|
|
142
|
+
},
|
|
134
143
|
"./databricks": {
|
|
135
144
|
"types": "./lib/src/databricks.d.ts",
|
|
136
145
|
"default": "./lib/src/databricks.js"
|
package/src/_cache-storage.ts
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import { createRequire } from "node:module";
|
|
18
18
|
import { dirname, join } from "node:path";
|
|
19
19
|
import { createLakebasePool, getWorkspaceClient, type CacheConfig } from "@databricks/appkit";
|
|
20
|
+
import { postgresConnectionOptions } from "@dbx-tools/postgres";
|
|
20
21
|
import { errorUtils, hash, log } from "@dbx-tools/shared-core";
|
|
21
22
|
import { handleOwnershipMigrationError } from "./migration.ts";
|
|
22
23
|
|
|
@@ -163,7 +164,9 @@ export async function createSoftPersistentStorage(
|
|
|
163
164
|
|
|
164
165
|
let pool: LakebasePool | undefined;
|
|
165
166
|
try {
|
|
166
|
-
const createdPool = createLakebasePool(
|
|
167
|
+
const createdPool = createLakebasePool(
|
|
168
|
+
postgresConnectionOptions({ workspaceClient: getWorkspaceClient({}) }),
|
|
169
|
+
);
|
|
167
170
|
pool = createdPool;
|
|
168
171
|
const storage = new PersistentStorage(cache ?? {}, createdPool);
|
|
169
172
|
softenInitialize(storage, () => tableOwnedByAnotherRole(storage, createdPool));
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AppKit child-process lifecycle built on `@dbx-tools/core/exec`.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import * as exec from "@dbx-tools/core/exec";
|
|
7
|
+
|
|
8
|
+
/** Spawn arguments accepted by {@link AppKitChildProcess}. */
|
|
9
|
+
export type AppKitSpawnArgs = exec.SpawnArgs<exec.ExecOptions>;
|
|
10
|
+
|
|
11
|
+
/** Graceful and forced shutdown policy for an AppKit child process. */
|
|
12
|
+
export interface AppKitChildProcessOptions {
|
|
13
|
+
/** Signal sent when shutdown starts. Defaults to `SIGTERM`. */
|
|
14
|
+
gracefulSignal?: NodeJS.Signals;
|
|
15
|
+
/** Time to wait after the graceful signal. Defaults to 7 seconds. */
|
|
16
|
+
gracefulTimeoutMs?: number;
|
|
17
|
+
/** Signal sent when graceful shutdown times out. Defaults to `SIGKILL`. */
|
|
18
|
+
forceSignal?: NodeJS.Signals;
|
|
19
|
+
/** Time to wait after the force signal. Defaults to 1 second. */
|
|
20
|
+
forceTimeoutMs?: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Start and stop one AppKit-owned subprocess.
|
|
25
|
+
*
|
|
26
|
+
* The spawn arguments use {@link exec.ExecOptions}, including core exec's
|
|
27
|
+
* stdin, output capture, line handlers, exit checking, and trim policy.
|
|
28
|
+
* Shutdown is idempotent and escalates from the graceful signal to the force
|
|
29
|
+
* signal when the child does not exit within the configured timeouts.
|
|
30
|
+
*/
|
|
31
|
+
export class AppKitChildProcess {
|
|
32
|
+
readonly #spawnArgs: AppKitSpawnArgs;
|
|
33
|
+
readonly #options: Required<AppKitChildProcessOptions>;
|
|
34
|
+
readonly #detached: boolean;
|
|
35
|
+
|
|
36
|
+
#child?: exec.ChildProcessResult;
|
|
37
|
+
#shutdownPromise?: Promise<void>;
|
|
38
|
+
|
|
39
|
+
constructor(spawnArgs: AppKitSpawnArgs, options: AppKitChildProcessOptions = {}) {
|
|
40
|
+
this.#spawnArgs = spawnArgs;
|
|
41
|
+
this.#options = {
|
|
42
|
+
gracefulSignal: options.gracefulSignal ?? "SIGTERM",
|
|
43
|
+
gracefulTimeoutMs: options.gracefulTimeoutMs ?? 7_000,
|
|
44
|
+
forceSignal: options.forceSignal ?? "SIGKILL",
|
|
45
|
+
forceTimeoutMs: options.forceTimeoutMs ?? 1_000,
|
|
46
|
+
};
|
|
47
|
+
this.#detached = spawnOptions(spawnArgs)?.detached === true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Current child handle, or `undefined` when no child is running. */
|
|
51
|
+
get process(): exec.ChildProcessResult | undefined {
|
|
52
|
+
return this.#child;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Whether the current child has not reported an exit code or signal. */
|
|
56
|
+
get running(): boolean {
|
|
57
|
+
return this.#child !== undefined && !hasExited(this.#child);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Start the configured child process. */
|
|
61
|
+
start(): exec.ChildProcessResult {
|
|
62
|
+
if (this.running) throw new Error("Child process is already running");
|
|
63
|
+
if (this.#shutdownPromise) {
|
|
64
|
+
throw new Error("Child process is shutting down or has been shut down");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const child = exec.spawn(...this.#spawnArgs);
|
|
68
|
+
this.#child = child;
|
|
69
|
+
void child.once("close", () => {
|
|
70
|
+
if (this.#child === child) this.#child = undefined;
|
|
71
|
+
});
|
|
72
|
+
return child;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Stop the child once, escalating when graceful shutdown times out. */
|
|
76
|
+
shutdown(): Promise<void> {
|
|
77
|
+
this.#shutdownPromise ??= this.#performShutdown();
|
|
78
|
+
return this.#shutdownPromise;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async #performShutdown(): Promise<void> {
|
|
82
|
+
const child = this.#child;
|
|
83
|
+
if (!child || hasExited(child)) {
|
|
84
|
+
this.#child = undefined;
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
signalChild(child, this.#options.gracefulSignal, this.#detached);
|
|
89
|
+
if (await waitForExit(child, this.#options.gracefulTimeoutMs)) {
|
|
90
|
+
if (this.#child === child) this.#child = undefined;
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
signalChild(child, this.#options.forceSignal, this.#detached);
|
|
95
|
+
if (!(await waitForExit(child, this.#options.forceTimeoutMs))) {
|
|
96
|
+
throw new Error(`Child process ${child.pid ?? "<unknown>"} did not terminate`);
|
|
97
|
+
}
|
|
98
|
+
if (this.#child === child) this.#child = undefined;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function spawnOptions(args: AppKitSpawnArgs): exec.ExecOptions | undefined {
|
|
103
|
+
const value = args.at(-1);
|
|
104
|
+
return isExecOptions(value) ? value : undefined;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function isExecOptions(value: unknown): value is exec.ExecOptions {
|
|
108
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function hasExited(child: exec.ChildProcessResult): boolean {
|
|
112
|
+
return child.exitCode !== null || child.signalCode !== null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function signalChild(
|
|
116
|
+
child: exec.ChildProcessResult,
|
|
117
|
+
signal: NodeJS.Signals,
|
|
118
|
+
detached: boolean,
|
|
119
|
+
): void {
|
|
120
|
+
if (detached && process.platform !== "win32" && child.pid) {
|
|
121
|
+
try {
|
|
122
|
+
process.kill(-child.pid, signal);
|
|
123
|
+
return;
|
|
124
|
+
} catch {
|
|
125
|
+
// Fall back to the direct child when the process group already exited.
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
child.kill(signal);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function waitForExit(child: exec.ChildProcessResult, timeoutMs: number): Promise<boolean> {
|
|
132
|
+
if (hasExited(child)) return Promise.resolve(true);
|
|
133
|
+
|
|
134
|
+
return new Promise((resolve) => {
|
|
135
|
+
let timer: NodeJS.Timeout | undefined;
|
|
136
|
+
let settled = false;
|
|
137
|
+
|
|
138
|
+
const finish = (exited: boolean) => {
|
|
139
|
+
if (settled) return;
|
|
140
|
+
settled = true;
|
|
141
|
+
if (timer) clearTimeout(timer);
|
|
142
|
+
void child.off("exit", onExit);
|
|
143
|
+
void child.off("error", onError);
|
|
144
|
+
resolve(exited);
|
|
145
|
+
};
|
|
146
|
+
const onExit = () => finish(true);
|
|
147
|
+
const onError = () => finish(true);
|
|
148
|
+
|
|
149
|
+
void child.once("exit", onExit);
|
|
150
|
+
void child.once("error", onError);
|
|
151
|
+
if (hasExited(child)) {
|
|
152
|
+
finish(true);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
timer = setTimeout(() => finish(false), timeoutMs);
|
|
156
|
+
});
|
|
157
|
+
}
|
package/src/provision.ts
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
import { createLakebasePool, getWorkspaceClient, ValidationError } from "@databricks/appkit";
|
|
25
25
|
import { configUtils } from "@dbx-tools/core";
|
|
26
|
+
import { postgresConnectionOptions, quotePostgresIdentifier } from "@dbx-tools/postgres";
|
|
26
27
|
import { errorUtils, log } from "@dbx-tools/shared-core";
|
|
27
28
|
|
|
28
29
|
const defaultLogger = log.logger("provision");
|
|
@@ -44,17 +45,6 @@ const ROLE_PATTERN = /^[A-Za-z0-9._@+-]{1,255}$/;
|
|
|
44
45
|
const CONNECT_TIMEOUT_MS = 10_000;
|
|
45
46
|
const STATEMENT_TIMEOUT_MS = 15_000;
|
|
46
47
|
|
|
47
|
-
/**
|
|
48
|
-
* Quote a Postgres identifier: wrap in double quotes and double any embedded
|
|
49
|
-
* quote. Schema and role names are identifiers, and Postgres does not accept a
|
|
50
|
-
* bind parameter in an identifier position, so quoting is the only defense
|
|
51
|
-
* available for these statements. Lakebase role names are usually emails
|
|
52
|
-
* (`user@host`), which must be quoted to be a valid identifier at all.
|
|
53
|
-
*/
|
|
54
|
-
function quoteIdent(ident: string): string {
|
|
55
|
-
return `"${ident.replace(/"/g, '""')}"`;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
48
|
/**
|
|
59
49
|
* Idempotent grants that make the (already-existing) AppKit cache schema fully
|
|
60
50
|
* usable by `role`. The `ALTER DEFAULT PRIVILEGES` lines cover the cache table
|
|
@@ -67,8 +57,8 @@ export function cacheGrantStatements(role: string): readonly string[] {
|
|
|
67
57
|
if (!ROLE_PATTERN.test(role)) {
|
|
68
58
|
throw ValidationError.invalidValue("role", role, "a Postgres role name");
|
|
69
59
|
}
|
|
70
|
-
const schema =
|
|
71
|
-
const target =
|
|
60
|
+
const schema = quotePostgresIdentifier(CACHE_SCHEMA);
|
|
61
|
+
const target = quotePostgresIdentifier(role);
|
|
72
62
|
return [
|
|
73
63
|
`GRANT USAGE, CREATE ON SCHEMA ${schema} TO ${target}`,
|
|
74
64
|
`GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA ${schema} TO ${target}`,
|
|
@@ -114,12 +104,14 @@ export async function provisionCacheSchema(
|
|
|
114
104
|
// returns a fresh default-auth client - literally `new WorkspaceClient({})`,
|
|
115
105
|
// but built against the SDK version AppKit's `createLakebasePool` expects
|
|
116
106
|
// (importing the SDK class directly here pulls a newer, type-incompatible copy).
|
|
117
|
-
const pool = createLakebasePool(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
107
|
+
const pool = createLakebasePool(
|
|
108
|
+
postgresConnectionOptions({
|
|
109
|
+
user: role,
|
|
110
|
+
workspaceClient: getWorkspaceClient({}),
|
|
111
|
+
connectionTimeoutMillis: CONNECT_TIMEOUT_MS,
|
|
112
|
+
statement_timeout: STATEMENT_TIMEOUT_MS,
|
|
113
|
+
}),
|
|
114
|
+
);
|
|
123
115
|
try {
|
|
124
116
|
const found = await pool.query(
|
|
125
117
|
"SELECT 1 FROM information_schema.schemata WHERE schema_name = $1",
|