local-serverless-stack 0.2.0 → 0.3.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 +11 -0
- package/dist/client/config-discovery.d.ts +10 -0
- package/dist/client/config-discovery.d.ts.map +1 -0
- package/dist/client/config-discovery.js +63 -0
- package/dist/client/config-discovery.js.map +1 -0
- package/dist/client/http.d.ts +32 -0
- package/dist/client/http.d.ts.map +1 -0
- package/dist/client/http.js +124 -0
- package/dist/client/http.js.map +1 -0
- package/dist/client/index.d.ts +40 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +59 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/lifecycle.d.ts +53 -0
- package/dist/client/lifecycle.d.ts.map +1 -0
- package/dist/client/lifecycle.js +97 -0
- package/dist/client/lifecycle.js.map +1 -0
- package/dist/client/namespaces/buckets.d.ts +19 -0
- package/dist/client/namespaces/buckets.d.ts.map +1 -0
- package/dist/client/namespaces/buckets.js +26 -0
- package/dist/client/namespaces/buckets.js.map +1 -0
- package/dist/client/namespaces/config.d.ts +7 -0
- package/dist/client/namespaces/config.d.ts.map +1 -0
- package/dist/client/namespaces/config.js +9 -0
- package/dist/client/namespaces/config.js.map +1 -0
- package/dist/client/namespaces/dynamo.d.ts +23 -0
- package/dist/client/namespaces/dynamo.d.ts.map +1 -0
- package/dist/client/namespaces/dynamo.js +22 -0
- package/dist/client/namespaces/dynamo.js.map +1 -0
- package/dist/client/namespaces/health.d.ts +8 -0
- package/dist/client/namespaces/health.d.ts.map +1 -0
- package/dist/client/namespaces/health.js +9 -0
- package/dist/client/namespaces/health.js.map +1 -0
- package/dist/client/namespaces/queues.d.ts +26 -0
- package/dist/client/namespaces/queues.d.ts.map +1 -0
- package/dist/client/namespaces/queues.js +28 -0
- package/dist/client/namespaces/queues.js.map +1 -0
- package/dist/client/namespaces/resources.d.ts +10 -0
- package/dist/client/namespaces/resources.d.ts.map +1 -0
- package/dist/client/namespaces/resources.js +11 -0
- package/dist/client/namespaces/resources.js.map +1 -0
- package/dist/client/namespaces/seeds.d.ts +16 -0
- package/dist/client/namespaces/seeds.d.ts.map +1 -0
- package/dist/client/namespaces/seeds.js +18 -0
- package/dist/client/namespaces/seeds.js.map +1 -0
- package/dist/client/namespaces/services.d.ts +27 -0
- package/dist/client/namespaces/services.d.ts.map +1 -0
- package/dist/client/namespaces/services.js +17 -0
- package/dist/client/namespaces/services.js.map +1 -0
- package/dist/client/types.d.ts +236 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +10 -0
- package/dist/client/types.js.map +1 -0
- package/package.json +19 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.3.0] - 2026-06-06
|
|
9
|
+
|
|
10
|
+
Programmatic client (`LssClient`) so downstream Jest e2e suites can drive everything the `lss` CLI does at runtime via `import`, instead of shelling out to `npx lss` per step.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Programmatic client `LssClient`** (`import { LssClient } from 'local-serverless-stack'`): everything the `lss` CLI/orchestrator exposes, callable from Jest at runtime instead of spawning `npx lss` per step. The data-plane is a thin typed HTTP wrapper over the orchestrator's `/api/*` endpoints, grouped into namespaces — `seeds` (`run`/`clear`/`list`), `queues` (incl. `awaitIdle`, `hold`/`captured`/`release`, `send`/`receive`/`purge`), `dynamo` (tables/scan/query/item CRUD/TTL), `buckets` (S3 list/objects/`getObject` as a `Buffer`/put/delete), `resources`, `services`, `config`, `health` — plus a `request()` escape hatch. `lifecycle` (`start`/`stop`/`status`/`logs`) shells out to the battle-tested `bin/cli.js` (so PID/`stateDir` logic is reused, not duplicated), and `lifecycle.waitUntilReady()` polls `GET /api/health` until LocalStack is actually up (the CLI returns before that). The constructor resolves its target from options → env (`LSS_CONFIG`, `LSS_BASE_URL`, `LSS_SERVER_PORT`, `AWS_REGION`) → `lss.config.json`/`.lssrc`, so `new LssClient()` works purely from the environment or `new LssClient({ configPath })` from an explicit file. Quirks handled for callers: `queues.awaitIdle` resolves on both `200` (drained) and `408` (timeout) rather than throwing, and `buckets.getObject` returns the raw binary body. Errors throw an `LssHttpError` carrying `{ status, statusText, body, path }` and the orchestrator's own `{error|message}`.
|
|
14
|
+
- **Package now ships a library entry point**: added `main`/`types`/`exports` to `package.json` pointing at a self-contained CommonJS build at `dist/client` (mirrors the `serverless-lss` plugin's CJS build so consumers on CJS or ESM can `import`/`require` it). New `client:build` (`tsc --project src/client/tsconfig.json`) wired into `npm run build`. Importable as `local-serverless-stack` or `local-serverless-stack/client`.
|
|
15
|
+
|
|
16
|
+
### Tests
|
|
17
|
+
- **100% coverage extended to `src/client/**`**: stub-HTTP-server unit tests assert every namespace method maps to the right route/query/body and cover the full error-mapping matrix (`{error}`/`{message}`/snippet/empty/over-long/non-JSON, timeout, connection refused); lifecycle is driven against a fake CLI fixture (`tests/fixtures/fake-cli.js`) via the `LSS_CLI_PATH` seam plus `waitUntilReady` polling. The integration suite (`features.test.ts`) gained a "programmatic client" block that drives the same isolated instance through `LssClient` end-to-end.
|
|
18
|
+
|
|
8
19
|
## [0.2.0] - 2026-06-04
|
|
9
20
|
|
|
10
21
|
Testability features for downstream e2e suites: an isolated test instance and a deterministic queue-drain wait. Plugin `serverless-lss` bumped to `0.1.0` (it gained `LSS_DASHBOARD_PORT` support — install both).
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { LssClientOptions } from './types';
|
|
2
|
+
export interface ResolvedConfig {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
region?: string;
|
|
5
|
+
configPath?: string;
|
|
6
|
+
cwd: string;
|
|
7
|
+
timeoutMs: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function resolveConfig(options?: LssClientOptions): ResolvedConfig;
|
|
10
|
+
//# sourceMappingURL=config-discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-discovery.d.ts","sourceRoot":"","sources":["../../src/client/config-discovery.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB;AA6CD,wBAAgB,aAAa,CAAC,OAAO,GAAE,gBAAqB,GAAG,cAAc,CAO5E"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Resolves where the orchestrator lives (baseUrl) and the default region, from
|
|
3
|
+
// explicit options → environment → config file → defaults. Mirrors the CLI's
|
|
4
|
+
// port handling (bin/cli.js getServerPort / getConfig) but honors the client's
|
|
5
|
+
// own configPath/cwd instead of process.argv, which the CLI freezes at load.
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.resolveConfig = resolveConfig;
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const DEFAULT_PORT = 3100;
|
|
14
|
+
const DEFAULT_TIMEOUT_MS = 15000;
|
|
15
|
+
function stripTrailingSlash(url) {
|
|
16
|
+
return url.endsWith('/') ? url.slice(0, -1) : url;
|
|
17
|
+
}
|
|
18
|
+
function readServerPortFromConfig(configPath, cwd) {
|
|
19
|
+
const candidates = configPath
|
|
20
|
+
? [path_1.default.resolve(cwd, configPath)]
|
|
21
|
+
: [path_1.default.join(cwd, 'lss.config.json'), path_1.default.join(cwd, '.lssrc')];
|
|
22
|
+
for (const candidate of candidates) {
|
|
23
|
+
try {
|
|
24
|
+
if (fs_1.default.existsSync(candidate)) {
|
|
25
|
+
const cfg = JSON.parse(fs_1.default.readFileSync(candidate, 'utf-8'));
|
|
26
|
+
if (typeof cfg.serverPort === 'number')
|
|
27
|
+
return cfg.serverPort;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// Unreadable/invalid config — fall through to the next candidate / default.
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return DEFAULT_PORT;
|
|
35
|
+
}
|
|
36
|
+
function resolveBaseUrl(options, configPath, cwd) {
|
|
37
|
+
if (options.baseUrl)
|
|
38
|
+
return stripTrailingSlash(options.baseUrl);
|
|
39
|
+
if (process.env.LSS_BASE_URL)
|
|
40
|
+
return stripTrailingSlash(process.env.LSS_BASE_URL);
|
|
41
|
+
const host = options.host ?? 'localhost';
|
|
42
|
+
let port = options.port;
|
|
43
|
+
if (port === undefined && process.env.LSS_SERVER_PORT) {
|
|
44
|
+
// Strict parse + validation: a non-numeric/zero/negative env value falls
|
|
45
|
+
// through to the config file / default rather than yielding "http://host:NaN".
|
|
46
|
+
const parsed = Number(process.env.LSS_SERVER_PORT);
|
|
47
|
+
if (Number.isInteger(parsed) && parsed > 0)
|
|
48
|
+
port = parsed;
|
|
49
|
+
}
|
|
50
|
+
if (port === undefined) {
|
|
51
|
+
port = readServerPortFromConfig(configPath, cwd);
|
|
52
|
+
}
|
|
53
|
+
return `http://${host}:${port}`;
|
|
54
|
+
}
|
|
55
|
+
function resolveConfig(options = {}) {
|
|
56
|
+
const cwd = options.cwd ?? process.cwd();
|
|
57
|
+
const configPath = options.configPath ?? process.env.LSS_CONFIG ?? undefined;
|
|
58
|
+
const region = options.region ?? process.env.AWS_REGION ?? undefined;
|
|
59
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
60
|
+
const baseUrl = resolveBaseUrl(options, configPath, cwd);
|
|
61
|
+
return { baseUrl, region, configPath, cwd, timeoutMs };
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=config-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-discovery.js","sourceRoot":"","sources":["../../src/client/config-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare class LssHttpError extends Error {
|
|
2
|
+
readonly status: number;
|
|
3
|
+
readonly statusText: string;
|
|
4
|
+
readonly body?: string;
|
|
5
|
+
readonly path: string;
|
|
6
|
+
constructor(message: string, info: {
|
|
7
|
+
status: number;
|
|
8
|
+
statusText: string;
|
|
9
|
+
body?: string;
|
|
10
|
+
path: string;
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export type QueryValue = string | number | boolean | undefined;
|
|
14
|
+
export interface RequestOptions {
|
|
15
|
+
body?: unknown;
|
|
16
|
+
query?: Record<string, QueryValue>;
|
|
17
|
+
/** Status codes treated as success in addition to 2xx (e.g. await-idle's 408). */
|
|
18
|
+
okStatuses?: number[];
|
|
19
|
+
}
|
|
20
|
+
export interface RequestContext {
|
|
21
|
+
baseUrl: string;
|
|
22
|
+
timeoutMs: number;
|
|
23
|
+
}
|
|
24
|
+
export declare class Http {
|
|
25
|
+
private readonly ctx;
|
|
26
|
+
constructor(ctx: RequestContext);
|
|
27
|
+
/** Request expecting a JSON response (or an empty body on success). */
|
|
28
|
+
json<T>(method: string, path: string, opts?: RequestOptions): Promise<T>;
|
|
29
|
+
/** Request expecting a raw binary body (e.g. S3 object content). */
|
|
30
|
+
raw(method: string, path: string, opts: RequestOptions): Promise<Buffer>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/client/http.ts"],"names":[],"mappings":"AAKA,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;CAQvG;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAE/D,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAiFD,qBAAa,IAAI;IACH,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,cAAc;IAEhD,uEAAuE;IACjE,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;IASlF,oEAAoE;IAC9D,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;CAQ/E"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Minimal HTTP layer for the LSS client. Talks to the orchestrator's `/api/*`
|
|
3
|
+
// endpoints over `fetch` (Node >=18). The error mapping mirrors the CLI's
|
|
4
|
+
// buildHttpError/formatError (bin/cli.js) so failures carry the orchestrator's
|
|
5
|
+
// own `{error|message}` instead of an opaque status.
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.Http = exports.LssHttpError = void 0;
|
|
8
|
+
class LssHttpError extends Error {
|
|
9
|
+
status;
|
|
10
|
+
statusText;
|
|
11
|
+
body;
|
|
12
|
+
path;
|
|
13
|
+
constructor(message, info) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = 'LssHttpError';
|
|
16
|
+
this.status = info.status;
|
|
17
|
+
this.statusText = info.statusText;
|
|
18
|
+
this.body = info.body;
|
|
19
|
+
this.path = info.path;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.LssHttpError = LssHttpError;
|
|
23
|
+
/* istanbul ignore next -- defensive: only runs on connection failure, where the error's message shape varies by runtime */
|
|
24
|
+
function reason(err) {
|
|
25
|
+
return err instanceof Error && err.message ? err.message : String(err);
|
|
26
|
+
}
|
|
27
|
+
function buildQuery(query) {
|
|
28
|
+
if (!query)
|
|
29
|
+
return '';
|
|
30
|
+
const parts = [];
|
|
31
|
+
for (const [key, value] of Object.entries(query)) {
|
|
32
|
+
if (value === undefined)
|
|
33
|
+
continue;
|
|
34
|
+
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
|
|
35
|
+
}
|
|
36
|
+
return parts.length ? `?${parts.join('&')}` : '';
|
|
37
|
+
}
|
|
38
|
+
function isOk(status, okStatuses) {
|
|
39
|
+
// okStatuses is ADDITIVE to the 2xx range, not a replacement — so passing
|
|
40
|
+
// e.g. [408] still treats a normal 200 as success.
|
|
41
|
+
if (status >= 200 && status < 300)
|
|
42
|
+
return true;
|
|
43
|
+
return okStatuses ? okStatuses.includes(status) : false;
|
|
44
|
+
}
|
|
45
|
+
function httpError(status, statusText, data, path) {
|
|
46
|
+
let parsed;
|
|
47
|
+
try {
|
|
48
|
+
parsed = data ? JSON.parse(data) : {};
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
parsed = null;
|
|
52
|
+
}
|
|
53
|
+
const fromBody = parsed && (parsed.error || parsed.message);
|
|
54
|
+
const label = statusText ? `${status} ${statusText}` : `${status}`;
|
|
55
|
+
let message;
|
|
56
|
+
if (fromBody && String(fromBody).trim()) {
|
|
57
|
+
message = String(fromBody).trim();
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
const snippet = data && data.length < 300 ? data.trim() : '';
|
|
61
|
+
message = snippet ? `HTTP ${label}: ${snippet}` : `HTTP ${label} (no error body)`;
|
|
62
|
+
}
|
|
63
|
+
return new LssHttpError(message, { status, statusText, body: data, path });
|
|
64
|
+
}
|
|
65
|
+
async function doFetch(ctx, method, path, opts) {
|
|
66
|
+
const url = ctx.baseUrl + path + buildQuery(opts.query);
|
|
67
|
+
const controller = new AbortController();
|
|
68
|
+
const timer = setTimeout(() => controller.abort(), ctx.timeoutMs);
|
|
69
|
+
const hasBody = opts.body !== undefined;
|
|
70
|
+
try {
|
|
71
|
+
return await fetch(url, {
|
|
72
|
+
method,
|
|
73
|
+
headers: hasBody ? { 'Content-Type': 'application/json' } : undefined,
|
|
74
|
+
body: hasBody ? JSON.stringify(opts.body) : undefined,
|
|
75
|
+
signal: controller.signal,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
// An aborted fetch rejects with a DOMException named 'AbortError' (not always
|
|
80
|
+
// an Error subclass across Node versions), so match on the name directly.
|
|
81
|
+
const name = err.name;
|
|
82
|
+
if (name === 'AbortError') {
|
|
83
|
+
throw new LssHttpError(`request to ${path} timed out after ${ctx.timeoutMs}ms`, {
|
|
84
|
+
status: 0,
|
|
85
|
+
statusText: 'timeout',
|
|
86
|
+
path,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
throw new LssHttpError(`could not connect to orchestrator at ${ctx.baseUrl}: ${reason(err)}`, {
|
|
90
|
+
status: 0,
|
|
91
|
+
statusText: 'connection_error',
|
|
92
|
+
path,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
clearTimeout(timer);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
class Http {
|
|
100
|
+
ctx;
|
|
101
|
+
constructor(ctx) {
|
|
102
|
+
this.ctx = ctx;
|
|
103
|
+
}
|
|
104
|
+
/** Request expecting a JSON response (or an empty body on success). */
|
|
105
|
+
async json(method, path, opts = {}) {
|
|
106
|
+
const res = await doFetch(this.ctx, method, path, opts);
|
|
107
|
+
const text = await res.text();
|
|
108
|
+
if (!isOk(res.status, opts.okStatuses)) {
|
|
109
|
+
throw httpError(res.status, res.statusText, text, path);
|
|
110
|
+
}
|
|
111
|
+
return (text ? JSON.parse(text) : {});
|
|
112
|
+
}
|
|
113
|
+
/** Request expecting a raw binary body (e.g. S3 object content). */
|
|
114
|
+
async raw(method, path, opts) {
|
|
115
|
+
const res = await doFetch(this.ctx, method, path, opts);
|
|
116
|
+
if (!isOk(res.status, opts.okStatuses)) {
|
|
117
|
+
const text = await res.text();
|
|
118
|
+
throw httpError(res.status, res.statusText, text, path);
|
|
119
|
+
}
|
|
120
|
+
return Buffer.from(await res.arrayBuffer());
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
exports.Http = Http;
|
|
124
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/client/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type QueryValue } from './http';
|
|
2
|
+
import { type LifecycleApi } from './lifecycle';
|
|
3
|
+
import { type SeedsApi } from './namespaces/seeds';
|
|
4
|
+
import { type QueuesApi } from './namespaces/queues';
|
|
5
|
+
import { type DynamoApi } from './namespaces/dynamo';
|
|
6
|
+
import { type BucketsApi } from './namespaces/buckets';
|
|
7
|
+
import { type ResourcesApi } from './namespaces/resources';
|
|
8
|
+
import { type ServicesApi } from './namespaces/services';
|
|
9
|
+
import { type ConfigApi } from './namespaces/config';
|
|
10
|
+
import { type HealthApi } from './namespaces/health';
|
|
11
|
+
import type { LssClientOptions } from './types';
|
|
12
|
+
export declare class LssClient {
|
|
13
|
+
/** Resolved base URL the data-plane talks to. */
|
|
14
|
+
readonly baseUrl: string;
|
|
15
|
+
readonly seeds: SeedsApi;
|
|
16
|
+
readonly queues: QueuesApi;
|
|
17
|
+
readonly dynamo: DynamoApi;
|
|
18
|
+
readonly buckets: BucketsApi;
|
|
19
|
+
readonly resources: ResourcesApi;
|
|
20
|
+
readonly services: ServicesApi;
|
|
21
|
+
readonly config: ConfigApi;
|
|
22
|
+
readonly health: HealthApi;
|
|
23
|
+
readonly lifecycle: LifecycleApi;
|
|
24
|
+
private readonly http;
|
|
25
|
+
constructor(options?: LssClientOptions);
|
|
26
|
+
/** Escape hatch for an arbitrary orchestrator call not covered by a namespace. */
|
|
27
|
+
request<T = unknown>(method: string, path: string, body?: unknown, query?: Record<string, QueryValue>): Promise<T>;
|
|
28
|
+
}
|
|
29
|
+
export { LssHttpError } from './http';
|
|
30
|
+
export type { SeedsApi } from './namespaces/seeds';
|
|
31
|
+
export type { QueuesApi } from './namespaces/queues';
|
|
32
|
+
export type { DynamoApi } from './namespaces/dynamo';
|
|
33
|
+
export type { BucketsApi } from './namespaces/buckets';
|
|
34
|
+
export type { ResourcesApi } from './namespaces/resources';
|
|
35
|
+
export type { ServicesApi } from './namespaces/services';
|
|
36
|
+
export type { ConfigApi } from './namespaces/config';
|
|
37
|
+
export type { HealthApi } from './namespaces/health';
|
|
38
|
+
export type { LifecycleApi, StartOptions, StartResult, StopResult, StatusResult, LogsResult, WaitUntilReadyOptions, } from './lifecycle';
|
|
39
|
+
export type * from './types';
|
|
40
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,qBAAa,SAAS;IACpB,iDAAiD;IACjD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IAEjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAO;gBAEhB,OAAO,GAAE,gBAAqB;IAgB1C,kFAAkF;IAClF,OAAO,CAAC,CAAC,GAAG,OAAO,EACjB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GACjC,OAAO,CAAC,CAAC,CAAC;CAGd;AAED,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,YAAY,EACZ,UAAU,EACV,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,mBAAmB,SAAS,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Programmatic client for the Local Serverless Stack orchestrator.
|
|
3
|
+
//
|
|
4
|
+
// import { LssClient } from 'local-serverless-stack';
|
|
5
|
+
// const lss = new LssClient({ configPath: 'lss.e2e.config.json' });
|
|
6
|
+
// // or, pure-ENV (LSS_CONFIG / LSS_BASE_URL / AWS_REGION): new LssClient();
|
|
7
|
+
//
|
|
8
|
+
// Everything the `lss` CLI does, callable from Jest at runtime. The data-plane
|
|
9
|
+
// (seeds/queues/dynamo/buckets/resources/services/config/health) is HTTP against
|
|
10
|
+
// a running orchestrator; lifecycle (start/stop/status/logs) shells out to the CLI.
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.LssHttpError = exports.LssClient = void 0;
|
|
13
|
+
const config_discovery_1 = require("./config-discovery");
|
|
14
|
+
const http_1 = require("./http");
|
|
15
|
+
const lifecycle_1 = require("./lifecycle");
|
|
16
|
+
const seeds_1 = require("./namespaces/seeds");
|
|
17
|
+
const queues_1 = require("./namespaces/queues");
|
|
18
|
+
const dynamo_1 = require("./namespaces/dynamo");
|
|
19
|
+
const buckets_1 = require("./namespaces/buckets");
|
|
20
|
+
const resources_1 = require("./namespaces/resources");
|
|
21
|
+
const services_1 = require("./namespaces/services");
|
|
22
|
+
const config_1 = require("./namespaces/config");
|
|
23
|
+
const health_1 = require("./namespaces/health");
|
|
24
|
+
class LssClient {
|
|
25
|
+
/** Resolved base URL the data-plane talks to. */
|
|
26
|
+
baseUrl;
|
|
27
|
+
seeds;
|
|
28
|
+
queues;
|
|
29
|
+
dynamo;
|
|
30
|
+
buckets;
|
|
31
|
+
resources;
|
|
32
|
+
services;
|
|
33
|
+
config;
|
|
34
|
+
health;
|
|
35
|
+
lifecycle;
|
|
36
|
+
http;
|
|
37
|
+
constructor(options = {}) {
|
|
38
|
+
const cfg = (0, config_discovery_1.resolveConfig)(options);
|
|
39
|
+
this.http = new http_1.Http({ baseUrl: cfg.baseUrl, timeoutMs: cfg.timeoutMs });
|
|
40
|
+
this.baseUrl = cfg.baseUrl;
|
|
41
|
+
this.seeds = (0, seeds_1.createSeedsApi)(this.http, cfg.region);
|
|
42
|
+
this.queues = (0, queues_1.createQueuesApi)(this.http, cfg.region);
|
|
43
|
+
this.dynamo = (0, dynamo_1.createDynamoApi)(this.http, cfg.region);
|
|
44
|
+
this.buckets = (0, buckets_1.createBucketsApi)(this.http, cfg.region);
|
|
45
|
+
this.resources = (0, resources_1.createResourcesApi)(this.http, cfg.region);
|
|
46
|
+
this.services = (0, services_1.createServicesApi)(this.http);
|
|
47
|
+
this.config = (0, config_1.createConfigApi)(this.http);
|
|
48
|
+
this.health = (0, health_1.createHealthApi)(this.http);
|
|
49
|
+
this.lifecycle = new lifecycle_1.Lifecycle({ health: this.health, cwd: cfg.cwd, configPath: cfg.configPath });
|
|
50
|
+
}
|
|
51
|
+
/** Escape hatch for an arbitrary orchestrator call not covered by a namespace. */
|
|
52
|
+
request(method, path, body, query) {
|
|
53
|
+
return this.http.json(method, path, { body, query });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.LssClient = LssClient;
|
|
57
|
+
var http_2 = require("./http");
|
|
58
|
+
Object.defineProperty(exports, "LssHttpError", { enumerable: true, get: function () { return http_2.LssHttpError; } });
|
|
59
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":";AAAA,mEAAmE;AACnE,EAAE;AACF,wDAAwD;AACxD,sEAAsE;AACtE,+EAA+E;AAC/E,EAAE;AACF,+EAA+E;AAC/E,iFAAiF;AACjF,oFAAoF;;;AAEpF,yDAAmD;AACnD,iCAA+C;AAC/C,2CAA2D;AAC3D,8CAAmE;AACnE,gDAAsE;AACtE,gDAAsE;AACtE,kDAAyE;AACzE,sDAA+E;AAC/E,oDAA4E;AAC5E,gDAAsE;AACtE,gDAAsE;AAGtE,MAAa,SAAS;IACpB,iDAAiD;IACxC,OAAO,CAAS;IAChB,KAAK,CAAW;IAChB,MAAM,CAAY;IAClB,MAAM,CAAY;IAClB,OAAO,CAAa;IACpB,SAAS,CAAe;IACxB,QAAQ,CAAc;IACtB,MAAM,CAAY;IAClB,MAAM,CAAY;IAClB,SAAS,CAAe;IAEhB,IAAI,CAAO;IAE5B,YAAY,UAA4B,EAAE;QACxC,MAAM,GAAG,GAAG,IAAA,gCAAa,EAAC,OAAO,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,WAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;QACzE,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAE3B,IAAI,CAAC,KAAK,GAAG,IAAA,sBAAc,EAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,GAAG,IAAA,wBAAe,EAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,CAAC,MAAM,GAAG,IAAA,wBAAe,EAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,CAAC,OAAO,GAAG,IAAA,0BAAgB,EAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACvD,IAAI,CAAC,SAAS,GAAG,IAAA,8BAAkB,EAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3D,IAAI,CAAC,QAAQ,GAAG,IAAA,4BAAiB,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG,IAAA,wBAAe,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,GAAG,IAAA,wBAAe,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,SAAS,GAAG,IAAI,qBAAS,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;IACpG,CAAC;IAED,kFAAkF;IAClF,OAAO,CACL,MAAc,EACd,IAAY,EACZ,IAAc,EACd,KAAkC;QAElC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAI,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1D,CAAC;CACF;AAxCD,8BAwCC;AAED,+BAAsC;AAA7B,oGAAA,YAAY,OAAA"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { HealthApi } from './namespaces/health';
|
|
2
|
+
export interface StartOptions {
|
|
3
|
+
/** Overrides the client's configPath for this invocation (threaded as --config). */
|
|
4
|
+
configPath?: string;
|
|
5
|
+
enableDynamoProxy?: boolean;
|
|
6
|
+
external?: boolean;
|
|
7
|
+
pro?: boolean;
|
|
8
|
+
localstackToken?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface StartResult {
|
|
11
|
+
alreadyRunning: boolean;
|
|
12
|
+
raw: string;
|
|
13
|
+
}
|
|
14
|
+
export interface StopResult {
|
|
15
|
+
wasRunning: boolean;
|
|
16
|
+
raw: string;
|
|
17
|
+
}
|
|
18
|
+
export interface StatusResult {
|
|
19
|
+
running: boolean;
|
|
20
|
+
raw: string;
|
|
21
|
+
}
|
|
22
|
+
export interface LogsResult {
|
|
23
|
+
raw: string;
|
|
24
|
+
}
|
|
25
|
+
export interface WaitUntilReadyOptions {
|
|
26
|
+
timeoutMs?: number;
|
|
27
|
+
intervalMs?: number;
|
|
28
|
+
}
|
|
29
|
+
export interface LifecycleApi {
|
|
30
|
+
start(opts?: StartOptions): Promise<StartResult>;
|
|
31
|
+
stop(): Promise<StopResult>;
|
|
32
|
+
status(): Promise<StatusResult>;
|
|
33
|
+
logs(): Promise<LogsResult>;
|
|
34
|
+
/** Poll GET /api/health until LocalStack reports ready, or reject after timeoutMs. */
|
|
35
|
+
waitUntilReady(opts?: WaitUntilReadyOptions): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
export interface LifecycleDeps {
|
|
38
|
+
health: HealthApi;
|
|
39
|
+
cwd: string;
|
|
40
|
+
configPath?: string;
|
|
41
|
+
}
|
|
42
|
+
export declare function resolveCliPath(): string;
|
|
43
|
+
export declare class Lifecycle implements LifecycleApi {
|
|
44
|
+
private readonly deps;
|
|
45
|
+
constructor(deps: LifecycleDeps);
|
|
46
|
+
private configArgs;
|
|
47
|
+
start(opts?: StartOptions): Promise<StartResult>;
|
|
48
|
+
stop(): Promise<StopResult>;
|
|
49
|
+
status(): Promise<StatusResult>;
|
|
50
|
+
logs(): Promise<LogsResult>;
|
|
51
|
+
waitUntilReady(opts?: WaitUntilReadyOptions): Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/client/lifecycle.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,WAAW,YAAY;IAC3B,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AACD,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,OAAO,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;CACb;AACD,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;CACb;AACD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AACD,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;CACb;AACD,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACjD,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5B,MAAM,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;IAChC,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5B,sFAAsF;IACtF,cAAc,CAAC,IAAI,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAYD,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAqBD,qBAAa,SAAU,YAAW,YAAY;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,aAAa;IAEhD,OAAO,CAAC,UAAU;IAKZ,KAAK,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,WAAW,CAAC;IAYpD,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;IAM3B,MAAM,IAAI,OAAO,CAAC,YAAY,CAAC;IAM/B,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;IAK3B,cAAc,CAAC,IAAI,GAAE,qBAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;CAiBtE"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Programmatic orchestrator lifecycle. start/stop/status/logs are process-spawn
|
|
3
|
+
// + PID/stateDir file work — NOT HTTP — so instead of duplicating the CLI's
|
|
4
|
+
// battle-tested logic we shell out to `bin/cli.js`. `waitUntilReady` then polls
|
|
5
|
+
// GET /api/health, because `lss start` returns before LocalStack is actually up.
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.Lifecycle = void 0;
|
|
11
|
+
exports.resolveCliPath = resolveCliPath;
|
|
12
|
+
const child_process_1 = require("child_process");
|
|
13
|
+
const path_1 = __importDefault(require("path"));
|
|
14
|
+
// `bin/cli.js` always sits two levels above the built client (dist/client/ or,
|
|
15
|
+
// in tests, src/client/). LSS_CLI_PATH overrides it (e.g. to a fake CLI in tests
|
|
16
|
+
// or a pinned install). No require.resolve needed — the relative layout holds
|
|
17
|
+
// both in-repo and when installed under node_modules.
|
|
18
|
+
function resolveCliPath() {
|
|
19
|
+
return process.env.LSS_CLI_PATH || path_1.default.join(__dirname, '..', '..', 'bin', 'cli.js');
|
|
20
|
+
}
|
|
21
|
+
function runCli(args, cwd) {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
const child = (0, child_process_1.spawn)(process.execPath, [resolveCliPath(), ...args], { cwd, env: process.env });
|
|
24
|
+
let stdout = '';
|
|
25
|
+
let stderr = '';
|
|
26
|
+
child.stdout.on('data', (d) => (stdout += d.toString()));
|
|
27
|
+
child.stderr.on('data', (d) => (stderr += d.toString()));
|
|
28
|
+
/* istanbul ignore next -- defensive: process.execPath is always spawnable */
|
|
29
|
+
child.on('error', reject);
|
|
30
|
+
child.on('close', (code) => resolve({ stdout, stderr, code }));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const delay = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
34
|
+
function cliError(verb, r) {
|
|
35
|
+
return new Error(`lss ${verb} failed (exit ${r.code}): ${(r.stderr || r.stdout).trim()}`);
|
|
36
|
+
}
|
|
37
|
+
class Lifecycle {
|
|
38
|
+
deps;
|
|
39
|
+
constructor(deps) {
|
|
40
|
+
this.deps = deps;
|
|
41
|
+
}
|
|
42
|
+
configArgs(override) {
|
|
43
|
+
const cp = override ?? this.deps.configPath;
|
|
44
|
+
return cp ? ['--config', path_1.default.resolve(this.deps.cwd, cp)] : [];
|
|
45
|
+
}
|
|
46
|
+
async start(opts = {}) {
|
|
47
|
+
const args = ['start', ...this.configArgs(opts.configPath)];
|
|
48
|
+
if (opts.enableDynamoProxy)
|
|
49
|
+
args.push('--enable-dynamo-proxy');
|
|
50
|
+
if (opts.external)
|
|
51
|
+
args.push('--external');
|
|
52
|
+
if (opts.pro)
|
|
53
|
+
args.push('--pro');
|
|
54
|
+
if (opts.localstackToken)
|
|
55
|
+
args.push('--localstack-token', opts.localstackToken);
|
|
56
|
+
const r = await runCli(args, this.deps.cwd);
|
|
57
|
+
if (r.code !== 0)
|
|
58
|
+
throw cliError('start', r);
|
|
59
|
+
return { alreadyRunning: /already running/i.test(r.stdout), raw: r.stdout };
|
|
60
|
+
}
|
|
61
|
+
async stop() {
|
|
62
|
+
const r = await runCli(['stop', ...this.configArgs()], this.deps.cwd);
|
|
63
|
+
if (r.code !== 0)
|
|
64
|
+
throw cliError('stop', r);
|
|
65
|
+
return { wasRunning: !/not running/i.test(r.stdout), raw: r.stdout };
|
|
66
|
+
}
|
|
67
|
+
async status() {
|
|
68
|
+
const r = await runCli(['status', ...this.configArgs()], this.deps.cwd);
|
|
69
|
+
const running = /running/i.test(r.stdout) && !/not running/i.test(r.stdout);
|
|
70
|
+
return { running, raw: r.stdout };
|
|
71
|
+
}
|
|
72
|
+
async logs() {
|
|
73
|
+
const r = await runCli(['logs', ...this.configArgs()], this.deps.cwd);
|
|
74
|
+
return { raw: r.stdout };
|
|
75
|
+
}
|
|
76
|
+
async waitUntilReady(opts = {}) {
|
|
77
|
+
const timeoutMs = opts.timeoutMs ?? 120000;
|
|
78
|
+
const intervalMs = opts.intervalMs ?? 1000;
|
|
79
|
+
const startedAt = Date.now();
|
|
80
|
+
for (;;) {
|
|
81
|
+
try {
|
|
82
|
+
const health = await this.deps.health.get();
|
|
83
|
+
if (health.localstack === true)
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// Orchestrator not accepting connections yet — keep polling.
|
|
88
|
+
}
|
|
89
|
+
if (Date.now() - startedAt >= timeoutMs) {
|
|
90
|
+
throw new Error(`orchestrator not ready after ${timeoutMs}ms`);
|
|
91
|
+
}
|
|
92
|
+
await delay(intervalMs);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
exports.Lifecycle = Lifecycle;
|
|
97
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/client/lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Http } from '../http';
|
|
2
|
+
import type { BucketSnapshot, ListObjectsInput, ListObjectsResult, PutObjectInput } from '../types';
|
|
3
|
+
export interface BucketsApi {
|
|
4
|
+
list(region?: string): Promise<BucketSnapshot[]>;
|
|
5
|
+
get(name: string, region?: string): Promise<BucketSnapshot>;
|
|
6
|
+
listObjects(name: string, input?: ListObjectsInput, region?: string): Promise<ListObjectsResult>;
|
|
7
|
+
/** GET /api/buckets/:name/objects/content — returns the raw object body as a Buffer. */
|
|
8
|
+
getObject(name: string, key: string, opts?: {
|
|
9
|
+
download?: boolean;
|
|
10
|
+
}, region?: string): Promise<Buffer>;
|
|
11
|
+
putObject(name: string, input: PutObjectInput, region?: string): Promise<{
|
|
12
|
+
success: true;
|
|
13
|
+
}>;
|
|
14
|
+
deleteObject(name: string, key: string, region?: string): Promise<{
|
|
15
|
+
success: true;
|
|
16
|
+
}>;
|
|
17
|
+
}
|
|
18
|
+
export declare function createBucketsApi(http: Http, defaultRegion?: string): BucketsApi;
|
|
19
|
+
//# sourceMappingURL=buckets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buckets.d.ts","sourceRoot":"","sources":["../../../src/client/namespaces/buckets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEpG,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACjD,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC5D,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACjG,wFAAwF;IACxF,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IAC5F,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;CACtF;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,UAAU,CAyB/E"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createBucketsApi = createBucketsApi;
|
|
4
|
+
function createBucketsApi(http, defaultRegion) {
|
|
5
|
+
const reg = (r) => r ?? defaultRegion;
|
|
6
|
+
const base = (name) => `/api/buckets/${encodeURIComponent(name)}`;
|
|
7
|
+
return {
|
|
8
|
+
list: (r) => http.json('GET', '/api/buckets', { query: { region: reg(r) } }),
|
|
9
|
+
get: (name, r) => http.json('GET', base(name), { query: { region: reg(r) } }),
|
|
10
|
+
listObjects: (name, input, r) => http.json('GET', `${base(name)}/objects`, {
|
|
11
|
+
query: {
|
|
12
|
+
prefix: input?.prefix,
|
|
13
|
+
continuationToken: input?.continuationToken,
|
|
14
|
+
delimiter: input?.delimiter,
|
|
15
|
+
maxKeys: input?.maxKeys,
|
|
16
|
+
region: reg(r),
|
|
17
|
+
},
|
|
18
|
+
}),
|
|
19
|
+
getObject: (name, key, opts, r) => http.raw('GET', `${base(name)}/objects/content`, {
|
|
20
|
+
query: { key, download: opts?.download ? '1' : undefined, region: reg(r) },
|
|
21
|
+
}),
|
|
22
|
+
putObject: (name, input, r) => http.json('POST', `${base(name)}/objects`, { body: input, query: { region: reg(r) } }),
|
|
23
|
+
deleteObject: (name, key, r) => http.json('DELETE', `${base(name)}/objects`, { query: { key, region: reg(r) } }),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=buckets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buckets.js","sourceRoot":"","sources":["../../../src/client/namespaces/buckets.ts"],"names":[],"mappings":";;AAaA,4CAyBC;AAzBD,SAAgB,gBAAgB,CAAC,IAAU,EAAE,aAAsB;IACjE,MAAM,GAAG,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,IAAI,aAAa,CAAC;IAC/C,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,gBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;IAC1E,OAAO;QACL,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC5E,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC7E,WAAW,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAC9B,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YACxC,KAAK,EAAE;gBACL,MAAM,EAAE,KAAK,EAAE,MAAM;gBACrB,iBAAiB,EAAE,KAAK,EAAE,iBAAiB;gBAC3C,SAAS,EAAE,KAAK,EAAE,SAAS;gBAC3B,OAAO,EAAE,KAAK,EAAE,OAAO;gBACvB,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;aACf;SACF,CAAC;QACJ,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAChC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE;YAC/C,KAAK,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE;SAC3E,CAAC;QACJ,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACxF,YAAY,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,CAC7B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;KACnF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Http } from '../http';
|
|
2
|
+
export interface ConfigApi {
|
|
3
|
+
/** GET /api/config — public-safe orchestrator config snapshot (never leaks the auth token). */
|
|
4
|
+
get(): Promise<unknown>;
|
|
5
|
+
}
|
|
6
|
+
export declare function createConfigApi(http: Http): ConfigApi;
|
|
7
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/client/namespaces/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAEpC,MAAM,WAAW,SAAS;IACxB,+FAA+F;IAC/F,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACzB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAIrD"}
|