@infracraft/pulumi 1.16.2 → 1.16.4
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/{deploy-command.cjs → commands/deploy.cjs} +7 -7
- package/dist/commands/deploy.cjs.map +1 -0
- package/dist/{deploy-command.d.mts → commands/deploy.d.cts} +3 -3
- package/dist/commands/deploy.d.cts.map +1 -0
- package/dist/{deploy-command.d.cts → commands/deploy.d.mts} +4 -4
- package/dist/commands/deploy.d.mts.map +1 -0
- package/dist/{deploy-command.mjs → commands/deploy.mjs} +6 -6
- package/dist/commands/deploy.mjs.map +1 -0
- package/dist/fly/deploy.cjs +2 -2
- package/dist/fly/deploy.cjs.map +1 -1
- package/dist/fly/deploy.mjs +1 -1
- package/dist/fly/deploy.mjs.map +1 -1
- package/dist/hash.cjs +2 -2
- package/dist/hash.mjs +1 -1
- package/dist/railway/deploy.cjs +2 -2
- package/dist/railway/deploy.cjs.map +1 -1
- package/dist/railway/deploy.mjs +1 -1
- package/dist/railway/deploy.mjs.map +1 -1
- package/dist/sandbox.cjs +34 -11
- package/dist/sandbox.cjs.map +1 -1
- package/dist/sandbox.d.cts +6 -1
- package/dist/sandbox.d.cts.map +1 -1
- package/dist/sandbox.d.mts +6 -1
- package/dist/sandbox.d.mts.map +1 -1
- package/dist/sandbox.mjs +34 -11
- package/dist/sandbox.mjs.map +1 -1
- package/dist/vercel/deploy.cjs +2 -2
- package/dist/vercel/deploy.cjs.map +1 -1
- package/dist/vercel/deploy.mjs +1 -1
- package/dist/vercel/deploy.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/deploy-command.cjs.map +0 -1
- package/dist/deploy-command.d.cts.map +0 -1
- package/dist/deploy-command.d.mts.map +0 -1
- package/dist/deploy-command.mjs.map +0 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_chunk = require('
|
|
3
|
-
const require_git_guard = require('
|
|
4
|
-
const require_sandbox = require('
|
|
5
|
-
let _pulumi_command = require("@pulumi/command");
|
|
6
|
-
_pulumi_command = require_chunk.__toESM(_pulumi_command, 1);
|
|
2
|
+
const require_chunk = require('../chunk-BVYJZCqc.cjs');
|
|
3
|
+
const require_git_guard = require('../git-guard.cjs');
|
|
4
|
+
const require_sandbox = require('../sandbox.cjs');
|
|
7
5
|
let _pulumi_pulumi = require("@pulumi/pulumi");
|
|
8
6
|
_pulumi_pulumi = require_chunk.__toESM(_pulumi_pulumi, 1);
|
|
7
|
+
let _pulumi_command = require("@pulumi/command");
|
|
8
|
+
_pulumi_command = require_chunk.__toESM(_pulumi_command, 1);
|
|
9
9
|
|
|
10
|
-
//#region src/deploy
|
|
10
|
+
//#region src/commands/deploy.ts
|
|
11
11
|
/** Reads a `dependsOn` opt into a flat array of resource instances. */
|
|
12
12
|
function dependsOnList(opts) {
|
|
13
13
|
const dep = opts.dependsOn;
|
|
@@ -47,4 +47,4 @@ function createDeployCommand(args, opts) {
|
|
|
47
47
|
|
|
48
48
|
//#endregion
|
|
49
49
|
exports.createDeployCommand = createDeployCommand;
|
|
50
|
-
//# sourceMappingURL=deploy
|
|
50
|
+
//# sourceMappingURL=deploy.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.cjs","names":["isDeploySandbox","isGitGuard","pulumi","buildSandboxScript","command"],"sources":["../../src/commands/deploy.ts"],"sourcesContent":["// src/commands/deploy.ts\nimport * as command from \"@pulumi/command\";\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { isGitGuard } from \"../git-guard\";\nimport { buildSandboxScript, isDeploySandbox } from \"../sandbox\";\n\nexport interface CreateDeployCommandArgs {\n\t/** Resource name; the child command is `<name>` and the sandbox dir uses it. */\n\tname: string;\n\t/** Fully-formed platform deploy command (may be an Output, e.g. Railway). */\n\tcli: pulumi.Input<string>;\n\t/** Redeploy triggers (source/env hashes). */\n\ttriggers: pulumi.Input<pulumi.Input<string>[]>;\n\t/** Upload-scoping excludes (applied only in stub mode). */\n\texcludePaths?: string[];\n\t/** Shell run in the working dir before `cli` (e.g. write railpack.json). */\n\tsetup?: string;\n\t/** Env passed to the command (secrets that survive preview; not the inlined ones). */\n\tenvironment?: Record<string, pulumi.Input<string>>;\n}\n\nexport interface CreateDeployCommandResult {\n\tcommand: command.local.Command;\n\t/** The deploy CLI's final stdout line (the production URL for Vercel/Fly). */\n\tdeploymentUrl: pulumi.Output<string>;\n}\n\n/** Reads a `dependsOn` opt into a flat array of resource instances. */\nfunction dependsOnList(opts: pulumi.ComponentResourceOptions): unknown[] {\n\tconst dep = opts.dependsOn;\n\n\tif (Array.isArray(dep)) {\n\t\treturn dep;\n\t}\n\n\treturn dep ? [dep] : [];\n}\n\n/**\n * Builds a sandboxed deploy command. Inspects `opts.dependsOn` by brand:\n * a DeploySandbox → isolate; a GitGuard → stub `.git`; GitGuard alone → throw.\n * The platform deploy resources call ONLY this; they never touch the sandbox.\n */\nexport function createDeployCommand(\n\targs: CreateDeployCommandArgs,\n\topts: pulumi.ComponentResourceOptions,\n): CreateDeployCommandResult {\n\tconst deps = dependsOnList(opts);\n\tconst sandbox = deps.some(isDeploySandbox);\n\tconst gitGuard = deps.some(isGitGuard);\n\n\tif (gitGuard && !sandbox) {\n\t\tthrow new Error(\n\t\t\t`[infracraft] ${args.name}: GitGuard has no effect without a DeploySandbox in dependsOn`,\n\t\t);\n\t}\n\n\tconst env = pulumi.getStack();\n\n\tconst create = pulumi.output(args.cli).apply((cli) =>\n\t\tbuildSandboxScript({\n\t\t\tsandbox,\n\t\t\tgitGuard,\n\t\t\tappName: args.name,\n\t\t\tenv,\n\t\t\texcludePaths: args.excludePaths,\n\t\t\tsetup: args.setup,\n\t\t\tcli,\n\t\t}),\n\t);\n\n\tconst cmd = new command.local.Command(\n\t\targs.name,\n\t\t{ create, triggers: args.triggers, environment: args.environment },\n\t\topts,\n\t);\n\n\tconst deploymentUrl = cmd.stdout.apply(\n\t\t(out) => out.trim().split(\"\\n\").pop() ?? \"\",\n\t);\n\n\treturn { command: cmd, deploymentUrl };\n}\n"],"mappings":";;;;;;;;;;;AA6BA,SAAS,cAAc,MAAkD;CACxE,MAAM,MAAM,KAAK;CAEjB,IAAI,MAAM,QAAQ,GAAG,GACpB,OAAO;CAGR,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC;AACvB;;;;;;AAOA,SAAgB,oBACf,MACA,MAC4B;CAC5B,MAAM,OAAO,cAAc,IAAI;CAC/B,MAAM,UAAU,KAAK,KAAKA,+BAAe;CACzC,MAAM,WAAW,KAAK,KAAKC,4BAAU;CAErC,IAAI,YAAY,CAAC,SAChB,MAAM,IAAI,MACT,gBAAgB,KAAK,KAAK,8DAC3B;CAGD,MAAM,MAAMC,eAAO,SAAS;CAE5B,MAAM,SAASA,eAAO,OAAO,KAAK,GAAG,EAAE,OAAO,QAC7CC,mCAAmB;EAClB;EACA;EACA,SAAS,KAAK;EACd;EACA,cAAc,KAAK;EACnB,OAAO,KAAK;EACZ;CACD,CAAC,CACF;CAEA,MAAM,MAAM,IAAIC,gBAAQ,MAAM,QAC7B,KAAK,MACL;EAAE;EAAQ,UAAU,KAAK;EAAU,aAAa,KAAK;CAAY,GACjE,IACD;CAMA,OAAO;EAAE,SAAS;EAAK,eAJD,IAAI,OAAO,OAC/B,QAAQ,IAAI,KAAK,EAAE,MAAM,IAAI,EAAE,IAAI,KAAK,EAGP;CAAE;AACtC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as __name } from "
|
|
1
|
+
import { t as __name } from "../chunk-OPjESj5l.cjs";
|
|
2
2
|
import * as command from "@pulumi/command";
|
|
3
3
|
import * as pulumi from "@pulumi/pulumi";
|
|
4
4
|
|
|
5
|
-
//#region src/deploy
|
|
5
|
+
//#region src/commands/deploy.d.ts
|
|
6
6
|
interface CreateDeployCommandArgs {
|
|
7
7
|
/** Resource name; the child command is `<name>` and the sandbox dir uses it. */
|
|
8
8
|
name: string;
|
|
@@ -30,4 +30,4 @@ interface CreateDeployCommandResult {
|
|
|
30
30
|
declare function createDeployCommand(args: CreateDeployCommandArgs, opts: pulumi.ComponentResourceOptions): CreateDeployCommandResult;
|
|
31
31
|
//#endregion
|
|
32
32
|
export { CreateDeployCommandArgs, CreateDeployCommandResult, createDeployCommand };
|
|
33
|
-
//# sourceMappingURL=deploy
|
|
33
|
+
//# sourceMappingURL=deploy.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.d.cts","names":[],"sources":["../../src/commands/deploy.ts"],"mappings":";;;;;UAOiB,uBAAA;;EAEhB,IAAA;EAFgB;EAIhB,GAAA,EAAK,MAAA,CAAO,KAAA;;EAEZ,QAAA,EAAU,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,KAAA;EAAP;EAEvB,YAAA;EAI6B;EAF7B,KAAA;EAEoB;EAApB,WAAA,GAAc,MAAA,SAAe,MAAA,CAAO,KAAA;AAAA;AAAA,UAGpB,yBAAA;EAChB,OAAA,EAAS,OAAA,CAAQ,KAAA,CAAM,OAAA;EAZX;EAcZ,aAAA,EAAe,MAAA,CAAO,MAAM;AAAA;;;;;;iBAmBb,mBAAA,CACf,IAAA,EAAM,uBAAA,EACN,IAAA,EAAM,MAAA,CAAO,wBAAA,GACX,yBAAA"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as __name } from "
|
|
2
|
-
import * as command from "@pulumi/command";
|
|
1
|
+
import { t as __name } from "../chunk-OPjESj5l.mjs";
|
|
3
2
|
import * as pulumi from "@pulumi/pulumi";
|
|
3
|
+
import * as command from "@pulumi/command";
|
|
4
4
|
|
|
5
|
-
//#region src/deploy
|
|
5
|
+
//#region src/commands/deploy.d.ts
|
|
6
6
|
interface CreateDeployCommandArgs {
|
|
7
7
|
/** Resource name; the child command is `<name>` and the sandbox dir uses it. */
|
|
8
8
|
name: string;
|
|
@@ -30,4 +30,4 @@ interface CreateDeployCommandResult {
|
|
|
30
30
|
declare function createDeployCommand(args: CreateDeployCommandArgs, opts: pulumi.ComponentResourceOptions): CreateDeployCommandResult;
|
|
31
31
|
//#endregion
|
|
32
32
|
export { CreateDeployCommandArgs, CreateDeployCommandResult, createDeployCommand };
|
|
33
|
-
//# sourceMappingURL=deploy
|
|
33
|
+
//# sourceMappingURL=deploy.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.d.mts","names":[],"sources":["../../src/commands/deploy.ts"],"mappings":";;;;;UAOiB,uBAAA;;EAEhB,IAAA;EAFgB;EAIhB,GAAA,EAAK,MAAA,CAAO,KAAA;;EAEZ,QAAA,EAAU,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,KAAA;EAAP;EAEvB,YAAA;EAI6B;EAF7B,KAAA;EAEoB;EAApB,WAAA,GAAc,MAAA,SAAe,MAAA,CAAO,KAAA;AAAA;AAAA,UAGpB,yBAAA;EAChB,OAAA,EAAS,OAAA,CAAQ,KAAA,CAAM,OAAA;EAZX;EAcZ,aAAA,EAAe,MAAA,CAAO,MAAM;AAAA;;;;;;iBAmBb,mBAAA,CACf,IAAA,EAAM,uBAAA,EACN,IAAA,EAAM,MAAA,CAAO,wBAAA,GACX,yBAAA"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { t as __name } from "
|
|
2
|
-
import { isGitGuard } from "
|
|
3
|
-
import { buildSandboxScript, isDeploySandbox } from "
|
|
4
|
-
import * as command from "@pulumi/command";
|
|
1
|
+
import { t as __name } from "../chunk-OPjESj5l.mjs";
|
|
2
|
+
import { isGitGuard } from "../git-guard.mjs";
|
|
3
|
+
import { buildSandboxScript, isDeploySandbox } from "../sandbox.mjs";
|
|
5
4
|
import * as pulumi from "@pulumi/pulumi";
|
|
5
|
+
import * as command from "@pulumi/command";
|
|
6
6
|
|
|
7
|
-
//#region src/deploy
|
|
7
|
+
//#region src/commands/deploy.ts
|
|
8
8
|
/** Reads a `dependsOn` opt into a flat array of resource instances. */
|
|
9
9
|
function dependsOnList(opts) {
|
|
10
10
|
const dep = opts.dependsOn;
|
|
@@ -44,4 +44,4 @@ function createDeployCommand(args, opts) {
|
|
|
44
44
|
|
|
45
45
|
//#endregion
|
|
46
46
|
export { createDeployCommand };
|
|
47
|
-
//# sourceMappingURL=deploy
|
|
47
|
+
//# sourceMappingURL=deploy.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.mjs","names":[],"sources":["../../src/commands/deploy.ts"],"sourcesContent":["// src/commands/deploy.ts\nimport * as command from \"@pulumi/command\";\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { isGitGuard } from \"../git-guard\";\nimport { buildSandboxScript, isDeploySandbox } from \"../sandbox\";\n\nexport interface CreateDeployCommandArgs {\n\t/** Resource name; the child command is `<name>` and the sandbox dir uses it. */\n\tname: string;\n\t/** Fully-formed platform deploy command (may be an Output, e.g. Railway). */\n\tcli: pulumi.Input<string>;\n\t/** Redeploy triggers (source/env hashes). */\n\ttriggers: pulumi.Input<pulumi.Input<string>[]>;\n\t/** Upload-scoping excludes (applied only in stub mode). */\n\texcludePaths?: string[];\n\t/** Shell run in the working dir before `cli` (e.g. write railpack.json). */\n\tsetup?: string;\n\t/** Env passed to the command (secrets that survive preview; not the inlined ones). */\n\tenvironment?: Record<string, pulumi.Input<string>>;\n}\n\nexport interface CreateDeployCommandResult {\n\tcommand: command.local.Command;\n\t/** The deploy CLI's final stdout line (the production URL for Vercel/Fly). */\n\tdeploymentUrl: pulumi.Output<string>;\n}\n\n/** Reads a `dependsOn` opt into a flat array of resource instances. */\nfunction dependsOnList(opts: pulumi.ComponentResourceOptions): unknown[] {\n\tconst dep = opts.dependsOn;\n\n\tif (Array.isArray(dep)) {\n\t\treturn dep;\n\t}\n\n\treturn dep ? [dep] : [];\n}\n\n/**\n * Builds a sandboxed deploy command. Inspects `opts.dependsOn` by brand:\n * a DeploySandbox → isolate; a GitGuard → stub `.git`; GitGuard alone → throw.\n * The platform deploy resources call ONLY this; they never touch the sandbox.\n */\nexport function createDeployCommand(\n\targs: CreateDeployCommandArgs,\n\topts: pulumi.ComponentResourceOptions,\n): CreateDeployCommandResult {\n\tconst deps = dependsOnList(opts);\n\tconst sandbox = deps.some(isDeploySandbox);\n\tconst gitGuard = deps.some(isGitGuard);\n\n\tif (gitGuard && !sandbox) {\n\t\tthrow new Error(\n\t\t\t`[infracraft] ${args.name}: GitGuard has no effect without a DeploySandbox in dependsOn`,\n\t\t);\n\t}\n\n\tconst env = pulumi.getStack();\n\n\tconst create = pulumi.output(args.cli).apply((cli) =>\n\t\tbuildSandboxScript({\n\t\t\tsandbox,\n\t\t\tgitGuard,\n\t\t\tappName: args.name,\n\t\t\tenv,\n\t\t\texcludePaths: args.excludePaths,\n\t\t\tsetup: args.setup,\n\t\t\tcli,\n\t\t}),\n\t);\n\n\tconst cmd = new command.local.Command(\n\t\targs.name,\n\t\t{ create, triggers: args.triggers, environment: args.environment },\n\t\topts,\n\t);\n\n\tconst deploymentUrl = cmd.stdout.apply(\n\t\t(out) => out.trim().split(\"\\n\").pop() ?? \"\",\n\t);\n\n\treturn { command: cmd, deploymentUrl };\n}\n"],"mappings":";;;;;;;;AA6BA,SAAS,cAAc,MAAkD;CACxE,MAAM,MAAM,KAAK;CAEjB,IAAI,MAAM,QAAQ,GAAG,GACpB,OAAO;CAGR,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC;AACvB;;;;;;AAOA,SAAgB,oBACf,MACA,MAC4B;CAC5B,MAAM,OAAO,cAAc,IAAI;CAC/B,MAAM,UAAU,KAAK,KAAK,eAAe;CACzC,MAAM,WAAW,KAAK,KAAK,UAAU;CAErC,IAAI,YAAY,CAAC,SAChB,MAAM,IAAI,MACT,gBAAgB,KAAK,KAAK,8DAC3B;CAGD,MAAM,MAAM,OAAO,SAAS;CAE5B,MAAM,SAAS,OAAO,OAAO,KAAK,GAAG,EAAE,OAAO,QAC7C,mBAAmB;EAClB;EACA;EACA,SAAS,KAAK;EACd;EACA,cAAc,KAAK;EACnB,OAAO,KAAK;EACZ;CACD,CAAC,CACF;CAEA,MAAM,MAAM,IAAI,QAAQ,MAAM,QAC7B,KAAK,MACL;EAAE;EAAQ,UAAU,KAAK;EAAU,aAAa,KAAK;CAAY,GACjE,IACD;CAMA,OAAO;EAAE,SAAS;EAAK,eAJD,IAAI,OAAO,OAC/B,QAAQ,IAAI,KAAK,EAAE,MAAM,IAAI,EAAE,IAAI,KAAK,EAGP;CAAE;AACtC"}
|
package/dist/fly/deploy.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_chunk = require('../chunk-BVYJZCqc.cjs');
|
|
3
|
-
const
|
|
3
|
+
const require_commands_deploy = require('../commands/deploy.cjs');
|
|
4
4
|
const require_fly_toml = require('./toml.cjs');
|
|
5
5
|
let _pulumi_pulumi = require("@pulumi/pulumi");
|
|
6
6
|
_pulumi_pulumi = require_chunk.__toESM(_pulumi_pulumi, 1);
|
|
@@ -26,7 +26,7 @@ var FlyDeploy = class extends _pulumi_pulumi.ComponentResource {
|
|
|
26
26
|
if (Array.isArray(pulumiOpts.dependsOn)) consumerDeps = pulumiOpts.dependsOn;
|
|
27
27
|
else if (pulumiOpts.dependsOn) consumerDeps = [pulumiOpts.dependsOn];
|
|
28
28
|
else consumerDeps = [];
|
|
29
|
-
|
|
29
|
+
require_commands_deploy.createDeployCommand({
|
|
30
30
|
name,
|
|
31
31
|
cli,
|
|
32
32
|
triggers,
|
package/dist/fly/deploy.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.cjs","names":["pulumi","generateFlyToml"],"sources":["../../src/fly/deploy.ts"],"sourcesContent":["// src/fly/deploy.ts (replace entire file)\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { createDeployCommand } from \"../deploy
|
|
1
|
+
{"version":3,"file":"deploy.cjs","names":["pulumi","generateFlyToml"],"sources":["../../src/fly/deploy.ts"],"sourcesContent":["// src/fly/deploy.ts (replace entire file)\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { createDeployCommand } from \"../commands/deploy\";\nimport type { FlyApp } from \"./app\";\nimport type { FlyProvider } from \"./provider\";\nimport { type FlyTomlConfig, generateFlyToml } from \"./toml\";\n\ntype FlyDeployOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\tprovider: FlyProvider;\n\tapp: FlyApp;\n};\n\nexport interface FlyDeployArgs {\n\t/** fly.toml configuration. `config.app` must equal the FlyApp name. */\n\tconfig: FlyTomlConfig;\n\t/** Redeploy triggers; the generated toml content is appended automatically. */\n\ttriggers: pulumi.Input<pulumi.Input<string>[]>;\n\t/** `fly deploy --wait-timeout` seconds (default 300). */\n\twaitTimeout?: number;\n\t/** `fly deploy --release-command-timeout` seconds (default 600). */\n\treleaseCommandTimeout?: number;\n\t/** `fly deploy --ha` (default false). */\n\thighAvailability?: boolean;\n}\n\n/**\n * Deploys a Fly app via `fly deploy --remote-only` from a generated fly.toml.\n * Isolation/git are the seam's job (list a `DeploySandbox`, optionally a `GitGuard`).\n */\nexport class FlyDeploy extends pulumi.ComponentResource {\n\tconstructor(name: string, args: FlyDeployArgs, opts: FlyDeployOptions) {\n\t\tconst { provider, app, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:Deploy\", name, {}, pulumiOpts);\n\n\t\tconst tomlContent = generateFlyToml(args.config);\n\t\tconst configPath = `.fly/${args.config.app}.toml`;\n\n\t\tconst waitTimeout = args.waitTimeout ?? 300;\n\t\tconst releaseCommandTimeout = args.releaseCommandTimeout ?? 600;\n\t\tconst highAvailability = args.highAvailability ?? false;\n\n\t\t// The toml content arrives via FLY_TOML_CONTENT (avoids shell escaping).\n\t\tconst setup = `mkdir -p .fly && printf '%s' \"$FLY_TOML_CONTENT\" > ${configPath}`;\n\t\tconst cli = `fly deploy --config ${configPath} --remote-only --ha=${highAvailability} --wait-timeout ${waitTimeout} --release-command-timeout ${releaseCommandTimeout}`;\n\n\t\tconst triggers = pulumi\n\t\t\t.output(args.triggers)\n\t\t\t.apply((values) => [...values, tomlContent]);\n\n\t\tlet consumerDeps: pulumi.Resource[];\n\n\t\tif (Array.isArray(pulumiOpts.dependsOn)) {\n\t\t\tconsumerDeps = pulumiOpts.dependsOn as pulumi.Resource[];\n\t\t} else if (pulumiOpts.dependsOn) {\n\t\t\tconsumerDeps = [pulumiOpts.dependsOn as pulumi.Resource];\n\t\t} else {\n\t\t\tconsumerDeps = [];\n\t\t}\n\n\t\tcreateDeployCommand(\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tcli,\n\t\t\t\ttriggers,\n\t\t\t\tsetup,\n\t\t\t\tenvironment: {\n\t\t\t\t\tFLY_API_TOKEN: provider.token,\n\t\t\t\t\tFLY_TOML_CONTENT: tomlContent,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ ...pulumiOpts, parent: this, dependsOn: [app, ...consumerDeps] },\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;;;;;;;;AA8BA,IAAa,YAAb,cAA+BA,eAAO,kBAAkB;CACvD,YAAY,MAAc,MAAqB,MAAwB;EACtE,MAAM,EAAE,UAAU,KAAK,GAAG,eAAe;EAEzC,MAAM,yBAAyB,MAAM,CAAC,GAAG,UAAU;EAEnD,MAAM,cAAcC,iCAAgB,KAAK,MAAM;EAC/C,MAAM,aAAa,QAAQ,KAAK,OAAO,IAAI;EAE3C,MAAM,cAAc,KAAK,eAAe;EACxC,MAAM,wBAAwB,KAAK,yBAAyB;EAC5D,MAAM,mBAAmB,KAAK,oBAAoB;EAGlD,MAAM,QAAQ,sDAAsD;EACpE,MAAM,MAAM,uBAAuB,WAAW,sBAAsB,iBAAiB,kBAAkB,YAAY,6BAA6B;EAEhJ,MAAM,WAAWD,eACf,OAAO,KAAK,QAAQ,EACpB,OAAO,WAAW,CAAC,GAAG,QAAQ,WAAW,CAAC;EAE5C,IAAI;EAEJ,IAAI,MAAM,QAAQ,WAAW,SAAS,GACrC,eAAe,WAAW;OACpB,IAAI,WAAW,WACrB,eAAe,CAAC,WAAW,SAA4B;OAEvD,eAAe,CAAC;EAGjB,4CACC;GACC;GACA;GACA;GACA;GACA,aAAa;IACZ,eAAe,SAAS;IACxB,kBAAkB;GACnB;EACD,GACA;GAAE,GAAG;GAAY,QAAQ;GAAM,WAAW,CAAC,KAAK,GAAG,YAAY;EAAE,CAClE;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
|
package/dist/fly/deploy.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __name } from "../chunk-OPjESj5l.mjs";
|
|
2
|
-
import { createDeployCommand } from "../deploy
|
|
2
|
+
import { createDeployCommand } from "../commands/deploy.mjs";
|
|
3
3
|
import { generateFlyToml } from "./toml.mjs";
|
|
4
4
|
import * as pulumi from "@pulumi/pulumi";
|
|
5
5
|
|
package/dist/fly/deploy.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.mjs","names":[],"sources":["../../src/fly/deploy.ts"],"sourcesContent":["// src/fly/deploy.ts (replace entire file)\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { createDeployCommand } from \"../deploy
|
|
1
|
+
{"version":3,"file":"deploy.mjs","names":[],"sources":["../../src/fly/deploy.ts"],"sourcesContent":["// src/fly/deploy.ts (replace entire file)\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { createDeployCommand } from \"../commands/deploy\";\nimport type { FlyApp } from \"./app\";\nimport type { FlyProvider } from \"./provider\";\nimport { type FlyTomlConfig, generateFlyToml } from \"./toml\";\n\ntype FlyDeployOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\tprovider: FlyProvider;\n\tapp: FlyApp;\n};\n\nexport interface FlyDeployArgs {\n\t/** fly.toml configuration. `config.app` must equal the FlyApp name. */\n\tconfig: FlyTomlConfig;\n\t/** Redeploy triggers; the generated toml content is appended automatically. */\n\ttriggers: pulumi.Input<pulumi.Input<string>[]>;\n\t/** `fly deploy --wait-timeout` seconds (default 300). */\n\twaitTimeout?: number;\n\t/** `fly deploy --release-command-timeout` seconds (default 600). */\n\treleaseCommandTimeout?: number;\n\t/** `fly deploy --ha` (default false). */\n\thighAvailability?: boolean;\n}\n\n/**\n * Deploys a Fly app via `fly deploy --remote-only` from a generated fly.toml.\n * Isolation/git are the seam's job (list a `DeploySandbox`, optionally a `GitGuard`).\n */\nexport class FlyDeploy extends pulumi.ComponentResource {\n\tconstructor(name: string, args: FlyDeployArgs, opts: FlyDeployOptions) {\n\t\tconst { provider, app, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:Deploy\", name, {}, pulumiOpts);\n\n\t\tconst tomlContent = generateFlyToml(args.config);\n\t\tconst configPath = `.fly/${args.config.app}.toml`;\n\n\t\tconst waitTimeout = args.waitTimeout ?? 300;\n\t\tconst releaseCommandTimeout = args.releaseCommandTimeout ?? 600;\n\t\tconst highAvailability = args.highAvailability ?? false;\n\n\t\t// The toml content arrives via FLY_TOML_CONTENT (avoids shell escaping).\n\t\tconst setup = `mkdir -p .fly && printf '%s' \"$FLY_TOML_CONTENT\" > ${configPath}`;\n\t\tconst cli = `fly deploy --config ${configPath} --remote-only --ha=${highAvailability} --wait-timeout ${waitTimeout} --release-command-timeout ${releaseCommandTimeout}`;\n\n\t\tconst triggers = pulumi\n\t\t\t.output(args.triggers)\n\t\t\t.apply((values) => [...values, tomlContent]);\n\n\t\tlet consumerDeps: pulumi.Resource[];\n\n\t\tif (Array.isArray(pulumiOpts.dependsOn)) {\n\t\t\tconsumerDeps = pulumiOpts.dependsOn as pulumi.Resource[];\n\t\t} else if (pulumiOpts.dependsOn) {\n\t\t\tconsumerDeps = [pulumiOpts.dependsOn as pulumi.Resource];\n\t\t} else {\n\t\t\tconsumerDeps = [];\n\t\t}\n\n\t\tcreateDeployCommand(\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tcli,\n\t\t\t\ttriggers,\n\t\t\t\tsetup,\n\t\t\t\tenvironment: {\n\t\t\t\t\tFLY_API_TOKEN: provider.token,\n\t\t\t\t\tFLY_TOML_CONTENT: tomlContent,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ ...pulumiOpts, parent: this, dependsOn: [app, ...consumerDeps] },\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;;;;;;AA8BA,IAAa,YAAb,cAA+B,OAAO,kBAAkB;CACvD,YAAY,MAAc,MAAqB,MAAwB;EACtE,MAAM,EAAE,UAAU,KAAK,GAAG,eAAe;EAEzC,MAAM,yBAAyB,MAAM,CAAC,GAAG,UAAU;EAEnD,MAAM,cAAc,gBAAgB,KAAK,MAAM;EAC/C,MAAM,aAAa,QAAQ,KAAK,OAAO,IAAI;EAE3C,MAAM,cAAc,KAAK,eAAe;EACxC,MAAM,wBAAwB,KAAK,yBAAyB;EAC5D,MAAM,mBAAmB,KAAK,oBAAoB;EAGlD,MAAM,QAAQ,sDAAsD;EACpE,MAAM,MAAM,uBAAuB,WAAW,sBAAsB,iBAAiB,kBAAkB,YAAY,6BAA6B;EAEhJ,MAAM,WAAW,OACf,OAAO,KAAK,QAAQ,EACpB,OAAO,WAAW,CAAC,GAAG,QAAQ,WAAW,CAAC;EAE5C,IAAI;EAEJ,IAAI,MAAM,QAAQ,WAAW,SAAS,GACrC,eAAe,WAAW;OACpB,IAAI,WAAW,WACrB,eAAe,CAAC,WAAW,SAA4B;OAEvD,eAAe,CAAC;EAGjB,oBACC;GACC;GACA;GACA;GACA;GACA,aAAa;IACZ,eAAe,SAAS;IACxB,kBAAkB;GACnB;EACD,GACA;GAAE,GAAG;GAAY,QAAQ;GAAM,WAAW,CAAC,KAAK,GAAG,YAAY;EAAE,CAClE;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
|
package/dist/hash.cjs
CHANGED
|
@@ -2,12 +2,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
const require_chunk = require('./chunk-BVYJZCqc.cjs');
|
|
3
3
|
let _pulumi_pulumi = require("@pulumi/pulumi");
|
|
4
4
|
_pulumi_pulumi = require_chunk.__toESM(_pulumi_pulumi, 1);
|
|
5
|
+
let node_crypto = require("node:crypto");
|
|
6
|
+
node_crypto = require_chunk.__toESM(node_crypto, 1);
|
|
5
7
|
let node_fs = require("node:fs");
|
|
6
8
|
node_fs = require_chunk.__toESM(node_fs, 1);
|
|
7
9
|
let node_path = require("node:path");
|
|
8
10
|
node_path = require_chunk.__toESM(node_path, 1);
|
|
9
|
-
let node_crypto = require("node:crypto");
|
|
10
|
-
node_crypto = require_chunk.__toESM(node_crypto, 1);
|
|
11
11
|
|
|
12
12
|
//#region src/hash.ts
|
|
13
13
|
const DEFAULT_IGNORE = new Set([
|
package/dist/hash.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { t as __name } from "./chunk-OPjESj5l.mjs";
|
|
2
2
|
import * as pulumi from "@pulumi/pulumi";
|
|
3
|
+
import * as crypto from "node:crypto";
|
|
3
4
|
import * as fs from "node:fs";
|
|
4
5
|
import * as path from "node:path";
|
|
5
|
-
import * as crypto from "node:crypto";
|
|
6
6
|
|
|
7
7
|
//#region src/hash.ts
|
|
8
8
|
const DEFAULT_IGNORE = new Set([
|
package/dist/railway/deploy.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_chunk = require('../chunk-BVYJZCqc.cjs');
|
|
3
|
-
const
|
|
3
|
+
const require_commands_deploy = require('../commands/deploy.cjs');
|
|
4
4
|
let _pulumi_pulumi = require("@pulumi/pulumi");
|
|
5
5
|
_pulumi_pulumi = require_chunk.__toESM(_pulumi_pulumi, 1);
|
|
6
6
|
|
|
@@ -28,7 +28,7 @@ var RailwayDeploy = class extends _pulumi_pulumi.ComponentResource {
|
|
|
28
28
|
super("infracraft:railway:Deploy", name, {}, pulumiOpts);
|
|
29
29
|
const cli = _pulumi_pulumi.interpolate`RAILWAY_TOKEN=${projectToken} railway up --ci --project ${project.id} --service ${service.id} --environment ${environment.id}; EXIT=$?; if [ "$EXIT" -ne 0 ]; then exit "$EXIT"; fi; if [ -n "$INFRACRAFT_SKIP_DEPLOY_WAIT" ]; then exit 0; fi; IC_TOK=${projectToken} IC_PROJ=${project.id} IC_ENV=${environment.id} IC_SVC=${service.id} node -e '${DEPLOY_WAIT_SCRIPT}'`;
|
|
30
30
|
const setup = args.railpackConfig ? `printf '${JSON.stringify(args.railpackConfig).replace(/'/g, "\\'")}' > railpack.json` : void 0;
|
|
31
|
-
|
|
31
|
+
require_commands_deploy.createDeployCommand({
|
|
32
32
|
name,
|
|
33
33
|
cli,
|
|
34
34
|
triggers: args.triggers,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.cjs","names":["pulumi"],"sources":["../../src/railway/deploy.ts"],"sourcesContent":["// src/railway/deploy.ts (replace entire file)\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { createDeployCommand } from \"../deploy
|
|
1
|
+
{"version":3,"file":"deploy.cjs","names":["pulumi"],"sources":["../../src/railway/deploy.ts"],"sourcesContent":["// src/railway/deploy.ts (replace entire file)\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { createDeployCommand } from \"../commands/deploy\";\nimport type { RailwayEnvironment } from \"./environment\";\nimport type { RailwayProject } from \"./project\";\nimport type { RailwayProvider } from \"./provider\";\nimport { RailwayBuilder, type RailwayService } from \"./service\";\n\nexport interface RailwayDeployConfig {\n\tbuilder?: RailwayBuilder;\n\tstartCommand?: string;\n\tpreDeployCommand?: string;\n}\n\nexport interface RailwayDeployArgs {\n\t/** Redeploy triggers (e.g. source hashes, env hashes). */\n\ttriggers: pulumi.Input<pulumi.Input<string>[]>;\n\t/** Paths excluded from the upload when running with `DeploySandbox` + `GitGuard`. */\n\texcludePaths?: string[];\n\t/** Railpack configuration written to `railpack.json` before deploy. */\n\trailpackConfig?: Record<string, unknown>;\n}\n\ntype RailwayDeployOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\tprovider: RailwayProvider;\n\tproject: RailwayProject;\n\tenvironment: RailwayEnvironment;\n\tservice: RailwayService;\n\t/** Environment-scoped Railway deploy token (provision via RailwayProjectToken). */\n\tprojectToken: pulumi.Input<string>;\n};\n\n/**\n * The deploy-wait poller. `railway up --ci` only blocks until upload; this polls\n * the Railway GraphQL API to a terminal status and fails the resource on\n * FAILED/CRASHED/REMOVED. Runs under `node -e`, single-quoted in the shell, so it\n * uses ONLY double quotes and reads inputs from IC_* env vars.\n */\nconst DEPLOY_WAIT_SCRIPT = `const t=process.env.IC_TOK,p=process.env.IC_PROJ,e=process.env.IC_ENV,s=process.env.IC_SVC;const u=\"https://backboard.railway.app/graphql/v2\";const q=(query,variables)=>fetch(u,{method:\"POST\",headers:{\"Project-Access-Token\":t,\"Content-Type\":\"application/json\"},body:JSON.stringify({query,variables})}).then(r=>r.json()).catch(()=>({}));const sl=ms=>new Promise(r=>setTimeout(r,ms));(async()=>{let id;for(let i=0;i<6&&!id;i++){const d=await q(\"query($p:String!,$e:String!,$s:String!){deployments(first:1,input:{projectId:$p,environmentId:$e,serviceId:$s}){edges{node{id status}}}}\",{p,e,s});const g=d&&d.data&&d.data.deployments&&d.data.deployments.edges;if(g&&g[0])id=g[0].node.id;if(!id)await sl(5000);}if(!id){console.error(\"[infracraft] could not resolve Railway deployment id; build succeeded, not blocking\");process.exit(0);}for(let i=0;i<120;i++){const r=await q(\"query($d:String!){deployment(id:$d){status}}\",{d:id});const st=r&&r.data&&r.data.deployment&&r.data.deployment.status;if(st)console.error(\"[infracraft] railway deployment \"+id+\" status=\"+st);if(st===\"SUCCESS\")process.exit(0);if(st===\"FAILED\"||st===\"CRASHED\"||st===\"REMOVED\"){const l=await q(\"query($d:String!){deploymentLogs(deploymentId:$d,limit:60){message}}\",{d:id});const lg=(l&&l.data&&l.data.deploymentLogs)||[];for(const x of lg)console.error(\" \"+(x.message||\"\"));console.error(\"[infracraft] railway deployment \"+id+\" \"+st+\" — failing the Pulumi resource\");process.exit(1);}await sl(10000);}console.error(\"[infracraft] timed out waiting for Railway deployment \"+id);process.exit(1);})();`;\n\n/**\n * Deploys a Railway service and waits for a terminal status. Isolation/git are the\n * seam's job (list a `DeploySandbox` and optionally a `GitGuard` in `dependsOn`).\n *\n * @example\n * ```typescript\n * new RailwayDeploy(\"mesh\", { triggers: [sourceHash], railpackConfig: { apt: [\"libatomic1\"] } },\n * { provider, project, environment, service, projectToken: token.token, dependsOn: [sandbox, gitGuard] });\n * ```\n */\nexport class RailwayDeploy extends pulumi.ComponentResource {\n\tconstructor(\n\t\tname: string,\n\t\targs: RailwayDeployArgs,\n\t\topts: RailwayDeployOptions,\n\t) {\n\t\tconst {\n\t\t\tprovider,\n\t\t\tproject,\n\t\t\tenvironment,\n\t\t\tservice,\n\t\t\tprojectToken,\n\t\t\t...pulumiOpts\n\t\t} = opts;\n\n\t\tsuper(\"infracraft:railway:Deploy\", name, {}, pulumiOpts);\n\n\t\t// Token is inlined (not via the env map): it is an unknown secret at preview,\n\t\t// and an unknown secret in `environment` makes `pulumi preview` fail.\n\t\tconst cli = pulumi.interpolate`RAILWAY_TOKEN=${projectToken} railway up --ci --project ${project.id} --service ${service.id} --environment ${environment.id}; EXIT=$?; if [ \"$EXIT\" -ne 0 ]; then exit \"$EXIT\"; fi; if [ -n \"$INFRACRAFT_SKIP_DEPLOY_WAIT\" ]; then exit 0; fi; IC_TOK=${projectToken} IC_PROJ=${project.id} IC_ENV=${environment.id} IC_SVC=${service.id} node -e '${DEPLOY_WAIT_SCRIPT}'`;\n\n\t\tconst setup = args.railpackConfig\n\t\t\t? `printf '${JSON.stringify(args.railpackConfig).replace(/'/g, \"\\\\'\")}' > railpack.json`\n\t\t\t: undefined;\n\n\t\tcreateDeployCommand(\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tcli,\n\t\t\t\ttriggers: args.triggers,\n\t\t\t\texcludePaths: args.excludePaths,\n\t\t\t\tsetup,\n\t\t\t},\n\t\t\t{ parent: this, ...pulumiOpts },\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;AA0CA,MAAM,qBAAqB;;;;;;;;;;;AAY3B,IAAa,gBAAb,cAAmCA,eAAO,kBAAkB;CAC3D,YACC,MACA,MACA,MACC;EACD,MAAM,EACL,UACA,SACA,aACA,SACA,cACA,GAAG,eACA;EAEJ,MAAM,6BAA6B,MAAM,CAAC,GAAG,UAAU;EAIvD,MAAM,MAAM,eAAO,WAAW,iBAAiB,aAAa,6BAA6B,QAAQ,GAAG,aAAa,QAAQ,GAAG,iBAAiB,YAAY,GAAG,4HAA4H,aAAa,WAAW,QAAQ,GAAG,UAAU,YAAY,GAAG,UAAU,QAAQ,GAAG,YAAY,mBAAmB;EAExY,MAAM,QAAQ,KAAK,iBAChB,WAAW,KAAK,UAAU,KAAK,cAAc,EAAE,QAAQ,MAAM,KAAK,EAAE,qBACpE;EAEH,4CACC;GACC;GACA;GACA,UAAU,KAAK;GACf,cAAc,KAAK;GACnB;EACD,GACA;GAAE,QAAQ;GAAM,GAAG;EAAW,CAC/B;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
|
package/dist/railway/deploy.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.mjs","names":[],"sources":["../../src/railway/deploy.ts"],"sourcesContent":["// src/railway/deploy.ts (replace entire file)\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { createDeployCommand } from \"../deploy
|
|
1
|
+
{"version":3,"file":"deploy.mjs","names":[],"sources":["../../src/railway/deploy.ts"],"sourcesContent":["// src/railway/deploy.ts (replace entire file)\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { createDeployCommand } from \"../commands/deploy\";\nimport type { RailwayEnvironment } from \"./environment\";\nimport type { RailwayProject } from \"./project\";\nimport type { RailwayProvider } from \"./provider\";\nimport { RailwayBuilder, type RailwayService } from \"./service\";\n\nexport interface RailwayDeployConfig {\n\tbuilder?: RailwayBuilder;\n\tstartCommand?: string;\n\tpreDeployCommand?: string;\n}\n\nexport interface RailwayDeployArgs {\n\t/** Redeploy triggers (e.g. source hashes, env hashes). */\n\ttriggers: pulumi.Input<pulumi.Input<string>[]>;\n\t/** Paths excluded from the upload when running with `DeploySandbox` + `GitGuard`. */\n\texcludePaths?: string[];\n\t/** Railpack configuration written to `railpack.json` before deploy. */\n\trailpackConfig?: Record<string, unknown>;\n}\n\ntype RailwayDeployOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\tprovider: RailwayProvider;\n\tproject: RailwayProject;\n\tenvironment: RailwayEnvironment;\n\tservice: RailwayService;\n\t/** Environment-scoped Railway deploy token (provision via RailwayProjectToken). */\n\tprojectToken: pulumi.Input<string>;\n};\n\n/**\n * The deploy-wait poller. `railway up --ci` only blocks until upload; this polls\n * the Railway GraphQL API to a terminal status and fails the resource on\n * FAILED/CRASHED/REMOVED. Runs under `node -e`, single-quoted in the shell, so it\n * uses ONLY double quotes and reads inputs from IC_* env vars.\n */\nconst DEPLOY_WAIT_SCRIPT = `const t=process.env.IC_TOK,p=process.env.IC_PROJ,e=process.env.IC_ENV,s=process.env.IC_SVC;const u=\"https://backboard.railway.app/graphql/v2\";const q=(query,variables)=>fetch(u,{method:\"POST\",headers:{\"Project-Access-Token\":t,\"Content-Type\":\"application/json\"},body:JSON.stringify({query,variables})}).then(r=>r.json()).catch(()=>({}));const sl=ms=>new Promise(r=>setTimeout(r,ms));(async()=>{let id;for(let i=0;i<6&&!id;i++){const d=await q(\"query($p:String!,$e:String!,$s:String!){deployments(first:1,input:{projectId:$p,environmentId:$e,serviceId:$s}){edges{node{id status}}}}\",{p,e,s});const g=d&&d.data&&d.data.deployments&&d.data.deployments.edges;if(g&&g[0])id=g[0].node.id;if(!id)await sl(5000);}if(!id){console.error(\"[infracraft] could not resolve Railway deployment id; build succeeded, not blocking\");process.exit(0);}for(let i=0;i<120;i++){const r=await q(\"query($d:String!){deployment(id:$d){status}}\",{d:id});const st=r&&r.data&&r.data.deployment&&r.data.deployment.status;if(st)console.error(\"[infracraft] railway deployment \"+id+\" status=\"+st);if(st===\"SUCCESS\")process.exit(0);if(st===\"FAILED\"||st===\"CRASHED\"||st===\"REMOVED\"){const l=await q(\"query($d:String!){deploymentLogs(deploymentId:$d,limit:60){message}}\",{d:id});const lg=(l&&l.data&&l.data.deploymentLogs)||[];for(const x of lg)console.error(\" \"+(x.message||\"\"));console.error(\"[infracraft] railway deployment \"+id+\" \"+st+\" — failing the Pulumi resource\");process.exit(1);}await sl(10000);}console.error(\"[infracraft] timed out waiting for Railway deployment \"+id);process.exit(1);})();`;\n\n/**\n * Deploys a Railway service and waits for a terminal status. Isolation/git are the\n * seam's job (list a `DeploySandbox` and optionally a `GitGuard` in `dependsOn`).\n *\n * @example\n * ```typescript\n * new RailwayDeploy(\"mesh\", { triggers: [sourceHash], railpackConfig: { apt: [\"libatomic1\"] } },\n * { provider, project, environment, service, projectToken: token.token, dependsOn: [sandbox, gitGuard] });\n * ```\n */\nexport class RailwayDeploy extends pulumi.ComponentResource {\n\tconstructor(\n\t\tname: string,\n\t\targs: RailwayDeployArgs,\n\t\topts: RailwayDeployOptions,\n\t) {\n\t\tconst {\n\t\t\tprovider,\n\t\t\tproject,\n\t\t\tenvironment,\n\t\t\tservice,\n\t\t\tprojectToken,\n\t\t\t...pulumiOpts\n\t\t} = opts;\n\n\t\tsuper(\"infracraft:railway:Deploy\", name, {}, pulumiOpts);\n\n\t\t// Token is inlined (not via the env map): it is an unknown secret at preview,\n\t\t// and an unknown secret in `environment` makes `pulumi preview` fail.\n\t\tconst cli = pulumi.interpolate`RAILWAY_TOKEN=${projectToken} railway up --ci --project ${project.id} --service ${service.id} --environment ${environment.id}; EXIT=$?; if [ \"$EXIT\" -ne 0 ]; then exit \"$EXIT\"; fi; if [ -n \"$INFRACRAFT_SKIP_DEPLOY_WAIT\" ]; then exit 0; fi; IC_TOK=${projectToken} IC_PROJ=${project.id} IC_ENV=${environment.id} IC_SVC=${service.id} node -e '${DEPLOY_WAIT_SCRIPT}'`;\n\n\t\tconst setup = args.railpackConfig\n\t\t\t? `printf '${JSON.stringify(args.railpackConfig).replace(/'/g, \"\\\\'\")}' > railpack.json`\n\t\t\t: undefined;\n\n\t\tcreateDeployCommand(\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tcli,\n\t\t\t\ttriggers: args.triggers,\n\t\t\t\texcludePaths: args.excludePaths,\n\t\t\t\tsetup,\n\t\t\t},\n\t\t\t{ parent: this, ...pulumiOpts },\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;;;;;;;AA0CA,MAAM,qBAAqB;;;;;;;;;;;AAY3B,IAAa,gBAAb,cAAmC,OAAO,kBAAkB;CAC3D,YACC,MACA,MACA,MACC;EACD,MAAM,EACL,UACA,SACA,aACA,SACA,cACA,GAAG,eACA;EAEJ,MAAM,6BAA6B,MAAM,CAAC,GAAG,UAAU;EAIvD,MAAM,MAAM,OAAO,WAAW,iBAAiB,aAAa,6BAA6B,QAAQ,GAAG,aAAa,QAAQ,GAAG,iBAAiB,YAAY,GAAG,4HAA4H,aAAa,WAAW,QAAQ,GAAG,UAAU,YAAY,GAAG,UAAU,QAAQ,GAAG,YAAY,mBAAmB;EAExY,MAAM,QAAQ,KAAK,iBAChB,WAAW,KAAK,UAAU,KAAK,cAAc,EAAE,QAAQ,MAAM,KAAK,EAAE,qBACpE;EAEH,oBACC;GACC;GACA;GACA,UAAU,KAAK;GACf,cAAc,KAAK;GACnB;EACD,GACA;GAAE,QAAQ;GAAM,GAAG;EAAW,CAC/B;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
|
package/dist/sandbox.cjs
CHANGED
|
@@ -38,7 +38,13 @@ function buildSandboxScript(options) {
|
|
|
38
38
|
const head = `REPO=$(git rev-parse --show-toplevel)`;
|
|
39
39
|
const runSetupAndCli = [setup, cli].filter(Boolean).join("; ");
|
|
40
40
|
if (!sandbox) return `${head}; cd "$REPO"; ${runSetupAndCli}`;
|
|
41
|
-
const
|
|
41
|
+
const dirPrefix = env ? `${env}-${appName}` : appName;
|
|
42
|
+
const makeSandbox = [
|
|
43
|
+
`PROJECT_DIR="${SANDBOX_ROOT}/$(basename "$REPO")"`,
|
|
44
|
+
`mkdir -p "$PROJECT_DIR"`,
|
|
45
|
+
`SANDBOX=$(mktemp -d "$PROJECT_DIR/${dirPrefix}.XXXXXX")`,
|
|
46
|
+
`trap 'rm -rf "$SANDBOX"; rmdir "$PROJECT_DIR" 2>/dev/null || true' EXIT`
|
|
47
|
+
].join("; ");
|
|
42
48
|
if (gitGuard) return `${head}; ${makeSandbox}; ${`git -C "$REPO" ls-files | ${buildSandboxFileFilter(excludePaths)} | rsync -a --files-from=- "$REPO"/ "$SANDBOX"/`}; cd "\$SANDBOX" && git init -q && git add -A; ${runSetupAndCli}`;
|
|
43
49
|
return `${head}; ${makeSandbox}; git -C "\$REPO" ls-files | rsync -a --files-from=- "\$REPO"/ "\$SANDBOX"/; cp -c -R "\$REPO/.git" "\$SANDBOX/.git" 2>/dev/null || cp -R "\$REPO/.git" "\$SANDBOX/.git"; cd "$SANDBOX"; ${runSetupAndCli}`;
|
|
44
50
|
}
|
|
@@ -59,23 +65,40 @@ var DeploySandbox = class extends _pulumi_pulumi.ComponentResource {
|
|
|
59
65
|
if (!_pulumi_pulumi.runtime.isDryRun()) this.prepareWorkspace();
|
|
60
66
|
this.registerOutputs({});
|
|
61
67
|
}
|
|
62
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* mkdir the workspace root and GC stale sandboxes (best-effort). Sandboxes are
|
|
70
|
+
* nested one level under a per-project dir (`/tmp/infracraft/<project>/<sandbox>`),
|
|
71
|
+
* so this sweeps individual stale sandboxes and then drops any now-empty project
|
|
72
|
+
* dir (`rmdir` is a no-op on a project dir with live deploys).
|
|
73
|
+
*/
|
|
63
74
|
prepareWorkspace() {
|
|
64
75
|
node_fs.mkdirSync(SANDBOX_ROOT, { recursive: true });
|
|
65
|
-
|
|
76
|
+
const now = Date.now();
|
|
77
|
+
let projects = [];
|
|
66
78
|
try {
|
|
67
|
-
|
|
79
|
+
projects = node_fs.readdirSync(SANDBOX_ROOT);
|
|
68
80
|
} catch {
|
|
69
81
|
return;
|
|
70
82
|
}
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
83
|
+
for (const project of projects) {
|
|
84
|
+
const projectDir = node_path.join(SANDBOX_ROOT, project);
|
|
85
|
+
let sandboxes = [];
|
|
86
|
+
try {
|
|
87
|
+
sandboxes = node_fs.readdirSync(projectDir);
|
|
88
|
+
} catch {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
for (const sandbox of sandboxes) {
|
|
92
|
+
const full = node_path.join(projectDir, sandbox);
|
|
93
|
+
try {
|
|
94
|
+
if (now - node_fs.statSync(full).mtimeMs > STALE_SANDBOX_MS) node_fs.rmSync(full, {
|
|
95
|
+
recursive: true,
|
|
96
|
+
force: true
|
|
97
|
+
});
|
|
98
|
+
} catch {}
|
|
99
|
+
}
|
|
74
100
|
try {
|
|
75
|
-
|
|
76
|
-
recursive: true,
|
|
77
|
-
force: true
|
|
78
|
-
});
|
|
101
|
+
node_fs.rmdirSync(projectDir);
|
|
79
102
|
} catch {}
|
|
80
103
|
}
|
|
81
104
|
}
|
package/dist/sandbox.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.cjs","names":["pulumi","fs","path"],"sources":["../src/sandbox.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as pulumi from \"@pulumi/pulumi\";\n\n/** Escapes a path literal for embedding inside an awk ERE. */\nfunction escapeAwkRegex(path: string): string {\n\treturn path.replace(/[.[\\]{}()*+?^$|\\\\/]/g, \"\\\\$&\");\n}\n\n/**\n * Builds the shell filter applied to newline-delimited `git ls-files` output\n * before `rsync --files-from`. For `apps/<x>` it drops the app's files but keeps\n * `apps/<x>/package.json` (the monorepo workspace graph needs it during build);\n * any other entry drops the path and its subtree. Returns `cat` (passthrough)\n * when nothing is excluded. Uses awk so it is portable across macOS and Linux.\n */\nexport function buildSandboxFileFilter(excludePaths: string[] = []): string {\n\tif (excludePaths.length === 0) {\n\t\treturn \"cat\";\n\t}\n\n\tconst clauses = excludePaths.map((entry) => {\n\t\tconst escaped = escapeAwkRegex(entry);\n\n\t\tif (entry.startsWith(\"apps/\")) {\n\t\t\treturn `!(/^${escaped}\\\\// && !/^${escaped}\\\\/package\\\\.json$/)`;\n\t\t}\n\n\t\treturn `!/^${escaped}(\\\\/|$)/`;\n\t});\n\n\treturn `awk '${clauses.join(\" && \")}'`;\n}\n\n/** Root of the per-deploy sandbox tree. The DeploySandbox resource GCs this. */\nconst SANDBOX_ROOT = \"/tmp/infracraft\";\n\ninterface SandboxScriptOptions {\n\t/** Whether to isolate into a /tmp copy (false → run in the live tree). */\n\tsandbox: boolean;\n\t/** Whether the sandbox `.git` is a metadata-free stub (true) or the real one. */\n\tgitGuard: boolean;\n\t/** Resource-derived name, used in the sandbox dir prefix. */\n\tappName: string;\n\t/** Stack/environment name, prefixed to the sandbox dir so leftovers and\n\t * concurrent deploys are identifiable (e.g. `staging-vercel-deploy-nexus.XXXX`). */\n\tenv?: string;\n\t/** Upload-scoping excludes; applied only in stub mode (see design spec). */\n\texcludePaths?: string[];\n\t/** Shell run in the working dir before `cli` (e.g. write railpack.json). */\n\tsetup?: string;\n\t/** Fully-formed platform deploy command (its exit code becomes the script's). */\n\tcli: string;\n}\n\n/**\n * Builds the shell for a deploy's `command.local.Command.create`. See\n * docs/superpowers/specs/2026-06-05-deploy-sandbox-design.md for the modes.\n */\nexport function buildSandboxScript(options: SandboxScriptOptions): string {\n\tconst { sandbox, gitGuard, appName, env, excludePaths, setup, cli } = options;\n\n\tconst head = `REPO=$(git rev-parse --show-toplevel)`;\n\tconst runSetupAndCli = [setup, cli].filter(Boolean).join(\"; \");\n\n\tif (!sandbox) {\n\t\treturn `${head}; cd \"$REPO\"; ${runSetupAndCli}`;\n\t}\n\n\t// Prefix the dir with the env so leftovers/concurrent deploys are identifiable.\n\tconst dirPrefix = env ? `${env}-${appName}` : appName;\n\n\tconst makeSandbox = [\n\t\t`SANDBOX=$(mktemp -d $
|
|
1
|
+
{"version":3,"file":"sandbox.cjs","names":["pulumi","fs","path"],"sources":["../src/sandbox.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as pulumi from \"@pulumi/pulumi\";\n\n/** Escapes a path literal for embedding inside an awk ERE. */\nfunction escapeAwkRegex(path: string): string {\n\treturn path.replace(/[.[\\]{}()*+?^$|\\\\/]/g, \"\\\\$&\");\n}\n\n/**\n * Builds the shell filter applied to newline-delimited `git ls-files` output\n * before `rsync --files-from`. For `apps/<x>` it drops the app's files but keeps\n * `apps/<x>/package.json` (the monorepo workspace graph needs it during build);\n * any other entry drops the path and its subtree. Returns `cat` (passthrough)\n * when nothing is excluded. Uses awk so it is portable across macOS and Linux.\n */\nexport function buildSandboxFileFilter(excludePaths: string[] = []): string {\n\tif (excludePaths.length === 0) {\n\t\treturn \"cat\";\n\t}\n\n\tconst clauses = excludePaths.map((entry) => {\n\t\tconst escaped = escapeAwkRegex(entry);\n\n\t\tif (entry.startsWith(\"apps/\")) {\n\t\t\treturn `!(/^${escaped}\\\\// && !/^${escaped}\\\\/package\\\\.json$/)`;\n\t\t}\n\n\t\treturn `!/^${escaped}(\\\\/|$)/`;\n\t});\n\n\treturn `awk '${clauses.join(\" && \")}'`;\n}\n\n/** Root of the per-deploy sandbox tree. The DeploySandbox resource GCs this. */\nconst SANDBOX_ROOT = \"/tmp/infracraft\";\n\ninterface SandboxScriptOptions {\n\t/** Whether to isolate into a /tmp copy (false → run in the live tree). */\n\tsandbox: boolean;\n\t/** Whether the sandbox `.git` is a metadata-free stub (true) or the real one. */\n\tgitGuard: boolean;\n\t/** Resource-derived name, used in the sandbox dir prefix. */\n\tappName: string;\n\t/** Stack/environment name, prefixed to the sandbox dir so leftovers and\n\t * concurrent deploys are identifiable (e.g. `staging-vercel-deploy-nexus.XXXX`). */\n\tenv?: string;\n\t/** Upload-scoping excludes; applied only in stub mode (see design spec). */\n\texcludePaths?: string[];\n\t/** Shell run in the working dir before `cli` (e.g. write railpack.json). */\n\tsetup?: string;\n\t/** Fully-formed platform deploy command (its exit code becomes the script's). */\n\tcli: string;\n}\n\n/**\n * Builds the shell for a deploy's `command.local.Command.create`. See\n * docs/superpowers/specs/2026-06-05-deploy-sandbox-design.md for the modes.\n */\nexport function buildSandboxScript(options: SandboxScriptOptions): string {\n\tconst { sandbox, gitGuard, appName, env, excludePaths, setup, cli } = options;\n\n\tconst head = `REPO=$(git rev-parse --show-toplevel)`;\n\tconst runSetupAndCli = [setup, cli].filter(Boolean).join(\"; \");\n\n\tif (!sandbox) {\n\t\treturn `${head}; cd \"$REPO\"; ${runSetupAndCli}`;\n\t}\n\n\t// Prefix the dir with the env so leftovers/concurrent deploys are identifiable.\n\tconst dirPrefix = env ? `${env}-${appName}` : appName;\n\n\t// Group a repo's sandboxes under a per-project dir (named after the repo\n\t// folder) so concurrent deploys of different repos never mix. The project dir\n\t// is removed only once empty — `rmdir` fails on a non-empty dir, so it\n\t// survives until the project's last deploy has cleaned up its own sandbox.\n\tconst makeSandbox = [\n\t\t`PROJECT_DIR=\"${SANDBOX_ROOT}/$(basename \"$REPO\")\"`,\n\t\t`mkdir -p \"$PROJECT_DIR\"`,\n\t\t`SANDBOX=$(mktemp -d \"$PROJECT_DIR/${dirPrefix}.XXXXXX\")`,\n\t\t`trap 'rm -rf \"$SANDBOX\"; rmdir \"$PROJECT_DIR\" 2>/dev/null || true' EXIT`,\n\t].join(\"; \");\n\n\tif (gitGuard) {\n\t\tconst filter = buildSandboxFileFilter(excludePaths);\n\n\t\tconst copy =\n\t\t\t`git -C \"$REPO\" ls-files | ${filter} | ` +\n\t\t\t`rsync -a --files-from=- \"$REPO\"/ \"$SANDBOX\"/`;\n\n\t\tconst stubGit = `cd \"$SANDBOX\" && git init -q && git add -A`;\n\n\t\treturn `${head}; ${makeSandbox}; ${copy}; ${stubGit}; ${runSetupAndCli}`;\n\t}\n\n\t// Original `.git`, full clean tree (no filter, no reconciliation needed).\n\tconst copy = `git -C \"$REPO\" ls-files | rsync -a --files-from=- \"$REPO\"/ \"$SANDBOX\"/`;\n\n\tconst copyGit =\n\t\t`cp -c -R \"$REPO/.git\" \"$SANDBOX/.git\" 2>/dev/null || ` +\n\t\t`cp -R \"$REPO/.git\" \"$SANDBOX/.git\"`;\n\n\treturn `${head}; ${makeSandbox}; ${copy}; ${copyGit}; cd \"$SANDBOX\"; ${runSetupAndCli}`;\n}\n\n/** Cross-bundle brand: `instanceof` is unreliable when the seam and the resource\n * come from different built entries, so the seam detects sandboxes by this. */\nconst DEPLOY_SANDBOX_BRAND = Symbol.for(\"@infracraft/pulumi/DeploySandbox\");\n\n/** Sweep sandboxes orphaned by a hard-killed run (older than this). */\nconst STALE_SANDBOX_MS = 24 * 60 * 60 * 1000;\n\n/**\n * Isolation marker + workspace lifecycle. Listing it in a deploy's `dependsOn`\n * makes that deploy run in an isolated `/tmp/infracraft` copy. Carries no config;\n * the repo root is derived at runtime by the deploy command.\n */\nexport class DeploySandbox extends pulumi.ComponentResource {\n\tconstructor(name: string, opts?: pulumi.ComponentResourceOptions) {\n\t\tsuper(\"infracraft:sandbox:DeploySandbox\", name, {}, opts);\n\n\t\t(this as Record<symbol, unknown>)[DEPLOY_SANDBOX_BRAND] = true;\n\n\t\tif (!pulumi.runtime.isDryRun()) {\n\t\t\tthis.prepareWorkspace();\n\t\t}\n\n\t\tthis.registerOutputs({});\n\t}\n\n\t/**\n\t * mkdir the workspace root and GC stale sandboxes (best-effort). Sandboxes are\n\t * nested one level under a per-project dir (`/tmp/infracraft/<project>/<sandbox>`),\n\t * so this sweeps individual stale sandboxes and then drops any now-empty project\n\t * dir (`rmdir` is a no-op on a project dir with live deploys).\n\t */\n\tprivate prepareWorkspace(): void {\n\t\tfs.mkdirSync(SANDBOX_ROOT, { recursive: true });\n\n\t\tconst now = Date.now();\n\n\t\tlet projects: string[] = [];\n\n\t\ttry {\n\t\t\tprojects = fs.readdirSync(SANDBOX_ROOT) as string[];\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const project of projects) {\n\t\t\tconst projectDir = path.join(SANDBOX_ROOT, project);\n\n\t\t\tlet sandboxes: string[] = [];\n\n\t\t\ttry {\n\t\t\t\tsandboxes = fs.readdirSync(projectDir) as string[];\n\t\t\t} catch {\n\t\t\t\t// Not a directory (e.g. a stray file) — skip.\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tfor (const sandbox of sandboxes) {\n\t\t\t\tconst full = path.join(projectDir, sandbox);\n\n\t\t\t\ttry {\n\t\t\t\t\tif (now - fs.statSync(full).mtimeMs > STALE_SANDBOX_MS) {\n\t\t\t\t\t\tfs.rmSync(full, { recursive: true, force: true });\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Racing with an in-flight deploy's cleanup — ignore.\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Drop the project dir only if the sweep left it empty (best-effort).\n\t\t\ttry {\n\t\t\t\tfs.rmdirSync(projectDir);\n\t\t\t} catch {\n\t\t\t\t// Non-empty (live deploys) or already gone — ignore.\n\t\t\t}\n\t\t}\n\t}\n}\n\n/** Bundle-safe check for a `DeploySandbox` in a `dependsOn` array. */\nexport function isDeploySandbox(value: unknown): value is DeploySandbox {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t(value as Record<symbol, unknown>)[DEPLOY_SANDBOX_BRAND] === true\n\t);\n}\n"],"mappings":";;;;;;;;;;;AAKA,SAAS,eAAe,MAAsB;CAC7C,OAAO,KAAK,QAAQ,wBAAwB,MAAM;AACnD;;;;;;;;AASA,SAAgB,uBAAuB,eAAyB,CAAC,GAAW;CAC3E,IAAI,aAAa,WAAW,GAC3B,OAAO;CAaR,OAAO,QAVS,aAAa,KAAK,UAAU;EAC3C,MAAM,UAAU,eAAe,KAAK;EAEpC,IAAI,MAAM,WAAW,OAAO,GAC3B,OAAO,OAAO,QAAQ,aAAa,QAAQ;EAG5C,OAAO,MAAM,QAAQ;CACtB,CAEqB,EAAE,KAAK,MAAM,EAAE;AACrC;;AAGA,MAAM,eAAe;;;;;AAwBrB,SAAgB,mBAAmB,SAAuC;CACzE,MAAM,EAAE,SAAS,UAAU,SAAS,KAAK,cAAc,OAAO,QAAQ;CAEtE,MAAM,OAAO;CACb,MAAM,iBAAiB,CAAC,OAAO,GAAG,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;CAE7D,IAAI,CAAC,SACJ,OAAO,GAAG,KAAK,gBAAgB;CAIhC,MAAM,YAAY,MAAM,GAAG,IAAI,GAAG,YAAY;CAM9C,MAAM,cAAc;EACnB,gBAAgB,aAAa;EAC7B;EACA,qCAAqC,UAAU;EAC/C;CACD,EAAE,KAAK,IAAI;CAEX,IAAI,UASH,OAAO,GAAG,KAAK,IAAI,YAAY,IAAI,6BARpB,uBAAuB,YAGH,EAAE,iDAKG,iDAAgB;CAUzD,OAAO,GAAG,KAAK,IAAI,YAAY,2LAAwC;AACxE;;;AAIA,MAAM,uBAAuB,OAAO,IAAI,kCAAkC;;AAG1E,MAAM,mBAAmB,OAAU,KAAK;;;;;;AAOxC,IAAa,gBAAb,cAAmCA,eAAO,kBAAkB;CAC3D,YAAY,MAAc,MAAwC;EACjE,MAAM,oCAAoC,MAAM,CAAC,GAAG,IAAI;EAExD,AAAC,KAAiC,wBAAwB;EAE1D,IAAI,CAACA,eAAO,QAAQ,SAAS,GAC5B,KAAK,iBAAiB;EAGvB,KAAK,gBAAgB,CAAC,CAAC;CACxB;;;;;;;CAQA,AAAQ,mBAAyB;EAChC,QAAG,UAAU,cAAc,EAAE,WAAW,KAAK,CAAC;EAE9C,MAAM,MAAM,KAAK,IAAI;EAErB,IAAI,WAAqB,CAAC;EAE1B,IAAI;GACH,WAAWC,QAAG,YAAY,YAAY;EACvC,QAAQ;GACP;EACD;EAEA,KAAK,MAAM,WAAW,UAAU;GAC/B,MAAM,aAAaC,UAAK,KAAK,cAAc,OAAO;GAElD,IAAI,YAAsB,CAAC;GAE3B,IAAI;IACH,YAAYD,QAAG,YAAY,UAAU;GACtC,QAAQ;IAEP;GACD;GAEA,KAAK,MAAM,WAAW,WAAW;IAChC,MAAM,OAAOC,UAAK,KAAK,YAAY,OAAO;IAE1C,IAAI;KACH,IAAI,MAAMD,QAAG,SAAS,IAAI,EAAE,UAAU,kBACrC,QAAG,OAAO,MAAM;MAAE,WAAW;MAAM,OAAO;KAAK,CAAC;IAElD,QAAQ,CAER;GACD;GAGA,IAAI;IACH,QAAG,UAAU,UAAU;GACxB,QAAQ,CAER;EACD;CACD;AACD;;AAGA,SAAgB,gBAAgB,OAAwC;CACvE,OACC,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,0BAA0B;AAE/D"}
|
package/dist/sandbox.d.cts
CHANGED
|
@@ -39,7 +39,12 @@ declare function buildSandboxScript(options: SandboxScriptOptions): string;
|
|
|
39
39
|
*/
|
|
40
40
|
declare class DeploySandbox extends pulumi.ComponentResource {
|
|
41
41
|
constructor(name: string, opts?: pulumi.ComponentResourceOptions);
|
|
42
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* mkdir the workspace root and GC stale sandboxes (best-effort). Sandboxes are
|
|
44
|
+
* nested one level under a per-project dir (`/tmp/infracraft/<project>/<sandbox>`),
|
|
45
|
+
* so this sweeps individual stale sandboxes and then drops any now-empty project
|
|
46
|
+
* dir (`rmdir` is a no-op on a project dir with live deploys).
|
|
47
|
+
*/
|
|
43
48
|
private prepareWorkspace;
|
|
44
49
|
}
|
|
45
50
|
/** Bundle-safe check for a `DeploySandbox` in a `dependsOn` array. */
|
package/dist/sandbox.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.d.cts","names":[],"sources":["../src/sandbox.ts"],"mappings":";;;;;;;AAgBA;;;;iBAAgB,sBAAA,CAAuB,YAA2B;AAAA,UAqBxD,oBAAA;EAAoB;EAE7B,OAAA;EAF6B;EAI7B,QAAA;EAAA;EAEA,OAAA;EAGA;;EAAA,GAAA;EAMA;EAJA,YAAA;EAIG;EAFH,KAAA;EASiC;EAPjC,GAAA;AAAA;AAO+D;
|
|
1
|
+
{"version":3,"file":"sandbox.d.cts","names":[],"sources":["../src/sandbox.ts"],"mappings":";;;;;;;AAgBA;;;;iBAAgB,sBAAA,CAAuB,YAA2B;AAAA,UAqBxD,oBAAA;EAAoB;EAE7B,OAAA;EAF6B;EAI7B,QAAA;EAAA;EAEA,OAAA;EAGA;;EAAA,GAAA;EAMA;EAJA,YAAA;EAIG;EAFH,KAAA;EASiC;EAPjC,GAAA;AAAA;AAO+D;AA0DhE;;;AA1DgE,iBAAhD,kBAAA,CAAmB,OAA6B,EAApB,oBAAoB;;;;;;cA0DnD,aAAA,SAAsB,MAAA,CAAO,iBAAiB;cAC9C,IAAA,UAAc,IAAA,GAAO,MAAA,CAAO,wBAAA;EAkBhC;;AAAgB;AAgDzB;;;EAhDS,QAAA,gBAAA;AAAA;;iBAgDO,eAAA,CAAgB,KAAA,YAAiB,KAAA,IAAS,aAAa"}
|
package/dist/sandbox.d.mts
CHANGED
|
@@ -39,7 +39,12 @@ declare function buildSandboxScript(options: SandboxScriptOptions): string;
|
|
|
39
39
|
*/
|
|
40
40
|
declare class DeploySandbox extends pulumi.ComponentResource {
|
|
41
41
|
constructor(name: string, opts?: pulumi.ComponentResourceOptions);
|
|
42
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* mkdir the workspace root and GC stale sandboxes (best-effort). Sandboxes are
|
|
44
|
+
* nested one level under a per-project dir (`/tmp/infracraft/<project>/<sandbox>`),
|
|
45
|
+
* so this sweeps individual stale sandboxes and then drops any now-empty project
|
|
46
|
+
* dir (`rmdir` is a no-op on a project dir with live deploys).
|
|
47
|
+
*/
|
|
43
48
|
private prepareWorkspace;
|
|
44
49
|
}
|
|
45
50
|
/** Bundle-safe check for a `DeploySandbox` in a `dependsOn` array. */
|
package/dist/sandbox.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.d.mts","names":[],"sources":["../src/sandbox.ts"],"mappings":";;;;;;;AAgBA;;;;iBAAgB,sBAAA,CAAuB,YAA2B;AAAA,UAqBxD,oBAAA;EAAoB;EAE7B,OAAA;EAF6B;EAI7B,QAAA;EAAA;EAEA,OAAA;EAGA;;EAAA,GAAA;EAMA;EAJA,YAAA;EAIG;EAFH,KAAA;EASiC;EAPjC,GAAA;AAAA;AAO+D;
|
|
1
|
+
{"version":3,"file":"sandbox.d.mts","names":[],"sources":["../src/sandbox.ts"],"mappings":";;;;;;;AAgBA;;;;iBAAgB,sBAAA,CAAuB,YAA2B;AAAA,UAqBxD,oBAAA;EAAoB;EAE7B,OAAA;EAF6B;EAI7B,QAAA;EAAA;EAEA,OAAA;EAGA;;EAAA,GAAA;EAMA;EAJA,YAAA;EAIG;EAFH,KAAA;EASiC;EAPjC,GAAA;AAAA;AAO+D;AA0DhE;;;AA1DgE,iBAAhD,kBAAA,CAAmB,OAA6B,EAApB,oBAAoB;;;;;;cA0DnD,aAAA,SAAsB,MAAA,CAAO,iBAAiB;cAC9C,IAAA,UAAc,IAAA,GAAO,MAAA,CAAO,wBAAA;EAkBhC;;AAAgB;AAgDzB;;;EAhDS,QAAA,gBAAA;AAAA;;iBAgDO,eAAA,CAAgB,KAAA,YAAiB,KAAA,IAAS,aAAa"}
|
package/dist/sandbox.mjs
CHANGED
|
@@ -34,7 +34,13 @@ function buildSandboxScript(options) {
|
|
|
34
34
|
const head = `REPO=$(git rev-parse --show-toplevel)`;
|
|
35
35
|
const runSetupAndCli = [setup, cli].filter(Boolean).join("; ");
|
|
36
36
|
if (!sandbox) return `${head}; cd "$REPO"; ${runSetupAndCli}`;
|
|
37
|
-
const
|
|
37
|
+
const dirPrefix = env ? `${env}-${appName}` : appName;
|
|
38
|
+
const makeSandbox = [
|
|
39
|
+
`PROJECT_DIR="${SANDBOX_ROOT}/$(basename "$REPO")"`,
|
|
40
|
+
`mkdir -p "$PROJECT_DIR"`,
|
|
41
|
+
`SANDBOX=$(mktemp -d "$PROJECT_DIR/${dirPrefix}.XXXXXX")`,
|
|
42
|
+
`trap 'rm -rf "$SANDBOX"; rmdir "$PROJECT_DIR" 2>/dev/null || true' EXIT`
|
|
43
|
+
].join("; ");
|
|
38
44
|
if (gitGuard) return `${head}; ${makeSandbox}; ${`git -C "$REPO" ls-files | ${buildSandboxFileFilter(excludePaths)} | rsync -a --files-from=- "$REPO"/ "$SANDBOX"/`}; cd "\$SANDBOX" && git init -q && git add -A; ${runSetupAndCli}`;
|
|
39
45
|
return `${head}; ${makeSandbox}; git -C "\$REPO" ls-files | rsync -a --files-from=- "\$REPO"/ "\$SANDBOX"/; cp -c -R "\$REPO/.git" "\$SANDBOX/.git" 2>/dev/null || cp -R "\$REPO/.git" "\$SANDBOX/.git"; cd "$SANDBOX"; ${runSetupAndCli}`;
|
|
40
46
|
}
|
|
@@ -55,23 +61,40 @@ var DeploySandbox = class extends pulumi.ComponentResource {
|
|
|
55
61
|
if (!pulumi.runtime.isDryRun()) this.prepareWorkspace();
|
|
56
62
|
this.registerOutputs({});
|
|
57
63
|
}
|
|
58
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* mkdir the workspace root and GC stale sandboxes (best-effort). Sandboxes are
|
|
66
|
+
* nested one level under a per-project dir (`/tmp/infracraft/<project>/<sandbox>`),
|
|
67
|
+
* so this sweeps individual stale sandboxes and then drops any now-empty project
|
|
68
|
+
* dir (`rmdir` is a no-op on a project dir with live deploys).
|
|
69
|
+
*/
|
|
59
70
|
prepareWorkspace() {
|
|
60
71
|
fs.mkdirSync(SANDBOX_ROOT, { recursive: true });
|
|
61
|
-
|
|
72
|
+
const now = Date.now();
|
|
73
|
+
let projects = [];
|
|
62
74
|
try {
|
|
63
|
-
|
|
75
|
+
projects = fs.readdirSync(SANDBOX_ROOT);
|
|
64
76
|
} catch {
|
|
65
77
|
return;
|
|
66
78
|
}
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
79
|
+
for (const project of projects) {
|
|
80
|
+
const projectDir = path.join(SANDBOX_ROOT, project);
|
|
81
|
+
let sandboxes = [];
|
|
82
|
+
try {
|
|
83
|
+
sandboxes = fs.readdirSync(projectDir);
|
|
84
|
+
} catch {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
for (const sandbox of sandboxes) {
|
|
88
|
+
const full = path.join(projectDir, sandbox);
|
|
89
|
+
try {
|
|
90
|
+
if (now - fs.statSync(full).mtimeMs > STALE_SANDBOX_MS) fs.rmSync(full, {
|
|
91
|
+
recursive: true,
|
|
92
|
+
force: true
|
|
93
|
+
});
|
|
94
|
+
} catch {}
|
|
95
|
+
}
|
|
70
96
|
try {
|
|
71
|
-
|
|
72
|
-
recursive: true,
|
|
73
|
-
force: true
|
|
74
|
-
});
|
|
97
|
+
fs.rmdirSync(projectDir);
|
|
75
98
|
} catch {}
|
|
76
99
|
}
|
|
77
100
|
}
|
package/dist/sandbox.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.mjs","names":[],"sources":["../src/sandbox.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as pulumi from \"@pulumi/pulumi\";\n\n/** Escapes a path literal for embedding inside an awk ERE. */\nfunction escapeAwkRegex(path: string): string {\n\treturn path.replace(/[.[\\]{}()*+?^$|\\\\/]/g, \"\\\\$&\");\n}\n\n/**\n * Builds the shell filter applied to newline-delimited `git ls-files` output\n * before `rsync --files-from`. For `apps/<x>` it drops the app's files but keeps\n * `apps/<x>/package.json` (the monorepo workspace graph needs it during build);\n * any other entry drops the path and its subtree. Returns `cat` (passthrough)\n * when nothing is excluded. Uses awk so it is portable across macOS and Linux.\n */\nexport function buildSandboxFileFilter(excludePaths: string[] = []): string {\n\tif (excludePaths.length === 0) {\n\t\treturn \"cat\";\n\t}\n\n\tconst clauses = excludePaths.map((entry) => {\n\t\tconst escaped = escapeAwkRegex(entry);\n\n\t\tif (entry.startsWith(\"apps/\")) {\n\t\t\treturn `!(/^${escaped}\\\\// && !/^${escaped}\\\\/package\\\\.json$/)`;\n\t\t}\n\n\t\treturn `!/^${escaped}(\\\\/|$)/`;\n\t});\n\n\treturn `awk '${clauses.join(\" && \")}'`;\n}\n\n/** Root of the per-deploy sandbox tree. The DeploySandbox resource GCs this. */\nconst SANDBOX_ROOT = \"/tmp/infracraft\";\n\ninterface SandboxScriptOptions {\n\t/** Whether to isolate into a /tmp copy (false → run in the live tree). */\n\tsandbox: boolean;\n\t/** Whether the sandbox `.git` is a metadata-free stub (true) or the real one. */\n\tgitGuard: boolean;\n\t/** Resource-derived name, used in the sandbox dir prefix. */\n\tappName: string;\n\t/** Stack/environment name, prefixed to the sandbox dir so leftovers and\n\t * concurrent deploys are identifiable (e.g. `staging-vercel-deploy-nexus.XXXX`). */\n\tenv?: string;\n\t/** Upload-scoping excludes; applied only in stub mode (see design spec). */\n\texcludePaths?: string[];\n\t/** Shell run in the working dir before `cli` (e.g. write railpack.json). */\n\tsetup?: string;\n\t/** Fully-formed platform deploy command (its exit code becomes the script's). */\n\tcli: string;\n}\n\n/**\n * Builds the shell for a deploy's `command.local.Command.create`. See\n * docs/superpowers/specs/2026-06-05-deploy-sandbox-design.md for the modes.\n */\nexport function buildSandboxScript(options: SandboxScriptOptions): string {\n\tconst { sandbox, gitGuard, appName, env, excludePaths, setup, cli } = options;\n\n\tconst head = `REPO=$(git rev-parse --show-toplevel)`;\n\tconst runSetupAndCli = [setup, cli].filter(Boolean).join(\"; \");\n\n\tif (!sandbox) {\n\t\treturn `${head}; cd \"$REPO\"; ${runSetupAndCli}`;\n\t}\n\n\t// Prefix the dir with the env so leftovers/concurrent deploys are identifiable.\n\tconst dirPrefix = env ? `${env}-${appName}` : appName;\n\n\tconst makeSandbox = [\n\t\t`SANDBOX=$(mktemp -d $
|
|
1
|
+
{"version":3,"file":"sandbox.mjs","names":[],"sources":["../src/sandbox.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as pulumi from \"@pulumi/pulumi\";\n\n/** Escapes a path literal for embedding inside an awk ERE. */\nfunction escapeAwkRegex(path: string): string {\n\treturn path.replace(/[.[\\]{}()*+?^$|\\\\/]/g, \"\\\\$&\");\n}\n\n/**\n * Builds the shell filter applied to newline-delimited `git ls-files` output\n * before `rsync --files-from`. For `apps/<x>` it drops the app's files but keeps\n * `apps/<x>/package.json` (the monorepo workspace graph needs it during build);\n * any other entry drops the path and its subtree. Returns `cat` (passthrough)\n * when nothing is excluded. Uses awk so it is portable across macOS and Linux.\n */\nexport function buildSandboxFileFilter(excludePaths: string[] = []): string {\n\tif (excludePaths.length === 0) {\n\t\treturn \"cat\";\n\t}\n\n\tconst clauses = excludePaths.map((entry) => {\n\t\tconst escaped = escapeAwkRegex(entry);\n\n\t\tif (entry.startsWith(\"apps/\")) {\n\t\t\treturn `!(/^${escaped}\\\\// && !/^${escaped}\\\\/package\\\\.json$/)`;\n\t\t}\n\n\t\treturn `!/^${escaped}(\\\\/|$)/`;\n\t});\n\n\treturn `awk '${clauses.join(\" && \")}'`;\n}\n\n/** Root of the per-deploy sandbox tree. The DeploySandbox resource GCs this. */\nconst SANDBOX_ROOT = \"/tmp/infracraft\";\n\ninterface SandboxScriptOptions {\n\t/** Whether to isolate into a /tmp copy (false → run in the live tree). */\n\tsandbox: boolean;\n\t/** Whether the sandbox `.git` is a metadata-free stub (true) or the real one. */\n\tgitGuard: boolean;\n\t/** Resource-derived name, used in the sandbox dir prefix. */\n\tappName: string;\n\t/** Stack/environment name, prefixed to the sandbox dir so leftovers and\n\t * concurrent deploys are identifiable (e.g. `staging-vercel-deploy-nexus.XXXX`). */\n\tenv?: string;\n\t/** Upload-scoping excludes; applied only in stub mode (see design spec). */\n\texcludePaths?: string[];\n\t/** Shell run in the working dir before `cli` (e.g. write railpack.json). */\n\tsetup?: string;\n\t/** Fully-formed platform deploy command (its exit code becomes the script's). */\n\tcli: string;\n}\n\n/**\n * Builds the shell for a deploy's `command.local.Command.create`. See\n * docs/superpowers/specs/2026-06-05-deploy-sandbox-design.md for the modes.\n */\nexport function buildSandboxScript(options: SandboxScriptOptions): string {\n\tconst { sandbox, gitGuard, appName, env, excludePaths, setup, cli } = options;\n\n\tconst head = `REPO=$(git rev-parse --show-toplevel)`;\n\tconst runSetupAndCli = [setup, cli].filter(Boolean).join(\"; \");\n\n\tif (!sandbox) {\n\t\treturn `${head}; cd \"$REPO\"; ${runSetupAndCli}`;\n\t}\n\n\t// Prefix the dir with the env so leftovers/concurrent deploys are identifiable.\n\tconst dirPrefix = env ? `${env}-${appName}` : appName;\n\n\t// Group a repo's sandboxes under a per-project dir (named after the repo\n\t// folder) so concurrent deploys of different repos never mix. The project dir\n\t// is removed only once empty — `rmdir` fails on a non-empty dir, so it\n\t// survives until the project's last deploy has cleaned up its own sandbox.\n\tconst makeSandbox = [\n\t\t`PROJECT_DIR=\"${SANDBOX_ROOT}/$(basename \"$REPO\")\"`,\n\t\t`mkdir -p \"$PROJECT_DIR\"`,\n\t\t`SANDBOX=$(mktemp -d \"$PROJECT_DIR/${dirPrefix}.XXXXXX\")`,\n\t\t`trap 'rm -rf \"$SANDBOX\"; rmdir \"$PROJECT_DIR\" 2>/dev/null || true' EXIT`,\n\t].join(\"; \");\n\n\tif (gitGuard) {\n\t\tconst filter = buildSandboxFileFilter(excludePaths);\n\n\t\tconst copy =\n\t\t\t`git -C \"$REPO\" ls-files | ${filter} | ` +\n\t\t\t`rsync -a --files-from=- \"$REPO\"/ \"$SANDBOX\"/`;\n\n\t\tconst stubGit = `cd \"$SANDBOX\" && git init -q && git add -A`;\n\n\t\treturn `${head}; ${makeSandbox}; ${copy}; ${stubGit}; ${runSetupAndCli}`;\n\t}\n\n\t// Original `.git`, full clean tree (no filter, no reconciliation needed).\n\tconst copy = `git -C \"$REPO\" ls-files | rsync -a --files-from=- \"$REPO\"/ \"$SANDBOX\"/`;\n\n\tconst copyGit =\n\t\t`cp -c -R \"$REPO/.git\" \"$SANDBOX/.git\" 2>/dev/null || ` +\n\t\t`cp -R \"$REPO/.git\" \"$SANDBOX/.git\"`;\n\n\treturn `${head}; ${makeSandbox}; ${copy}; ${copyGit}; cd \"$SANDBOX\"; ${runSetupAndCli}`;\n}\n\n/** Cross-bundle brand: `instanceof` is unreliable when the seam and the resource\n * come from different built entries, so the seam detects sandboxes by this. */\nconst DEPLOY_SANDBOX_BRAND = Symbol.for(\"@infracraft/pulumi/DeploySandbox\");\n\n/** Sweep sandboxes orphaned by a hard-killed run (older than this). */\nconst STALE_SANDBOX_MS = 24 * 60 * 60 * 1000;\n\n/**\n * Isolation marker + workspace lifecycle. Listing it in a deploy's `dependsOn`\n * makes that deploy run in an isolated `/tmp/infracraft` copy. Carries no config;\n * the repo root is derived at runtime by the deploy command.\n */\nexport class DeploySandbox extends pulumi.ComponentResource {\n\tconstructor(name: string, opts?: pulumi.ComponentResourceOptions) {\n\t\tsuper(\"infracraft:sandbox:DeploySandbox\", name, {}, opts);\n\n\t\t(this as Record<symbol, unknown>)[DEPLOY_SANDBOX_BRAND] = true;\n\n\t\tif (!pulumi.runtime.isDryRun()) {\n\t\t\tthis.prepareWorkspace();\n\t\t}\n\n\t\tthis.registerOutputs({});\n\t}\n\n\t/**\n\t * mkdir the workspace root and GC stale sandboxes (best-effort). Sandboxes are\n\t * nested one level under a per-project dir (`/tmp/infracraft/<project>/<sandbox>`),\n\t * so this sweeps individual stale sandboxes and then drops any now-empty project\n\t * dir (`rmdir` is a no-op on a project dir with live deploys).\n\t */\n\tprivate prepareWorkspace(): void {\n\t\tfs.mkdirSync(SANDBOX_ROOT, { recursive: true });\n\n\t\tconst now = Date.now();\n\n\t\tlet projects: string[] = [];\n\n\t\ttry {\n\t\t\tprojects = fs.readdirSync(SANDBOX_ROOT) as string[];\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const project of projects) {\n\t\t\tconst projectDir = path.join(SANDBOX_ROOT, project);\n\n\t\t\tlet sandboxes: string[] = [];\n\n\t\t\ttry {\n\t\t\t\tsandboxes = fs.readdirSync(projectDir) as string[];\n\t\t\t} catch {\n\t\t\t\t// Not a directory (e.g. a stray file) — skip.\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tfor (const sandbox of sandboxes) {\n\t\t\t\tconst full = path.join(projectDir, sandbox);\n\n\t\t\t\ttry {\n\t\t\t\t\tif (now - fs.statSync(full).mtimeMs > STALE_SANDBOX_MS) {\n\t\t\t\t\t\tfs.rmSync(full, { recursive: true, force: true });\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Racing with an in-flight deploy's cleanup — ignore.\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Drop the project dir only if the sweep left it empty (best-effort).\n\t\t\ttry {\n\t\t\t\tfs.rmdirSync(projectDir);\n\t\t\t} catch {\n\t\t\t\t// Non-empty (live deploys) or already gone — ignore.\n\t\t\t}\n\t\t}\n\t}\n}\n\n/** Bundle-safe check for a `DeploySandbox` in a `dependsOn` array. */\nexport function isDeploySandbox(value: unknown): value is DeploySandbox {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t(value as Record<symbol, unknown>)[DEPLOY_SANDBOX_BRAND] === true\n\t);\n}\n"],"mappings":";;;;;;;AAKA,SAAS,eAAe,MAAsB;CAC7C,OAAO,KAAK,QAAQ,wBAAwB,MAAM;AACnD;;;;;;;;AASA,SAAgB,uBAAuB,eAAyB,CAAC,GAAW;CAC3E,IAAI,aAAa,WAAW,GAC3B,OAAO;CAaR,OAAO,QAVS,aAAa,KAAK,UAAU;EAC3C,MAAM,UAAU,eAAe,KAAK;EAEpC,IAAI,MAAM,WAAW,OAAO,GAC3B,OAAO,OAAO,QAAQ,aAAa,QAAQ;EAG5C,OAAO,MAAM,QAAQ;CACtB,CAEqB,EAAE,KAAK,MAAM,EAAE;AACrC;;AAGA,MAAM,eAAe;;;;;AAwBrB,SAAgB,mBAAmB,SAAuC;CACzE,MAAM,EAAE,SAAS,UAAU,SAAS,KAAK,cAAc,OAAO,QAAQ;CAEtE,MAAM,OAAO;CACb,MAAM,iBAAiB,CAAC,OAAO,GAAG,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;CAE7D,IAAI,CAAC,SACJ,OAAO,GAAG,KAAK,gBAAgB;CAIhC,MAAM,YAAY,MAAM,GAAG,IAAI,GAAG,YAAY;CAM9C,MAAM,cAAc;EACnB,gBAAgB,aAAa;EAC7B;EACA,qCAAqC,UAAU;EAC/C;CACD,EAAE,KAAK,IAAI;CAEX,IAAI,UASH,OAAO,GAAG,KAAK,IAAI,YAAY,IAAI,6BARpB,uBAAuB,YAGH,EAAE,iDAKG,iDAAgB;CAUzD,OAAO,GAAG,KAAK,IAAI,YAAY,2LAAwC;AACxE;;;AAIA,MAAM,uBAAuB,OAAO,IAAI,kCAAkC;;AAG1E,MAAM,mBAAmB,OAAU,KAAK;;;;;;AAOxC,IAAa,gBAAb,cAAmC,OAAO,kBAAkB;CAC3D,YAAY,MAAc,MAAwC;EACjE,MAAM,oCAAoC,MAAM,CAAC,GAAG,IAAI;EAExD,AAAC,KAAiC,wBAAwB;EAE1D,IAAI,CAAC,OAAO,QAAQ,SAAS,GAC5B,KAAK,iBAAiB;EAGvB,KAAK,gBAAgB,CAAC,CAAC;CACxB;;;;;;;CAQA,AAAQ,mBAAyB;EAChC,GAAG,UAAU,cAAc,EAAE,WAAW,KAAK,CAAC;EAE9C,MAAM,MAAM,KAAK,IAAI;EAErB,IAAI,WAAqB,CAAC;EAE1B,IAAI;GACH,WAAW,GAAG,YAAY,YAAY;EACvC,QAAQ;GACP;EACD;EAEA,KAAK,MAAM,WAAW,UAAU;GAC/B,MAAM,aAAa,KAAK,KAAK,cAAc,OAAO;GAElD,IAAI,YAAsB,CAAC;GAE3B,IAAI;IACH,YAAY,GAAG,YAAY,UAAU;GACtC,QAAQ;IAEP;GACD;GAEA,KAAK,MAAM,WAAW,WAAW;IAChC,MAAM,OAAO,KAAK,KAAK,YAAY,OAAO;IAE1C,IAAI;KACH,IAAI,MAAM,GAAG,SAAS,IAAI,EAAE,UAAU,kBACrC,GAAG,OAAO,MAAM;MAAE,WAAW;MAAM,OAAO;KAAK,CAAC;IAElD,QAAQ,CAER;GACD;GAGA,IAAI;IACH,GAAG,UAAU,UAAU;GACxB,QAAQ,CAER;EACD;CACD;AACD;;AAGA,SAAgB,gBAAgB,OAAwC;CACvE,OACC,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,0BAA0B;AAE/D"}
|
package/dist/vercel/deploy.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_chunk = require('../chunk-BVYJZCqc.cjs');
|
|
3
|
-
const
|
|
3
|
+
const require_commands_deploy = require('../commands/deploy.cjs');
|
|
4
4
|
let _pulumi_pulumi = require("@pulumi/pulumi");
|
|
5
5
|
_pulumi_pulumi = require_chunk.__toESM(_pulumi_pulumi, 1);
|
|
6
6
|
|
|
@@ -22,7 +22,7 @@ var VercelDeploy = class extends _pulumi_pulumi.ComponentResource {
|
|
|
22
22
|
super("infracraft:vercel:Deploy", name, {}, pulumiOpts);
|
|
23
23
|
const projectId = project ? project.id : args.projectId;
|
|
24
24
|
if (!projectId) throw new Error("VercelDeploy: either `args.projectId` or `opts.project` must be provided");
|
|
25
|
-
const { deploymentUrl } =
|
|
25
|
+
const { deploymentUrl } = require_commands_deploy.createDeployCommand({
|
|
26
26
|
name,
|
|
27
27
|
cli: "vercel deploy --prod --yes",
|
|
28
28
|
triggers: args.triggers,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.cjs","names":["pulumi","createDeployCommand"],"sources":["../../src/vercel/deploy.ts"],"sourcesContent":["// src/vercel/deploy.ts (replace entire file)\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { createDeployCommand } from \"../deploy
|
|
1
|
+
{"version":3,"file":"deploy.cjs","names":["pulumi","createDeployCommand"],"sources":["../../src/vercel/deploy.ts"],"sourcesContent":["// src/vercel/deploy.ts (replace entire file)\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { createDeployCommand } from \"../commands/deploy\";\nimport type { VercelProject } from \"./project\";\nimport type { VercelProvider } from \"./provider\";\n\ntype VercelDeployOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Vercel authentication context. */\n\tprovider: VercelProvider;\n\t/** VercelProject to source the project ID from (optional if `args.projectId` given). */\n\tproject?: VercelProject;\n};\n\nexport interface VercelDeployArgs {\n\t/** Vercel project ID. Required when `opts.project` is not provided. */\n\tprojectId?: pulumi.Input<string>;\n\t/** Redeploy triggers (e.g. source hash, env content hash). */\n\ttriggers: pulumi.Input<pulumi.Input<string>[]>;\n\t/** Paths excluded from the upload when running with `DeploySandbox` + `GitGuard`. */\n\texcludePaths?: string[];\n}\n\n/**\n * Deploys a Vercel project via `vercel deploy --prod --yes`. Isolation and\n * git-metadata handling are entirely the seam's job — list a `DeploySandbox`\n * (and optionally a `GitGuard`) in `opts.dependsOn` to control them.\n *\n * @example\n * ```typescript\n * new VercelDeploy(\"nexus\", { projectId: project.id, triggers: [sourceHash, envHash], excludePaths: [\"apps/mesh\"] },\n * { provider, dependsOn: [sandbox, gitGuard] });\n * ```\n */\nexport class VercelDeploy extends pulumi.ComponentResource {\n\tpublic readonly deploymentUrl: pulumi.Output<string>;\n\n\tconstructor(name: string, args: VercelDeployArgs, opts: VercelDeployOptions) {\n\t\tconst { provider, project, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:vercel:Deploy\", name, {}, pulumiOpts);\n\n\t\tconst projectId = project\n\t\t\t? project.id\n\t\t\t: (args.projectId as pulumi.Input<string>);\n\n\t\tif (!projectId) {\n\t\t\tthrow new Error(\n\t\t\t\t\"VercelDeploy: either `args.projectId` or `opts.project` must be provided\",\n\t\t\t);\n\t\t}\n\n\t\tconst { deploymentUrl } = createDeployCommand(\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tcli: \"vercel deploy --prod --yes\",\n\t\t\t\ttriggers: args.triggers,\n\t\t\t\texcludePaths: args.excludePaths,\n\t\t\t\tenvironment: {\n\t\t\t\t\tVERCEL_TOKEN: provider.token,\n\t\t\t\t\tVERCEL_ORG_ID: provider.teamId,\n\t\t\t\t\tVERCEL_PROJECT_ID: projectId,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ parent: this, ...pulumiOpts },\n\t\t);\n\n\t\tthis.deploymentUrl = deploymentUrl;\n\n\t\tthis.registerOutputs({ deploymentUrl: this.deploymentUrl });\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkCA,IAAa,eAAb,cAAkCA,eAAO,kBAAkB;CAG1D,YAAY,MAAc,MAAwB,MAA2B;EAC5E,MAAM,EAAE,UAAU,SAAS,GAAG,eAAe;EAE7C,MAAM,4BAA4B,MAAM,CAAC,GAAG,UAAU;EAEtD,MAAM,YAAY,UACf,QAAQ,KACP,KAAK;EAET,IAAI,CAAC,WACJ,MAAM,IAAI,MACT,0EACD;EAGD,MAAM,EAAE,kBAAkBC,4CACzB;GACC;GACA,KAAK;GACL,UAAU,KAAK;GACf,cAAc,KAAK;GACnB,aAAa;IACZ,cAAc,SAAS;IACvB,eAAe,SAAS;IACxB,mBAAmB;GACpB;EACD,GACA;GAAE,QAAQ;GAAM,GAAG;EAAW,CAC/B;EAEA,KAAK,gBAAgB;EAErB,KAAK,gBAAgB,EAAE,eAAe,KAAK,cAAc,CAAC;CAC3D;AACD"}
|
package/dist/vercel/deploy.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.mjs","names":[],"sources":["../../src/vercel/deploy.ts"],"sourcesContent":["// src/vercel/deploy.ts (replace entire file)\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { createDeployCommand } from \"../deploy
|
|
1
|
+
{"version":3,"file":"deploy.mjs","names":[],"sources":["../../src/vercel/deploy.ts"],"sourcesContent":["// src/vercel/deploy.ts (replace entire file)\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { createDeployCommand } from \"../commands/deploy\";\nimport type { VercelProject } from \"./project\";\nimport type { VercelProvider } from \"./provider\";\n\ntype VercelDeployOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Vercel authentication context. */\n\tprovider: VercelProvider;\n\t/** VercelProject to source the project ID from (optional if `args.projectId` given). */\n\tproject?: VercelProject;\n};\n\nexport interface VercelDeployArgs {\n\t/** Vercel project ID. Required when `opts.project` is not provided. */\n\tprojectId?: pulumi.Input<string>;\n\t/** Redeploy triggers (e.g. source hash, env content hash). */\n\ttriggers: pulumi.Input<pulumi.Input<string>[]>;\n\t/** Paths excluded from the upload when running with `DeploySandbox` + `GitGuard`. */\n\texcludePaths?: string[];\n}\n\n/**\n * Deploys a Vercel project via `vercel deploy --prod --yes`. Isolation and\n * git-metadata handling are entirely the seam's job — list a `DeploySandbox`\n * (and optionally a `GitGuard`) in `opts.dependsOn` to control them.\n *\n * @example\n * ```typescript\n * new VercelDeploy(\"nexus\", { projectId: project.id, triggers: [sourceHash, envHash], excludePaths: [\"apps/mesh\"] },\n * { provider, dependsOn: [sandbox, gitGuard] });\n * ```\n */\nexport class VercelDeploy extends pulumi.ComponentResource {\n\tpublic readonly deploymentUrl: pulumi.Output<string>;\n\n\tconstructor(name: string, args: VercelDeployArgs, opts: VercelDeployOptions) {\n\t\tconst { provider, project, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:vercel:Deploy\", name, {}, pulumiOpts);\n\n\t\tconst projectId = project\n\t\t\t? project.id\n\t\t\t: (args.projectId as pulumi.Input<string>);\n\n\t\tif (!projectId) {\n\t\t\tthrow new Error(\n\t\t\t\t\"VercelDeploy: either `args.projectId` or `opts.project` must be provided\",\n\t\t\t);\n\t\t}\n\n\t\tconst { deploymentUrl } = createDeployCommand(\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tcli: \"vercel deploy --prod --yes\",\n\t\t\t\ttriggers: args.triggers,\n\t\t\t\texcludePaths: args.excludePaths,\n\t\t\t\tenvironment: {\n\t\t\t\t\tVERCEL_TOKEN: provider.token,\n\t\t\t\t\tVERCEL_ORG_ID: provider.teamId,\n\t\t\t\t\tVERCEL_PROJECT_ID: projectId,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ parent: this, ...pulumiOpts },\n\t\t);\n\n\t\tthis.deploymentUrl = deploymentUrl;\n\n\t\tthis.registerOutputs({ deploymentUrl: this.deploymentUrl });\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkCA,IAAa,eAAb,cAAkC,OAAO,kBAAkB;CAG1D,YAAY,MAAc,MAAwB,MAA2B;EAC5E,MAAM,EAAE,UAAU,SAAS,GAAG,eAAe;EAE7C,MAAM,4BAA4B,MAAM,CAAC,GAAG,UAAU;EAEtD,MAAM,YAAY,UACf,QAAQ,KACP,KAAK;EAET,IAAI,CAAC,WACJ,MAAM,IAAI,MACT,0EACD;EAGD,MAAM,EAAE,kBAAkB,oBACzB;GACC;GACA,KAAK;GACL,UAAU,KAAK;GACf,cAAc,KAAK;GACnB,aAAa;IACZ,cAAc,SAAS;IACvB,eAAe,SAAS;IACxB,mBAAmB;GACpB;EACD,GACA;GAAE,QAAQ;GAAM,GAAG;EAAW,CAC/B;EAEA,KAAK,gBAAgB;EAErB,KAAK,gBAAgB,EAAE,eAAe,KAAK,cAAc,CAAC;CAC3D;AACD"}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deploy-command.cjs","names":["isDeploySandbox","isGitGuard","pulumi","buildSandboxScript","command"],"sources":["../src/deploy-command.ts"],"sourcesContent":["// src/deploy-command.ts\nimport * as command from \"@pulumi/command\";\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { isGitGuard } from \"./git-guard\";\nimport { buildSandboxScript, isDeploySandbox } from \"./sandbox\";\n\nexport interface CreateDeployCommandArgs {\n\t/** Resource name; the child command is `<name>` and the sandbox dir uses it. */\n\tname: string;\n\t/** Fully-formed platform deploy command (may be an Output, e.g. Railway). */\n\tcli: pulumi.Input<string>;\n\t/** Redeploy triggers (source/env hashes). */\n\ttriggers: pulumi.Input<pulumi.Input<string>[]>;\n\t/** Upload-scoping excludes (applied only in stub mode). */\n\texcludePaths?: string[];\n\t/** Shell run in the working dir before `cli` (e.g. write railpack.json). */\n\tsetup?: string;\n\t/** Env passed to the command (secrets that survive preview; not the inlined ones). */\n\tenvironment?: Record<string, pulumi.Input<string>>;\n}\n\nexport interface CreateDeployCommandResult {\n\tcommand: command.local.Command;\n\t/** The deploy CLI's final stdout line (the production URL for Vercel/Fly). */\n\tdeploymentUrl: pulumi.Output<string>;\n}\n\n/** Reads a `dependsOn` opt into a flat array of resource instances. */\nfunction dependsOnList(opts: pulumi.ComponentResourceOptions): unknown[] {\n\tconst dep = opts.dependsOn;\n\n\tif (Array.isArray(dep)) {\n\t\treturn dep;\n\t}\n\n\treturn dep ? [dep] : [];\n}\n\n/**\n * Builds a sandboxed deploy command. Inspects `opts.dependsOn` by brand:\n * a DeploySandbox → isolate; a GitGuard → stub `.git`; GitGuard alone → throw.\n * The platform deploy resources call ONLY this; they never touch the sandbox.\n */\nexport function createDeployCommand(\n\targs: CreateDeployCommandArgs,\n\topts: pulumi.ComponentResourceOptions,\n): CreateDeployCommandResult {\n\tconst deps = dependsOnList(opts);\n\tconst sandbox = deps.some(isDeploySandbox);\n\tconst gitGuard = deps.some(isGitGuard);\n\n\tif (gitGuard && !sandbox) {\n\t\tthrow new Error(\n\t\t\t`[infracraft] ${args.name}: GitGuard has no effect without a DeploySandbox in dependsOn`,\n\t\t);\n\t}\n\n\tconst env = pulumi.getStack();\n\n\tconst create = pulumi.output(args.cli).apply((cli) =>\n\t\tbuildSandboxScript({\n\t\t\tsandbox,\n\t\t\tgitGuard,\n\t\t\tappName: args.name,\n\t\t\tenv,\n\t\t\texcludePaths: args.excludePaths,\n\t\t\tsetup: args.setup,\n\t\t\tcli,\n\t\t}),\n\t);\n\n\tconst cmd = new command.local.Command(\n\t\targs.name,\n\t\t{ create, triggers: args.triggers, environment: args.environment },\n\t\topts,\n\t);\n\n\tconst deploymentUrl = cmd.stdout.apply(\n\t\t(out) => out.trim().split(\"\\n\").pop() ?? \"\",\n\t);\n\n\treturn { command: cmd, deploymentUrl };\n}\n"],"mappings":";;;;;;;;;;;AA6BA,SAAS,cAAc,MAAkD;CACxE,MAAM,MAAM,KAAK;CAEjB,IAAI,MAAM,QAAQ,GAAG,GACpB,OAAO;CAGR,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC;AACvB;;;;;;AAOA,SAAgB,oBACf,MACA,MAC4B;CAC5B,MAAM,OAAO,cAAc,IAAI;CAC/B,MAAM,UAAU,KAAK,KAAKA,+BAAe;CACzC,MAAM,WAAW,KAAK,KAAKC,4BAAU;CAErC,IAAI,YAAY,CAAC,SAChB,MAAM,IAAI,MACT,gBAAgB,KAAK,KAAK,8DAC3B;CAGD,MAAM,MAAMC,eAAO,SAAS;CAE5B,MAAM,SAASA,eAAO,OAAO,KAAK,GAAG,EAAE,OAAO,QAC7CC,mCAAmB;EAClB;EACA;EACA,SAAS,KAAK;EACd;EACA,cAAc,KAAK;EACnB,OAAO,KAAK;EACZ;CACD,CAAC,CACF;CAEA,MAAM,MAAM,IAAIC,gBAAQ,MAAM,QAC7B,KAAK,MACL;EAAE;EAAQ,UAAU,KAAK;EAAU,aAAa,KAAK;CAAY,GACjE,IACD;CAMA,OAAO;EAAE,SAAS;EAAK,eAJD,IAAI,OAAO,OAC/B,QAAQ,IAAI,KAAK,EAAE,MAAM,IAAI,EAAE,IAAI,KAAK,EAGP;CAAE;AACtC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deploy-command.d.cts","names":[],"sources":["../src/deploy-command.ts"],"mappings":";;;;;UAOiB,uBAAA;;EAEhB,IAAA;EAFgB;EAIhB,GAAA,EAAK,MAAA,CAAO,KAAA;;EAEZ,QAAA,EAAU,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,KAAA;EAAP;EAEvB,YAAA;EAI6B;EAF7B,KAAA;EAEoB;EAApB,WAAA,GAAc,MAAA,SAAe,MAAA,CAAO,KAAA;AAAA;AAAA,UAGpB,yBAAA;EAChB,OAAA,EAAS,OAAA,CAAQ,KAAA,CAAM,OAAA;EAZX;EAcZ,aAAA,EAAe,MAAA,CAAO,MAAM;AAAA;;;;;;iBAmBb,mBAAA,CACf,IAAA,EAAM,uBAAA,EACN,IAAA,EAAM,MAAA,CAAO,wBAAA,GACX,yBAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deploy-command.d.mts","names":[],"sources":["../src/deploy-command.ts"],"mappings":";;;;;UAOiB,uBAAA;;EAEhB,IAAA;EAFgB;EAIhB,GAAA,EAAK,MAAA,CAAO,KAAA;;EAEZ,QAAA,EAAU,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,KAAA;EAAP;EAEvB,YAAA;EAI6B;EAF7B,KAAA;EAEoB;EAApB,WAAA,GAAc,MAAA,SAAe,MAAA,CAAO,KAAA;AAAA;AAAA,UAGpB,yBAAA;EAChB,OAAA,EAAS,OAAA,CAAQ,KAAA,CAAM,OAAA;EAZX;EAcZ,aAAA,EAAe,MAAA,CAAO,MAAM;AAAA;;;;;;iBAmBb,mBAAA,CACf,IAAA,EAAM,uBAAA,EACN,IAAA,EAAM,MAAA,CAAO,wBAAA,GACX,yBAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deploy-command.mjs","names":[],"sources":["../src/deploy-command.ts"],"sourcesContent":["// src/deploy-command.ts\nimport * as command from \"@pulumi/command\";\nimport * as pulumi from \"@pulumi/pulumi\";\n\nimport { isGitGuard } from \"./git-guard\";\nimport { buildSandboxScript, isDeploySandbox } from \"./sandbox\";\n\nexport interface CreateDeployCommandArgs {\n\t/** Resource name; the child command is `<name>` and the sandbox dir uses it. */\n\tname: string;\n\t/** Fully-formed platform deploy command (may be an Output, e.g. Railway). */\n\tcli: pulumi.Input<string>;\n\t/** Redeploy triggers (source/env hashes). */\n\ttriggers: pulumi.Input<pulumi.Input<string>[]>;\n\t/** Upload-scoping excludes (applied only in stub mode). */\n\texcludePaths?: string[];\n\t/** Shell run in the working dir before `cli` (e.g. write railpack.json). */\n\tsetup?: string;\n\t/** Env passed to the command (secrets that survive preview; not the inlined ones). */\n\tenvironment?: Record<string, pulumi.Input<string>>;\n}\n\nexport interface CreateDeployCommandResult {\n\tcommand: command.local.Command;\n\t/** The deploy CLI's final stdout line (the production URL for Vercel/Fly). */\n\tdeploymentUrl: pulumi.Output<string>;\n}\n\n/** Reads a `dependsOn` opt into a flat array of resource instances. */\nfunction dependsOnList(opts: pulumi.ComponentResourceOptions): unknown[] {\n\tconst dep = opts.dependsOn;\n\n\tif (Array.isArray(dep)) {\n\t\treturn dep;\n\t}\n\n\treturn dep ? [dep] : [];\n}\n\n/**\n * Builds a sandboxed deploy command. Inspects `opts.dependsOn` by brand:\n * a DeploySandbox → isolate; a GitGuard → stub `.git`; GitGuard alone → throw.\n * The platform deploy resources call ONLY this; they never touch the sandbox.\n */\nexport function createDeployCommand(\n\targs: CreateDeployCommandArgs,\n\topts: pulumi.ComponentResourceOptions,\n): CreateDeployCommandResult {\n\tconst deps = dependsOnList(opts);\n\tconst sandbox = deps.some(isDeploySandbox);\n\tconst gitGuard = deps.some(isGitGuard);\n\n\tif (gitGuard && !sandbox) {\n\t\tthrow new Error(\n\t\t\t`[infracraft] ${args.name}: GitGuard has no effect without a DeploySandbox in dependsOn`,\n\t\t);\n\t}\n\n\tconst env = pulumi.getStack();\n\n\tconst create = pulumi.output(args.cli).apply((cli) =>\n\t\tbuildSandboxScript({\n\t\t\tsandbox,\n\t\t\tgitGuard,\n\t\t\tappName: args.name,\n\t\t\tenv,\n\t\t\texcludePaths: args.excludePaths,\n\t\t\tsetup: args.setup,\n\t\t\tcli,\n\t\t}),\n\t);\n\n\tconst cmd = new command.local.Command(\n\t\targs.name,\n\t\t{ create, triggers: args.triggers, environment: args.environment },\n\t\topts,\n\t);\n\n\tconst deploymentUrl = cmd.stdout.apply(\n\t\t(out) => out.trim().split(\"\\n\").pop() ?? \"\",\n\t);\n\n\treturn { command: cmd, deploymentUrl };\n}\n"],"mappings":";;;;;;;;AA6BA,SAAS,cAAc,MAAkD;CACxE,MAAM,MAAM,KAAK;CAEjB,IAAI,MAAM,QAAQ,GAAG,GACpB,OAAO;CAGR,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC;AACvB;;;;;;AAOA,SAAgB,oBACf,MACA,MAC4B;CAC5B,MAAM,OAAO,cAAc,IAAI;CAC/B,MAAM,UAAU,KAAK,KAAK,eAAe;CACzC,MAAM,WAAW,KAAK,KAAK,UAAU;CAErC,IAAI,YAAY,CAAC,SAChB,MAAM,IAAI,MACT,gBAAgB,KAAK,KAAK,8DAC3B;CAGD,MAAM,MAAM,OAAO,SAAS;CAE5B,MAAM,SAAS,OAAO,OAAO,KAAK,GAAG,EAAE,OAAO,QAC7C,mBAAmB;EAClB;EACA;EACA,SAAS,KAAK;EACd;EACA,cAAc,KAAK;EACnB,OAAO,KAAK;EACZ;CACD,CAAC,CACF;CAEA,MAAM,MAAM,IAAI,QAAQ,MAAM,QAC7B,KAAK,MACL;EAAE;EAAQ,UAAU,KAAK;EAAU,aAAa,KAAK;CAAY,GACjE,IACD;CAMA,OAAO;EAAE,SAAS;EAAK,eAJD,IAAI,OAAO,OAC/B,QAAQ,IAAI,KAAK,EAAE,MAAM,IAAI,EAAE,IAAI,KAAK,EAGP;CAAE;AACtC"}
|