local-serverless-stack 0.17.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +327 -0
- package/README.md +1157 -224
- package/assets/icon.svg +37 -0
- package/assets/logo.svg +38 -0
- package/bin/cli.js +384 -217
- package/bin/i18n.js +498 -0
- package/dist/client/config-discovery.d.ts.map +1 -1
- package/dist/client/config-discovery.js +2 -1
- package/dist/client/config-discovery.js.map +1 -1
- package/dist/client/http.d.ts +7 -0
- package/dist/client/http.d.ts.map +1 -1
- package/dist/client/http.js +3 -2
- package/dist/client/http.js.map +1 -1
- package/dist/client/lifecycle.d.ts +1 -4
- package/dist/client/lifecycle.d.ts.map +1 -1
- package/dist/client/lifecycle.js +2 -8
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/namespaces/health.d.ts +1 -1
- package/dist/client/namespaces/health.d.ts.map +1 -1
- package/dist/client/namespaces/queues.d.ts.map +1 -1
- package/dist/client/namespaces/queues.js +9 -0
- package/dist/client/namespaces/queues.js.map +1 -1
- package/dist/client/namespaces/seeds.d.ts +1 -1
- package/dist/client/namespaces/services.d.ts +34 -0
- package/dist/client/namespaces/services.d.ts.map +1 -1
- package/dist/client/namespaces/services.js +3 -0
- package/dist/client/namespaces/services.js.map +1 -1
- package/dist/client/types.d.ts +17 -5
- package/dist/client/types.d.ts.map +1 -1
- package/dist/mcp/http.d.ts +15 -0
- package/dist/mcp/http.d.ts.map +1 -0
- package/dist/mcp/http.js +86 -0
- package/dist/mcp/http.js.map +1 -0
- package/dist/mcp/protocol.d.ts +36 -0
- package/dist/mcp/protocol.d.ts.map +1 -0
- package/dist/mcp/protocol.js +96 -0
- package/dist/mcp/protocol.js.map +1 -0
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +41 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +18 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +323 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/server/dev/dynamo-proxy.d.ts.map +1 -1
- package/dist/server/dev/dynamo-proxy.js +16 -2
- package/dist/server/dev/dynamo-proxy.js.map +1 -1
- package/dist/server/engine/backends/self-backend.d.ts +11 -2
- package/dist/server/engine/backends/self-backend.d.ts.map +1 -1
- package/dist/server/engine/backends/self-backend.js +42 -1
- package/dist/server/engine/backends/self-backend.js.map +1 -1
- package/dist/server/engine/dispatch/dispatcher.js +2 -2
- package/dist/server/engine/dispatch/dispatcher.js.map +1 -1
- package/dist/server/engine/engine-manager.d.ts +6 -1
- package/dist/server/engine/engine-manager.d.ts.map +1 -1
- package/dist/server/engine/engine-manager.js +30 -27
- package/dist/server/engine/engine-manager.js.map +1 -1
- package/dist/server/engine/http/is-aws-request.d.ts +8 -0
- package/dist/server/engine/http/is-aws-request.d.ts.map +1 -0
- package/dist/server/engine/http/is-aws-request.js +53 -0
- package/dist/server/engine/http/is-aws-request.js.map +1 -0
- package/dist/server/engine/http/router.d.ts.map +1 -1
- package/dist/server/engine/http/router.js +7 -1
- package/dist/server/engine/http/router.js.map +1 -1
- package/dist/server/engine/store/engine-store.d.ts +1 -0
- package/dist/server/engine/store/engine-store.d.ts.map +1 -1
- package/dist/server/engine/store/engine-store.js +2 -1
- package/dist/server/engine/store/engine-store.js.map +1 -1
- package/dist/server/engine/store/memory-store.d.ts +16 -0
- package/dist/server/engine/store/memory-store.d.ts.map +1 -0
- package/dist/server/engine/store/memory-store.js +167 -0
- package/dist/server/engine/store/memory-store.js.map +1 -0
- package/dist/server/engine/store/wal.d.ts +3 -0
- package/dist/server/engine/store/wal.d.ts.map +1 -1
- package/dist/server/engine/store/wal.js +35 -1
- package/dist/server/engine/store/wal.js.map +1 -1
- package/dist/server/index.js +159 -44
- package/dist/server/index.js.map +1 -1
- package/dist/server/routes/config.d.ts.map +1 -1
- package/dist/server/routes/config.js +164 -15
- package/dist/server/routes/config.js.map +1 -1
- package/dist/server/routes/lambdas.d.ts.map +1 -1
- package/dist/server/routes/lambdas.js +65 -0
- package/dist/server/routes/lambdas.js.map +1 -1
- package/dist/server/routes/services.d.ts.map +1 -1
- package/dist/server/routes/services.js +275 -24
- package/dist/server/routes/services.js.map +1 -1
- package/dist/server/services/bind-host.d.ts +30 -0
- package/dist/server/services/bind-host.d.ts.map +1 -0
- package/dist/server/services/bind-host.js +182 -0
- package/dist/server/services/bind-host.js.map +1 -0
- package/dist/server/services/cache-manager.d.ts +2 -1
- package/dist/server/services/cache-manager.d.ts.map +1 -1
- package/dist/server/services/cache-manager.js +4 -14
- package/dist/server/services/cache-manager.js.map +1 -1
- package/dist/server/services/config-manager.d.ts +59 -35
- package/dist/server/services/config-manager.d.ts.map +1 -1
- package/dist/server/services/config-manager.js +787 -131
- package/dist/server/services/config-manager.js.map +1 -1
- package/dist/server/services/dynamo-explorer.d.ts +1 -0
- package/dist/server/services/dynamo-explorer.d.ts.map +1 -1
- package/dist/server/services/dynamo-explorer.js +28 -6
- package/dist/server/services/dynamo-explorer.js.map +1 -1
- package/dist/server/services/explorer-region.d.ts +2 -0
- package/dist/server/services/explorer-region.d.ts.map +1 -0
- package/dist/server/services/explorer-region.js +23 -0
- package/dist/server/services/explorer-region.js.map +1 -0
- package/dist/server/services/gateway-manager.d.ts.map +1 -1
- package/dist/server/services/gateway-manager.js +18 -5
- package/dist/server/services/gateway-manager.js.map +1 -1
- package/dist/server/services/invocation-activity.d.ts +45 -0
- package/dist/server/services/invocation-activity.d.ts.map +1 -0
- package/dist/server/services/invocation-activity.js +102 -0
- package/dist/server/services/invocation-activity.js.map +1 -0
- package/dist/server/services/lambda-runtime-manager.d.ts +7 -1
- package/dist/server/services/lambda-runtime-manager.d.ts.map +1 -1
- package/dist/server/services/lambda-runtime-manager.js +118 -10
- package/dist/server/services/lambda-runtime-manager.js.map +1 -1
- package/dist/server/services/opensearch-explorer.d.ts.map +1 -1
- package/dist/server/services/opensearch-explorer.js +14 -10
- package/dist/server/services/opensearch-explorer.js.map +1 -1
- package/dist/server/services/project-scope.d.ts +2 -0
- package/dist/server/services/project-scope.d.ts.map +1 -0
- package/dist/server/services/project-scope.js +23 -0
- package/dist/server/services/project-scope.js.map +1 -0
- package/dist/server/services/queue-inspector.d.ts.map +1 -1
- package/dist/server/services/queue-inspector.js +15 -6
- package/dist/server/services/queue-inspector.js.map +1 -1
- package/dist/server/services/resource-provisioner.d.ts +0 -2
- package/dist/server/services/resource-provisioner.d.ts.map +1 -1
- package/dist/server/services/resource-provisioner.js +24 -14
- package/dist/server/services/resource-provisioner.js.map +1 -1
- package/dist/server/services/s3-explorer.js +3 -3
- package/dist/server/services/s3-explorer.js.map +1 -1
- package/dist/server/services/secrets-explorer.d.ts.map +1 -1
- package/dist/server/services/secrets-explorer.js +10 -3
- package/dist/server/services/secrets-explorer.js.map +1 -1
- package/dist/server/services/seed-manager.d.ts.map +1 -1
- package/dist/server/services/seed-manager.js +17 -8
- package/dist/server/services/seed-manager.js.map +1 -1
- package/dist/server/services/serverless-state-parser.d.ts +10 -0
- package/dist/server/services/serverless-state-parser.d.ts.map +1 -1
- package/dist/server/services/serverless-state-parser.js +20 -1
- package/dist/server/services/serverless-state-parser.js.map +1 -1
- package/dist/server/services/service-registrar.d.ts.map +1 -1
- package/dist/server/services/service-registrar.js +19 -5
- package/dist/server/services/service-registrar.js.map +1 -1
- package/dist/server/services/service-scanner.d.ts +20 -0
- package/dist/server/services/service-scanner.d.ts.map +1 -0
- package/dist/server/services/service-scanner.js +173 -0
- package/dist/server/services/service-scanner.js.map +1 -0
- package/dist/server/services/source-watcher.d.ts.map +1 -1
- package/dist/server/services/source-watcher.js +31 -6
- package/dist/server/services/source-watcher.js.map +1 -1
- package/dist/ui/assets/ApisPage-BOuimwWz.js +1 -0
- package/dist/ui/assets/BucketDetailPage-vLYwhoQt.js +1 -0
- package/dist/ui/assets/BucketsPage-Cu5lU1Hp.js +1 -0
- package/dist/ui/assets/DynamoPage-y3TTEPUL.js +1 -0
- package/dist/ui/assets/DynamoTablePage-BnmSRZjc.js +3 -0
- package/dist/ui/assets/LambdaDetailPage-B5q_d27t.js +4 -0
- package/dist/ui/assets/LambdasPage-CJpRoEDx.js +1 -0
- package/dist/ui/assets/OnboardingPage-D02dymQi.js +1 -0
- package/dist/ui/assets/OpenSearchCollectionPage-B_wWTlfL.js +1 -0
- package/dist/ui/assets/OpenSearchPage-BLEgfF_g.js +1 -0
- package/dist/ui/assets/{OverviewPage-C7JlCyW1.css → OverviewPage-C1pBJ8aP.css} +1 -1
- package/dist/ui/assets/OverviewPage-EdJWiAt6.js +1 -0
- package/dist/ui/assets/QueueDetailPage-ByEYHvHe.js +1 -0
- package/dist/ui/assets/QueuesPage-CvwYHSll.js +1 -0
- package/dist/ui/assets/SecretsPage-DASw8Ntf.js +1 -0
- package/dist/ui/assets/ServiceDetailPage-BMsUDg6L.js +2 -0
- package/dist/ui/assets/ServicesPage-2JuiIiRr.js +2 -0
- package/dist/ui/assets/SettingsPage-DStO4bgN.js +1 -0
- package/dist/ui/assets/engine-D0mFFNbL.js +1 -0
- package/dist/ui/assets/index-BIEznsi4.js +37 -0
- package/dist/ui/assets/index-BRMvNP3Y.css +1 -0
- package/dist/ui/assets/onboarding-DQmlvyWU.js +1 -0
- package/dist/ui/assets/resourceIcons-baecADXA.js +1 -0
- package/dist/ui/assets/triggerIcons-DIPWQkJ3.js +1 -0
- package/dist/ui/favicon.svg +37 -0
- package/dist/ui/index.html +5 -3
- package/package.json +12 -12
- package/dist/server/engine/aoss-sidecar.d.ts +0 -13
- package/dist/server/engine/aoss-sidecar.d.ts.map +0 -1
- package/dist/server/engine/aoss-sidecar.js +0 -93
- package/dist/server/engine/aoss-sidecar.js.map +0 -1
- package/dist/server/engine/backends/localstack-backend.d.ts +0 -25
- package/dist/server/engine/backends/localstack-backend.d.ts.map +0 -1
- package/dist/server/engine/backends/localstack-backend.js +0 -199
- package/dist/server/engine/backends/localstack-backend.js.map +0 -1
- package/dist/server/engine/engine-backend.d.ts +0 -17
- package/dist/server/engine/engine-backend.d.ts.map +0 -1
- package/dist/server/engine/engine-backend.js +0 -7
- package/dist/server/engine/engine-backend.js.map +0 -1
- package/dist/server/services/localstack-manager.d.ts +0 -17
- package/dist/server/services/localstack-manager.d.ts.map +0 -1
- package/dist/server/services/localstack-manager.js +0 -31
- package/dist/server/services/localstack-manager.js.map +0 -1
- package/dist/ui/assets/ApisPage-9Lk0_ZLj.js +0 -1
- package/dist/ui/assets/BucketDetailPage-CdLGW5em.js +0 -1
- package/dist/ui/assets/BucketsPage-CDP95vp8.js +0 -1
- package/dist/ui/assets/DynamoPage-CV7omZpi.js +0 -1
- package/dist/ui/assets/DynamoTablePage-C8v42fy7.js +0 -3
- package/dist/ui/assets/LambdaDetailPage-DkGxePSD.js +0 -4
- package/dist/ui/assets/LambdasPage-Bg7_taxW.js +0 -1
- package/dist/ui/assets/OpenSearchCollectionPage-Ci1hHyy2.js +0 -1
- package/dist/ui/assets/OpenSearchPage-CBKqZeim.js +0 -1
- package/dist/ui/assets/OverviewPage-D8lrE9rQ.js +0 -1
- package/dist/ui/assets/QueueDetailPage-D0DSIGZ2.js +0 -1
- package/dist/ui/assets/QueuesPage-BXebf6st.js +0 -1
- package/dist/ui/assets/SecretsPage-Be2Nw9BM.js +0 -1
- package/dist/ui/assets/SecretsPage-D3XYogv-.css +0 -1
- package/dist/ui/assets/ServiceDetailPage-DZpczZ-G.js +0 -2
- package/dist/ui/assets/ServicesPage-CdzxEqs3.js +0 -2
- package/dist/ui/assets/_plugin-vue_export-helper-DlAUqK2U.js +0 -1
- package/dist/ui/assets/index-C1Wb35Y8.css +0 -1
- package/dist/ui/assets/index-CGpxa55R.js +0 -37
- package/packages/serverless-plugin/README.md +0 -115
- package/packages/serverless-plugin/dist/index.d.ts +0 -2
- package/packages/serverless-plugin/dist/index.d.ts.map +0 -1
- package/packages/serverless-plugin/dist/index.js +0 -107
- package/packages/serverless-plugin/dist/index.js.map +0 -1
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
// OpenSearch Serverless (aoss) sidecar: the self-engine OpenSearch emulator
|
|
2
|
-
// served in-process behind the engine router, on its own port next to a
|
|
3
|
-
// LocalStack engine. No LocalStack edition provides aoss, so LSS fills the
|
|
4
|
-
// gap itself — the control plane (X-Amz-Target OpenSearchServerless.*) and
|
|
5
|
-
// the data plane (/_aoss/<collection>/...) both answer on this listener,
|
|
6
|
-
// persisted under the sidecar's own data dir. Never started in self-engine
|
|
7
|
-
// mode, where aoss is native.
|
|
8
|
-
import http from 'http';
|
|
9
|
-
import { EngineBus } from './bus.js';
|
|
10
|
-
import { createEngineStore } from './store/engine-store.js';
|
|
11
|
-
import { createEngineRequestHandler } from './http/router.js';
|
|
12
|
-
import { OpenSearchEmulator } from './emulators/opensearch/index.js';
|
|
13
|
-
// Same residency defaults as the self engine (config-manager.ts) — the
|
|
14
|
-
// sidecar hosts one emulator, so there is no reason to expose knobs for them.
|
|
15
|
-
const IDLE_UNLOAD_MS = 300_000;
|
|
16
|
-
const MEMORY_BUDGET_MB = 128;
|
|
17
|
-
export async function startAossSidecar(opts) {
|
|
18
|
-
const store = createEngineStore({
|
|
19
|
-
dataDir: opts.dataDir,
|
|
20
|
-
idleUnloadMs: IDLE_UNLOAD_MS,
|
|
21
|
-
memoryBudgetMb: MEMORY_BUDGET_MB,
|
|
22
|
-
fsync: false,
|
|
23
|
-
});
|
|
24
|
-
// The emulator resolves collectionEndpoint through ctx.endpoint() at request
|
|
25
|
-
// time; a closure over the mutable port keeps it correct once listen() has
|
|
26
|
-
// picked the real port (port 0 case).
|
|
27
|
-
let boundPort = opts.port;
|
|
28
|
-
const ctx = {
|
|
29
|
-
config: {
|
|
30
|
-
port: opts.port,
|
|
31
|
-
dataDir: opts.dataDir,
|
|
32
|
-
account: opts.account ?? '000000000000',
|
|
33
|
-
region: opts.region,
|
|
34
|
-
idleUnloadMs: IDLE_UNLOAD_MS,
|
|
35
|
-
memoryBudgetMb: MEMORY_BUDGET_MB,
|
|
36
|
-
fsync: false,
|
|
37
|
-
fallbackEndpoint: null,
|
|
38
|
-
persistence: true,
|
|
39
|
-
},
|
|
40
|
-
store,
|
|
41
|
-
bus: new EngineBus(),
|
|
42
|
-
// The OpenSearch emulator never invokes functions; the stub keeps the
|
|
43
|
-
// context honest without dragging the dispatcher (and the Lambda runtime)
|
|
44
|
-
// into the sidecar.
|
|
45
|
-
dispatcher: { invokeFunction: async () => ({ ok: true }) },
|
|
46
|
-
endpoint: () => `http://localhost:${boundPort}`,
|
|
47
|
-
};
|
|
48
|
-
const emulator = new OpenSearchEmulator(ctx);
|
|
49
|
-
const handler = createEngineRequestHandler({ ctx, emulators: [emulator] });
|
|
50
|
-
const server = http.createServer(handler);
|
|
51
|
-
// Keep-alive sockets must be destroyed for server.close() not to hang.
|
|
52
|
-
const sockets = new Set();
|
|
53
|
-
server.on('connection', socket => {
|
|
54
|
-
sockets.add(socket);
|
|
55
|
-
socket.on('close', () => sockets.delete(socket));
|
|
56
|
-
});
|
|
57
|
-
await new Promise((resolve, reject) => {
|
|
58
|
-
const onError = (err) => {
|
|
59
|
-
server.removeListener('listening', onListening);
|
|
60
|
-
if (err.code === 'EADDRINUSE') {
|
|
61
|
-
reject(new Error(`aoss sidecar could not bind port ${opts.port}: address already in use. ` +
|
|
62
|
-
'Stop the conflicting process or set aossSidecar.port to a free port.'));
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
reject(err);
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
const onListening = () => {
|
|
69
|
-
server.removeListener('error', onError);
|
|
70
|
-
resolve();
|
|
71
|
-
};
|
|
72
|
-
server.once('error', onError);
|
|
73
|
-
server.once('listening', onListening);
|
|
74
|
-
server.listen(opts.port, '0.0.0.0');
|
|
75
|
-
});
|
|
76
|
-
boundPort = server.address().port;
|
|
77
|
-
store.startSweeper();
|
|
78
|
-
return {
|
|
79
|
-
port: boundPort,
|
|
80
|
-
endpoint: `http://localhost:${boundPort}`,
|
|
81
|
-
async close() {
|
|
82
|
-
await store.flushAll();
|
|
83
|
-
store.stopSweeper();
|
|
84
|
-
await new Promise(resolve => {
|
|
85
|
-
server.close(() => resolve());
|
|
86
|
-
for (const socket of sockets)
|
|
87
|
-
socket.destroy();
|
|
88
|
-
sockets.clear();
|
|
89
|
-
});
|
|
90
|
-
},
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
//# sourceMappingURL=aoss-sidecar.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"aoss-sidecar.js","sourceRoot":"","sources":["../../../src/server/engine/aoss-sidecar.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,wEAAwE;AACxE,2EAA2E;AAC3E,2EAA2E;AAC3E,yEAAyE;AACzE,2EAA2E;AAC3E,8BAA8B;AAE9B,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAErE,uEAAuE;AACvE,8EAA8E;AAC9E,MAAM,cAAc,GAAG,OAAO,CAAC;AAC/B,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAiB7B,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAwB;IAC7D,MAAM,KAAK,GAAG,iBAAiB,CAAC;QAC9B,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,YAAY,EAAE,cAAc;QAC5B,cAAc,EAAE,gBAAgB;QAChC,KAAK,EAAE,KAAK;KACb,CAAC,CAAC;IAEH,6EAA6E;IAC7E,2EAA2E;IAC3E,sCAAsC;IACtC,IAAI,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC;IAC1B,MAAM,GAAG,GAAkB;QACzB,MAAM,EAAE;YACN,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,cAAc;YACvC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,YAAY,EAAE,cAAc;YAC5B,cAAc,EAAE,gBAAgB;YAChC,KAAK,EAAE,KAAK;YACZ,gBAAgB,EAAE,IAAI;YACtB,WAAW,EAAE,IAAI;SAClB;QACD,KAAK;QACL,GAAG,EAAE,IAAI,SAAS,EAAE;QACpB,sEAAsE;QACtE,0EAA0E;QAC1E,oBAAoB;QACpB,UAAU,EAAE,EAAE,cAAc,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;QAC1D,QAAQ,EAAE,GAAG,EAAE,CAAC,oBAAoB,SAAS,EAAE;KAChD,CAAC;IAEF,MAAM,QAAQ,GAAG,IAAI,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,0BAA0B,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC1C,uEAAuE;IACvE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC,EAAE;QAC/B,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,OAAO,GAAG,CAAC,GAA0B,EAAQ,EAAE;YACnD,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YAChD,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC9B,MAAM,CAAC,IAAI,KAAK,CACd,oCAAoC,IAAI,CAAC,IAAI,4BAA4B;oBACvE,sEAAsE,CACzE,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC;QACH,CAAC,CAAC;QACF,MAAM,WAAW,GAAG,GAAS,EAAE;YAC7B,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxC,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,SAAS,GAAI,MAAM,CAAC,OAAO,EAAkB,CAAC,IAAI,CAAC;IACnD,KAAK,CAAC,YAAY,EAAE,CAAC;IAErB,OAAO;QACL,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,oBAAoB,SAAS,EAAE;QACzC,KAAK,CAAC,KAAK;YACT,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC;YACvB,KAAK,CAAC,WAAW,EAAE,CAAC;YACpB,MAAM,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;gBAChC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC9B,KAAK,MAAM,MAAM,IAAI,OAAO;oBAAE,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC/C,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { EngineBackend } from '../engine-backend.js';
|
|
2
|
-
export declare class LocalStackBackend implements EngineBackend {
|
|
3
|
-
readonly kind: "localstack";
|
|
4
|
-
private process;
|
|
5
|
-
private _isRunning;
|
|
6
|
-
private endpoint;
|
|
7
|
-
private readonly containerName;
|
|
8
|
-
private readonly configManager;
|
|
9
|
-
constructor();
|
|
10
|
-
start(): Promise<void>;
|
|
11
|
-
stop(): Promise<void>;
|
|
12
|
-
private waitForReady;
|
|
13
|
-
isRunning(): boolean;
|
|
14
|
-
getEndpoint(): string;
|
|
15
|
-
getConfig(): {
|
|
16
|
-
endpoint: string;
|
|
17
|
-
region: string;
|
|
18
|
-
credentials: {
|
|
19
|
-
accessKeyId: string;
|
|
20
|
-
secretAccessKey: string;
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
healthDetail(): Record<string, unknown>;
|
|
24
|
-
}
|
|
25
|
-
//# sourceMappingURL=localstack-backend.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"localstack-backend.d.ts","sourceRoot":"","sources":["../../../../src/server/engine/backends/localstack-backend.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI1D,qBAAa,iBAAkB,YAAW,aAAa;IACrD,QAAQ,CAAC,IAAI,EAAG,YAAY,CAAU;IACtC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAS;IAKzB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;;IASxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA+HtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAwBb,YAAY;IAmB1B,SAAS,IAAI,OAAO;IAIpB,WAAW,IAAI,MAAM;IAIrB,SAAS;;;;;;;;IAWT,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAQxC"}
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
// LocalStack lifecycle backend (docker container, managed/external). This is
|
|
2
|
-
// the code that used to live in services/localstack-manager.ts — that module
|
|
3
|
-
// is now a thin facade over EngineManager so existing call sites keep working
|
|
4
|
-
// regardless of the active engine.
|
|
5
|
-
import { spawn, exec } from 'child_process';
|
|
6
|
-
import { promisify } from 'util';
|
|
7
|
-
import { ConfigManager } from '../../services/config-manager.js';
|
|
8
|
-
const execAsync = promisify(exec);
|
|
9
|
-
export class LocalStackBackend {
|
|
10
|
-
kind = 'localstack';
|
|
11
|
-
process = null;
|
|
12
|
-
_isRunning = false;
|
|
13
|
-
endpoint;
|
|
14
|
-
// Container name is scoped to the LocalStack port so multiple LSS instances
|
|
15
|
-
// (one per example/project) can launch their own container side by side.
|
|
16
|
-
// Falls back to "lss-localstack" when the default 4566 is in use to preserve
|
|
17
|
-
// existing teardown scripts that look for that name.
|
|
18
|
-
containerName;
|
|
19
|
-
configManager;
|
|
20
|
-
constructor() {
|
|
21
|
-
this.configManager = ConfigManager.getInstance();
|
|
22
|
-
this.endpoint = this.configManager.getLocalStackEndpoint();
|
|
23
|
-
const port = this.configManager.getLocalStackPort();
|
|
24
|
-
this.containerName = port === 4566 ? 'lss-localstack' : `lss-localstack-${port}`;
|
|
25
|
-
}
|
|
26
|
-
async start() {
|
|
27
|
-
if (this._isRunning) {
|
|
28
|
-
console.log('⚠️ LocalStack already running');
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
if (this.configManager.isExternal()) {
|
|
32
|
-
console.log(`🔗 Using external LocalStack at ${this.endpoint}`);
|
|
33
|
-
await this.waitForReady(30);
|
|
34
|
-
this._isRunning = true;
|
|
35
|
-
console.log('✅ Connected to external LocalStack');
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
try {
|
|
39
|
-
// Check if docker is available
|
|
40
|
-
await execAsync('docker ps -q', { timeout: 5000 });
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
throw new Error('Docker is not available or not running. Please start Docker first.');
|
|
44
|
-
}
|
|
45
|
-
const edition = this.configManager.getLocalStackEdition();
|
|
46
|
-
const image = this.configManager.getLocalStackImage();
|
|
47
|
-
const authToken = this.configManager.getLocalStackAuthToken();
|
|
48
|
-
if (edition === 'pro' && !authToken) {
|
|
49
|
-
throw new Error('LocalStack Pro requires LOCALSTACK_AUTH_TOKEN. Set the env var or "localstackAuthToken" in your config.');
|
|
50
|
-
}
|
|
51
|
-
if (edition === 'community' && !authToken) {
|
|
52
|
-
console.warn('⚠️ LOCALSTACK_AUTH_TOKEN not set. Recent localstack/localstack images (>= 2026.5) require a token even for the community edition.');
|
|
53
|
-
}
|
|
54
|
-
return new Promise((resolve, reject) => {
|
|
55
|
-
console.log(`🔄 Starting LocalStack (${image})...`);
|
|
56
|
-
const port = this.configManager.getLocalStackPort();
|
|
57
|
-
const services = this.configManager.getServices().join(',');
|
|
58
|
-
const persistence = this.configManager.isPersistence() ? '1' : '0';
|
|
59
|
-
const debug = this.configManager.isDebug() ? '1' : '0';
|
|
60
|
-
// Persistence volume is scoped to the container so two LSS instances
|
|
61
|
-
// don't share (and corrupt) the same on-disk state.
|
|
62
|
-
const volumeName = this.containerName === 'lss-localstack'
|
|
63
|
-
? 'lss-localstack-data'
|
|
64
|
-
: `${this.containerName}-data`;
|
|
65
|
-
const dockerArgs = [
|
|
66
|
-
'run',
|
|
67
|
-
'--rm',
|
|
68
|
-
'-p',
|
|
69
|
-
`${port}:4566`,
|
|
70
|
-
'-v',
|
|
71
|
-
`${volumeName}:/var/lib/localstack`,
|
|
72
|
-
'-v',
|
|
73
|
-
'/var/run/docker.sock:/var/run/docker.sock',
|
|
74
|
-
// host.docker.internal resolves natively on Docker Desktop but not on
|
|
75
|
-
// Linux; the generated Lambda proxies target it to reach the invoke
|
|
76
|
-
// listeners on the host, so map it explicitly (no-op elsewhere).
|
|
77
|
-
'--add-host',
|
|
78
|
-
'host.docker.internal:host-gateway',
|
|
79
|
-
'--name',
|
|
80
|
-
this.containerName,
|
|
81
|
-
'-e',
|
|
82
|
-
`SERVICES=${services}`,
|
|
83
|
-
'-e',
|
|
84
|
-
'LAMBDA_EXECUTOR=local',
|
|
85
|
-
// Lambda containers spawned BY LocalStack (which run the proxies) need
|
|
86
|
-
// the same host mapping.
|
|
87
|
-
'-e',
|
|
88
|
-
'LAMBDA_DOCKER_FLAGS=--add-host host.docker.internal:host-gateway',
|
|
89
|
-
'-e',
|
|
90
|
-
`PERSISTENCE=${persistence}`,
|
|
91
|
-
'-e',
|
|
92
|
-
`DEBUG=${debug}`,
|
|
93
|
-
];
|
|
94
|
-
if (authToken) {
|
|
95
|
-
dockerArgs.push('-e', `LOCALSTACK_AUTH_TOKEN=${authToken}`);
|
|
96
|
-
}
|
|
97
|
-
dockerArgs.push(image);
|
|
98
|
-
this.process = spawn('docker', dockerArgs);
|
|
99
|
-
let stderr = '';
|
|
100
|
-
let stdout = '';
|
|
101
|
-
this.process.stderr?.on('data', data => {
|
|
102
|
-
stderr += data.toString();
|
|
103
|
-
console.log(`[LocalStack stderr] ${data.toString().trim()}`);
|
|
104
|
-
});
|
|
105
|
-
this.process.stdout?.on('data', data => {
|
|
106
|
-
stdout += data.toString();
|
|
107
|
-
console.log(`[LocalStack stdout] ${data.toString().trim()}`);
|
|
108
|
-
});
|
|
109
|
-
this.process.on('error', error => {
|
|
110
|
-
console.error('❌ Failed to start LocalStack process:', error);
|
|
111
|
-
reject(error);
|
|
112
|
-
});
|
|
113
|
-
this.process.on('close', code => {
|
|
114
|
-
if (code !== 0) {
|
|
115
|
-
console.error(`Container exited with code ${code}`);
|
|
116
|
-
console.error('stderr:', stderr);
|
|
117
|
-
console.error('stdout:', stdout);
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
// Wait for LocalStack to be ready
|
|
121
|
-
this.waitForReady()
|
|
122
|
-
.then(() => {
|
|
123
|
-
this._isRunning = true;
|
|
124
|
-
console.log('✅ LocalStack ready');
|
|
125
|
-
resolve();
|
|
126
|
-
})
|
|
127
|
-
.catch(err => {
|
|
128
|
-
console.error('LocalStack startup error:', err.message);
|
|
129
|
-
this.process?.kill();
|
|
130
|
-
reject(err);
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
async stop() {
|
|
135
|
-
if (!this._isRunning) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
if (this.configManager.isExternal()) {
|
|
139
|
-
console.log('🔗 External LocalStack — leaving container untouched');
|
|
140
|
-
this._isRunning = false;
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
console.log('🛑 Stopping LocalStack...');
|
|
144
|
-
try {
|
|
145
|
-
await execAsync(`docker stop ${this.containerName}`, { timeout: 10000 });
|
|
146
|
-
this._isRunning = false;
|
|
147
|
-
this.process = null;
|
|
148
|
-
console.log('✅ LocalStack stopped');
|
|
149
|
-
}
|
|
150
|
-
catch (error) {
|
|
151
|
-
console.error('⚠️ Error stopping LocalStack:', error instanceof Error ? error.message : 'Unknown error');
|
|
152
|
-
this._isRunning = false;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
async waitForReady(maxAttempts = 120) {
|
|
156
|
-
for (let i = 0; i < maxAttempts; i++) {
|
|
157
|
-
try {
|
|
158
|
-
const response = await fetch(`${this.endpoint}/_localstack/health`);
|
|
159
|
-
if (response.ok) {
|
|
160
|
-
console.log(`✓ LocalStack is responsive (attempt ${i + 1}/${maxAttempts})`);
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
catch {
|
|
165
|
-
// Ignore fetch errors during startup
|
|
166
|
-
if (i % 20 === 0) {
|
|
167
|
-
console.log(`⏳ Waiting for LocalStack... (attempt ${i + 1}/${maxAttempts})`);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
171
|
-
}
|
|
172
|
-
throw new Error('LocalStack failed to start in time (120s timeout). Check Docker and container logs.');
|
|
173
|
-
}
|
|
174
|
-
isRunning() {
|
|
175
|
-
return this._isRunning;
|
|
176
|
-
}
|
|
177
|
-
getEndpoint() {
|
|
178
|
-
return this.endpoint;
|
|
179
|
-
}
|
|
180
|
-
getConfig() {
|
|
181
|
-
return {
|
|
182
|
-
endpoint: this.endpoint,
|
|
183
|
-
region: this.configManager.getRegion(),
|
|
184
|
-
credentials: {
|
|
185
|
-
accessKeyId: process.env.LOCALSTACK_ACCESS_KEY_ID || 'test',
|
|
186
|
-
secretAccessKey: process.env.LOCALSTACK_SECRET_ACCESS_KEY || 'test',
|
|
187
|
-
},
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
healthDetail() {
|
|
191
|
-
return {
|
|
192
|
-
endpoint: this.endpoint,
|
|
193
|
-
running: this._isRunning,
|
|
194
|
-
mode: this.configManager.getMode(),
|
|
195
|
-
image: this.configManager.isExternal() ? undefined : this.configManager.getLocalStackImage(),
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
//# sourceMappingURL=localstack-backend.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"localstack-backend.js","sourceRoot":"","sources":["../../../../src/server/engine/backends/localstack-backend.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export interface EngineBackend {
|
|
2
|
-
readonly kind: 'localstack' | 'self';
|
|
3
|
-
start(): Promise<void>;
|
|
4
|
-
stop(): Promise<void>;
|
|
5
|
-
isRunning(): boolean;
|
|
6
|
-
getEndpoint(): string;
|
|
7
|
-
getConfig(): {
|
|
8
|
-
endpoint: string;
|
|
9
|
-
region: string;
|
|
10
|
-
credentials: {
|
|
11
|
-
accessKeyId: string;
|
|
12
|
-
secretAccessKey: string;
|
|
13
|
-
};
|
|
14
|
-
};
|
|
15
|
-
healthDetail(): Record<string, unknown>;
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=engine-backend.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"engine-backend.d.ts","sourceRoot":"","sources":["../../../src/server/engine/engine-backend.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAAC;IACrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,SAAS,IAAI,OAAO,CAAC;IACrB,WAAW,IAAI,MAAM,CAAC;IACtB,SAAS,IAAI;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE;YAAE,WAAW,EAAE,MAAM,CAAC;YAAC,eAAe,EAAE,MAAM,CAAA;SAAE,CAAC;KAC/D,CAAC;IACF,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
// Lifecycle seam between the orchestrator and whichever AWS provider is
|
|
2
|
-
// active. Provisioning is NOT part of this interface on purpose: both engines
|
|
3
|
-
// are driven through the AWS wire API by the existing SDK-based code
|
|
4
|
-
// (provisioner, explorers, seeds), so the only thing that varies is lifecycle
|
|
5
|
-
// and endpoint. See docs/PRD_SELF_ENGINE.md §5.1.
|
|
6
|
-
export {};
|
|
7
|
-
//# sourceMappingURL=engine-backend.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"engine-backend.js","sourceRoot":"","sources":["../../../src/server/engine/engine-backend.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,8EAA8E;AAC9E,qEAAqE;AACrE,8EAA8E;AAC9E,kDAAkD"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export declare class LocalStackManager {
|
|
2
|
-
private static instance;
|
|
3
|
-
static getInstance(): LocalStackManager;
|
|
4
|
-
start(): Promise<void>;
|
|
5
|
-
stop(): Promise<void>;
|
|
6
|
-
isRunning(): boolean;
|
|
7
|
-
getEndpoint(): string;
|
|
8
|
-
getConfig(): {
|
|
9
|
-
endpoint: string;
|
|
10
|
-
region: string;
|
|
11
|
-
credentials: {
|
|
12
|
-
accessKeyId: string;
|
|
13
|
-
secretAccessKey: string;
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=localstack-manager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"localstack-manager.d.ts","sourceRoot":"","sources":["../../../src/server/services/localstack-manager.ts"],"names":[],"mappings":"AAQA,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAoB;IAE3C,MAAM,CAAC,WAAW,IAAI,iBAAiB;IAOjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,SAAS,IAAI,OAAO;IAIpB,WAAW,IAAI,MAAM;IAIrB,SAAS,IAAI;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE;YAAE,WAAW,EAAE,MAAM,CAAC;YAAC,eAAe,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE;CAGjH"}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
// Deprecated facade kept so the ~10 existing call sites (provisioner,
|
|
2
|
-
// explorers, seeds, dynamo-proxy, routes) stay untouched: they keep importing
|
|
3
|
-
// LocalStackManager, but the active provider may be the LocalStack container
|
|
4
|
-
// OR the in-process self engine — EngineManager decides from the config.
|
|
5
|
-
// New code should use EngineManager directly.
|
|
6
|
-
import { EngineManager } from '../engine/engine-manager.js';
|
|
7
|
-
export class LocalStackManager {
|
|
8
|
-
static instance;
|
|
9
|
-
static getInstance() {
|
|
10
|
-
if (!LocalStackManager.instance) {
|
|
11
|
-
LocalStackManager.instance = new LocalStackManager();
|
|
12
|
-
}
|
|
13
|
-
return LocalStackManager.instance;
|
|
14
|
-
}
|
|
15
|
-
async start() {
|
|
16
|
-
return EngineManager.getInstance().start();
|
|
17
|
-
}
|
|
18
|
-
async stop() {
|
|
19
|
-
return EngineManager.getInstance().stop();
|
|
20
|
-
}
|
|
21
|
-
isRunning() {
|
|
22
|
-
return EngineManager.getInstance().isRunning();
|
|
23
|
-
}
|
|
24
|
-
getEndpoint() {
|
|
25
|
-
return EngineManager.getInstance().getEndpoint();
|
|
26
|
-
}
|
|
27
|
-
getConfig() {
|
|
28
|
-
return EngineManager.getInstance().getConfig();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
//# sourceMappingURL=localstack-manager.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"localstack-manager.js","sourceRoot":"","sources":["../../../src/server/services/localstack-manager.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,8EAA8E;AAC9E,6EAA6E;AAC7E,yEAAyE;AACzE,8CAA8C;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,MAAM,OAAO,iBAAiB;IACpB,MAAM,CAAC,QAAQ,CAAoB;IAE3C,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,CAAC;YAChC,iBAAiB,CAAC,QAAQ,GAAG,IAAI,iBAAiB,EAAE,CAAC;QACvD,CAAC;QACD,OAAO,iBAAiB,CAAC,QAAQ,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,KAAK;QACT,OAAO,aAAa,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,aAAa,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAC5C,CAAC;IAED,SAAS;QACP,OAAO,aAAa,CAAC,WAAW,EAAE,CAAC,SAAS,EAAE,CAAC;IACjD,CAAC;IAED,WAAW;QACT,OAAO,aAAa,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,CAAC;IACnD,CAAC;IAED,SAAS;QACP,OAAO,aAAa,CAAC,WAAW,EAAE,CAAC,SAAS,EAAE,CAAC;IACjD,CAAC;CACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{k as R,l as q,o as E,m as u,e as d,W as t,t as p,$ as e,j as n,y as J,z as w,J as W,i,V as s,f as y,v as X,B as N,g as T,F as I,n as Y,u as G,C as P,A as S,w as v,q as c,R as H,s as _,x as K,D as O,r as z,b as Q,a as x,c as Z}from"./index-CGpxa55R.js";const ee=R({__name:"ApisView",setup(V){const k=Z(),f=z([]),h=z(!0),g=z(null),m=z({});let b=null;const F=[{key:"method",label:"Method"},{key:"path",label:"Path"},{key:"functionName",label:"→ Function"},{key:"eventType",label:"Type"},{key:"authorizerName",label:"Auth"},{key:"actions",label:"",align:"right"}],j=[{key:"name",label:"Name"},{key:"type",label:"Type"},{key:"payloadVersion",label:"Payload"},{key:"resultTtlInSeconds",label:"TTL",align:"right"},{key:"identitySource",label:"Identity source"},{key:"target",label:"Function / ARN"}],$=Q(()=>({services:f.value.length,routes:f.value.reduce((r,l)=>r+l.routes.length,0),online:f.value.filter(r=>r.status==="online").length}));function B(r){return r.routes.map(l=>({...l}))}function L(r){return r.authorizers.map(l=>({...l,identitySource:l.identitySource.join(", "),target:l.functionName||l.arn||""}))}async function A(){try{f.value=await x.listApis(),g.value=null}catch(r){g.value=r.message||"Failed to load APIs"}finally{h.value=!1}}async function D(r){if(!m.value[r]){m.value={...m.value,[r]:!0};try{const l=await x.clearAuthorizerCache({service:r});k.add({title:"Authorizer cache cleared",description:`${l.removed} cached result${l.removed===1?"":"s"} removed`,variant:"success"})}catch(l){k.add({title:"Failed to clear authorizer cache",description:l.message,variant:"danger"})}finally{m.value={...m.value,[r]:!1}}}}function U(r,l){var a;const o=`curl -X ${l.method} http://localhost:${r.apiPort}${l.path}`;(a=navigator.clipboard)==null||a.writeText(o).then(()=>{k.add({title:"curl command copied",description:o,variant:"success"})})}function C(r){switch(r){case"online":return"success";case"port-conflict":return"warning";default:return"neutral"}}function M(r){return r==="ANY"?"info":"neutral"}return q(()=>{A(),b=window.setInterval(A,1e4)}),E(()=>{b&&window.clearInterval(b)}),(r,l)=>(u(),d(t(p),{direction:"vertical",gap:"1.25rem"},{default:e(()=>[n(t(J),{columns:3,gap:"1rem"},{default:e(()=>[n(t(w),{label:"Services with APIs",value:$.value.services,tone:"info",loading:h.value},null,8,["value","loading"]),n(t(w),{label:"Routes",value:$.value.routes,tone:"info",loading:h.value},null,8,["value","loading"]),n(t(w),{label:"Listeners online",value:$.value.online,tone:"success",loading:h.value},null,8,["value","loading"])]),_:1}),g.value?(u(),d(t(W),{key:0,variant:"danger",dismissible:"",onDismiss:l[0]||(l[0]=o=>g.value=null)},{default:e(()=>[i(s(g.value),1)]),_:1})):y("",!0),h.value&&!f.value.length?(u(),d(t(p),{key:1,direction:"horizontal",justify:"center",align:"center"},{default:e(()=>[n(t(X),{label:"Loading APIs..."})]),_:1})):f.value.length?y("",!0):(u(),d(t(N),{key:2,title:"No APIs registered",description:"Register a microservice that defines http or httpApi events to see its routes here."})),(u(!0),T(I,null,Y(f.value,o=>(u(),d(t(G),{key:o.service,variant:"outline"},{header:e(()=>[n(t(p),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between",wrap:""},{default:e(()=>[n(t(p),{direction:"horizontal",gap:"0.5rem",align:"center",wrap:""},{default:e(()=>[n(t(O),{to:`/services/${encodeURIComponent(o.service)}`},{default:e(()=>[n(t(c),{weight:"semibold"},{default:e(()=>[i(s(o.service),1)]),_:2},1024)]),_:2},1032,["to"]),o.apiPort?(u(),d(t(_),{key:0,tone:"info",variant:"soft"},{default:e(()=>[i(":"+s(o.apiPort),1)]),_:2},1024)):y("",!0),n(t(_),{tone:C(o.status),variant:"soft"},{default:e(()=>[i(s(o.status),1)]),_:2},1032,["tone"]),o.invokePort?(u(),d(t(_),{key:1,tone:C(o.invokeStatus),variant:"soft"},{default:e(()=>[i(" invoke :"+s(o.invokePort),1)]),_:2},1032,["tone"])):y("",!0),o.stage?(u(),d(t(v),{key:2,size:"sm",variant:"soft"},{default:e(()=>[i("stage: "+s(o.stage),1)]),_:2},1024)):y("",!0)]),_:2},1024),n(t(S),{size:"sm",variant:"ghost",loading:m.value[o.service],onClick:a=>D(o.service)},{default:e(()=>[...l[1]||(l[1]=[i(" Clear authorizer cache ",-1)])]),_:1},8,["loading","onClick"])]),_:2},1024)]),default:e(()=>[n(t(p),{direction:"vertical",gap:"0.75rem"},{default:e(()=>[o.routes.length?(u(),d(t(P),{key:0,columns:F,rows:B(o),"aria-label":"API routes"},{"cell-method":e(({row:a})=>[n(t(_),{tone:M(String(a.method)),variant:"soft"},{default:e(()=>[i(s(a.method),1)]),_:2},1032,["tone"])]),"cell-path":e(({row:a})=>[n(t(c),{family:"mono"},{default:e(()=>[i(s(a.path),1)]),_:2},1024)]),"cell-functionName":e(({row:a})=>[n(t(H),{to:`/lambdas/${encodeURIComponent(String(a.functionName))}`,style:{"text-decoration":"none"}},{default:e(()=>[n(t(v),{size:"sm",variant:"soft",clickable:""},{default:e(()=>[i(s(a.functionName),1)]),_:2},1024)]),_:2},1032,["to"])]),"cell-eventType":e(({row:a})=>[n(t(v),{size:"sm",variant:"soft"},{default:e(()=>[i(s(a.payloadVersion==="2.0"?"v2":"v1"),1)]),_:2},1024)]),"cell-authorizerName":e(({row:a})=>[a.authorizerName?(u(),d(t(v),{key:0,size:"sm",variant:"soft"},{default:e(()=>[i(s(a.authorizerName),1)]),_:2},1024)):(u(),d(t(c),{key:1,tone:"muted"},{default:e(()=>[...l[2]||(l[2]=[i("—",-1)])]),_:1}))]),"cell-actions":e(({row:a})=>[n(t(p),{direction:"horizontal",gap:"0.375rem",justify:"flex-end"},{default:e(()=>[n(t(S),{size:"sm",variant:"ghost",onClick:te=>U(o,a)},{default:e(()=>[...l[3]||(l[3]=[i(" Copy curl ",-1)])]),_:1},8,["onClick"])]),_:2},1024)]),_:2},1032,["rows"])):(u(),d(t(N),{key:1,title:"No routes",description:"This service exposes no http or httpApi routes."})),o.authorizers.length?(u(),T(I,{key:2},[n(t(K)),n(t(c),{weight:"semibold",size:"sm"},{default:e(()=>[...l[4]||(l[4]=[i("Authorizers",-1)])]),_:1}),n(t(P),{columns:j,rows:L(o),"aria-label":"Authorizers"},{"cell-name":e(({row:a})=>[n(t(c),{family:"mono",size:"sm"},{default:e(()=>[i(s(a.name),1)]),_:2},1024)]),"cell-type":e(({row:a})=>[n(t(v),{size:"sm",variant:"soft"},{default:e(()=>[i(s(a.type),1)]),_:2},1024)]),"cell-payloadVersion":e(({row:a})=>[n(t(v),{size:"sm",variant:"soft"},{default:e(()=>[i(s(a.payloadVersion==="2.0"?"v2":"v1"),1)]),_:2},1024)]),"cell-resultTtlInSeconds":e(({row:a})=>[n(t(c),{family:"mono",size:"sm"},{default:e(()=>[i(s(a.resultTtlInSeconds)+"s",1)]),_:2},1024)]),"cell-identitySource":e(({row:a})=>[n(t(c),{family:"mono",size:"xs"},{default:e(()=>[i(s(a.identitySource||"—"),1)]),_:2},1024)]),"cell-target":e(({row:a})=>[a.target?(u(),d(t(c),{key:0,family:"mono",size:"xs"},{default:e(()=>[i(s(a.target),1)]),_:2},1024)):(u(),d(t(c),{key:1,tone:"muted"},{default:e(()=>[...l[5]||(l[5]=[i("—",-1)])]),_:1}))]),_:1},8,["rows"])],64)):y("",!0)]),_:2},1024)]),_:2},1024))),128))]),_:1}))}}),le=R({__name:"ApisPage",setup(V){return(k,f)=>(u(),d(ee))}});export{le as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{k as L,l as P,_ as W,e as f,W as t,t as r,$ as a,a as g,m as c,j as l,A as p,p as Y,i,q as $,V as b,s as Z,f as M,J as Q,v as F,g as X,z as x,y as ee,I as U,a0 as te,Z as ae,d as T,u as _,B as le,C as ne,D as oe,a1 as ie,F as ue,c as re,r as s,b as se,Y as de}from"./index-CGpxa55R.js";const ce=["href"],fe=L({__name:"BucketDetail",props:{bucketName:{}},emits:["back"],setup(z,{emit:N}){const d=z,S=N,v=re(),u=s(null),k=s([]),V=s(""),K=s(!0),B=s(!1),y=s(null),j=s(""),w=s(""),h=s("text/plain"),C=s(!1),q=[{key:"key",label:"Key"},{key:"size",label:"Size",align:"right"},{key:"lastModified",label:"Modified"},{key:"actions",label:"",align:"right"}],A=se(()=>k.value.reduce((o,e)=>o+(e.size||0),0));function O(o){if(o==null)return"—";if(o===0)return"0 B";const e=["B","KB","MB","GB","TB"],n=Math.floor(Math.log(o)/Math.log(1024));return`${(o/Math.pow(1024,n)).toFixed(n===0?0:1)} ${e[n]}`}function E(o){return o?new Date(o).toLocaleString():"—"}async function D(){try{u.value=await g.getBucket(d.bucketName),y.value=null}catch(o){y.value=o.message||"Failed to load bucket",u.value=null}finally{K.value=!1}}async function m(){B.value=!0;try{const o=await g.listBucketObjects(d.bucketName,{prefix:V.value||void 0,maxKeys:200});k.value=o.objects}catch(o){v.add({title:"Failed to load objects",description:o.message,variant:"danger"})}finally{B.value=!1}}function R(o){return g.bucketObjectContentUrl(d.bucketName,o,!1)}function G(o){return g.bucketObjectContentUrl(d.bucketName,o,!0)}async function H(o){if(confirm(`Delete object "${o}"?`))try{await g.deleteBucketObject(d.bucketName,o),v.add({title:"Object deleted",variant:"info"}),await m()}catch(e){v.add({title:"Failed to delete object",description:e.message,variant:"danger"})}}async function I(){if(!j.value||!w.value){v.add({title:"Key and body are required",variant:"warning"});return}C.value=!0;try{await g.putBucketObject(d.bucketName,{key:j.value,body:w.value,contentType:h.value||void 0}),v.add({title:"Object uploaded",variant:"info"}),j.value="",w.value="",await m(),await D()}catch(o){v.add({title:"Failed to upload object",description:o.message,variant:"danger"})}finally{C.value=!1}}return P(()=>{D(),m()}),W(()=>d.bucketName,()=>{D(),m()}),(o,e)=>(c(),f(t(r),{direction:"vertical",gap:"1rem"},{default:a(()=>[l(t(r),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:a(()=>[l(t(r),{direction:"horizontal",gap:"0.5rem",align:"center"},{default:a(()=>{var n;return[l(t(p),{size:"sm",variant:"ghost",onClick:e[0]||(e[0]=J=>S("back"))},{default:a(()=>[l(t(Y),{name:"arrow-left"}),e[9]||(e[9]=i(" Buckets",-1))]),_:1}),l(t($),{size:"lg",weight:"semibold"},{default:a(()=>[i(b(z.bucketName),1)]),_:1}),(n=u.value)!=null&&n.versioning?(c(),f(t(Z),{key:0,tone:"info",variant:"soft"},{default:a(()=>[...e[10]||(e[10]=[i("Versioning",-1)])]),_:1})):M("",!0)]}),_:1}),l(t(p),{size:"sm",variant:"ghost",loading:B.value,onClick:e[1]||(e[1]=n=>m())},{default:a(()=>[...e[11]||(e[11]=[i("Refresh",-1)])]),_:1},8,["loading"])]),_:1}),y.value?(c(),f(t(Q),{key:0,variant:"danger",dismissible:"",onDismiss:e[2]||(e[2]=n=>y.value=null)},{default:a(()=>[i(b(y.value),1)]),_:1})):M("",!0),K.value&&!u.value?(c(),f(t(r),{key:1,direction:"horizontal",justify:"center",align:"center"},{default:a(()=>[l(t(F),{label:"Loading bucket..."})]),_:1})):u.value?(c(),X(ue,{key:2},[l(t(ee),{columns:4,gap:"0.75rem"},{default:a(()=>[l(t(x),{label:"Objects",value:u.value.objectCount??0,tone:"info"},null,8,["value"]),l(t(x),{label:"Size",value:O(u.value.totalSize),tone:"neutral"},null,8,["value"]),l(t(x),{label:"Versioning",value:u.value.versioning?"Enabled":"Disabled",tone:u.value.versioning?"success":"neutral"},null,8,["value","tone"]),l(t(x),{label:"Notifications",value:u.value.notifications??0,tone:(u.value.notifications??0)>0?"info":"neutral"},null,8,["value","tone"])]),_:1}),l(t(_),{variant:"outline"},{header:a(()=>[l(t($),{weight:"semibold"},{default:a(()=>[...e[12]||(e[12]=[i("Upload object",-1)])]),_:1})]),default:a(()=>[l(t(r),{direction:"vertical",gap:"0.5rem"},{default:a(()=>[l(t(U),{modelValue:j.value,"onUpdate:modelValue":e[3]||(e[3]=n=>j.value=n),placeholder:"object/key.txt",label:"Key"},null,8,["modelValue"]),l(t(U),{modelValue:h.value,"onUpdate:modelValue":e[4]||(e[4]=n=>h.value=n),placeholder:"text/plain",label:"Content-Type"},null,8,["modelValue"]),l(t($),{as:"label",tone:"muted",size:"sm"},{default:a(()=>[...e[13]||(e[13]=[i("Body",-1)])]),_:1}),te(T("textarea",{"onUpdate:modelValue":e[5]||(e[5]=n=>w.value=n),rows:"4",style:{width:"100%","font-family":"var(--tree-font-mono, monospace)",padding:"0.5rem"},placeholder:"Hello, world!"},null,512),[[ae,w.value]]),l(t(r),{direction:"horizontal",justify:"flex-end"},{default:a(()=>[l(t(p),{size:"sm",loading:C.value,onClick:I},{default:a(()=>[...e[14]||(e[14]=[i("Upload",-1)])]),_:1},8,["loading"])]),_:1})]),_:1})]),_:1}),l(t(_),{variant:"outline"},{header:a(()=>[l(t(r),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:a(()=>[l(t($),{weight:"semibold"},{default:a(()=>[i("Objects ("+b(k.value.length)+" · "+b(O(A.value))+")",1)]),_:1}),l(t(r),{direction:"horizontal",gap:"0.5rem",align:"center"},{default:a(()=>[l(t(U),{modelValue:V.value,"onUpdate:modelValue":e[6]||(e[6]=n=>V.value=n),placeholder:"prefix filter",size:"sm",onKeyup:e[7]||(e[7]=ie(n=>m(),["enter"]))},null,8,["modelValue"]),l(t(p),{size:"sm",variant:"ghost",onClick:e[8]||(e[8]=n=>m())},{default:a(()=>[...e[15]||(e[15]=[i("Apply",-1)])]),_:1})]),_:1})]),_:1})]),default:a(()=>[B.value?(c(),f(t(r),{key:0,direction:"horizontal",justify:"center",align:"center"},{default:a(()=>[l(t(F),{label:"Loading objects..."})]),_:1})):k.value.length?(c(),f(t(ne),{key:2,columns:q,rows:k.value,"aria-label":"Bucket objects"},{"cell-key":a(({row:n})=>[l(t(oe),{href:R(String(n.key)),external:"",style:{"font-weight":"500"}},{default:a(()=>[i(b(n.key),1)]),_:2},1032,["href"])]),"cell-size":a(({row:n})=>[i(b(O(Number(n.size))),1)]),"cell-lastModified":a(({row:n})=>[i(b(E(n.lastModified)),1)]),"cell-actions":a(({row:n})=>[l(t(r),{direction:"horizontal",gap:"0.25rem",justify:"flex-end"},{default:a(()=>[T("a",{href:G(String(n.key)),target:"_blank",rel:"noopener noreferrer",style:{"text-decoration":"none"}},[l(t(p),{size:"sm",variant:"ghost"},{default:a(()=>[...e[16]||(e[16]=[i("Download",-1)])]),_:1})],8,ce),l(t(p),{size:"sm",variant:"ghost",tone:"danger",onClick:J=>H(String(n.key))},{default:a(()=>[...e[17]||(e[17]=[i(" Delete ",-1)])]),_:1},8,["onClick"])]),_:2},1024)]),_:1},8,["rows"])):(c(),f(t(le),{key:1,title:"No objects",description:"This bucket is empty (or the prefix filter excluded everything)."}))]),_:1})],64)):M("",!0)]),_:1}))}}),me=L({__name:"BucketDetailPage",props:{bucketName:{}},setup(z){const N=de();function d(){N.push("/buckets")}return(S,v)=>(c(),f(fe,{"bucket-name":z.bucketName,onBack:d},null,8,["bucket-name"]))}});export{me as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{k as C,Y as N,l as V,o as D,m as i,e as u,W as a,t as b,$ as t,j as o,y as I,z as p,J as O,i as s,V as c,f as T,u as U,v as L,B as q,C as F,A as P,s as _,R as A,w as E,q as y,D as G,r as f,b as S,a as w}from"./index-CGpxa55R.js";const J=C({__name:"BucketsView",setup(j){const $=N(),r=f([]),B=f({}),d=f(!0),v=f(null);let m=null;const R=[{key:"name",label:"Bucket"},{key:"service",label:"Service"},{key:"objectCount",label:"Objects",align:"right"},{key:"totalSize",label:"Size",align:"right"},{key:"versioning",label:"Versioning"},{key:"notifications",label:"Notifications",align:"right"},{key:"actions",label:"",align:"right"}],x=S(()=>r.value.map(n=>({...n,service:B.value[n.name]||""}))),g=S(()=>({buckets:r.value.length,objects:r.value.reduce((n,l)=>n+(l.objectCount||0),0),size:r.value.reduce((n,l)=>n+(l.totalSize||0),0)}));function h(n){if(n==null)return"—";if(n===0)return"0 B";const l=["B","KB","MB","GB","TB"],e=Math.floor(Math.log(n)/Math.log(1024));return`${(n/Math.pow(1024,e)).toFixed(e===0?0:1)} ${l[e]}`}async function z(){try{const[n,l]=await Promise.all([w.listBuckets(),w.listResourceOwners().catch(()=>({tables:[],queues:[],topics:[],buckets:[]}))]);r.value=n;const e={};for(const k of l.buckets||[])e[k.name]=k.service;B.value=e,v.value=null}catch(n){v.value=n.message||"Failed to load buckets"}finally{d.value=!1}}function M(n){$.push(`/buckets/${encodeURIComponent(n)}`)}return V(()=>{z(),m=window.setInterval(z,1e4)}),D(()=>{m&&window.clearInterval(m)}),(n,l)=>(i(),u(a(b),{direction:"vertical",gap:"1.25rem"},{default:t(()=>[o(a(I),{columns:3,gap:"1rem"},{default:t(()=>[o(a(p),{label:"Buckets",value:g.value.buckets,tone:"info",loading:d.value},null,8,["value","loading"]),o(a(p),{label:"Objects",value:g.value.objects,tone:"success",loading:d.value},null,8,["value","loading"]),o(a(p),{label:"Total size",value:h(g.value.size),tone:"neutral",loading:d.value},null,8,["value","loading"])]),_:1}),v.value?(i(),u(a(O),{key:0,variant:"danger",dismissible:"",onDismiss:l[0]||(l[0]=e=>v.value=null)},{default:t(()=>[s(c(v.value),1)]),_:1})):T("",!0),o(a(U),{variant:"outline"},{header:t(()=>[o(a(b),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:t(()=>[o(a(y),{weight:"semibold"},{default:t(()=>[...l[1]||(l[1]=[s("S3 Buckets",-1)])]),_:1}),o(a(y),{tone:"muted"},{default:t(()=>[...l[2]||(l[2]=[s("Refreshes every 10s",-1)])]),_:1})]),_:1})]),default:t(()=>[d.value?(i(),u(a(b),{key:0,direction:"horizontal",justify:"center",align:"center"},{default:t(()=>[o(a(L),{label:"Loading buckets..."})]),_:1})):r.value.length?(i(),u(a(F),{key:2,columns:R,rows:x.value,"aria-label":"S3 buckets"},{"cell-name":t(({row:e})=>[o(a(G),{to:`/buckets/${encodeURIComponent(String(e.name))}`,style:{"font-weight":"600"}},{default:t(()=>[s(c(e.name),1)]),_:2},1032,["to"])]),"cell-service":t(({row:e})=>[e.service?(i(),u(a(A),{key:0,to:`/services/${encodeURIComponent(String(e.service))}`,style:{"text-decoration":"none"}},{default:t(()=>[o(a(E),{size:"sm",variant:"soft",clickable:""},{default:t(()=>[s(c(e.service),1)]),_:2},1024)]),_:2},1032,["to"])):(i(),u(a(y),{key:1,tone:"muted",size:"xs"},{default:t(()=>[...l[3]||(l[3]=[s("unmanaged",-1)])]),_:1}))]),"cell-objectCount":t(({row:e})=>[o(a(_),{tone:"info",variant:"soft"},{default:t(()=>[s(c(e.objectCount??0),1)]),_:2},1024)]),"cell-totalSize":t(({row:e})=>[s(c(h(e.totalSize)),1)]),"cell-versioning":t(({row:e})=>[o(a(_),{tone:e.versioning?"success":"neutral",variant:"soft"},{default:t(()=>[s(c(e.versioning?"Enabled":"Disabled"),1)]),_:2},1032,["tone"])]),"cell-notifications":t(({row:e})=>[o(a(_),{tone:Number(e.notifications)>0?"info":"neutral",variant:"soft"},{default:t(()=>[s(c(e.notifications??0),1)]),_:2},1032,["tone"])]),"cell-actions":t(({row:e})=>[o(a(P),{size:"sm",variant:"ghost",onClick:k=>M(String(e.name))},{default:t(()=>[...l[4]||(l[4]=[s(" Open ",-1)])]),_:1},8,["onClick"])]),_:1},8,["rows"])):(i(),u(a(q),{key:1,title:"No buckets found",description:"Register a microservice that defines S3 resources or create buckets directly in LocalStack."}))]),_:1})]),_:1}))}}),W=C({__name:"BucketsPage",setup(j){return($,r)=>(i(),u(J))}});export{W as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{k as A,l as U,o as j,m as n,e as l,W as a,t as v,$ as s,j as u,y as q,z as D,J as F,i as o,V as r,f as b,u as W,v as H,B as G,C as J,A as Y,q as m,w as c,s as R,R as Q,I as X,r as p,b as S,a as L,Y as Z}from"./index-CGpxa55R.js";const ee=A({__name:"DynamoTablesList",emits:["open"],setup(K,{emit:z}){const N=z,d=p([]),k=p([]),_=p({}),y=p(!0),C=p(null),$=p("");let I=null;const M=[{key:"name",label:"Table"},{key:"service",label:"Service"},{key:"status",label:"Status"},{key:"itemCount",label:"Items",align:"right"},{key:"seed",label:"Seed"},{key:"features",label:"Features"},{key:"actions",label:"",align:"right"}],h=S(()=>{const i=d.value.map(e=>{var P,V;const t=(P=e.keySchema.find(x=>x.KeyType==="HASH"))==null?void 0:P.AttributeName,f=(V=e.keySchema.find(x=>x.KeyType==="RANGE"))==null?void 0:V.AttributeName,w=f?`PK: ${t} · SK: ${f}`:`PK: ${t??"—"}`,E=k.value.find(x=>x.tableName===e.name);return{name:e.name,status:e.status,itemCount:e.itemCount||0,keyDescriptor:w,billingMode:e.billingMode,ttlOn:e.ttl.enabled,streamOn:e.streamEnabled,hasGsi:e.hasGsi,hasLsi:e.hasLsi,service:_.value[e.name]||"",seedItemCount:E?E.itemCount:null,exists:!0}});for(const e of k.value)!e.tableExists&&!i.some(t=>t.name===e.tableName)&&i.push({name:e.tableName,status:"PENDING",itemCount:0,keyDescriptor:"—",ttlOn:!1,streamOn:!1,hasGsi:!1,hasLsi:!1,service:_.value[e.tableName]||"",seedItemCount:e.itemCount,exists:!1});return i.sort((e,t)=>e.name.localeCompare(t.name))}),T=S(()=>{const i=$.value.trim().toLowerCase();return i?h.value.filter(e=>e.name.toLowerCase().includes(i)||(e.service||"").toLowerCase().includes(i)):h.value}),g=S(()=>({tables:d.value.length,items:d.value.reduce((i,e)=>i+(e.itemCount||0),0),warnings:d.value.reduce((i,e)=>{var t;return i+(((t=e.warnings)==null?void 0:t.length)||0)},0),seedsPending:k.value.filter(i=>!i.tableExists).length}));async function B(){try{const[i,e,t]=await Promise.all([L.listDynamoTables(),L.listSeeds().catch(()=>({seedsDir:"",entries:[]})),L.listResourceOwners().catch(()=>({tables:[],queues:[],topics:[],buckets:[]}))]);d.value=i.tables,k.value=e.entries;const f={};for(const w of t.tables)f[w.name]=w.service;_.value=f,C.value=null}catch(i){C.value=i.message||"Failed to load DynamoDB tables"}finally{y.value=!1}}function O(i){i.exists&&N("open",i.name)}return U(()=>{B(),I=window.setInterval(B,15e3)}),j(()=>{I&&window.clearInterval(I)}),(i,e)=>(n(),l(a(v),{direction:"vertical",gap:"1.25rem"},{default:s(()=>[u(a(q),{columns:4,gap:"1rem"},{default:s(()=>[u(a(D),{label:"Tables",value:g.value.tables,tone:"info",loading:y.value},null,8,["value","loading"]),u(a(D),{label:"Total items",value:g.value.items,tone:"success",loading:y.value},null,8,["value","loading"]),u(a(D),{label:"Seeds pending",value:g.value.seedsPending,tone:g.value.seedsPending>0?"warning":"neutral",loading:y.value},null,8,["value","tone","loading"]),u(a(D),{label:"Warnings",value:g.value.warnings,tone:g.value.warnings>0?"warning":"neutral",loading:y.value},null,8,["value","tone","loading"])]),_:1}),C.value?(n(),l(a(F),{key:0,variant:"danger",dismissible:"",onDismiss:e[0]||(e[0]=t=>C.value=null)},{default:s(()=>[o(r(C.value),1)]),_:1})):b("",!0),u(a(W),{variant:"outline"},{header:s(()=>[u(a(v),{direction:"horizontal",justify:"space-between",align:"center",gap:"1rem"},{default:s(()=>[u(a(m),{weight:"semibold"},{default:s(()=>[...e[2]||(e[2]=[o("DynamoDB tables",-1)])]),_:1}),u(a(v),{direction:"horizontal",align:"center",gap:"1rem"},{default:s(()=>[u(a(X),{modelValue:$.value,"onUpdate:modelValue":e[1]||(e[1]=t=>$.value=t),placeholder:"Filter tables...",style:{"min-width":"16rem"}},null,8,["modelValue"]),u(a(m),{tone:"muted",size:"xs"},{default:s(()=>[...e[3]||(e[3]=[o(" Rows with reduced opacity exist only as a seed file ",-1)])]),_:1})]),_:1})]),_:1})]),default:s(()=>[y.value?(n(),l(a(v),{key:0,direction:"horizontal",justify:"center",align:"center"},{default:s(()=>[u(a(H),{label:"Loading tables..."})]),_:1})):h.value.length?T.value.length?(n(),l(a(J),{key:3,columns:M,rows:T.value,"row-key":"name","row-state":t=>t.exists?"default":"muted","aria-label":"DynamoDB tables"},{"cell-name":s(({row:t})=>[u(a(v),{direction:"vertical",gap:"0.125rem"},{default:s(()=>[t.exists?(n(),l(a(m),{key:0,weight:"semibold",style:{cursor:"pointer","text-decoration":"underline","text-decoration-style":"dotted","text-underline-offset":"3px"},onClick:f=>O(t)},{default:s(()=>[o(r(t.name),1)]),_:2},1032,["onClick"])):(n(),l(a(v),{key:1,direction:"horizontal",gap:"0.375rem",align:"center"},{default:s(()=>[u(a(m),{weight:"semibold"},{default:s(()=>[o(r(t.name),1)]),_:2},1024),u(a(c),{size:"sm",variant:"soft"},{default:s(()=>[...e[4]||(e[4]=[o("seed only",-1)])]),_:1})]),_:2},1024)),u(a(m),{tone:"muted",family:"mono",size:"xs"},{default:s(()=>[o(r(t.keyDescriptor),1)]),_:2},1024)]),_:2},1024)]),"cell-service":s(({row:t})=>[t.service?(n(),l(a(Q),{key:0,to:`/services/${encodeURIComponent(String(t.service))}`,style:{"text-decoration":"none"}},{default:s(()=>[u(a(c),{size:"sm",variant:"soft",clickable:""},{default:s(()=>[o(r(t.service),1)]),_:2},1024)]),_:2},1032,["to"])):(n(),l(a(m),{key:1,tone:"muted",size:"xs"},{default:s(()=>[...e[5]||(e[5]=[o("—",-1)])]),_:1}))]),"cell-status":s(({row:t})=>[t.exists?(n(),l(a(R),{key:0,tone:t.status==="ACTIVE"?"success":"warning",variant:"soft"},{default:s(()=>[o(r(t.status||"UNKNOWN"),1)]),_:2},1032,["tone"])):(n(),l(a(R),{key:1,tone:"warning",variant:"outline"},{default:s(()=>[...e[6]||(e[6]=[o("Not created",-1)])]),_:1}))]),"cell-itemCount":s(({row:t})=>[o(r(t.exists?t.itemCount:"—"),1)]),"cell-seed":s(({row:t})=>[t.seedItemCount!==null?(n(),l(a(R),{key:0,tone:t.exists?"info":"warning",variant:"soft"},{default:s(()=>[o(r(t.seedItemCount)+" seeded item"+r(t.seedItemCount===1?"":"s"),1)]),_:2},1032,["tone"])):(n(),l(a(m),{key:1,tone:"muted",size:"xs"},{default:s(()=>[...e[7]||(e[7]=[o("no seed",-1)])]),_:1}))]),"cell-features":s(({row:t})=>[u(a(v),{direction:"horizontal",gap:"0.25rem",wrap:""},{default:s(()=>[t.billingMode?(n(),l(a(c),{key:0,size:"sm",variant:"soft"},{default:s(()=>[o(r(t.billingMode),1)]),_:2},1024)):b("",!0),t.ttlOn?(n(),l(a(c),{key:1,size:"sm",variant:"solid"},{default:s(()=>[...e[8]||(e[8]=[o("TTL",-1)])]),_:1})):b("",!0),t.streamOn?(n(),l(a(c),{key:2,size:"sm",variant:"solid"},{default:s(()=>[...e[9]||(e[9]=[o("Streams",-1)])]),_:1})):b("",!0),t.hasGsi?(n(),l(a(c),{key:3,size:"sm",variant:"soft"},{default:s(()=>[...e[10]||(e[10]=[o("GSI",-1)])]),_:1})):b("",!0),t.hasLsi?(n(),l(a(c),{key:4,size:"sm",variant:"soft"},{default:s(()=>[...e[11]||(e[11]=[o("LSI",-1)])]),_:1})):b("",!0)]),_:2},1024)]),"cell-actions":s(({row:t})=>[t.exists?(n(),l(a(Y),{key:0,size:"sm",variant:"soft",onClick:f=>O(t)},{default:s(()=>[...e[12]||(e[12]=[o(" Explore ",-1)])]),_:1},8,["onClick"])):(n(),l(a(m),{key:1,tone:"muted",size:"xs"},{default:s(()=>[...e[13]||(e[13]=[o(" Register service to provision ",-1)])]),_:1}))]),_:1},8,["rows","row-state"])):(n(),l(a(G),{key:2,title:"No matching tables",description:`No tables match "${$.value}".`},null,8,["description"])):(n(),l(a(G),{key:1,title:"No DynamoDB tables",description:"Register a microservice with DynamoDB resources or drop a seed file into the seeds directory."}))]),_:1})]),_:1}))}}),ae=A({__name:"DynamoPage",setup(K){const z=Z();function N(d){z.push(`/dynamo/${encodeURIComponent(d)}`)}return(d,k)=>(n(),l(ee,{onOpen:N}))}});export{ae as default};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{k as X,_ as fe,m as d,e as b,W as e,E as et,$ as t,j as a,t as s,J as ie,i as r,V as y,f as C,q as k,s as F,N as tt,A as D,g as J,F as M,r as c,b as j,a as R,c as be,u as L,d as W,S as at,H as q,O as ne,x as xe,I as O,T as lt,D as Ve,a2 as Se,p as ce,n as G,v as ze,B as Ae,C as nt,h as it,G as ke,y as Ne,z as de,U as ut,w as $e,l as rt,P as ot,L as me,K as st,M as ve,X as dt,Y as Ce}from"./index-CGpxa55R.js";const mt=X({__name:"DynamoItemEditor",props:{open:{type:Boolean},tableName:{},mode:{},item:{},originalKey:{}},emits:["update:open","saved","request-edit","request-clone","request-delete"],setup(A,{emit:$}){const o=A,T=$,S=be(),V=c(""),f=c(null),w=c(!1),_=j({get:()=>o.open,set:i=>T("update:open",i)}),h=j(()=>o.mode==="create"?`Create item · ${o.tableName}`:o.mode==="view"?`View item · ${o.tableName}`:`Edit item · ${o.tableName}`),E=j(()=>o.mode==="view");fe(()=>[o.open,o.item,o.mode],([i])=>{i&&(V.value=o.item&&Object.keys(o.item).length?JSON.stringify(o.item,null,2):`{
|
|
2
|
-
|
|
3
|
-
}`,f.value=null)},{immediate:!0});function z(){try{const i=JSON.parse(V.value);return i===null||typeof i!="object"||Array.isArray(i)?(f.value="Item must be a JSON object",null):(f.value=null,i)}catch(i){return f.value=i.message,null}}async function N(){const i=z();if(i){w.value=!0;try{o.mode==="edit"&&o.originalKey&&Object.entries(o.originalKey).some(([p,x])=>JSON.stringify(i[p])!==JSON.stringify(x))&&await R.deleteDynamoItem(o.tableName,o.originalKey),await R.putDynamoItem(o.tableName,i),S.add({title:o.mode==="create"?"Item created":"Item saved",variant:"success"}),T("saved"),_.value=!1}catch(m){S.add({title:"Save failed",description:m.message,variant:"danger"})}finally{w.value=!1}}}function g(){const i=z();i&&(V.value=JSON.stringify(i,null,2))}return(i,m)=>(d(),b(e(et),{open:_.value,"onUpdate:open":m[5]||(m[5]=p=>_.value=p),title:h.value,size:"lg"},{footer:t(()=>[a(e(s),{direction:"horizontal",gap:"0.5rem",justify:"space-between"},{default:t(()=>[a(e(s),{direction:"horizontal",gap:"0.5rem"},{default:t(()=>[E.value?C("",!0):(d(),b(e(D),{key:0,size:"sm",variant:"ghost",onClick:g},{default:t(()=>[...m[8]||(m[8]=[r(" Format JSON ",-1)])]),_:1})),E.value?(d(),J(M,{key:1},[a(e(D),{size:"sm",variant:"soft",onClick:m[1]||(m[1]=p=>T("request-edit"))},{default:t(()=>[...m[9]||(m[9]=[r("Edit",-1)])]),_:1}),a(e(D),{size:"sm",variant:"ghost",onClick:m[2]||(m[2]=p=>T("request-clone"))},{default:t(()=>[...m[10]||(m[10]=[r("Clone",-1)])]),_:1}),a(e(D),{size:"sm",variant:"ghost",tone:"danger",onClick:m[3]||(m[3]=p=>T("request-delete"))},{default:t(()=>[...m[11]||(m[11]=[r("Delete",-1)])]),_:1})],64)):C("",!0)]),_:1}),a(e(s),{direction:"horizontal",gap:"0.5rem"},{default:t(()=>[a(e(D),{size:"sm",variant:"ghost",onClick:m[4]||(m[4]=p=>_.value=!1)},{default:t(()=>[r(y(E.value?"Close":"Cancel"),1)]),_:1}),E.value?C("",!0):(d(),b(e(D),{key:0,size:"sm",variant:"solid",loading:w.value,disabled:!!f.value,onClick:N},{default:t(()=>[r(y(A.mode==="create"?"Create":"Save"),1)]),_:1},8,["loading","disabled"]))]),_:1})]),_:1})]),default:t(()=>[a(e(s),{direction:"vertical",gap:"0.75rem"},{default:t(()=>[f.value?(d(),b(e(ie),{key:0,variant:"danger"},{default:t(()=>[r(y(f.value),1)]),_:1})):C("",!0),a(e(s),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:t(()=>[a(e(k),{tone:"muted",size:"xs"},{default:t(()=>[...m[6]||(m[6]=[r(" JSON object. Types are inferred — numbers, booleans, strings, arrays, nested objects are all supported. ",-1)])]),_:1}),E.value?(d(),b(e(F),{key:0,tone:"neutral",variant:"soft"},{default:t(()=>[...m[7]||(m[7]=[r("read-only",-1)])]),_:1})):C("",!0)]),_:1}),a(e(tt),{modelValue:V.value,"onUpdate:modelValue":m[0]||(m[0]=p=>V.value=p),rows:18,readonly:E.value,spellcheck:"false",class:"mono",onBlur:z},null,8,["modelValue","readonly"])]),_:1})]),_:1},8,["open","title"]))}}),vt={style:{width:"100%"}},ft=X({__name:"DynamoItemsExplorer",props:{table:{}},setup(A){const $=A,o=be(),T=c("scan"),S=c(""),V=c(50),f=c(""),w=c("="),_=c(""),h=c(""),E=c(!1),z=c([]),N=c(!1),g=c([]),i=c(void 0),m=c(void 0),p=c(null),x=c(!1),B=c(null),Y=c(!1),Z=c(!1),ee=c("view"),U=c(null),te=c(null),ue=c(!1),re=c(null),Te=[{value:"scan",label:"Scan"},{value:"query",label:"Query"}],he=[{value:"=",label:"Equal to"},{value:"<=",label:"Less than or equal to"},{value:"<",label:"Less than"},{value:">=",label:"Greater than or equal to"},{value:">",label:"Greater than"},{value:"between",label:"Between"},{value:"begins_with",label:"Begins with"}],Ie=[{value:"=",label:"Equal to"},{value:"<>",label:"Not equal to"},{value:"<",label:"Less than"},{value:"<=",label:"Less than or equal to"},{value:">",label:"Greater than"},{value:">=",label:"Greater than or equal to"},{value:"begins_with",label:"Begins with"},{value:"contains",label:"Contains"},{value:"attribute_exists",label:"Exists"},{value:"attribute_not_exists",label:"Does not exist"}],De=[{value:"String",label:"String"},{value:"Number",label:"Number"},{value:"Boolean",label:"Boolean"},{value:"Null",label:"Null"}],Ee=j(()=>{const u=[{value:"",label:`Table - ${$.table.name}`}];for(const l of $.table.gsis||[])l.IndexName&&u.push({value:l.IndexName,label:`Index - ${l.IndexName}`});for(const l of $.table.lsis||[])l.IndexName&&u.push({value:l.IndexName,label:`Index - ${l.IndexName}`});return u}),pe=j(()=>{if(!S.value)return $.table.keySchema;const u=$.table.gsis.find(l=>l.IndexName===S.value)||$.table.lsis.find(l=>l.IndexName===S.value);return(u==null?void 0:u.KeySchema)||$.table.keySchema}),ae=j(()=>{var u,l;return((l=(u=pe.value)==null?void 0:u.find(n=>n.KeyType==="HASH"))==null?void 0:l.AttributeName)||""}),P=j(()=>{var u,l;return((l=(u=pe.value)==null?void 0:u.find(n=>n.KeyType==="RANGE"))==null?void 0:l.AttributeName)||""}),oe=j(()=>(pe.value||[]).map(u=>u.AttributeName).filter(u=>!!u)),ge=j(()=>{const u=new Set;for(const l of g.value)Object.keys(l).forEach(n=>{oe.value.includes(n)||u.add(n)});return Array.from(u).sort()});function je(u){const l=$.table.attributeDefinitions.find(n=>n.AttributeName===u);return l!=null&&l.AttributeType?l.AttributeType==="S"?"String":l.AttributeType==="N"?"Number":l.AttributeType==="B"?"Binary":l.AttributeType:null}function we(u,l,n){const v=je(u);return l?v?`${u} (${v}, PK)`:`${u} (PK)`:n?v?`${u} (${v}, SK)`:`${u} (SK)`:v?`${u} (${v})`:u}const qe=j(()=>{const u=oe.value.map((n,v)=>({key:`__attr__${n}`,label:we(n,v===0,v===1)})),l=ge.value.map(n=>({key:`__attr__${n}`,label:we(n)}));return[...u,...l]}),Re=j(()=>g.value.map((u,l)=>{const n={__id:l,__raw:u};for(const v of oe.value)n[`__attr__${v}`]=u[v];for(const v of ge.value)n[`__attr__${v}`]=u[v];return n}));function ye(u){return u===void 0?"—":u===null?"null":typeof u=="boolean"?u?"true":"false":typeof u=="object"?JSON.stringify(u).slice(0,80):String(u).slice(0,80)}function Be(u,l){switch(l){case"Number":{const n=Number(u);if(Number.isNaN(n))throw new Error(`"${u}" is not a number`);return n}case"Boolean":return u==="true"||u==="1";case"Null":return null;case"String":default:return u}}function le(u,l){const n=$.table.attributeDefinitions.find(v=>v.AttributeName===l);if((n==null?void 0:n.AttributeType)==="N"){const v=Number(u);if(Number.isNaN(v))throw new Error(`"${u}" is not a number for ${l}`);return v}return u}function Ke(){const u={},l={};if(!ae.value)throw new Error("No partition key on the selected table or index");if(!f.value)throw new Error(`Partition key value (${ae.value}) is required`);u["#pk"]=ae.value,l[":pkv"]=le(f.value,ae.value);let n="#pk = :pkv";if(P.value&&_.value)if(u["#sk"]=P.value,w.value==="between"){if(!h.value)throw new Error("BETWEEN requires two values");l[":skv1"]=le(_.value,P.value),l[":skv2"]=le(h.value,P.value),n+=" AND #sk BETWEEN :skv1 AND :skv2"}else w.value==="begins_with"?(l[":skv"]=le(_.value,P.value),n+=" AND begins_with(#sk, :skv)"):(l[":skv"]=le(_.value,P.value),n+=` AND #sk ${w.value} :skv`);return{keyExpr:n,names:u,values:l}}function Ue(){const u={},l={},n=[];return z.value.forEach((v,I)=>{if(!v.attr)return;const K=`#fn${I}`,se=`:fv${I}`;if(u[K]=v.attr,v.op==="attribute_exists"){n.push(`attribute_exists(${K})`);return}if(v.op==="attribute_not_exists"){n.push(`attribute_not_exists(${K})`);return}l[se]=Be(v.value,v.type),v.op==="begins_with"?n.push(`begins_with(${K}, ${se})`):v.op==="contains"?n.push(`contains(${K}, ${se})`):n.push(`${K} ${v.op} ${se}`)}),{expr:n.join(" AND "),names:u,values:l}}function Oe(u){const l=Ue(),n={indexName:S.value||void 0,limit:V.value>0?V.value:void 0,exclusiveStartKey:u};let v=l.names,I=l.values;if(l.expr&&(n.filterExpression=l.expr),T.value==="query"){const K=Ke();n.keyConditionExpression=K.keyExpr,v={...v,...K.names},I={...I,...K.values},E.value&&(n.scanIndexForward=!1)}return Object.keys(v).length&&(n.expressionAttributeNames=v),Object.keys(I).length&&(n.expressionAttributeValues=I),n}async function H(u){x.value=!0,B.value=null;try{const l=Oe(u),n=T.value==="scan"?await R.scanDynamoTable($.table.name,l):await R.queryDynamoTable($.table.name,l);u?g.value=[...g.value,...n.items]:(g.value=n.items,p.value=new Date),i.value=n.lastEvaluatedKey,m.value=n.scannedCount,Y.value=!0}catch(l){B.value=l.message||"Request failed"}finally{x.value=!1}}function Le(){f.value="",w.value="=",_.value="",h.value="",E.value=!1,z.value=[],g.value=[],i.value=void 0,m.value=void 0,Y.value=!1,B.value=null}function Pe(){i.value&&H(i.value)}function Fe(){z.value.push({attr:"",op:"=",type:"String",value:""}),N.value=!0}function Je(u){z.value.splice(u,1)}function _e(u){const l={};for(const n of $.table.keySchema)n.AttributeName&&(l[n.AttributeName]=u[n.AttributeName]);return l}function Me(){const u={};for(const l of $.table.keySchema){if(!l.AttributeName)continue;const n=$.table.attributeDefinitions.find(v=>v.AttributeName===l.AttributeName);u[l.AttributeName]=(n==null?void 0:n.AttributeType)==="N"?0:""}return u}function Ge(){ee.value="create",U.value=Me(),te.value=null,Z.value=!0}function We(u){ee.value="view",U.value=u,te.value=null,Z.value=!0}function He(){U.value&&(te.value=_e(U.value),ee.value="edit")}function Qe(){if(!U.value)return;const u={...U.value};for(const l of $.table.keySchema){if(!l.AttributeName)continue;const n=$.table.attributeDefinitions.find(v=>v.AttributeName===l.AttributeName);u[l.AttributeName]=(n==null?void 0:n.AttributeType)==="N"?0:""}U.value=u,te.value=null,ee.value="create"}function Xe(){U.value&&(re.value=_e(U.value),ue.value=!0)}async function Ye(){if(re.value)try{await R.deleteDynamoItem($.table.name,re.value),o.add({title:"Item deleted",variant:"info"}),Z.value=!1,await H()}catch(u){o.add({title:"Delete failed",description:u.message,variant:"danger"})}finally{ue.value=!1,re.value=null}}function Ze(){H()}const Q=j(()=>{const u=g.value.length,l=m.value??u,n=l>0?Math.round(u/l*100):100;return{returned:u,scanned:l,efficiency:n,finished:!i.value}});return H(),fe(()=>[T.value,S.value],()=>{g.value=[],i.value=void 0,m.value=void 0,Y.value=!1}),(u,l)=>(d(),b(e(s),{direction:"vertical",gap:"1rem"},{default:t(()=>[a(e(L),{variant:"outline"},{header:t(()=>[a(e(k),{weight:"semibold"},{default:t(()=>[...l[15]||(l[15]=[r("Scan or query items",-1)])]),_:1})]),footer:t(()=>[a(e(s),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:t(()=>[a(e(s),{direction:"horizontal",gap:"0.5rem",align:"center"},{default:t(()=>[a(e(D),{variant:"solid",loading:x.value,onClick:l[8]||(l[8]=n=>H())},{default:t(()=>[...l[21]||(l[21]=[r("Run",-1)])]),_:1},8,["loading"]),a(e(D),{variant:"ghost",onClick:Le},{default:t(()=>[...l[22]||(l[22]=[r("Reset",-1)])]),_:1})]),_:1}),a(e(s),{direction:"horizontal",gap:"0.5rem",align:"center"},{default:t(()=>[a(e(k),{tone:"muted"},{default:t(()=>[...l[23]||(l[23]=[r("Limit",-1)])]),_:1}),a(e(O),{modelValue:V.value,"onUpdate:modelValue":l[9]||(l[9]=n=>V.value=n),modelModifiers:{number:!0},type:"number",size:"sm",style:{width:"6rem"}},null,8,["modelValue"])]),_:1})]),_:1})]),default:t(()=>[a(e(s),{direction:"vertical",gap:"1rem"},{default:t(()=>[W("div",vt,[a(e(at),{modelValue:T.value,"onUpdate:modelValue":l[0]||(l[0]=n=>T.value=n),options:Te,size:"md"},null,8,["modelValue"])]),a(e(s),{direction:"horizontal",gap:"1rem"},{default:t(()=>[a(e(q),{label:"Select a table or index",style:{flex:"1"}},{default:t(()=>[a(e(ne),{modelValue:S.value,"onUpdate:modelValue":l[1]||(l[1]=n=>S.value=n),options:Ee.value},null,8,["modelValue","options"])]),_:1}),a(e(q),{label:"Select attribute projection",style:{flex:"1"}},{default:t(()=>[a(e(ne),{"model-value":"All attributes",options:[{value:"All attributes",label:"All attributes"}],disabled:""})]),_:1})]),_:1}),T.value==="query"?(d(),J(M,{key:0},[a(e(xe)),a(e(s),{direction:"vertical",gap:"0.5rem"},{default:t(()=>[a(e(k),{weight:"semibold",style:{"font-size":"0.9rem"}},{default:t(()=>[...l[16]||(l[16]=[r("Partition key",-1)])]),_:1}),a(e(s),{direction:"horizontal",gap:"1rem"},{default:t(()=>[a(e(q),{label:"Attribute",style:{flex:"1"}},{default:t(()=>[a(e(O),{"model-value":ae.value||"—",disabled:""},null,8,["model-value"])]),_:1}),a(e(q),{label:"Value",style:{flex:"2"}},{default:t(()=>[a(e(O),{modelValue:f.value,"onUpdate:modelValue":l[2]||(l[2]=n=>f.value=n),placeholder:"Enter attribute value"},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),P.value?(d(),b(e(s),{key:0,direction:"vertical",gap:"0.5rem"},{default:t(()=>[a(e(k),{weight:"semibold",style:{"font-size":"0.9rem"}},{default:t(()=>[...l[17]||(l[17]=[r("Sort key – optional",-1)])]),_:1}),a(e(s),{direction:"horizontal",gap:"0.75rem",align:"end"},{default:t(()=>[a(e(q),{label:"Attribute",style:{flex:"1.4"}},{default:t(()=>[a(e(O),{"model-value":P.value,disabled:""},null,8,["model-value"])]),_:1}),a(e(q),{label:"Value",style:{flex:"1.2","min-width":"11rem"}},{default:t(()=>[a(e(ne),{modelValue:w.value,"onUpdate:modelValue":l[3]||(l[3]=n=>w.value=n),options:he},null,8,["modelValue"])]),_:1}),a(e(O),{modelValue:_.value,"onUpdate:modelValue":l[4]||(l[4]=n=>_.value=n),placeholder:"Enter attribute value",style:{flex:"2"}},null,8,["modelValue"]),w.value==="between"?(d(),b(e(O),{key:0,modelValue:h.value,"onUpdate:modelValue":l[5]||(l[5]=n=>h.value=n),placeholder:"and value",style:{flex:"2"}},null,8,["modelValue"])):C("",!0),a(e(lt),{modelValue:E.value,"onUpdate:modelValue":l[6]||(l[6]=n=>E.value=n),label:"Sort descending"},null,8,["modelValue"])]),_:1})]),_:1})):C("",!0)],64)):C("",!0),a(e(xe)),a(e(s),{direction:"vertical",gap:"0.5rem"},{default:t(()=>[a(e(Ve),{href:"#",style:{"font-weight":"600","font-size":"0.9rem"},onClick:l[7]||(l[7]=Se(n=>N.value=!N.value,["prevent"]))},{default:t(()=>[a(e(ce),{name:N.value?"chevron-down":"chevron-right"},null,8,["name"]),l[18]||(l[18]=r(" Filters – optional ",-1))]),_:1}),N.value?(d(),b(e(s),{key:0,direction:"vertical",gap:"0.5rem"},{default:t(()=>[(d(!0),J(M,null,G(z.value,(n,v)=>(d(),b(e(s),{key:`f-${v}`,direction:"horizontal",gap:"0.5rem",align:"end"},{default:t(()=>[a(e(q),{label:"Attribute name",style:{flex:"1.4"}},{default:t(()=>[a(e(O),{modelValue:n.attr,"onUpdate:modelValue":I=>n.attr=I,placeholder:"Enter attribute name"},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),a(e(q),{label:"Condition",style:{flex:"1.4"}},{default:t(()=>[a(e(ne),{modelValue:n.op,"onUpdate:modelValue":I=>n.op=I,options:Ie},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),a(e(q),{label:"Type",style:{flex:"0.9"}},{default:t(()=>[a(e(ne),{modelValue:n.type,"onUpdate:modelValue":I=>n.type=I,options:De},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),a(e(q),{label:"Value",style:{flex:"1.7"}},{default:t(()=>[a(e(O),{modelValue:n.value,"onUpdate:modelValue":I=>n.value=I,disabled:n.op==="attribute_exists"||n.op==="attribute_not_exists",placeholder:"Enter attribute value"},null,8,["modelValue","onUpdate:modelValue","disabled"])]),_:2},1024),a(e(D),{size:"sm",variant:"outline",onClick:I=>Je(v)},{default:t(()=>[...l[19]||(l[19]=[r("Remove",-1)])]),_:1},8,["onClick"])]),_:2},1024))),128)),W("div",null,[a(e(D),{size:"sm",variant:"outline",onClick:Fe},{default:t(()=>[...l[20]||(l[20]=[r("Add filter",-1)])]),_:1})])]),_:1})):C("",!0)]),_:1})]),_:1})]),_:1}),B.value?(d(),b(e(ie),{key:0,variant:"danger",dismissible:"",onDismiss:l[10]||(l[10]=n=>B.value=null)},{default:t(()=>[r(y(B.value),1)]),_:1})):C("",!0),Y.value&&!B.value?(d(),b(e(ie),{key:1,variant:Q.value.finished?"success":"warning",dismissible:"",onDismiss:l[11]||(l[11]=n=>Y.value=!1)},{default:t(()=>[a(e(s),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:t(()=>[W("span",null,[a(e(k),{as:"strong",weight:"semibold"},{default:t(()=>[r(y(Q.value.finished?"Completed":"Stopped"),1)]),_:1}),l[24]||(l[24]=r(" · Items returned: ",-1)),a(e(k),{as:"strong",weight:"semibold"},{default:t(()=>[r(y(Q.value.returned),1)]),_:1}),l[25]||(l[25]=r(" · Items scanned: ",-1)),a(e(k),{as:"strong",weight:"semibold"},{default:t(()=>[r(y(Q.value.scanned),1)]),_:1}),l[26]||(l[26]=r(" · Efficiency: ",-1)),a(e(k),{as:"strong",weight:"semibold"},{default:t(()=>[r(y(Q.value.efficiency)+"%",1)]),_:1})]),Q.value.finished?C("",!0):(d(),b(e(D),{key:0,size:"sm",variant:"outline",loading:x.value,onClick:Pe},{default:t(()=>[...l[27]||(l[27]=[r(" Retrieve next page ",-1)])]),_:1},8,["loading"]))]),_:1})]),_:1},8,["variant"])):C("",!0),a(e(L),{variant:"outline"},{header:t(()=>[a(e(s),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:t(()=>[a(e(s),{direction:"vertical",gap:"0.125rem"},{default:t(()=>[a(e(k),{weight:"semibold"},{default:t(()=>[r(y(S.value?`Index: ${S.value} (${$.table.name})`:`Table: ${$.table.name}`)+" – Items returned ("+y(g.value.length)+") ",1)]),_:1}),a(e(k),{tone:"muted",size:"xs"},{default:t(()=>[r(y(T.value==="scan"?"Scan":"Query")+" started on "+y(p.value?p.value.toLocaleString():"—"),1)]),_:1})]),_:1}),a(e(s),{direction:"horizontal",gap:"0.5rem"},{default:t(()=>[a(e(D),{size:"sm",variant:"ghost",loading:x.value,onClick:l[12]||(l[12]=n=>H())},{default:t(()=>[...l[28]||(l[28]=[r("Refresh",-1)])]),_:1},8,["loading"]),a(e(D),{size:"sm",variant:"outline",onClick:Ge},{default:t(()=>[...l[29]||(l[29]=[r("Create item",-1)])]),_:1})]),_:1})]),_:1})]),default:t(()=>[x.value&&!g.value.length?(d(),b(e(s),{key:0,direction:"horizontal",justify:"center",align:"center"},{default:t(()=>[a(e(ze),{label:"Running..."})]),_:1})):g.value.length?(d(),b(e(nt),{key:2,columns:qe.value,rows:Re.value,"aria-label":"Scan and query results"},it({_:2},[G(oe.value,(n,v)=>({name:`cell-__attr__${n}`,fn:t(({row:I})=>[v===0?(d(),b(e(Ve),{key:0,href:"#",class:"mono",onClick:Se(K=>We(I.__raw),["prevent"])},{default:t(()=>[r(y(ye(I[`__attr__${n}`])),1)]),_:2},1032,["onClick"])):(d(),b(e(k),{key:1,family:"mono"},{default:t(()=>[r(y(ye(I[`__attr__${n}`])),1)]),_:2},1024))])})),G(ge.value,n=>({name:`cell-__attr__${n}`,fn:t(({row:v})=>[a(e(k),{family:"mono",size:"sm"},{default:t(()=>[r(y(ye(v[`__attr__${n}`])),1)]),_:2},1024)])}))]),1032,["columns","rows"])):(d(),b(e(Ae),{key:1,title:"No items",description:"Run the operation to load items."}))]),_:1}),a(mt,{open:Z.value,"onUpdate:open":l[13]||(l[13]=n=>Z.value=n),"table-name":$.table.name,mode:ee.value,item:U.value,"original-key":te.value,onSaved:Ze,onRequestEdit:He,onRequestClone:Qe,onRequestDelete:Xe},null,8,["open","table-name","mode","item","original-key"]),a(e(ke),{open:ue.value,"onUpdate:open":l[14]||(l[14]=n=>ue.value=n),title:"Delete item",description:`Delete this item from ${$.table.name}? This cannot be undone.`,"confirm-label":"Delete","cancel-label":"Cancel",tone:"danger",onConfirm:Ye},null,8,["open","description"])]),_:1}))}}),bt=X({__name:"DynamoTableSettings",props:{table:{}},emits:["refresh"],setup(A,{emit:$}){const o=A,T=$,S=be(),V=c(o.table.ttl.enabled),f=c(o.table.ttl.attributeName||""),w=c(!1),_=c(null);fe(()=>[o.table.ttl.enabled,o.table.ttl.attributeName],([z,N])=>{V.value=z,f.value=N||""});async function h(){if(V.value&&!f.value.trim()){_.value="Attribute name is required to enable TTL";return}w.value=!0,_.value=null;try{await R.setDynamoTtl(o.table.name,V.value,f.value.trim()||void 0),S.add({title:V.value?"TTL enabled":"TTL disabled",description:V.value?`Attribute: ${f.value}`:void 0,variant:"success"}),T("refresh")}catch(z){_.value=z.message||"Failed to update TTL"}finally{w.value=!1}}function E(z){return z<1024?`${z} B`:z<1024*1024?`${(z/1024).toFixed(1)} KB`:`${(z/(1024*1024)).toFixed(1)} MB`}return(z,N)=>(d(),b(e(s),{direction:"vertical",gap:"1rem"},{default:t(()=>[a(e(Ne),{columns:4,gap:"0.75rem"},{default:t(()=>[a(e(de),{label:"Items",value:o.table.itemCount,tone:"info"},null,8,["value"]),a(e(de),{label:"Size",value:E(o.table.sizeBytes),tone:"neutral"},null,8,["value"]),a(e(de),{label:"Status",value:o.table.status||"UNKNOWN",tone:o.table.status==="ACTIVE"?"success":"warning"},null,8,["value","tone"]),a(e(de),{label:"Billing",value:o.table.billingMode||"—",tone:"neutral"},null,8,["value"])]),_:1}),a(e(L),{variant:"outline"},{header:t(()=>[a(e(k),{weight:"semibold"},{default:t(()=>[...N[3]||(N[3]=[r("Time to Live (TTL)",-1)])]),_:1})]),default:t(()=>[_.value?(d(),b(e(ie),{key:0,variant:"danger",dismissible:"",onDismiss:N[0]||(N[0]=g=>_.value=null)},{default:t(()=>[r(y(_.value),1)]),_:1})):C("",!0),a(e(s),{direction:"vertical",gap:"0.75rem"},{default:t(()=>[a(e(k),{tone:"muted",size:"sm"},{default:t(()=>[...N[4]||(N[4]=[r(" When TTL is enabled, items are automatically deleted by DynamoDB after the timestamp in the configured attribute (epoch seconds). Items are eventually consistent and may take time to be removed. ",-1)])]),_:1}),a(e(q),{label:"Enable TTL"},{default:t(()=>[a(e(ut),{modelValue:V.value,"onUpdate:modelValue":N[1]||(N[1]=g=>V.value=g)},null,8,["modelValue"])]),_:1}),a(e(q),{label:"Attribute name",hint:V.value?"Required when enabling TTL":"Disabled — value retained for reference"},{default:t(()=>[a(e(O),{modelValue:f.value,"onUpdate:modelValue":N[2]||(N[2]=g=>f.value=g),placeholder:"e.g. expiresAt",disabled:!V.value},null,8,["modelValue","disabled"])]),_:1},8,["hint"]),a(e(s),{direction:"horizontal",justify:"flex-end"},{default:t(()=>[a(e(D),{size:"sm",variant:"solid",loading:w.value,onClick:h},{default:t(()=>[...N[5]||(N[5]=[r(" Apply ",-1)])]),_:1},8,["loading"])]),_:1})]),_:1})]),_:1}),a(e(L),{variant:"outline"},{header:t(()=>[a(e(k),{weight:"semibold"},{default:t(()=>[...N[6]||(N[6]=[r("Streams",-1)])]),_:1})]),default:t(()=>[a(e(s),{direction:"vertical",gap:"0.5rem"},{default:t(()=>[a(e(s),{direction:"horizontal",gap:"0.5rem",align:"center"},{default:t(()=>[a(e(F),{tone:o.table.streamEnabled?"success":"neutral",variant:"soft"},{default:t(()=>[r(y(o.table.streamEnabled?"Enabled":"Disabled"),1)]),_:1},8,["tone"]),o.table.streamViewType?(d(),b(e($e),{key:0,size:"sm",variant:"soft"},{default:t(()=>[r(y(o.table.streamViewType),1)]),_:1})):C("",!0)]),_:1}),o.table.streamArn?(d(),b(e(k),{key:0,tone:"muted",family:"mono",style:{"font-size":"0.7rem"}},{default:t(()=>[r(y(o.table.streamArn),1)]),_:1})):(d(),b(e(k),{key:1,tone:"muted",size:"xs"},{default:t(()=>[...N[7]||(N[7]=[r(" Streams configuration is set at table creation time and cannot be changed from here. ",-1)])]),_:1}))]),_:1})]),_:1}),a(e(L),{variant:"outline"},{header:t(()=>[a(e(k),{weight:"semibold"},{default:t(()=>[...N[8]||(N[8]=[r("Identifier",-1)])]),_:1})]),default:t(()=>[a(e(s),{direction:"vertical",gap:"0.25rem"},{default:t(()=>[a(e(k),{tone:"muted",family:"mono",size:"xs"},{default:t(()=>[r(" ARN: "+y(o.table.arn||"—"),1)]),_:1}),a(e(k),{tone:"muted",size:"xs"},{default:t(()=>[r(" Created: "+y(o.table.createdAt?new Date(o.table.createdAt).toLocaleString():"—"),1)]),_:1})]),_:1})]),_:1})]),_:1}))}}),pt=X({__name:"DynamoSeedPanel",props:{tableName:{},seedFile:{},seedItemCount:{},tableItemCount:{}},emits:["refresh"],setup(A,{emit:$}){const o=A,T=$,S=be(),V=c(!1),f=c(!1),w=c(!1),_=c(!1),h=c(!1);async function E(){if(!V.value){V.value=!0;try{const g=await R.runSeed(o.tableName),i=g.results.reduce((p,x)=>p+(x.inserted||0),0),m=g.results.find(p=>p.skipped);m?S.add({title:"Seed skipped",description:`${o.tableName}: ${m.reason||"unknown reason"}`,variant:"warning"}):S.add({title:"Seed applied",description:`${i} item(s) inserted into ${o.tableName}`,variant:"success"}),T("refresh")}catch(g){S.add({title:"Seed failed",description:g.message,variant:"danger"})}finally{V.value=!1}}}async function z(){if(!w.value){w.value=!0;try{const i=(await R.clearSeed(o.tableName)).results.reduce((m,p)=>m+(p.deleted||0),0);S.add({title:"Table purged",description:`${i} item(s) removed from ${o.tableName}`,variant:"info"}),T("refresh")}catch(g){S.add({title:"Purge failed",description:g.message,variant:"danger"})}finally{w.value=!1,_.value=!1}}}async function N(){if(!f.value){f.value=!0;try{const i=(await R.clearSeed(o.tableName)).results.reduce((x,B)=>x+(B.deleted||0),0),p=(await R.runSeed(o.tableName)).results.reduce((x,B)=>x+(B.inserted||0),0);S.add({title:"Seed redone",description:`${i} removed, ${p} inserted in ${o.tableName}`,variant:"success"}),T("refresh")}catch(g){S.add({title:"Redo failed",description:g.message,variant:"danger"})}finally{f.value=!1,h.value=!1}}}return(g,i)=>(d(),b(e(s),{direction:"vertical",gap:"1rem"},{default:t(()=>[a(e(L),{variant:"outline"},{header:t(()=>[a(e(s),{direction:"horizontal",justify:"space-between",align:"center"},{default:t(()=>[a(e(k),{weight:"semibold"},{default:t(()=>[...i[4]||(i[4]=[r("Seed file",-1)])]),_:1}),a(e(F),{tone:"info",variant:"soft"},{default:t(()=>[r(y(A.seedItemCount)+" item"+y(A.seedItemCount===1?"":"s"),1)]),_:1})]),_:1})]),default:t(()=>[a(e(s),{direction:"vertical",gap:"0.5rem"},{default:t(()=>[a(e(s),{direction:"horizontal",justify:"space-between",align:"center"},{default:t(()=>[a(e(k),{tone:"muted"},{default:t(()=>[...i[5]||(i[5]=[r("Path",-1)])]),_:1}),a(e(k),{family:"mono",size:"sm"},{default:t(()=>[r(y(A.seedFile),1)]),_:1})]),_:1}),a(e(s),{direction:"horizontal",justify:"space-between",align:"center"},{default:t(()=>[a(e(k),{tone:"muted"},{default:t(()=>[...i[6]||(i[6]=[r("Current rows in table",-1)])]),_:1}),a(e(k),{family:"mono"},{default:t(()=>[r(y(A.tableItemCount),1)]),_:1})]),_:1})]),_:1})]),_:1}),a(e(L),{variant:"outline"},{header:t(()=>[a(e(k),{weight:"semibold"},{default:t(()=>[...i[7]||(i[7]=[r("Actions",-1)])]),_:1})]),default:t(()=>[a(e(s),{direction:"vertical",gap:"0.75rem"},{default:t(()=>[a(e(s),{direction:"horizontal",justify:"space-between",align:"center",gap:"1rem"},{default:t(()=>[a(e(s),{direction:"vertical",gap:"0.125rem"},{default:t(()=>[a(e(k),{weight:"semibold"},{default:t(()=>[...i[8]||(i[8]=[r("Apply seed",-1)])]),_:1}),a(e(k),{tone:"muted",size:"sm"},{default:t(()=>[...i[9]||(i[9]=[r(" Inserts every item from the seed file. Existing items with the same key are overwritten. ",-1)])]),_:1})]),_:1}),a(e(D),{variant:"solid",loading:V.value,disabled:A.seedItemCount<=0,onClick:E},{default:t(()=>[...i[10]||(i[10]=[r(" Apply ",-1)])]),_:1},8,["loading","disabled"])]),_:1}),a(e(s),{direction:"horizontal",justify:"space-between",align:"center",gap:"1rem"},{default:t(()=>[a(e(s),{direction:"vertical",gap:"0.125rem"},{default:t(()=>[a(e(k),{weight:"semibold"},{default:t(()=>[...i[11]||(i[11]=[r("Redo seed",-1)])]),_:1}),a(e(k),{tone:"muted",size:"sm"},{default:t(()=>[...i[12]||(i[12]=[r(" Purges the table first, then re-applies the seed file. Use when stale rows are blocking a fresh load. ",-1)])]),_:1})]),_:1}),a(e(D),{variant:"soft",loading:f.value,disabled:A.seedItemCount<=0,onClick:i[0]||(i[0]=m=>h.value=!0)},{default:t(()=>[...i[13]||(i[13]=[r(" Redo ",-1)])]),_:1},8,["loading","disabled"])]),_:1}),a(e(s),{direction:"horizontal",justify:"space-between",align:"center",gap:"1rem"},{default:t(()=>[a(e(s),{direction:"vertical",gap:"0.125rem"},{default:t(()=>[a(e(k),{weight:"semibold"},{default:t(()=>[...i[14]||(i[14]=[r("Purge table",-1)])]),_:1}),a(e(k),{tone:"muted",size:"sm"},{default:t(()=>[...i[15]||(i[15]=[r(" Deletes every item currently in this table. The seed file is not touched. ",-1)])]),_:1})]),_:1}),a(e(D),{variant:"danger",loading:w.value,onClick:i[1]||(i[1]=m=>_.value=!0)},{default:t(()=>[...i[16]||(i[16]=[r(" Purge ",-1)])]),_:1},8,["loading"])]),_:1})]),_:1})]),_:1}),a(e(ke),{open:_.value,"onUpdate:open":i[2]||(i[2]=m=>_.value=m),title:`Purge ${A.tableName}?`,description:`This deletes all ${A.tableItemCount} item(s) currently in the table. The seed file on disk is not affected.`,"confirm-label":"Purge","cancel-label":"Cancel","confirm-variant":"danger",onConfirm:z},null,8,["open","title","description"]),a(e(ke),{open:h.value,"onUpdate:open":i[3]||(i[3]=m=>h.value=m),title:`Redo seed for ${A.tableName}?`,description:`This purges all ${A.tableItemCount} current item(s), then re-applies ${A.seedItemCount} seeded item(s).`,"confirm-label":"Redo","cancel-label":"Cancel","confirm-variant":"danger",onConfirm:N},null,8,["open","title","description"])]),_:1}))}}),gt={style:{"padding-top":"1rem"}},yt={style:{"padding-top":"1rem"}},ct={style:{"padding-top":"1rem"}},kt={style:{"padding-top":"1rem"}},Nt=X({__name:"DynamoTableDetail",props:{tableName:{}},emits:["back"],setup(A,{emit:$}){const o=A,T=$,S=dt(),V=Ce(),f=c(null),w=c(null),_=c(!0),h=c(null),E=["items","indexes","settings","seed"],z=j({get(){const g=String(S.query.tab||"");return E.includes(g)?g:"items"},set(g){V.replace({query:{...S.query,tab:g==="items"?void 0:g}})}});async function N(){_.value=!0;try{const[g,i]=await Promise.all([R.describeDynamoTable(o.tableName),R.listSeeds().catch(()=>({seedsDir:"",entries:[]}))]);f.value=g,w.value=i.entries.find(m=>m.tableName===o.tableName)||null,h.value=null}catch(g){h.value=g.message||"Failed to load table",f.value=null}finally{_.value=!1}}return rt(N),fe(()=>o.tableName,N),(g,i)=>(d(),b(e(s),{direction:"vertical",gap:"1rem"},{default:t(()=>{var m;return[a(e(s),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:t(()=>[a(e(s),{direction:"horizontal",gap:"0.5rem",align:"center"},{default:t(()=>{var p;return[a(e(D),{size:"sm",variant:"ghost",onClick:i[0]||(i[0]=x=>T("back"))},{default:t(()=>[a(e(ce),{name:"arrow-left"}),i[3]||(i[3]=r(" Tables",-1))]),_:1}),a(e(k),{size:"lg",weight:"semibold"},{default:t(()=>[r(y(A.tableName),1)]),_:1}),(p=f.value)!=null&&p.status?(d(),b(e(F),{key:0,tone:f.value.status==="ACTIVE"?"success":"warning",variant:"soft"},{default:t(()=>[r(y(f.value.status),1)]),_:1},8,["tone"])):C("",!0),w.value?(d(),b(e(F),{key:1,tone:"info",variant:"soft"},{default:t(()=>[r(" Seed: "+y(w.value.itemCount)+" item"+y(w.value.itemCount===1?"":"s"),1)]),_:1})):C("",!0)]}),_:1}),a(e(D),{size:"sm",variant:"ghost",loading:_.value,onClick:N},{default:t(()=>[...i[4]||(i[4]=[r("Refresh",-1)])]),_:1},8,["loading"])]),_:1}),(m=f.value)!=null&&m.warnings.length?(d(),b(e(s),{key:0,direction:"horizontal",gap:"0.375rem",wrap:""},{default:t(()=>[(d(!0),J(M,null,G(f.value.warnings,p=>(d(),b(e(F),{key:p,tone:"warning",variant:"soft"},{default:t(()=>[a(e(ce),{name:"triangle-alert"}),r(" "+y(p),1)]),_:2},1024))),128))]),_:1})):C("",!0),h.value?(d(),b(e(ie),{key:1,variant:"danger",dismissible:"",onDismiss:i[1]||(i[1]=p=>h.value=null)},{default:t(()=>[r(y(h.value),1)]),_:1})):C("",!0),_.value&&!f.value?(d(),b(e(s),{key:2,direction:"horizontal",justify:"center",align:"center"},{default:t(()=>[a(e(ze),{label:"Loading table..."})]),_:1})):f.value?(d(),b(e(ot),{key:3,modelValue:z.value,"onUpdate:modelValue":i[2]||(i[2]=p=>z.value=p)},{default:t(()=>[a(e(st),null,{default:t(()=>[a(e(me),{value:"items"},{default:t(()=>[...i[5]||(i[5]=[r("Items",-1)])]),_:1}),a(e(me),{value:"indexes"},{default:t(()=>[...i[6]||(i[6]=[r("Indexes",-1)])]),_:1}),a(e(me),{value:"settings"},{default:t(()=>[...i[7]||(i[7]=[r("Settings",-1)])]),_:1}),w.value?(d(),b(e(me),{key:0,value:"seed"},{default:t(()=>[...i[8]||(i[8]=[r("Seed",-1)])]),_:1})):C("",!0)]),_:1}),a(e(ve),{value:"items"},{default:t(()=>[W("div",gt,[a(ft,{table:f.value},null,8,["table"])])]),_:1}),a(e(ve),{value:"indexes"},{default:t(()=>[W("div",yt,[!f.value.gsis.length&&!f.value.lsis.length?(d(),b(e(Ae),{key:0,title:"No secondary indexes",description:"This table has only the primary key."})):(d(),b(e(s),{key:1,direction:"vertical",gap:"1rem"},{default:t(()=>[f.value.gsis.length?(d(),b(e(Ne),{key:0,columns:2,gap:"0.75rem"},{default:t(()=>[(d(!0),J(M,null,G(f.value.gsis,p=>(d(),b(e(L),{key:p.IndexName,variant:"outline"},{header:t(()=>[a(e(s),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:t(()=>[a(e(k),{weight:"semibold"},{default:t(()=>[r(y(p.IndexName),1)]),_:2},1024),a(e(F),{tone:"info",variant:"soft"},{default:t(()=>[...i[9]||(i[9]=[r("GSI",-1)])]),_:1})]),_:2},1024)]),default:t(()=>[a(e(s),{direction:"vertical",gap:"0.5rem"},{default:t(()=>[a(e(s),{direction:"horizontal",gap:"0.5rem",wrap:""},{default:t(()=>[(d(!0),J(M,null,G(p.KeySchema||[],x=>(d(),b(e($e),{key:x.AttributeName,size:"sm",variant:"soft"},{default:t(()=>[r(y(x.AttributeName)+" ("+y(x.KeyType)+") ",1)]),_:2},1024))),128))]),_:2},1024),a(e(k),{tone:"muted",size:"xs"},{default:t(()=>{var x;return[r(" Projection: "+y(((x=p.Projection)==null?void 0:x.ProjectionType)||"—")+" · Items: "+y(p.ItemCount??"—")+" · Status: "+y(p.IndexStatus||"—"),1)]}),_:2},1024)]),_:2},1024)]),_:2},1024))),128))]),_:1})):C("",!0),f.value.lsis.length?(d(),b(e(Ne),{key:1,columns:2,gap:"0.75rem"},{default:t(()=>[(d(!0),J(M,null,G(f.value.lsis,p=>(d(),b(e(L),{key:p.IndexName,variant:"outline"},{header:t(()=>[a(e(s),{direction:"horizontal",gap:"0.5rem",align:"center",justify:"space-between"},{default:t(()=>[a(e(k),{weight:"semibold"},{default:t(()=>[r(y(p.IndexName),1)]),_:2},1024),a(e(F),{tone:"neutral",variant:"soft"},{default:t(()=>[...i[10]||(i[10]=[r("LSI",-1)])]),_:1})]),_:2},1024)]),default:t(()=>[a(e(s),{direction:"vertical",gap:"0.5rem"},{default:t(()=>[a(e(s),{direction:"horizontal",gap:"0.5rem",wrap:""},{default:t(()=>[(d(!0),J(M,null,G(p.KeySchema||[],x=>(d(),b(e($e),{key:x.AttributeName,size:"sm",variant:"soft"},{default:t(()=>[r(y(x.AttributeName)+" ("+y(x.KeyType)+") ",1)]),_:2},1024))),128))]),_:2},1024),a(e(k),{tone:"muted",size:"xs"},{default:t(()=>{var x;return[r(" Projection: "+y(((x=p.Projection)==null?void 0:x.ProjectionType)||"—"),1)]}),_:2},1024)]),_:2},1024)]),_:2},1024))),128))]),_:1})):C("",!0)]),_:1}))])]),_:1}),a(e(ve),{value:"settings"},{default:t(()=>[W("div",ct,[a(bt,{table:f.value,onRefresh:N},null,8,["table"])])]),_:1}),w.value?(d(),b(e(ve),{key:0,value:"seed"},{default:t(()=>[W("div",kt,[a(pt,{"table-name":f.value.name,"seed-file":w.value.file,"seed-item-count":w.value.itemCount,"table-item-count":f.value.itemCount,onRefresh:N},null,8,["table-name","seed-file","seed-item-count","table-item-count"])])]),_:1})):C("",!0)]),_:1},8,["modelValue"])):C("",!0)]}),_:1}))}}),wt=X({__name:"DynamoTablePage",props:{tableName:{}},setup(A){const $=Ce();function o(){$.push("/dynamo")}return(T,S)=>(d(),b(Nt,{"table-name":A.tableName,onBack:o},null,8,["table-name"]))}});export{wt as default};
|