@infracraft/pulumi 1.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/railway/deploy.cjs +1 -2
  2. package/dist/railway/deploy.cjs.map +1 -1
  3. package/dist/railway/deploy.d.cts +2 -4
  4. package/dist/railway/deploy.d.cts.map +1 -1
  5. package/dist/railway/deploy.d.mts +2 -4
  6. package/dist/railway/deploy.d.mts.map +1 -1
  7. package/dist/railway/deploy.mjs +1 -2
  8. package/dist/railway/deploy.mjs.map +1 -1
  9. package/dist/vercel/deploy.cjs +6 -16
  10. package/dist/vercel/deploy.cjs.map +1 -1
  11. package/dist/vercel/deploy.d.cts +13 -10
  12. package/dist/vercel/deploy.d.cts.map +1 -1
  13. package/dist/vercel/deploy.d.mts +13 -10
  14. package/dist/vercel/deploy.d.mts.map +1 -1
  15. package/dist/vercel/deploy.mjs +6 -15
  16. package/dist/vercel/deploy.mjs.map +1 -1
  17. package/dist/vercel/index.cjs +2 -0
  18. package/dist/vercel/index.d.cts +2 -1
  19. package/dist/vercel/index.d.mts +2 -1
  20. package/dist/vercel/index.mjs +2 -1
  21. package/dist/vercel/project.cjs +162 -0
  22. package/dist/vercel/project.cjs.map +1 -0
  23. package/dist/vercel/project.d.cts +72 -0
  24. package/dist/vercel/project.d.cts.map +1 -0
  25. package/dist/vercel/project.d.mts +72 -0
  26. package/dist/vercel/project.d.mts.map +1 -0
  27. package/dist/vercel/project.mjs +160 -0
  28. package/dist/vercel/project.mjs.map +1 -0
  29. package/dist/vercel/variable.cjs +4 -2
  30. package/dist/vercel/variable.cjs.map +1 -1
  31. package/dist/vercel/variable.d.cts +11 -2
  32. package/dist/vercel/variable.d.cts.map +1 -1
  33. package/dist/vercel/variable.d.mts +11 -2
  34. package/dist/vercel/variable.d.mts.map +1 -1
  35. package/dist/vercel/variable.mjs +4 -2
  36. package/dist/vercel/variable.mjs.map +1 -1
  37. package/package.json +1 -1
@@ -33,11 +33,10 @@ var RailwayDeploy = class extends _pulumi_pulumi.ComponentResource {
33
33
  return dir;
34
34
  }).join("\\n");
35
35
  const setupLines = [ignorePatterns ? `printf '${ignorePatterns}\\n' > .railwayignore` : "", args.railpackConfig ? `printf '${JSON.stringify(args.railpackConfig).replace(/'/g, "\\'")}' > railpack.json` : ""].filter(Boolean).join("; ");
36
- const envHash = _pulumi_pulumi.all(Object.entries(args.env).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => _pulumi_pulumi.output(v).apply((val) => `${k}=${val}`))).apply((parts) => parts.join(","));
37
36
  const deployCmd = _pulumi_pulumi.interpolate`while ! mkdir ${LOCK_DIR} 2>/dev/null; do sleep 1; done; ${setupLines}; { sleep 5; rm -f .railwayignore railpack.json; rmdir ${LOCK_DIR} 2>/dev/null; } & railway up --ci --project ${project.id} --service ${service.id} --environment ${environment.id}; EXIT=$?; rm -f .railwayignore railpack.json; rmdir ${LOCK_DIR} 2>/dev/null; wait; exit $EXIT`;
38
37
  new _pulumi_command.local.Command(`${name}-deploy`, {
39
38
  create: deployCmd,
40
- triggers: [args.sourceHash, envHash],
39
+ triggers: args.triggers,
41
40
  dir: args.directory,
42
41
  environment: { RAILWAY_TOKEN: project.projectToken }
43
42
  }, { parent: this });
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.cjs","names":["pulumi","command"],"sources":["../../src/railway/deploy.ts"],"sourcesContent":["import * as command from \"@pulumi/command\";\nimport * as pulumi from \"@pulumi/pulumi\";\nimport type { RailwayEnvironment } from \"./environment.js\";\nimport type { RailwayProject } from \"./project.js\";\nimport type { RailwayProvider } from \"./provider.js\";\nimport type { RailwayService } from \"./service.js\";\n\n/** Build and deploy configuration for a Railway service. */\nexport interface RailwayDeployConfig {\n\t/** Build system: `\"RAILPACK\"`, `\"NIXPACKS\"`, or `\"DOCKERFILE\"`. */\n\tbuilder?: string;\n\n\t/** Shell command executed to start the service at runtime. */\n\tstartCommand?: string;\n\n\t/** Shell command executed before the main deploy (e.g. migrations). */\n\tpreDeployCommand?: string;\n}\n\n/** Args for RailwayDeploy. */\nexport interface RailwayDeployArgs {\n\t/** Absolute path to the monorepo root (working directory for `railway up`). */\n\tdirectory: string;\n\n\t/** SHA-256 hash of the app source directory, used as a deploy trigger. */\n\tsourceHash: string;\n\n\t/** Env var map used as deploy trigger. */\n\tenv: Record<string, pulumi.Input<string>>;\n\n\t/** Directories to exclude via `.railwayignore`. */\n\texcludePaths?: string[];\n\n\t/** Railpack configuration written to `railpack.json` before deploy. */\n\trailpackConfig?: Record<string, unknown>;\n}\n\n/** Options type for RailwayDeploy — replaces Pulumi's native `provider` field. */\ntype RailwayDeployOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Railway authentication context. */\n\tprovider: RailwayProvider;\n\n\t/** Railway project context. */\n\tproject: RailwayProject;\n\n\t/** Railway environment context. */\n\tenvironment: RailwayEnvironment;\n\n\t/** Railway service context. */\n\tservice: RailwayService;\n};\n\nconst LOCK_DIR = \"/tmp/.railway-upload-lock\";\n\n/**\n * Deploys a Railway service and waits for the build to complete.\n *\n * Uses `railway up --ci` which blocks until the build finishes.\n * Multiple deploys run in parallel — a mkdir lock serializes only the\n * brief upload phase (~5s) when `.railwayignore` must be consistent,\n * then releases so builds stream concurrently.\n *\n * @example\n * ```typescript\n * new RailwayDeploy(\"api-deploy\", {\n * directory: monorepoRoot,\n * sourceHash,\n * env: { DATABASE_URL: dbUrl },\n * }, { provider, project, environment, service });\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 { provider, project, environment, service, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:railway:Deploy\", name, {}, pulumiOpts);\n\n\t\tconst ignorePatterns = (args.excludePaths ?? [])\n\t\t\t.map((dir) => {\n\t\t\t\tif (dir.startsWith(\"apps/\")) {\n\t\t\t\t\treturn `${dir}/**\\\\n!${dir}/package.json`;\n\t\t\t\t}\n\n\t\t\t\treturn dir;\n\t\t\t})\n\t\t\t.join(\"\\\\n\");\n\n\t\tconst writeIgnore = ignorePatterns\n\t\t\t? `printf '${ignorePatterns}\\\\n' > .railwayignore`\n\t\t\t: \"\";\n\n\t\tconst writeRailpack = args.railpackConfig\n\t\t\t? `printf '${JSON.stringify(args.railpackConfig).replace(/'/g, \"\\\\'\")}' > railpack.json`\n\t\t\t: \"\";\n\n\t\tconst setupLines = [writeIgnore, writeRailpack].filter(Boolean).join(\"; \");\n\n\t\tconst envHash = pulumi\n\t\t\t.all(\n\t\t\t\tObject.entries(args.env)\n\t\t\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t\t\t.map(([k, v]) => pulumi.output(v).apply((val) => `${k}=${val}`)),\n\t\t\t)\n\t\t\t.apply((parts) => parts.join(\",\"));\n\n\t\t// Parallel-safe upload: multiple stacks deploy concurrently, but each writes\n\t\t// .railwayignore and railpack.json to the same monorepo root before calling\n\t\t// `railway up`. The mkdir lock serializes that brief window (~5s upload phase).\n\t\t// After upload, the background job releases the lock so builds stream in parallel.\n\t\t//\n\t\t// Flow: acquire lock → write config files → release lock after 5s (background) →\n\t\t// railway up --ci (blocks through upload, then streams build logs) →\n\t\t// cleanup on exit\n\t\tconst deployCmd = pulumi.interpolate`while ! mkdir ${LOCK_DIR} 2>/dev/null; do sleep 1; done; ${setupLines}; { sleep 5; rm -f .railwayignore railpack.json; rmdir ${LOCK_DIR} 2>/dev/null; } & railway up --ci --project ${project.id} --service ${service.id} --environment ${environment.id}; EXIT=$?; rm -f .railwayignore railpack.json; rmdir ${LOCK_DIR} 2>/dev/null; wait; exit $EXIT`;\n\n\t\tnew command.local.Command(\n\t\t\t`${name}-deploy`,\n\t\t\t{\n\t\t\t\tcreate: deployCmd,\n\t\t\t\ttriggers: [args.sourceHash, envHash],\n\t\t\t\tdir: args.directory,\n\t\t\t\tenvironment: {\n\t\t\t\t\tRAILWAY_TOKEN: project.projectToken,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;;;;AAuDA,MAAM,WAAW;;;;;;;;;;;;;;;;;;AAmBjB,IAAa,gBAAb,cAAmCA,eAAO,kBAAkB;CAC3D,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,SAAS,aAAa,SAAS,GAAG,eAAe;EAEnE,MAAM,6BAA6B,MAAM,CAAC,GAAG,UAAU;EAEvD,MAAM,kBAAkB,KAAK,gBAAgB,CAAC,GAC5C,KAAK,QAAQ;GACb,IAAI,IAAI,WAAW,OAAO,GACzB,OAAO,GAAG,IAAI,SAAS,IAAI;GAG5B,OAAO;EACR,CAAC,EACA,KAAK,KAAK;EAUZ,MAAM,aAAa,CARC,iBACjB,WAAW,eAAe,yBAC1B,IAEmB,KAAK,iBACxB,WAAW,KAAK,UAAU,KAAK,cAAc,EAAE,QAAQ,MAAM,KAAK,EAAE,qBACpE,EAE2C,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;EAEzE,MAAM,UAAUA,eACd,IACA,OAAO,QAAQ,KAAK,GAAG,EACrB,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,EACrC,KAAK,CAAC,GAAG,OAAOA,eAAO,OAAO,CAAC,EAAE,OAAO,QAAQ,GAAG,EAAE,GAAG,KAAK,CAAC,CACjE,EACC,OAAO,UAAU,MAAM,KAAK,GAAG,CAAC;EAUlC,MAAM,YAAY,eAAO,WAAW,iBAAiB,SAAS,kCAAkC,WAAW,yDAAyD,SAAS,8CAA8C,QAAQ,GAAG,aAAa,QAAQ,GAAG,iBAAiB,YAAY,GAAG,uDAAuD,SAAS;EAE9V,IAAIC,gBAAQ,MAAM,QACjB,GAAG,KAAK,UACR;GACC,QAAQ;GACR,UAAU,CAAC,KAAK,YAAY,OAAO;GACnC,KAAK,KAAK;GACV,aAAa,EACZ,eAAe,QAAQ,aACxB;EACD,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
1
+ {"version":3,"file":"deploy.cjs","names":["pulumi","command"],"sources":["../../src/railway/deploy.ts"],"sourcesContent":["import * as command from \"@pulumi/command\";\nimport * as pulumi from \"@pulumi/pulumi\";\nimport type { RailwayEnvironment } from \"./environment.js\";\nimport type { RailwayProject } from \"./project.js\";\nimport type { RailwayProvider } from \"./provider.js\";\nimport type { RailwayService } from \"./service.js\";\n\n/** Build and deploy configuration for a Railway service. */\nexport interface RailwayDeployConfig {\n\t/** Build system: `\"RAILPACK\"`, `\"NIXPACKS\"`, or `\"DOCKERFILE\"`. */\n\tbuilder?: string;\n\n\t/** Shell command executed to start the service at runtime. */\n\tstartCommand?: string;\n\n\t/** Shell command executed before the main deploy (e.g. migrations). */\n\tpreDeployCommand?: string;\n}\n\n/** Args for RailwayDeploy. */\nexport interface RailwayDeployArgs {\n\t/** Absolute path to the monorepo root (working directory for `railway up`). */\n\tdirectory: string;\n\n\t/** Values that trigger a redeploy when changed (e.g. source hashes, env hashes). */\n\ttriggers: pulumi.Input<pulumi.Input<string>[]>;\n\n\t/** Directories to exclude via `.railwayignore`. */\n\texcludePaths?: string[];\n\n\t/** Railpack configuration written to `railpack.json` before deploy. */\n\trailpackConfig?: Record<string, unknown>;\n}\n\n/** Options type for RailwayDeploy — replaces Pulumi's native `provider` field. */\ntype RailwayDeployOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Railway authentication context. */\n\tprovider: RailwayProvider;\n\n\t/** Railway project context. */\n\tproject: RailwayProject;\n\n\t/** Railway environment context. */\n\tenvironment: RailwayEnvironment;\n\n\t/** Railway service context. */\n\tservice: RailwayService;\n};\n\nconst LOCK_DIR = \"/tmp/.railway-upload-lock\";\n\n/**\n * Deploys a Railway service and waits for the build to complete.\n *\n * Uses `railway up --ci` which blocks until the build finishes.\n * Multiple deploys run in parallel — a mkdir lock serializes only the\n * brief upload phase (~5s) when `.railwayignore` must be consistent,\n * then releases so builds stream concurrently.\n *\n * @example\n * ```typescript\n * new RailwayDeploy(\"api-deploy\", {\n * directory: monorepoRoot,\n * sourceHash,\n * env: { DATABASE_URL: dbUrl },\n * }, { provider, project, environment, service });\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 { provider, project, environment, service, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:railway:Deploy\", name, {}, pulumiOpts);\n\n\t\tconst ignorePatterns = (args.excludePaths ?? [])\n\t\t\t.map((dir) => {\n\t\t\t\tif (dir.startsWith(\"apps/\")) {\n\t\t\t\t\treturn `${dir}/**\\\\n!${dir}/package.json`;\n\t\t\t\t}\n\n\t\t\t\treturn dir;\n\t\t\t})\n\t\t\t.join(\"\\\\n\");\n\n\t\tconst writeIgnore = ignorePatterns\n\t\t\t? `printf '${ignorePatterns}\\\\n' > .railwayignore`\n\t\t\t: \"\";\n\n\t\tconst writeRailpack = args.railpackConfig\n\t\t\t? `printf '${JSON.stringify(args.railpackConfig).replace(/'/g, \"\\\\'\")}' > railpack.json`\n\t\t\t: \"\";\n\n\t\tconst setupLines = [writeIgnore, writeRailpack].filter(Boolean).join(\"; \");\n\n\t\tconst deployCmd = pulumi.interpolate`while ! mkdir ${LOCK_DIR} 2>/dev/null; do sleep 1; done; ${setupLines}; { sleep 5; rm -f .railwayignore railpack.json; rmdir ${LOCK_DIR} 2>/dev/null; } & railway up --ci --project ${project.id} --service ${service.id} --environment ${environment.id}; EXIT=$?; rm -f .railwayignore railpack.json; rmdir ${LOCK_DIR} 2>/dev/null; wait; exit $EXIT`;\n\n\t\tnew command.local.Command(\n\t\t\t`${name}-deploy`,\n\t\t\t{\n\t\t\t\tcreate: deployCmd,\n\t\t\t\ttriggers: args.triggers,\n\t\t\t\tdir: args.directory,\n\t\t\t\tenvironment: {\n\t\t\t\t\tRAILWAY_TOKEN: project.projectToken,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;;;;AAoDA,MAAM,WAAW;;;;;;;;;;;;;;;;;;AAmBjB,IAAa,gBAAb,cAAmCA,eAAO,kBAAkB;CAC3D,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,SAAS,aAAa,SAAS,GAAG,eAAe;EAEnE,MAAM,6BAA6B,MAAM,CAAC,GAAG,UAAU;EAEvD,MAAM,kBAAkB,KAAK,gBAAgB,CAAC,GAC5C,KAAK,QAAQ;GACb,IAAI,IAAI,WAAW,OAAO,GACzB,OAAO,GAAG,IAAI,SAAS,IAAI;GAG5B,OAAO;EACR,CAAC,EACA,KAAK,KAAK;EAUZ,MAAM,aAAa,CARC,iBACjB,WAAW,eAAe,yBAC1B,IAEmB,KAAK,iBACxB,WAAW,KAAK,UAAU,KAAK,cAAc,EAAE,QAAQ,MAAM,KAAK,EAAE,qBACpE,EAE2C,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;EAEzE,MAAM,YAAY,eAAO,WAAW,iBAAiB,SAAS,kCAAkC,WAAW,yDAAyD,SAAS,8CAA8C,QAAQ,GAAG,aAAa,QAAQ,GAAG,iBAAiB,YAAY,GAAG,uDAAuD,SAAS;EAE9V,IAAIC,gBAAQ,MAAM,QACjB,GAAG,KAAK,UACR;GACC,QAAQ;GACR,UAAU,KAAK;GACf,KAAK,KAAK;GACV,aAAa,EACZ,eAAe,QAAQ,aACxB;EACD,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
@@ -19,10 +19,8 @@ interface RailwayDeployConfig {
19
19
  interface RailwayDeployArgs {
20
20
  /** Absolute path to the monorepo root (working directory for `railway up`). */
21
21
  directory: string;
22
- /** SHA-256 hash of the app source directory, used as a deploy trigger. */
23
- sourceHash: string;
24
- /** Env var map used as deploy trigger. */
25
- env: Record<string, pulumi.Input<string>>;
22
+ /** Values that trigger a redeploy when changed (e.g. source hashes, env hashes). */
23
+ triggers: pulumi.Input<pulumi.Input<string>[]>;
26
24
  /** Directories to exclude via `.railwayignore`. */
27
25
  excludePaths?: string[];
28
26
  /** Railpack configuration written to `railpack.json` before deploy. */
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.cts","names":[],"sources":["../../src/railway/deploy.ts"],"mappings":";;;;;;;;;UAQiB,mBAAA;;EAEhB,OAAA;EAFmC;EAKnC,YAAA;EALmC;EAQnC,gBAAA;AAAA;;UAIgB,iBAAA;EAJA;EAMhB,SAAA;EAFiC;EAKjC,UAAA;EAGoB;EAApB,GAAA,EAAK,MAAA,SAAe,MAAA,CAAO,KAAA;EAMV;EAHjB,YAAA;EAGuB;EAAvB,cAAA,GAAiB,MAAA;AAAA;;KAIb,oBAAA,GAAuB,IAAA,CAC3B,MAAA,CAAO,wBAAA;EAXa,sCAepB,QAAA,EAAU,eAAA,EAZV;EAeA,OAAA,EAAS,cAAA,EAZQ;EAejB,WAAA,EAAa,kBAAA,EAfU;EAkBvB,OAAA,EAAS,cAAA;AAAA;;;;;;;;;;;;;;;;;;cAsBG,aAAA,SAAsB,MAAA,CAAO,iBAAA;cAExC,IAAA,UACA,IAAA,EAAM,iBAAA,EACN,IAAA,EAAM,oBAAA;AAAA"}
1
+ {"version":3,"file":"deploy.d.cts","names":[],"sources":["../../src/railway/deploy.ts"],"mappings":";;;;;;;;;UAQiB,mBAAA;;EAEhB,OAAA;EAFmC;EAKnC,YAAA;EALmC;EAQnC,gBAAA;AAAA;;UAIgB,iBAAA;EAJA;EAMhB,SAAA;EAFiC;EAKjC,QAAA,EAAU,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,KAAA;EAAP;EAGvB,YAAA;EAGiB;EAAjB,cAAA,GAAiB,MAAA;AAAA;;KAIb,oBAAA,GAAuB,IAAA,CAC3B,MAAA,CAAO,wBAAA;EAXG,sCAeV,QAAA,EAAU,eAAA,EAfa;EAkBvB,OAAA,EAAS,cAAA,EAfT;EAkBA,WAAA,EAAa,kBAAA,EAfI;EAkBjB,OAAA,EAAS,cAAA;AAAA;AAjBT;;;;;;;;;;;;;;;;;AAAA,cAuCY,aAAA,SAAsB,MAAA,CAAO,iBAAA;cAExC,IAAA,UACA,IAAA,EAAM,iBAAA,EACN,IAAA,EAAM,oBAAA;AAAA"}
@@ -19,10 +19,8 @@ interface RailwayDeployConfig {
19
19
  interface RailwayDeployArgs {
20
20
  /** Absolute path to the monorepo root (working directory for `railway up`). */
21
21
  directory: string;
22
- /** SHA-256 hash of the app source directory, used as a deploy trigger. */
23
- sourceHash: string;
24
- /** Env var map used as deploy trigger. */
25
- env: Record<string, pulumi.Input<string>>;
22
+ /** Values that trigger a redeploy when changed (e.g. source hashes, env hashes). */
23
+ triggers: pulumi.Input<pulumi.Input<string>[]>;
26
24
  /** Directories to exclude via `.railwayignore`. */
27
25
  excludePaths?: string[];
28
26
  /** Railpack configuration written to `railpack.json` before deploy. */
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.mts","names":[],"sources":["../../src/railway/deploy.ts"],"mappings":";;;;;;;;;UAQiB,mBAAA;;EAEhB,OAAA;EAFmC;EAKnC,YAAA;EALmC;EAQnC,gBAAA;AAAA;;UAIgB,iBAAA;EAJA;EAMhB,SAAA;EAFiC;EAKjC,UAAA;EAGoB;EAApB,GAAA,EAAK,MAAA,SAAe,MAAA,CAAO,KAAA;EAMV;EAHjB,YAAA;EAGuB;EAAvB,cAAA,GAAiB,MAAA;AAAA;;KAIb,oBAAA,GAAuB,IAAA,CAC3B,MAAA,CAAO,wBAAA;EAXa,sCAepB,QAAA,EAAU,eAAA,EAZV;EAeA,OAAA,EAAS,cAAA,EAZQ;EAejB,WAAA,EAAa,kBAAA,EAfU;EAkBvB,OAAA,EAAS,cAAA;AAAA;;;;;;;;;;;;;;;;;;cAsBG,aAAA,SAAsB,MAAA,CAAO,iBAAA;cAExC,IAAA,UACA,IAAA,EAAM,iBAAA,EACN,IAAA,EAAM,oBAAA;AAAA"}
1
+ {"version":3,"file":"deploy.d.mts","names":[],"sources":["../../src/railway/deploy.ts"],"mappings":";;;;;;;;;UAQiB,mBAAA;;EAEhB,OAAA;EAFmC;EAKnC,YAAA;EALmC;EAQnC,gBAAA;AAAA;;UAIgB,iBAAA;EAJA;EAMhB,SAAA;EAFiC;EAKjC,QAAA,EAAU,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,KAAA;EAAP;EAGvB,YAAA;EAGiB;EAAjB,cAAA,GAAiB,MAAA;AAAA;;KAIb,oBAAA,GAAuB,IAAA,CAC3B,MAAA,CAAO,wBAAA;EAXG,sCAeV,QAAA,EAAU,eAAA,EAfa;EAkBvB,OAAA,EAAS,cAAA,EAfT;EAkBA,WAAA,EAAa,kBAAA,EAfI;EAkBjB,OAAA,EAAS,cAAA;AAAA;AAjBT;;;;;;;;;;;;;;;;;AAAA,cAuCY,aAAA,SAAsB,MAAA,CAAO,iBAAA;cAExC,IAAA,UACA,IAAA,EAAM,iBAAA,EACN,IAAA,EAAM,oBAAA;AAAA"}
@@ -30,11 +30,10 @@ var RailwayDeploy = class extends pulumi.ComponentResource {
30
30
  return dir;
31
31
  }).join("\\n");
32
32
  const setupLines = [ignorePatterns ? `printf '${ignorePatterns}\\n' > .railwayignore` : "", args.railpackConfig ? `printf '${JSON.stringify(args.railpackConfig).replace(/'/g, "\\'")}' > railpack.json` : ""].filter(Boolean).join("; ");
33
- const envHash = pulumi.all(Object.entries(args.env).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => pulumi.output(v).apply((val) => `${k}=${val}`))).apply((parts) => parts.join(","));
34
33
  const deployCmd = pulumi.interpolate`while ! mkdir ${LOCK_DIR} 2>/dev/null; do sleep 1; done; ${setupLines}; { sleep 5; rm -f .railwayignore railpack.json; rmdir ${LOCK_DIR} 2>/dev/null; } & railway up --ci --project ${project.id} --service ${service.id} --environment ${environment.id}; EXIT=$?; rm -f .railwayignore railpack.json; rmdir ${LOCK_DIR} 2>/dev/null; wait; exit $EXIT`;
35
34
  new command.local.Command(`${name}-deploy`, {
36
35
  create: deployCmd,
37
- triggers: [args.sourceHash, envHash],
36
+ triggers: args.triggers,
38
37
  dir: args.directory,
39
38
  environment: { RAILWAY_TOKEN: project.projectToken }
40
39
  }, { parent: this });
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.mjs","names":[],"sources":["../../src/railway/deploy.ts"],"sourcesContent":["import * as command from \"@pulumi/command\";\nimport * as pulumi from \"@pulumi/pulumi\";\nimport type { RailwayEnvironment } from \"./environment.js\";\nimport type { RailwayProject } from \"./project.js\";\nimport type { RailwayProvider } from \"./provider.js\";\nimport type { RailwayService } from \"./service.js\";\n\n/** Build and deploy configuration for a Railway service. */\nexport interface RailwayDeployConfig {\n\t/** Build system: `\"RAILPACK\"`, `\"NIXPACKS\"`, or `\"DOCKERFILE\"`. */\n\tbuilder?: string;\n\n\t/** Shell command executed to start the service at runtime. */\n\tstartCommand?: string;\n\n\t/** Shell command executed before the main deploy (e.g. migrations). */\n\tpreDeployCommand?: string;\n}\n\n/** Args for RailwayDeploy. */\nexport interface RailwayDeployArgs {\n\t/** Absolute path to the monorepo root (working directory for `railway up`). */\n\tdirectory: string;\n\n\t/** SHA-256 hash of the app source directory, used as a deploy trigger. */\n\tsourceHash: string;\n\n\t/** Env var map used as deploy trigger. */\n\tenv: Record<string, pulumi.Input<string>>;\n\n\t/** Directories to exclude via `.railwayignore`. */\n\texcludePaths?: string[];\n\n\t/** Railpack configuration written to `railpack.json` before deploy. */\n\trailpackConfig?: Record<string, unknown>;\n}\n\n/** Options type for RailwayDeploy — replaces Pulumi's native `provider` field. */\ntype RailwayDeployOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Railway authentication context. */\n\tprovider: RailwayProvider;\n\n\t/** Railway project context. */\n\tproject: RailwayProject;\n\n\t/** Railway environment context. */\n\tenvironment: RailwayEnvironment;\n\n\t/** Railway service context. */\n\tservice: RailwayService;\n};\n\nconst LOCK_DIR = \"/tmp/.railway-upload-lock\";\n\n/**\n * Deploys a Railway service and waits for the build to complete.\n *\n * Uses `railway up --ci` which blocks until the build finishes.\n * Multiple deploys run in parallel — a mkdir lock serializes only the\n * brief upload phase (~5s) when `.railwayignore` must be consistent,\n * then releases so builds stream concurrently.\n *\n * @example\n * ```typescript\n * new RailwayDeploy(\"api-deploy\", {\n * directory: monorepoRoot,\n * sourceHash,\n * env: { DATABASE_URL: dbUrl },\n * }, { provider, project, environment, service });\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 { provider, project, environment, service, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:railway:Deploy\", name, {}, pulumiOpts);\n\n\t\tconst ignorePatterns = (args.excludePaths ?? [])\n\t\t\t.map((dir) => {\n\t\t\t\tif (dir.startsWith(\"apps/\")) {\n\t\t\t\t\treturn `${dir}/**\\\\n!${dir}/package.json`;\n\t\t\t\t}\n\n\t\t\t\treturn dir;\n\t\t\t})\n\t\t\t.join(\"\\\\n\");\n\n\t\tconst writeIgnore = ignorePatterns\n\t\t\t? `printf '${ignorePatterns}\\\\n' > .railwayignore`\n\t\t\t: \"\";\n\n\t\tconst writeRailpack = args.railpackConfig\n\t\t\t? `printf '${JSON.stringify(args.railpackConfig).replace(/'/g, \"\\\\'\")}' > railpack.json`\n\t\t\t: \"\";\n\n\t\tconst setupLines = [writeIgnore, writeRailpack].filter(Boolean).join(\"; \");\n\n\t\tconst envHash = pulumi\n\t\t\t.all(\n\t\t\t\tObject.entries(args.env)\n\t\t\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t\t\t.map(([k, v]) => pulumi.output(v).apply((val) => `${k}=${val}`)),\n\t\t\t)\n\t\t\t.apply((parts) => parts.join(\",\"));\n\n\t\t// Parallel-safe upload: multiple stacks deploy concurrently, but each writes\n\t\t// .railwayignore and railpack.json to the same monorepo root before calling\n\t\t// `railway up`. The mkdir lock serializes that brief window (~5s upload phase).\n\t\t// After upload, the background job releases the lock so builds stream in parallel.\n\t\t//\n\t\t// Flow: acquire lock → write config files → release lock after 5s (background) →\n\t\t// railway up --ci (blocks through upload, then streams build logs) →\n\t\t// cleanup on exit\n\t\tconst deployCmd = pulumi.interpolate`while ! mkdir ${LOCK_DIR} 2>/dev/null; do sleep 1; done; ${setupLines}; { sleep 5; rm -f .railwayignore railpack.json; rmdir ${LOCK_DIR} 2>/dev/null; } & railway up --ci --project ${project.id} --service ${service.id} --environment ${environment.id}; EXIT=$?; rm -f .railwayignore railpack.json; rmdir ${LOCK_DIR} 2>/dev/null; wait; exit $EXIT`;\n\n\t\tnew command.local.Command(\n\t\t\t`${name}-deploy`,\n\t\t\t{\n\t\t\t\tcreate: deployCmd,\n\t\t\t\ttriggers: [args.sourceHash, envHash],\n\t\t\t\tdir: args.directory,\n\t\t\t\tenvironment: {\n\t\t\t\t\tRAILWAY_TOKEN: project.projectToken,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;AAuDA,MAAM,WAAW;;;;;;;;;;;;;;;;;;AAmBjB,IAAa,gBAAb,cAAmC,OAAO,kBAAkB;CAC3D,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,SAAS,aAAa,SAAS,GAAG,eAAe;EAEnE,MAAM,6BAA6B,MAAM,CAAC,GAAG,UAAU;EAEvD,MAAM,kBAAkB,KAAK,gBAAgB,CAAC,GAC5C,KAAK,QAAQ;GACb,IAAI,IAAI,WAAW,OAAO,GACzB,OAAO,GAAG,IAAI,SAAS,IAAI;GAG5B,OAAO;EACR,CAAC,EACA,KAAK,KAAK;EAUZ,MAAM,aAAa,CARC,iBACjB,WAAW,eAAe,yBAC1B,IAEmB,KAAK,iBACxB,WAAW,KAAK,UAAU,KAAK,cAAc,EAAE,QAAQ,MAAM,KAAK,EAAE,qBACpE,EAE2C,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;EAEzE,MAAM,UAAU,OACd,IACA,OAAO,QAAQ,KAAK,GAAG,EACrB,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,EACrC,KAAK,CAAC,GAAG,OAAO,OAAO,OAAO,CAAC,EAAE,OAAO,QAAQ,GAAG,EAAE,GAAG,KAAK,CAAC,CACjE,EACC,OAAO,UAAU,MAAM,KAAK,GAAG,CAAC;EAUlC,MAAM,YAAY,OAAO,WAAW,iBAAiB,SAAS,kCAAkC,WAAW,yDAAyD,SAAS,8CAA8C,QAAQ,GAAG,aAAa,QAAQ,GAAG,iBAAiB,YAAY,GAAG,uDAAuD,SAAS;EAE9V,IAAI,QAAQ,MAAM,QACjB,GAAG,KAAK,UACR;GACC,QAAQ;GACR,UAAU,CAAC,KAAK,YAAY,OAAO;GACnC,KAAK,KAAK;GACV,aAAa,EACZ,eAAe,QAAQ,aACxB;EACD,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
1
+ {"version":3,"file":"deploy.mjs","names":[],"sources":["../../src/railway/deploy.ts"],"sourcesContent":["import * as command from \"@pulumi/command\";\nimport * as pulumi from \"@pulumi/pulumi\";\nimport type { RailwayEnvironment } from \"./environment.js\";\nimport type { RailwayProject } from \"./project.js\";\nimport type { RailwayProvider } from \"./provider.js\";\nimport type { RailwayService } from \"./service.js\";\n\n/** Build and deploy configuration for a Railway service. */\nexport interface RailwayDeployConfig {\n\t/** Build system: `\"RAILPACK\"`, `\"NIXPACKS\"`, or `\"DOCKERFILE\"`. */\n\tbuilder?: string;\n\n\t/** Shell command executed to start the service at runtime. */\n\tstartCommand?: string;\n\n\t/** Shell command executed before the main deploy (e.g. migrations). */\n\tpreDeployCommand?: string;\n}\n\n/** Args for RailwayDeploy. */\nexport interface RailwayDeployArgs {\n\t/** Absolute path to the monorepo root (working directory for `railway up`). */\n\tdirectory: string;\n\n\t/** Values that trigger a redeploy when changed (e.g. source hashes, env hashes). */\n\ttriggers: pulumi.Input<pulumi.Input<string>[]>;\n\n\t/** Directories to exclude via `.railwayignore`. */\n\texcludePaths?: string[];\n\n\t/** Railpack configuration written to `railpack.json` before deploy. */\n\trailpackConfig?: Record<string, unknown>;\n}\n\n/** Options type for RailwayDeploy — replaces Pulumi's native `provider` field. */\ntype RailwayDeployOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Railway authentication context. */\n\tprovider: RailwayProvider;\n\n\t/** Railway project context. */\n\tproject: RailwayProject;\n\n\t/** Railway environment context. */\n\tenvironment: RailwayEnvironment;\n\n\t/** Railway service context. */\n\tservice: RailwayService;\n};\n\nconst LOCK_DIR = \"/tmp/.railway-upload-lock\";\n\n/**\n * Deploys a Railway service and waits for the build to complete.\n *\n * Uses `railway up --ci` which blocks until the build finishes.\n * Multiple deploys run in parallel — a mkdir lock serializes only the\n * brief upload phase (~5s) when `.railwayignore` must be consistent,\n * then releases so builds stream concurrently.\n *\n * @example\n * ```typescript\n * new RailwayDeploy(\"api-deploy\", {\n * directory: monorepoRoot,\n * sourceHash,\n * env: { DATABASE_URL: dbUrl },\n * }, { provider, project, environment, service });\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 { provider, project, environment, service, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:railway:Deploy\", name, {}, pulumiOpts);\n\n\t\tconst ignorePatterns = (args.excludePaths ?? [])\n\t\t\t.map((dir) => {\n\t\t\t\tif (dir.startsWith(\"apps/\")) {\n\t\t\t\t\treturn `${dir}/**\\\\n!${dir}/package.json`;\n\t\t\t\t}\n\n\t\t\t\treturn dir;\n\t\t\t})\n\t\t\t.join(\"\\\\n\");\n\n\t\tconst writeIgnore = ignorePatterns\n\t\t\t? `printf '${ignorePatterns}\\\\n' > .railwayignore`\n\t\t\t: \"\";\n\n\t\tconst writeRailpack = args.railpackConfig\n\t\t\t? `printf '${JSON.stringify(args.railpackConfig).replace(/'/g, \"\\\\'\")}' > railpack.json`\n\t\t\t: \"\";\n\n\t\tconst setupLines = [writeIgnore, writeRailpack].filter(Boolean).join(\"; \");\n\n\t\tconst deployCmd = pulumi.interpolate`while ! mkdir ${LOCK_DIR} 2>/dev/null; do sleep 1; done; ${setupLines}; { sleep 5; rm -f .railwayignore railpack.json; rmdir ${LOCK_DIR} 2>/dev/null; } & railway up --ci --project ${project.id} --service ${service.id} --environment ${environment.id}; EXIT=$?; rm -f .railwayignore railpack.json; rmdir ${LOCK_DIR} 2>/dev/null; wait; exit $EXIT`;\n\n\t\tnew command.local.Command(\n\t\t\t`${name}-deploy`,\n\t\t\t{\n\t\t\t\tcreate: deployCmd,\n\t\t\t\ttriggers: args.triggers,\n\t\t\t\tdir: args.directory,\n\t\t\t\tenvironment: {\n\t\t\t\t\tRAILWAY_TOKEN: project.projectToken,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;AAoDA,MAAM,WAAW;;;;;;;;;;;;;;;;;;AAmBjB,IAAa,gBAAb,cAAmC,OAAO,kBAAkB;CAC3D,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,SAAS,aAAa,SAAS,GAAG,eAAe;EAEnE,MAAM,6BAA6B,MAAM,CAAC,GAAG,UAAU;EAEvD,MAAM,kBAAkB,KAAK,gBAAgB,CAAC,GAC5C,KAAK,QAAQ;GACb,IAAI,IAAI,WAAW,OAAO,GACzB,OAAO,GAAG,IAAI,SAAS,IAAI;GAG5B,OAAO;EACR,CAAC,EACA,KAAK,KAAK;EAUZ,MAAM,aAAa,CARC,iBACjB,WAAW,eAAe,yBAC1B,IAEmB,KAAK,iBACxB,WAAW,KAAK,UAAU,KAAK,cAAc,EAAE,QAAQ,MAAM,KAAK,EAAE,qBACpE,EAE2C,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;EAEzE,MAAM,YAAY,OAAO,WAAW,iBAAiB,SAAS,kCAAkC,WAAW,yDAAyD,SAAS,8CAA8C,QAAQ,GAAG,aAAa,QAAQ,GAAG,iBAAiB,YAAY,GAAG,uDAAuD,SAAS;EAE9V,IAAI,QAAQ,MAAM,QACjB,GAAG,KAAK,UACR;GACC,QAAQ;GACR,UAAU,KAAK;GACf,KAAK,KAAK;GACV,aAAa,EACZ,eAAe,QAAQ,aACxB;EACD,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
@@ -1,8 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_chunk = require('../chunk-BVYJZCqc.cjs');
3
- const require_hash = require('../hash.cjs');
4
- let node_path = require("node:path");
5
- node_path = require_chunk.__toESM(node_path, 1);
6
3
  let _pulumi_command = require("@pulumi/command");
7
4
  _pulumi_command = require_chunk.__toESM(_pulumi_command, 1);
8
5
  let _pulumi_pulumi = require("@pulumi/pulumi");
@@ -29,27 +26,20 @@ _pulumi_pulumi = require_chunk.__toESM(_pulumi_pulumi, 1);
29
26
  */
30
27
  var VercelDeploy = class extends _pulumi_pulumi.ComponentResource {
31
28
  constructor(name, args, opts) {
32
- const { provider, ...pulumiOpts } = opts;
29
+ const { provider, project, ...pulumiOpts } = opts;
33
30
  super("infracraft:vercel:Deploy", name, {}, pulumiOpts);
34
- const hashParts = [require_hash.hashDirectory(node_path.join(args.monorepoRoot, args.rootDirectory))];
35
- for (const dir of args.additionalSourceDirs ?? []) hashParts.push(require_hash.hashDirectory(node_path.join(args.monorepoRoot, dir)));
36
- const sourceHash = hashParts.join(",");
37
- const commandOpts = { parent: this };
38
- if (args.dependsOn && args.dependsOn.length > 0) commandOpts.dependsOn = args.dependsOn;
39
- const envHash = _pulumi_pulumi.all(Object.entries(args.env).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => _pulumi_pulumi.output(v).apply((val) => `${k}=${val}`))).apply((parts) => parts.join(","));
31
+ const projectId = project ? project.id : args.projectId;
32
+ if (!projectId) throw new Error("VercelDeploy: either `args.projectId` or `opts.project` must be provided");
40
33
  new _pulumi_command.local.Command(`${name}-deploy`, {
41
34
  create: "vercel deploy --prod --yes",
42
- triggers: [sourceHash, envHash],
35
+ triggers: args.triggers,
43
36
  dir: args.monorepoRoot,
44
37
  environment: {
45
38
  VERCEL_TOKEN: provider.token,
46
39
  VERCEL_ORG_ID: provider.teamId,
47
- VERCEL_PROJECT_ID: args.projectId
40
+ VERCEL_PROJECT_ID: projectId
48
41
  }
49
- }, {
50
- parent: this,
51
- ...commandOpts.dependsOn ? { dependsOn: commandOpts.dependsOn } : {}
52
- });
42
+ }, { parent: this });
53
43
  this.registerOutputs({});
54
44
  }
55
45
  };
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.cjs","names":["pulumi","hashDirectory","path","command"],"sources":["../../src/vercel/deploy.ts"],"sourcesContent":["import * as path from \"node:path\";\nimport * as command from \"@pulumi/command\";\nimport * as pulumi from \"@pulumi/pulumi\";\nimport { hashDirectory } from \"../hash.js\";\nimport type { VercelProvider } from \"./provider.js\";\n\n/** Options type for VercelDeploy — replaces Pulumi's native `provider` field. */\ntype VercelDeployOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Vercel authentication context. */\n\tprovider: VercelProvider;\n};\n\n/** Args for VercelDeploy. */\nexport interface VercelDeployArgs {\n\t/** Vercel project ID (Output from `vercel.Project`). */\n\tprojectId: pulumi.Input<string>;\n\n\t/** Relative path from monorepo root to the app directory (e.g. `\"apps/nexus\"`). */\n\trootDirectory: string;\n\n\t/** Absolute path to the monorepo root (working directory for `vercel deploy`). */\n\tmonorepoRoot: string;\n\n\t/** Env var map used as deploy trigger. Hashes both keys and resolved values so value changes trigger redeploy. */\n\tenv: Record<string, pulumi.Input<string>>;\n\n\t/** Additional directories (relative to monorepo root) to include in source hash. Changes in these trigger redeploy. */\n\tadditionalSourceDirs?: string[];\n\n\t/** Resources that must complete before the deploy runs. */\n\tdependsOn?: pulumi.Resource[];\n}\n\n/**\n * Deploys a Vercel project via `vercel deploy --prod --yes` CLI.\n *\n * Triggers on source hash (computed from the app directory) and env content hash\n * (from `VercelVariable.contentHash`). When an env value changes — whether from\n * code, a new mesh URL, or a drift fix after `pulumi refresh` — the hash changes\n * and a redeploy is triggered.\n *\n * @example\n * ```typescript\n * new VercelDeploy(\"nexus-deploy\", {\n * projectId: vercelProject.id,\n * rootDirectory: \"apps/nexus\",\n * monorepoRoot,\n * env: { NEXT_PUBLIC_API_URL: meshUrl },\n * }, { provider });\n * ```\n */\nexport class VercelDeploy extends pulumi.ComponentResource {\n\tconstructor(\n\t\tname: string,\n\t\targs: VercelDeployArgs,\n\t\topts: VercelDeployOptions,\n\t) {\n\t\tconst { provider, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:vercel:Deploy\", name, {}, pulumiOpts);\n\n\t\tconst appDir = path.join(args.monorepoRoot, args.rootDirectory);\n\n\t\tconst hashParts = [hashDirectory(appDir)];\n\n\t\tfor (const dir of args.additionalSourceDirs ?? []) {\n\t\t\thashParts.push(hashDirectory(path.join(args.monorepoRoot, dir)));\n\t\t}\n\n\t\tconst sourceHash = hashParts.join(\",\");\n\n\t\tconst commandOpts: pulumi.ResourceOptions = { parent: this };\n\n\t\tif (args.dependsOn && args.dependsOn.length > 0) {\n\t\t\tcommandOpts.dependsOn = args.dependsOn;\n\t\t}\n\n\t\tconst envHash = pulumi\n\t\t\t.all(\n\t\t\t\tObject.entries(args.env)\n\t\t\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t\t\t.map(([k, v]) => pulumi.output(v).apply((val) => `${k}=${val}`)),\n\t\t\t)\n\t\t\t.apply((parts) => parts.join(\",\"));\n\n\t\tnew command.local.Command(\n\t\t\t`${name}-deploy`,\n\t\t\t{\n\t\t\t\tcreate: \"vercel deploy --prod --yes\",\n\t\t\t\ttriggers: [sourceHash, envHash],\n\t\t\t\tdir: args.monorepoRoot,\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: args.projectId,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tparent: this,\n\t\t\t\t...(commandOpts.dependsOn ? { dependsOn: commandOpts.dependsOn } : {}),\n\t\t\t},\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,IAAa,eAAb,cAAkCA,eAAO,kBAAkB;CAC1D,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,GAAG,eAAe;EAEpC,MAAM,4BAA4B,MAAM,CAAC,GAAG,UAAU;EAItD,MAAM,YAAY,CAACC,2BAFJC,UAAK,KAAK,KAAK,cAAc,KAAK,aAEX,CAAC,CAAC;EAExC,KAAK,MAAM,OAAO,KAAK,wBAAwB,CAAC,GAC/C,UAAU,KAAKD,2BAAcC,UAAK,KAAK,KAAK,cAAc,GAAG,CAAC,CAAC;EAGhE,MAAM,aAAa,UAAU,KAAK,GAAG;EAErC,MAAM,cAAsC,EAAE,QAAQ,KAAK;EAE3D,IAAI,KAAK,aAAa,KAAK,UAAU,SAAS,GAC7C,YAAY,YAAY,KAAK;EAG9B,MAAM,UAAUF,eACd,IACA,OAAO,QAAQ,KAAK,GAAG,EACrB,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,EACrC,KAAK,CAAC,GAAG,OAAOA,eAAO,OAAO,CAAC,EAAE,OAAO,QAAQ,GAAG,EAAE,GAAG,KAAK,CAAC,CACjE,EACC,OAAO,UAAU,MAAM,KAAK,GAAG,CAAC;EAElC,IAAIG,gBAAQ,MAAM,QACjB,GAAG,KAAK,UACR;GACC,QAAQ;GACR,UAAU,CAAC,YAAY,OAAO;GAC9B,KAAK,KAAK;GACV,aAAa;IACZ,cAAc,SAAS;IACvB,eAAe,SAAS;IACxB,mBAAmB,KAAK;GACzB;EACD,GACA;GACC,QAAQ;GACR,GAAI,YAAY,YAAY,EAAE,WAAW,YAAY,UAAU,IAAI,CAAC;EACrE,CACD;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
1
+ {"version":3,"file":"deploy.cjs","names":["pulumi","command"],"sources":["../../src/vercel/deploy.ts"],"sourcesContent":["import * as command from \"@pulumi/command\";\nimport * as pulumi from \"@pulumi/pulumi\";\nimport type { VercelProject } from \"./project.js\";\nimport type { VercelProvider } from \"./provider.js\";\n\n/** Options type for VercelDeploy — replaces Pulumi's native `provider` field. */\ntype VercelDeployOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Vercel authentication context. */\n\tprovider: VercelProvider;\n\n\t/**\n\t * VercelProject resource to source the project ID from.\n\t * When provided, `args.projectId` is optional and ignored if both are given.\n\t */\n\tproject?: VercelProject;\n};\n\n/** Args for VercelDeploy. */\nexport interface VercelDeployArgs {\n\t/**\n\t * Vercel project ID.\n\t * Required when `opts.project` is not provided.\n\t */\n\tprojectId?: pulumi.Input<string>;\n\n\t/** Absolute path to the monorepo root (working directory for `vercel deploy`). */\n\tmonorepoRoot: string;\n\n\t/** Values that trigger a redeploy when changed (e.g. source hashes, env hashes). */\n\ttriggers: pulumi.Input<pulumi.Input<string>[]>;\n}\n\n/**\n * Deploys a Vercel project via `vercel deploy --prod --yes` CLI.\n *\n * Triggers on source hash (computed from the app directory) and env content hash\n * (from `VercelVariable.contentHash`). When an env value changes — whether from\n * code, a new mesh URL, or a drift fix after `pulumi refresh` — the hash changes\n * and a redeploy is triggered.\n *\n * @example\n * ```typescript\n * new VercelDeploy(\"nexus-deploy\", {\n * projectId: vercelProject.id,\n * rootDirectory: \"apps/nexus\",\n * monorepoRoot,\n * env: { NEXT_PUBLIC_API_URL: meshUrl },\n * }, { provider });\n * ```\n */\nexport class VercelDeploy extends pulumi.ComponentResource {\n\tconstructor(\n\t\tname: string,\n\t\targs: VercelDeployArgs,\n\t\topts: VercelDeployOptions,\n\t) {\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\tnew command.local.Command(\n\t\t\t`${name}-deploy`,\n\t\t\t{\n\t\t\t\tcreate: \"vercel deploy --prod --yes\",\n\t\t\t\ttriggers: args.triggers,\n\t\t\t\tdir: args.monorepoRoot,\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 },\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAqDA,IAAa,eAAb,cAAkCA,eAAO,kBAAkB;CAC1D,YACC,MACA,MACA,MACC;EACD,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,IAAIC,gBAAQ,MAAM,QACjB,GAAG,KAAK,UACR;GACC,QAAQ;GACR,UAAU,KAAK;GACf,KAAK,KAAK;GACV,aAAa;IACZ,cAAc,SAAS;IACvB,eAAe,SAAS;IACxB,mBAAmB;GACpB;EACD,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
@@ -1,26 +1,29 @@
1
1
  import { t as __name } from "../chunk-OPjESj5l.cjs";
2
2
  import { VercelProvider } from "./provider.cjs";
3
+ import { VercelProject } from "./project.cjs";
3
4
  import * as pulumi from "@pulumi/pulumi";
4
5
 
5
6
  //#region src/vercel/deploy.d.ts
6
7
  /** Options type for VercelDeploy — replaces Pulumi's native `provider` field. */
7
8
  type VercelDeployOptions = Omit<pulumi.ComponentResourceOptions, "provider"> & {
8
9
  /** Vercel authentication context. */provider: VercelProvider;
10
+ /**
11
+ * VercelProject resource to source the project ID from.
12
+ * When provided, `args.projectId` is optional and ignored if both are given.
13
+ */
14
+ project?: VercelProject;
9
15
  };
10
16
  /** Args for VercelDeploy. */
11
17
  interface VercelDeployArgs {
12
- /** Vercel project ID (Output from `vercel.Project`). */
13
- projectId: pulumi.Input<string>;
14
- /** Relative path from monorepo root to the app directory (e.g. `"apps/nexus"`). */
15
- rootDirectory: string;
18
+ /**
19
+ * Vercel project ID.
20
+ * Required when `opts.project` is not provided.
21
+ */
22
+ projectId?: pulumi.Input<string>;
16
23
  /** Absolute path to the monorepo root (working directory for `vercel deploy`). */
17
24
  monorepoRoot: string;
18
- /** Env var map used as deploy trigger. Hashes both keys and resolved values so value changes trigger redeploy. */
19
- env: Record<string, pulumi.Input<string>>;
20
- /** Additional directories (relative to monorepo root) to include in source hash. Changes in these trigger redeploy. */
21
- additionalSourceDirs?: string[];
22
- /** Resources that must complete before the deploy runs. */
23
- dependsOn?: pulumi.Resource[];
25
+ /** Values that trigger a redeploy when changed (e.g. source hashes, env hashes). */
26
+ triggers: pulumi.Input<pulumi.Input<string>[]>;
24
27
  }
25
28
  /**
26
29
  * Deploys a Vercel project via `vercel deploy --prod --yes` CLI.
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.cts","names":[],"sources":["../../src/vercel/deploy.ts"],"mappings":";;;;;;KAOK,mBAAA,GAAsB,IAAA,CAC1B,MAAA,CAAO,wBAAA;uCAIP,QAAA,EAAU,cAAA;AAAA;;UAIM,gBAAA;EATU;EAW1B,SAAA,EAAW,MAAA,CAAO,KAAA;EANM;EASxB,aAAA;EAd0B;EAiB1B,YAAA;EAhBO;EAmBP,GAAA,EAAK,MAAA,SAAe,MAAA,CAAO,KAAA;EAfjB;EAkBV,oBAAA;EAlBwB;EAqBxB,SAAA,GAAY,MAAA,CAAO,QAAA;AAAA;;;;;;;;;;;;;;;;;;;cAqBP,YAAA,SAAqB,MAAA,CAAO,iBAAA;cAEvC,IAAA,UACA,IAAA,EAAM,gBAAA,EACN,IAAA,EAAM,mBAAA;AAAA"}
1
+ {"version":3,"file":"deploy.d.cts","names":[],"sources":["../../src/vercel/deploy.ts"],"mappings":";;;;;;;KAMK,mBAAA,GAAsB,IAAA,CAC1B,MAAA,CAAO,wBAAA;uCAIP,QAAA,EAAU,cAAA;EALa;;;;EAWvB,OAAA,GAAU,aAAA;AAAA;;UAIM,gBAAA;EAfU;;;;EAoB1B,SAAA,GAAY,MAAA,CAAO,KAAA;EATnB;EAYA,YAAA;EAZuB;EAevB,QAAA,EAAU,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,KAAA;AAAA;;;;;;;;;;;;;;;;;;AAAK;cAqBvB,YAAA,SAAqB,MAAA,CAAO,iBAAA;cAEvC,IAAA,UACA,IAAA,EAAM,gBAAA,EACN,IAAA,EAAM,mBAAA;AAAA"}
@@ -1,26 +1,29 @@
1
1
  import { t as __name } from "../chunk-OPjESj5l.mjs";
2
2
  import { VercelProvider } from "./provider.mjs";
3
+ import { VercelProject } from "./project.mjs";
3
4
  import * as pulumi from "@pulumi/pulumi";
4
5
 
5
6
  //#region src/vercel/deploy.d.ts
6
7
  /** Options type for VercelDeploy — replaces Pulumi's native `provider` field. */
7
8
  type VercelDeployOptions = Omit<pulumi.ComponentResourceOptions, "provider"> & {
8
9
  /** Vercel authentication context. */provider: VercelProvider;
10
+ /**
11
+ * VercelProject resource to source the project ID from.
12
+ * When provided, `args.projectId` is optional and ignored if both are given.
13
+ */
14
+ project?: VercelProject;
9
15
  };
10
16
  /** Args for VercelDeploy. */
11
17
  interface VercelDeployArgs {
12
- /** Vercel project ID (Output from `vercel.Project`). */
13
- projectId: pulumi.Input<string>;
14
- /** Relative path from monorepo root to the app directory (e.g. `"apps/nexus"`). */
15
- rootDirectory: string;
18
+ /**
19
+ * Vercel project ID.
20
+ * Required when `opts.project` is not provided.
21
+ */
22
+ projectId?: pulumi.Input<string>;
16
23
  /** Absolute path to the monorepo root (working directory for `vercel deploy`). */
17
24
  monorepoRoot: string;
18
- /** Env var map used as deploy trigger. Hashes both keys and resolved values so value changes trigger redeploy. */
19
- env: Record<string, pulumi.Input<string>>;
20
- /** Additional directories (relative to monorepo root) to include in source hash. Changes in these trigger redeploy. */
21
- additionalSourceDirs?: string[];
22
- /** Resources that must complete before the deploy runs. */
23
- dependsOn?: pulumi.Resource[];
25
+ /** Values that trigger a redeploy when changed (e.g. source hashes, env hashes). */
26
+ triggers: pulumi.Input<pulumi.Input<string>[]>;
24
27
  }
25
28
  /**
26
29
  * Deploys a Vercel project via `vercel deploy --prod --yes` CLI.
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.mts","names":[],"sources":["../../src/vercel/deploy.ts"],"mappings":";;;;;;KAOK,mBAAA,GAAsB,IAAA,CAC1B,MAAA,CAAO,wBAAA;uCAIP,QAAA,EAAU,cAAA;AAAA;;UAIM,gBAAA;EATU;EAW1B,SAAA,EAAW,MAAA,CAAO,KAAA;EANM;EASxB,aAAA;EAd0B;EAiB1B,YAAA;EAhBO;EAmBP,GAAA,EAAK,MAAA,SAAe,MAAA,CAAO,KAAA;EAfjB;EAkBV,oBAAA;EAlBwB;EAqBxB,SAAA,GAAY,MAAA,CAAO,QAAA;AAAA;;;;;;;;;;;;;;;;;;;cAqBP,YAAA,SAAqB,MAAA,CAAO,iBAAA;cAEvC,IAAA,UACA,IAAA,EAAM,gBAAA,EACN,IAAA,EAAM,mBAAA;AAAA"}
1
+ {"version":3,"file":"deploy.d.mts","names":[],"sources":["../../src/vercel/deploy.ts"],"mappings":";;;;;;;KAMK,mBAAA,GAAsB,IAAA,CAC1B,MAAA,CAAO,wBAAA;uCAIP,QAAA,EAAU,cAAA;EALa;;;;EAWvB,OAAA,GAAU,aAAA;AAAA;;UAIM,gBAAA;EAfU;;;;EAoB1B,SAAA,GAAY,MAAA,CAAO,KAAA;EATnB;EAYA,YAAA;EAZuB;EAevB,QAAA,EAAU,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,KAAA;AAAA;;;;;;;;;;;;;;;;;;AAAK;cAqBvB,YAAA,SAAqB,MAAA,CAAO,iBAAA;cAEvC,IAAA,UACA,IAAA,EAAM,gBAAA,EACN,IAAA,EAAM,mBAAA;AAAA"}
@@ -1,6 +1,4 @@
1
1
  import { t as __name } from "../chunk-OPjESj5l.mjs";
2
- import { hashDirectory } from "../hash.mjs";
3
- import * as path from "node:path";
4
2
  import * as command from "@pulumi/command";
5
3
  import * as pulumi from "@pulumi/pulumi";
6
4
 
@@ -25,27 +23,20 @@ import * as pulumi from "@pulumi/pulumi";
25
23
  */
26
24
  var VercelDeploy = class extends pulumi.ComponentResource {
27
25
  constructor(name, args, opts) {
28
- const { provider, ...pulumiOpts } = opts;
26
+ const { provider, project, ...pulumiOpts } = opts;
29
27
  super("infracraft:vercel:Deploy", name, {}, pulumiOpts);
30
- const hashParts = [hashDirectory(path.join(args.monorepoRoot, args.rootDirectory))];
31
- for (const dir of args.additionalSourceDirs ?? []) hashParts.push(hashDirectory(path.join(args.monorepoRoot, dir)));
32
- const sourceHash = hashParts.join(",");
33
- const commandOpts = { parent: this };
34
- if (args.dependsOn && args.dependsOn.length > 0) commandOpts.dependsOn = args.dependsOn;
35
- const envHash = pulumi.all(Object.entries(args.env).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => pulumi.output(v).apply((val) => `${k}=${val}`))).apply((parts) => parts.join(","));
28
+ const projectId = project ? project.id : args.projectId;
29
+ if (!projectId) throw new Error("VercelDeploy: either `args.projectId` or `opts.project` must be provided");
36
30
  new command.local.Command(`${name}-deploy`, {
37
31
  create: "vercel deploy --prod --yes",
38
- triggers: [sourceHash, envHash],
32
+ triggers: args.triggers,
39
33
  dir: args.monorepoRoot,
40
34
  environment: {
41
35
  VERCEL_TOKEN: provider.token,
42
36
  VERCEL_ORG_ID: provider.teamId,
43
- VERCEL_PROJECT_ID: args.projectId
37
+ VERCEL_PROJECT_ID: projectId
44
38
  }
45
- }, {
46
- parent: this,
47
- ...commandOpts.dependsOn ? { dependsOn: commandOpts.dependsOn } : {}
48
- });
39
+ }, { parent: this });
49
40
  this.registerOutputs({});
50
41
  }
51
42
  };
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.mjs","names":[],"sources":["../../src/vercel/deploy.ts"],"sourcesContent":["import * as path from \"node:path\";\nimport * as command from \"@pulumi/command\";\nimport * as pulumi from \"@pulumi/pulumi\";\nimport { hashDirectory } from \"../hash.js\";\nimport type { VercelProvider } from \"./provider.js\";\n\n/** Options type for VercelDeploy — replaces Pulumi's native `provider` field. */\ntype VercelDeployOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Vercel authentication context. */\n\tprovider: VercelProvider;\n};\n\n/** Args for VercelDeploy. */\nexport interface VercelDeployArgs {\n\t/** Vercel project ID (Output from `vercel.Project`). */\n\tprojectId: pulumi.Input<string>;\n\n\t/** Relative path from monorepo root to the app directory (e.g. `\"apps/nexus\"`). */\n\trootDirectory: string;\n\n\t/** Absolute path to the monorepo root (working directory for `vercel deploy`). */\n\tmonorepoRoot: string;\n\n\t/** Env var map used as deploy trigger. Hashes both keys and resolved values so value changes trigger redeploy. */\n\tenv: Record<string, pulumi.Input<string>>;\n\n\t/** Additional directories (relative to monorepo root) to include in source hash. Changes in these trigger redeploy. */\n\tadditionalSourceDirs?: string[];\n\n\t/** Resources that must complete before the deploy runs. */\n\tdependsOn?: pulumi.Resource[];\n}\n\n/**\n * Deploys a Vercel project via `vercel deploy --prod --yes` CLI.\n *\n * Triggers on source hash (computed from the app directory) and env content hash\n * (from `VercelVariable.contentHash`). When an env value changes — whether from\n * code, a new mesh URL, or a drift fix after `pulumi refresh` — the hash changes\n * and a redeploy is triggered.\n *\n * @example\n * ```typescript\n * new VercelDeploy(\"nexus-deploy\", {\n * projectId: vercelProject.id,\n * rootDirectory: \"apps/nexus\",\n * monorepoRoot,\n * env: { NEXT_PUBLIC_API_URL: meshUrl },\n * }, { provider });\n * ```\n */\nexport class VercelDeploy extends pulumi.ComponentResource {\n\tconstructor(\n\t\tname: string,\n\t\targs: VercelDeployArgs,\n\t\topts: VercelDeployOptions,\n\t) {\n\t\tconst { provider, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:vercel:Deploy\", name, {}, pulumiOpts);\n\n\t\tconst appDir = path.join(args.monorepoRoot, args.rootDirectory);\n\n\t\tconst hashParts = [hashDirectory(appDir)];\n\n\t\tfor (const dir of args.additionalSourceDirs ?? []) {\n\t\t\thashParts.push(hashDirectory(path.join(args.monorepoRoot, dir)));\n\t\t}\n\n\t\tconst sourceHash = hashParts.join(\",\");\n\n\t\tconst commandOpts: pulumi.ResourceOptions = { parent: this };\n\n\t\tif (args.dependsOn && args.dependsOn.length > 0) {\n\t\t\tcommandOpts.dependsOn = args.dependsOn;\n\t\t}\n\n\t\tconst envHash = pulumi\n\t\t\t.all(\n\t\t\t\tObject.entries(args.env)\n\t\t\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t\t\t.map(([k, v]) => pulumi.output(v).apply((val) => `${k}=${val}`)),\n\t\t\t)\n\t\t\t.apply((parts) => parts.join(\",\"));\n\n\t\tnew command.local.Command(\n\t\t\t`${name}-deploy`,\n\t\t\t{\n\t\t\t\tcreate: \"vercel deploy --prod --yes\",\n\t\t\t\ttriggers: [sourceHash, envHash],\n\t\t\t\tdir: args.monorepoRoot,\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: args.projectId,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tparent: this,\n\t\t\t\t...(commandOpts.dependsOn ? { dependsOn: commandOpts.dependsOn } : {}),\n\t\t\t},\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,IAAa,eAAb,cAAkC,OAAO,kBAAkB;CAC1D,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,GAAG,eAAe;EAEpC,MAAM,4BAA4B,MAAM,CAAC,GAAG,UAAU;EAItD,MAAM,YAAY,CAAC,cAFJ,KAAK,KAAK,KAAK,cAAc,KAAK,aAEX,CAAC,CAAC;EAExC,KAAK,MAAM,OAAO,KAAK,wBAAwB,CAAC,GAC/C,UAAU,KAAK,cAAc,KAAK,KAAK,KAAK,cAAc,GAAG,CAAC,CAAC;EAGhE,MAAM,aAAa,UAAU,KAAK,GAAG;EAErC,MAAM,cAAsC,EAAE,QAAQ,KAAK;EAE3D,IAAI,KAAK,aAAa,KAAK,UAAU,SAAS,GAC7C,YAAY,YAAY,KAAK;EAG9B,MAAM,UAAU,OACd,IACA,OAAO,QAAQ,KAAK,GAAG,EACrB,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,EACrC,KAAK,CAAC,GAAG,OAAO,OAAO,OAAO,CAAC,EAAE,OAAO,QAAQ,GAAG,EAAE,GAAG,KAAK,CAAC,CACjE,EACC,OAAO,UAAU,MAAM,KAAK,GAAG,CAAC;EAElC,IAAI,QAAQ,MAAM,QACjB,GAAG,KAAK,UACR;GACC,QAAQ;GACR,UAAU,CAAC,YAAY,OAAO;GAC9B,KAAK,KAAK;GACV,aAAa;IACZ,cAAc,SAAS;IACvB,eAAe,SAAS;IACxB,mBAAmB,KAAK;GACzB;EACD,GACA;GACC,QAAQ;GACR,GAAI,YAAY,YAAY,EAAE,WAAW,YAAY,UAAU,IAAI,CAAC;EACrE,CACD;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
1
+ {"version":3,"file":"deploy.mjs","names":[],"sources":["../../src/vercel/deploy.ts"],"sourcesContent":["import * as command from \"@pulumi/command\";\nimport * as pulumi from \"@pulumi/pulumi\";\nimport type { VercelProject } from \"./project.js\";\nimport type { VercelProvider } from \"./provider.js\";\n\n/** Options type for VercelDeploy — replaces Pulumi's native `provider` field. */\ntype VercelDeployOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Vercel authentication context. */\n\tprovider: VercelProvider;\n\n\t/**\n\t * VercelProject resource to source the project ID from.\n\t * When provided, `args.projectId` is optional and ignored if both are given.\n\t */\n\tproject?: VercelProject;\n};\n\n/** Args for VercelDeploy. */\nexport interface VercelDeployArgs {\n\t/**\n\t * Vercel project ID.\n\t * Required when `opts.project` is not provided.\n\t */\n\tprojectId?: pulumi.Input<string>;\n\n\t/** Absolute path to the monorepo root (working directory for `vercel deploy`). */\n\tmonorepoRoot: string;\n\n\t/** Values that trigger a redeploy when changed (e.g. source hashes, env hashes). */\n\ttriggers: pulumi.Input<pulumi.Input<string>[]>;\n}\n\n/**\n * Deploys a Vercel project via `vercel deploy --prod --yes` CLI.\n *\n * Triggers on source hash (computed from the app directory) and env content hash\n * (from `VercelVariable.contentHash`). When an env value changes — whether from\n * code, a new mesh URL, or a drift fix after `pulumi refresh` — the hash changes\n * and a redeploy is triggered.\n *\n * @example\n * ```typescript\n * new VercelDeploy(\"nexus-deploy\", {\n * projectId: vercelProject.id,\n * rootDirectory: \"apps/nexus\",\n * monorepoRoot,\n * env: { NEXT_PUBLIC_API_URL: meshUrl },\n * }, { provider });\n * ```\n */\nexport class VercelDeploy extends pulumi.ComponentResource {\n\tconstructor(\n\t\tname: string,\n\t\targs: VercelDeployArgs,\n\t\topts: VercelDeployOptions,\n\t) {\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\tnew command.local.Command(\n\t\t\t`${name}-deploy`,\n\t\t\t{\n\t\t\t\tcreate: \"vercel deploy --prod --yes\",\n\t\t\t\ttriggers: args.triggers,\n\t\t\t\tdir: args.monorepoRoot,\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 },\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAqDA,IAAa,eAAb,cAAkC,OAAO,kBAAkB;CAC1D,YACC,MACA,MACA,MACC;EACD,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,IAAI,QAAQ,MAAM,QACjB,GAAG,KAAK,UACR;GACC,QAAQ;GACR,UAAU,KAAK;GACf,KAAK,KAAK;GACV,aAAa;IACZ,cAAc,SAAS;IACvB,eAAe,SAAS;IACxB,mBAAmB;GACpB;EACD,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
@@ -1,8 +1,10 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_vercel_deploy = require('./deploy.cjs');
3
3
  const require_vercel_provider = require('./provider.cjs');
4
+ const require_vercel_project = require('./project.cjs');
4
5
  const require_vercel_variable = require('./variable.cjs');
5
6
 
6
7
  exports.VercelDeploy = require_vercel_deploy.VercelDeploy;
8
+ exports.VercelProject = require_vercel_project.VercelProject;
7
9
  exports.VercelProvider = require_vercel_provider.VercelProvider;
8
10
  exports.VercelVariable = require_vercel_variable.VercelVariable;
@@ -1,4 +1,5 @@
1
1
  import { VercelProvider } from "./provider.cjs";
2
+ import { VercelProject, VercelProjectArgs } from "./project.cjs";
2
3
  import { VercelDeploy, VercelDeployArgs } from "./deploy.cjs";
3
4
  import { VercelVariable, VercelVariableArgs } from "./variable.cjs";
4
- export { VercelDeploy, type VercelDeployArgs, VercelProvider, VercelVariable, type VercelVariableArgs };
5
+ export { VercelDeploy, type VercelDeployArgs, VercelProject, type VercelProjectArgs, VercelProvider, VercelVariable, type VercelVariableArgs };
@@ -1,4 +1,5 @@
1
1
  import { VercelProvider } from "./provider.mjs";
2
+ import { VercelProject, VercelProjectArgs } from "./project.mjs";
2
3
  import { VercelDeploy, VercelDeployArgs } from "./deploy.mjs";
3
4
  import { VercelVariable, VercelVariableArgs } from "./variable.mjs";
4
- export { VercelDeploy, type VercelDeployArgs, VercelProvider, VercelVariable, type VercelVariableArgs };
5
+ export { VercelDeploy, type VercelDeployArgs, VercelProject, type VercelProjectArgs, VercelProvider, VercelVariable, type VercelVariableArgs };
@@ -1,5 +1,6 @@
1
1
  import { VercelDeploy } from "./deploy.mjs";
2
2
  import { VercelProvider } from "./provider.mjs";
3
+ import { VercelProject } from "./project.mjs";
3
4
  import { VercelVariable } from "./variable.mjs";
4
5
 
5
- export { VercelDeploy, VercelProvider, VercelVariable };
6
+ export { VercelDeploy, VercelProject, VercelProvider, VercelVariable };
@@ -0,0 +1,162 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_chunk = require('../chunk-BVYJZCqc.cjs');
3
+ let _pulumi_pulumi = require("@pulumi/pulumi");
4
+ _pulumi_pulumi = require_chunk.__toESM(_pulumi_pulumi, 1);
5
+
6
+ //#region src/vercel/project.ts
7
+ const VERCEL_API_URL = "https://api.vercel.com";
8
+ /**
9
+ * Fetches a Vercel project by name or ID.
10
+ * Returns `null` if the project is not found (404).
11
+ */
12
+ async function fetchProject(token, teamId, idOrName) {
13
+ const response = await fetch(`${VERCEL_API_URL}/v9/projects/${encodeURIComponent(idOrName)}?teamId=${teamId}`, { headers: { Authorization: `Bearer ${token}` } });
14
+ if (response.status === 404) return null;
15
+ if (!response.ok) throw new Error(`Vercel API error fetching project "${idOrName}" (${response.status}): ${await response.text()}`);
16
+ return await response.json();
17
+ }
18
+ /**
19
+ * Builds the project body for create / update calls.
20
+ * Only includes defined optional fields.
21
+ */
22
+ function buildProjectBody(inputs) {
23
+ const body = { name: inputs.name };
24
+ if (inputs.framework !== void 0) body.framework = inputs.framework;
25
+ if (inputs.rootDirectory !== void 0) body.rootDirectory = inputs.rootDirectory;
26
+ if (inputs.buildCommand !== void 0) body.buildCommand = inputs.buildCommand;
27
+ if (inputs.installCommand !== void 0) body.installCommand = inputs.installCommand;
28
+ if (inputs.outputDirectory !== void 0) body.outputDirectory = inputs.outputDirectory;
29
+ return body;
30
+ }
31
+ /**
32
+ * Dynamic provider implementing adopt-or-create for Vercel projects.
33
+ *
34
+ * On `create()`, calls `GET /v9/projects/{name}?teamId=…`. If found, adopts
35
+ * the existing project. If 404, creates a new one via `POST /v9/projects`.
36
+ * Deletion is a no-op to protect production projects.
37
+ */
38
+ var VercelProjectResourceProvider = class {
39
+ async create(inputs) {
40
+ const existing = await fetchProject(inputs.token, inputs.teamId, inputs.name);
41
+ let projectId;
42
+ if (existing) {
43
+ _pulumi_pulumi.log.info(`Adopting existing Vercel project "${inputs.name}" (${existing.id})`);
44
+ projectId = existing.id;
45
+ } else {
46
+ _pulumi_pulumi.log.info(`Vercel project "${inputs.name}" not found — creating...`);
47
+ const response = await fetch(`${VERCEL_API_URL}/v9/projects?teamId=${inputs.teamId}`, {
48
+ method: "POST",
49
+ headers: {
50
+ Authorization: `Bearer ${inputs.token}`,
51
+ "Content-Type": "application/json"
52
+ },
53
+ body: JSON.stringify(buildProjectBody(inputs))
54
+ });
55
+ if (!response.ok) throw new Error(`Vercel API error creating project "${inputs.name}" (${response.status}): ${await response.text()}`);
56
+ projectId = (await response.json()).id;
57
+ }
58
+ const outs = {
59
+ ...inputs,
60
+ projectId
61
+ };
62
+ return {
63
+ id: projectId,
64
+ outs
65
+ };
66
+ }
67
+ async read(id, props) {
68
+ const project = await fetchProject(props.token, props.teamId, id);
69
+ if (!project) throw new Error(`Vercel project "${id}" not found during refresh`);
70
+ return {
71
+ id: project.id,
72
+ props: {
73
+ ...props,
74
+ name: project.name,
75
+ projectId: project.id
76
+ }
77
+ };
78
+ }
79
+ async update(id, _olds, news) {
80
+ const response = await fetch(`${VERCEL_API_URL}/v9/projects/${id}?teamId=${news.teamId}`, {
81
+ method: "PATCH",
82
+ headers: {
83
+ Authorization: `Bearer ${news.token}`,
84
+ "Content-Type": "application/json"
85
+ },
86
+ body: JSON.stringify(buildProjectBody(news))
87
+ });
88
+ if (!response.ok) throw new Error(`Vercel API error updating project "${id}" (${response.status}): ${await response.text()}`);
89
+ return { outs: {
90
+ ...news,
91
+ projectId: id
92
+ } };
93
+ }
94
+ async delete() {
95
+ _pulumi_pulumi.log.warn("Vercel project deletion skipped — projects are not deleted by Pulumi");
96
+ }
97
+ async diff(_id, olds, news) {
98
+ const replaces = [];
99
+ const changes = [];
100
+ if (olds.teamId !== news.teamId) replaces.push("teamId");
101
+ for (const field of [
102
+ "name",
103
+ "framework",
104
+ "rootDirectory",
105
+ "buildCommand",
106
+ "installCommand",
107
+ "outputDirectory"
108
+ ]) if (olds[field] !== news[field]) changes.push(field);
109
+ return {
110
+ changes: replaces.length > 0 || changes.length > 0,
111
+ replaces,
112
+ deleteBeforeReplace: true
113
+ };
114
+ }
115
+ };
116
+ /** Internal dynamic resource — not part of the public API. */
117
+ var VercelProjectResource = class extends _pulumi_pulumi.dynamic.Resource {
118
+ constructor(name, args, opts) {
119
+ super(new VercelProjectResourceProvider(), name, {
120
+ ...args,
121
+ projectId: void 0
122
+ }, opts);
123
+ }
124
+ };
125
+ /**
126
+ * Manages a Vercel project with adopt-or-create semantics.
127
+ *
128
+ * On first `pulumi up`, looks up the project by name. If it already exists,
129
+ * the resource adopts it. If not, a new project is created. Deletion is a
130
+ * no-op to protect production projects.
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * const project = new VercelProject("nexus", {
135
+ * name: "nexus",
136
+ * framework: "nextjs",
137
+ * rootDirectory: "apps/nexus",
138
+ * }, { provider });
139
+ *
140
+ * new VercelVariable("nexus-vars", {
141
+ * projectId: project.id,
142
+ * variables: { NEXT_PUBLIC_API_URL: meshUrl },
143
+ * }, { provider });
144
+ * ```
145
+ */
146
+ var VercelProject = class extends _pulumi_pulumi.ComponentResource {
147
+ constructor(name, args, opts) {
148
+ const { provider, ...pulumiOpts } = opts;
149
+ super("infracraft:vercel:Project", name, {}, pulumiOpts);
150
+ const resource = new VercelProjectResource(`${name}-resource`, {
151
+ token: provider.token,
152
+ teamId: provider.teamId,
153
+ ...args
154
+ }, { parent: this });
155
+ this.id = resource.projectId;
156
+ this.registerOutputs({ id: this.id });
157
+ }
158
+ };
159
+
160
+ //#endregion
161
+ exports.VercelProject = VercelProject;
162
+ //# sourceMappingURL=project.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.cjs","names":["pulumi"],"sources":["../../src/vercel/project.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport type { VercelProvider } from \"./provider.js\";\n\nconst VERCEL_API_URL = \"https://api.vercel.com\";\n\n/** Resolved inputs for the Vercel project dynamic provider. */\nexport interface VercelProjectInputs {\n\t/** Vercel API bearer token. */\n\ttoken: string;\n\n\t/** Vercel team/org ID. */\n\tteamId: string;\n\n\t/** Project name. */\n\tname: string;\n\n\t/** Framework preset (e.g. `\"nextjs\"`, `\"remix\"`). */\n\tframework?: string;\n\n\t/** Relative path to the project root within a monorepo (e.g. `\"apps/nexus\"`). */\n\trootDirectory?: string;\n\n\t/** Custom build command. */\n\tbuildCommand?: string;\n\n\t/** Custom install command. */\n\tinstallCommand?: string;\n\n\t/** Custom output directory. */\n\toutputDirectory?: string;\n}\n\n/** Persisted state for the Vercel project. */\ninterface VercelProjectOutputs extends VercelProjectInputs {\n\t/** Vercel-assigned project ID. */\n\tprojectId: string;\n}\n\n/** Vercel API response shape for a project. */\ninterface VercelProjectResponse {\n\tid: string;\n\tname: string;\n}\n\n/**\n * Fetches a Vercel project by name or ID.\n * Returns `null` if the project is not found (404).\n */\nasync function fetchProject(\n\ttoken: string,\n\tteamId: string,\n\tidOrName: string,\n): Promise<VercelProjectResponse | null> {\n\tconst response = await fetch(\n\t\t`${VERCEL_API_URL}/v9/projects/${encodeURIComponent(idOrName)}?teamId=${teamId}`,\n\t\t{ headers: { Authorization: `Bearer ${token}` } },\n\t);\n\n\tif (response.status === 404) {\n\t\treturn null;\n\t}\n\n\tif (!response.ok) {\n\t\tthrow new Error(\n\t\t\t`Vercel API error fetching project \"${idOrName}\" (${response.status}): ${await response.text()}`,\n\t\t);\n\t}\n\n\treturn (await response.json()) as VercelProjectResponse;\n}\n\n/**\n * Builds the project body for create / update calls.\n * Only includes defined optional fields.\n */\nfunction buildProjectBody(\n\tinputs: Omit<VercelProjectInputs, \"token\" | \"teamId\">,\n): Record<string, string> {\n\tconst body: Record<string, string> = { name: inputs.name };\n\n\tif (inputs.framework !== undefined) body.framework = inputs.framework;\n\tif (inputs.rootDirectory !== undefined)\n\t\tbody.rootDirectory = inputs.rootDirectory;\n\tif (inputs.buildCommand !== undefined) body.buildCommand = inputs.buildCommand;\n\tif (inputs.installCommand !== undefined)\n\t\tbody.installCommand = inputs.installCommand;\n\tif (inputs.outputDirectory !== undefined)\n\t\tbody.outputDirectory = inputs.outputDirectory;\n\n\treturn body;\n}\n\n/**\n * Dynamic provider implementing adopt-or-create for Vercel projects.\n *\n * On `create()`, calls `GET /v9/projects/{name}?teamId=…`. If found, adopts\n * the existing project. If 404, creates a new one via `POST /v9/projects`.\n * Deletion is a no-op to protect production projects.\n */\nclass VercelProjectResourceProvider\n\timplements pulumi.dynamic.ResourceProvider\n{\n\tasync create(\n\t\tinputs: VercelProjectInputs,\n\t): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst existing = await fetchProject(inputs.token, inputs.teamId, inputs.name);\n\n\t\tlet projectId: string;\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopting existing Vercel project \"${inputs.name}\" (${existing.id})`,\n\t\t\t);\n\n\t\t\tprojectId = existing.id;\n\t\t} else {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Vercel project \"${inputs.name}\" not found — creating...`,\n\t\t\t);\n\n\t\t\tconst response = await fetch(\n\t\t\t\t`${VERCEL_API_URL}/v9/projects?teamId=${inputs.teamId}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Bearer ${inputs.token}`,\n\t\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify(buildProjectBody(inputs)),\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Vercel API error creating project \"${inputs.name}\" (${response.status}): ${await response.text()}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst created = (await response.json()) as VercelProjectResponse;\n\n\t\t\tprojectId = created.id;\n\t\t}\n\n\t\tconst outs: VercelProjectOutputs = { ...inputs, projectId };\n\n\t\treturn { id: projectId, outs };\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: VercelProjectOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst project = await fetchProject(props.token, props.teamId, id);\n\n\t\tif (!project) {\n\t\t\tthrow new Error(`Vercel project \"${id}\" not found during refresh`);\n\t\t}\n\n\t\treturn {\n\t\t\tid: project.id,\n\t\t\tprops: { ...props, name: project.name, projectId: project.id },\n\t\t};\n\t}\n\n\tasync update(\n\t\tid: string,\n\t\t_olds: VercelProjectOutputs,\n\t\tnews: VercelProjectInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\tconst response = await fetch(\n\t\t\t`${VERCEL_API_URL}/v9/projects/${id}?teamId=${news.teamId}`,\n\t\t\t{\n\t\t\t\tmethod: \"PATCH\",\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${news.token}`,\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(buildProjectBody(news)),\n\t\t\t},\n\t\t);\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vercel API error updating project \"${id}\" (${response.status}): ${await response.text()}`,\n\t\t\t);\n\t\t}\n\n\t\treturn { outs: { ...news, projectId: id } };\n\t}\n\n\tasync delete(): Promise<void> {\n\t\tpulumi.log.warn(\n\t\t\t\"Vercel project deletion skipped — projects are not deleted by Pulumi\",\n\t\t);\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: VercelProjectOutputs,\n\t\tnews: VercelProjectInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\t\tconst changes: string[] = [];\n\n\t\tif (olds.teamId !== news.teamId) {\n\t\t\treplaces.push(\"teamId\");\n\t\t}\n\n\t\tconst updatableFields = [\n\t\t\t\"name\",\n\t\t\t\"framework\",\n\t\t\t\"rootDirectory\",\n\t\t\t\"buildCommand\",\n\t\t\t\"installCommand\",\n\t\t\t\"outputDirectory\",\n\t\t] as const;\n\n\t\tfor (const field of updatableFields) {\n\t\t\tif (olds[field] !== news[field]) {\n\t\t\t\tchanges.push(field);\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0 || changes.length > 0,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n}\n\n/** Internal dynamic resource — not part of the public API. */\nclass VercelProjectResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly projectId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tteamId: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t\tframework?: pulumi.Input<string>;\n\t\t\trootDirectory?: pulumi.Input<string>;\n\t\t\tbuildCommand?: pulumi.Input<string>;\n\t\t\tinstallCommand?: pulumi.Input<string>;\n\t\t\toutputDirectory?: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew VercelProjectResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, projectId: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for VercelProject — replaces Pulumi's native `provider` field. */\ntype VercelProjectOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Vercel authentication context. */\n\tprovider: VercelProvider;\n};\n\n/** Args for VercelProject. */\nexport interface VercelProjectArgs {\n\t/** Project name. Used for both adoption lookup and display name. */\n\tname: pulumi.Input<string>;\n\n\t/** Framework preset (e.g. `\"nextjs\"`, `\"remix\"`). */\n\tframework?: pulumi.Input<string>;\n\n\t/** Relative path to the project root within a monorepo (e.g. `\"apps/nexus\"`). */\n\trootDirectory?: pulumi.Input<string>;\n\n\t/** Custom build command. */\n\tbuildCommand?: pulumi.Input<string>;\n\n\t/** Custom install command. */\n\tinstallCommand?: pulumi.Input<string>;\n\n\t/** Custom output directory. */\n\toutputDirectory?: pulumi.Input<string>;\n}\n\n/**\n * Manages a Vercel project with adopt-or-create semantics.\n *\n * On first `pulumi up`, looks up the project by name. If it already exists,\n * the resource adopts it. If not, a new project is created. Deletion is a\n * no-op to protect production projects.\n *\n * @example\n * ```typescript\n * const project = new VercelProject(\"nexus\", {\n * name: \"nexus\",\n * framework: \"nextjs\",\n * rootDirectory: \"apps/nexus\",\n * }, { provider });\n *\n * new VercelVariable(\"nexus-vars\", {\n * projectId: project.id,\n * variables: { NEXT_PUBLIC_API_URL: meshUrl },\n * }, { provider });\n * ```\n */\nexport class VercelProject extends pulumi.ComponentResource {\n\t/** Vercel-assigned project ID. */\n\tpublic readonly id: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: VercelProjectArgs,\n\t\topts: VercelProjectOptions,\n\t) {\n\t\tconst { provider, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:vercel:Project\", name, {}, pulumiOpts);\n\n\t\tconst resource = new VercelProjectResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tteamId: provider.teamId,\n\t\t\t\t...args,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = resource.projectId;\n\n\t\tthis.registerOutputs({ id: this.id });\n\t}\n}\n"],"mappings":";;;;;;AAGA,MAAM,iBAAiB;;;;;AA6CvB,eAAe,aACd,OACA,QACA,UACwC;CACxC,MAAM,WAAW,MAAM,MACtB,GAAG,eAAe,eAAe,mBAAmB,QAAQ,EAAE,UAAU,UACxE,EAAE,SAAS,EAAE,eAAe,UAAU,QAAQ,EAAE,CACjD;CAEA,IAAI,SAAS,WAAW,KACvB,OAAO;CAGR,IAAI,CAAC,SAAS,IACb,MAAM,IAAI,MACT,sCAAsC,SAAS,KAAK,SAAS,OAAO,KAAK,MAAM,SAAS,KAAK,GAC9F;CAGD,OAAQ,MAAM,SAAS,KAAK;AAC7B;;;;;AAMA,SAAS,iBACR,QACyB;CACzB,MAAM,OAA+B,EAAE,MAAM,OAAO,KAAK;CAEzD,IAAI,OAAO,cAAc,QAAW,KAAK,YAAY,OAAO;CAC5D,IAAI,OAAO,kBAAkB,QAC5B,KAAK,gBAAgB,OAAO;CAC7B,IAAI,OAAO,iBAAiB,QAAW,KAAK,eAAe,OAAO;CAClE,IAAI,OAAO,mBAAmB,QAC7B,KAAK,iBAAiB,OAAO;CAC9B,IAAI,OAAO,oBAAoB,QAC9B,KAAK,kBAAkB,OAAO;CAE/B,OAAO;AACR;;;;;;;;AASA,IAAM,gCAAN,MAEA;CACC,MAAM,OACL,QACuC;EACvC,MAAM,WAAW,MAAM,aAAa,OAAO,OAAO,OAAO,QAAQ,OAAO,IAAI;EAE5E,IAAI;EAEJ,IAAI,UAAU;GACb,eAAO,IAAI,KACV,qCAAqC,OAAO,KAAK,KAAK,SAAS,GAAG,EACnE;GAEA,YAAY,SAAS;EACtB,OAAO;GACN,eAAO,IAAI,KACV,mBAAmB,OAAO,KAAK,0BAChC;GAEA,MAAM,WAAW,MAAM,MACtB,GAAG,eAAe,sBAAsB,OAAO,UAC/C;IACC,QAAQ;IACR,SAAS;KACR,eAAe,UAAU,OAAO;KAChC,gBAAgB;IACjB;IACA,MAAM,KAAK,UAAU,iBAAiB,MAAM,CAAC;GAC9C,CACD;GAEA,IAAI,CAAC,SAAS,IACb,MAAM,IAAI,MACT,sCAAsC,OAAO,KAAK,KAAK,SAAS,OAAO,KAAK,MAAM,SAAS,KAAK,GACjG;GAKD,aAAY,MAFW,SAAS,KAAK,GAEjB;EACrB;EAEA,MAAM,OAA6B;GAAE,GAAG;GAAQ;EAAU;EAE1D,OAAO;GAAE,IAAI;GAAW;EAAK;CAC9B;CAEA,MAAM,KACL,IACA,OACqC;EACrC,MAAM,UAAU,MAAM,aAAa,MAAM,OAAO,MAAM,QAAQ,EAAE;EAEhE,IAAI,CAAC,SACJ,MAAM,IAAI,MAAM,mBAAmB,GAAG,2BAA2B;EAGlE,OAAO;GACN,IAAI,QAAQ;GACZ,OAAO;IAAE,GAAG;IAAO,MAAM,QAAQ;IAAM,WAAW,QAAQ;GAAG;EAC9D;CACD;CAEA,MAAM,OACL,IACA,OACA,MACuC;EACvC,MAAM,WAAW,MAAM,MACtB,GAAG,eAAe,eAAe,GAAG,UAAU,KAAK,UACnD;GACC,QAAQ;GACR,SAAS;IACR,eAAe,UAAU,KAAK;IAC9B,gBAAgB;GACjB;GACA,MAAM,KAAK,UAAU,iBAAiB,IAAI,CAAC;EAC5C,CACD;EAEA,IAAI,CAAC,SAAS,IACb,MAAM,IAAI,MACT,sCAAsC,GAAG,KAAK,SAAS,OAAO,KAAK,MAAM,SAAS,KAAK,GACxF;EAGD,OAAO,EAAE,MAAM;GAAE,GAAG;GAAM,WAAW;EAAG,EAAE;CAC3C;CAEA,MAAM,SAAwB;EAC7B,eAAO,IAAI,KACV,sEACD;CACD;CAEA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAC5B,MAAM,UAAoB,CAAC;EAE3B,IAAI,KAAK,WAAW,KAAK,QACxB,SAAS,KAAK,QAAQ;EAYvB,KAAK,MAAM,SAAS;GARnB;GACA;GACA;GACA;GACA;GACA;EAGiC,GACjC,IAAI,KAAK,WAAW,KAAK,QACxB,QAAQ,KAAK,KAAK;EAIpB,OAAO;GACN,SAAS,SAAS,SAAS,KAAK,QAAQ,SAAS;GACjD;GACA,qBAAqB;EACtB;CACD;AACD;;AAGA,IAAM,wBAAN,cAAoCA,eAAO,QAAQ,SAAS;CAG3D,YACC,MACA,MAUA,MACC;EACD,MACC,IAAI,8BAA8B,GAClC,MACA;GAAE,GAAG;GAAM,WAAW;EAAU,GAChC,IACD;CACD;AACD;;;;;;;;;;;;;;;;;;;;;;AAkDA,IAAa,gBAAb,cAAmCA,eAAO,kBAAkB;CAI3D,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,GAAG,eAAe;EAEpC,MAAM,6BAA6B,MAAM,CAAC,GAAG,UAAU;EAEvD,MAAM,WAAW,IAAI,sBACpB,GAAG,KAAK,YACR;GACC,OAAO,SAAS;GAChB,QAAQ,SAAS;GACjB,GAAG;EACJ,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,KAAK,SAAS;EAEnB,KAAK,gBAAgB,EAAE,IAAI,KAAK,GAAG,CAAC;CACrC;AACD"}