dbctx 1.5.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/assemble.d.mts.map +1 -1
- package/dist/app/assemble.mjs +20 -4
- package/dist/app/list.d.mts +4 -0
- package/dist/app/list.d.mts.map +1 -0
- package/dist/app/list.mjs +93 -0
- package/dist/app/load-introspection.d.mts +26 -0
- package/dist/app/load-introspection.d.mts.map +1 -0
- package/dist/app/load-introspection.mjs +89 -0
- package/dist/app/login.d.mts +2 -0
- package/dist/app/login.d.mts.map +1 -0
- package/dist/app/login.mjs +69 -0
- package/dist/app/open-url.d.mts +2 -0
- package/dist/app/open-url.d.mts.map +1 -1
- package/dist/app/open-url.mjs +8 -3
- package/dist/app/sample.d.mts +24 -0
- package/dist/app/sample.d.mts.map +1 -0
- package/dist/app/sample.mjs +257 -0
- package/dist/app/session.d.mts +1 -0
- package/dist/app/session.d.mts.map +1 -1
- package/dist/app/session.mjs +44 -4
- package/dist/app/tail.d.mts +13 -0
- package/dist/app/tail.d.mts.map +1 -0
- package/dist/app/tail.mjs +168 -0
- package/dist/db/check-constraints.d.mts +9 -0
- package/dist/db/check-constraints.d.mts.map +1 -0
- package/dist/db/check-constraints.mjs +17 -0
- package/dist/db/custom-types.d.mts +26 -0
- package/dist/db/custom-types.d.mts.map +1 -0
- package/dist/db/custom-types.mjs +61 -0
- package/dist/db/extensions.d.mts +8 -0
- package/dist/db/extensions.d.mts.map +1 -0
- package/dist/db/extensions.mjs +14 -0
- package/dist/db/functions.d.mts +11 -0
- package/dist/db/functions.d.mts.map +1 -0
- package/dist/db/functions.mjs +23 -0
- package/dist/db/index.d.mts +9 -0
- package/dist/db/index.d.mts.map +1 -1
- package/dist/db/index.mjs +10 -1
- package/dist/db/planner-stats.d.mts +33 -0
- package/dist/db/planner-stats.d.mts.map +1 -0
- package/dist/db/planner-stats.mjs +103 -0
- package/dist/db/rls.d.mts +21 -0
- package/dist/db/rls.d.mts.map +1 -0
- package/dist/db/rls.mjs +48 -0
- package/dist/db/sample.d.mts +16 -0
- package/dist/db/sample.d.mts.map +1 -0
- package/dist/db/sample.mjs +73 -0
- package/dist/db/sequences.d.mts +15 -0
- package/dist/db/sequences.d.mts.map +1 -0
- package/dist/db/sequences.mjs +31 -0
- package/dist/db/triggers.d.mts +11 -0
- package/dist/db/triggers.d.mts.map +1 -0
- package/dist/db/triggers.mjs +21 -0
- package/dist/flow/events.d.mts +115 -0
- package/dist/flow/events.d.mts.map +1 -0
- package/dist/flow/events.mjs +2 -0
- package/dist/flow/interpreter.d.mts +21 -0
- package/dist/flow/interpreter.d.mts.map +1 -0
- package/dist/flow/interpreter.mjs +605 -0
- package/dist/flow/projection.d.mts +17 -0
- package/dist/flow/projection.d.mts.map +1 -0
- package/dist/flow/projection.mjs +83 -0
- package/dist/flow/projection.test.d.mts +2 -0
- package/dist/flow/projection.test.d.mts.map +1 -0
- package/dist/flow/projection.test.mjs +162 -0
- package/dist/flow/reducer.d.mts +5 -0
- package/dist/flow/reducer.d.mts.map +1 -0
- package/dist/flow/reducer.mjs +306 -0
- package/dist/flow/reducer.test.d.mts +2 -0
- package/dist/flow/reducer.test.d.mts.map +1 -0
- package/dist/flow/reducer.test.mjs +479 -0
- package/dist/flow/run.d.mts +3 -0
- package/dist/flow/run.d.mts.map +1 -0
- package/dist/flow/run.mjs +89 -0
- package/dist/flow/states.d.mts +54 -0
- package/dist/flow/states.d.mts.map +1 -0
- package/dist/flow/states.mjs +39 -0
- package/dist/index.d.mts +7 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +112 -13
- package/dist/lib/atomic-write.d.mts +4 -0
- package/dist/lib/atomic-write.d.mts.map +1 -0
- package/dist/lib/atomic-write.mjs +75 -0
- package/dist/lib/stream-job.d.mts +19 -0
- package/dist/lib/stream-job.d.mts.map +1 -0
- package/dist/lib/stream-job.mjs +55 -0
- package/dist/lib/trpc-url.mjs +2 -2
- package/dist/lib/trpc.mjs +2 -2
- package/dist/logger.d.mts.map +1 -1
- package/dist/logger.mjs +6 -3
- package/dist/providers/TrpcProvider.js +3 -3
- package/dist/store.d.mts +95 -2
- package/dist/store.d.mts.map +1 -1
- package/dist/store.mjs +64 -1
- package/dist/ui/App.d.ts +1 -1
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +22 -4
- package/dist/ui/components/Analyze.d.ts +10 -0
- package/dist/ui/components/Analyze.d.ts.map +1 -0
- package/dist/ui/components/Analyze.js +54 -0
- package/dist/ui/components/Billing.d.ts +10 -0
- package/dist/ui/components/Billing.d.ts.map +1 -0
- package/dist/ui/components/Billing.js +40 -0
- package/dist/ui/components/DB.d.ts.map +1 -1
- package/dist/ui/components/DB.js +2 -2
- package/dist/ui/components/DatabasePicker.d.ts +13 -0
- package/dist/ui/components/DatabasePicker.d.ts.map +1 -0
- package/dist/ui/components/DatabasePicker.js +79 -0
- package/dist/ui/components/Enrich.d.ts +10 -0
- package/dist/ui/components/Enrich.d.ts.map +1 -0
- package/dist/ui/components/Enrich.js +41 -0
- package/dist/ui/components/Gate.js +2 -2
- package/dist/ui/components/Introspect.d.ts.map +1 -1
- package/dist/ui/components/Introspect.js +2 -2
- package/dist/ui/components/IntrospectionUpload.d.ts +10 -0
- package/dist/ui/components/IntrospectionUpload.d.ts.map +1 -0
- package/dist/ui/components/IntrospectionUpload.js +30 -0
- package/dist/ui/components/Login.d.ts +19 -0
- package/dist/ui/components/Login.d.ts.map +1 -0
- package/dist/ui/components/Login.js +38 -0
- package/dist/ui/components/OutputJson.d.ts.map +1 -1
- package/dist/ui/components/OutputJson.js +2 -2
- package/dist/ui/components/SSH.d.ts.map +1 -1
- package/dist/ui/components/SSH.js +2 -2
- package/dist/ui/components/SamplesUpload.d.ts +10 -0
- package/dist/ui/components/SamplesUpload.d.ts.map +1 -0
- package/dist/ui/components/SamplesUpload.js +24 -0
- package/dist/ui/components/Sampling.d.ts +10 -0
- package/dist/ui/components/Sampling.d.ts.map +1 -0
- package/dist/ui/components/Sampling.js +58 -0
- package/dist/ui/components/Session.d.ts.map +1 -1
- package/dist/ui/components/Session.js +4 -4
- package/dist/ui/components/Spinner.d.ts.map +1 -1
- package/dist/ui/components/Spinner.js +17 -5
- package/dist/validatePaths.d.mts +1 -1
- package/dist/validatePaths.d.mts.map +1 -1
- package/dist/validatePaths.mjs +5 -1
- package/package.json +7 -7
- package/dist/app/index.d.mts +0 -3
- package/dist/app/index.d.mts.map +0 -1
- package/dist/app/index.mjs +0 -156
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dbctx",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "AI-enriched database context for humans and coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
@@ -28,9 +28,6 @@
|
|
|
28
28
|
"url": "https://github.com/dbctx/dbctx"
|
|
29
29
|
},
|
|
30
30
|
"license": "MIT",
|
|
31
|
-
"imports": {
|
|
32
|
-
"#client/*": "./dist/*"
|
|
33
|
-
},
|
|
34
31
|
"dependencies": {
|
|
35
32
|
"@tanstack/react-query": "5.90.20",
|
|
36
33
|
"@trpc/client": "11.8.1",
|
|
@@ -50,9 +47,11 @@
|
|
|
50
47
|
"scope-utilities": "2.2.1",
|
|
51
48
|
"ssh-config": "5.0.4",
|
|
52
49
|
"ssh2": "1.17.0",
|
|
50
|
+
"terminal-link": "5.0.0",
|
|
53
51
|
"uuidv7": "1.0.2",
|
|
54
52
|
"winston": "3.19.0",
|
|
55
|
-
"zod": "4.3.6"
|
|
53
|
+
"zod": "4.3.6",
|
|
54
|
+
"@dbctx/common": "0.0.0"
|
|
56
55
|
},
|
|
57
56
|
"devDependencies": {
|
|
58
57
|
"@types/node": "24.0.0",
|
|
@@ -63,7 +62,7 @@
|
|
|
63
62
|
"cross-env": "7.0.3",
|
|
64
63
|
"prettier": "3.8.1",
|
|
65
64
|
"typescript": "5.9.3",
|
|
66
|
-
"@dbctx/core": "
|
|
65
|
+
"@dbctx/core": "2.0.5"
|
|
67
66
|
},
|
|
68
67
|
"volta": {
|
|
69
68
|
"node": "24.0.0"
|
|
@@ -75,6 +74,7 @@
|
|
|
75
74
|
"start": "tsc && node ./dist/index.mjs",
|
|
76
75
|
"dev": "tsc --watch --preserveWatchOutput",
|
|
77
76
|
"build": "tsc",
|
|
78
|
-
"build:ts:watch": "tsc --watch --preserveWatchOutput"
|
|
77
|
+
"build:ts:watch": "tsc --watch --preserveWatchOutput",
|
|
78
|
+
"test": "tsc && node --test dist/flow/*.test.mjs"
|
|
79
79
|
}
|
|
80
80
|
}
|
package/dist/app/index.d.mts
DELETED
package/dist/app/index.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sourceRoot":"./src/","sources":["app/index.mts"],"names":[],"mappings":"AAIA,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AAgBpC,wBAAsB,GAAG,CAAC,KAAK,EAAE,MAAM,iBAyLtC"}
|
package/dist/app/index.mjs
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import { mkdir, writeFile } from 'node:fs/promises';
|
|
3
|
-
import { dirname } from 'node:path';
|
|
4
|
-
import { connectSSH } from './ssh.mjs';
|
|
5
|
-
import { connectDB } from './db.mjs';
|
|
6
|
-
import { assembleDatabase } from './assemble.mjs';
|
|
7
|
-
import { createSession, waitForAuthorization, connectAccount, checkGate, } from './session.mjs';
|
|
8
|
-
import { readConfig, flushConfig } from './config.mjs';
|
|
9
|
-
import { TRPCClientError } from '@trpc/client';
|
|
10
|
-
import { when, runInAction } from 'mobx';
|
|
11
|
-
import { DBCTX_DEV } from '#client/lib/env.mjs';
|
|
12
|
-
import { logger } from '../logger.mjs';
|
|
13
|
-
export async function run(store) {
|
|
14
|
-
try {
|
|
15
|
-
const cleanupSSH = await connectSSH(store);
|
|
16
|
-
if (store.steps.sshConnection.enabled) {
|
|
17
|
-
await when(() => ['connected', 'error'].includes(store.steps.sshConnection.state));
|
|
18
|
-
if (store.steps.sshConnection.state === 'error') {
|
|
19
|
-
cleanupSSH?.();
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
if (store.outputOptions.stopAfter === 'ssh-connect') {
|
|
23
|
-
cleanupSSH?.();
|
|
24
|
-
process.exit(0);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
const db = await connectDB(store);
|
|
28
|
-
await when(() => ['connected', 'error'].includes(store.steps.databaseConnection.state));
|
|
29
|
-
if (store.steps.databaseConnection.state === 'error') {
|
|
30
|
-
db?.cleanup();
|
|
31
|
-
cleanupSSH?.();
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
if (store.outputOptions.stopAfter === 'db-connect') {
|
|
35
|
-
db?.cleanup();
|
|
36
|
-
cleanupSSH?.();
|
|
37
|
-
process.exit(0);
|
|
38
|
-
}
|
|
39
|
-
if (db) {
|
|
40
|
-
const result = await assembleDatabase(db.pool, store);
|
|
41
|
-
if (DBCTX_DEV) {
|
|
42
|
-
const { databaseIntrospectionSchema } = await import('@dbctx/core/schemas/introspection');
|
|
43
|
-
databaseIntrospectionSchema.parse(result);
|
|
44
|
-
}
|
|
45
|
-
if (store.outputOptions.stopAfter === 'introspection') {
|
|
46
|
-
db.pool.end();
|
|
47
|
-
cleanupSSH?.();
|
|
48
|
-
process.exit(0);
|
|
49
|
-
}
|
|
50
|
-
// Account + gate check (before explanation prompt)
|
|
51
|
-
const config = await readConfig();
|
|
52
|
-
try {
|
|
53
|
-
const sessionId = await createSession(db.pool, result, store, config.token ?? null, config.device_id);
|
|
54
|
-
if (config.token) {
|
|
55
|
-
try {
|
|
56
|
-
await connectAccount(config.token, store);
|
|
57
|
-
const canContinue = await checkGate(config.token, store);
|
|
58
|
-
if (!canContinue) {
|
|
59
|
-
db.pool.end();
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
catch (err) {
|
|
64
|
-
if (err instanceof TRPCClientError &&
|
|
65
|
-
(err.data?.code === 'UNAUTHORIZED' ||
|
|
66
|
-
err.data?.code === 'NOT_FOUND')) {
|
|
67
|
-
await flushConfig();
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
throw err;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
if (store.steps.account.state !== 'connected') {
|
|
75
|
-
await waitForAuthorization(sessionId, store);
|
|
76
|
-
const freshToken = (await readConfig()).token;
|
|
77
|
-
if (freshToken) {
|
|
78
|
-
const canContinue = await checkGate(freshToken, store);
|
|
79
|
-
if (!canContinue) {
|
|
80
|
-
db.pool.end();
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
catch (err) {
|
|
87
|
-
runInAction(() => {
|
|
88
|
-
store.steps.account.state = 'error';
|
|
89
|
-
store.steps.account.error =
|
|
90
|
-
err instanceof Error
|
|
91
|
-
? err.message
|
|
92
|
-
: 'Session creation failed';
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
// User explanation step
|
|
96
|
-
if (store.outputOptions.explanation) {
|
|
97
|
-
runInAction(() => {
|
|
98
|
-
store.steps.userExplanation.state = 'done';
|
|
99
|
-
store.steps.userExplanation.value =
|
|
100
|
-
store.outputOptions.explanation;
|
|
101
|
-
});
|
|
102
|
-
result.userExplanation = store.outputOptions.explanation;
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
runInAction(() => {
|
|
106
|
-
store.steps.userExplanation.state = 'prompting';
|
|
107
|
-
});
|
|
108
|
-
await when(() => store.steps.userExplanation.state === 'done');
|
|
109
|
-
result.userExplanation = store.steps.userExplanation.value;
|
|
110
|
-
}
|
|
111
|
-
if (store.outputOptions.outputIntrospectionJson) {
|
|
112
|
-
const outputPath = store.outputOptions.outputIntrospectionJson;
|
|
113
|
-
if (existsSync(outputPath) && !store.outputOptions.overwrite) {
|
|
114
|
-
runInAction(() => {
|
|
115
|
-
store.steps.outputJson.state = 'prompting-overwrite';
|
|
116
|
-
store.steps.outputJson.path = outputPath;
|
|
117
|
-
});
|
|
118
|
-
await when(() => store.steps.outputJson.confirmed !== null);
|
|
119
|
-
if (!store.steps.outputJson.confirmed) {
|
|
120
|
-
db.pool.end();
|
|
121
|
-
cleanupSSH?.();
|
|
122
|
-
process.exit(0);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
runInAction(() => {
|
|
126
|
-
store.steps.outputJson.state = 'writing';
|
|
127
|
-
store.steps.outputJson.path = outputPath;
|
|
128
|
-
});
|
|
129
|
-
try {
|
|
130
|
-
await mkdir(dirname(outputPath), { recursive: true });
|
|
131
|
-
await writeFile(outputPath, JSON.stringify(result, null, 2));
|
|
132
|
-
runInAction(() => {
|
|
133
|
-
store.steps.outputJson.state = 'done';
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
catch (err) {
|
|
137
|
-
runInAction(() => {
|
|
138
|
-
store.steps.outputJson.state = 'error';
|
|
139
|
-
store.steps.outputJson.error =
|
|
140
|
-
err instanceof Error ? err.message : String(err);
|
|
141
|
-
});
|
|
142
|
-
db.pool.end();
|
|
143
|
-
cleanupSSH?.();
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
db.pool.end();
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
catch (err) {
|
|
151
|
-
if (DBCTX_DEV) {
|
|
152
|
-
logger.error(`${err}`, { error: err });
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXgubWpzIiwic291cmNlUm9vdCI6Ii4vc3JjLyIsInNvdXJjZXMiOlsiYXBwL2luZGV4Lm10cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sU0FBUyxDQUFDO0FBQ25DLE9BQU8sRUFBQyxLQUFLLEVBQUUsU0FBUyxFQUFDLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFDLE9BQU8sRUFBQyxNQUFNLFdBQVcsQ0FBQztBQUdsQyxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQ3JDLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFDbkMsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEQsT0FBTyxFQUNILGFBQWEsRUFDYixvQkFBb0IsRUFDcEIsY0FBYyxFQUNkLFNBQVMsR0FDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsVUFBVSxFQUFFLFdBQVcsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUNyRCxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sY0FBYyxDQUFDO0FBQzdDLE9BQU8sRUFBQyxJQUFJLEVBQUUsV0FBVyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ3ZDLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUM5QyxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBRXJDLE1BQU0sQ0FBQyxLQUFLLFVBQVUsR0FBRyxDQUFDLEtBQWE7SUFDbkMsSUFBSSxDQUFDO1FBQ0QsTUFBTSxVQUFVLEdBQUcsTUFBTSxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFM0MsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNwQyxNQUFNLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FDWixDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQyxRQUFR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LENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ3pELENBQUMsQ0FBQyxDQUFDO29CQUNILEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7b0JBQ2QsVUFBVSxFQUFFLEVBQUUsQ0FBQztvQkFDZixPQUFPO2dCQUNYLENBQUM7WUFDTCxDQUFDO1lBRUQsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNsQixDQUFDO0lBQ0wsQ0FBQztJQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDWCxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQ1osTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQyxDQUFDLENBQUM7UUFDekMsQ0FBQztJQUNMLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtleGlzdHNTeW5jfSBmcm9tICdub2RlOmZzJztcbmltcG9ydCB7bWtkaXIsIHdyaXRlRmlsZX0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQge2Rpcm5hbWV9IGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB7VFN0b3JlfSBmcm9tICcuLi9zdG9yZS5tanMnO1xuaW1wb3J0IHtjb25uZWN0U1NIfSBmcm9tICcuL3NzaC5tanMnO1xuaW1wb3J0IHtjb25uZWN0REJ9IGZyb20gJy4vZGIubWpzJztcbmltcG9ydCB7YXNzZW1ibGVEYXRhYmFzZX0gZnJvbSAnLi9hc3NlbWJsZS5tanMnO1xuaW1wb3J0IHtcbiAgICBjcmVhdGVTZXNzaW9uLFxuICAgIHdhaXRGb3JBdXRob3JpemF0aW9uLFxuICAgIGNvbm5lY3RBY2NvdW50LFxuICAgIGNoZWNrR2F0ZSxcbn0gZnJvbSAnLi9zZXNzaW9uLm1qcyc7XG5pbXBvcnQge3JlYWRDb25maWcsIGZsdXNoQ29uZmlnfSBmcm9tICcuL2NvbmZpZy5tanMnO1xuaW1wb3J0IHtUUlBDQ2xpZW50RXJyb3J9IGZyb20gJ0B0cnBjL2NsaWVudCc7XG5pbXBvcnQge3doZW4sIHJ1bkluQWN0aW9ufSBmcm9tICdtb2J4JztcbmltcG9ydCB7REJDVFhfREVWfSBmcm9tICcjY2xpZW50L2xpYi9lbnYubWpzJztcbmltcG9ydCB7bG9nZ2VyfSBmcm9tICcuLi9sb2dnZXIubWpzJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1bihzdG9yZTogVFN0b3JlKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgY2xlYW51cFNTSCA9IGF3YWl0IGNvbm5lY3RTU0goc3RvcmUpO1xuXG4gICAgICAgIGlmIChzdG9yZS5zdGVwcy5zc2hDb25uZWN0aW9uLmVuYWJsZWQpIHtcbiAgICAgICAgICAgIGF3YWl0IHdoZW4oKCkgPT5cbiAgICAgICAgICAgICAgICBbJ2Nvbm5lY3RlZCcsICdlcnJvciddLmluY2x1ZGVzKFxuICAgICAgICAgICAgICAgICAgICBzdG9yZS5zdGVwcy5zc2hDb25uZWN0aW9uLnN0YXRlLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBpZiAoc3RvcmUuc3RlcHMuc3NoQ29ubmVjdGlvbi5zdGF0ZSA9PT0gJ2Vycm9yJykge1xuICAgICAgICAgICAgICAgIGNsZWFudXBTU0g/LigpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHN0b3JlLm91dHB1dE9wdGlvbnMuc3RvcEFmdGVyID09PSAnc3NoLWNvbm5lY3QnKSB7XG4gICAgICAgICAgICAgICAgY2xlYW51cFNTSD8uKCk7XG4gICAgICAgICAgICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGIgPSBhd2FpdCBjb25uZWN0REIoc3RvcmUpO1xuXG4gICAgICAgIGF3YWl0IHdoZW4oKCkgPT5cbiAgICAgICAgICAgIFsnY29ubmVjdGVkJywgJ2Vycm9yJ10uaW5jbHVkZXMoXG4gICAgICAgICAgICAgICAgc3RvcmUuc3RlcHMuZGF0YWJhc2VDb25uZWN0aW9uLnN0YXRlLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoc3RvcmUuc3RlcHMuZGF0YWJhc2VDb25uZWN0aW9uLnN0YXRlID09PSAnZXJyb3InKSB7XG4gICAgICAgICAgICBkYj8uY2xlYW51cCgpO1xuICAgICAgICAgICAgY2xlYW51cFNTSD8uKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RvcmUub3V0cHV0T3B0aW9ucy5zdG9wQWZ0ZXIgPT09ICdkYi1jb25uZWN0Jykge1xuICAgICAgICAgICAgZGI/LmNsZWFudXAoKTtcbiAgICAgICAgICAgIGNsZWFudXBTU0g/LigpO1xuICAgICAgICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRiKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhc3NlbWJsZURhdGFiYXNlKGRiLnBvb2wsIHN0b3JlKTtcblxuICAgICAgICAgICAgaWYgKERCQ1RYX0RFVikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHtkYXRhYmFzZUludHJvc3BlY3Rpb25TY2hlbWF9ID1cbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgaW1wb3J0KCdAZGJjdHgvY29yZS9zY2hlbWFzL2ludHJvc3BlY3Rpb24nKTtcbiAgICAgICAgICAgICAgICBkYXRhYmFzZUludHJvc3BlY3Rpb25TY2hlbWEucGFyc2UocmVzdWx0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHN0b3JlLm91dHB1dE9wdGlvbnMuc3RvcEFmdGVyID09PSAnaW50cm9zcGVjdGlvbicpIHtcbiAgICAgICAgICAgICAgICBkYi5wb29sLmVuZCgpO1xuICAgICAgICAgICAgICAgIGNsZWFudXBTU0g/LigpO1xuICAgICAgICAgICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQWNjb3VudCArIGdhdGUgY2hlY2sgKGJlZm9yZSBleHBsYW5hdGlvbiBwcm9tcHQpXG4gICAgICAgICAgICBjb25zdCBjb25maWcgPSBhd2FpdCByZWFkQ29uZmlnKCk7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbklkID0gYXdhaXQgY3JlYXRlU2Vzc2lvbihcbiAgICAgICAgICAgICAgICAgICAgZGIucG9vbCxcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LFxuICAgICAgICAgICAgICAgICAgICBzdG9yZSxcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnLnRva2VuID8/IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5kZXZpY2VfaWQsXG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIGlmIChjb25maWcudG9rZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBY2NvdW50KGNvbmZpZy50b2tlbiwgc3RvcmUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuQ29udGludWUgPSBhd2FpdCBjaGVja0dhdGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLnRva2VuLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlLFxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY2FuQ29udGludWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYi5wb29sLmVuZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyIGluc3RhbmNlb2YgVFJQQ0NsaWVudEVycm9yICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVyci5kYXRhPy5jb2RlID09PSAnVU5BVVRIT1JJWkVEJyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnIuZGF0YT8uY29kZSA9PT0gJ05PVF9GT1VORCcpXG4gICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBmbHVzaENvbmZpZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoc3RvcmUuc3RlcHMuYWNjb3VudC5zdGF0ZSAhPT0gJ2Nvbm5lY3RlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgd2FpdEZvckF1dGhvcml6YXRpb24oc2Vzc2lvbklkLCBzdG9yZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZnJlc2hUb2tlbiA9IChhd2FpdCByZWFkQ29uZmlnKCkpLnRva2VuO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZnJlc2hUb2tlbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuQ29udGludWUgPSBhd2FpdCBjaGVja0dhdGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlc2hUb2tlbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNhbkNvbnRpbnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGIucG9vbC5lbmQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBydW5JbkFjdGlvbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHN0b3JlLnN0ZXBzLmFjY291bnQuc3RhdGUgPSAnZXJyb3InO1xuICAgICAgICAgICAgICAgICAgICBzdG9yZS5zdGVwcy5hY2NvdW50LmVycm9yID1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVyciBpbnN0YW5jZW9mIEVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBlcnIubWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJ1Nlc3Npb24gY3JlYXRpb24gZmFpbGVkJztcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVXNlciBleHBsYW5hdGlvbiBzdGVwXG4gICAgICAgICAgICBpZiAoc3RvcmUub3V0cHV0T3B0aW9ucy5leHBsYW5hdGlvbikge1xuICAgICAgICAgICAgICAgIHJ1bkluQWN0aW9uKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc3RvcmUuc3RlcHMudXNlckV4cGxhbmF0aW9uLnN0YXRlID0gJ2RvbmUnO1xuICAgICAgICAgICAgICAgICAgICBzdG9yZS5zdGVwcy51c2VyRXhwbGFuYXRpb24udmFsdWUgPVxuICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmUub3V0cHV0T3B0aW9ucy5leHBsYW5hdGlvbjtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXN1bHQudXNlckV4cGxhbmF0aW9uID0gc3RvcmUub3V0cHV0T3B0aW9ucy5leHBsYW5hdGlvbjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcnVuSW5BY3Rpb24oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBzdG9yZS5zdGVwcy51c2VyRXhwbGFuYXRpb24uc3RhdGUgPSAncHJvbXB0aW5nJztcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBhd2FpdCB3aGVuKCgpID0+IHN0b3JlLnN0ZXBzLnVzZXJFeHBsYW5hdGlvbi5zdGF0ZSA9PT0gJ2RvbmUnKTtcbiAgICAgICAgICAgICAgICByZXN1bHQudXNlckV4cGxhbmF0aW9uID0gc3RvcmUuc3RlcHMudXNlckV4cGxhbmF0aW9uLnZhbHVlITtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHN0b3JlLm91dHB1dE9wdGlvbnMub3V0cHV0SW50cm9zcGVjdGlvbkpzb24pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXRQYXRoID0gc3RvcmUub3V0cHV0T3B0aW9ucy5vdXRwdXRJbnRyb3NwZWN0aW9uSnNvbjtcblxuICAgICAgICAgICAgICAgIGlmIChleGlzdHNTeW5jKG91dHB1dFBhdGgpICYmICFzdG9yZS5vdXRwdXRPcHRpb25zLm92ZXJ3cml0ZSkge1xuICAgICAgICAgICAgICAgICAgICBydW5JbkFjdGlvbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdG9yZS5zdGVwcy5vdXRwdXRKc29uLnN0YXRlID0gJ3Byb21wdGluZy1vdmVyd3JpdGUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmUuc3RlcHMub3V0cHV0SnNvbi5wYXRoID0gb3V0cHV0UGF0aDtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgd2hlbigoKSA9PiBzdG9yZS5zdGVwcy5vdXRwdXRKc29uLmNvbmZpcm1lZCAhPT0gbnVsbCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzdG9yZS5zdGVwcy5vdXRwdXRKc29uLmNvbmZpcm1lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGIucG9vbC5lbmQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFudXBTU0g/LigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcnVuSW5BY3Rpb24oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBzdG9yZS5zdGVwcy5vdXRwdXRKc29uLnN0YXRlID0gJ3dyaXRpbmcnO1xuICAgICAgICAgICAgICAgICAgICBzdG9yZS5zdGVwcy5vdXRwdXRKc29uLnBhdGggPSBvdXRwdXRQYXRoO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgbWtkaXIoZGlybmFtZShvdXRwdXRQYXRoKSwge3JlY3Vyc2l2ZTogdHJ1ZX0pO1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCB3cml0ZUZpbGUoXG4gICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRQYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkocmVzdWx0LCBudWxsLCAyKSxcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgcnVuSW5BY3Rpb24oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmUuc3RlcHMub3V0cHV0SnNvbi5zdGF0ZSA9ICdkb25lJztcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJ1bkluQWN0aW9uKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlLnN0ZXBzLm91dHB1dEpzb24uc3RhdGUgPSAnZXJyb3InO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmUuc3RlcHMub3V0cHV0SnNvbi5lcnJvciA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgZGIucG9vbC5lbmQoKTtcbiAgICAgICAgICAgICAgICAgICAgY2xlYW51cFNTSD8uKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRiLnBvb2wuZW5kKCk7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgaWYgKERCQ1RYX0RFVikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGAke2Vycn1gLCB7ZXJyb3I6IGVycn0pO1xuICAgICAgICB9XG4gICAgfVxufVxuIl19
|