@infracraft/pulumi 1.5.1 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fly/app.cjs.map +1 -1
- package/dist/fly/app.d.cts.map +1 -1
- package/dist/fly/app.d.mts.map +1 -1
- package/dist/fly/app.mjs.map +1 -1
- package/dist/fly/certificate.cjs.map +1 -1
- package/dist/fly/certificate.d.cts.map +1 -1
- package/dist/fly/certificate.d.mts.map +1 -1
- package/dist/fly/certificate.mjs.map +1 -1
- package/dist/fly/ip.cjs.map +1 -1
- package/dist/fly/ip.d.cts.map +1 -1
- package/dist/fly/ip.d.mts.map +1 -1
- package/dist/fly/ip.mjs.map +1 -1
- package/dist/fly/toml.cjs.map +1 -1
- package/dist/fly/toml.d.cts.map +1 -1
- package/dist/fly/toml.d.mts.map +1 -1
- package/dist/fly/toml.mjs.map +1 -1
- package/dist/fly/volume.cjs.map +1 -1
- package/dist/fly/volume.d.cts.map +1 -1
- package/dist/fly/volume.d.mts.map +1 -1
- package/dist/fly/volume.mjs.map +1 -1
- package/dist/git-guard.cjs +144 -38
- package/dist/git-guard.cjs.map +1 -1
- package/dist/git-guard.d.cts +75 -2
- package/dist/git-guard.d.cts.map +1 -1
- package/dist/git-guard.d.mts +75 -2
- package/dist/git-guard.d.mts.map +1 -1
- package/dist/git-guard.mjs +141 -39
- package/dist/git-guard.mjs.map +1 -1
- package/dist/vercel/project.cjs.map +1 -1
- package/dist/vercel/project.d.cts.map +1 -1
- package/dist/vercel/project.d.mts.map +1 -1
- package/dist/vercel/project.mjs.map +1 -1
- package/package.json +1 -1
package/dist/fly/app.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.cjs","names":["FlyClient","pulumi"],"sources":["../../src/fly/app.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\n\nimport { FlyClient } from \"./client\";\nimport type { FlyProvider } from \"./provider\";\n\n/** Resolved inputs for the Fly app dynamic provider. */\nexport interface FlyAppInputs {\n\t/** Fly API token. */\n\ttoken: string;\n\n\t/** App name (globally unique). Used as the resource identifier. */\n\tname: string;\n\n\t/** Org slug used only when creating a new app. */\n\torganization?: string;\n}\n\n/** Persisted state for the Fly app. */\ninterface FlyAppOutputs extends FlyAppInputs {\n\t/** App identifier — equals the app name (all child paths key off the name). */\n\tappId: string;\n}\n\n/** Get-app response (only the fields we read). */\ninterface FlyAppResponse {\n\tid: string;\n\tname: string;\n}\n\n/**\n * Dynamic provider implementing adopt-or-create for Fly apps.\n *\n * `create()` does `GET /v1/apps/{name}`; if found it adopts, otherwise it\n * `POST /v1/apps`. `delete()` is a no-op — deleting a Fly app destroys\n * everything in it, so (like Railway/Neon/Vercel top-level resources) Pulumi\n * does not delete apps.\n */\nclass FlyAppResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(inputs: FlyAppInputs): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new FlyClient(inputs.token);\n\t\tconst existing = await client.tryGet<FlyAppResponse>(\n\t\t\t`/v1/apps/${inputs.name}`,\n\t\t);\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(`Adopting existing Fly app \"${inputs.name}\"`);\n\t\t} else {\n\t\t\tif (!inputs.organization) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`FlyApp \"${inputs.name}\": an organization is required to create a new app — set it on FlyProvider or FlyApp args`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tpulumi.log.info(`Fly app \"${inputs.name}\" not found — creating...`);\n\n\t\t\tawait client.post(\"/v1/apps\", {\n\t\t\t\tapp_name: inputs.name,\n\t\t\t\torg_slug: inputs.organization,\n\t\t\t});\n\t\t}\n\n\t\tconst outs: FlyAppOutputs = { ...inputs, appId: inputs.name };\n\n\t\treturn { id: inputs.name, outs };\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: FlyAppOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new FlyClient(props.token);\n\t\tconst app = await client.tryGet<FlyAppResponse>(`/v1/apps/${id}`);\n\n\t\tif (!app) {\n\t\t\tthrow new Error(`Fly app \"${id}\" not found during refresh`);\n\t\t}\n\n\t\treturn { id, props: { ...props, name: app.name, appId: app.name } };\n\t}\n\n\tasync update(\n\t\tid: string,\n\t\t_olds: FlyAppOutputs,\n\t\tnews: FlyAppInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\treturn { outs: { ...news, appId: id } };\n\t}\n\n\tasync delete(): Promise<void> {\n\t\tpulumi.log.warn(\n\t\t\t\"Fly app deletion skipped — apps are not deleted by Pulumi (would destroy all contained resources)\",\n\t\t);\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: FlyAppOutputs,\n\t\tnews: FlyAppInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.name !== news.name) {\n\t\t\treplaces.push(\"name\");\n\t\t}\n\t\tif (olds.organization !== news.organization) {\n\t\t\treplaces.push(\"organization\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.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 FlyAppResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly appId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t\torganization?: pulumi.Input<string | undefined>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew FlyAppResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, appId: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for FlyApp — replaces Pulumi's native `provider` field. */\ntype FlyAppOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Fly authentication context. */\n\tprovider: FlyProvider;\n};\n\n/** Args for FlyApp. */\nexport interface FlyAppArgs {\n\t/** App name (globally unique). Used for adoption lookup and as `.id`. */\n\tname: pulumi.Input<string>;\n\n\t/**\n\t * Org slug for app creation. Overrides `FlyProvider.organization`.\n\t * Ignored when the app already exists (adoption).\n\t */\n\torganization?: pulumi.Input<string>;\n}\n\n/**\n * Manages a Fly app with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const app = new FlyApp(\"api\", { name: \"rby-api\" }, { provider });\n * ```\n */\nexport class FlyApp extends pulumi.ComponentResource {\n\t/** App identifier (equals the app name). */\n\tpublic readonly id: pulumi.Output<string>;\n\n\tconstructor(name: string, args: FlyAppArgs, opts: FlyAppOptions) {\n\t\tconst { provider, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:App\", name, {}, pulumiOpts);\n\n\t\tconst resource = new FlyAppResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tname: args.name,\n\t\t\t\torganization: args.organization ?? provider.organization,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = resource.appId;\n\n\t\tthis.registerOutputs({ id: this.id });\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;AAqCA,IAAM,yBAAN,MAAwE;CACvE,MAAM,OAAO,QAA4D;EACxE,MAAM,SAAS,IAAIA,6BAAU,OAAO,KAAK;
|
|
1
|
+
{"version":3,"file":"app.cjs","names":["FlyClient","pulumi"],"sources":["../../src/fly/app.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\n\nimport { FlyClient } from \"./client\";\nimport type { FlyProvider } from \"./provider\";\n\n/** Resolved inputs for the Fly app dynamic provider. */\nexport interface FlyAppInputs {\n\t/** Fly API token. */\n\ttoken: string;\n\n\t/** App name (globally unique). Used as the resource identifier. */\n\tname: string;\n\n\t/** Org slug used only when creating a new app. */\n\torganization?: string;\n}\n\n/** Persisted state for the Fly app. */\ninterface FlyAppOutputs extends FlyAppInputs {\n\t/** App identifier — equals the app name (all child paths key off the name). */\n\tappId: string;\n}\n\n/** Get-app response (only the fields we read). */\ninterface FlyAppResponse {\n\tid: string;\n\tname: string;\n}\n\n/**\n * Dynamic provider implementing adopt-or-create for Fly apps.\n *\n * `create()` does `GET /v1/apps/{name}`; if found it adopts, otherwise it\n * `POST /v1/apps`. `delete()` is a no-op — deleting a Fly app destroys\n * everything in it, so (like Railway/Neon/Vercel top-level resources) Pulumi\n * does not delete apps.\n */\nclass FlyAppResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(inputs: FlyAppInputs): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new FlyClient(inputs.token);\n\n\t\tconst existing = await client.tryGet<FlyAppResponse>(\n\t\t\t`/v1/apps/${inputs.name}`,\n\t\t);\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(`Adopting existing Fly app \"${inputs.name}\"`);\n\t\t} else {\n\t\t\tif (!inputs.organization) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`FlyApp \"${inputs.name}\": an organization is required to create a new app — set it on FlyProvider or FlyApp args`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tpulumi.log.info(`Fly app \"${inputs.name}\" not found — creating...`);\n\n\t\t\tawait client.post(\"/v1/apps\", {\n\t\t\t\tapp_name: inputs.name,\n\t\t\t\torg_slug: inputs.organization,\n\t\t\t});\n\t\t}\n\n\t\tconst outs: FlyAppOutputs = { ...inputs, appId: inputs.name };\n\n\t\treturn { id: inputs.name, outs };\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: FlyAppOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new FlyClient(props.token);\n\t\tconst app = await client.tryGet<FlyAppResponse>(`/v1/apps/${id}`);\n\n\t\tif (!app) {\n\t\t\tthrow new Error(`Fly app \"${id}\" not found during refresh`);\n\t\t}\n\n\t\treturn { id, props: { ...props, name: app.name, appId: app.name } };\n\t}\n\n\tasync update(\n\t\tid: string,\n\t\t_olds: FlyAppOutputs,\n\t\tnews: FlyAppInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\treturn { outs: { ...news, appId: id } };\n\t}\n\n\tasync delete(): Promise<void> {\n\t\tpulumi.log.warn(\n\t\t\t\"Fly app deletion skipped — apps are not deleted by Pulumi (would destroy all contained resources)\",\n\t\t);\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: FlyAppOutputs,\n\t\tnews: FlyAppInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.name !== news.name) {\n\t\t\treplaces.push(\"name\");\n\t\t}\n\n\t\tif (olds.organization !== news.organization) {\n\t\t\treplaces.push(\"organization\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.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 FlyAppResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly appId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t\torganization?: pulumi.Input<string | undefined>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew FlyAppResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, appId: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for FlyApp — replaces Pulumi's native `provider` field. */\ntype FlyAppOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Fly authentication context. */\n\tprovider: FlyProvider;\n};\n\n/** Args for FlyApp. */\nexport interface FlyAppArgs {\n\t/** App name (globally unique). Used for adoption lookup and as `.id`. */\n\tname: pulumi.Input<string>;\n\n\t/**\n\t * Org slug for app creation. Overrides `FlyProvider.organization`.\n\t * Ignored when the app already exists (adoption).\n\t */\n\torganization?: pulumi.Input<string>;\n}\n\n/**\n * Manages a Fly app with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const app = new FlyApp(\"api\", { name: \"rby-api\" }, { provider });\n * ```\n */\nexport class FlyApp extends pulumi.ComponentResource {\n\t/** App identifier (equals the app name). */\n\tpublic readonly id: pulumi.Output<string>;\n\n\tconstructor(name: string, args: FlyAppArgs, opts: FlyAppOptions) {\n\t\tconst { provider, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:App\", name, {}, pulumiOpts);\n\n\t\tconst resource = new FlyAppResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tname: args.name,\n\t\t\t\torganization: args.organization ?? provider.organization,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = resource.appId;\n\n\t\tthis.registerOutputs({ id: this.id });\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;AAqCA,IAAM,yBAAN,MAAwE;CACvE,MAAM,OAAO,QAA4D;EACxE,MAAM,SAAS,IAAIA,6BAAU,OAAO,KAAK;EAMzC,IAAI,MAJmB,OAAO,OAC7B,YAAY,OAAO,MACpB,GAGC,eAAO,IAAI,KAAK,8BAA8B,OAAO,KAAK,EAAE;OACtD;GACN,IAAI,CAAC,OAAO,cACX,MAAM,IAAI,MACT,WAAW,OAAO,KAAK,0FACxB;GAGD,eAAO,IAAI,KAAK,YAAY,OAAO,KAAK,0BAA0B;GAElE,MAAM,OAAO,KAAK,YAAY;IAC7B,UAAU,OAAO;IACjB,UAAU,OAAO;GAClB,CAAC;EACF;EAEA,MAAM,OAAsB;GAAE,GAAG;GAAQ,OAAO,OAAO;EAAK;EAE5D,OAAO;GAAE,IAAI,OAAO;GAAM;EAAK;CAChC;CAEA,MAAM,KACL,IACA,OACqC;EAErC,MAAM,MAAM,MAAM,IADCA,6BAAU,MAAM,KACZ,EAAE,OAAuB,YAAY,IAAI;EAEhE,IAAI,CAAC,KACJ,MAAM,IAAI,MAAM,YAAY,GAAG,2BAA2B;EAG3D,OAAO;GAAE;GAAI,OAAO;IAAE,GAAG;IAAO,MAAM,IAAI;IAAM,OAAO,IAAI;GAAK;EAAE;CACnE;CAEA,MAAM,OACL,IACA,OACA,MACuC;EACvC,OAAO,EAAE,MAAM;GAAE,GAAG;GAAM,OAAO;EAAG,EAAE;CACvC;CAEA,MAAM,SAAwB;EAC7B,eAAO,IAAI,KACV,mGACD;CACD;CAEA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAE5B,IAAI,KAAK,SAAS,KAAK,MACtB,SAAS,KAAK,MAAM;EAGrB,IAAI,KAAK,iBAAiB,KAAK,cAC9B,SAAS,KAAK,cAAc;EAG7B,OAAO;GACN,SAAS,SAAS,SAAS;GAC3B;GACA,qBAAqB;EACtB;CACD;AACD;;AAGA,IAAM,iBAAN,cAA6BC,eAAO,QAAQ,SAAS;CAGpD,YACC,MACA,MAKA,MACC;EACD,MACC,IAAI,uBAAuB,GAC3B,MACA;GAAE,GAAG;GAAM,OAAO;EAAU,GAC5B,IACD;CACD;AACD;;;;;;;;;AA4BA,IAAa,SAAb,cAA4BA,eAAO,kBAAkB;CAIpD,YAAY,MAAc,MAAkB,MAAqB;EAChE,MAAM,EAAE,UAAU,GAAG,eAAe;EAEpC,MAAM,sBAAsB,MAAM,CAAC,GAAG,UAAU;EAEhD,MAAM,WAAW,IAAI,eACpB,GAAG,KAAK,YACR;GACC,OAAO,SAAS;GAChB,MAAM,KAAK;GACX,cAAc,KAAK,gBAAgB,SAAS;EAC7C,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,KAAK,SAAS;EAEnB,KAAK,gBAAgB,EAAE,IAAI,KAAK,GAAG,CAAC;CACrC;AACD"}
|
package/dist/fly/app.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.cts","names":[],"sources":["../../src/fly/app.ts"],"mappings":";;;;;;UAMiB,YAAA;;EAEhB,KAAA;EAF4B;EAK5B,IAAA;EAL4B;EAQ5B,YAAA;AAAA;;
|
|
1
|
+
{"version":3,"file":"app.d.cts","names":[],"sources":["../../src/fly/app.ts"],"mappings":";;;;;;UAMiB,YAAA;;EAEhB,KAAA;EAF4B;EAK5B,IAAA;EAL4B;EAQ5B,YAAA;AAAA;;KA+HI,aAAA,GAAgB,IAAA,CAAK,MAAA,CAAO,wBAAA;EA/HpB,kCAiIZ,QAAA,EAAU,WAAA;AAAA;;UAIM,UAAA;EANI;EAQpB,IAAA,EAAM,MAAA,CAAO,KAAA;EANQ;;;;EAYrB,YAAA,GAAe,MAAA,CAAO,KAAK;AAAA;;;AAZN;AAItB;;;;;cAmBa,MAAA,SAAe,MAAA,CAAO,iBAAA;EAjBrB;EAAA,SAmBG,EAAA,EAAI,MAAA,CAAO,MAAA;cAEf,IAAA,UAAc,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,aAAA;AAAA"}
|
package/dist/fly/app.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.mts","names":[],"sources":["../../src/fly/app.ts"],"mappings":";;;;;;UAMiB,YAAA;;EAEhB,KAAA;EAF4B;EAK5B,IAAA;EAL4B;EAQ5B,YAAA;AAAA;;
|
|
1
|
+
{"version":3,"file":"app.d.mts","names":[],"sources":["../../src/fly/app.ts"],"mappings":";;;;;;UAMiB,YAAA;;EAEhB,KAAA;EAF4B;EAK5B,IAAA;EAL4B;EAQ5B,YAAA;AAAA;;KA+HI,aAAA,GAAgB,IAAA,CAAK,MAAA,CAAO,wBAAA;EA/HpB,kCAiIZ,QAAA,EAAU,WAAA;AAAA;;UAIM,UAAA;EANI;EAQpB,IAAA,EAAM,MAAA,CAAO,KAAA;EANQ;;;;EAYrB,YAAA,GAAe,MAAA,CAAO,KAAK;AAAA;;;AAZN;AAItB;;;;;cAmBa,MAAA,SAAe,MAAA,CAAO,iBAAA;EAjBrB;EAAA,SAmBG,EAAA,EAAI,MAAA,CAAO,MAAA;cAEf,IAAA,UAAc,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,aAAA;AAAA"}
|
package/dist/fly/app.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.mjs","names":[],"sources":["../../src/fly/app.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\n\nimport { FlyClient } from \"./client\";\nimport type { FlyProvider } from \"./provider\";\n\n/** Resolved inputs for the Fly app dynamic provider. */\nexport interface FlyAppInputs {\n\t/** Fly API token. */\n\ttoken: string;\n\n\t/** App name (globally unique). Used as the resource identifier. */\n\tname: string;\n\n\t/** Org slug used only when creating a new app. */\n\torganization?: string;\n}\n\n/** Persisted state for the Fly app. */\ninterface FlyAppOutputs extends FlyAppInputs {\n\t/** App identifier — equals the app name (all child paths key off the name). */\n\tappId: string;\n}\n\n/** Get-app response (only the fields we read). */\ninterface FlyAppResponse {\n\tid: string;\n\tname: string;\n}\n\n/**\n * Dynamic provider implementing adopt-or-create for Fly apps.\n *\n * `create()` does `GET /v1/apps/{name}`; if found it adopts, otherwise it\n * `POST /v1/apps`. `delete()` is a no-op — deleting a Fly app destroys\n * everything in it, so (like Railway/Neon/Vercel top-level resources) Pulumi\n * does not delete apps.\n */\nclass FlyAppResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(inputs: FlyAppInputs): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new FlyClient(inputs.token);\n\t\tconst existing = await client.tryGet<FlyAppResponse>(\n\t\t\t`/v1/apps/${inputs.name}`,\n\t\t);\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(`Adopting existing Fly app \"${inputs.name}\"`);\n\t\t} else {\n\t\t\tif (!inputs.organization) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`FlyApp \"${inputs.name}\": an organization is required to create a new app — set it on FlyProvider or FlyApp args`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tpulumi.log.info(`Fly app \"${inputs.name}\" not found — creating...`);\n\n\t\t\tawait client.post(\"/v1/apps\", {\n\t\t\t\tapp_name: inputs.name,\n\t\t\t\torg_slug: inputs.organization,\n\t\t\t});\n\t\t}\n\n\t\tconst outs: FlyAppOutputs = { ...inputs, appId: inputs.name };\n\n\t\treturn { id: inputs.name, outs };\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: FlyAppOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new FlyClient(props.token);\n\t\tconst app = await client.tryGet<FlyAppResponse>(`/v1/apps/${id}`);\n\n\t\tif (!app) {\n\t\t\tthrow new Error(`Fly app \"${id}\" not found during refresh`);\n\t\t}\n\n\t\treturn { id, props: { ...props, name: app.name, appId: app.name } };\n\t}\n\n\tasync update(\n\t\tid: string,\n\t\t_olds: FlyAppOutputs,\n\t\tnews: FlyAppInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\treturn { outs: { ...news, appId: id } };\n\t}\n\n\tasync delete(): Promise<void> {\n\t\tpulumi.log.warn(\n\t\t\t\"Fly app deletion skipped — apps are not deleted by Pulumi (would destroy all contained resources)\",\n\t\t);\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: FlyAppOutputs,\n\t\tnews: FlyAppInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.name !== news.name) {\n\t\t\treplaces.push(\"name\");\n\t\t}\n\t\tif (olds.organization !== news.organization) {\n\t\t\treplaces.push(\"organization\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.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 FlyAppResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly appId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t\torganization?: pulumi.Input<string | undefined>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew FlyAppResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, appId: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for FlyApp — replaces Pulumi's native `provider` field. */\ntype FlyAppOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Fly authentication context. */\n\tprovider: FlyProvider;\n};\n\n/** Args for FlyApp. */\nexport interface FlyAppArgs {\n\t/** App name (globally unique). Used for adoption lookup and as `.id`. */\n\tname: pulumi.Input<string>;\n\n\t/**\n\t * Org slug for app creation. Overrides `FlyProvider.organization`.\n\t * Ignored when the app already exists (adoption).\n\t */\n\torganization?: pulumi.Input<string>;\n}\n\n/**\n * Manages a Fly app with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const app = new FlyApp(\"api\", { name: \"rby-api\" }, { provider });\n * ```\n */\nexport class FlyApp extends pulumi.ComponentResource {\n\t/** App identifier (equals the app name). */\n\tpublic readonly id: pulumi.Output<string>;\n\n\tconstructor(name: string, args: FlyAppArgs, opts: FlyAppOptions) {\n\t\tconst { provider, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:App\", name, {}, pulumiOpts);\n\n\t\tconst resource = new FlyAppResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tname: args.name,\n\t\t\t\torganization: args.organization ?? provider.organization,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = resource.appId;\n\n\t\tthis.registerOutputs({ id: this.id });\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;AAqCA,IAAM,yBAAN,MAAwE;CACvE,MAAM,OAAO,QAA4D;EACxE,MAAM,SAAS,IAAI,UAAU,OAAO,KAAK;
|
|
1
|
+
{"version":3,"file":"app.mjs","names":[],"sources":["../../src/fly/app.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\n\nimport { FlyClient } from \"./client\";\nimport type { FlyProvider } from \"./provider\";\n\n/** Resolved inputs for the Fly app dynamic provider. */\nexport interface FlyAppInputs {\n\t/** Fly API token. */\n\ttoken: string;\n\n\t/** App name (globally unique). Used as the resource identifier. */\n\tname: string;\n\n\t/** Org slug used only when creating a new app. */\n\torganization?: string;\n}\n\n/** Persisted state for the Fly app. */\ninterface FlyAppOutputs extends FlyAppInputs {\n\t/** App identifier — equals the app name (all child paths key off the name). */\n\tappId: string;\n}\n\n/** Get-app response (only the fields we read). */\ninterface FlyAppResponse {\n\tid: string;\n\tname: string;\n}\n\n/**\n * Dynamic provider implementing adopt-or-create for Fly apps.\n *\n * `create()` does `GET /v1/apps/{name}`; if found it adopts, otherwise it\n * `POST /v1/apps`. `delete()` is a no-op — deleting a Fly app destroys\n * everything in it, so (like Railway/Neon/Vercel top-level resources) Pulumi\n * does not delete apps.\n */\nclass FlyAppResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(inputs: FlyAppInputs): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new FlyClient(inputs.token);\n\n\t\tconst existing = await client.tryGet<FlyAppResponse>(\n\t\t\t`/v1/apps/${inputs.name}`,\n\t\t);\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(`Adopting existing Fly app \"${inputs.name}\"`);\n\t\t} else {\n\t\t\tif (!inputs.organization) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`FlyApp \"${inputs.name}\": an organization is required to create a new app — set it on FlyProvider or FlyApp args`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tpulumi.log.info(`Fly app \"${inputs.name}\" not found — creating...`);\n\n\t\t\tawait client.post(\"/v1/apps\", {\n\t\t\t\tapp_name: inputs.name,\n\t\t\t\torg_slug: inputs.organization,\n\t\t\t});\n\t\t}\n\n\t\tconst outs: FlyAppOutputs = { ...inputs, appId: inputs.name };\n\n\t\treturn { id: inputs.name, outs };\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: FlyAppOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new FlyClient(props.token);\n\t\tconst app = await client.tryGet<FlyAppResponse>(`/v1/apps/${id}`);\n\n\t\tif (!app) {\n\t\t\tthrow new Error(`Fly app \"${id}\" not found during refresh`);\n\t\t}\n\n\t\treturn { id, props: { ...props, name: app.name, appId: app.name } };\n\t}\n\n\tasync update(\n\t\tid: string,\n\t\t_olds: FlyAppOutputs,\n\t\tnews: FlyAppInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\treturn { outs: { ...news, appId: id } };\n\t}\n\n\tasync delete(): Promise<void> {\n\t\tpulumi.log.warn(\n\t\t\t\"Fly app deletion skipped — apps are not deleted by Pulumi (would destroy all contained resources)\",\n\t\t);\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: FlyAppOutputs,\n\t\tnews: FlyAppInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.name !== news.name) {\n\t\t\treplaces.push(\"name\");\n\t\t}\n\n\t\tif (olds.organization !== news.organization) {\n\t\t\treplaces.push(\"organization\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.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 FlyAppResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly appId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t\torganization?: pulumi.Input<string | undefined>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew FlyAppResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, appId: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for FlyApp — replaces Pulumi's native `provider` field. */\ntype FlyAppOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Fly authentication context. */\n\tprovider: FlyProvider;\n};\n\n/** Args for FlyApp. */\nexport interface FlyAppArgs {\n\t/** App name (globally unique). Used for adoption lookup and as `.id`. */\n\tname: pulumi.Input<string>;\n\n\t/**\n\t * Org slug for app creation. Overrides `FlyProvider.organization`.\n\t * Ignored when the app already exists (adoption).\n\t */\n\torganization?: pulumi.Input<string>;\n}\n\n/**\n * Manages a Fly app with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const app = new FlyApp(\"api\", { name: \"rby-api\" }, { provider });\n * ```\n */\nexport class FlyApp extends pulumi.ComponentResource {\n\t/** App identifier (equals the app name). */\n\tpublic readonly id: pulumi.Output<string>;\n\n\tconstructor(name: string, args: FlyAppArgs, opts: FlyAppOptions) {\n\t\tconst { provider, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:App\", name, {}, pulumiOpts);\n\n\t\tconst resource = new FlyAppResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tname: args.name,\n\t\t\t\torganization: args.organization ?? provider.organization,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = resource.appId;\n\n\t\tthis.registerOutputs({ id: this.id });\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;AAqCA,IAAM,yBAAN,MAAwE;CACvE,MAAM,OAAO,QAA4D;EACxE,MAAM,SAAS,IAAI,UAAU,OAAO,KAAK;EAMzC,IAAI,MAJmB,OAAO,OAC7B,YAAY,OAAO,MACpB,GAGC,OAAO,IAAI,KAAK,8BAA8B,OAAO,KAAK,EAAE;OACtD;GACN,IAAI,CAAC,OAAO,cACX,MAAM,IAAI,MACT,WAAW,OAAO,KAAK,0FACxB;GAGD,OAAO,IAAI,KAAK,YAAY,OAAO,KAAK,0BAA0B;GAElE,MAAM,OAAO,KAAK,YAAY;IAC7B,UAAU,OAAO;IACjB,UAAU,OAAO;GAClB,CAAC;EACF;EAEA,MAAM,OAAsB;GAAE,GAAG;GAAQ,OAAO,OAAO;EAAK;EAE5D,OAAO;GAAE,IAAI,OAAO;GAAM;EAAK;CAChC;CAEA,MAAM,KACL,IACA,OACqC;EAErC,MAAM,MAAM,MAAM,IADC,UAAU,MAAM,KACZ,EAAE,OAAuB,YAAY,IAAI;EAEhE,IAAI,CAAC,KACJ,MAAM,IAAI,MAAM,YAAY,GAAG,2BAA2B;EAG3D,OAAO;GAAE;GAAI,OAAO;IAAE,GAAG;IAAO,MAAM,IAAI;IAAM,OAAO,IAAI;GAAK;EAAE;CACnE;CAEA,MAAM,OACL,IACA,OACA,MACuC;EACvC,OAAO,EAAE,MAAM;GAAE,GAAG;GAAM,OAAO;EAAG,EAAE;CACvC;CAEA,MAAM,SAAwB;EAC7B,OAAO,IAAI,KACV,mGACD;CACD;CAEA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAE5B,IAAI,KAAK,SAAS,KAAK,MACtB,SAAS,KAAK,MAAM;EAGrB,IAAI,KAAK,iBAAiB,KAAK,cAC9B,SAAS,KAAK,cAAc;EAG7B,OAAO;GACN,SAAS,SAAS,SAAS;GAC3B;GACA,qBAAqB;EACtB;CACD;AACD;;AAGA,IAAM,iBAAN,cAA6B,OAAO,QAAQ,SAAS;CAGpD,YACC,MACA,MAKA,MACC;EACD,MACC,IAAI,uBAAuB,GAC3B,MACA;GAAE,GAAG;GAAM,OAAO;EAAU,GAC5B,IACD;CACD;AACD;;;;;;;;;AA4BA,IAAa,SAAb,cAA4B,OAAO,kBAAkB;CAIpD,YAAY,MAAc,MAAkB,MAAqB;EAChE,MAAM,EAAE,UAAU,GAAG,eAAe;EAEpC,MAAM,sBAAsB,MAAM,CAAC,GAAG,UAAU;EAEhD,MAAM,WAAW,IAAI,eACpB,GAAG,KAAK,YACR;GACC,OAAO,SAAS;GAChB,MAAM,KAAK;GACX,cAAc,KAAK,gBAAgB,SAAS;EAC7C,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,KAAK,SAAS;EAEnB,KAAK,gBAAgB,EAAE,IAAI,KAAK,GAAG,CAAC;CACrC;AACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"certificate.cjs","names":["FlyClient","pulumi"],"sources":["../../src/fly/certificate.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\n\nimport type { FlyApp } from \"./app\";\nimport { FlyClient } from \"./client\";\nimport type { FlyProvider } from \"./provider\";\n\n/** DNS records the consumer must create for certificate validation. */\nexport interface FlyDnsRequirements {\n\t/** ACME challenge CNAME record. */\n\tacme_challenge?: { name: string; target: string };\n\n\t/** `_fly-ownership` TXT record. */\n\townership?: { name: string; app_value: string };\n\n\t/** CNAME target for the hostname itself. */\n\tcname?: string;\n}\n\n/** Resolved inputs for the Fly certificate dynamic provider. */\nexport interface FlyCertificateInputs {\n\t/** Fly API token. */\n\ttoken: string;\n\n\t/** App name the certificate belongs to. */\n\tappName: string;\n\n\t/** Hostname to issue an ACME certificate for. Used as the resource key. */\n\thostname: string;\n}\n\n/** Persisted state for the Fly certificate. */\ninterface FlyCertificateOutputs extends FlyCertificateInputs {\n\t/** Whether the certificate is fully provisioned (DNS correct). */\n\tconfigured: boolean;\n\n\t/** DNS records required for validation. */\n\tdnsRequirements: FlyDnsRequirements;\n}\n\n/** Certificate response (only the fields we read). */\ninterface FlyCertificateResponse {\n\thostname: string;\n\tconfigured: boolean;\n\tdns_requirements?: FlyDnsRequirements;\n}\n\n/**\n * Dynamic provider for Fly ACME (Let's Encrypt) certificates. `create()` checks\n * for an existing cert by hostname and adopts it, otherwise it requests one via\n * `POST /v1/apps/{app}/certificates/acme`. The Machines API returns no `id` —\n * the hostname is the resource key.\n */\nclass FlyCertificateResourceProvider\n\timplements pulumi.dynamic.ResourceProvider\n{\n\tasync create(\n\t\tinputs: FlyCertificateInputs,\n\t): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new FlyClient(inputs.token);\n\t\tconst path = `/v1/apps/${inputs.appName}/certificates/${encodeURIComponent(inputs.hostname)}`;\n\n\t\tlet cert = await client.tryGet<FlyCertificateResponse>(path);\n\n\t\tif (cert) {\n\t\t\tpulumi.log.info(`Adopting existing Fly certificate \"${inputs.hostname}\"`);\n\t\t} else {\n\t\t\tcert = await client.post<FlyCertificateResponse>(\n\t\t\t\t`/v1/apps/${inputs.appName}/certificates/acme`,\n\t\t\t\t{ hostname: inputs.hostname },\n\t\t\t);\n\t\t}\n\n\t\tconst outs: FlyCertificateOutputs = {\n\t\t\t...inputs,\n\t\t\tconfigured: cert.configured ?? false,\n\t\t\tdnsRequirements: cert.dns_requirements ?? {},\n\t\t};\n\n\t\treturn { id: inputs.hostname, outs };\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: FlyCertificateOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tconst cert = await client.tryGet<FlyCertificateResponse>(\n\t\t\t`/v1/apps/${props.appName}/certificates/${encodeURIComponent(id)}`,\n\t\t);\n\n\t\tif (!cert) {\n\t\t\tthrow new Error(`Fly certificate \"${id}\" not found during refresh`);\n\t\t}\n\n\t\treturn {\n\t\t\tid,\n\t\t\tprops: {\n\t\t\t\t...props,\n\t\t\t\tconfigured: cert.configured ?? false,\n\t\t\t\tdnsRequirements: cert.dns_requirements ?? {},\n\t\t\t},\n\t\t};\n\t}\n\n\tasync update(\n\t\t_id: string,\n\t\t_olds: FlyCertificateOutputs,\n\t\tnews: FlyCertificateInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\t// Hostname/app changes force replacement (see diff); nothing else is updatable.\n\t\treturn {\n\t\t\touts: { ...news, configured: false, dnsRequirements: {} },\n\t\t};\n\t}\n\n\tasync delete(id: string, props: FlyCertificateOutputs): Promise<void> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tawait client.delete(\n\t\t\t`/v1/apps/${props.appName}/certificates/${encodeURIComponent(id)}`,\n\t\t);\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: FlyCertificateOutputs,\n\t\tnews: FlyCertificateInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.appName !== news.appName) {\n\t\t\treplaces.push(\"appName\");\n\t\t}\n\t\tif (olds.hostname !== news.hostname) {\n\t\t\treplaces.push(\"hostname\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.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 FlyCertificateResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly configured: pulumi.Output<boolean>;\n\tpublic declare readonly dnsRequirements: pulumi.Output<FlyDnsRequirements>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tappName: pulumi.Input<string>;\n\t\t\thostname: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew FlyCertificateResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, configured: undefined, dnsRequirements: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for FlyCertificate. */\ntype FlyCertificateOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Fly authentication context. */\n\tprovider: FlyProvider;\n\n\t/** App the certificate belongs to. */\n\tapp: FlyApp;\n};\n\n/** Args for FlyCertificate. */\nexport interface FlyCertificateArgs {\n\t/** Hostname to issue an ACME certificate for (e.g. `\"api.example.com\"`). */\n\thostname: pulumi.Input<string>;\n}\n\n/**\n * Manages a Fly ACME certificate for a custom hostname.\n *\n * Exposes `.configured` and `.dnsRequirements` so the consumer can wire up the\n * required DNS records.\n *\n * @example\n * ```typescript\n * const cert = new FlyCertificate(\"api-cert\", {\n * hostname: \"api.example.com\",\n * }, { provider, app });\n * ```\n */\nexport class FlyCertificate extends pulumi.ComponentResource {\n\t/** Certificate identifier (equals the hostname). */\n\tpublic readonly id: pulumi.Output<string>;\n\n\t/** Whether the certificate is fully provisioned. */\n\tpublic readonly configured: pulumi.Output<boolean>;\n\n\t/** DNS records required for validation. */\n\tpublic readonly dnsRequirements: pulumi.Output<FlyDnsRequirements>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: FlyCertificateArgs,\n\t\topts: FlyCertificateOptions,\n\t) {\n\t\tconst { provider, app, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:Certificate\", name, {}, pulumiOpts);\n\n\t\tconst resource = new FlyCertificateResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tappName: app.id,\n\t\t\t\thostname: args.hostname,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = pulumi.output(args.hostname);\n\t\tthis.configured = resource.configured;\n\t\tthis.dnsRequirements = resource.dnsRequirements;\n\n\t\tthis.registerOutputs({\n\t\t\tid: this.id,\n\t\t\tconfigured: this.configured,\n\t\t\tdnsRequirements: this.dnsRequirements,\n\t\t});\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;AAoDA,IAAM,iCAAN,MAEA;CACC,MAAM,OACL,QACuC;EACvC,MAAM,SAAS,IAAIA,6BAAU,OAAO,KAAK;EACzC,MAAM,OAAO,YAAY,OAAO,QAAQ,gBAAgB,mBAAmB,OAAO,QAAQ;EAE1F,IAAI,OAAO,MAAM,OAAO,OAA+B,IAAI;EAE3D,IAAI,MACH,eAAO,IAAI,KAAK,sCAAsC,OAAO,SAAS,EAAE;OAExE,OAAO,MAAM,OAAO,KACnB,YAAY,OAAO,QAAQ,qBAC3B,EAAE,UAAU,OAAO,SAAS,CAC7B;EAGD,MAAM,OAA8B;GACnC,GAAG;GACH,YAAY,KAAK,cAAc;GAC/B,iBAAiB,KAAK,oBAAoB,CAAC;EAC5C;EAEA,OAAO;GAAE,IAAI,OAAO;GAAU;EAAK;CACpC;CAEA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,OAAO,MAAM,IAFAA,6BAAU,MAAM,KAEX,EAAE,OACzB,YAAY,MAAM,QAAQ,gBAAgB,mBAAmB,EAAE,GAChE;EAEA,IAAI,CAAC,MACJ,MAAM,IAAI,MAAM,oBAAoB,GAAG,2BAA2B;EAGnE,OAAO;GACN;GACA,OAAO;IACN,GAAG;IACH,YAAY,KAAK,cAAc;IAC/B,iBAAiB,KAAK,oBAAoB,CAAC;GAC5C;EACD;CACD;CAEA,MAAM,OACL,KACA,OACA,MACuC;EAEvC,OAAO,EACN,MAAM;GAAE,GAAG;GAAM,YAAY;GAAO,iBAAiB,CAAC;EAAE,EACzD;CACD;CAEA,MAAM,OAAO,IAAY,OAA6C;EAGrE,MAAM,IAFaA,6BAAU,MAAM,KAExB,EAAE,OACZ,YAAY,MAAM,QAAQ,gBAAgB,mBAAmB,EAAE,GAChE;CACD;CAEA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAE5B,IAAI,KAAK,YAAY,KAAK,SACzB,SAAS,KAAK,SAAS;
|
|
1
|
+
{"version":3,"file":"certificate.cjs","names":["FlyClient","pulumi"],"sources":["../../src/fly/certificate.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\n\nimport type { FlyApp } from \"./app\";\nimport { FlyClient } from \"./client\";\nimport type { FlyProvider } from \"./provider\";\n\n/** DNS records the consumer must create for certificate validation. */\nexport interface FlyDnsRequirements {\n\t/** ACME challenge CNAME record. */\n\tacme_challenge?: { name: string; target: string };\n\n\t/** `_fly-ownership` TXT record. */\n\townership?: { name: string; app_value: string };\n\n\t/** CNAME target for the hostname itself. */\n\tcname?: string;\n}\n\n/** Resolved inputs for the Fly certificate dynamic provider. */\nexport interface FlyCertificateInputs {\n\t/** Fly API token. */\n\ttoken: string;\n\n\t/** App name the certificate belongs to. */\n\tappName: string;\n\n\t/** Hostname to issue an ACME certificate for. Used as the resource key. */\n\thostname: string;\n}\n\n/** Persisted state for the Fly certificate. */\ninterface FlyCertificateOutputs extends FlyCertificateInputs {\n\t/** Whether the certificate is fully provisioned (DNS correct). */\n\tconfigured: boolean;\n\n\t/** DNS records required for validation. */\n\tdnsRequirements: FlyDnsRequirements;\n}\n\n/** Certificate response (only the fields we read). */\ninterface FlyCertificateResponse {\n\thostname: string;\n\tconfigured: boolean;\n\tdns_requirements?: FlyDnsRequirements;\n}\n\n/**\n * Dynamic provider for Fly ACME (Let's Encrypt) certificates. `create()` checks\n * for an existing cert by hostname and adopts it, otherwise it requests one via\n * `POST /v1/apps/{app}/certificates/acme`. The Machines API returns no `id` —\n * the hostname is the resource key.\n */\nclass FlyCertificateResourceProvider\n\timplements pulumi.dynamic.ResourceProvider\n{\n\tasync create(\n\t\tinputs: FlyCertificateInputs,\n\t): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new FlyClient(inputs.token);\n\t\tconst path = `/v1/apps/${inputs.appName}/certificates/${encodeURIComponent(inputs.hostname)}`;\n\n\t\tlet cert = await client.tryGet<FlyCertificateResponse>(path);\n\n\t\tif (cert) {\n\t\t\tpulumi.log.info(`Adopting existing Fly certificate \"${inputs.hostname}\"`);\n\t\t} else {\n\t\t\tcert = await client.post<FlyCertificateResponse>(\n\t\t\t\t`/v1/apps/${inputs.appName}/certificates/acme`,\n\t\t\t\t{ hostname: inputs.hostname },\n\t\t\t);\n\t\t}\n\n\t\tconst outs: FlyCertificateOutputs = {\n\t\t\t...inputs,\n\t\t\tconfigured: cert.configured ?? false,\n\t\t\tdnsRequirements: cert.dns_requirements ?? {},\n\t\t};\n\n\t\treturn { id: inputs.hostname, outs };\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: FlyCertificateOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tconst cert = await client.tryGet<FlyCertificateResponse>(\n\t\t\t`/v1/apps/${props.appName}/certificates/${encodeURIComponent(id)}`,\n\t\t);\n\n\t\tif (!cert) {\n\t\t\tthrow new Error(`Fly certificate \"${id}\" not found during refresh`);\n\t\t}\n\n\t\treturn {\n\t\t\tid,\n\t\t\tprops: {\n\t\t\t\t...props,\n\t\t\t\tconfigured: cert.configured ?? false,\n\t\t\t\tdnsRequirements: cert.dns_requirements ?? {},\n\t\t\t},\n\t\t};\n\t}\n\n\tasync update(\n\t\t_id: string,\n\t\t_olds: FlyCertificateOutputs,\n\t\tnews: FlyCertificateInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\t// Hostname/app changes force replacement (see diff); nothing else is updatable.\n\t\treturn {\n\t\t\touts: { ...news, configured: false, dnsRequirements: {} },\n\t\t};\n\t}\n\n\tasync delete(id: string, props: FlyCertificateOutputs): Promise<void> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tawait client.delete(\n\t\t\t`/v1/apps/${props.appName}/certificates/${encodeURIComponent(id)}`,\n\t\t);\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: FlyCertificateOutputs,\n\t\tnews: FlyCertificateInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.appName !== news.appName) {\n\t\t\treplaces.push(\"appName\");\n\t\t}\n\n\t\tif (olds.hostname !== news.hostname) {\n\t\t\treplaces.push(\"hostname\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.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 FlyCertificateResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly configured: pulumi.Output<boolean>;\n\tpublic declare readonly dnsRequirements: pulumi.Output<FlyDnsRequirements>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tappName: pulumi.Input<string>;\n\t\t\thostname: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew FlyCertificateResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, configured: undefined, dnsRequirements: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for FlyCertificate. */\ntype FlyCertificateOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Fly authentication context. */\n\tprovider: FlyProvider;\n\n\t/** App the certificate belongs to. */\n\tapp: FlyApp;\n};\n\n/** Args for FlyCertificate. */\nexport interface FlyCertificateArgs {\n\t/** Hostname to issue an ACME certificate for (e.g. `\"api.example.com\"`). */\n\thostname: pulumi.Input<string>;\n}\n\n/**\n * Manages a Fly ACME certificate for a custom hostname.\n *\n * Exposes `.configured` and `.dnsRequirements` so the consumer can wire up the\n * required DNS records.\n *\n * @example\n * ```typescript\n * const cert = new FlyCertificate(\"api-cert\", {\n * hostname: \"api.example.com\",\n * }, { provider, app });\n * ```\n */\nexport class FlyCertificate extends pulumi.ComponentResource {\n\t/** Certificate identifier (equals the hostname). */\n\tpublic readonly id: pulumi.Output<string>;\n\n\t/** Whether the certificate is fully provisioned. */\n\tpublic readonly configured: pulumi.Output<boolean>;\n\n\t/** DNS records required for validation. */\n\tpublic readonly dnsRequirements: pulumi.Output<FlyDnsRequirements>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: FlyCertificateArgs,\n\t\topts: FlyCertificateOptions,\n\t) {\n\t\tconst { provider, app, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:Certificate\", name, {}, pulumiOpts);\n\n\t\tconst resource = new FlyCertificateResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tappName: app.id,\n\t\t\t\thostname: args.hostname,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = pulumi.output(args.hostname);\n\t\tthis.configured = resource.configured;\n\t\tthis.dnsRequirements = resource.dnsRequirements;\n\n\t\tthis.registerOutputs({\n\t\t\tid: this.id,\n\t\t\tconfigured: this.configured,\n\t\t\tdnsRequirements: this.dnsRequirements,\n\t\t});\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;AAoDA,IAAM,iCAAN,MAEA;CACC,MAAM,OACL,QACuC;EACvC,MAAM,SAAS,IAAIA,6BAAU,OAAO,KAAK;EACzC,MAAM,OAAO,YAAY,OAAO,QAAQ,gBAAgB,mBAAmB,OAAO,QAAQ;EAE1F,IAAI,OAAO,MAAM,OAAO,OAA+B,IAAI;EAE3D,IAAI,MACH,eAAO,IAAI,KAAK,sCAAsC,OAAO,SAAS,EAAE;OAExE,OAAO,MAAM,OAAO,KACnB,YAAY,OAAO,QAAQ,qBAC3B,EAAE,UAAU,OAAO,SAAS,CAC7B;EAGD,MAAM,OAA8B;GACnC,GAAG;GACH,YAAY,KAAK,cAAc;GAC/B,iBAAiB,KAAK,oBAAoB,CAAC;EAC5C;EAEA,OAAO;GAAE,IAAI,OAAO;GAAU;EAAK;CACpC;CAEA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,OAAO,MAAM,IAFAA,6BAAU,MAAM,KAEX,EAAE,OACzB,YAAY,MAAM,QAAQ,gBAAgB,mBAAmB,EAAE,GAChE;EAEA,IAAI,CAAC,MACJ,MAAM,IAAI,MAAM,oBAAoB,GAAG,2BAA2B;EAGnE,OAAO;GACN;GACA,OAAO;IACN,GAAG;IACH,YAAY,KAAK,cAAc;IAC/B,iBAAiB,KAAK,oBAAoB,CAAC;GAC5C;EACD;CACD;CAEA,MAAM,OACL,KACA,OACA,MACuC;EAEvC,OAAO,EACN,MAAM;GAAE,GAAG;GAAM,YAAY;GAAO,iBAAiB,CAAC;EAAE,EACzD;CACD;CAEA,MAAM,OAAO,IAAY,OAA6C;EAGrE,MAAM,IAFaA,6BAAU,MAAM,KAExB,EAAE,OACZ,YAAY,MAAM,QAAQ,gBAAgB,mBAAmB,EAAE,GAChE;CACD;CAEA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAE5B,IAAI,KAAK,YAAY,KAAK,SACzB,SAAS,KAAK,SAAS;EAGxB,IAAI,KAAK,aAAa,KAAK,UAC1B,SAAS,KAAK,UAAU;EAGzB,OAAO;GACN,SAAS,SAAS,SAAS;GAC3B;GACA,qBAAqB;EACtB;CACD;AACD;;AAGA,IAAM,yBAAN,cAAqCC,eAAO,QAAQ,SAAS;CAI5D,YACC,MACA,MAKA,MACC;EACD,MACC,IAAI,+BAA+B,GACnC,MACA;GAAE,GAAG;GAAM,YAAY;GAAW,iBAAiB;EAAU,GAC7D,IACD;CACD;AACD;;;;;;;;;;;;;;AAiCA,IAAa,iBAAb,cAAoCA,eAAO,kBAAkB;CAU5D,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,KAAK,GAAG,eAAe;EAEzC,MAAM,8BAA8B,MAAM,CAAC,GAAG,UAAU;EAExD,MAAM,WAAW,IAAI,uBACpB,GAAG,KAAK,YACR;GACC,OAAO,SAAS;GAChB,SAAS,IAAI;GACb,UAAU,KAAK;EAChB,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,KAAKA,eAAO,OAAO,KAAK,QAAQ;EACrC,KAAK,aAAa,SAAS;EAC3B,KAAK,kBAAkB,SAAS;EAEhC,KAAK,gBAAgB;GACpB,IAAI,KAAK;GACT,YAAY,KAAK;GACjB,iBAAiB,KAAK;EACvB,CAAC;CACF;AACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"certificate.d.cts","names":[],"sources":["../../src/fly/certificate.ts"],"mappings":";;;;;;;UAOiB,kBAAA;;EAEhB,cAAA;IAAmB,IAAA;IAAc,MAAA;EAAA;EAAjC;EAGA,SAAA;IAAc,IAAA;IAAc,SAAA;EAAA;EAAA;EAG5B,KAAA;AAAA;AAAK;AAAA,UAIW,oBAAA;EAAoB;EAEpC,KAAA;EAFoC;EAKpC,OAAA;EAAA;EAGA,QAAA;AAAA;AAAQ;AAAA,
|
|
1
|
+
{"version":3,"file":"certificate.d.cts","names":[],"sources":["../../src/fly/certificate.ts"],"mappings":";;;;;;;UAOiB,kBAAA;;EAEhB,cAAA;IAAmB,IAAA;IAAc,MAAA;EAAA;EAAjC;EAGA,SAAA;IAAc,IAAA;IAAc,SAAA;EAAA;EAAA;EAG5B,KAAA;AAAA;AAAK;AAAA,UAIW,oBAAA;EAAoB;EAEpC,KAAA;EAFoC;EAKpC,OAAA;EAAA;EAGA,QAAA;AAAA;AAAQ;AAAA,KAgJJ,qBAAA,GAAwB,IAAA,CAC5B,MAAA,CAAO,wBAAA;EADkB,kCAKzB,QAAA,EAAU,WAAA,EAJV;EAOA,GAAA,EAAK,MAAA;AAAA;;UAIW,kBAAA;EAJL;EAMX,QAAA,EAAU,MAAA,CAAO,KAAK;AAAA;;;;;;;AANX;AAIZ;;;;;;cAkBa,cAAA,SAAuB,MAAA,CAAO,iBAAA;EAhBpB;EAAA,SAkBN,EAAA,EAAI,MAAA,CAAO,MAAA;EAFf;EAAA,SAKI,UAAA,EAAY,MAAA,CAAO,MAAA;;WAGnB,eAAA,EAAiB,MAAA,CAAO,MAAA,CAAO,kBAAA;cAG9C,IAAA,UACA,IAAA,EAAM,kBAAA,EACN,IAAA,EAAM,qBAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"certificate.d.mts","names":[],"sources":["../../src/fly/certificate.ts"],"mappings":";;;;;;;UAOiB,kBAAA;;EAEhB,cAAA;IAAmB,IAAA;IAAc,MAAA;EAAA;EAAjC;EAGA,SAAA;IAAc,IAAA;IAAc,SAAA;EAAA;EAAA;EAG5B,KAAA;AAAA;AAAK;AAAA,UAIW,oBAAA;EAAoB;EAEpC,KAAA;EAFoC;EAKpC,OAAA;EAAA;EAGA,QAAA;AAAA;AAAQ;AAAA,
|
|
1
|
+
{"version":3,"file":"certificate.d.mts","names":[],"sources":["../../src/fly/certificate.ts"],"mappings":";;;;;;;UAOiB,kBAAA;;EAEhB,cAAA;IAAmB,IAAA;IAAc,MAAA;EAAA;EAAjC;EAGA,SAAA;IAAc,IAAA;IAAc,SAAA;EAAA;EAAA;EAG5B,KAAA;AAAA;AAAK;AAAA,UAIW,oBAAA;EAAoB;EAEpC,KAAA;EAFoC;EAKpC,OAAA;EAAA;EAGA,QAAA;AAAA;AAAQ;AAAA,KAgJJ,qBAAA,GAAwB,IAAA,CAC5B,MAAA,CAAO,wBAAA;EADkB,kCAKzB,QAAA,EAAU,WAAA,EAJV;EAOA,GAAA,EAAK,MAAA;AAAA;;UAIW,kBAAA;EAJL;EAMX,QAAA,EAAU,MAAA,CAAO,KAAK;AAAA;;;;;;;AANX;AAIZ;;;;;;cAkBa,cAAA,SAAuB,MAAA,CAAO,iBAAA;EAhBpB;EAAA,SAkBN,EAAA,EAAI,MAAA,CAAO,MAAA;EAFf;EAAA,SAKI,UAAA,EAAY,MAAA,CAAO,MAAA;;WAGnB,eAAA,EAAiB,MAAA,CAAO,MAAA,CAAO,kBAAA;cAG9C,IAAA,UACA,IAAA,EAAM,kBAAA,EACN,IAAA,EAAM,qBAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"certificate.mjs","names":[],"sources":["../../src/fly/certificate.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\n\nimport type { FlyApp } from \"./app\";\nimport { FlyClient } from \"./client\";\nimport type { FlyProvider } from \"./provider\";\n\n/** DNS records the consumer must create for certificate validation. */\nexport interface FlyDnsRequirements {\n\t/** ACME challenge CNAME record. */\n\tacme_challenge?: { name: string; target: string };\n\n\t/** `_fly-ownership` TXT record. */\n\townership?: { name: string; app_value: string };\n\n\t/** CNAME target for the hostname itself. */\n\tcname?: string;\n}\n\n/** Resolved inputs for the Fly certificate dynamic provider. */\nexport interface FlyCertificateInputs {\n\t/** Fly API token. */\n\ttoken: string;\n\n\t/** App name the certificate belongs to. */\n\tappName: string;\n\n\t/** Hostname to issue an ACME certificate for. Used as the resource key. */\n\thostname: string;\n}\n\n/** Persisted state for the Fly certificate. */\ninterface FlyCertificateOutputs extends FlyCertificateInputs {\n\t/** Whether the certificate is fully provisioned (DNS correct). */\n\tconfigured: boolean;\n\n\t/** DNS records required for validation. */\n\tdnsRequirements: FlyDnsRequirements;\n}\n\n/** Certificate response (only the fields we read). */\ninterface FlyCertificateResponse {\n\thostname: string;\n\tconfigured: boolean;\n\tdns_requirements?: FlyDnsRequirements;\n}\n\n/**\n * Dynamic provider for Fly ACME (Let's Encrypt) certificates. `create()` checks\n * for an existing cert by hostname and adopts it, otherwise it requests one via\n * `POST /v1/apps/{app}/certificates/acme`. The Machines API returns no `id` —\n * the hostname is the resource key.\n */\nclass FlyCertificateResourceProvider\n\timplements pulumi.dynamic.ResourceProvider\n{\n\tasync create(\n\t\tinputs: FlyCertificateInputs,\n\t): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new FlyClient(inputs.token);\n\t\tconst path = `/v1/apps/${inputs.appName}/certificates/${encodeURIComponent(inputs.hostname)}`;\n\n\t\tlet cert = await client.tryGet<FlyCertificateResponse>(path);\n\n\t\tif (cert) {\n\t\t\tpulumi.log.info(`Adopting existing Fly certificate \"${inputs.hostname}\"`);\n\t\t} else {\n\t\t\tcert = await client.post<FlyCertificateResponse>(\n\t\t\t\t`/v1/apps/${inputs.appName}/certificates/acme`,\n\t\t\t\t{ hostname: inputs.hostname },\n\t\t\t);\n\t\t}\n\n\t\tconst outs: FlyCertificateOutputs = {\n\t\t\t...inputs,\n\t\t\tconfigured: cert.configured ?? false,\n\t\t\tdnsRequirements: cert.dns_requirements ?? {},\n\t\t};\n\n\t\treturn { id: inputs.hostname, outs };\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: FlyCertificateOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tconst cert = await client.tryGet<FlyCertificateResponse>(\n\t\t\t`/v1/apps/${props.appName}/certificates/${encodeURIComponent(id)}`,\n\t\t);\n\n\t\tif (!cert) {\n\t\t\tthrow new Error(`Fly certificate \"${id}\" not found during refresh`);\n\t\t}\n\n\t\treturn {\n\t\t\tid,\n\t\t\tprops: {\n\t\t\t\t...props,\n\t\t\t\tconfigured: cert.configured ?? false,\n\t\t\t\tdnsRequirements: cert.dns_requirements ?? {},\n\t\t\t},\n\t\t};\n\t}\n\n\tasync update(\n\t\t_id: string,\n\t\t_olds: FlyCertificateOutputs,\n\t\tnews: FlyCertificateInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\t// Hostname/app changes force replacement (see diff); nothing else is updatable.\n\t\treturn {\n\t\t\touts: { ...news, configured: false, dnsRequirements: {} },\n\t\t};\n\t}\n\n\tasync delete(id: string, props: FlyCertificateOutputs): Promise<void> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tawait client.delete(\n\t\t\t`/v1/apps/${props.appName}/certificates/${encodeURIComponent(id)}`,\n\t\t);\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: FlyCertificateOutputs,\n\t\tnews: FlyCertificateInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.appName !== news.appName) {\n\t\t\treplaces.push(\"appName\");\n\t\t}\n\t\tif (olds.hostname !== news.hostname) {\n\t\t\treplaces.push(\"hostname\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.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 FlyCertificateResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly configured: pulumi.Output<boolean>;\n\tpublic declare readonly dnsRequirements: pulumi.Output<FlyDnsRequirements>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tappName: pulumi.Input<string>;\n\t\t\thostname: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew FlyCertificateResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, configured: undefined, dnsRequirements: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for FlyCertificate. */\ntype FlyCertificateOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Fly authentication context. */\n\tprovider: FlyProvider;\n\n\t/** App the certificate belongs to. */\n\tapp: FlyApp;\n};\n\n/** Args for FlyCertificate. */\nexport interface FlyCertificateArgs {\n\t/** Hostname to issue an ACME certificate for (e.g. `\"api.example.com\"`). */\n\thostname: pulumi.Input<string>;\n}\n\n/**\n * Manages a Fly ACME certificate for a custom hostname.\n *\n * Exposes `.configured` and `.dnsRequirements` so the consumer can wire up the\n * required DNS records.\n *\n * @example\n * ```typescript\n * const cert = new FlyCertificate(\"api-cert\", {\n * hostname: \"api.example.com\",\n * }, { provider, app });\n * ```\n */\nexport class FlyCertificate extends pulumi.ComponentResource {\n\t/** Certificate identifier (equals the hostname). */\n\tpublic readonly id: pulumi.Output<string>;\n\n\t/** Whether the certificate is fully provisioned. */\n\tpublic readonly configured: pulumi.Output<boolean>;\n\n\t/** DNS records required for validation. */\n\tpublic readonly dnsRequirements: pulumi.Output<FlyDnsRequirements>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: FlyCertificateArgs,\n\t\topts: FlyCertificateOptions,\n\t) {\n\t\tconst { provider, app, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:Certificate\", name, {}, pulumiOpts);\n\n\t\tconst resource = new FlyCertificateResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tappName: app.id,\n\t\t\t\thostname: args.hostname,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = pulumi.output(args.hostname);\n\t\tthis.configured = resource.configured;\n\t\tthis.dnsRequirements = resource.dnsRequirements;\n\n\t\tthis.registerOutputs({\n\t\t\tid: this.id,\n\t\t\tconfigured: this.configured,\n\t\t\tdnsRequirements: this.dnsRequirements,\n\t\t});\n\t}\n}\n"],"mappings":";;;;;;;;;;;AAoDA,IAAM,iCAAN,MAEA;CACC,MAAM,OACL,QACuC;EACvC,MAAM,SAAS,IAAI,UAAU,OAAO,KAAK;EACzC,MAAM,OAAO,YAAY,OAAO,QAAQ,gBAAgB,mBAAmB,OAAO,QAAQ;EAE1F,IAAI,OAAO,MAAM,OAAO,OAA+B,IAAI;EAE3D,IAAI,MACH,OAAO,IAAI,KAAK,sCAAsC,OAAO,SAAS,EAAE;OAExE,OAAO,MAAM,OAAO,KACnB,YAAY,OAAO,QAAQ,qBAC3B,EAAE,UAAU,OAAO,SAAS,CAC7B;EAGD,MAAM,OAA8B;GACnC,GAAG;GACH,YAAY,KAAK,cAAc;GAC/B,iBAAiB,KAAK,oBAAoB,CAAC;EAC5C;EAEA,OAAO;GAAE,IAAI,OAAO;GAAU;EAAK;CACpC;CAEA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,OAAO,MAAM,IAFA,UAAU,MAAM,KAEX,EAAE,OACzB,YAAY,MAAM,QAAQ,gBAAgB,mBAAmB,EAAE,GAChE;EAEA,IAAI,CAAC,MACJ,MAAM,IAAI,MAAM,oBAAoB,GAAG,2BAA2B;EAGnE,OAAO;GACN;GACA,OAAO;IACN,GAAG;IACH,YAAY,KAAK,cAAc;IAC/B,iBAAiB,KAAK,oBAAoB,CAAC;GAC5C;EACD;CACD;CAEA,MAAM,OACL,KACA,OACA,MACuC;EAEvC,OAAO,EACN,MAAM;GAAE,GAAG;GAAM,YAAY;GAAO,iBAAiB,CAAC;EAAE,EACzD;CACD;CAEA,MAAM,OAAO,IAAY,OAA6C;EAGrE,MAAM,IAFa,UAAU,MAAM,KAExB,EAAE,OACZ,YAAY,MAAM,QAAQ,gBAAgB,mBAAmB,EAAE,GAChE;CACD;CAEA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAE5B,IAAI,KAAK,YAAY,KAAK,SACzB,SAAS,KAAK,SAAS;
|
|
1
|
+
{"version":3,"file":"certificate.mjs","names":[],"sources":["../../src/fly/certificate.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\n\nimport type { FlyApp } from \"./app\";\nimport { FlyClient } from \"./client\";\nimport type { FlyProvider } from \"./provider\";\n\n/** DNS records the consumer must create for certificate validation. */\nexport interface FlyDnsRequirements {\n\t/** ACME challenge CNAME record. */\n\tacme_challenge?: { name: string; target: string };\n\n\t/** `_fly-ownership` TXT record. */\n\townership?: { name: string; app_value: string };\n\n\t/** CNAME target for the hostname itself. */\n\tcname?: string;\n}\n\n/** Resolved inputs for the Fly certificate dynamic provider. */\nexport interface FlyCertificateInputs {\n\t/** Fly API token. */\n\ttoken: string;\n\n\t/** App name the certificate belongs to. */\n\tappName: string;\n\n\t/** Hostname to issue an ACME certificate for. Used as the resource key. */\n\thostname: string;\n}\n\n/** Persisted state for the Fly certificate. */\ninterface FlyCertificateOutputs extends FlyCertificateInputs {\n\t/** Whether the certificate is fully provisioned (DNS correct). */\n\tconfigured: boolean;\n\n\t/** DNS records required for validation. */\n\tdnsRequirements: FlyDnsRequirements;\n}\n\n/** Certificate response (only the fields we read). */\ninterface FlyCertificateResponse {\n\thostname: string;\n\tconfigured: boolean;\n\tdns_requirements?: FlyDnsRequirements;\n}\n\n/**\n * Dynamic provider for Fly ACME (Let's Encrypt) certificates. `create()` checks\n * for an existing cert by hostname and adopts it, otherwise it requests one via\n * `POST /v1/apps/{app}/certificates/acme`. The Machines API returns no `id` —\n * the hostname is the resource key.\n */\nclass FlyCertificateResourceProvider\n\timplements pulumi.dynamic.ResourceProvider\n{\n\tasync create(\n\t\tinputs: FlyCertificateInputs,\n\t): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new FlyClient(inputs.token);\n\t\tconst path = `/v1/apps/${inputs.appName}/certificates/${encodeURIComponent(inputs.hostname)}`;\n\n\t\tlet cert = await client.tryGet<FlyCertificateResponse>(path);\n\n\t\tif (cert) {\n\t\t\tpulumi.log.info(`Adopting existing Fly certificate \"${inputs.hostname}\"`);\n\t\t} else {\n\t\t\tcert = await client.post<FlyCertificateResponse>(\n\t\t\t\t`/v1/apps/${inputs.appName}/certificates/acme`,\n\t\t\t\t{ hostname: inputs.hostname },\n\t\t\t);\n\t\t}\n\n\t\tconst outs: FlyCertificateOutputs = {\n\t\t\t...inputs,\n\t\t\tconfigured: cert.configured ?? false,\n\t\t\tdnsRequirements: cert.dns_requirements ?? {},\n\t\t};\n\n\t\treturn { id: inputs.hostname, outs };\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: FlyCertificateOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tconst cert = await client.tryGet<FlyCertificateResponse>(\n\t\t\t`/v1/apps/${props.appName}/certificates/${encodeURIComponent(id)}`,\n\t\t);\n\n\t\tif (!cert) {\n\t\t\tthrow new Error(`Fly certificate \"${id}\" not found during refresh`);\n\t\t}\n\n\t\treturn {\n\t\t\tid,\n\t\t\tprops: {\n\t\t\t\t...props,\n\t\t\t\tconfigured: cert.configured ?? false,\n\t\t\t\tdnsRequirements: cert.dns_requirements ?? {},\n\t\t\t},\n\t\t};\n\t}\n\n\tasync update(\n\t\t_id: string,\n\t\t_olds: FlyCertificateOutputs,\n\t\tnews: FlyCertificateInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\t// Hostname/app changes force replacement (see diff); nothing else is updatable.\n\t\treturn {\n\t\t\touts: { ...news, configured: false, dnsRequirements: {} },\n\t\t};\n\t}\n\n\tasync delete(id: string, props: FlyCertificateOutputs): Promise<void> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tawait client.delete(\n\t\t\t`/v1/apps/${props.appName}/certificates/${encodeURIComponent(id)}`,\n\t\t);\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: FlyCertificateOutputs,\n\t\tnews: FlyCertificateInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.appName !== news.appName) {\n\t\t\treplaces.push(\"appName\");\n\t\t}\n\n\t\tif (olds.hostname !== news.hostname) {\n\t\t\treplaces.push(\"hostname\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.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 FlyCertificateResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly configured: pulumi.Output<boolean>;\n\tpublic declare readonly dnsRequirements: pulumi.Output<FlyDnsRequirements>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tappName: pulumi.Input<string>;\n\t\t\thostname: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew FlyCertificateResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, configured: undefined, dnsRequirements: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for FlyCertificate. */\ntype FlyCertificateOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Fly authentication context. */\n\tprovider: FlyProvider;\n\n\t/** App the certificate belongs to. */\n\tapp: FlyApp;\n};\n\n/** Args for FlyCertificate. */\nexport interface FlyCertificateArgs {\n\t/** Hostname to issue an ACME certificate for (e.g. `\"api.example.com\"`). */\n\thostname: pulumi.Input<string>;\n}\n\n/**\n * Manages a Fly ACME certificate for a custom hostname.\n *\n * Exposes `.configured` and `.dnsRequirements` so the consumer can wire up the\n * required DNS records.\n *\n * @example\n * ```typescript\n * const cert = new FlyCertificate(\"api-cert\", {\n * hostname: \"api.example.com\",\n * }, { provider, app });\n * ```\n */\nexport class FlyCertificate extends pulumi.ComponentResource {\n\t/** Certificate identifier (equals the hostname). */\n\tpublic readonly id: pulumi.Output<string>;\n\n\t/** Whether the certificate is fully provisioned. */\n\tpublic readonly configured: pulumi.Output<boolean>;\n\n\t/** DNS records required for validation. */\n\tpublic readonly dnsRequirements: pulumi.Output<FlyDnsRequirements>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: FlyCertificateArgs,\n\t\topts: FlyCertificateOptions,\n\t) {\n\t\tconst { provider, app, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:Certificate\", name, {}, pulumiOpts);\n\n\t\tconst resource = new FlyCertificateResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tappName: app.id,\n\t\t\t\thostname: args.hostname,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = pulumi.output(args.hostname);\n\t\tthis.configured = resource.configured;\n\t\tthis.dnsRequirements = resource.dnsRequirements;\n\n\t\tthis.registerOutputs({\n\t\t\tid: this.id,\n\t\t\tconfigured: this.configured,\n\t\t\tdnsRequirements: this.dnsRequirements,\n\t\t});\n\t}\n}\n"],"mappings":";;;;;;;;;;;AAoDA,IAAM,iCAAN,MAEA;CACC,MAAM,OACL,QACuC;EACvC,MAAM,SAAS,IAAI,UAAU,OAAO,KAAK;EACzC,MAAM,OAAO,YAAY,OAAO,QAAQ,gBAAgB,mBAAmB,OAAO,QAAQ;EAE1F,IAAI,OAAO,MAAM,OAAO,OAA+B,IAAI;EAE3D,IAAI,MACH,OAAO,IAAI,KAAK,sCAAsC,OAAO,SAAS,EAAE;OAExE,OAAO,MAAM,OAAO,KACnB,YAAY,OAAO,QAAQ,qBAC3B,EAAE,UAAU,OAAO,SAAS,CAC7B;EAGD,MAAM,OAA8B;GACnC,GAAG;GACH,YAAY,KAAK,cAAc;GAC/B,iBAAiB,KAAK,oBAAoB,CAAC;EAC5C;EAEA,OAAO;GAAE,IAAI,OAAO;GAAU;EAAK;CACpC;CAEA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,OAAO,MAAM,IAFA,UAAU,MAAM,KAEX,EAAE,OACzB,YAAY,MAAM,QAAQ,gBAAgB,mBAAmB,EAAE,GAChE;EAEA,IAAI,CAAC,MACJ,MAAM,IAAI,MAAM,oBAAoB,GAAG,2BAA2B;EAGnE,OAAO;GACN;GACA,OAAO;IACN,GAAG;IACH,YAAY,KAAK,cAAc;IAC/B,iBAAiB,KAAK,oBAAoB,CAAC;GAC5C;EACD;CACD;CAEA,MAAM,OACL,KACA,OACA,MACuC;EAEvC,OAAO,EACN,MAAM;GAAE,GAAG;GAAM,YAAY;GAAO,iBAAiB,CAAC;EAAE,EACzD;CACD;CAEA,MAAM,OAAO,IAAY,OAA6C;EAGrE,MAAM,IAFa,UAAU,MAAM,KAExB,EAAE,OACZ,YAAY,MAAM,QAAQ,gBAAgB,mBAAmB,EAAE,GAChE;CACD;CAEA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAE5B,IAAI,KAAK,YAAY,KAAK,SACzB,SAAS,KAAK,SAAS;EAGxB,IAAI,KAAK,aAAa,KAAK,UAC1B,SAAS,KAAK,UAAU;EAGzB,OAAO;GACN,SAAS,SAAS,SAAS;GAC3B;GACA,qBAAqB;EACtB;CACD;AACD;;AAGA,IAAM,yBAAN,cAAqC,OAAO,QAAQ,SAAS;CAI5D,YACC,MACA,MAKA,MACC;EACD,MACC,IAAI,+BAA+B,GACnC,MACA;GAAE,GAAG;GAAM,YAAY;GAAW,iBAAiB;EAAU,GAC7D,IACD;CACD;AACD;;;;;;;;;;;;;;AAiCA,IAAa,iBAAb,cAAoC,OAAO,kBAAkB;CAU5D,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,KAAK,GAAG,eAAe;EAEzC,MAAM,8BAA8B,MAAM,CAAC,GAAG,UAAU;EAExD,MAAM,WAAW,IAAI,uBACpB,GAAG,KAAK,YACR;GACC,OAAO,SAAS;GAChB,SAAS,IAAI;GACb,UAAU,KAAK;EAChB,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,KAAK,OAAO,OAAO,KAAK,QAAQ;EACrC,KAAK,aAAa,SAAS;EAC3B,KAAK,kBAAkB,SAAS;EAEhC,KAAK,gBAAgB;GACpB,IAAI,KAAK;GACT,YAAY,KAAK;GACjB,iBAAiB,KAAK;EACvB,CAAC;CACF;AACD"}
|
package/dist/fly/ip.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ip.cjs","names":["FlyClient","pulumi"],"sources":["../../src/fly/ip.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\n\nimport type { FlyApp } from \"./app\";\nimport { FlyClient } from \"./client\";\nimport type { FlyProvider } from \"./provider\";\n\n/**\n * Fly IP address type. Enum keys UPPERCASE; values are Fly's GraphQL enum\n * literals (lowercase wire format).\n */\nexport enum FlyIpType {\n\tV4 = \"v4\",\n\tV6 = \"v6\",\n\tSHARED_V4 = \"shared_v4\",\n\tPRIVATE_V6 = \"private_v6\",\n}\n\n/** Resolved inputs for the Fly IP dynamic provider. */\nexport interface FlyIpInputs {\n\t/** Fly API token. */\n\ttoken: string;\n\n\t/** App name (used as GraphQL appId). */\n\tappName: string;\n\n\t/** IP address type. */\n\ttype: FlyIpType;\n\n\t/** Region (IATA code); omit for global. */\n\tregion?: string;\n}\n\n/** Persisted state for the Fly IP. */\ninterface FlyIpOutputs extends FlyIpInputs {\n\t/** Allocated IP address (also the `.id`). */\n\taddress: string;\n\n\t/** GraphQL node ID, when present (absent for `shared_v4`). */\n\tipAddressId?: string;\n}\n\nconst LIST_IPS = `\n\tquery ($appName: String!) {\n\t\tapp(name: $appName) {\n\t\t\tsharedIpAddress\n\t\t\tipAddresses {\n\t\t\t\tnodes { id address type region }\n\t\t\t}\n\t\t}\n\t}\n`;\n\nconst ALLOCATE_IP = `\n\tmutation ($input: AllocateIPAddressInput!) {\n\t\tallocateIpAddress(input: $input) {\n\t\t\tipAddress { id address type region }\n\t\t\tapp { sharedIpAddress }\n\t\t}\n\t}\n`;\n\nconst RELEASE_IP = `\n\tmutation ($input: ReleaseIPAddressInput!) {\n\t\treleaseIpAddress(input: $input) { clientMutationId }\n\t}\n`;\n\ninterface IpNode {\n\tid: string;\n\taddress: string;\n\ttype: string;\n\tregion: string | null;\n}\n\ninterface ListIpsResult {\n\tapp: {\n\t\tsharedIpAddress: string | null;\n\t\tipAddresses: { nodes: IpNode[] };\n\t};\n}\n\ninterface AllocateResult {\n\tallocateIpAddress: {\n\t\tipAddress: IpNode | null;\n\t\tapp: { sharedIpAddress: string | null };\n\t};\n}\n\n/**\n * Dynamic provider for Fly dedicated/shared IP allocation via the Fly GraphQL\n * API. `create()` queries existing IPs and adopts a matching one, otherwise it\n * allocates. `shared_v4` allocations return a null `ipAddress` in the payload —\n * the address is read from `app.sharedIpAddress`.\n */\nclass FlyIpResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(inputs: FlyIpInputs): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new FlyClient(inputs.token);\n\n\t\tconst existing = await this.findExisting(client, inputs);\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopting existing Fly ${inputs.type} IP \"${existing.address}\"`,\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tid: existing.address,\n\t\t\t\touts: {\n\t\t\t\t\t...inputs,\n\t\t\t\t\taddress: existing.address,\n\t\t\t\t\tipAddressId: existing.ipAddressId,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst result = await client.graphql<AllocateResult>(ALLOCATE_IP, {\n\t\t\tinput: {\n\t\t\t\tappId: inputs.appName,\n\t\t\t\ttype: inputs.type,\n\t\t\t\tregion: inputs.region,\n\t\t\t},\n\t\t});\n\n\t\tconst node = result.allocateIpAddress.ipAddress;\n\n\t\tconst address =\n\t\t\tinputs.type === FlyIpType.SHARED_V4\n\t\t\t\t? (result.allocateIpAddress.app.sharedIpAddress ?? \"\")\n\t\t\t\t: (node?.address ?? \"\");\n\n\t\tif (!address) {\n\t\t\tthrow new Error(\n\t\t\t\t`Fly IP allocation for app \"${inputs.appName}\" (${inputs.type}) returned no address`,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tid: address,\n\t\t\touts: { ...inputs, address, ipAddressId: node?.id },\n\t\t};\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: FlyIpOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\treturn { id, props };\n\t}\n\n\tasync delete(_id: string, props: FlyIpOutputs): Promise<void> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tconst input: Record<string, string> = { appId: props.appName };\n\n\t\tif (props.ipAddressId) {\n\t\t\tinput.ipAddressId = props.ipAddressId;\n\t\t} else {\n\t\t\tinput.ip = props.address;\n\t\t}\n\n\t\tawait client.graphql(RELEASE_IP, { input });\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: FlyIpOutputs,\n\t\tnews: FlyIpInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.appName !== news.appName) {\n\t\t\treplaces.push(\"appName\");\n\t\t}\n\t\tif (olds.type !== news.type) {\n\t\t\treplaces.push(\"type\");\n\t\t}\n\t\tif (olds.region !== news.region) {\n\t\t\treplaces.push(\"region\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n\n\tprivate async findExisting(\n\t\tclient: FlyClient,\n\t\tinputs: FlyIpInputs,\n\t): Promise<{ address: string; ipAddressId?: string } | null> {\n\t\tconst result = await client.graphql<ListIpsResult>(LIST_IPS, {\n\t\t\tappName: inputs.appName,\n\t\t});\n\n\t\tif (inputs.type === FlyIpType.SHARED_V4) {\n\t\t\tconst shared = result.app.sharedIpAddress;\n\n\t\t\treturn shared ? { address: shared } : null;\n\t\t}\n\n\t\tconst match = result.app.ipAddresses.nodes.find(\n\t\t\t(node) =>\n\t\t\t\tnode.type === inputs.type &&\n\t\t\t\t(inputs.region === undefined || node.region === inputs.region),\n\t\t);\n\n\t\treturn match ? { address: match.address, ipAddressId: match.id } : null;\n\t}\n}\n\n/** Internal dynamic resource — not part of the public API. */\nclass FlyIpResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly address: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tappName: pulumi.Input<string>;\n\t\t\ttype: pulumi.Input<FlyIpType>;\n\t\t\tregion?: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew FlyIpResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, address: undefined, ipAddressId: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for FlyIp. */\ntype FlyIpOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Fly authentication context. */\n\tprovider: FlyProvider;\n\n\t/** App the IP belongs to. */\n\tapp: FlyApp;\n};\n\n/** Args for FlyIp. */\nexport interface FlyIpArgs {\n\t/** IP address type. */\n\ttype: pulumi.Input<FlyIpType>;\n\n\t/** Region (IATA code); omit for a global address. */\n\tregion?: pulumi.Input<string>;\n}\n\n/**\n * Allocates a Fly IP address (dedicated or shared) via the Fly GraphQL API.\n *\n * @example\n * ```typescript\n * const ip = new FlyIp(\"api-ip\", { type: FlyIpType.SHARED_V4 }, { provider, app });\n * ```\n */\nexport class FlyIp extends pulumi.ComponentResource {\n\t/** Allocated IP address. */\n\tpublic readonly id: pulumi.Output<string>;\n\n\tconstructor(name: string, args: FlyIpArgs, opts: FlyIpOptions) {\n\t\tconst { provider, app, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:Ip\", name, {}, pulumiOpts);\n\n\t\tconst resource = new FlyIpResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tappName: app.id,\n\t\t\t\ttype: args.type,\n\t\t\t\tregion: args.region,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = resource.address;\n\n\t\tthis.registerOutputs({ id: this.id });\n\t}\n}\n"],"mappings":";;;;;;;;;;;AAUA,IAAY,YAAL;CACN;CACA;CACA;CACA;;AACD;AA0BA,MAAM,WAAW;;;;;;;;;;AAWjB,MAAM,cAAc;;;;;;;;AASpB,MAAM,aAAa;;;;;;;;;;;AAiCnB,IAAM,wBAAN,MAAuE;CACtE,MAAM,OAAO,QAA2D;EACvE,MAAM,SAAS,IAAIA,6BAAU,OAAO,KAAK;EAEzC,MAAM,WAAW,MAAM,KAAK,aAAa,QAAQ,MAAM;EAEvD,IAAI,UAAU;GACb,eAAO,IAAI,KACV,yBAAyB,OAAO,KAAK,OAAO,SAAS,QAAQ,EAC9D;GAEA,OAAO;IACN,IAAI,SAAS;IACb,MAAM;KACL,GAAG;KACH,SAAS,SAAS;KAClB,aAAa,SAAS;IACvB;GACD;EACD;EAEA,MAAM,SAAS,MAAM,OAAO,QAAwB,aAAa,EAChE,OAAO;GACN,OAAO,OAAO;GACd,MAAM,OAAO;GACb,QAAQ,OAAO;EAChB,EACD,CAAC;EAED,MAAM,OAAO,OAAO,kBAAkB;EAEtC,MAAM,UACL,OAAO,uBACH,OAAO,kBAAkB,IAAI,mBAAmB,KAChD,MAAM,WAAW;EAEtB,IAAI,CAAC,SACJ,MAAM,IAAI,MACT,8BAA8B,OAAO,QAAQ,KAAK,OAAO,KAAK,sBAC/D;EAGD,OAAO;GACN,IAAI;GACJ,MAAM;IAAE,GAAG;IAAQ;IAAS,aAAa,MAAM;GAAG;EACnD;CACD;CAEA,MAAM,KACL,IACA,OACqC;EACrC,OAAO;GAAE;GAAI;EAAM;CACpB;CAEA,MAAM,OAAO,KAAa,OAAoC;EAC7D,MAAM,SAAS,IAAIA,6BAAU,MAAM,KAAK;EAExC,MAAM,QAAgC,EAAE,OAAO,MAAM,QAAQ;EAE7D,IAAI,MAAM,aACT,MAAM,cAAc,MAAM;OAE1B,MAAM,KAAK,MAAM;EAGlB,MAAM,OAAO,QAAQ,YAAY,EAAE,MAAM,CAAC;CAC3C;CAEA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAE5B,IAAI,KAAK,YAAY,KAAK,SACzB,SAAS,KAAK,SAAS;
|
|
1
|
+
{"version":3,"file":"ip.cjs","names":["FlyClient","pulumi"],"sources":["../../src/fly/ip.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\n\nimport type { FlyApp } from \"./app\";\nimport { FlyClient } from \"./client\";\nimport type { FlyProvider } from \"./provider\";\n\n/**\n * Fly IP address type. Enum keys UPPERCASE; values are Fly's GraphQL enum\n * literals (lowercase wire format).\n */\nexport enum FlyIpType {\n\tV4 = \"v4\",\n\tV6 = \"v6\",\n\tSHARED_V4 = \"shared_v4\",\n\tPRIVATE_V6 = \"private_v6\",\n}\n\n/** Resolved inputs for the Fly IP dynamic provider. */\nexport interface FlyIpInputs {\n\t/** Fly API token. */\n\ttoken: string;\n\n\t/** App name (used as GraphQL appId). */\n\tappName: string;\n\n\t/** IP address type. */\n\ttype: FlyIpType;\n\n\t/** Region (IATA code); omit for global. */\n\tregion?: string;\n}\n\n/** Persisted state for the Fly IP. */\ninterface FlyIpOutputs extends FlyIpInputs {\n\t/** Allocated IP address (also the `.id`). */\n\taddress: string;\n\n\t/** GraphQL node ID, when present (absent for `shared_v4`). */\n\tipAddressId?: string;\n}\n\nconst LIST_IPS = `\n\tquery ($appName: String!) {\n\t\tapp(name: $appName) {\n\t\t\tsharedIpAddress\n\t\t\tipAddresses {\n\t\t\t\tnodes { id address type region }\n\t\t\t}\n\t\t}\n\t}\n`;\n\nconst ALLOCATE_IP = `\n\tmutation ($input: AllocateIPAddressInput!) {\n\t\tallocateIpAddress(input: $input) {\n\t\t\tipAddress { id address type region }\n\t\t\tapp { sharedIpAddress }\n\t\t}\n\t}\n`;\n\nconst RELEASE_IP = `\n\tmutation ($input: ReleaseIPAddressInput!) {\n\t\treleaseIpAddress(input: $input) { clientMutationId }\n\t}\n`;\n\ninterface IpNode {\n\tid: string;\n\taddress: string;\n\ttype: string;\n\tregion: string | null;\n}\n\ninterface ListIpsResult {\n\tapp: {\n\t\tsharedIpAddress: string | null;\n\t\tipAddresses: { nodes: IpNode[] };\n\t};\n}\n\ninterface AllocateResult {\n\tallocateIpAddress: {\n\t\tipAddress: IpNode | null;\n\t\tapp: { sharedIpAddress: string | null };\n\t};\n}\n\n/**\n * Dynamic provider for Fly dedicated/shared IP allocation via the Fly GraphQL\n * API. `create()` queries existing IPs and adopts a matching one, otherwise it\n * allocates. `shared_v4` allocations return a null `ipAddress` in the payload —\n * the address is read from `app.sharedIpAddress`.\n */\nclass FlyIpResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(inputs: FlyIpInputs): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new FlyClient(inputs.token);\n\n\t\tconst existing = await this.findExisting(client, inputs);\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopting existing Fly ${inputs.type} IP \"${existing.address}\"`,\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tid: existing.address,\n\t\t\t\touts: {\n\t\t\t\t\t...inputs,\n\t\t\t\t\taddress: existing.address,\n\t\t\t\t\tipAddressId: existing.ipAddressId,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst result = await client.graphql<AllocateResult>(ALLOCATE_IP, {\n\t\t\tinput: {\n\t\t\t\tappId: inputs.appName,\n\t\t\t\ttype: inputs.type,\n\t\t\t\tregion: inputs.region,\n\t\t\t},\n\t\t});\n\n\t\tconst node = result.allocateIpAddress.ipAddress;\n\n\t\tconst address =\n\t\t\tinputs.type === FlyIpType.SHARED_V4\n\t\t\t\t? (result.allocateIpAddress.app.sharedIpAddress ?? \"\")\n\t\t\t\t: (node?.address ?? \"\");\n\n\t\tif (!address) {\n\t\t\tthrow new Error(\n\t\t\t\t`Fly IP allocation for app \"${inputs.appName}\" (${inputs.type}) returned no address`,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tid: address,\n\t\t\touts: { ...inputs, address, ipAddressId: node?.id },\n\t\t};\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: FlyIpOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\treturn { id, props };\n\t}\n\n\tasync delete(_id: string, props: FlyIpOutputs): Promise<void> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tconst input: Record<string, string> = { appId: props.appName };\n\n\t\tif (props.ipAddressId) {\n\t\t\tinput.ipAddressId = props.ipAddressId;\n\t\t} else {\n\t\t\tinput.ip = props.address;\n\t\t}\n\n\t\tawait client.graphql(RELEASE_IP, { input });\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: FlyIpOutputs,\n\t\tnews: FlyIpInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.appName !== news.appName) {\n\t\t\treplaces.push(\"appName\");\n\t\t}\n\n\t\tif (olds.type !== news.type) {\n\t\t\treplaces.push(\"type\");\n\t\t}\n\n\t\tif (olds.region !== news.region) {\n\t\t\treplaces.push(\"region\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n\n\tprivate async findExisting(\n\t\tclient: FlyClient,\n\t\tinputs: FlyIpInputs,\n\t): Promise<{ address: string; ipAddressId?: string } | null> {\n\t\tconst result = await client.graphql<ListIpsResult>(LIST_IPS, {\n\t\t\tappName: inputs.appName,\n\t\t});\n\n\t\tif (inputs.type === FlyIpType.SHARED_V4) {\n\t\t\tconst shared = result.app.sharedIpAddress;\n\n\t\t\treturn shared ? { address: shared } : null;\n\t\t}\n\n\t\tconst match = result.app.ipAddresses.nodes.find(\n\t\t\t(node) =>\n\t\t\t\tnode.type === inputs.type &&\n\t\t\t\t(inputs.region === undefined || node.region === inputs.region),\n\t\t);\n\n\t\treturn match ? { address: match.address, ipAddressId: match.id } : null;\n\t}\n}\n\n/** Internal dynamic resource — not part of the public API. */\nclass FlyIpResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly address: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tappName: pulumi.Input<string>;\n\t\t\ttype: pulumi.Input<FlyIpType>;\n\t\t\tregion?: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew FlyIpResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, address: undefined, ipAddressId: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for FlyIp. */\ntype FlyIpOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Fly authentication context. */\n\tprovider: FlyProvider;\n\n\t/** App the IP belongs to. */\n\tapp: FlyApp;\n};\n\n/** Args for FlyIp. */\nexport interface FlyIpArgs {\n\t/** IP address type. */\n\ttype: pulumi.Input<FlyIpType>;\n\n\t/** Region (IATA code); omit for a global address. */\n\tregion?: pulumi.Input<string>;\n}\n\n/**\n * Allocates a Fly IP address (dedicated or shared) via the Fly GraphQL API.\n *\n * @example\n * ```typescript\n * const ip = new FlyIp(\"api-ip\", { type: FlyIpType.SHARED_V4 }, { provider, app });\n * ```\n */\nexport class FlyIp extends pulumi.ComponentResource {\n\t/** Allocated IP address. */\n\tpublic readonly id: pulumi.Output<string>;\n\n\tconstructor(name: string, args: FlyIpArgs, opts: FlyIpOptions) {\n\t\tconst { provider, app, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:Ip\", name, {}, pulumiOpts);\n\n\t\tconst resource = new FlyIpResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tappName: app.id,\n\t\t\t\ttype: args.type,\n\t\t\t\tregion: args.region,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = resource.address;\n\n\t\tthis.registerOutputs({ id: this.id });\n\t}\n}\n"],"mappings":"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"}
|
package/dist/fly/ip.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ip.d.cts","names":[],"sources":["../../src/fly/ip.ts"],"mappings":";;;;;;;;;AAUA;aAAY,SAAA;EACX,EAAA;EACA,EAAA;EACA,SAAA;EACA,UAAA;AAAA;;UAIgB,WAAA;EAJN;EAMV,KAAA;EAF2B;EAK3B,OAAA;EAGe;EAAf,IAAA,EAAM,SAAS;EAHf;EAMA,MAAA;AAAA;;
|
|
1
|
+
{"version":3,"file":"ip.d.cts","names":[],"sources":["../../src/fly/ip.ts"],"mappings":";;;;;;;;;AAUA;aAAY,SAAA;EACX,EAAA;EACA,EAAA;EACA,SAAA;EACA,UAAA;AAAA;;UAIgB,WAAA;EAJN;EAMV,KAAA;EAF2B;EAK3B,OAAA;EAGe;EAAf,IAAA,EAAM,SAAS;EAHf;EAMA,MAAA;AAAA;;KAgNI,YAAA,GAAe,IAAA,CAAK,MAAA,CAAO,wBAAA;EAhNzB,kCAkNN,QAAA,EAAU,WAAA,EAFM;EAKhB,GAAA,EAAK,MAAA;AAAA;;UAIW,SAAA;EAJX;EAML,IAAA,EAAM,MAAA,CAAO,KAAA,CAAM,SAAA;EANR;EASX,MAAA,GAAS,MAAA,CAAO,KAAA;AAAA;;;;;;;AATL;AAIZ;cAgBa,KAAA,SAAc,MAAA,CAAO,iBAAA;;WAEjB,EAAA,EAAI,MAAA,CAAO,MAAA;cAEf,IAAA,UAAc,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,YAAA;AAAA"}
|
package/dist/fly/ip.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ip.d.mts","names":[],"sources":["../../src/fly/ip.ts"],"mappings":";;;;;;;;;AAUA;aAAY,SAAA;EACX,EAAA;EACA,EAAA;EACA,SAAA;EACA,UAAA;AAAA;;UAIgB,WAAA;EAJN;EAMV,KAAA;EAF2B;EAK3B,OAAA;EAGe;EAAf,IAAA,EAAM,SAAS;EAHf;EAMA,MAAA;AAAA;;
|
|
1
|
+
{"version":3,"file":"ip.d.mts","names":[],"sources":["../../src/fly/ip.ts"],"mappings":";;;;;;;;;AAUA;aAAY,SAAA;EACX,EAAA;EACA,EAAA;EACA,SAAA;EACA,UAAA;AAAA;;UAIgB,WAAA;EAJN;EAMV,KAAA;EAF2B;EAK3B,OAAA;EAGe;EAAf,IAAA,EAAM,SAAS;EAHf;EAMA,MAAA;AAAA;;KAgNI,YAAA,GAAe,IAAA,CAAK,MAAA,CAAO,wBAAA;EAhNzB,kCAkNN,QAAA,EAAU,WAAA,EAFM;EAKhB,GAAA,EAAK,MAAA;AAAA;;UAIW,SAAA;EAJX;EAML,IAAA,EAAM,MAAA,CAAO,KAAA,CAAM,SAAA;EANR;EASX,MAAA,GAAS,MAAA,CAAO,KAAA;AAAA;;;;;;;AATL;AAIZ;cAgBa,KAAA,SAAc,MAAA,CAAO,iBAAA;;WAEjB,EAAA,EAAI,MAAA,CAAO,MAAA;cAEf,IAAA,UAAc,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,YAAA;AAAA"}
|
package/dist/fly/ip.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ip.mjs","names":[],"sources":["../../src/fly/ip.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\n\nimport type { FlyApp } from \"./app\";\nimport { FlyClient } from \"./client\";\nimport type { FlyProvider } from \"./provider\";\n\n/**\n * Fly IP address type. Enum keys UPPERCASE; values are Fly's GraphQL enum\n * literals (lowercase wire format).\n */\nexport enum FlyIpType {\n\tV4 = \"v4\",\n\tV6 = \"v6\",\n\tSHARED_V4 = \"shared_v4\",\n\tPRIVATE_V6 = \"private_v6\",\n}\n\n/** Resolved inputs for the Fly IP dynamic provider. */\nexport interface FlyIpInputs {\n\t/** Fly API token. */\n\ttoken: string;\n\n\t/** App name (used as GraphQL appId). */\n\tappName: string;\n\n\t/** IP address type. */\n\ttype: FlyIpType;\n\n\t/** Region (IATA code); omit for global. */\n\tregion?: string;\n}\n\n/** Persisted state for the Fly IP. */\ninterface FlyIpOutputs extends FlyIpInputs {\n\t/** Allocated IP address (also the `.id`). */\n\taddress: string;\n\n\t/** GraphQL node ID, when present (absent for `shared_v4`). */\n\tipAddressId?: string;\n}\n\nconst LIST_IPS = `\n\tquery ($appName: String!) {\n\t\tapp(name: $appName) {\n\t\t\tsharedIpAddress\n\t\t\tipAddresses {\n\t\t\t\tnodes { id address type region }\n\t\t\t}\n\t\t}\n\t}\n`;\n\nconst ALLOCATE_IP = `\n\tmutation ($input: AllocateIPAddressInput!) {\n\t\tallocateIpAddress(input: $input) {\n\t\t\tipAddress { id address type region }\n\t\t\tapp { sharedIpAddress }\n\t\t}\n\t}\n`;\n\nconst RELEASE_IP = `\n\tmutation ($input: ReleaseIPAddressInput!) {\n\t\treleaseIpAddress(input: $input) { clientMutationId }\n\t}\n`;\n\ninterface IpNode {\n\tid: string;\n\taddress: string;\n\ttype: string;\n\tregion: string | null;\n}\n\ninterface ListIpsResult {\n\tapp: {\n\t\tsharedIpAddress: string | null;\n\t\tipAddresses: { nodes: IpNode[] };\n\t};\n}\n\ninterface AllocateResult {\n\tallocateIpAddress: {\n\t\tipAddress: IpNode | null;\n\t\tapp: { sharedIpAddress: string | null };\n\t};\n}\n\n/**\n * Dynamic provider for Fly dedicated/shared IP allocation via the Fly GraphQL\n * API. `create()` queries existing IPs and adopts a matching one, otherwise it\n * allocates. `shared_v4` allocations return a null `ipAddress` in the payload —\n * the address is read from `app.sharedIpAddress`.\n */\nclass FlyIpResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(inputs: FlyIpInputs): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new FlyClient(inputs.token);\n\n\t\tconst existing = await this.findExisting(client, inputs);\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopting existing Fly ${inputs.type} IP \"${existing.address}\"`,\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tid: existing.address,\n\t\t\t\touts: {\n\t\t\t\t\t...inputs,\n\t\t\t\t\taddress: existing.address,\n\t\t\t\t\tipAddressId: existing.ipAddressId,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst result = await client.graphql<AllocateResult>(ALLOCATE_IP, {\n\t\t\tinput: {\n\t\t\t\tappId: inputs.appName,\n\t\t\t\ttype: inputs.type,\n\t\t\t\tregion: inputs.region,\n\t\t\t},\n\t\t});\n\n\t\tconst node = result.allocateIpAddress.ipAddress;\n\n\t\tconst address =\n\t\t\tinputs.type === FlyIpType.SHARED_V4\n\t\t\t\t? (result.allocateIpAddress.app.sharedIpAddress ?? \"\")\n\t\t\t\t: (node?.address ?? \"\");\n\n\t\tif (!address) {\n\t\t\tthrow new Error(\n\t\t\t\t`Fly IP allocation for app \"${inputs.appName}\" (${inputs.type}) returned no address`,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tid: address,\n\t\t\touts: { ...inputs, address, ipAddressId: node?.id },\n\t\t};\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: FlyIpOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\treturn { id, props };\n\t}\n\n\tasync delete(_id: string, props: FlyIpOutputs): Promise<void> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tconst input: Record<string, string> = { appId: props.appName };\n\n\t\tif (props.ipAddressId) {\n\t\t\tinput.ipAddressId = props.ipAddressId;\n\t\t} else {\n\t\t\tinput.ip = props.address;\n\t\t}\n\n\t\tawait client.graphql(RELEASE_IP, { input });\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: FlyIpOutputs,\n\t\tnews: FlyIpInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.appName !== news.appName) {\n\t\t\treplaces.push(\"appName\");\n\t\t}\n\t\tif (olds.type !== news.type) {\n\t\t\treplaces.push(\"type\");\n\t\t}\n\t\tif (olds.region !== news.region) {\n\t\t\treplaces.push(\"region\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n\n\tprivate async findExisting(\n\t\tclient: FlyClient,\n\t\tinputs: FlyIpInputs,\n\t): Promise<{ address: string; ipAddressId?: string } | null> {\n\t\tconst result = await client.graphql<ListIpsResult>(LIST_IPS, {\n\t\t\tappName: inputs.appName,\n\t\t});\n\n\t\tif (inputs.type === FlyIpType.SHARED_V4) {\n\t\t\tconst shared = result.app.sharedIpAddress;\n\n\t\t\treturn shared ? { address: shared } : null;\n\t\t}\n\n\t\tconst match = result.app.ipAddresses.nodes.find(\n\t\t\t(node) =>\n\t\t\t\tnode.type === inputs.type &&\n\t\t\t\t(inputs.region === undefined || node.region === inputs.region),\n\t\t);\n\n\t\treturn match ? { address: match.address, ipAddressId: match.id } : null;\n\t}\n}\n\n/** Internal dynamic resource — not part of the public API. */\nclass FlyIpResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly address: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tappName: pulumi.Input<string>;\n\t\t\ttype: pulumi.Input<FlyIpType>;\n\t\t\tregion?: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew FlyIpResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, address: undefined, ipAddressId: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for FlyIp. */\ntype FlyIpOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Fly authentication context. */\n\tprovider: FlyProvider;\n\n\t/** App the IP belongs to. */\n\tapp: FlyApp;\n};\n\n/** Args for FlyIp. */\nexport interface FlyIpArgs {\n\t/** IP address type. */\n\ttype: pulumi.Input<FlyIpType>;\n\n\t/** Region (IATA code); omit for a global address. */\n\tregion?: pulumi.Input<string>;\n}\n\n/**\n * Allocates a Fly IP address (dedicated or shared) via the Fly GraphQL API.\n *\n * @example\n * ```typescript\n * const ip = new FlyIp(\"api-ip\", { type: FlyIpType.SHARED_V4 }, { provider, app });\n * ```\n */\nexport class FlyIp extends pulumi.ComponentResource {\n\t/** Allocated IP address. */\n\tpublic readonly id: pulumi.Output<string>;\n\n\tconstructor(name: string, args: FlyIpArgs, opts: FlyIpOptions) {\n\t\tconst { provider, app, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:Ip\", name, {}, pulumiOpts);\n\n\t\tconst resource = new FlyIpResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tappName: app.id,\n\t\t\t\ttype: args.type,\n\t\t\t\tregion: args.region,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = resource.address;\n\n\t\tthis.registerOutputs({ id: this.id });\n\t}\n}\n"],"mappings":";;;;;;;;;AAUA,IAAY,YAAL;CACN;CACA;CACA;CACA;;AACD;AA0BA,MAAM,WAAW;;;;;;;;;;AAWjB,MAAM,cAAc;;;;;;;;AASpB,MAAM,aAAa;;;;;;;;;;;AAiCnB,IAAM,wBAAN,MAAuE;CACtE,MAAM,OAAO,QAA2D;EACvE,MAAM,SAAS,IAAI,UAAU,OAAO,KAAK;EAEzC,MAAM,WAAW,MAAM,KAAK,aAAa,QAAQ,MAAM;EAEvD,IAAI,UAAU;GACb,OAAO,IAAI,KACV,yBAAyB,OAAO,KAAK,OAAO,SAAS,QAAQ,EAC9D;GAEA,OAAO;IACN,IAAI,SAAS;IACb,MAAM;KACL,GAAG;KACH,SAAS,SAAS;KAClB,aAAa,SAAS;IACvB;GACD;EACD;EAEA,MAAM,SAAS,MAAM,OAAO,QAAwB,aAAa,EAChE,OAAO;GACN,OAAO,OAAO;GACd,MAAM,OAAO;GACb,QAAQ,OAAO;EAChB,EACD,CAAC;EAED,MAAM,OAAO,OAAO,kBAAkB;EAEtC,MAAM,UACL,OAAO,uBACH,OAAO,kBAAkB,IAAI,mBAAmB,KAChD,MAAM,WAAW;EAEtB,IAAI,CAAC,SACJ,MAAM,IAAI,MACT,8BAA8B,OAAO,QAAQ,KAAK,OAAO,KAAK,sBAC/D;EAGD,OAAO;GACN,IAAI;GACJ,MAAM;IAAE,GAAG;IAAQ;IAAS,aAAa,MAAM;GAAG;EACnD;CACD;CAEA,MAAM,KACL,IACA,OACqC;EACrC,OAAO;GAAE;GAAI;EAAM;CACpB;CAEA,MAAM,OAAO,KAAa,OAAoC;EAC7D,MAAM,SAAS,IAAI,UAAU,MAAM,KAAK;EAExC,MAAM,QAAgC,EAAE,OAAO,MAAM,QAAQ;EAE7D,IAAI,MAAM,aACT,MAAM,cAAc,MAAM;OAE1B,MAAM,KAAK,MAAM;EAGlB,MAAM,OAAO,QAAQ,YAAY,EAAE,MAAM,CAAC;CAC3C;CAEA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAE5B,IAAI,KAAK,YAAY,KAAK,SACzB,SAAS,KAAK,SAAS;
|
|
1
|
+
{"version":3,"file":"ip.mjs","names":[],"sources":["../../src/fly/ip.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\n\nimport type { FlyApp } from \"./app\";\nimport { FlyClient } from \"./client\";\nimport type { FlyProvider } from \"./provider\";\n\n/**\n * Fly IP address type. Enum keys UPPERCASE; values are Fly's GraphQL enum\n * literals (lowercase wire format).\n */\nexport enum FlyIpType {\n\tV4 = \"v4\",\n\tV6 = \"v6\",\n\tSHARED_V4 = \"shared_v4\",\n\tPRIVATE_V6 = \"private_v6\",\n}\n\n/** Resolved inputs for the Fly IP dynamic provider. */\nexport interface FlyIpInputs {\n\t/** Fly API token. */\n\ttoken: string;\n\n\t/** App name (used as GraphQL appId). */\n\tappName: string;\n\n\t/** IP address type. */\n\ttype: FlyIpType;\n\n\t/** Region (IATA code); omit for global. */\n\tregion?: string;\n}\n\n/** Persisted state for the Fly IP. */\ninterface FlyIpOutputs extends FlyIpInputs {\n\t/** Allocated IP address (also the `.id`). */\n\taddress: string;\n\n\t/** GraphQL node ID, when present (absent for `shared_v4`). */\n\tipAddressId?: string;\n}\n\nconst LIST_IPS = `\n\tquery ($appName: String!) {\n\t\tapp(name: $appName) {\n\t\t\tsharedIpAddress\n\t\t\tipAddresses {\n\t\t\t\tnodes { id address type region }\n\t\t\t}\n\t\t}\n\t}\n`;\n\nconst ALLOCATE_IP = `\n\tmutation ($input: AllocateIPAddressInput!) {\n\t\tallocateIpAddress(input: $input) {\n\t\t\tipAddress { id address type region }\n\t\t\tapp { sharedIpAddress }\n\t\t}\n\t}\n`;\n\nconst RELEASE_IP = `\n\tmutation ($input: ReleaseIPAddressInput!) {\n\t\treleaseIpAddress(input: $input) { clientMutationId }\n\t}\n`;\n\ninterface IpNode {\n\tid: string;\n\taddress: string;\n\ttype: string;\n\tregion: string | null;\n}\n\ninterface ListIpsResult {\n\tapp: {\n\t\tsharedIpAddress: string | null;\n\t\tipAddresses: { nodes: IpNode[] };\n\t};\n}\n\ninterface AllocateResult {\n\tallocateIpAddress: {\n\t\tipAddress: IpNode | null;\n\t\tapp: { sharedIpAddress: string | null };\n\t};\n}\n\n/**\n * Dynamic provider for Fly dedicated/shared IP allocation via the Fly GraphQL\n * API. `create()` queries existing IPs and adopts a matching one, otherwise it\n * allocates. `shared_v4` allocations return a null `ipAddress` in the payload —\n * the address is read from `app.sharedIpAddress`.\n */\nclass FlyIpResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(inputs: FlyIpInputs): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new FlyClient(inputs.token);\n\n\t\tconst existing = await this.findExisting(client, inputs);\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopting existing Fly ${inputs.type} IP \"${existing.address}\"`,\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tid: existing.address,\n\t\t\t\touts: {\n\t\t\t\t\t...inputs,\n\t\t\t\t\taddress: existing.address,\n\t\t\t\t\tipAddressId: existing.ipAddressId,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst result = await client.graphql<AllocateResult>(ALLOCATE_IP, {\n\t\t\tinput: {\n\t\t\t\tappId: inputs.appName,\n\t\t\t\ttype: inputs.type,\n\t\t\t\tregion: inputs.region,\n\t\t\t},\n\t\t});\n\n\t\tconst node = result.allocateIpAddress.ipAddress;\n\n\t\tconst address =\n\t\t\tinputs.type === FlyIpType.SHARED_V4\n\t\t\t\t? (result.allocateIpAddress.app.sharedIpAddress ?? \"\")\n\t\t\t\t: (node?.address ?? \"\");\n\n\t\tif (!address) {\n\t\t\tthrow new Error(\n\t\t\t\t`Fly IP allocation for app \"${inputs.appName}\" (${inputs.type}) returned no address`,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tid: address,\n\t\t\touts: { ...inputs, address, ipAddressId: node?.id },\n\t\t};\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: FlyIpOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\treturn { id, props };\n\t}\n\n\tasync delete(_id: string, props: FlyIpOutputs): Promise<void> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tconst input: Record<string, string> = { appId: props.appName };\n\n\t\tif (props.ipAddressId) {\n\t\t\tinput.ipAddressId = props.ipAddressId;\n\t\t} else {\n\t\t\tinput.ip = props.address;\n\t\t}\n\n\t\tawait client.graphql(RELEASE_IP, { input });\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: FlyIpOutputs,\n\t\tnews: FlyIpInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.appName !== news.appName) {\n\t\t\treplaces.push(\"appName\");\n\t\t}\n\n\t\tif (olds.type !== news.type) {\n\t\t\treplaces.push(\"type\");\n\t\t}\n\n\t\tif (olds.region !== news.region) {\n\t\t\treplaces.push(\"region\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n\n\tprivate async findExisting(\n\t\tclient: FlyClient,\n\t\tinputs: FlyIpInputs,\n\t): Promise<{ address: string; ipAddressId?: string } | null> {\n\t\tconst result = await client.graphql<ListIpsResult>(LIST_IPS, {\n\t\t\tappName: inputs.appName,\n\t\t});\n\n\t\tif (inputs.type === FlyIpType.SHARED_V4) {\n\t\t\tconst shared = result.app.sharedIpAddress;\n\n\t\t\treturn shared ? { address: shared } : null;\n\t\t}\n\n\t\tconst match = result.app.ipAddresses.nodes.find(\n\t\t\t(node) =>\n\t\t\t\tnode.type === inputs.type &&\n\t\t\t\t(inputs.region === undefined || node.region === inputs.region),\n\t\t);\n\n\t\treturn match ? { address: match.address, ipAddressId: match.id } : null;\n\t}\n}\n\n/** Internal dynamic resource — not part of the public API. */\nclass FlyIpResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly address: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tappName: pulumi.Input<string>;\n\t\t\ttype: pulumi.Input<FlyIpType>;\n\t\t\tregion?: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew FlyIpResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, address: undefined, ipAddressId: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for FlyIp. */\ntype FlyIpOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Fly authentication context. */\n\tprovider: FlyProvider;\n\n\t/** App the IP belongs to. */\n\tapp: FlyApp;\n};\n\n/** Args for FlyIp. */\nexport interface FlyIpArgs {\n\t/** IP address type. */\n\ttype: pulumi.Input<FlyIpType>;\n\n\t/** Region (IATA code); omit for a global address. */\n\tregion?: pulumi.Input<string>;\n}\n\n/**\n * Allocates a Fly IP address (dedicated or shared) via the Fly GraphQL API.\n *\n * @example\n * ```typescript\n * const ip = new FlyIp(\"api-ip\", { type: FlyIpType.SHARED_V4 }, { provider, app });\n * ```\n */\nexport class FlyIp extends pulumi.ComponentResource {\n\t/** Allocated IP address. */\n\tpublic readonly id: pulumi.Output<string>;\n\n\tconstructor(name: string, args: FlyIpArgs, opts: FlyIpOptions) {\n\t\tconst { provider, app, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:Ip\", name, {}, pulumiOpts);\n\n\t\tconst resource = new FlyIpResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tappName: app.id,\n\t\t\t\ttype: args.type,\n\t\t\t\tregion: args.region,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = resource.address;\n\n\t\tthis.registerOutputs({ id: this.id });\n\t}\n}\n"],"mappings":"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"}
|
package/dist/fly/toml.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toml.cjs","names":[],"sources":["../../src/fly/toml.ts"],"sourcesContent":["/**\n * fly.toml deploy strategy. Enum keys are UPPERCASE per convention; values are\n * Fly's required lowercase wire literals (external format — cannot be uppercased).\n * Note: 'canary' requires more than one machine; falls back to 'rolling' when\n * max-per-region is 1. Default is 'rolling'.\n */\nexport enum FlyDeployStrategy {\n\tROLLING = \"rolling\",\n\tIMMEDIATE = \"immediate\",\n\tCANARY = \"canary\",\n\tBLUEGREEN = \"bluegreen\",\n}\n\n/** Machine restart policy. Default is 'on-failure'. */\nexport enum FlyRestartPolicy {\n\tALWAYS = \"always\",\n\tON_FAILURE = \"on-failure\",\n\tNEVER = \"never\",\n}\n\n/**\n * Idle-machine auto-stop behavior. 'off' is equivalent to boolean false,\n * 'stop' is equivalent to boolean true, but 'suspend' cannot be expressed\n * as a boolean. Default is 'off'.\n */\nexport enum FlyAutoStopMachines {\n\tOFF = \"off\",\n\tSTOP = \"stop\",\n\tSUSPEND = \"suspend\",\n}\n\n/**\n * Concurrency limit unit. 'connections' is the default. For HTTP apps,\n * 'requests' is recommended because the proxy can pool connections.\n */\nexport enum FlyConcurrencyType {\n\tCONNECTIONS = \"connections\",\n\tREQUESTS = \"requests\",\n}\n\n/** Raw service protocol. When 'udp', handlers must be left unset. */\nexport enum FlyServiceProtocol {\n\tTCP = \"tcp\",\n\tUDP = \"udp\",\n}\n\n/** Port handler. Only valid for TCP services; omit entirely for UDP services. */\nexport enum FlyPortHandler {\n\tHTTP = \"http\",\n\tTLS = \"tls\",\n\tPG_TLS = \"pg_tls\",\n\tPROXY_PROTO = \"proxy_proto\",\n\tEDGE_HTTP = \"edge_http\",\n}\n\n/** VM CPU kind. */\nexport enum FlyCpuKind {\n\tSHARED = \"shared\",\n\tPERFORMANCE = \"performance\",\n}\n\n/** Health-check type. */\nexport enum FlyCheckType {\n\tHTTP = \"http\",\n\tTCP = \"tcp\",\n}\n\n/**\n * Authoritative list of Fly region codes (IATA).\n * Consumers may use this array for validation or UI rendering.\n * Source: https://fly.io/docs/reference/regions/\n */\nexport const FLY_REGIONS = [\n\t// Americas\n\t\"bos\",\n\t\"dfw\",\n\t\"ewr\",\n\t\"gig\",\n\t\"gru\",\n\t\"iad\",\n\t\"lax\",\n\t\"mia\",\n\t\"ord\",\n\t\"scl\",\n\t\"sea\",\n\t\"sjc\",\n\t\"yul\",\n\t\"yyz\",\n\t// Europe\n\t\"ams\",\n\t\"arn\",\n\t\"cdg\",\n\t\"fra\",\n\t\"lhr\",\n\t\"mad\",\n\t\"waw\",\n\t// Asia-Pacific\n\t\"bom\",\n\t\"hkg\",\n\t\"maa\",\n\t\"nrt\",\n\t\"sin\",\n\t\"syd\",\n\t// Africa\n\t\"jnb\",\n] as const;\n\n/**\n * Fly region code (IATA). Derived from {@link FLY_REGIONS} — single source of truth.\n * When Fly adds a new region, update {@link FLY_REGIONS} and release a new version.\n */\nexport type FlyRegion = (typeof FLY_REGIONS)[number];\n\n/**\n * Authoritative list of Fly machine size presets.\n * Consumers may use this array for validation or UI rendering.\n * Source: https://fly.io/docs/about/pricing/#compute\n */\nexport const FLY_VM_SIZES = [\n\t// Shared CPU\n\t\"shared-cpu-1x\",\n\t\"shared-cpu-2x\",\n\t\"shared-cpu-4x\",\n\t\"shared-cpu-6x\",\n\t\"shared-cpu-8x\",\n\t// Performance CPU\n\t\"performance-1x\",\n\t\"performance-2x\",\n\t\"performance-4x\",\n\t\"performance-6x\",\n\t\"performance-8x\",\n\t\"performance-10x\",\n\t\"performance-12x\",\n\t\"performance-14x\",\n\t\"performance-16x\",\n\t// GPU\n\t\"a10\",\n\t\"a100-40gb\",\n\t\"a100-80gb\",\n\t\"l40s\",\n] as const;\n\n/**\n * Fly machine size preset. Derived from {@link FLY_VM_SIZES} — single source of truth.\n * When Fly adds a new size, update {@link FLY_VM_SIZES} and release a new version.\n * Pass the raw string directly — e.g. \"shared-cpu-1x\".\n */\nexport type FlyVmSize = (typeof FLY_VM_SIZES)[number];\n\n/**\n * Number of CPUs for a [[vm]] entry. Valid values depend on the chosen\n * cpu_kind — not all counts are available for both shared and performance\n * CPU kinds. The union covers the full documented permitted set.\n */\nexport type FlyCpuCount = 1 | 2 | 4 | 8 | 16;\n\n/** A single health check. */\nexport interface FlyCheck {\n\ttype?: FlyCheckType;\n\tport?: number;\n\tmethod?: string;\n\tpath?: string;\n\t/**\n\t * How often to run the check. Go duration format — e.g. \"15s\", \"1m\", \"500ms\".\n\t * Compound forms like \"1m30s\" are also valid.\n\t */\n\tinterval: string;\n\t/**\n\t * Maximum time to wait for the check to complete. Go duration format — e.g. \"10s\".\n\t * Compound forms like \"1m30s\" are also valid.\n\t */\n\ttimeout: string;\n\t/**\n\t * Grace period before checks begin after machine start. Go duration format — e.g. \"30s\".\n\t * Compound forms like \"1m30s\" are also valid.\n\t */\n\tgracePeriod?: string;\n}\n\n/** Concurrency configuration for a service. */\nexport interface FlyConcurrency {\n\ttype: FlyConcurrencyType;\n\tsoftLimit: number;\n\thardLimit: number;\n}\n\n/** `[build]` section. */\nexport interface FlyBuildConfig {\n\tdockerfile?: string;\n\timage?: string;\n}\n\n/** `[http_service]` section. */\nexport interface FlyHttpService {\n\tinternalPort: number;\n\tforceHttps?: boolean;\n\tautoStopMachines?: FlyAutoStopMachines;\n\tautoStartMachines?: boolean;\n\tminMachinesRunning?: number;\n\tprocesses?: string[];\n\tconcurrency?: FlyConcurrency;\n\tchecks?: FlyCheck[];\n}\n\n/** A `[[services.ports]]` entry. */\nexport interface FlyServicePort {\n\tport: number;\n\thandlers?: FlyPortHandler[];\n}\n\n/** A `[[services]]` entry. */\nexport interface FlyService {\n\tinternalPort: number;\n\tprotocol: FlyServiceProtocol;\n\tautoStopMachines?: FlyAutoStopMachines;\n\tautoStartMachines?: boolean;\n\tminMachinesRunning?: number;\n\tprocesses?: string[];\n\tports: FlyServicePort[];\n\tconcurrency?: FlyConcurrency;\n\tchecks?: FlyCheck[];\n}\n\n/** A `[[mounts]]` entry. */\nexport interface FlyMount {\n\tsource: string;\n\tdestination: string;\n\tprocesses?: string[];\n\tinitialSize?: string;\n}\n\n/** A `[[vm]]` entry. `count` is intentionally absent — machine count is set via `fly scale`. */\nexport interface FlyVm {\n\tsize?: FlyVmSize;\n\t/**\n\t * Memory allocation. Accepts a bare integer (interpreted as MB, e.g. 1024)\n\t * or a string with units (e.g. \"512mb\", \"2gb\"). Valid values are\n\t * hardware-tier-dependent; see https://fly.io/docs/about/pricing/.\n\t */\n\tmemory?: string | number;\n\tcpuKind?: FlyCpuKind;\n\t/** Number of CPUs. Valid values depend on the chosen `cpuKind`. */\n\tcpus?: FlyCpuCount;\n\tprocesses?: string[];\n}\n\n/** `[deploy]` section. */\nexport interface FlyDeployConfig {\n\tstrategy?: FlyDeployStrategy;\n\treleaseCommand?: string;\n}\n\n/** A `[[restart]]` entry. */\nexport interface FlyRestartConfig {\n\tpolicy?: FlyRestartPolicy;\n\tretries?: number;\n\tprocesses?: string[];\n}\n\n/**\n * Typed fly.toml configuration. All fields are plain values (NOT `pulumi.Input`)\n * because `generateFlyToml()` runs synchronously to write the toml file — resolve\n * any `Output` before constructing this object.\n */\nexport interface FlyTomlConfig {\n\tapp: string;\n\tprimaryRegion: FlyRegion;\n\tbuild?: FlyBuildConfig;\n\tenv?: Record<string, string>;\n\tprocesses?: Record<string, string>;\n\thttpService?: FlyHttpService;\n\tservices?: FlyService[];\n\tmounts?: FlyMount[];\n\tvm?: FlyVm[];\n\tdeploy?: FlyDeployConfig;\n\trestart?: FlyRestartConfig;\n\tchecks?: Record<string, FlyCheck>;\n}\n\nfunction quote(value: string): string {\n\treturn `\"${value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`;\n}\n\nfunction array(values: string[]): string {\n\treturn `[${values.map((value) => quote(value)).join(\", \")}]`;\n}\n\nfunction pushCheck(lines: string[], header: string, check: FlyCheck): void {\n\tlines.push(\"\", header);\n\n\tif (check.type !== undefined) {\n\t\tlines.push(` type = ${quote(check.type)}`);\n\t}\n\tif (check.port !== undefined) {\n\t\tlines.push(` port = ${check.port}`);\n\t}\n\tif (check.method !== undefined) {\n\t\tlines.push(` method = ${quote(check.method)}`);\n\t}\n\tif (check.path !== undefined) {\n\t\tlines.push(` path = ${quote(check.path)}`);\n\t}\n\n\tlines.push(` interval = ${quote(check.interval)}`);\n\tlines.push(` timeout = ${quote(check.timeout)}`);\n\n\tif (check.gracePeriod !== undefined) {\n\t\tlines.push(` grace_period = ${quote(check.gracePeriod)}`);\n\t}\n}\n\nfunction pushConcurrency(\n\tlines: string[],\n\theader: string,\n\tconcurrency: FlyConcurrency,\n): void {\n\tlines.push(\"\", header);\n\tlines.push(` type = ${quote(concurrency.type)}`);\n\tlines.push(` soft_limit = ${concurrency.softLimit}`);\n\tlines.push(` hard_limit = ${concurrency.hardLimit}`);\n}\n\n/**\n * Serializes a {@link FlyTomlConfig} into fly.toml text.\n *\n * Field names are camelCase on the TypeScript side and emitted as Fly's\n * snake_case toml keys. Output is deterministic (stable section ordering) so it\n * can be used directly as a `FlyDeploy` redeploy trigger.\n */\nexport function generateFlyToml(config: FlyTomlConfig): string {\n\tconst lines: string[] = [];\n\n\tlines.push(`app = ${quote(config.app)}`);\n\tlines.push(`primary_region = ${quote(config.primaryRegion)}`);\n\n\tif (config.build) {\n\t\tlines.push(\"\", \"[build]\");\n\n\t\tif (config.build.dockerfile !== undefined) {\n\t\t\tlines.push(` dockerfile = ${quote(config.build.dockerfile)}`);\n\t\t}\n\t\tif (config.build.image !== undefined) {\n\t\t\tlines.push(` image = ${quote(config.build.image)}`);\n\t\t}\n\t}\n\n\tif (config.env) {\n\t\tlines.push(\"\", \"[env]\");\n\t\tfor (const [key, value] of Object.entries(config.env)) {\n\t\t\tlines.push(` ${key} = ${quote(value)}`);\n\t\t}\n\t}\n\n\tif (config.processes) {\n\t\tlines.push(\"\", \"[processes]\");\n\t\tfor (const [key, value] of Object.entries(config.processes)) {\n\t\t\tlines.push(` ${key} = ${quote(value)}`);\n\t\t}\n\t}\n\n\tif (config.httpService) {\n\t\tconst service = config.httpService;\n\n\t\tlines.push(\"\", \"[http_service]\");\n\t\tlines.push(` internal_port = ${service.internalPort}`);\n\n\t\tif (service.forceHttps !== undefined) {\n\t\t\tlines.push(` force_https = ${service.forceHttps}`);\n\t\t}\n\t\tif (service.autoStopMachines !== undefined) {\n\t\t\tlines.push(` auto_stop_machines = ${quote(service.autoStopMachines)}`);\n\t\t}\n\t\tif (service.autoStartMachines !== undefined) {\n\t\t\tlines.push(` auto_start_machines = ${service.autoStartMachines}`);\n\t\t}\n\t\tif (service.minMachinesRunning !== undefined) {\n\t\t\tlines.push(` min_machines_running = ${service.minMachinesRunning}`);\n\t\t}\n\t\tif (service.processes !== undefined) {\n\t\t\tlines.push(` processes = ${array(service.processes)}`);\n\t\t}\n\n\t\tif (service.concurrency) {\n\t\t\tpushConcurrency(\n\t\t\t\tlines,\n\t\t\t\t\" [http_service.concurrency]\",\n\t\t\t\tservice.concurrency,\n\t\t\t);\n\t\t}\n\n\t\tif (service.checks) {\n\t\t\tfor (const check of service.checks) {\n\t\t\t\tpushCheck(lines, \" [[http_service.checks]]\", check);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.services) {\n\t\tfor (const service of config.services) {\n\t\t\tlines.push(\"\", \"[[services]]\");\n\t\t\tlines.push(` internal_port = ${service.internalPort}`);\n\t\t\tlines.push(` protocol = ${quote(service.protocol)}`);\n\n\t\t\tif (service.autoStopMachines !== undefined) {\n\t\t\t\tlines.push(` auto_stop_machines = ${quote(service.autoStopMachines)}`);\n\t\t\t}\n\t\t\tif (service.autoStartMachines !== undefined) {\n\t\t\t\tlines.push(` auto_start_machines = ${service.autoStartMachines}`);\n\t\t\t}\n\t\t\tif (service.minMachinesRunning !== undefined) {\n\t\t\t\tlines.push(` min_machines_running = ${service.minMachinesRunning}`);\n\t\t\t}\n\t\t\tif (service.processes !== undefined) {\n\t\t\t\tlines.push(` processes = ${array(service.processes)}`);\n\t\t\t}\n\n\t\t\tfor (const port of service.ports) {\n\t\t\t\tlines.push(\"\", \" [[services.ports]]\");\n\t\t\t\tlines.push(` port = ${port.port}`);\n\t\t\t\tif (port.handlers !== undefined) {\n\t\t\t\t\tlines.push(` handlers = ${array(port.handlers)}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (service.concurrency) {\n\t\t\t\tpushConcurrency(lines, \" [services.concurrency]\", service.concurrency);\n\t\t\t}\n\n\t\t\tif (service.checks) {\n\t\t\t\tfor (const check of service.checks) {\n\t\t\t\t\tpushCheck(lines, \" [[services.checks]]\", check);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.mounts) {\n\t\tfor (const mount of config.mounts) {\n\t\t\tlines.push(\"\", \"[[mounts]]\");\n\t\t\tlines.push(` source = ${quote(mount.source)}`);\n\t\t\tlines.push(` destination = ${quote(mount.destination)}`);\n\n\t\t\tif (mount.processes !== undefined) {\n\t\t\t\tlines.push(` processes = ${array(mount.processes)}`);\n\t\t\t}\n\t\t\tif (mount.initialSize !== undefined) {\n\t\t\t\tlines.push(` initial_size = ${quote(mount.initialSize)}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.vm) {\n\t\tfor (const vm of config.vm) {\n\t\t\tlines.push(\"\", \"[[vm]]\");\n\n\t\t\tif (vm.size !== undefined) {\n\t\t\t\tlines.push(` size = ${quote(vm.size)}`);\n\t\t\t}\n\t\t\tif (vm.memory !== undefined) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttypeof vm.memory === \"number\"\n\t\t\t\t\t\t? ` memory = ${vm.memory}`\n\t\t\t\t\t\t: ` memory = ${quote(vm.memory)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (vm.cpuKind !== undefined) {\n\t\t\t\tlines.push(` cpu_kind = ${quote(vm.cpuKind)}`);\n\t\t\t}\n\t\t\tif (vm.cpus !== undefined) {\n\t\t\t\tlines.push(` cpus = ${vm.cpus}`);\n\t\t\t}\n\t\t\tif (vm.processes !== undefined) {\n\t\t\t\tlines.push(` processes = ${array(vm.processes)}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.deploy) {\n\t\tlines.push(\"\", \"[deploy]\");\n\n\t\tif (config.deploy.strategy !== undefined) {\n\t\t\tlines.push(` strategy = ${quote(config.deploy.strategy)}`);\n\t\t}\n\t\tif (config.deploy.releaseCommand !== undefined) {\n\t\t\tlines.push(` release_command = ${quote(config.deploy.releaseCommand)}`);\n\t\t}\n\t}\n\n\tif (config.restart) {\n\t\tlines.push(\"\", \"[[restart]]\");\n\n\t\tif (config.restart.policy !== undefined) {\n\t\t\tlines.push(` policy = ${quote(config.restart.policy)}`);\n\t\t}\n\t\tif (config.restart.retries !== undefined) {\n\t\t\tlines.push(` retries = ${config.restart.retries}`);\n\t\t}\n\t\tif (config.restart.processes !== undefined) {\n\t\t\tlines.push(` processes = ${array(config.restart.processes)}`);\n\t\t}\n\t}\n\n\tif (config.checks) {\n\t\tfor (const [checkName, check] of Object.entries(config.checks)) {\n\t\t\tpushCheck(lines, `[checks.${checkName}]`, check);\n\t\t}\n\t}\n\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"toml.cjs","names":[],"sources":["../../src/fly/toml.ts"],"sourcesContent":["/**\n * fly.toml deploy strategy. Enum keys are UPPERCASE per convention; values are\n * Fly's required lowercase wire literals (external format — cannot be uppercased).\n * Note: 'canary' requires more than one machine; falls back to 'rolling' when\n * max-per-region is 1. Default is 'rolling'.\n */\nexport enum FlyDeployStrategy {\n\tROLLING = \"rolling\",\n\tIMMEDIATE = \"immediate\",\n\tCANARY = \"canary\",\n\tBLUEGREEN = \"bluegreen\",\n}\n\n/** Machine restart policy. Default is 'on-failure'. */\nexport enum FlyRestartPolicy {\n\tALWAYS = \"always\",\n\tON_FAILURE = \"on-failure\",\n\tNEVER = \"never\",\n}\n\n/**\n * Idle-machine auto-stop behavior. 'off' is equivalent to boolean false,\n * 'stop' is equivalent to boolean true, but 'suspend' cannot be expressed\n * as a boolean. Default is 'off'.\n */\nexport enum FlyAutoStopMachines {\n\tOFF = \"off\",\n\tSTOP = \"stop\",\n\tSUSPEND = \"suspend\",\n}\n\n/**\n * Concurrency limit unit. 'connections' is the default. For HTTP apps,\n * 'requests' is recommended because the proxy can pool connections.\n */\nexport enum FlyConcurrencyType {\n\tCONNECTIONS = \"connections\",\n\tREQUESTS = \"requests\",\n}\n\n/** Raw service protocol. When 'udp', handlers must be left unset. */\nexport enum FlyServiceProtocol {\n\tTCP = \"tcp\",\n\tUDP = \"udp\",\n}\n\n/** Port handler. Only valid for TCP services; omit entirely for UDP services. */\nexport enum FlyPortHandler {\n\tHTTP = \"http\",\n\tTLS = \"tls\",\n\tPG_TLS = \"pg_tls\",\n\tPROXY_PROTO = \"proxy_proto\",\n\tEDGE_HTTP = \"edge_http\",\n}\n\n/** VM CPU kind. */\nexport enum FlyCpuKind {\n\tSHARED = \"shared\",\n\tPERFORMANCE = \"performance\",\n}\n\n/** Health-check type. */\nexport enum FlyCheckType {\n\tHTTP = \"http\",\n\tTCP = \"tcp\",\n}\n\n/**\n * Authoritative list of Fly region codes (IATA).\n * Consumers may use this array for validation or UI rendering.\n * Source: https://fly.io/docs/reference/regions/\n */\nexport const FLY_REGIONS = [\n\t// Americas\n\t\"bos\",\n\t\"dfw\",\n\t\"ewr\",\n\t\"gig\",\n\t\"gru\",\n\t\"iad\",\n\t\"lax\",\n\t\"mia\",\n\t\"ord\",\n\t\"scl\",\n\t\"sea\",\n\t\"sjc\",\n\t\"yul\",\n\t\"yyz\",\n\t// Europe\n\t\"ams\",\n\t\"arn\",\n\t\"cdg\",\n\t\"fra\",\n\t\"lhr\",\n\t\"mad\",\n\t\"waw\",\n\t// Asia-Pacific\n\t\"bom\",\n\t\"hkg\",\n\t\"maa\",\n\t\"nrt\",\n\t\"sin\",\n\t\"syd\",\n\t// Africa\n\t\"jnb\",\n] as const;\n\n/**\n * Fly region code (IATA). Derived from {@link FLY_REGIONS} — single source of truth.\n * When Fly adds a new region, update {@link FLY_REGIONS} and release a new version.\n */\nexport type FlyRegion = (typeof FLY_REGIONS)[number];\n\n/**\n * Authoritative list of Fly machine size presets.\n * Consumers may use this array for validation or UI rendering.\n * Source: https://fly.io/docs/about/pricing/#compute\n */\nexport const FLY_VM_SIZES = [\n\t// Shared CPU\n\t\"shared-cpu-1x\",\n\t\"shared-cpu-2x\",\n\t\"shared-cpu-4x\",\n\t\"shared-cpu-6x\",\n\t\"shared-cpu-8x\",\n\t// Performance CPU\n\t\"performance-1x\",\n\t\"performance-2x\",\n\t\"performance-4x\",\n\t\"performance-6x\",\n\t\"performance-8x\",\n\t\"performance-10x\",\n\t\"performance-12x\",\n\t\"performance-14x\",\n\t\"performance-16x\",\n\t// GPU\n\t\"a10\",\n\t\"a100-40gb\",\n\t\"a100-80gb\",\n\t\"l40s\",\n] as const;\n\n/**\n * Fly machine size preset. Derived from {@link FLY_VM_SIZES} — single source of truth.\n * When Fly adds a new size, update {@link FLY_VM_SIZES} and release a new version.\n * Pass the raw string directly — e.g. \"shared-cpu-1x\".\n */\nexport type FlyVmSize = (typeof FLY_VM_SIZES)[number];\n\n/**\n * Number of CPUs for a [[vm]] entry. Valid values depend on the chosen\n * cpu_kind — not all counts are available for both shared and performance\n * CPU kinds. The union covers the full documented permitted set.\n */\nexport type FlyCpuCount = 1 | 2 | 4 | 8 | 16;\n\n/** A single health check. */\nexport interface FlyCheck {\n\ttype?: FlyCheckType;\n\tport?: number;\n\tmethod?: string;\n\tpath?: string;\n\t/**\n\t * How often to run the check. Go duration format — e.g. \"15s\", \"1m\", \"500ms\".\n\t * Compound forms like \"1m30s\" are also valid.\n\t */\n\tinterval: string;\n\t/**\n\t * Maximum time to wait for the check to complete. Go duration format — e.g. \"10s\".\n\t * Compound forms like \"1m30s\" are also valid.\n\t */\n\ttimeout: string;\n\t/**\n\t * Grace period before checks begin after machine start. Go duration format — e.g. \"30s\".\n\t * Compound forms like \"1m30s\" are also valid.\n\t */\n\tgracePeriod?: string;\n}\n\n/** Concurrency configuration for a service. */\nexport interface FlyConcurrency {\n\ttype: FlyConcurrencyType;\n\tsoftLimit: number;\n\thardLimit: number;\n}\n\n/** `[build]` section. */\nexport interface FlyBuildConfig {\n\tdockerfile?: string;\n\timage?: string;\n}\n\n/** `[http_service]` section. */\nexport interface FlyHttpService {\n\tinternalPort: number;\n\tforceHttps?: boolean;\n\tautoStopMachines?: FlyAutoStopMachines;\n\tautoStartMachines?: boolean;\n\tminMachinesRunning?: number;\n\tprocesses?: string[];\n\tconcurrency?: FlyConcurrency;\n\tchecks?: FlyCheck[];\n}\n\n/** A `[[services.ports]]` entry. */\nexport interface FlyServicePort {\n\tport: number;\n\thandlers?: FlyPortHandler[];\n}\n\n/** A `[[services]]` entry. */\nexport interface FlyService {\n\tinternalPort: number;\n\tprotocol: FlyServiceProtocol;\n\tautoStopMachines?: FlyAutoStopMachines;\n\tautoStartMachines?: boolean;\n\tminMachinesRunning?: number;\n\tprocesses?: string[];\n\tports: FlyServicePort[];\n\tconcurrency?: FlyConcurrency;\n\tchecks?: FlyCheck[];\n}\n\n/** A `[[mounts]]` entry. */\nexport interface FlyMount {\n\tsource: string;\n\tdestination: string;\n\tprocesses?: string[];\n\tinitialSize?: string;\n}\n\n/** A `[[vm]]` entry. `count` is intentionally absent — machine count is set via `fly scale`. */\nexport interface FlyVm {\n\tsize?: FlyVmSize;\n\t/**\n\t * Memory allocation. Accepts a bare integer (interpreted as MB, e.g. 1024)\n\t * or a string with units (e.g. \"512mb\", \"2gb\"). Valid values are\n\t * hardware-tier-dependent; see https://fly.io/docs/about/pricing/.\n\t */\n\tmemory?: string | number;\n\tcpuKind?: FlyCpuKind;\n\t/** Number of CPUs. Valid values depend on the chosen `cpuKind`. */\n\tcpus?: FlyCpuCount;\n\tprocesses?: string[];\n}\n\n/** `[deploy]` section. */\nexport interface FlyDeployConfig {\n\tstrategy?: FlyDeployStrategy;\n\treleaseCommand?: string;\n}\n\n/** A `[[restart]]` entry. */\nexport interface FlyRestartConfig {\n\tpolicy?: FlyRestartPolicy;\n\tretries?: number;\n\tprocesses?: string[];\n}\n\n/**\n * Typed fly.toml configuration. All fields are plain values (NOT `pulumi.Input`)\n * because `generateFlyToml()` runs synchronously to write the toml file — resolve\n * any `Output` before constructing this object.\n */\nexport interface FlyTomlConfig {\n\tapp: string;\n\tprimaryRegion: FlyRegion;\n\tbuild?: FlyBuildConfig;\n\tenv?: Record<string, string>;\n\tprocesses?: Record<string, string>;\n\thttpService?: FlyHttpService;\n\tservices?: FlyService[];\n\tmounts?: FlyMount[];\n\tvm?: FlyVm[];\n\tdeploy?: FlyDeployConfig;\n\trestart?: FlyRestartConfig;\n\tchecks?: Record<string, FlyCheck>;\n}\n\nfunction quote(value: string): string {\n\treturn `\"${value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`;\n}\n\nfunction array(values: string[]): string {\n\treturn `[${values.map((value) => quote(value)).join(\", \")}]`;\n}\n\nfunction pushCheck(lines: string[], header: string, check: FlyCheck): void {\n\tlines.push(\"\", header);\n\n\tif (check.type !== undefined) {\n\t\tlines.push(` type = ${quote(check.type)}`);\n\t}\n\n\tif (check.port !== undefined) {\n\t\tlines.push(` port = ${check.port}`);\n\t}\n\n\tif (check.method !== undefined) {\n\t\tlines.push(` method = ${quote(check.method)}`);\n\t}\n\n\tif (check.path !== undefined) {\n\t\tlines.push(` path = ${quote(check.path)}`);\n\t}\n\n\tlines.push(` interval = ${quote(check.interval)}`);\n\tlines.push(` timeout = ${quote(check.timeout)}`);\n\n\tif (check.gracePeriod !== undefined) {\n\t\tlines.push(` grace_period = ${quote(check.gracePeriod)}`);\n\t}\n}\n\nfunction pushConcurrency(\n\tlines: string[],\n\theader: string,\n\tconcurrency: FlyConcurrency,\n): void {\n\tlines.push(\"\", header);\n\tlines.push(` type = ${quote(concurrency.type)}`);\n\tlines.push(` soft_limit = ${concurrency.softLimit}`);\n\tlines.push(` hard_limit = ${concurrency.hardLimit}`);\n}\n\n/**\n * Serializes a {@link FlyTomlConfig} into fly.toml text.\n *\n * Field names are camelCase on the TypeScript side and emitted as Fly's\n * snake_case toml keys. Output is deterministic (stable section ordering) so it\n * can be used directly as a `FlyDeploy` redeploy trigger.\n */\nexport function generateFlyToml(config: FlyTomlConfig): string {\n\tconst lines: string[] = [];\n\n\tlines.push(`app = ${quote(config.app)}`);\n\tlines.push(`primary_region = ${quote(config.primaryRegion)}`);\n\n\tif (config.build) {\n\t\tlines.push(\"\", \"[build]\");\n\n\t\tif (config.build.dockerfile !== undefined) {\n\t\t\tlines.push(` dockerfile = ${quote(config.build.dockerfile)}`);\n\t\t}\n\n\t\tif (config.build.image !== undefined) {\n\t\t\tlines.push(` image = ${quote(config.build.image)}`);\n\t\t}\n\t}\n\n\tif (config.env) {\n\t\tlines.push(\"\", \"[env]\");\n\t\tfor (const [key, value] of Object.entries(config.env)) {\n\t\t\tlines.push(` ${key} = ${quote(value)}`);\n\t\t}\n\t}\n\n\tif (config.processes) {\n\t\tlines.push(\"\", \"[processes]\");\n\t\tfor (const [key, value] of Object.entries(config.processes)) {\n\t\t\tlines.push(` ${key} = ${quote(value)}`);\n\t\t}\n\t}\n\n\tif (config.httpService) {\n\t\tconst service = config.httpService;\n\n\t\tlines.push(\"\", \"[http_service]\");\n\t\tlines.push(` internal_port = ${service.internalPort}`);\n\n\t\tif (service.forceHttps !== undefined) {\n\t\t\tlines.push(` force_https = ${service.forceHttps}`);\n\t\t}\n\n\t\tif (service.autoStopMachines !== undefined) {\n\t\t\tlines.push(` auto_stop_machines = ${quote(service.autoStopMachines)}`);\n\t\t}\n\n\t\tif (service.autoStartMachines !== undefined) {\n\t\t\tlines.push(` auto_start_machines = ${service.autoStartMachines}`);\n\t\t}\n\n\t\tif (service.minMachinesRunning !== undefined) {\n\t\t\tlines.push(` min_machines_running = ${service.minMachinesRunning}`);\n\t\t}\n\n\t\tif (service.processes !== undefined) {\n\t\t\tlines.push(` processes = ${array(service.processes)}`);\n\t\t}\n\n\t\tif (service.concurrency) {\n\t\t\tpushConcurrency(\n\t\t\t\tlines,\n\t\t\t\t\" [http_service.concurrency]\",\n\t\t\t\tservice.concurrency,\n\t\t\t);\n\t\t}\n\n\t\tif (service.checks) {\n\t\t\tfor (const check of service.checks) {\n\t\t\t\tpushCheck(lines, \" [[http_service.checks]]\", check);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.services) {\n\t\tfor (const service of config.services) {\n\t\t\tlines.push(\"\", \"[[services]]\");\n\t\t\tlines.push(` internal_port = ${service.internalPort}`);\n\t\t\tlines.push(` protocol = ${quote(service.protocol)}`);\n\n\t\t\tif (service.autoStopMachines !== undefined) {\n\t\t\t\tlines.push(` auto_stop_machines = ${quote(service.autoStopMachines)}`);\n\t\t\t}\n\n\t\t\tif (service.autoStartMachines !== undefined) {\n\t\t\t\tlines.push(` auto_start_machines = ${service.autoStartMachines}`);\n\t\t\t}\n\n\t\t\tif (service.minMachinesRunning !== undefined) {\n\t\t\t\tlines.push(` min_machines_running = ${service.minMachinesRunning}`);\n\t\t\t}\n\n\t\t\tif (service.processes !== undefined) {\n\t\t\t\tlines.push(` processes = ${array(service.processes)}`);\n\t\t\t}\n\n\t\t\tfor (const port of service.ports) {\n\t\t\t\tlines.push(\"\", \" [[services.ports]]\");\n\t\t\t\tlines.push(` port = ${port.port}`);\n\n\t\t\t\tif (port.handlers !== undefined) {\n\t\t\t\t\tlines.push(` handlers = ${array(port.handlers)}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (service.concurrency) {\n\t\t\t\tpushConcurrency(lines, \" [services.concurrency]\", service.concurrency);\n\t\t\t}\n\n\t\t\tif (service.checks) {\n\t\t\t\tfor (const check of service.checks) {\n\t\t\t\t\tpushCheck(lines, \" [[services.checks]]\", check);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.mounts) {\n\t\tfor (const mount of config.mounts) {\n\t\t\tlines.push(\"\", \"[[mounts]]\");\n\t\t\tlines.push(` source = ${quote(mount.source)}`);\n\t\t\tlines.push(` destination = ${quote(mount.destination)}`);\n\n\t\t\tif (mount.processes !== undefined) {\n\t\t\t\tlines.push(` processes = ${array(mount.processes)}`);\n\t\t\t}\n\n\t\t\tif (mount.initialSize !== undefined) {\n\t\t\t\tlines.push(` initial_size = ${quote(mount.initialSize)}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.vm) {\n\t\tfor (const vm of config.vm) {\n\t\t\tlines.push(\"\", \"[[vm]]\");\n\n\t\t\tif (vm.size !== undefined) {\n\t\t\t\tlines.push(` size = ${quote(vm.size)}`);\n\t\t\t}\n\n\t\t\tif (vm.memory !== undefined) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttypeof vm.memory === \"number\"\n\t\t\t\t\t\t? ` memory = ${vm.memory}`\n\t\t\t\t\t\t: ` memory = ${quote(vm.memory)}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (vm.cpuKind !== undefined) {\n\t\t\t\tlines.push(` cpu_kind = ${quote(vm.cpuKind)}`);\n\t\t\t}\n\n\t\t\tif (vm.cpus !== undefined) {\n\t\t\t\tlines.push(` cpus = ${vm.cpus}`);\n\t\t\t}\n\n\t\t\tif (vm.processes !== undefined) {\n\t\t\t\tlines.push(` processes = ${array(vm.processes)}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.deploy) {\n\t\tlines.push(\"\", \"[deploy]\");\n\n\t\tif (config.deploy.strategy !== undefined) {\n\t\t\tlines.push(` strategy = ${quote(config.deploy.strategy)}`);\n\t\t}\n\n\t\tif (config.deploy.releaseCommand !== undefined) {\n\t\t\tlines.push(` release_command = ${quote(config.deploy.releaseCommand)}`);\n\t\t}\n\t}\n\n\tif (config.restart) {\n\t\tlines.push(\"\", \"[[restart]]\");\n\n\t\tif (config.restart.policy !== undefined) {\n\t\t\tlines.push(` policy = ${quote(config.restart.policy)}`);\n\t\t}\n\n\t\tif (config.restart.retries !== undefined) {\n\t\t\tlines.push(` retries = ${config.restart.retries}`);\n\t\t}\n\n\t\tif (config.restart.processes !== undefined) {\n\t\t\tlines.push(` processes = ${array(config.restart.processes)}`);\n\t\t}\n\t}\n\n\tif (config.checks) {\n\t\tfor (const [checkName, check] of Object.entries(config.checks)) {\n\t\t\tpushCheck(lines, `[checks.${checkName}]`, check);\n\t\t}\n\t}\n\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n"],"mappings":"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"}
|
package/dist/fly/toml.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toml.d.cts","names":[],"sources":["../../src/fly/toml.ts"],"mappings":";;;;;;AAMA;;;aAAY,iBAAA;EACX,OAAA;EACA,SAAA;EACA,MAAA;EACA,SAAA;AAAA;AAAS;AAAA,aAIE,gBAAA;EACX,MAAA;EACA,UAAA;EACA,KAAA;AAAA;;;;AAAK;AAQN;aAAY,mBAAA;EACX,GAAA;EACA,IAAA;EACA,OAAA;AAAA;;;AAAO;AAOR;aAAY,kBAAA;EACX,WAAA;EACA,QAAQ;AAAA;AAIT;AAAA,aAAY,kBAAA;EACX,GAAA;EACA,GAAG;AAAA;AAIJ;AAAA,aAAY,cAAA;EACX,IAAA;EACA,GAAA;EACA,MAAA;EACA,WAAA;EACA,SAAA;AAAA;;aAIW,UAAA;EACX,MAAA;EACA,WAAW;AAAA;;aAIA,YAAA;EACX,IAAA;EACA,GAAG;AAAA;;;AAAA;AAQJ;;cAAa,WAAA;;AAiCH;AAMV;;KAAY,SAAA,WAAoB,WAAW;;AAAA;AAO3C;;;cAAa,YAAA;AAsBH;AAOV;;;;AAPU,KAOE,SAAA,WAAoB,YAAY;AAO5C;;;;AAAuB;AAAvB,KAAY,WAAA;;UAGK,QAAA;EAChB,IAAA,GAAO,YAAY;EACnB,IAAA;EACA,MAAA;EACA,IAAA;EADA;;;;EAMA,QAAA;EAUW;AAAA;AAIZ;;EATC,OAAA;EAUwB;;;;EALxB,WAAA;AAAA;AAOS;AAAA,UAHO,cAAA;EAChB,IAAA,EAAM,kBAAkB;EACxB,SAAA;EACA,SAAA;AAAA;AAUD;AAAA,UANiB,cAAA;EAChB,UAAA;EACA,KAAK;AAAA;;UAIW,cAAA;EAChB,YAAA;EACA,UAAA;EACA,gBAAA,GAAmB,mBAAA;EACnB,iBAAA;EACA,kBAAA;EACA,SAAA;EACA,WAAA,GAAc,cAAA;EACd,MAAA,GAAS,QAAA;AAAA;;UAIO,cAAA;EAChB,IAAA;EACA,QAAA,GAAW,cAAc;AAAA;AAF1B;AAAA,UAMiB,UAAA;EAChB,YAAA;EACA,QAAA,EAAU,kBAAA;EACV,gBAAA,GAAmB,mBAAA;EACnB,iBAAA;EACA,kBAAA;EACA,SAAA;EACA,KAAA,EAAO,cAAA;EACP,WAAA,GAAc,cAAA;EACd,MAAA,GAAS,QAAA;AAAA;;UAIO,QAAA;EAChB,MAAA;EACA,WAAA;EACA,SAAA;EACA,WAAA;AAAA;;UAIgB,KAAA;EAChB,IAAA,GAAO,SAAA;EAnBP;;;;;EAyBA,MAAA;EACA,OAAA,GAAU,UAAA;EArBV;EAuBA,IAAA,GAAO,WAAA;EACP,SAAA;AAAA;;UAIgB,eAAA;EAChB,QAAA,GAAW,iBAAiB;EAC5B,cAAA;AAAA;;UAIgB,gBAAA;EAChB,MAAA,GAAS,gBAAgB;EACzB,OAAA;EACA,SAAA;AAAA;AA5BW;AAIZ;;;;AAJY,UAoCK,aAAA;EAChB,GAAA;EACA,aAAA,EAAe,SAAA;EACf,KAAA,GAAQ,cAAA;EACR,GAAA,GAAM,MAAA;EACN,SAAA,GAAY,MAAA;EACZ,WAAA,GAAc,cAAA;EACd,QAAA,GAAW,UAAA;EACX,MAAA,GAAS,QAAA;EACT,EAAA,GAAK,KAAA;EACL,MAAA,GAAS,eAAA;EACT,OAAA,GAAU,gBAAA;EACV,MAAA,GAAS,MAAA,SAAe,QAAA;AAAA;AA7BzB;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"toml.d.cts","names":[],"sources":["../../src/fly/toml.ts"],"mappings":";;;;;;AAMA;;;aAAY,iBAAA;EACX,OAAA;EACA,SAAA;EACA,MAAA;EACA,SAAA;AAAA;AAAS;AAAA,aAIE,gBAAA;EACX,MAAA;EACA,UAAA;EACA,KAAA;AAAA;;;;AAAK;AAQN;aAAY,mBAAA;EACX,GAAA;EACA,IAAA;EACA,OAAA;AAAA;;;AAAO;AAOR;aAAY,kBAAA;EACX,WAAA;EACA,QAAQ;AAAA;AAIT;AAAA,aAAY,kBAAA;EACX,GAAA;EACA,GAAG;AAAA;AAIJ;AAAA,aAAY,cAAA;EACX,IAAA;EACA,GAAA;EACA,MAAA;EACA,WAAA;EACA,SAAA;AAAA;;aAIW,UAAA;EACX,MAAA;EACA,WAAW;AAAA;;aAIA,YAAA;EACX,IAAA;EACA,GAAG;AAAA;;;AAAA;AAQJ;;cAAa,WAAA;;AAiCH;AAMV;;KAAY,SAAA,WAAoB,WAAW;;AAAA;AAO3C;;;cAAa,YAAA;AAsBH;AAOV;;;;AAPU,KAOE,SAAA,WAAoB,YAAY;AAO5C;;;;AAAuB;AAAvB,KAAY,WAAA;;UAGK,QAAA;EAChB,IAAA,GAAO,YAAY;EACnB,IAAA;EACA,MAAA;EACA,IAAA;EADA;;;;EAMA,QAAA;EAUW;AAAA;AAIZ;;EATC,OAAA;EAUwB;;;;EALxB,WAAA;AAAA;AAOS;AAAA,UAHO,cAAA;EAChB,IAAA,EAAM,kBAAkB;EACxB,SAAA;EACA,SAAA;AAAA;AAUD;AAAA,UANiB,cAAA;EAChB,UAAA;EACA,KAAK;AAAA;;UAIW,cAAA;EAChB,YAAA;EACA,UAAA;EACA,gBAAA,GAAmB,mBAAA;EACnB,iBAAA;EACA,kBAAA;EACA,SAAA;EACA,WAAA,GAAc,cAAA;EACd,MAAA,GAAS,QAAA;AAAA;;UAIO,cAAA;EAChB,IAAA;EACA,QAAA,GAAW,cAAc;AAAA;AAF1B;AAAA,UAMiB,UAAA;EAChB,YAAA;EACA,QAAA,EAAU,kBAAA;EACV,gBAAA,GAAmB,mBAAA;EACnB,iBAAA;EACA,kBAAA;EACA,SAAA;EACA,KAAA,EAAO,cAAA;EACP,WAAA,GAAc,cAAA;EACd,MAAA,GAAS,QAAA;AAAA;;UAIO,QAAA;EAChB,MAAA;EACA,WAAA;EACA,SAAA;EACA,WAAA;AAAA;;UAIgB,KAAA;EAChB,IAAA,GAAO,SAAA;EAnBP;;;;;EAyBA,MAAA;EACA,OAAA,GAAU,UAAA;EArBV;EAuBA,IAAA,GAAO,WAAA;EACP,SAAA;AAAA;;UAIgB,eAAA;EAChB,QAAA,GAAW,iBAAiB;EAC5B,cAAA;AAAA;;UAIgB,gBAAA;EAChB,MAAA,GAAS,gBAAgB;EACzB,OAAA;EACA,SAAA;AAAA;AA5BW;AAIZ;;;;AAJY,UAoCK,aAAA;EAChB,GAAA;EACA,aAAA,EAAe,SAAA;EACf,KAAA,GAAQ,cAAA;EACR,GAAA,GAAM,MAAA;EACN,SAAA,GAAY,MAAA;EACZ,WAAA,GAAc,cAAA;EACd,QAAA,GAAW,UAAA;EACX,MAAA,GAAS,QAAA;EACT,EAAA,GAAK,KAAA;EACL,MAAA,GAAS,eAAA;EACT,OAAA,GAAU,gBAAA;EACV,MAAA,GAAS,MAAA,SAAe,QAAA;AAAA;AA7BzB;;;;;;;AAAA,iBAqFgB,eAAA,CAAgB,MAAqB,EAAb,aAAa"}
|
package/dist/fly/toml.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toml.d.mts","names":[],"sources":["../../src/fly/toml.ts"],"mappings":";;;;;;AAMA;;;aAAY,iBAAA;EACX,OAAA;EACA,SAAA;EACA,MAAA;EACA,SAAA;AAAA;AAAS;AAAA,aAIE,gBAAA;EACX,MAAA;EACA,UAAA;EACA,KAAA;AAAA;;;;AAAK;AAQN;aAAY,mBAAA;EACX,GAAA;EACA,IAAA;EACA,OAAA;AAAA;;;AAAO;AAOR;aAAY,kBAAA;EACX,WAAA;EACA,QAAQ;AAAA;AAIT;AAAA,aAAY,kBAAA;EACX,GAAA;EACA,GAAG;AAAA;AAIJ;AAAA,aAAY,cAAA;EACX,IAAA;EACA,GAAA;EACA,MAAA;EACA,WAAA;EACA,SAAA;AAAA;;aAIW,UAAA;EACX,MAAA;EACA,WAAW;AAAA;;aAIA,YAAA;EACX,IAAA;EACA,GAAG;AAAA;;;AAAA;AAQJ;;cAAa,WAAA;;AAiCH;AAMV;;KAAY,SAAA,WAAoB,WAAW;;AAAA;AAO3C;;;cAAa,YAAA;AAsBH;AAOV;;;;AAPU,KAOE,SAAA,WAAoB,YAAY;AAO5C;;;;AAAuB;AAAvB,KAAY,WAAA;;UAGK,QAAA;EAChB,IAAA,GAAO,YAAY;EACnB,IAAA;EACA,MAAA;EACA,IAAA;EADA;;;;EAMA,QAAA;EAUW;AAAA;AAIZ;;EATC,OAAA;EAUwB;;;;EALxB,WAAA;AAAA;AAOS;AAAA,UAHO,cAAA;EAChB,IAAA,EAAM,kBAAkB;EACxB,SAAA;EACA,SAAA;AAAA;AAUD;AAAA,UANiB,cAAA;EAChB,UAAA;EACA,KAAK;AAAA;;UAIW,cAAA;EAChB,YAAA;EACA,UAAA;EACA,gBAAA,GAAmB,mBAAA;EACnB,iBAAA;EACA,kBAAA;EACA,SAAA;EACA,WAAA,GAAc,cAAA;EACd,MAAA,GAAS,QAAA;AAAA;;UAIO,cAAA;EAChB,IAAA;EACA,QAAA,GAAW,cAAc;AAAA;AAF1B;AAAA,UAMiB,UAAA;EAChB,YAAA;EACA,QAAA,EAAU,kBAAA;EACV,gBAAA,GAAmB,mBAAA;EACnB,iBAAA;EACA,kBAAA;EACA,SAAA;EACA,KAAA,EAAO,cAAA;EACP,WAAA,GAAc,cAAA;EACd,MAAA,GAAS,QAAA;AAAA;;UAIO,QAAA;EAChB,MAAA;EACA,WAAA;EACA,SAAA;EACA,WAAA;AAAA;;UAIgB,KAAA;EAChB,IAAA,GAAO,SAAA;EAnBP;;;;;EAyBA,MAAA;EACA,OAAA,GAAU,UAAA;EArBV;EAuBA,IAAA,GAAO,WAAA;EACP,SAAA;AAAA;;UAIgB,eAAA;EAChB,QAAA,GAAW,iBAAiB;EAC5B,cAAA;AAAA;;UAIgB,gBAAA;EAChB,MAAA,GAAS,gBAAgB;EACzB,OAAA;EACA,SAAA;AAAA;AA5BW;AAIZ;;;;AAJY,UAoCK,aAAA;EAChB,GAAA;EACA,aAAA,EAAe,SAAA;EACf,KAAA,GAAQ,cAAA;EACR,GAAA,GAAM,MAAA;EACN,SAAA,GAAY,MAAA;EACZ,WAAA,GAAc,cAAA;EACd,QAAA,GAAW,UAAA;EACX,MAAA,GAAS,QAAA;EACT,EAAA,GAAK,KAAA;EACL,MAAA,GAAS,eAAA;EACT,OAAA,GAAU,gBAAA;EACV,MAAA,GAAS,MAAA,SAAe,QAAA;AAAA;AA7BzB;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"toml.d.mts","names":[],"sources":["../../src/fly/toml.ts"],"mappings":";;;;;;AAMA;;;aAAY,iBAAA;EACX,OAAA;EACA,SAAA;EACA,MAAA;EACA,SAAA;AAAA;AAAS;AAAA,aAIE,gBAAA;EACX,MAAA;EACA,UAAA;EACA,KAAA;AAAA;;;;AAAK;AAQN;aAAY,mBAAA;EACX,GAAA;EACA,IAAA;EACA,OAAA;AAAA;;;AAAO;AAOR;aAAY,kBAAA;EACX,WAAA;EACA,QAAQ;AAAA;AAIT;AAAA,aAAY,kBAAA;EACX,GAAA;EACA,GAAG;AAAA;AAIJ;AAAA,aAAY,cAAA;EACX,IAAA;EACA,GAAA;EACA,MAAA;EACA,WAAA;EACA,SAAA;AAAA;;aAIW,UAAA;EACX,MAAA;EACA,WAAW;AAAA;;aAIA,YAAA;EACX,IAAA;EACA,GAAG;AAAA;;;AAAA;AAQJ;;cAAa,WAAA;;AAiCH;AAMV;;KAAY,SAAA,WAAoB,WAAW;;AAAA;AAO3C;;;cAAa,YAAA;AAsBH;AAOV;;;;AAPU,KAOE,SAAA,WAAoB,YAAY;AAO5C;;;;AAAuB;AAAvB,KAAY,WAAA;;UAGK,QAAA;EAChB,IAAA,GAAO,YAAY;EACnB,IAAA;EACA,MAAA;EACA,IAAA;EADA;;;;EAMA,QAAA;EAUW;AAAA;AAIZ;;EATC,OAAA;EAUwB;;;;EALxB,WAAA;AAAA;AAOS;AAAA,UAHO,cAAA;EAChB,IAAA,EAAM,kBAAkB;EACxB,SAAA;EACA,SAAA;AAAA;AAUD;AAAA,UANiB,cAAA;EAChB,UAAA;EACA,KAAK;AAAA;;UAIW,cAAA;EAChB,YAAA;EACA,UAAA;EACA,gBAAA,GAAmB,mBAAA;EACnB,iBAAA;EACA,kBAAA;EACA,SAAA;EACA,WAAA,GAAc,cAAA;EACd,MAAA,GAAS,QAAA;AAAA;;UAIO,cAAA;EAChB,IAAA;EACA,QAAA,GAAW,cAAc;AAAA;AAF1B;AAAA,UAMiB,UAAA;EAChB,YAAA;EACA,QAAA,EAAU,kBAAA;EACV,gBAAA,GAAmB,mBAAA;EACnB,iBAAA;EACA,kBAAA;EACA,SAAA;EACA,KAAA,EAAO,cAAA;EACP,WAAA,GAAc,cAAA;EACd,MAAA,GAAS,QAAA;AAAA;;UAIO,QAAA;EAChB,MAAA;EACA,WAAA;EACA,SAAA;EACA,WAAA;AAAA;;UAIgB,KAAA;EAChB,IAAA,GAAO,SAAA;EAnBP;;;;;EAyBA,MAAA;EACA,OAAA,GAAU,UAAA;EArBV;EAuBA,IAAA,GAAO,WAAA;EACP,SAAA;AAAA;;UAIgB,eAAA;EAChB,QAAA,GAAW,iBAAiB;EAC5B,cAAA;AAAA;;UAIgB,gBAAA;EAChB,MAAA,GAAS,gBAAgB;EACzB,OAAA;EACA,SAAA;AAAA;AA5BW;AAIZ;;;;AAJY,UAoCK,aAAA;EAChB,GAAA;EACA,aAAA,EAAe,SAAA;EACf,KAAA,GAAQ,cAAA;EACR,GAAA,GAAM,MAAA;EACN,SAAA,GAAY,MAAA;EACZ,WAAA,GAAc,cAAA;EACd,QAAA,GAAW,UAAA;EACX,MAAA,GAAS,QAAA;EACT,EAAA,GAAK,KAAA;EACL,MAAA,GAAS,eAAA;EACT,OAAA,GAAU,gBAAA;EACV,MAAA,GAAS,MAAA,SAAe,QAAA;AAAA;AA7BzB;;;;;;;AAAA,iBAqFgB,eAAA,CAAgB,MAAqB,EAAb,aAAa"}
|
package/dist/fly/toml.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toml.mjs","names":[],"sources":["../../src/fly/toml.ts"],"sourcesContent":["/**\n * fly.toml deploy strategy. Enum keys are UPPERCASE per convention; values are\n * Fly's required lowercase wire literals (external format — cannot be uppercased).\n * Note: 'canary' requires more than one machine; falls back to 'rolling' when\n * max-per-region is 1. Default is 'rolling'.\n */\nexport enum FlyDeployStrategy {\n\tROLLING = \"rolling\",\n\tIMMEDIATE = \"immediate\",\n\tCANARY = \"canary\",\n\tBLUEGREEN = \"bluegreen\",\n}\n\n/** Machine restart policy. Default is 'on-failure'. */\nexport enum FlyRestartPolicy {\n\tALWAYS = \"always\",\n\tON_FAILURE = \"on-failure\",\n\tNEVER = \"never\",\n}\n\n/**\n * Idle-machine auto-stop behavior. 'off' is equivalent to boolean false,\n * 'stop' is equivalent to boolean true, but 'suspend' cannot be expressed\n * as a boolean. Default is 'off'.\n */\nexport enum FlyAutoStopMachines {\n\tOFF = \"off\",\n\tSTOP = \"stop\",\n\tSUSPEND = \"suspend\",\n}\n\n/**\n * Concurrency limit unit. 'connections' is the default. For HTTP apps,\n * 'requests' is recommended because the proxy can pool connections.\n */\nexport enum FlyConcurrencyType {\n\tCONNECTIONS = \"connections\",\n\tREQUESTS = \"requests\",\n}\n\n/** Raw service protocol. When 'udp', handlers must be left unset. */\nexport enum FlyServiceProtocol {\n\tTCP = \"tcp\",\n\tUDP = \"udp\",\n}\n\n/** Port handler. Only valid for TCP services; omit entirely for UDP services. */\nexport enum FlyPortHandler {\n\tHTTP = \"http\",\n\tTLS = \"tls\",\n\tPG_TLS = \"pg_tls\",\n\tPROXY_PROTO = \"proxy_proto\",\n\tEDGE_HTTP = \"edge_http\",\n}\n\n/** VM CPU kind. */\nexport enum FlyCpuKind {\n\tSHARED = \"shared\",\n\tPERFORMANCE = \"performance\",\n}\n\n/** Health-check type. */\nexport enum FlyCheckType {\n\tHTTP = \"http\",\n\tTCP = \"tcp\",\n}\n\n/**\n * Authoritative list of Fly region codes (IATA).\n * Consumers may use this array for validation or UI rendering.\n * Source: https://fly.io/docs/reference/regions/\n */\nexport const FLY_REGIONS = [\n\t// Americas\n\t\"bos\",\n\t\"dfw\",\n\t\"ewr\",\n\t\"gig\",\n\t\"gru\",\n\t\"iad\",\n\t\"lax\",\n\t\"mia\",\n\t\"ord\",\n\t\"scl\",\n\t\"sea\",\n\t\"sjc\",\n\t\"yul\",\n\t\"yyz\",\n\t// Europe\n\t\"ams\",\n\t\"arn\",\n\t\"cdg\",\n\t\"fra\",\n\t\"lhr\",\n\t\"mad\",\n\t\"waw\",\n\t// Asia-Pacific\n\t\"bom\",\n\t\"hkg\",\n\t\"maa\",\n\t\"nrt\",\n\t\"sin\",\n\t\"syd\",\n\t// Africa\n\t\"jnb\",\n] as const;\n\n/**\n * Fly region code (IATA). Derived from {@link FLY_REGIONS} — single source of truth.\n * When Fly adds a new region, update {@link FLY_REGIONS} and release a new version.\n */\nexport type FlyRegion = (typeof FLY_REGIONS)[number];\n\n/**\n * Authoritative list of Fly machine size presets.\n * Consumers may use this array for validation or UI rendering.\n * Source: https://fly.io/docs/about/pricing/#compute\n */\nexport const FLY_VM_SIZES = [\n\t// Shared CPU\n\t\"shared-cpu-1x\",\n\t\"shared-cpu-2x\",\n\t\"shared-cpu-4x\",\n\t\"shared-cpu-6x\",\n\t\"shared-cpu-8x\",\n\t// Performance CPU\n\t\"performance-1x\",\n\t\"performance-2x\",\n\t\"performance-4x\",\n\t\"performance-6x\",\n\t\"performance-8x\",\n\t\"performance-10x\",\n\t\"performance-12x\",\n\t\"performance-14x\",\n\t\"performance-16x\",\n\t// GPU\n\t\"a10\",\n\t\"a100-40gb\",\n\t\"a100-80gb\",\n\t\"l40s\",\n] as const;\n\n/**\n * Fly machine size preset. Derived from {@link FLY_VM_SIZES} — single source of truth.\n * When Fly adds a new size, update {@link FLY_VM_SIZES} and release a new version.\n * Pass the raw string directly — e.g. \"shared-cpu-1x\".\n */\nexport type FlyVmSize = (typeof FLY_VM_SIZES)[number];\n\n/**\n * Number of CPUs for a [[vm]] entry. Valid values depend on the chosen\n * cpu_kind — not all counts are available for both shared and performance\n * CPU kinds. The union covers the full documented permitted set.\n */\nexport type FlyCpuCount = 1 | 2 | 4 | 8 | 16;\n\n/** A single health check. */\nexport interface FlyCheck {\n\ttype?: FlyCheckType;\n\tport?: number;\n\tmethod?: string;\n\tpath?: string;\n\t/**\n\t * How often to run the check. Go duration format — e.g. \"15s\", \"1m\", \"500ms\".\n\t * Compound forms like \"1m30s\" are also valid.\n\t */\n\tinterval: string;\n\t/**\n\t * Maximum time to wait for the check to complete. Go duration format — e.g. \"10s\".\n\t * Compound forms like \"1m30s\" are also valid.\n\t */\n\ttimeout: string;\n\t/**\n\t * Grace period before checks begin after machine start. Go duration format — e.g. \"30s\".\n\t * Compound forms like \"1m30s\" are also valid.\n\t */\n\tgracePeriod?: string;\n}\n\n/** Concurrency configuration for a service. */\nexport interface FlyConcurrency {\n\ttype: FlyConcurrencyType;\n\tsoftLimit: number;\n\thardLimit: number;\n}\n\n/** `[build]` section. */\nexport interface FlyBuildConfig {\n\tdockerfile?: string;\n\timage?: string;\n}\n\n/** `[http_service]` section. */\nexport interface FlyHttpService {\n\tinternalPort: number;\n\tforceHttps?: boolean;\n\tautoStopMachines?: FlyAutoStopMachines;\n\tautoStartMachines?: boolean;\n\tminMachinesRunning?: number;\n\tprocesses?: string[];\n\tconcurrency?: FlyConcurrency;\n\tchecks?: FlyCheck[];\n}\n\n/** A `[[services.ports]]` entry. */\nexport interface FlyServicePort {\n\tport: number;\n\thandlers?: FlyPortHandler[];\n}\n\n/** A `[[services]]` entry. */\nexport interface FlyService {\n\tinternalPort: number;\n\tprotocol: FlyServiceProtocol;\n\tautoStopMachines?: FlyAutoStopMachines;\n\tautoStartMachines?: boolean;\n\tminMachinesRunning?: number;\n\tprocesses?: string[];\n\tports: FlyServicePort[];\n\tconcurrency?: FlyConcurrency;\n\tchecks?: FlyCheck[];\n}\n\n/** A `[[mounts]]` entry. */\nexport interface FlyMount {\n\tsource: string;\n\tdestination: string;\n\tprocesses?: string[];\n\tinitialSize?: string;\n}\n\n/** A `[[vm]]` entry. `count` is intentionally absent — machine count is set via `fly scale`. */\nexport interface FlyVm {\n\tsize?: FlyVmSize;\n\t/**\n\t * Memory allocation. Accepts a bare integer (interpreted as MB, e.g. 1024)\n\t * or a string with units (e.g. \"512mb\", \"2gb\"). Valid values are\n\t * hardware-tier-dependent; see https://fly.io/docs/about/pricing/.\n\t */\n\tmemory?: string | number;\n\tcpuKind?: FlyCpuKind;\n\t/** Number of CPUs. Valid values depend on the chosen `cpuKind`. */\n\tcpus?: FlyCpuCount;\n\tprocesses?: string[];\n}\n\n/** `[deploy]` section. */\nexport interface FlyDeployConfig {\n\tstrategy?: FlyDeployStrategy;\n\treleaseCommand?: string;\n}\n\n/** A `[[restart]]` entry. */\nexport interface FlyRestartConfig {\n\tpolicy?: FlyRestartPolicy;\n\tretries?: number;\n\tprocesses?: string[];\n}\n\n/**\n * Typed fly.toml configuration. All fields are plain values (NOT `pulumi.Input`)\n * because `generateFlyToml()` runs synchronously to write the toml file — resolve\n * any `Output` before constructing this object.\n */\nexport interface FlyTomlConfig {\n\tapp: string;\n\tprimaryRegion: FlyRegion;\n\tbuild?: FlyBuildConfig;\n\tenv?: Record<string, string>;\n\tprocesses?: Record<string, string>;\n\thttpService?: FlyHttpService;\n\tservices?: FlyService[];\n\tmounts?: FlyMount[];\n\tvm?: FlyVm[];\n\tdeploy?: FlyDeployConfig;\n\trestart?: FlyRestartConfig;\n\tchecks?: Record<string, FlyCheck>;\n}\n\nfunction quote(value: string): string {\n\treturn `\"${value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`;\n}\n\nfunction array(values: string[]): string {\n\treturn `[${values.map((value) => quote(value)).join(\", \")}]`;\n}\n\nfunction pushCheck(lines: string[], header: string, check: FlyCheck): void {\n\tlines.push(\"\", header);\n\n\tif (check.type !== undefined) {\n\t\tlines.push(` type = ${quote(check.type)}`);\n\t}\n\tif (check.port !== undefined) {\n\t\tlines.push(` port = ${check.port}`);\n\t}\n\tif (check.method !== undefined) {\n\t\tlines.push(` method = ${quote(check.method)}`);\n\t}\n\tif (check.path !== undefined) {\n\t\tlines.push(` path = ${quote(check.path)}`);\n\t}\n\n\tlines.push(` interval = ${quote(check.interval)}`);\n\tlines.push(` timeout = ${quote(check.timeout)}`);\n\n\tif (check.gracePeriod !== undefined) {\n\t\tlines.push(` grace_period = ${quote(check.gracePeriod)}`);\n\t}\n}\n\nfunction pushConcurrency(\n\tlines: string[],\n\theader: string,\n\tconcurrency: FlyConcurrency,\n): void {\n\tlines.push(\"\", header);\n\tlines.push(` type = ${quote(concurrency.type)}`);\n\tlines.push(` soft_limit = ${concurrency.softLimit}`);\n\tlines.push(` hard_limit = ${concurrency.hardLimit}`);\n}\n\n/**\n * Serializes a {@link FlyTomlConfig} into fly.toml text.\n *\n * Field names are camelCase on the TypeScript side and emitted as Fly's\n * snake_case toml keys. Output is deterministic (stable section ordering) so it\n * can be used directly as a `FlyDeploy` redeploy trigger.\n */\nexport function generateFlyToml(config: FlyTomlConfig): string {\n\tconst lines: string[] = [];\n\n\tlines.push(`app = ${quote(config.app)}`);\n\tlines.push(`primary_region = ${quote(config.primaryRegion)}`);\n\n\tif (config.build) {\n\t\tlines.push(\"\", \"[build]\");\n\n\t\tif (config.build.dockerfile !== undefined) {\n\t\t\tlines.push(` dockerfile = ${quote(config.build.dockerfile)}`);\n\t\t}\n\t\tif (config.build.image !== undefined) {\n\t\t\tlines.push(` image = ${quote(config.build.image)}`);\n\t\t}\n\t}\n\n\tif (config.env) {\n\t\tlines.push(\"\", \"[env]\");\n\t\tfor (const [key, value] of Object.entries(config.env)) {\n\t\t\tlines.push(` ${key} = ${quote(value)}`);\n\t\t}\n\t}\n\n\tif (config.processes) {\n\t\tlines.push(\"\", \"[processes]\");\n\t\tfor (const [key, value] of Object.entries(config.processes)) {\n\t\t\tlines.push(` ${key} = ${quote(value)}`);\n\t\t}\n\t}\n\n\tif (config.httpService) {\n\t\tconst service = config.httpService;\n\n\t\tlines.push(\"\", \"[http_service]\");\n\t\tlines.push(` internal_port = ${service.internalPort}`);\n\n\t\tif (service.forceHttps !== undefined) {\n\t\t\tlines.push(` force_https = ${service.forceHttps}`);\n\t\t}\n\t\tif (service.autoStopMachines !== undefined) {\n\t\t\tlines.push(` auto_stop_machines = ${quote(service.autoStopMachines)}`);\n\t\t}\n\t\tif (service.autoStartMachines !== undefined) {\n\t\t\tlines.push(` auto_start_machines = ${service.autoStartMachines}`);\n\t\t}\n\t\tif (service.minMachinesRunning !== undefined) {\n\t\t\tlines.push(` min_machines_running = ${service.minMachinesRunning}`);\n\t\t}\n\t\tif (service.processes !== undefined) {\n\t\t\tlines.push(` processes = ${array(service.processes)}`);\n\t\t}\n\n\t\tif (service.concurrency) {\n\t\t\tpushConcurrency(\n\t\t\t\tlines,\n\t\t\t\t\" [http_service.concurrency]\",\n\t\t\t\tservice.concurrency,\n\t\t\t);\n\t\t}\n\n\t\tif (service.checks) {\n\t\t\tfor (const check of service.checks) {\n\t\t\t\tpushCheck(lines, \" [[http_service.checks]]\", check);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.services) {\n\t\tfor (const service of config.services) {\n\t\t\tlines.push(\"\", \"[[services]]\");\n\t\t\tlines.push(` internal_port = ${service.internalPort}`);\n\t\t\tlines.push(` protocol = ${quote(service.protocol)}`);\n\n\t\t\tif (service.autoStopMachines !== undefined) {\n\t\t\t\tlines.push(` auto_stop_machines = ${quote(service.autoStopMachines)}`);\n\t\t\t}\n\t\t\tif (service.autoStartMachines !== undefined) {\n\t\t\t\tlines.push(` auto_start_machines = ${service.autoStartMachines}`);\n\t\t\t}\n\t\t\tif (service.minMachinesRunning !== undefined) {\n\t\t\t\tlines.push(` min_machines_running = ${service.minMachinesRunning}`);\n\t\t\t}\n\t\t\tif (service.processes !== undefined) {\n\t\t\t\tlines.push(` processes = ${array(service.processes)}`);\n\t\t\t}\n\n\t\t\tfor (const port of service.ports) {\n\t\t\t\tlines.push(\"\", \" [[services.ports]]\");\n\t\t\t\tlines.push(` port = ${port.port}`);\n\t\t\t\tif (port.handlers !== undefined) {\n\t\t\t\t\tlines.push(` handlers = ${array(port.handlers)}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (service.concurrency) {\n\t\t\t\tpushConcurrency(lines, \" [services.concurrency]\", service.concurrency);\n\t\t\t}\n\n\t\t\tif (service.checks) {\n\t\t\t\tfor (const check of service.checks) {\n\t\t\t\t\tpushCheck(lines, \" [[services.checks]]\", check);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.mounts) {\n\t\tfor (const mount of config.mounts) {\n\t\t\tlines.push(\"\", \"[[mounts]]\");\n\t\t\tlines.push(` source = ${quote(mount.source)}`);\n\t\t\tlines.push(` destination = ${quote(mount.destination)}`);\n\n\t\t\tif (mount.processes !== undefined) {\n\t\t\t\tlines.push(` processes = ${array(mount.processes)}`);\n\t\t\t}\n\t\t\tif (mount.initialSize !== undefined) {\n\t\t\t\tlines.push(` initial_size = ${quote(mount.initialSize)}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.vm) {\n\t\tfor (const vm of config.vm) {\n\t\t\tlines.push(\"\", \"[[vm]]\");\n\n\t\t\tif (vm.size !== undefined) {\n\t\t\t\tlines.push(` size = ${quote(vm.size)}`);\n\t\t\t}\n\t\t\tif (vm.memory !== undefined) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttypeof vm.memory === \"number\"\n\t\t\t\t\t\t? ` memory = ${vm.memory}`\n\t\t\t\t\t\t: ` memory = ${quote(vm.memory)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (vm.cpuKind !== undefined) {\n\t\t\t\tlines.push(` cpu_kind = ${quote(vm.cpuKind)}`);\n\t\t\t}\n\t\t\tif (vm.cpus !== undefined) {\n\t\t\t\tlines.push(` cpus = ${vm.cpus}`);\n\t\t\t}\n\t\t\tif (vm.processes !== undefined) {\n\t\t\t\tlines.push(` processes = ${array(vm.processes)}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.deploy) {\n\t\tlines.push(\"\", \"[deploy]\");\n\n\t\tif (config.deploy.strategy !== undefined) {\n\t\t\tlines.push(` strategy = ${quote(config.deploy.strategy)}`);\n\t\t}\n\t\tif (config.deploy.releaseCommand !== undefined) {\n\t\t\tlines.push(` release_command = ${quote(config.deploy.releaseCommand)}`);\n\t\t}\n\t}\n\n\tif (config.restart) {\n\t\tlines.push(\"\", \"[[restart]]\");\n\n\t\tif (config.restart.policy !== undefined) {\n\t\t\tlines.push(` policy = ${quote(config.restart.policy)}`);\n\t\t}\n\t\tif (config.restart.retries !== undefined) {\n\t\t\tlines.push(` retries = ${config.restart.retries}`);\n\t\t}\n\t\tif (config.restart.processes !== undefined) {\n\t\t\tlines.push(` processes = ${array(config.restart.processes)}`);\n\t\t}\n\t}\n\n\tif (config.checks) {\n\t\tfor (const [checkName, check] of Object.entries(config.checks)) {\n\t\t\tpushCheck(lines, `[checks.${checkName}]`, check);\n\t\t}\n\t}\n\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"toml.mjs","names":[],"sources":["../../src/fly/toml.ts"],"sourcesContent":["/**\n * fly.toml deploy strategy. Enum keys are UPPERCASE per convention; values are\n * Fly's required lowercase wire literals (external format — cannot be uppercased).\n * Note: 'canary' requires more than one machine; falls back to 'rolling' when\n * max-per-region is 1. Default is 'rolling'.\n */\nexport enum FlyDeployStrategy {\n\tROLLING = \"rolling\",\n\tIMMEDIATE = \"immediate\",\n\tCANARY = \"canary\",\n\tBLUEGREEN = \"bluegreen\",\n}\n\n/** Machine restart policy. Default is 'on-failure'. */\nexport enum FlyRestartPolicy {\n\tALWAYS = \"always\",\n\tON_FAILURE = \"on-failure\",\n\tNEVER = \"never\",\n}\n\n/**\n * Idle-machine auto-stop behavior. 'off' is equivalent to boolean false,\n * 'stop' is equivalent to boolean true, but 'suspend' cannot be expressed\n * as a boolean. Default is 'off'.\n */\nexport enum FlyAutoStopMachines {\n\tOFF = \"off\",\n\tSTOP = \"stop\",\n\tSUSPEND = \"suspend\",\n}\n\n/**\n * Concurrency limit unit. 'connections' is the default. For HTTP apps,\n * 'requests' is recommended because the proxy can pool connections.\n */\nexport enum FlyConcurrencyType {\n\tCONNECTIONS = \"connections\",\n\tREQUESTS = \"requests\",\n}\n\n/** Raw service protocol. When 'udp', handlers must be left unset. */\nexport enum FlyServiceProtocol {\n\tTCP = \"tcp\",\n\tUDP = \"udp\",\n}\n\n/** Port handler. Only valid for TCP services; omit entirely for UDP services. */\nexport enum FlyPortHandler {\n\tHTTP = \"http\",\n\tTLS = \"tls\",\n\tPG_TLS = \"pg_tls\",\n\tPROXY_PROTO = \"proxy_proto\",\n\tEDGE_HTTP = \"edge_http\",\n}\n\n/** VM CPU kind. */\nexport enum FlyCpuKind {\n\tSHARED = \"shared\",\n\tPERFORMANCE = \"performance\",\n}\n\n/** Health-check type. */\nexport enum FlyCheckType {\n\tHTTP = \"http\",\n\tTCP = \"tcp\",\n}\n\n/**\n * Authoritative list of Fly region codes (IATA).\n * Consumers may use this array for validation or UI rendering.\n * Source: https://fly.io/docs/reference/regions/\n */\nexport const FLY_REGIONS = [\n\t// Americas\n\t\"bos\",\n\t\"dfw\",\n\t\"ewr\",\n\t\"gig\",\n\t\"gru\",\n\t\"iad\",\n\t\"lax\",\n\t\"mia\",\n\t\"ord\",\n\t\"scl\",\n\t\"sea\",\n\t\"sjc\",\n\t\"yul\",\n\t\"yyz\",\n\t// Europe\n\t\"ams\",\n\t\"arn\",\n\t\"cdg\",\n\t\"fra\",\n\t\"lhr\",\n\t\"mad\",\n\t\"waw\",\n\t// Asia-Pacific\n\t\"bom\",\n\t\"hkg\",\n\t\"maa\",\n\t\"nrt\",\n\t\"sin\",\n\t\"syd\",\n\t// Africa\n\t\"jnb\",\n] as const;\n\n/**\n * Fly region code (IATA). Derived from {@link FLY_REGIONS} — single source of truth.\n * When Fly adds a new region, update {@link FLY_REGIONS} and release a new version.\n */\nexport type FlyRegion = (typeof FLY_REGIONS)[number];\n\n/**\n * Authoritative list of Fly machine size presets.\n * Consumers may use this array for validation or UI rendering.\n * Source: https://fly.io/docs/about/pricing/#compute\n */\nexport const FLY_VM_SIZES = [\n\t// Shared CPU\n\t\"shared-cpu-1x\",\n\t\"shared-cpu-2x\",\n\t\"shared-cpu-4x\",\n\t\"shared-cpu-6x\",\n\t\"shared-cpu-8x\",\n\t// Performance CPU\n\t\"performance-1x\",\n\t\"performance-2x\",\n\t\"performance-4x\",\n\t\"performance-6x\",\n\t\"performance-8x\",\n\t\"performance-10x\",\n\t\"performance-12x\",\n\t\"performance-14x\",\n\t\"performance-16x\",\n\t// GPU\n\t\"a10\",\n\t\"a100-40gb\",\n\t\"a100-80gb\",\n\t\"l40s\",\n] as const;\n\n/**\n * Fly machine size preset. Derived from {@link FLY_VM_SIZES} — single source of truth.\n * When Fly adds a new size, update {@link FLY_VM_SIZES} and release a new version.\n * Pass the raw string directly — e.g. \"shared-cpu-1x\".\n */\nexport type FlyVmSize = (typeof FLY_VM_SIZES)[number];\n\n/**\n * Number of CPUs for a [[vm]] entry. Valid values depend on the chosen\n * cpu_kind — not all counts are available for both shared and performance\n * CPU kinds. The union covers the full documented permitted set.\n */\nexport type FlyCpuCount = 1 | 2 | 4 | 8 | 16;\n\n/** A single health check. */\nexport interface FlyCheck {\n\ttype?: FlyCheckType;\n\tport?: number;\n\tmethod?: string;\n\tpath?: string;\n\t/**\n\t * How often to run the check. Go duration format — e.g. \"15s\", \"1m\", \"500ms\".\n\t * Compound forms like \"1m30s\" are also valid.\n\t */\n\tinterval: string;\n\t/**\n\t * Maximum time to wait for the check to complete. Go duration format — e.g. \"10s\".\n\t * Compound forms like \"1m30s\" are also valid.\n\t */\n\ttimeout: string;\n\t/**\n\t * Grace period before checks begin after machine start. Go duration format — e.g. \"30s\".\n\t * Compound forms like \"1m30s\" are also valid.\n\t */\n\tgracePeriod?: string;\n}\n\n/** Concurrency configuration for a service. */\nexport interface FlyConcurrency {\n\ttype: FlyConcurrencyType;\n\tsoftLimit: number;\n\thardLimit: number;\n}\n\n/** `[build]` section. */\nexport interface FlyBuildConfig {\n\tdockerfile?: string;\n\timage?: string;\n}\n\n/** `[http_service]` section. */\nexport interface FlyHttpService {\n\tinternalPort: number;\n\tforceHttps?: boolean;\n\tautoStopMachines?: FlyAutoStopMachines;\n\tautoStartMachines?: boolean;\n\tminMachinesRunning?: number;\n\tprocesses?: string[];\n\tconcurrency?: FlyConcurrency;\n\tchecks?: FlyCheck[];\n}\n\n/** A `[[services.ports]]` entry. */\nexport interface FlyServicePort {\n\tport: number;\n\thandlers?: FlyPortHandler[];\n}\n\n/** A `[[services]]` entry. */\nexport interface FlyService {\n\tinternalPort: number;\n\tprotocol: FlyServiceProtocol;\n\tautoStopMachines?: FlyAutoStopMachines;\n\tautoStartMachines?: boolean;\n\tminMachinesRunning?: number;\n\tprocesses?: string[];\n\tports: FlyServicePort[];\n\tconcurrency?: FlyConcurrency;\n\tchecks?: FlyCheck[];\n}\n\n/** A `[[mounts]]` entry. */\nexport interface FlyMount {\n\tsource: string;\n\tdestination: string;\n\tprocesses?: string[];\n\tinitialSize?: string;\n}\n\n/** A `[[vm]]` entry. `count` is intentionally absent — machine count is set via `fly scale`. */\nexport interface FlyVm {\n\tsize?: FlyVmSize;\n\t/**\n\t * Memory allocation. Accepts a bare integer (interpreted as MB, e.g. 1024)\n\t * or a string with units (e.g. \"512mb\", \"2gb\"). Valid values are\n\t * hardware-tier-dependent; see https://fly.io/docs/about/pricing/.\n\t */\n\tmemory?: string | number;\n\tcpuKind?: FlyCpuKind;\n\t/** Number of CPUs. Valid values depend on the chosen `cpuKind`. */\n\tcpus?: FlyCpuCount;\n\tprocesses?: string[];\n}\n\n/** `[deploy]` section. */\nexport interface FlyDeployConfig {\n\tstrategy?: FlyDeployStrategy;\n\treleaseCommand?: string;\n}\n\n/** A `[[restart]]` entry. */\nexport interface FlyRestartConfig {\n\tpolicy?: FlyRestartPolicy;\n\tretries?: number;\n\tprocesses?: string[];\n}\n\n/**\n * Typed fly.toml configuration. All fields are plain values (NOT `pulumi.Input`)\n * because `generateFlyToml()` runs synchronously to write the toml file — resolve\n * any `Output` before constructing this object.\n */\nexport interface FlyTomlConfig {\n\tapp: string;\n\tprimaryRegion: FlyRegion;\n\tbuild?: FlyBuildConfig;\n\tenv?: Record<string, string>;\n\tprocesses?: Record<string, string>;\n\thttpService?: FlyHttpService;\n\tservices?: FlyService[];\n\tmounts?: FlyMount[];\n\tvm?: FlyVm[];\n\tdeploy?: FlyDeployConfig;\n\trestart?: FlyRestartConfig;\n\tchecks?: Record<string, FlyCheck>;\n}\n\nfunction quote(value: string): string {\n\treturn `\"${value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`;\n}\n\nfunction array(values: string[]): string {\n\treturn `[${values.map((value) => quote(value)).join(\", \")}]`;\n}\n\nfunction pushCheck(lines: string[], header: string, check: FlyCheck): void {\n\tlines.push(\"\", header);\n\n\tif (check.type !== undefined) {\n\t\tlines.push(` type = ${quote(check.type)}`);\n\t}\n\n\tif (check.port !== undefined) {\n\t\tlines.push(` port = ${check.port}`);\n\t}\n\n\tif (check.method !== undefined) {\n\t\tlines.push(` method = ${quote(check.method)}`);\n\t}\n\n\tif (check.path !== undefined) {\n\t\tlines.push(` path = ${quote(check.path)}`);\n\t}\n\n\tlines.push(` interval = ${quote(check.interval)}`);\n\tlines.push(` timeout = ${quote(check.timeout)}`);\n\n\tif (check.gracePeriod !== undefined) {\n\t\tlines.push(` grace_period = ${quote(check.gracePeriod)}`);\n\t}\n}\n\nfunction pushConcurrency(\n\tlines: string[],\n\theader: string,\n\tconcurrency: FlyConcurrency,\n): void {\n\tlines.push(\"\", header);\n\tlines.push(` type = ${quote(concurrency.type)}`);\n\tlines.push(` soft_limit = ${concurrency.softLimit}`);\n\tlines.push(` hard_limit = ${concurrency.hardLimit}`);\n}\n\n/**\n * Serializes a {@link FlyTomlConfig} into fly.toml text.\n *\n * Field names are camelCase on the TypeScript side and emitted as Fly's\n * snake_case toml keys. Output is deterministic (stable section ordering) so it\n * can be used directly as a `FlyDeploy` redeploy trigger.\n */\nexport function generateFlyToml(config: FlyTomlConfig): string {\n\tconst lines: string[] = [];\n\n\tlines.push(`app = ${quote(config.app)}`);\n\tlines.push(`primary_region = ${quote(config.primaryRegion)}`);\n\n\tif (config.build) {\n\t\tlines.push(\"\", \"[build]\");\n\n\t\tif (config.build.dockerfile !== undefined) {\n\t\t\tlines.push(` dockerfile = ${quote(config.build.dockerfile)}`);\n\t\t}\n\n\t\tif (config.build.image !== undefined) {\n\t\t\tlines.push(` image = ${quote(config.build.image)}`);\n\t\t}\n\t}\n\n\tif (config.env) {\n\t\tlines.push(\"\", \"[env]\");\n\t\tfor (const [key, value] of Object.entries(config.env)) {\n\t\t\tlines.push(` ${key} = ${quote(value)}`);\n\t\t}\n\t}\n\n\tif (config.processes) {\n\t\tlines.push(\"\", \"[processes]\");\n\t\tfor (const [key, value] of Object.entries(config.processes)) {\n\t\t\tlines.push(` ${key} = ${quote(value)}`);\n\t\t}\n\t}\n\n\tif (config.httpService) {\n\t\tconst service = config.httpService;\n\n\t\tlines.push(\"\", \"[http_service]\");\n\t\tlines.push(` internal_port = ${service.internalPort}`);\n\n\t\tif (service.forceHttps !== undefined) {\n\t\t\tlines.push(` force_https = ${service.forceHttps}`);\n\t\t}\n\n\t\tif (service.autoStopMachines !== undefined) {\n\t\t\tlines.push(` auto_stop_machines = ${quote(service.autoStopMachines)}`);\n\t\t}\n\n\t\tif (service.autoStartMachines !== undefined) {\n\t\t\tlines.push(` auto_start_machines = ${service.autoStartMachines}`);\n\t\t}\n\n\t\tif (service.minMachinesRunning !== undefined) {\n\t\t\tlines.push(` min_machines_running = ${service.minMachinesRunning}`);\n\t\t}\n\n\t\tif (service.processes !== undefined) {\n\t\t\tlines.push(` processes = ${array(service.processes)}`);\n\t\t}\n\n\t\tif (service.concurrency) {\n\t\t\tpushConcurrency(\n\t\t\t\tlines,\n\t\t\t\t\" [http_service.concurrency]\",\n\t\t\t\tservice.concurrency,\n\t\t\t);\n\t\t}\n\n\t\tif (service.checks) {\n\t\t\tfor (const check of service.checks) {\n\t\t\t\tpushCheck(lines, \" [[http_service.checks]]\", check);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.services) {\n\t\tfor (const service of config.services) {\n\t\t\tlines.push(\"\", \"[[services]]\");\n\t\t\tlines.push(` internal_port = ${service.internalPort}`);\n\t\t\tlines.push(` protocol = ${quote(service.protocol)}`);\n\n\t\t\tif (service.autoStopMachines !== undefined) {\n\t\t\t\tlines.push(` auto_stop_machines = ${quote(service.autoStopMachines)}`);\n\t\t\t}\n\n\t\t\tif (service.autoStartMachines !== undefined) {\n\t\t\t\tlines.push(` auto_start_machines = ${service.autoStartMachines}`);\n\t\t\t}\n\n\t\t\tif (service.minMachinesRunning !== undefined) {\n\t\t\t\tlines.push(` min_machines_running = ${service.minMachinesRunning}`);\n\t\t\t}\n\n\t\t\tif (service.processes !== undefined) {\n\t\t\t\tlines.push(` processes = ${array(service.processes)}`);\n\t\t\t}\n\n\t\t\tfor (const port of service.ports) {\n\t\t\t\tlines.push(\"\", \" [[services.ports]]\");\n\t\t\t\tlines.push(` port = ${port.port}`);\n\n\t\t\t\tif (port.handlers !== undefined) {\n\t\t\t\t\tlines.push(` handlers = ${array(port.handlers)}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (service.concurrency) {\n\t\t\t\tpushConcurrency(lines, \" [services.concurrency]\", service.concurrency);\n\t\t\t}\n\n\t\t\tif (service.checks) {\n\t\t\t\tfor (const check of service.checks) {\n\t\t\t\t\tpushCheck(lines, \" [[services.checks]]\", check);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.mounts) {\n\t\tfor (const mount of config.mounts) {\n\t\t\tlines.push(\"\", \"[[mounts]]\");\n\t\t\tlines.push(` source = ${quote(mount.source)}`);\n\t\t\tlines.push(` destination = ${quote(mount.destination)}`);\n\n\t\t\tif (mount.processes !== undefined) {\n\t\t\t\tlines.push(` processes = ${array(mount.processes)}`);\n\t\t\t}\n\n\t\t\tif (mount.initialSize !== undefined) {\n\t\t\t\tlines.push(` initial_size = ${quote(mount.initialSize)}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.vm) {\n\t\tfor (const vm of config.vm) {\n\t\t\tlines.push(\"\", \"[[vm]]\");\n\n\t\t\tif (vm.size !== undefined) {\n\t\t\t\tlines.push(` size = ${quote(vm.size)}`);\n\t\t\t}\n\n\t\t\tif (vm.memory !== undefined) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttypeof vm.memory === \"number\"\n\t\t\t\t\t\t? ` memory = ${vm.memory}`\n\t\t\t\t\t\t: ` memory = ${quote(vm.memory)}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (vm.cpuKind !== undefined) {\n\t\t\t\tlines.push(` cpu_kind = ${quote(vm.cpuKind)}`);\n\t\t\t}\n\n\t\t\tif (vm.cpus !== undefined) {\n\t\t\t\tlines.push(` cpus = ${vm.cpus}`);\n\t\t\t}\n\n\t\t\tif (vm.processes !== undefined) {\n\t\t\t\tlines.push(` processes = ${array(vm.processes)}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (config.deploy) {\n\t\tlines.push(\"\", \"[deploy]\");\n\n\t\tif (config.deploy.strategy !== undefined) {\n\t\t\tlines.push(` strategy = ${quote(config.deploy.strategy)}`);\n\t\t}\n\n\t\tif (config.deploy.releaseCommand !== undefined) {\n\t\t\tlines.push(` release_command = ${quote(config.deploy.releaseCommand)}`);\n\t\t}\n\t}\n\n\tif (config.restart) {\n\t\tlines.push(\"\", \"[[restart]]\");\n\n\t\tif (config.restart.policy !== undefined) {\n\t\t\tlines.push(` policy = ${quote(config.restart.policy)}`);\n\t\t}\n\n\t\tif (config.restart.retries !== undefined) {\n\t\t\tlines.push(` retries = ${config.restart.retries}`);\n\t\t}\n\n\t\tif (config.restart.processes !== undefined) {\n\t\t\tlines.push(` processes = ${array(config.restart.processes)}`);\n\t\t}\n\t}\n\n\tif (config.checks) {\n\t\tfor (const [checkName, check] of Object.entries(config.checks)) {\n\t\t\tpushCheck(lines, `[checks.${checkName}]`, check);\n\t\t}\n\t}\n\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n"],"mappings":"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"}
|
package/dist/fly/volume.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"volume.cjs","names":["FlyClient","pulumi"],"sources":["../../src/fly/volume.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\n\nimport type { FlyApp } from \"./app\";\nimport { FlyClient } from \"./client\";\nimport type { FlyProvider } from \"./provider\";\n\n/** Resolved inputs for the Fly volume dynamic provider. */\nexport interface FlyVolumeInputs {\n\t/** Fly API token. */\n\ttoken: string;\n\n\t/** App name the volume belongs to. */\n\tappName: string;\n\n\t/** Volume name (used for adoption lookup). */\n\tname: string;\n\n\t/** Region (IATA code). */\n\tregion: string;\n\n\t/** Volume size in GB. */\n\tsizeGb: number;\n}\n\n/** Persisted state for the Fly volume. */\ninterface FlyVolumeOutputs extends FlyVolumeInputs {\n\t/** Fly-assigned volume ID (`vol_…`). */\n\tvolumeId: string;\n}\n\n/** Volume response (only the fields we read). */\ninterface FlyVolumeResponse {\n\tid: string;\n\tname: string;\n\tstate: string;\n\tsize_gb: number;\n\tregion: string;\n}\n\n/**\n * Dynamic provider for Fly volumes. `create()` lists volumes and adopts one\n * matching the name (volume names are not unique, so it adopts the first\n * non-destroyed match); otherwise it creates a new encrypted volume. Growing\n * `sizeGb` extends in place; shrinking is not supported by Fly.\n */\nclass FlyVolumeResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(inputs: FlyVolumeInputs): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new FlyClient(inputs.token);\n\n\t\tconst volumes = await client.get<FlyVolumeResponse[]>(\n\t\t\t`/v1/apps/${inputs.appName}/volumes`,\n\t\t);\n\n\t\tconst existing = volumes.find(\n\t\t\t(volume) => volume.name === inputs.name && volume.state !== \"destroyed\",\n\t\t);\n\n\t\tlet volumeId: string;\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopting existing Fly volume \"${inputs.name}\" (${existing.id})`,\n\t\t\t);\n\n\t\t\tvolumeId = existing.id;\n\t\t} else {\n\t\t\tconst created = await client.post<FlyVolumeResponse>(\n\t\t\t\t`/v1/apps/${inputs.appName}/volumes`,\n\t\t\t\t{\n\t\t\t\t\tname: inputs.name,\n\t\t\t\t\tregion: inputs.region,\n\t\t\t\t\tsize_gb: inputs.sizeGb,\n\t\t\t\t\tencrypted: true,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tvolumeId = created.id;\n\t\t}\n\n\t\tconst outs: FlyVolumeOutputs = { ...inputs, volumeId };\n\n\t\treturn { id: volumeId, outs };\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: FlyVolumeOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tconst volume = await client.tryGet<FlyVolumeResponse>(\n\t\t\t`/v1/apps/${props.appName}/volumes/${id}`,\n\t\t);\n\n\t\tif (!volume) {\n\t\t\tthrow new Error(`Fly volume \"${id}\" not found during refresh`);\n\t\t}\n\n\t\treturn {\n\t\t\tid,\n\t\t\tprops: {\n\t\t\t\t...props,\n\t\t\t\tname: volume.name,\n\t\t\t\tregion: volume.region,\n\t\t\t\tsizeGb: volume.size_gb,\n\t\t\t},\n\t\t};\n\t}\n\n\tasync update(\n\t\tid: string,\n\t\tolds: FlyVolumeOutputs,\n\t\tnews: FlyVolumeInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\tif (news.sizeGb > olds.sizeGb) {\n\t\t\tconst client = new FlyClient(news.token);\n\n\t\t\tawait client.put(`/v1/apps/${news.appName}/volumes/${id}/extend`, {\n\t\t\t\tsize_gb: news.sizeGb,\n\t\t\t});\n\t\t}\n\n\t\treturn { outs: { ...news, volumeId: id } };\n\t}\n\n\tasync delete(id: string, props: FlyVolumeOutputs): Promise<void> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tawait client.delete(`/v1/apps/${props.appName}/volumes/${id}`);\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: FlyVolumeOutputs,\n\t\tnews: FlyVolumeInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.appName !== news.appName) {\n\t\t\treplaces.push(\"appName\");\n\t\t}\n\t\tif (olds.name !== news.name) {\n\t\t\treplaces.push(\"name\");\n\t\t}\n\t\tif (olds.region !== news.region) {\n\t\t\treplaces.push(\"region\");\n\t\t}\n\t\tif (news.sizeGb < olds.sizeGb) {\n\t\t\treplaces.push(\"sizeGb\");\n\t\t}\n\n\t\tconst sizeGrew = news.sizeGb > olds.sizeGb;\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0 || sizeGrew,\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 FlyVolumeResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly volumeId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tappName: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t\tregion: pulumi.Input<string>;\n\t\t\tsizeGb: pulumi.Input<number>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew FlyVolumeResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, volumeId: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for FlyVolume. */\ntype FlyVolumeOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Fly authentication context. */\n\tprovider: FlyProvider;\n\n\t/** App the volume belongs to. */\n\tapp: FlyApp;\n};\n\n/** Args for FlyVolume. */\nexport interface FlyVolumeArgs {\n\t/** Volume name. */\n\tname: pulumi.Input<string>;\n\n\t/** Region (IATA code, e.g. `\"iad\"`). */\n\tregion: pulumi.Input<string>;\n\n\t/** Volume size in GB. Can be grown (extended) but not shrunk. */\n\tsizeGb: pulumi.Input<number>;\n}\n\n/**\n * Manages a Fly volume with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const volume = new FlyVolume(\"api-data\", {\n * name: \"data\",\n * region: \"iad\",\n * sizeGb: 10,\n * }, { provider, app });\n * ```\n */\nexport class FlyVolume extends pulumi.ComponentResource {\n\t/** Fly-assigned volume ID. */\n\tpublic readonly id: pulumi.Output<string>;\n\n\tconstructor(name: string, args: FlyVolumeArgs, opts: FlyVolumeOptions) {\n\t\tconst { provider, app, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:Volume\", name, {}, pulumiOpts);\n\n\t\tconst resource = new FlyVolumeResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tappName: app.id,\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.volumeId;\n\n\t\tthis.registerOutputs({ id: this.id });\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;AA6CA,IAAM,4BAAN,MAA2E;CAC1E,MAAM,OAAO,QAA+D;EAC3E,MAAM,SAAS,IAAIA,6BAAU,OAAO,KAAK;EAMzC,MAAM,YAAW,MAJK,OAAO,IAC5B,YAAY,OAAO,QAAQ,SAC5B,GAEyB,MACvB,WAAW,OAAO,SAAS,OAAO,QAAQ,OAAO,UAAU,WAC7D;EAEA,IAAI;EAEJ,IAAI,UAAU;GACb,eAAO,IAAI,KACV,iCAAiC,OAAO,KAAK,KAAK,SAAS,GAAG,EAC/D;GAEA,WAAW,SAAS;EACrB,OAWC,YAAW,MAVW,OAAO,KAC5B,YAAY,OAAO,QAAQ,WAC3B;GACC,MAAM,OAAO;GACb,QAAQ,OAAO;GACf,SAAS,OAAO;GAChB,WAAW;EACZ,CACD,GAEmB;EAGpB,MAAM,OAAyB;GAAE,GAAG;GAAQ;EAAS;EAErD,OAAO;GAAE,IAAI;GAAU;EAAK;CAC7B;CAEA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,SAAS,MAAM,IAFFA,6BAAU,MAAM,KAET,EAAE,OAC3B,YAAY,MAAM,QAAQ,WAAW,IACtC;EAEA,IAAI,CAAC,QACJ,MAAM,IAAI,MAAM,eAAe,GAAG,2BAA2B;EAG9D,OAAO;GACN;GACA,OAAO;IACN,GAAG;IACH,MAAM,OAAO;IACb,QAAQ,OAAO;IACf,QAAQ,OAAO;GAChB;EACD;CACD;CAEA,MAAM,OACL,IACA,MACA,MACuC;EACvC,IAAI,KAAK,SAAS,KAAK,QAGtB,MAAM,IAFaA,6BAAU,KAAK,KAEvB,EAAE,IAAI,YAAY,KAAK,QAAQ,WAAW,GAAG,UAAU,EACjE,SAAS,KAAK,OACf,CAAC;EAGF,OAAO,EAAE,MAAM;GAAE,GAAG;GAAM,UAAU;EAAG,EAAE;CAC1C;CAEA,MAAM,OAAO,IAAY,OAAwC;EAGhE,MAAM,IAFaA,6BAAU,MAAM,KAExB,EAAE,OAAO,YAAY,MAAM,QAAQ,WAAW,IAAI;CAC9D;CAEA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAE5B,IAAI,KAAK,YAAY,KAAK,SACzB,SAAS,KAAK,SAAS;
|
|
1
|
+
{"version":3,"file":"volume.cjs","names":["FlyClient","pulumi"],"sources":["../../src/fly/volume.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\n\nimport type { FlyApp } from \"./app\";\nimport { FlyClient } from \"./client\";\nimport type { FlyProvider } from \"./provider\";\n\n/** Resolved inputs for the Fly volume dynamic provider. */\nexport interface FlyVolumeInputs {\n\t/** Fly API token. */\n\ttoken: string;\n\n\t/** App name the volume belongs to. */\n\tappName: string;\n\n\t/** Volume name (used for adoption lookup). */\n\tname: string;\n\n\t/** Region (IATA code). */\n\tregion: string;\n\n\t/** Volume size in GB. */\n\tsizeGb: number;\n}\n\n/** Persisted state for the Fly volume. */\ninterface FlyVolumeOutputs extends FlyVolumeInputs {\n\t/** Fly-assigned volume ID (`vol_…`). */\n\tvolumeId: string;\n}\n\n/** Volume response (only the fields we read). */\ninterface FlyVolumeResponse {\n\tid: string;\n\tname: string;\n\tstate: string;\n\tsize_gb: number;\n\tregion: string;\n}\n\n/**\n * Dynamic provider for Fly volumes. `create()` lists volumes and adopts one\n * matching the name (volume names are not unique, so it adopts the first\n * non-destroyed match); otherwise it creates a new encrypted volume. Growing\n * `sizeGb` extends in place; shrinking is not supported by Fly.\n */\nclass FlyVolumeResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(inputs: FlyVolumeInputs): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new FlyClient(inputs.token);\n\n\t\tconst volumes = await client.get<FlyVolumeResponse[]>(\n\t\t\t`/v1/apps/${inputs.appName}/volumes`,\n\t\t);\n\n\t\tconst existing = volumes.find(\n\t\t\t(volume) => volume.name === inputs.name && volume.state !== \"destroyed\",\n\t\t);\n\n\t\tlet volumeId: string;\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopting existing Fly volume \"${inputs.name}\" (${existing.id})`,\n\t\t\t);\n\n\t\t\tvolumeId = existing.id;\n\t\t} else {\n\t\t\tconst created = await client.post<FlyVolumeResponse>(\n\t\t\t\t`/v1/apps/${inputs.appName}/volumes`,\n\t\t\t\t{\n\t\t\t\t\tname: inputs.name,\n\t\t\t\t\tregion: inputs.region,\n\t\t\t\t\tsize_gb: inputs.sizeGb,\n\t\t\t\t\tencrypted: true,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tvolumeId = created.id;\n\t\t}\n\n\t\tconst outs: FlyVolumeOutputs = { ...inputs, volumeId };\n\n\t\treturn { id: volumeId, outs };\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: FlyVolumeOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tconst volume = await client.tryGet<FlyVolumeResponse>(\n\t\t\t`/v1/apps/${props.appName}/volumes/${id}`,\n\t\t);\n\n\t\tif (!volume) {\n\t\t\tthrow new Error(`Fly volume \"${id}\" not found during refresh`);\n\t\t}\n\n\t\treturn {\n\t\t\tid,\n\t\t\tprops: {\n\t\t\t\t...props,\n\t\t\t\tname: volume.name,\n\t\t\t\tregion: volume.region,\n\t\t\t\tsizeGb: volume.size_gb,\n\t\t\t},\n\t\t};\n\t}\n\n\tasync update(\n\t\tid: string,\n\t\tolds: FlyVolumeOutputs,\n\t\tnews: FlyVolumeInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\tif (news.sizeGb > olds.sizeGb) {\n\t\t\tconst client = new FlyClient(news.token);\n\n\t\t\tawait client.put(`/v1/apps/${news.appName}/volumes/${id}/extend`, {\n\t\t\t\tsize_gb: news.sizeGb,\n\t\t\t});\n\t\t}\n\n\t\treturn { outs: { ...news, volumeId: id } };\n\t}\n\n\tasync delete(id: string, props: FlyVolumeOutputs): Promise<void> {\n\t\tconst client = new FlyClient(props.token);\n\n\t\tawait client.delete(`/v1/apps/${props.appName}/volumes/${id}`);\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: FlyVolumeOutputs,\n\t\tnews: FlyVolumeInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.appName !== news.appName) {\n\t\t\treplaces.push(\"appName\");\n\t\t}\n\n\t\tif (olds.name !== news.name) {\n\t\t\treplaces.push(\"name\");\n\t\t}\n\n\t\tif (olds.region !== news.region) {\n\t\t\treplaces.push(\"region\");\n\t\t}\n\n\t\tif (news.sizeGb < olds.sizeGb) {\n\t\t\treplaces.push(\"sizeGb\");\n\t\t}\n\n\t\tconst sizeGrew = news.sizeGb > olds.sizeGb;\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0 || sizeGrew,\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 FlyVolumeResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly volumeId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tappName: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t\tregion: pulumi.Input<string>;\n\t\t\tsizeGb: pulumi.Input<number>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew FlyVolumeResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, volumeId: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for FlyVolume. */\ntype FlyVolumeOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Fly authentication context. */\n\tprovider: FlyProvider;\n\n\t/** App the volume belongs to. */\n\tapp: FlyApp;\n};\n\n/** Args for FlyVolume. */\nexport interface FlyVolumeArgs {\n\t/** Volume name. */\n\tname: pulumi.Input<string>;\n\n\t/** Region (IATA code, e.g. `\"iad\"`). */\n\tregion: pulumi.Input<string>;\n\n\t/** Volume size in GB. Can be grown (extended) but not shrunk. */\n\tsizeGb: pulumi.Input<number>;\n}\n\n/**\n * Manages a Fly volume with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const volume = new FlyVolume(\"api-data\", {\n * name: \"data\",\n * region: \"iad\",\n * sizeGb: 10,\n * }, { provider, app });\n * ```\n */\nexport class FlyVolume extends pulumi.ComponentResource {\n\t/** Fly-assigned volume ID. */\n\tpublic readonly id: pulumi.Output<string>;\n\n\tconstructor(name: string, args: FlyVolumeArgs, opts: FlyVolumeOptions) {\n\t\tconst { provider, app, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:fly:Volume\", name, {}, pulumiOpts);\n\n\t\tconst resource = new FlyVolumeResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tappName: app.id,\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.volumeId;\n\n\t\tthis.registerOutputs({ id: this.id });\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;AA6CA,IAAM,4BAAN,MAA2E;CAC1E,MAAM,OAAO,QAA+D;EAC3E,MAAM,SAAS,IAAIA,6BAAU,OAAO,KAAK;EAMzC,MAAM,YAAW,MAJK,OAAO,IAC5B,YAAY,OAAO,QAAQ,SAC5B,GAEyB,MACvB,WAAW,OAAO,SAAS,OAAO,QAAQ,OAAO,UAAU,WAC7D;EAEA,IAAI;EAEJ,IAAI,UAAU;GACb,eAAO,IAAI,KACV,iCAAiC,OAAO,KAAK,KAAK,SAAS,GAAG,EAC/D;GAEA,WAAW,SAAS;EACrB,OAWC,YAAW,MAVW,OAAO,KAC5B,YAAY,OAAO,QAAQ,WAC3B;GACC,MAAM,OAAO;GACb,QAAQ,OAAO;GACf,SAAS,OAAO;GAChB,WAAW;EACZ,CACD,GAEmB;EAGpB,MAAM,OAAyB;GAAE,GAAG;GAAQ;EAAS;EAErD,OAAO;GAAE,IAAI;GAAU;EAAK;CAC7B;CAEA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,SAAS,MAAM,IAFFA,6BAAU,MAAM,KAET,EAAE,OAC3B,YAAY,MAAM,QAAQ,WAAW,IACtC;EAEA,IAAI,CAAC,QACJ,MAAM,IAAI,MAAM,eAAe,GAAG,2BAA2B;EAG9D,OAAO;GACN;GACA,OAAO;IACN,GAAG;IACH,MAAM,OAAO;IACb,QAAQ,OAAO;IACf,QAAQ,OAAO;GAChB;EACD;CACD;CAEA,MAAM,OACL,IACA,MACA,MACuC;EACvC,IAAI,KAAK,SAAS,KAAK,QAGtB,MAAM,IAFaA,6BAAU,KAAK,KAEvB,EAAE,IAAI,YAAY,KAAK,QAAQ,WAAW,GAAG,UAAU,EACjE,SAAS,KAAK,OACf,CAAC;EAGF,OAAO,EAAE,MAAM;GAAE,GAAG;GAAM,UAAU;EAAG,EAAE;CAC1C;CAEA,MAAM,OAAO,IAAY,OAAwC;EAGhE,MAAM,IAFaA,6BAAU,MAAM,KAExB,EAAE,OAAO,YAAY,MAAM,QAAQ,WAAW,IAAI;CAC9D;CAEA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAE5B,IAAI,KAAK,YAAY,KAAK,SACzB,SAAS,KAAK,SAAS;EAGxB,IAAI,KAAK,SAAS,KAAK,MACtB,SAAS,KAAK,MAAM;EAGrB,IAAI,KAAK,WAAW,KAAK,QACxB,SAAS,KAAK,QAAQ;EAGvB,IAAI,KAAK,SAAS,KAAK,QACtB,SAAS,KAAK,QAAQ;EAGvB,MAAM,WAAW,KAAK,SAAS,KAAK;EAEpC,OAAO;GACN,SAAS,SAAS,SAAS,KAAK;GAChC;GACA,qBAAqB;EACtB;CACD;AACD;;AAGA,IAAM,oBAAN,cAAgCC,eAAO,QAAQ,SAAS;CAGvD,YACC,MACA,MAOA,MACC;EACD,MACC,IAAI,0BAA0B,GAC9B,MACA;GAAE,GAAG;GAAM,UAAU;EAAU,GAC/B,IACD;CACD;AACD;;;;;;;;;;;;;AAmCA,IAAa,YAAb,cAA+BA,eAAO,kBAAkB;CAIvD,YAAY,MAAc,MAAqB,MAAwB;EACtE,MAAM,EAAE,UAAU,KAAK,GAAG,eAAe;EAEzC,MAAM,yBAAyB,MAAM,CAAC,GAAG,UAAU;EAEnD,MAAM,WAAW,IAAI,kBACpB,GAAG,KAAK,YACR;GACC,OAAO,SAAS;GAChB,SAAS,IAAI;GACb,GAAG;EACJ,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,KAAK,SAAS;EAEnB,KAAK,gBAAgB,EAAE,IAAI,KAAK,GAAG,CAAC;CACrC;AACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"volume.d.cts","names":[],"sources":["../../src/fly/volume.ts"],"mappings":";;;;;;;UAOiB,eAAA;;EAEhB,KAAA;EAF+B;EAK/B,OAAA;EAL+B;EAQ/B,IAAA;EAHA;EAMA,MAAA;EAAA;EAGA,MAAA;AAAA;AAAM;AAAA,
|
|
1
|
+
{"version":3,"file":"volume.d.cts","names":[],"sources":["../../src/fly/volume.ts"],"mappings":";;;;;;;UAOiB,eAAA;;EAEhB,KAAA;EAF+B;EAK/B,OAAA;EAL+B;EAQ/B,IAAA;EAHA;EAMA,MAAA;EAAA;EAGA,MAAA;AAAA;AAAM;AAAA,KAwKF,gBAAA,GAAmB,IAAA,CAAK,MAAA,CAAO,wBAAA;EAAf,kCAEpB,QAAA,EAAU,WAAA,EAFkB;EAK5B,GAAA,EAAK,MAAA;AAAA;;UAIW,aAAA;EAJL;EAMX,IAAA,EAAM,MAAA,CAAO,KAAA;EAXe;EAc5B,MAAA,EAAQ,MAAA,CAAO,KAAA;EAZf;EAeA,MAAA,EAAQ,MAAA,CAAO,KAAA;AAAA;;;AAZJ;AAIZ;;;;;;;;;cAuBa,SAAA,SAAkB,MAAA,CAAO,iBAAA;EArBxB;EAAA,SAuBG,EAAA,EAAI,MAAA,CAAO,MAAA;cAEf,IAAA,UAAc,IAAA,EAAM,aAAA,EAAe,IAAA,EAAM,gBAAA;AAAA"}
|