@intentius/chant-lexicon-gcp 0.15.0 → 0.15.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/integrity.json +2 -2
- package/dist/manifest.json +1 -1
- package/dist/op/activities/floci-gcp.d.ts +44 -0
- package/dist/op/activities/floci-gcp.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +2 -0
- package/dist/op/activities/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/op/activities/floci-gcp.test.ts +29 -0
- package/src/op/activities/floci-gcp.ts +123 -0
- package/src/op/activities/index.ts +13 -0
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "3c45f5e54db2e865c44d31a6aad4819415ec4eb48fdef24c5caeebd8d5dd9744",
|
|
5
5
|
"meta.json": "475f10909854d059a2e2d4fb541c058803422e38b9c64bd4d6858c0623eedb8c",
|
|
6
6
|
"types/index.d.ts": "5433b54c04b57d6fda8f3d81ef92ed0aca87f7e8e5dd3ea92d8de6e62a3ccfab",
|
|
7
7
|
"rules/hardcoded-project.ts": "228631d3159e1ffcce2359c66073d4ae59bb0285f378e46e446f416aec50481c",
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
"skills/chant-gcp-patterns.md": "a7ef31c1eb2f7244d3f73952c300472ef94c1eb09bd7a1003281b89299b6b704",
|
|
38
38
|
"skills/chant-gcp-gke.md": "be277019da9a722c851e47cd2dfb9c9536668948c3535fb20db7697e934c4e2b"
|
|
39
39
|
},
|
|
40
|
-
"composite": "
|
|
40
|
+
"composite": "42fc10bc9384b76a76f820292b930953ad576e8417f95d969d0dfcf84dd4f204"
|
|
41
41
|
}
|
package/dist/manifest.json
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface FlociGcpUpArgs {
|
|
2
|
+
/** Container name. Default: `chant-floci-gcp`. */
|
|
3
|
+
name?: string;
|
|
4
|
+
/** Host port mapped to the emulator's `:4588`. Default: `4588`. */
|
|
5
|
+
port?: number;
|
|
6
|
+
/** Image. Default: `floci/floci-gcp:latest`. */
|
|
7
|
+
image?: string;
|
|
8
|
+
/** Readiness timeout in ms. Default: `60000`. */
|
|
9
|
+
timeoutMs?: number;
|
|
10
|
+
/** Health poll interval in ms. Default: `2000`. */
|
|
11
|
+
intervalMs?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface FlociGcpDownArgs {
|
|
14
|
+
/** Container name to remove. Default: `chant-floci-gcp`. */
|
|
15
|
+
name?: string;
|
|
16
|
+
}
|
|
17
|
+
/** `docker ps -q -f name=<name>` — non-empty stdout means the container is running. */
|
|
18
|
+
export declare function flociGcpExistsCommand(name: string): string;
|
|
19
|
+
/** Build the `docker run` command that boots floci-gcp. */
|
|
20
|
+
export declare function flociGcpRunCommand(args: FlociGcpUpArgs): string;
|
|
21
|
+
/** Build the `docker rm -f` command. */
|
|
22
|
+
export declare function flociGcpRmCommand(name: string): string;
|
|
23
|
+
/** The floci-gcp health endpoint URL for a host port. */
|
|
24
|
+
export declare function flociGcpHealthUrl(port: number): string;
|
|
25
|
+
/** The GCP endpoint URL (what `gcpApply`'s `endpoint` should point at). */
|
|
26
|
+
export declare function flociGcpEndpoint(port: number): string;
|
|
27
|
+
/**
|
|
28
|
+
* Boot a local floci-gcp (GCP emulator) in Docker and return its endpoint.
|
|
29
|
+
*
|
|
30
|
+
* Idempotent: reuses a running container of the same name. Waits for the health
|
|
31
|
+
* endpoint to answer, then returns `{ endpoint }` for `gcpApply({ endpoint })`.
|
|
32
|
+
* The typed twin of the AWS `flociUp` — replaces a raw `docker run` shell step so
|
|
33
|
+
* the emulator lifecycle is modeled, not scripted. Uses longInfra profile — 20m
|
|
34
|
+
* timeout, heartbeat every poll (the image may pull).
|
|
35
|
+
*/
|
|
36
|
+
export declare function flociGcpUp(args: FlociGcpUpArgs, signal?: AbortSignal): Promise<{
|
|
37
|
+
endpoint: string;
|
|
38
|
+
}>;
|
|
39
|
+
/**
|
|
40
|
+
* Stop and remove the local floci-gcp container. A no-op success when the
|
|
41
|
+
* container is already gone. Uses fastIdempotent profile — 5m timeout.
|
|
42
|
+
*/
|
|
43
|
+
export declare function flociGcpDown(args: FlociGcpDownArgs, signal?: AbortSignal): Promise<void>;
|
|
44
|
+
//# sourceMappingURL=floci-gcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"floci-gcp.d.ts","sourceRoot":"","sources":["../../../src/op/activities/floci-gcp.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,uFAAuF;AACvF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,2DAA2D;AAC3D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAK/D;AAED,wCAAwC;AACxC,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,yDAAyD;AACzD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,2EAA2E;AAC3E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA4C1G;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAO9F"}
|
|
@@ -6,4 +6,6 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { gcpApply, gcpDelete, applyResource, deleteResource, waitForOperation, longRunningOperation, bucketInsertBody, pubSubTopicBody, pubSubSubscriptionBody, cloudRunServiceBody, secretBody, serviceAccountBody, storageBucketMapper, pubSubTopicMapper, pubSubSubscriptionMapper, cloudRunServiceMapper, secretManagerSecretMapper, gcpServiceAccountMapper, MAPPERS, referencedNames, orderByReferences, pruneOrphans, chantOwnershipLabels, isChantOwned, resolveGcpProject, parseManifest, } from "./gcp-apply.js";
|
|
8
8
|
export type { GcpApplyArgs, GcpResource, CnrmStorageBucket, BucketInsertBody, PubSubTopicBody, ResourceMapper, OperationSpec, ListSpec, ApplyPlan, GcpHttp, } from "./gcp-apply.js";
|
|
9
|
+
export { flociGcpUp, flociGcpDown, flociGcpRunCommand, flociGcpRmCommand, flociGcpExistsCommand, flociGcpHealthUrl, flociGcpEndpoint, } from "./floci-gcp.js";
|
|
10
|
+
export type { FlociGcpUpArgs, FlociGcpDownArgs } from "./floci-gcp.js";
|
|
9
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/op/activities/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,QAAQ,EACR,SAAS,EACT,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACnB,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,uBAAuB,EACvB,OAAO,EACP,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,aAAa,EACb,QAAQ,EACR,SAAS,EACT,OAAO,GACR,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/op/activities/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,QAAQ,EACR,SAAS,EACT,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACnB,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,uBAAuB,EACvB,OAAO,EACP,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,aAAa,EACb,QAAQ,EACR,SAAS,EACT,OAAO,GACR,MAAM,aAAa,CAAC;AAIrB,OAAO,EACL,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-gcp",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.2",
|
|
4
4
|
"description": "Google Cloud lexicon for chant — declarative IaC in TypeScript",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://intentius.io/chant",
|
|
@@ -76,6 +76,6 @@
|
|
|
76
76
|
"typescript": "^5.9.3"
|
|
77
77
|
},
|
|
78
78
|
"peerDependencies": {
|
|
79
|
-
"@intentius/chant": "^0.15.
|
|
79
|
+
"@intentius/chant": "^0.15.2"
|
|
80
80
|
}
|
|
81
81
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
flociGcpRunCommand,
|
|
4
|
+
flociGcpRmCommand,
|
|
5
|
+
flociGcpExistsCommand,
|
|
6
|
+
flociGcpHealthUrl,
|
|
7
|
+
flociGcpEndpoint,
|
|
8
|
+
} from "./floci-gcp";
|
|
9
|
+
|
|
10
|
+
describe("floci-gcp lifecycle commands (typed emulator, not shell)", () => {
|
|
11
|
+
test("run command uses defaults and maps the port", () => {
|
|
12
|
+
expect(flociGcpRunCommand({})).toBe(
|
|
13
|
+
"docker run -d --rm --name chant-floci-gcp -p 4588:4588 floci/floci-gcp:latest",
|
|
14
|
+
);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test("run command honors name/port/image overrides", () => {
|
|
18
|
+
expect(flociGcpRunCommand({ name: "gcp2", port: 4599, image: "floci/floci-gcp:0.4.0" })).toBe(
|
|
19
|
+
"docker run -d --rm --name gcp2 -p 4599:4588 floci/floci-gcp:0.4.0",
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test("rm / exists / health / endpoint", () => {
|
|
24
|
+
expect(flociGcpRmCommand("gcp2")).toBe("docker rm -f gcp2");
|
|
25
|
+
expect(flociGcpExistsCommand("gcp2")).toBe("docker ps -q -f name=gcp2");
|
|
26
|
+
expect(flociGcpHealthUrl(4588)).toBe("http://localhost:4588/_floci-gcp/health");
|
|
27
|
+
expect(flociGcpEndpoint(4588)).toBe("http://localhost:4588");
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { exec } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { safeHeartbeat, sleep } from "@intentius/chant/op";
|
|
4
|
+
|
|
5
|
+
const execAsync = promisify(exec);
|
|
6
|
+
|
|
7
|
+
const DEFAULT_NAME = "chant-floci-gcp";
|
|
8
|
+
const DEFAULT_PORT = 4588;
|
|
9
|
+
const DEFAULT_IMAGE = "floci/floci-gcp:latest";
|
|
10
|
+
|
|
11
|
+
export interface FlociGcpUpArgs {
|
|
12
|
+
/** Container name. Default: `chant-floci-gcp`. */
|
|
13
|
+
name?: string;
|
|
14
|
+
/** Host port mapped to the emulator's `:4588`. Default: `4588`. */
|
|
15
|
+
port?: number;
|
|
16
|
+
/** Image. Default: `floci/floci-gcp:latest`. */
|
|
17
|
+
image?: string;
|
|
18
|
+
/** Readiness timeout in ms. Default: `60000`. */
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
/** Health poll interval in ms. Default: `2000`. */
|
|
21
|
+
intervalMs?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface FlociGcpDownArgs {
|
|
25
|
+
/** Container name to remove. Default: `chant-floci-gcp`. */
|
|
26
|
+
name?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** `docker ps -q -f name=<name>` — non-empty stdout means the container is running. */
|
|
30
|
+
export function flociGcpExistsCommand(name: string): string {
|
|
31
|
+
return `docker ps -q -f name=${name}`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Build the `docker run` command that boots floci-gcp. */
|
|
35
|
+
export function flociGcpRunCommand(args: FlociGcpUpArgs): string {
|
|
36
|
+
const name = args.name ?? DEFAULT_NAME;
|
|
37
|
+
const port = args.port ?? DEFAULT_PORT;
|
|
38
|
+
const image = args.image ?? DEFAULT_IMAGE;
|
|
39
|
+
return ["docker", "run", "-d", "--rm", "--name", name, "-p", `${port}:4588`, image].join(" ");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Build the `docker rm -f` command. */
|
|
43
|
+
export function flociGcpRmCommand(name: string): string {
|
|
44
|
+
return `docker rm -f ${name}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The floci-gcp health endpoint URL for a host port. */
|
|
48
|
+
export function flociGcpHealthUrl(port: number): string {
|
|
49
|
+
return `http://localhost:${port}/_floci-gcp/health`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** The GCP endpoint URL (what `gcpApply`'s `endpoint` should point at). */
|
|
53
|
+
export function flociGcpEndpoint(port: number): string {
|
|
54
|
+
return `http://localhost:${port}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Boot a local floci-gcp (GCP emulator) in Docker and return its endpoint.
|
|
59
|
+
*
|
|
60
|
+
* Idempotent: reuses a running container of the same name. Waits for the health
|
|
61
|
+
* endpoint to answer, then returns `{ endpoint }` for `gcpApply({ endpoint })`.
|
|
62
|
+
* The typed twin of the AWS `flociUp` — replaces a raw `docker run` shell step so
|
|
63
|
+
* the emulator lifecycle is modeled, not scripted. Uses longInfra profile — 20m
|
|
64
|
+
* timeout, heartbeat every poll (the image may pull).
|
|
65
|
+
*/
|
|
66
|
+
export async function flociGcpUp(args: FlociGcpUpArgs, signal?: AbortSignal): Promise<{ endpoint: string }> {
|
|
67
|
+
const name = args.name ?? DEFAULT_NAME;
|
|
68
|
+
const port = args.port ?? DEFAULT_PORT;
|
|
69
|
+
const timeoutMs = args.timeoutMs ?? 60_000;
|
|
70
|
+
const intervalMs = args.intervalMs ?? 2_000;
|
|
71
|
+
|
|
72
|
+
let running = false;
|
|
73
|
+
try {
|
|
74
|
+
const { stdout } = await execAsync(flociGcpExistsCommand(name), { signal });
|
|
75
|
+
running = Boolean(stdout.trim());
|
|
76
|
+
} catch {
|
|
77
|
+
// `docker ps` failed — assume not running and try to start it.
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (running) {
|
|
81
|
+
console.log(`floci-gcp container "${name}" already running — reusing`);
|
|
82
|
+
} else {
|
|
83
|
+
await execAsync(flociGcpRunCommand({ ...args, name, port }), { signal });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const url = flociGcpHealthUrl(port);
|
|
87
|
+
const deadline = Date.now() + timeoutMs;
|
|
88
|
+
let ready = false;
|
|
89
|
+
while (Date.now() < deadline) {
|
|
90
|
+
if (signal?.aborted) throw new Error("flociGcpUp aborted");
|
|
91
|
+
safeHeartbeat({ step: "flociGcpUp", container: name });
|
|
92
|
+
try {
|
|
93
|
+
const res = await fetch(url, { signal });
|
|
94
|
+
if (res.ok) {
|
|
95
|
+
ready = true;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
} catch {
|
|
99
|
+
// Not up yet (connection refused / non-2xx) — retry.
|
|
100
|
+
}
|
|
101
|
+
await sleep(intervalMs, signal);
|
|
102
|
+
}
|
|
103
|
+
if (!ready) {
|
|
104
|
+
throw new Error(`floci-gcp "${name}" did not become ready within ${timeoutMs}ms`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const endpoint = flociGcpEndpoint(port);
|
|
108
|
+
console.log(`floci-gcp ready on ${endpoint}`);
|
|
109
|
+
return { endpoint };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Stop and remove the local floci-gcp container. A no-op success when the
|
|
114
|
+
* container is already gone. Uses fastIdempotent profile — 5m timeout.
|
|
115
|
+
*/
|
|
116
|
+
export async function flociGcpDown(args: FlociGcpDownArgs, signal?: AbortSignal): Promise<void> {
|
|
117
|
+
const name = args.name ?? DEFAULT_NAME;
|
|
118
|
+
try {
|
|
119
|
+
await execAsync(flociGcpRmCommand(name), { signal });
|
|
120
|
+
} catch {
|
|
121
|
+
// Already removed (`--rm` on exit, or never started) — treat as success.
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -44,3 +44,16 @@ export type {
|
|
|
44
44
|
ApplyPlan,
|
|
45
45
|
GcpHttp,
|
|
46
46
|
} from "./gcp-apply";
|
|
47
|
+
|
|
48
|
+
// floci-gcp (GCP emulator) lifecycle — the typed twin of aws's flociUp/Down, so
|
|
49
|
+
// the trio's GCP op boots/tears down the emulator as a modeled step, not a shell.
|
|
50
|
+
export {
|
|
51
|
+
flociGcpUp,
|
|
52
|
+
flociGcpDown,
|
|
53
|
+
flociGcpRunCommand,
|
|
54
|
+
flociGcpRmCommand,
|
|
55
|
+
flociGcpExistsCommand,
|
|
56
|
+
flociGcpHealthUrl,
|
|
57
|
+
flociGcpEndpoint,
|
|
58
|
+
} from "./floci-gcp";
|
|
59
|
+
export type { FlociGcpUpArgs, FlociGcpDownArgs } from "./floci-gcp";
|