@absolutejs/deploy 0.23.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +204 -123
  2. package/dist/appStoreConnect.d.ts +182 -0
  3. package/dist/appStoreConnect.js +587 -0
  4. package/dist/appStoreConnect.js.map +10 -0
  5. package/dist/cloudTarget.d.ts +4 -4
  6. package/dist/cloudflare.d.ts +2 -2
  7. package/dist/cloudflare.js +11 -9
  8. package/dist/cloudflare.js.map +3 -3
  9. package/dist/deployer.d.ts +9 -9
  10. package/dist/digitalocean.d.ts +5 -5
  11. package/dist/digitalocean.js +21 -13
  12. package/dist/digitalocean.js.map +5 -5
  13. package/dist/digitaloceanDns.d.ts +2 -2
  14. package/dist/digitaloceanDns.js +16 -8
  15. package/dist/digitaloceanDns.js.map +6 -6
  16. package/dist/digitaloceanEphemeralInfrastructure.js +16 -8
  17. package/dist/digitaloceanEphemeralInfrastructure.js.map +5 -5
  18. package/dist/digitaloceanInfrastructure.js +16 -8
  19. package/dist/digitaloceanInfrastructure.js.map +6 -6
  20. package/dist/digitaloceanIngress.js +16 -8
  21. package/dist/digitaloceanIngress.js.map +5 -5
  22. package/dist/dns.d.ts +1 -1
  23. package/dist/dns.js +9 -7
  24. package/dist/dns.js.map +3 -3
  25. package/dist/edgeIngress.js +11 -9
  26. package/dist/edgeIngress.js.map +2 -2
  27. package/dist/env.d.ts +1 -1
  28. package/dist/env.js +13 -11
  29. package/dist/env.js.map +3 -3
  30. package/dist/gcp.js +99 -93
  31. package/dist/gcp.js.map +3 -3
  32. package/dist/gcpIngress.js +93 -91
  33. package/dist/gcpIngress.js.map +2 -2
  34. package/dist/googlePlay.d.ts +10 -2
  35. package/dist/googlePlay.js +96 -91
  36. package/dist/googlePlay.js.map +3 -3
  37. package/dist/hetzner.d.ts +3 -3
  38. package/dist/hetzner.js +21 -13
  39. package/dist/hetzner.js.map +5 -5
  40. package/dist/hetznerDns.d.ts +2 -2
  41. package/dist/hetznerDns.js +11 -9
  42. package/dist/hetznerDns.js.map +3 -3
  43. package/dist/hetznerInfrastructure.js +16 -8
  44. package/dist/hetznerInfrastructure.js.map +7 -7
  45. package/dist/index.d.ts +5 -1
  46. package/dist/index.js +1347 -284
  47. package/dist/index.js.map +10 -8
  48. package/dist/linode.d.ts +3 -3
  49. package/dist/linode.js +21 -13
  50. package/dist/linode.js.map +5 -5
  51. package/dist/linodeInfrastructure.js +21 -9
  52. package/dist/linodeInfrastructure.js.map +7 -7
  53. package/dist/managedPreview.js +9 -7
  54. package/dist/managedPreview.js.map +2 -2
  55. package/dist/mobileUpdate.d.ts +109 -0
  56. package/dist/mobileUpdate.js +464 -0
  57. package/dist/mobileUpdate.js.map +10 -0
  58. package/dist/nativeRelease.d.ts +17 -1
  59. package/dist/nativeRelease.js +63 -22
  60. package/dist/nativeRelease.js.map +3 -3
  61. package/dist/preview.d.ts +3 -3
  62. package/dist/preview.js +15 -10
  63. package/dist/preview.js.map +3 -3
  64. package/dist/processManagers.d.ts +4 -4
  65. package/dist/releaseArtifact.js +12 -10
  66. package/dist/releaseArtifact.js.map +2 -2
  67. package/dist/route53.d.ts +2 -2
  68. package/dist/route53.js +9 -7
  69. package/dist/route53.js.map +3 -3
  70. package/dist/targets.d.ts +1 -1
  71. package/dist/tls.d.ts +5 -5
  72. package/dist/tls.js +23 -18
  73. package/dist/tls.js.map +3 -3
  74. package/dist/vultr.d.ts +4 -4
  75. package/dist/vultr.js +21 -13
  76. package/dist/vultr.js.map +5 -5
  77. package/dist/vultrInfrastructure.js +16 -8
  78. package/dist/vultrInfrastructure.js.map +7 -7
  79. package/package.json +12 -2
@@ -19,12 +19,14 @@ var __toESM = (mod, isNodeMode, target) => {
19
19
  }
20
20
  target = mod != null ? __create(__getProtoOf(mod)) : {};
21
21
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
22
- for (let key of __getOwnPropNames(mod))
23
- if (!__hasOwnProp.call(to, key))
24
- __defProp(to, key, {
25
- get: __accessProp.bind(mod, key),
26
- enumerable: true
27
- });
22
+ if (mod && typeof mod === "object" || typeof mod === "function") {
23
+ for (let key of __getOwnPropNames(mod))
24
+ if (!__hasOwnProp.call(to, key))
25
+ __defProp(to, key, {
26
+ get: __accessProp.bind(mod, key),
27
+ enumerable: true
28
+ });
29
+ }
28
30
  if (canCache)
29
31
  cache.set(mod, to);
30
32
  return to;
@@ -61,24 +63,49 @@ var parseMetadata = (value) => {
61
63
  throw new NativeReleaseRegistryError("Native release appId is invalid");
62
64
  if (!SHA256_PATTERN.test(sha256))
63
65
  throw new NativeReleaseRegistryError("Native release sha256 is invalid");
64
- if (releaseId !== `amobile_android_${sha256}`)
66
+ if (value.platform !== "android" && value.platform !== "ios")
67
+ throw new NativeReleaseRegistryError("Native release metadata is invalid");
68
+ if (releaseId !== `amobile_${value.platform}_${sha256}`)
65
69
  throw new NativeReleaseRegistryError("Native release id does not match its artifact digest");
66
- if (value.artifact !== "app-release.aab" || value.engine !== "capacitor" || value.format !== 1 || value.platform !== "android" || value.type !== "aab" || typeof value.signed !== "boolean" || !Number.isSafeInteger(value.bytes) || Number(value.bytes) < 1 || value.versionCode !== undefined && (!Number.isSafeInteger(value.versionCode) || Number(value.versionCode) < 1 || Number(value.versionCode) > 2100000000))
70
+ const commonInvalid = value.engine !== "capacitor" || value.format !== 1 || typeof value.signed !== "boolean" || !Number.isSafeInteger(value.bytes) || Number(value.bytes) < 1;
71
+ if (commonInvalid)
72
+ throw new NativeReleaseRegistryError("Native release metadata is invalid");
73
+ if (value.platform === "android") {
74
+ if (value.artifact !== "app-release.aab" || value.type !== "aab" || value.versionCode !== undefined && (!Number.isSafeInteger(value.versionCode) || Number(value.versionCode) < 1 || Number(value.versionCode) > 2100000000))
75
+ throw new NativeReleaseRegistryError("Native release metadata is invalid");
76
+ return {
77
+ appBuild: requireString(value.appBuild, "appBuild"),
78
+ appId,
79
+ artifact: "app-release.aab",
80
+ bytes: Number(value.bytes),
81
+ engine: "capacitor",
82
+ format: 1,
83
+ platform: "android",
84
+ releaseId,
85
+ runtime: requireString(value.runtime, "runtime"),
86
+ sha256,
87
+ signed: value.signed === true,
88
+ type: "aab",
89
+ ...value.versionCode === undefined ? {} : { versionCode: Number(value.versionCode) }
90
+ };
91
+ }
92
+ if (value.artifact !== "App.ipa" || value.type !== "ipa" || typeof value.marketingVersion !== "string" || !/^\d+(?:\.\d+){0,2}$/.test(value.marketingVersion) || value.buildNumber !== undefined && (!Number.isSafeInteger(value.buildNumber) || Number(value.buildNumber) < 1))
67
93
  throw new NativeReleaseRegistryError("Native release metadata is invalid");
68
94
  return {
69
95
  appBuild: requireString(value.appBuild, "appBuild"),
70
96
  appId,
71
- artifact: "app-release.aab",
97
+ artifact: "App.ipa",
98
+ ...value.buildNumber === undefined ? {} : { buildNumber: Number(value.buildNumber) },
72
99
  bytes: Number(value.bytes),
73
100
  engine: "capacitor",
74
101
  format: 1,
75
- platform: "android",
102
+ marketingVersion: value.marketingVersion,
103
+ platform: "ios",
76
104
  releaseId,
77
105
  runtime: requireString(value.runtime, "runtime"),
78
106
  sha256,
79
- signed: value.signed,
80
- type: "aab",
81
- ...value.versionCode === undefined ? {} : { versionCode: Number(value.versionCode) }
107
+ signed: value.signed === true,
108
+ type: "ipa"
82
109
  };
83
110
  };
84
111
  var normalizedPrefix = (value) => {
@@ -120,7 +147,7 @@ var parseRecord = (value) => {
120
147
  };
121
148
  };
122
149
  var parseChannel = (value) => {
123
- if (!isRecord(value) || value.format !== NATIVE_RELEASE_REGISTRY_FORMAT || value.platform !== "android" || !isIsoTimestamp(value.promotedAt))
150
+ if (!isRecord(value) || value.format !== NATIVE_RELEASE_REGISTRY_FORMAT || value.platform !== "android" && value.platform !== "ios" || !isIsoTimestamp(value.promotedAt))
124
151
  throw new NativeReleaseRegistryError("Native release channel is invalid");
125
152
  const appId = requireString(value.appId, "channel appId");
126
153
  const channel = requireChannel(requireString(value.channel, "channel"));
@@ -128,13 +155,13 @@ var parseChannel = (value) => {
128
155
  const releaseId = requireString(value.releaseId, "channel releaseId");
129
156
  if (!APP_ID_PATTERN.test(appId) || !SHA256_PATTERN.test(sha256))
130
157
  throw new NativeReleaseRegistryError("Native release channel is invalid");
131
- if (releaseId !== `amobile_android_${sha256}`)
158
+ if (releaseId !== `amobile_${value.platform}_${sha256}`)
132
159
  throw new NativeReleaseRegistryError("Native release channel identity does not match");
133
160
  return {
134
161
  appId,
135
162
  channel,
136
163
  format: NATIVE_RELEASE_REGISTRY_FORMAT,
137
- platform: "android",
164
+ platform: value.platform,
138
165
  promotedAt: value.promotedAt,
139
166
  releaseId,
140
167
  sha256
@@ -159,10 +186,10 @@ var createNativeReleaseRegistry = (options) => {
159
186
  const read = async (input) => {
160
187
  if (!APP_ID_PATTERN.test(input.appId))
161
188
  throw new NativeReleaseRegistryError("Native release appId is invalid");
162
- const digest = input.releaseId.replace(/^amobile_android_/, "");
163
- if (!SHA256_PATTERN.test(digest) || input.releaseId !== `amobile_android_${digest}`)
189
+ const digest = input.releaseId.replace(new RegExp(`^amobile_${input.platform}_`), "");
190
+ if (!SHA256_PATTERN.test(digest) || input.releaseId !== `amobile_${input.platform}_${digest}`)
164
191
  throw new NativeReleaseRegistryError("Native release id is invalid");
165
- const identity = {
192
+ const identity = input.platform === "android" ? {
166
193
  appBuild: "lookup",
167
194
  appId: input.appId,
168
195
  artifact: "app-release.aab",
@@ -175,6 +202,20 @@ var createNativeReleaseRegistry = (options) => {
175
202
  sha256: digest,
176
203
  signed: true,
177
204
  type: "aab"
205
+ } : {
206
+ appBuild: "lookup",
207
+ appId: input.appId,
208
+ artifact: "App.ipa",
209
+ bytes: 1,
210
+ engine: "capacitor",
211
+ format: 1,
212
+ marketingVersion: "1.0.0",
213
+ platform: "ios",
214
+ releaseId: input.releaseId,
215
+ runtime: "lookup",
216
+ sha256: digest,
217
+ signed: true,
218
+ type: "ipa"
178
219
  };
179
220
  const key = recordKey(identity);
180
221
  const bytes = await options.store.get(key);
@@ -335,10 +376,10 @@ var createNativeReleaseRegistry = (options) => {
335
376
  };
336
377
  };
337
378
  export {
338
- createNativeReleaseRegistry,
379
+ NATIVE_RELEASE_REGISTRY_FORMAT,
339
380
  NativeReleaseRegistryError,
340
- NATIVE_RELEASE_REGISTRY_FORMAT
381
+ createNativeReleaseRegistry
341
382
  };
342
383
 
343
- //# debugId=F46B0E029BAE2F2864756E2164756E21
384
+ //# debugId=6862EDA92AEFFC3564756E2164756E21
344
385
  //# sourceMappingURL=nativeRelease.js.map
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/nativeRelease.ts"],
4
4
  "sourcesContent": [
5
- "import { createHash } from \"node:crypto\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nconst DEFAULT_PREFIX = \"absolutejs/native-releases\";\nconst DEFAULT_MAX_ARTIFACT_BYTES = 2_147_483_648;\nexport const NATIVE_RELEASE_REGISTRY_FORMAT = 1 as const;\nconst SHA256_PATTERN = /^[a-f0-9]{64}$/;\nconst APP_ID_PATTERN = /^[A-Za-z][\\w]*(?:\\.[A-Za-z][\\w]*)+$/;\nconst CHANNEL_PATTERN = /^[a-z0-9][a-z0-9._-]{0,63}$/;\n\nexport type AndroidNativeReleaseMetadata = {\n appBuild: string;\n appId: string;\n artifact: \"app-release.aab\";\n bytes: number;\n engine: \"capacitor\";\n format: 1;\n platform: \"android\";\n releaseId: string;\n runtime: string;\n sha256: string;\n signed: boolean;\n type: \"aab\";\n versionCode?: number;\n};\n\nexport type NativeReleaseMetadata = AndroidNativeReleaseMetadata;\n\nexport type NativeReleaseRecord = {\n artifactKey: string;\n format: typeof NATIVE_RELEASE_REGISTRY_FORMAT;\n metadata: NativeReleaseMetadata;\n};\n\nexport type NativeReleaseChannel = {\n appId: string;\n channel: string;\n format: typeof NATIVE_RELEASE_REGISTRY_FORMAT;\n platform: NativeReleaseMetadata[\"platform\"];\n promotedAt: string;\n releaseId: string;\n sha256: string;\n};\n\nexport type NativeReleaseBlobObject = {\n key: string;\n metadata?: Record<string, string>;\n size: number;\n};\n\nexport type NativeReleaseBlobStore = {\n get: (key: string) => Promise<Uint8Array | null>;\n head: (key: string) => Promise<NativeReleaseBlobObject | null>;\n put: (\n key: string,\n body: ReadableStream<Uint8Array> | Uint8Array | string,\n options?: {\n cacheControl?: string;\n contentType?: string;\n maxBytes?: number;\n metadata?: Record<string, string>;\n signal?: AbortSignal;\n },\n ) => Promise<unknown>;\n};\n\nexport type NativeReleasePublication = {\n channel?: NativeReleaseChannel;\n record: NativeReleaseRecord;\n reused: boolean;\n};\n\nexport type NativeReleaseRegistry = {\n promote: (options: {\n allowUnsigned?: boolean;\n appId: string;\n channel: string;\n platform: NativeReleaseMetadata[\"platform\"];\n releaseId: string;\n signal?: AbortSignal;\n }) => Promise<NativeReleaseChannel>;\n publish: (options: {\n allowUnsigned?: boolean;\n channel?: string;\n releaseRoot: string;\n signal?: AbortSignal;\n }) => Promise<NativeReleasePublication>;\n read: (options: {\n appId: string;\n platform: NativeReleaseMetadata[\"platform\"];\n releaseId: string;\n }) => Promise<NativeReleaseRecord | null>;\n resolve: (options: {\n appId: string;\n channel: string;\n platform: NativeReleaseMetadata[\"platform\"];\n }) => Promise<{\n channel: NativeReleaseChannel;\n record: NativeReleaseRecord;\n } | null>;\n};\n\nexport type NativeReleaseRegistryOptions = {\n clock?: () => Date;\n maxArtifactBytes?: number;\n prefix?: string;\n store: NativeReleaseBlobStore;\n};\n\nexport class NativeReleaseRegistryError extends Error {}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst requireString = (value: unknown, field: string) => {\n if (typeof value !== \"string\" || value.length === 0)\n throw new NativeReleaseRegistryError(`Native release ${field} is invalid`);\n\n return value;\n};\n\nconst parseMetadata = (value: unknown): NativeReleaseMetadata => {\n if (!isRecord(value))\n throw new NativeReleaseRegistryError(\"Native release metadata is invalid\");\n const appId = requireString(value.appId, \"appId\");\n const sha256 = requireString(value.sha256, \"sha256\");\n const releaseId = requireString(value.releaseId, \"releaseId\");\n if (!APP_ID_PATTERN.test(appId))\n throw new NativeReleaseRegistryError(\"Native release appId is invalid\");\n if (!SHA256_PATTERN.test(sha256))\n throw new NativeReleaseRegistryError(\"Native release sha256 is invalid\");\n if (releaseId !== `amobile_android_${sha256}`)\n throw new NativeReleaseRegistryError(\n \"Native release id does not match its artifact digest\",\n );\n if (\n value.artifact !== \"app-release.aab\" ||\n value.engine !== \"capacitor\" ||\n value.format !== 1 ||\n value.platform !== \"android\" ||\n value.type !== \"aab\" ||\n typeof value.signed !== \"boolean\" ||\n !Number.isSafeInteger(value.bytes) ||\n Number(value.bytes) < 1 ||\n (value.versionCode !== undefined &&\n (!Number.isSafeInteger(value.versionCode) ||\n Number(value.versionCode) < 1 ||\n Number(value.versionCode) > 2_100_000_000))\n )\n throw new NativeReleaseRegistryError(\"Native release metadata is invalid\");\n\n return {\n appBuild: requireString(value.appBuild, \"appBuild\"),\n appId,\n artifact: \"app-release.aab\",\n bytes: Number(value.bytes),\n engine: \"capacitor\",\n format: 1,\n platform: \"android\",\n releaseId,\n runtime: requireString(value.runtime, \"runtime\"),\n sha256,\n signed: value.signed,\n type: \"aab\",\n ...(value.versionCode === undefined\n ? {}\n : { versionCode: Number(value.versionCode) }),\n };\n};\n\nconst normalizedPrefix = (value: string) => {\n const prefix = value.replace(/^\\/+|\\/+$/g, \"\");\n if (\n prefix.length === 0 ||\n prefix.split(\"/\").some((segment) => segment === \".\" || segment === \"..\")\n )\n throw new NativeReleaseRegistryError(\"Native release prefix is invalid\");\n\n return prefix;\n};\n\nconst requireChannel = (value: string) => {\n if (!CHANNEL_PATTERN.test(value))\n throw new NativeReleaseRegistryError(\"Native release channel is invalid\");\n\n return value;\n};\n\nconst appIdentity = (appId: string) =>\n createHash(\"sha256\").update(appId).digest(\"hex\");\n\nconst sha256Bytes = (bytes: Uint8Array) =>\n createHash(\"sha256\").update(bytes).digest(\"hex\");\n\nconst isIsoTimestamp = (value: unknown): value is string => {\n if (typeof value !== \"string\" || Number.isNaN(Date.parse(value)))\n return false;\n\n return new Date(value).toISOString() === value;\n};\n\nconst sha256File = async (file: Bun.BunFile) => {\n const hasher = new Bun.CryptoHasher(\"sha256\");\n for await (const chunk of file.stream()) hasher.update(chunk);\n\n return hasher.digest(\"hex\");\n};\n\nconst encodedJson = (value: unknown) =>\n new TextEncoder().encode(`${JSON.stringify(value, null, 2)}\\n`);\n\nconst decodedJson = (bytes: Uint8Array) =>\n JSON.parse(new TextDecoder().decode(bytes)) as unknown;\n\nconst sameMetadata = (\n left: NativeReleaseMetadata,\n right: NativeReleaseMetadata,\n) => JSON.stringify(left) === JSON.stringify(right);\n\nconst parseRecord = (value: unknown): NativeReleaseRecord => {\n if (\n !isRecord(value) ||\n value.format !== NATIVE_RELEASE_REGISTRY_FORMAT ||\n typeof value.artifactKey !== \"string\"\n )\n throw new NativeReleaseRegistryError(\"Native release record is invalid\");\n const metadata = parseMetadata(value.metadata);\n\n return {\n artifactKey: value.artifactKey,\n format: NATIVE_RELEASE_REGISTRY_FORMAT,\n metadata,\n };\n};\n\nconst parseChannel = (value: unknown): NativeReleaseChannel => {\n if (\n !isRecord(value) ||\n value.format !== NATIVE_RELEASE_REGISTRY_FORMAT ||\n value.platform !== \"android\" ||\n !isIsoTimestamp(value.promotedAt)\n )\n throw new NativeReleaseRegistryError(\"Native release channel is invalid\");\n const appId = requireString(value.appId, \"channel appId\");\n const channel = requireChannel(requireString(value.channel, \"channel\"));\n const sha256 = requireString(value.sha256, \"channel sha256\");\n const releaseId = requireString(value.releaseId, \"channel releaseId\");\n if (!APP_ID_PATTERN.test(appId) || !SHA256_PATTERN.test(sha256))\n throw new NativeReleaseRegistryError(\"Native release channel is invalid\");\n if (releaseId !== `amobile_android_${sha256}`)\n throw new NativeReleaseRegistryError(\n \"Native release channel identity does not match\",\n );\n\n return {\n appId,\n channel,\n format: NATIVE_RELEASE_REGISTRY_FORMAT,\n platform: \"android\",\n promotedAt: value.promotedAt,\n releaseId,\n sha256,\n };\n};\n\nexport const createNativeReleaseRegistry = (\n options: NativeReleaseRegistryOptions,\n): NativeReleaseRegistry => {\n const prefix = normalizedPrefix(options.prefix ?? DEFAULT_PREFIX);\n const maxArtifactBytes =\n options.maxArtifactBytes ?? DEFAULT_MAX_ARTIFACT_BYTES;\n if (!Number.isSafeInteger(maxArtifactBytes) || maxArtifactBytes < 1)\n throw new NativeReleaseRegistryError(\n \"Native release maxArtifactBytes is invalid\",\n );\n const clock = options.clock ?? (() => new Date());\n const appRoot = (appId: string, platform: \"android\") =>\n `${prefix}/${appIdentity(appId)}/${platform}`;\n const releaseRoot = (metadata: NativeReleaseMetadata) =>\n `${appRoot(metadata.appId, metadata.platform)}/releases/${metadata.releaseId}`;\n const recordKey = (metadata: NativeReleaseMetadata) =>\n `${releaseRoot(metadata)}/release.json`;\n const artifactKey = (metadata: NativeReleaseMetadata) =>\n `${releaseRoot(metadata)}/${metadata.artifact}`;\n const channelKey = (appId: string, platform: \"android\", channel: string) =>\n `${appRoot(appId, platform)}/channels/${requireChannel(channel)}.json`;\n\n const requireStoredArtifact = async (\n key: string,\n metadata: NativeReleaseMetadata,\n ) => {\n const stored = await options.store.head(key);\n if (\n !stored ||\n stored.size !== metadata.bytes ||\n stored.metadata?.sha256 !== metadata.sha256 ||\n stored.metadata?.releaseId !== metadata.releaseId\n )\n throw new NativeReleaseRegistryError(\n \"Stored native release artifact does not match its immutable identity\",\n );\n };\n\n const read = async (input: {\n appId: string;\n platform: \"android\";\n releaseId: string;\n }) => {\n if (!APP_ID_PATTERN.test(input.appId))\n throw new NativeReleaseRegistryError(\"Native release appId is invalid\");\n const digest = input.releaseId.replace(/^amobile_android_/, \"\");\n if (\n !SHA256_PATTERN.test(digest) ||\n input.releaseId !== `amobile_android_${digest}`\n )\n throw new NativeReleaseRegistryError(\"Native release id is invalid\");\n const identity: NativeReleaseMetadata = {\n appBuild: \"lookup\",\n appId: input.appId,\n artifact: \"app-release.aab\",\n bytes: 1,\n engine: \"capacitor\",\n format: 1,\n platform: \"android\",\n releaseId: input.releaseId,\n runtime: \"lookup\",\n sha256: digest,\n signed: true,\n type: \"aab\",\n };\n const key = recordKey(identity);\n const bytes = await options.store.get(key);\n if (!bytes) return null;\n const storedRecord = await options.store.head(key);\n if (\n !storedRecord ||\n storedRecord.size !== bytes.byteLength ||\n storedRecord.metadata?.releaseId !== input.releaseId ||\n storedRecord.metadata?.sha256 !== sha256Bytes(bytes)\n )\n throw new NativeReleaseRegistryError(\n \"Stored native release record does not match its immutable identity\",\n );\n const record = parseRecord(decodedJson(bytes));\n if (\n record.metadata.appId !== input.appId ||\n record.metadata.platform !== input.platform ||\n record.metadata.releaseId !== input.releaseId ||\n record.artifactKey !== artifactKey(record.metadata)\n )\n throw new NativeReleaseRegistryError(\n \"Stored native release record identity does not match\",\n );\n await requireStoredArtifact(record.artifactKey, record.metadata);\n\n return record;\n };\n\n const promote: NativeReleaseRegistry[\"promote\"] = async (input) => {\n input.signal?.throwIfAborted();\n const record = await read(input);\n if (!record)\n throw new NativeReleaseRegistryError(\"Native release was not published\");\n if (!record.metadata.signed && !input.allowUnsigned)\n throw new NativeReleaseRegistryError(\n \"Unsigned native releases cannot be promoted\",\n );\n const key = channelKey(input.appId, input.platform, input.channel);\n const existingBytes = await options.store.get(key);\n if (existingBytes) {\n const existing = parseChannel(decodedJson(existingBytes));\n if (\n existing.appId !== input.appId ||\n existing.platform !== input.platform ||\n existing.channel !== input.channel\n )\n throw new NativeReleaseRegistryError(\n \"Stored native release channel identity does not match\",\n );\n if (existing.releaseId === input.releaseId) return existing;\n }\n const channel: NativeReleaseChannel = {\n appId: input.appId,\n channel: requireChannel(input.channel),\n format: NATIVE_RELEASE_REGISTRY_FORMAT,\n platform: input.platform,\n promotedAt: clock().toISOString(),\n releaseId: record.metadata.releaseId,\n sha256: record.metadata.sha256,\n };\n const serialized = encodedJson(channel);\n await options.store.put(key, serialized, {\n cacheControl: \"no-cache\",\n contentType: \"application/json\",\n maxBytes: serialized.byteLength,\n metadata: {\n channel: channel.channel,\n releaseId: channel.releaseId,\n sha256: channel.sha256,\n },\n signal: input.signal,\n });\n const stored = await options.store.get(key);\n if (\n !stored ||\n JSON.stringify(parseChannel(decodedJson(stored))) !==\n JSON.stringify(channel)\n )\n throw new NativeReleaseRegistryError(\n \"Native release channel verification failed\",\n );\n\n return channel;\n };\n\n return {\n promote,\n publish: async (input) => {\n input.signal?.throwIfAborted();\n const localRoot = path.resolve(input.releaseRoot);\n const metadata = parseMetadata(\n JSON.parse(\n await readFile(path.join(localRoot, \"release.json\"), \"utf8\"),\n ),\n );\n if (metadata.bytes > maxArtifactBytes)\n throw new NativeReleaseRegistryError(\n \"Native release exceeds the configured artifact limit\",\n );\n if (!metadata.signed && !input.allowUnsigned)\n throw new NativeReleaseRegistryError(\n \"Unsigned native releases cannot be published\",\n );\n const localArtifact = path.join(localRoot, metadata.artifact);\n const artifactStats = await stat(localArtifact).catch(() => null);\n if (!artifactStats?.isFile() || artifactStats.size !== metadata.bytes)\n throw new NativeReleaseRegistryError(\n \"Native release artifact size does not match its metadata\",\n );\n if ((await sha256File(Bun.file(localArtifact))) !== metadata.sha256)\n throw new NativeReleaseRegistryError(\n \"Native release artifact digest does not match its metadata\",\n );\n const existing = await read({\n appId: metadata.appId,\n platform: metadata.platform,\n releaseId: metadata.releaseId,\n });\n let record: NativeReleaseRecord;\n let reused = false;\n if (existing) {\n if (!sameMetadata(existing.metadata, metadata))\n throw new NativeReleaseRegistryError(\n \"Published native release metadata is immutable\",\n );\n record = existing;\n reused = true;\n } else {\n const key = artifactKey(metadata);\n const storedArtifact = await options.store.head(key);\n if (storedArtifact) {\n await requireStoredArtifact(key, metadata);\n } else {\n await options.store.put(key, Bun.file(localArtifact).stream(), {\n cacheControl: \"public, max-age=31536000, immutable\",\n contentType: \"application/octet-stream\",\n maxBytes: metadata.bytes,\n metadata: {\n appId: metadata.appId,\n releaseId: metadata.releaseId,\n sha256: metadata.sha256,\n },\n signal: input.signal,\n });\n await requireStoredArtifact(key, metadata);\n }\n record = {\n artifactKey: key,\n format: NATIVE_RELEASE_REGISTRY_FORMAT,\n metadata,\n };\n const serialized = encodedJson(record);\n await options.store.put(recordKey(metadata), serialized, {\n cacheControl: \"public, max-age=31536000, immutable\",\n contentType: \"application/json\",\n maxBytes: serialized.byteLength,\n metadata: {\n releaseId: metadata.releaseId,\n sha256: sha256Bytes(serialized),\n },\n signal: input.signal,\n });\n const verified = await read({\n appId: metadata.appId,\n platform: metadata.platform,\n releaseId: metadata.releaseId,\n });\n if (!verified || JSON.stringify(verified) !== JSON.stringify(record))\n throw new NativeReleaseRegistryError(\n \"Native release publication verification failed\",\n );\n }\n const channel = input.channel\n ? await promote({\n allowUnsigned: input.allowUnsigned,\n appId: metadata.appId,\n channel: input.channel,\n platform: metadata.platform,\n releaseId: metadata.releaseId,\n signal: input.signal,\n })\n : undefined;\n\n return { ...(channel ? { channel } : {}), record, reused };\n },\n read,\n resolve: async (input) => {\n if (!APP_ID_PATTERN.test(input.appId))\n throw new NativeReleaseRegistryError(\"Native release appId is invalid\");\n const key = channelKey(input.appId, input.platform, input.channel);\n const bytes = await options.store.get(key);\n if (!bytes) return null;\n const channel = parseChannel(decodedJson(bytes));\n if (\n channel.appId !== input.appId ||\n channel.platform !== input.platform ||\n channel.channel !== input.channel\n )\n throw new NativeReleaseRegistryError(\n \"Stored native release channel identity does not match\",\n );\n const record = await read({\n appId: channel.appId,\n platform: channel.platform,\n releaseId: channel.releaseId,\n });\n if (!record || record.metadata.sha256 !== channel.sha256)\n throw new NativeReleaseRegistryError(\n \"Native release channel points to a missing or invalid release\",\n );\n\n return { channel, record };\n },\n };\n};\n"
5
+ "import { createHash } from \"node:crypto\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nconst DEFAULT_PREFIX = \"absolutejs/native-releases\";\nconst DEFAULT_MAX_ARTIFACT_BYTES = 2_147_483_648;\nexport const NATIVE_RELEASE_REGISTRY_FORMAT = 1 as const;\nconst SHA256_PATTERN = /^[a-f0-9]{64}$/;\nconst APP_ID_PATTERN = /^[A-Za-z][\\w]*(?:\\.[A-Za-z][\\w]*)+$/;\nconst CHANNEL_PATTERN = /^[a-z0-9][a-z0-9._-]{0,63}$/;\n\nexport type AndroidNativeReleaseMetadata = {\n appBuild: string;\n appId: string;\n artifact: \"app-release.aab\";\n bytes: number;\n engine: \"capacitor\";\n format: 1;\n platform: \"android\";\n releaseId: string;\n runtime: string;\n sha256: string;\n signed: boolean;\n type: \"aab\";\n versionCode?: number;\n};\n\nexport type IosNativeReleaseMetadata = {\n appBuild: string;\n appId: string;\n artifact: \"App.ipa\";\n buildNumber?: number;\n bytes: number;\n engine: \"capacitor\";\n format: 1;\n marketingVersion: string;\n platform: \"ios\";\n releaseId: string;\n runtime: string;\n sha256: string;\n signed: boolean;\n type: \"ipa\";\n};\n\nexport type NativeReleaseMetadata =\n | AndroidNativeReleaseMetadata\n | IosNativeReleaseMetadata;\n\nexport type NativeReleaseRecord = {\n artifactKey: string;\n format: typeof NATIVE_RELEASE_REGISTRY_FORMAT;\n metadata: NativeReleaseMetadata;\n};\n\nexport type NativeReleaseChannel = {\n appId: string;\n channel: string;\n format: typeof NATIVE_RELEASE_REGISTRY_FORMAT;\n platform: NativeReleaseMetadata[\"platform\"];\n promotedAt: string;\n releaseId: string;\n sha256: string;\n};\n\nexport type NativeReleaseBlobObject = {\n key: string;\n metadata?: Record<string, string>;\n size: number;\n};\n\nexport type NativeReleaseBlobStore = {\n get: (key: string) => Promise<Uint8Array | null>;\n head: (key: string) => Promise<NativeReleaseBlobObject | null>;\n put: (\n key: string,\n body: ReadableStream<Uint8Array> | Uint8Array | string,\n options?: {\n cacheControl?: string;\n contentType?: string;\n maxBytes?: number;\n metadata?: Record<string, string>;\n signal?: AbortSignal;\n },\n ) => Promise<unknown>;\n};\n\nexport type NativeReleasePublication = {\n channel?: NativeReleaseChannel;\n record: NativeReleaseRecord;\n reused: boolean;\n};\n\nexport type NativeReleaseRegistry = {\n promote: (options: {\n allowUnsigned?: boolean;\n appId: string;\n channel: string;\n platform: NativeReleaseMetadata[\"platform\"];\n releaseId: string;\n signal?: AbortSignal;\n }) => Promise<NativeReleaseChannel>;\n publish: (options: {\n allowUnsigned?: boolean;\n channel?: string;\n releaseRoot: string;\n signal?: AbortSignal;\n }) => Promise<NativeReleasePublication>;\n read: (options: {\n appId: string;\n platform: NativeReleaseMetadata[\"platform\"];\n releaseId: string;\n }) => Promise<NativeReleaseRecord | null>;\n resolve: (options: {\n appId: string;\n channel: string;\n platform: NativeReleaseMetadata[\"platform\"];\n }) => Promise<{\n channel: NativeReleaseChannel;\n record: NativeReleaseRecord;\n } | null>;\n};\n\nexport type NativeReleaseRegistryOptions = {\n clock?: () => Date;\n maxArtifactBytes?: number;\n prefix?: string;\n store: NativeReleaseBlobStore;\n};\n\nexport class NativeReleaseRegistryError extends Error {}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst requireString = (value: unknown, field: string) => {\n if (typeof value !== \"string\" || value.length === 0)\n throw new NativeReleaseRegistryError(`Native release ${field} is invalid`);\n\n return value;\n};\n\nconst parseMetadata = (value: unknown): NativeReleaseMetadata => {\n if (!isRecord(value))\n throw new NativeReleaseRegistryError(\"Native release metadata is invalid\");\n const appId = requireString(value.appId, \"appId\");\n const sha256 = requireString(value.sha256, \"sha256\");\n const releaseId = requireString(value.releaseId, \"releaseId\");\n if (!APP_ID_PATTERN.test(appId))\n throw new NativeReleaseRegistryError(\"Native release appId is invalid\");\n if (!SHA256_PATTERN.test(sha256))\n throw new NativeReleaseRegistryError(\"Native release sha256 is invalid\");\n if (value.platform !== \"android\" && value.platform !== \"ios\")\n throw new NativeReleaseRegistryError(\"Native release metadata is invalid\");\n if (releaseId !== `amobile_${value.platform}_${sha256}`)\n throw new NativeReleaseRegistryError(\n \"Native release id does not match its artifact digest\",\n );\n const commonInvalid =\n value.engine !== \"capacitor\" ||\n value.format !== 1 ||\n typeof value.signed !== \"boolean\" ||\n !Number.isSafeInteger(value.bytes) ||\n Number(value.bytes) < 1;\n if (commonInvalid)\n throw new NativeReleaseRegistryError(\"Native release metadata is invalid\");\n if (value.platform === \"android\") {\n if (\n value.artifact !== \"app-release.aab\" ||\n value.type !== \"aab\" ||\n (value.versionCode !== undefined &&\n (!Number.isSafeInteger(value.versionCode) ||\n Number(value.versionCode) < 1 ||\n Number(value.versionCode) > 2_100_000_000))\n )\n throw new NativeReleaseRegistryError(\n \"Native release metadata is invalid\",\n );\n\n return {\n appBuild: requireString(value.appBuild, \"appBuild\"),\n appId,\n artifact: \"app-release.aab\",\n bytes: Number(value.bytes),\n engine: \"capacitor\",\n format: 1,\n platform: \"android\",\n releaseId,\n runtime: requireString(value.runtime, \"runtime\"),\n sha256,\n signed: value.signed === true,\n type: \"aab\",\n ...(value.versionCode === undefined\n ? {}\n : { versionCode: Number(value.versionCode) }),\n };\n }\n if (\n value.artifact !== \"App.ipa\" ||\n value.type !== \"ipa\" ||\n typeof value.marketingVersion !== \"string\" ||\n !/^\\d+(?:\\.\\d+){0,2}$/.test(value.marketingVersion) ||\n (value.buildNumber !== undefined &&\n (!Number.isSafeInteger(value.buildNumber) ||\n Number(value.buildNumber) < 1))\n )\n throw new NativeReleaseRegistryError(\"Native release metadata is invalid\");\n\n return {\n appBuild: requireString(value.appBuild, \"appBuild\"),\n appId,\n artifact: \"App.ipa\",\n ...(value.buildNumber === undefined\n ? {}\n : { buildNumber: Number(value.buildNumber) }),\n bytes: Number(value.bytes),\n engine: \"capacitor\",\n format: 1,\n marketingVersion: value.marketingVersion,\n platform: \"ios\",\n releaseId,\n runtime: requireString(value.runtime, \"runtime\"),\n sha256,\n signed: value.signed === true,\n type: \"ipa\",\n };\n};\n\nconst normalizedPrefix = (value: string) => {\n const prefix = value.replace(/^\\/+|\\/+$/g, \"\");\n if (\n prefix.length === 0 ||\n prefix.split(\"/\").some((segment) => segment === \".\" || segment === \"..\")\n )\n throw new NativeReleaseRegistryError(\"Native release prefix is invalid\");\n\n return prefix;\n};\n\nconst requireChannel = (value: string) => {\n if (!CHANNEL_PATTERN.test(value))\n throw new NativeReleaseRegistryError(\"Native release channel is invalid\");\n\n return value;\n};\n\nconst appIdentity = (appId: string) =>\n createHash(\"sha256\").update(appId).digest(\"hex\");\n\nconst sha256Bytes = (bytes: Uint8Array) =>\n createHash(\"sha256\").update(bytes).digest(\"hex\");\n\nconst isIsoTimestamp = (value: unknown): value is string => {\n if (typeof value !== \"string\" || Number.isNaN(Date.parse(value)))\n return false;\n\n return new Date(value).toISOString() === value;\n};\n\nconst sha256File = async (file: Bun.BunFile) => {\n const hasher = new Bun.CryptoHasher(\"sha256\");\n for await (const chunk of file.stream()) hasher.update(chunk);\n\n return hasher.digest(\"hex\");\n};\n\nconst encodedJson = (value: unknown) =>\n new TextEncoder().encode(`${JSON.stringify(value, null, 2)}\\n`);\n\nconst decodedJson = (bytes: Uint8Array) =>\n JSON.parse(new TextDecoder().decode(bytes)) as unknown;\n\nconst sameMetadata = (\n left: NativeReleaseMetadata,\n right: NativeReleaseMetadata,\n) => JSON.stringify(left) === JSON.stringify(right);\n\nconst parseRecord = (value: unknown): NativeReleaseRecord => {\n if (\n !isRecord(value) ||\n value.format !== NATIVE_RELEASE_REGISTRY_FORMAT ||\n typeof value.artifactKey !== \"string\"\n )\n throw new NativeReleaseRegistryError(\"Native release record is invalid\");\n const metadata = parseMetadata(value.metadata);\n\n return {\n artifactKey: value.artifactKey,\n format: NATIVE_RELEASE_REGISTRY_FORMAT,\n metadata,\n };\n};\n\nconst parseChannel = (value: unknown): NativeReleaseChannel => {\n if (\n !isRecord(value) ||\n value.format !== NATIVE_RELEASE_REGISTRY_FORMAT ||\n (value.platform !== \"android\" && value.platform !== \"ios\") ||\n !isIsoTimestamp(value.promotedAt)\n )\n throw new NativeReleaseRegistryError(\"Native release channel is invalid\");\n const appId = requireString(value.appId, \"channel appId\");\n const channel = requireChannel(requireString(value.channel, \"channel\"));\n const sha256 = requireString(value.sha256, \"channel sha256\");\n const releaseId = requireString(value.releaseId, \"channel releaseId\");\n if (!APP_ID_PATTERN.test(appId) || !SHA256_PATTERN.test(sha256))\n throw new NativeReleaseRegistryError(\"Native release channel is invalid\");\n if (releaseId !== `amobile_${value.platform}_${sha256}`)\n throw new NativeReleaseRegistryError(\n \"Native release channel identity does not match\",\n );\n\n return {\n appId,\n channel,\n format: NATIVE_RELEASE_REGISTRY_FORMAT,\n platform: value.platform,\n promotedAt: value.promotedAt,\n releaseId,\n sha256,\n };\n};\n\nexport const createNativeReleaseRegistry = (\n options: NativeReleaseRegistryOptions,\n): NativeReleaseRegistry => {\n const prefix = normalizedPrefix(options.prefix ?? DEFAULT_PREFIX);\n const maxArtifactBytes =\n options.maxArtifactBytes ?? DEFAULT_MAX_ARTIFACT_BYTES;\n if (!Number.isSafeInteger(maxArtifactBytes) || maxArtifactBytes < 1)\n throw new NativeReleaseRegistryError(\n \"Native release maxArtifactBytes is invalid\",\n );\n const clock = options.clock ?? (() => new Date());\n const appRoot = (\n appId: string,\n platform: NativeReleaseMetadata[\"platform\"],\n ) => `${prefix}/${appIdentity(appId)}/${platform}`;\n const releaseRoot = (metadata: NativeReleaseMetadata) =>\n `${appRoot(metadata.appId, metadata.platform)}/releases/${metadata.releaseId}`;\n const recordKey = (metadata: NativeReleaseMetadata) =>\n `${releaseRoot(metadata)}/release.json`;\n const artifactKey = (metadata: NativeReleaseMetadata) =>\n `${releaseRoot(metadata)}/${metadata.artifact}`;\n const channelKey = (\n appId: string,\n platform: NativeReleaseMetadata[\"platform\"],\n channel: string,\n ) => `${appRoot(appId, platform)}/channels/${requireChannel(channel)}.json`;\n\n const requireStoredArtifact = async (\n key: string,\n metadata: NativeReleaseMetadata,\n ) => {\n const stored = await options.store.head(key);\n if (\n !stored ||\n stored.size !== metadata.bytes ||\n stored.metadata?.sha256 !== metadata.sha256 ||\n stored.metadata?.releaseId !== metadata.releaseId\n )\n throw new NativeReleaseRegistryError(\n \"Stored native release artifact does not match its immutable identity\",\n );\n };\n\n const read = async (input: {\n appId: string;\n platform: NativeReleaseMetadata[\"platform\"];\n releaseId: string;\n }) => {\n if (!APP_ID_PATTERN.test(input.appId))\n throw new NativeReleaseRegistryError(\"Native release appId is invalid\");\n const digest = input.releaseId.replace(\n new RegExp(`^amobile_${input.platform}_`),\n \"\",\n );\n if (\n !SHA256_PATTERN.test(digest) ||\n input.releaseId !== `amobile_${input.platform}_${digest}`\n )\n throw new NativeReleaseRegistryError(\"Native release id is invalid\");\n const identity: NativeReleaseMetadata =\n input.platform === \"android\"\n ? {\n appBuild: \"lookup\",\n appId: input.appId,\n artifact: \"app-release.aab\",\n bytes: 1,\n engine: \"capacitor\",\n format: 1,\n platform: \"android\",\n releaseId: input.releaseId,\n runtime: \"lookup\",\n sha256: digest,\n signed: true,\n type: \"aab\",\n }\n : {\n appBuild: \"lookup\",\n appId: input.appId,\n artifact: \"App.ipa\",\n bytes: 1,\n engine: \"capacitor\",\n format: 1,\n marketingVersion: \"1.0.0\",\n platform: \"ios\",\n releaseId: input.releaseId,\n runtime: \"lookup\",\n sha256: digest,\n signed: true,\n type: \"ipa\",\n };\n const key = recordKey(identity);\n const bytes = await options.store.get(key);\n if (!bytes) return null;\n const storedRecord = await options.store.head(key);\n if (\n !storedRecord ||\n storedRecord.size !== bytes.byteLength ||\n storedRecord.metadata?.releaseId !== input.releaseId ||\n storedRecord.metadata?.sha256 !== sha256Bytes(bytes)\n )\n throw new NativeReleaseRegistryError(\n \"Stored native release record does not match its immutable identity\",\n );\n const record = parseRecord(decodedJson(bytes));\n if (\n record.metadata.appId !== input.appId ||\n record.metadata.platform !== input.platform ||\n record.metadata.releaseId !== input.releaseId ||\n record.artifactKey !== artifactKey(record.metadata)\n )\n throw new NativeReleaseRegistryError(\n \"Stored native release record identity does not match\",\n );\n await requireStoredArtifact(record.artifactKey, record.metadata);\n\n return record;\n };\n\n const promote: NativeReleaseRegistry[\"promote\"] = async (input) => {\n input.signal?.throwIfAborted();\n const record = await read(input);\n if (!record)\n throw new NativeReleaseRegistryError(\"Native release was not published\");\n if (!record.metadata.signed && !input.allowUnsigned)\n throw new NativeReleaseRegistryError(\n \"Unsigned native releases cannot be promoted\",\n );\n const key = channelKey(input.appId, input.platform, input.channel);\n const existingBytes = await options.store.get(key);\n if (existingBytes) {\n const existing = parseChannel(decodedJson(existingBytes));\n if (\n existing.appId !== input.appId ||\n existing.platform !== input.platform ||\n existing.channel !== input.channel\n )\n throw new NativeReleaseRegistryError(\n \"Stored native release channel identity does not match\",\n );\n if (existing.releaseId === input.releaseId) return existing;\n }\n const channel: NativeReleaseChannel = {\n appId: input.appId,\n channel: requireChannel(input.channel),\n format: NATIVE_RELEASE_REGISTRY_FORMAT,\n platform: input.platform,\n promotedAt: clock().toISOString(),\n releaseId: record.metadata.releaseId,\n sha256: record.metadata.sha256,\n };\n const serialized = encodedJson(channel);\n await options.store.put(key, serialized, {\n cacheControl: \"no-cache\",\n contentType: \"application/json\",\n maxBytes: serialized.byteLength,\n metadata: {\n channel: channel.channel,\n releaseId: channel.releaseId,\n sha256: channel.sha256,\n },\n signal: input.signal,\n });\n const stored = await options.store.get(key);\n if (\n !stored ||\n JSON.stringify(parseChannel(decodedJson(stored))) !==\n JSON.stringify(channel)\n )\n throw new NativeReleaseRegistryError(\n \"Native release channel verification failed\",\n );\n\n return channel;\n };\n\n return {\n promote,\n publish: async (input) => {\n input.signal?.throwIfAborted();\n const localRoot = path.resolve(input.releaseRoot);\n const metadata = parseMetadata(\n JSON.parse(\n await readFile(path.join(localRoot, \"release.json\"), \"utf8\"),\n ),\n );\n if (metadata.bytes > maxArtifactBytes)\n throw new NativeReleaseRegistryError(\n \"Native release exceeds the configured artifact limit\",\n );\n if (!metadata.signed && !input.allowUnsigned)\n throw new NativeReleaseRegistryError(\n \"Unsigned native releases cannot be published\",\n );\n const localArtifact = path.join(localRoot, metadata.artifact);\n const artifactStats = await stat(localArtifact).catch(() => null);\n if (!artifactStats?.isFile() || artifactStats.size !== metadata.bytes)\n throw new NativeReleaseRegistryError(\n \"Native release artifact size does not match its metadata\",\n );\n if ((await sha256File(Bun.file(localArtifact))) !== metadata.sha256)\n throw new NativeReleaseRegistryError(\n \"Native release artifact digest does not match its metadata\",\n );\n const existing = await read({\n appId: metadata.appId,\n platform: metadata.platform,\n releaseId: metadata.releaseId,\n });\n let record: NativeReleaseRecord;\n let reused = false;\n if (existing) {\n if (!sameMetadata(existing.metadata, metadata))\n throw new NativeReleaseRegistryError(\n \"Published native release metadata is immutable\",\n );\n record = existing;\n reused = true;\n } else {\n const key = artifactKey(metadata);\n const storedArtifact = await options.store.head(key);\n if (storedArtifact) {\n await requireStoredArtifact(key, metadata);\n } else {\n await options.store.put(key, Bun.file(localArtifact).stream(), {\n cacheControl: \"public, max-age=31536000, immutable\",\n contentType: \"application/octet-stream\",\n maxBytes: metadata.bytes,\n metadata: {\n appId: metadata.appId,\n releaseId: metadata.releaseId,\n sha256: metadata.sha256,\n },\n signal: input.signal,\n });\n await requireStoredArtifact(key, metadata);\n }\n record = {\n artifactKey: key,\n format: NATIVE_RELEASE_REGISTRY_FORMAT,\n metadata,\n };\n const serialized = encodedJson(record);\n await options.store.put(recordKey(metadata), serialized, {\n cacheControl: \"public, max-age=31536000, immutable\",\n contentType: \"application/json\",\n maxBytes: serialized.byteLength,\n metadata: {\n releaseId: metadata.releaseId,\n sha256: sha256Bytes(serialized),\n },\n signal: input.signal,\n });\n const verified = await read({\n appId: metadata.appId,\n platform: metadata.platform,\n releaseId: metadata.releaseId,\n });\n if (!verified || JSON.stringify(verified) !== JSON.stringify(record))\n throw new NativeReleaseRegistryError(\n \"Native release publication verification failed\",\n );\n }\n const channel = input.channel\n ? await promote({\n allowUnsigned: input.allowUnsigned,\n appId: metadata.appId,\n channel: input.channel,\n platform: metadata.platform,\n releaseId: metadata.releaseId,\n signal: input.signal,\n })\n : undefined;\n\n return { ...(channel ? { channel } : {}), record, reused };\n },\n read,\n resolve: async (input) => {\n if (!APP_ID_PATTERN.test(input.appId))\n throw new NativeReleaseRegistryError(\"Native release appId is invalid\");\n const key = channelKey(input.appId, input.platform, input.channel);\n const bytes = await options.store.get(key);\n if (!bytes) return null;\n const channel = parseChannel(decodedJson(bytes));\n if (\n channel.appId !== input.appId ||\n channel.platform !== input.platform ||\n channel.channel !== input.channel\n )\n throw new NativeReleaseRegistryError(\n \"Stored native release channel identity does not match\",\n );\n const record = await read({\n appId: channel.appId,\n platform: channel.platform,\n releaseId: channel.releaseId,\n });\n if (!record || record.metadata.sha256 !== channel.sha256)\n throw new NativeReleaseRegistryError(\n \"Native release channel points to a missing or invalid release\",\n );\n\n return { channel, record };\n },\n };\n};\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "F46B0E029BAE2F2864756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "6862EDA92AEFFC3564756E2164756E21",
9
9
  "names": []
10
10
  }
package/dist/preview.d.ts CHANGED
@@ -29,8 +29,8 @@
29
29
  * stopping the process) is a caller-supplied hook. The fleet owns
30
30
  * fleet bookkeeping, not application logic.
31
31
  */
32
- import type { Deployer, DeployResult, ReleaseAnnotations } from './deployer';
33
- import type { DnsProvider } from './dns';
32
+ import type { Deployer, DeployResult, ReleaseAnnotations } from "./deployer";
33
+ import type { DnsProvider } from "./dns";
34
34
  export type PreviewRecord = {
35
35
  previewId: string;
36
36
  hostname: string;
@@ -64,7 +64,7 @@ export type PreviewFleetOptions = {
64
64
  * Optional URL scheme. Defaults to `'https'`. Set `'http'` for
65
65
  * local-loop previews behind a localhost proxy.
66
66
  */
67
- scheme?: 'http' | 'https';
67
+ scheme?: "http" | "https";
68
68
  /**
69
69
  * DNS provider — `cloudflareProvider`, `route53Provider`, etc.
70
70
  * Optional: when absent, `fleet.create` skips DNS work and the
package/dist/preview.js CHANGED
@@ -19,12 +19,14 @@ var __toESM = (mod, isNodeMode, target) => {
19
19
  }
20
20
  target = mod != null ? __create(__getProtoOf(mod)) : {};
21
21
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
22
- for (let key of __getOwnPropNames(mod))
23
- if (!__hasOwnProp.call(to, key))
24
- __defProp(to, key, {
25
- get: __accessProp.bind(mod, key),
26
- enumerable: true
27
- });
22
+ if (mod && typeof mod === "object" || typeof mod === "function") {
23
+ for (let key of __getOwnPropNames(mod))
24
+ if (!__hasOwnProp.call(to, key))
25
+ __defProp(to, key, {
26
+ get: __accessProp.bind(mod, key),
27
+ enumerable: true
28
+ });
29
+ }
28
30
  if (canCache)
29
31
  cache.set(mod, to);
30
32
  return to;
@@ -144,7 +146,10 @@ var createPreviewFleet = (options) => {
144
146
  if (existing !== null) {
145
147
  port = existing.port;
146
148
  } else if (options.allocatePort !== undefined) {
147
- port = await options.allocatePort({ hostname, previewId: input.previewId });
149
+ port = await options.allocatePort({
150
+ hostname,
151
+ previewId: input.previewId
152
+ });
148
153
  } else {
149
154
  const used = new Set((await store.list()).map((record2) => record2.port));
150
155
  port = defaultAllocatePort(used, portRange);
@@ -219,10 +224,10 @@ var createPreviewFleet = (options) => {
219
224
  };
220
225
  };
221
226
  export {
222
- createPreviewFleet,
227
+ createFilePreviewStore,
223
228
  createMemoryPreviewStore,
224
- createFilePreviewStore
229
+ createPreviewFleet
225
230
  };
226
231
 
227
- //# debugId=1BF9EBCE13FAA19F64756E2164756E21
232
+ //# debugId=53B7E4B9FACC9F0C64756E2164756E21
228
233
  //# sourceMappingURL=preview.js.map
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/preview.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * Preview-deploys fleet for `@absolutejs/deploy`.\n *\n * A `PreviewFleet` is a tenant-aware orchestrator that creates,\n * lists, and tears down ephemeral environments — one per PR /\n * branch / commit. It composes the existing `Deployer` (release\n * dirs + atomic symlink swap + rollback) with a `DnsProvider` and a\n * persistent registry so a deploy bot can:\n *\n * const url = await fleet.create({ previewId: 'pr-42', ... });\n *\n * await fleet.teardown('pr-42');\n *\n * await fleet.gc({ olderThanMs: 7 * 24 * 60 * 60 * 1000 });\n *\n * Substrate responsibilities:\n *\n * - allocate a free port from a configurable pool\n * - build the hostname `<previewId>.<baseDomain>`\n * - upsert an A record for that hostname (DNS provider injected)\n * - call a caller-supplied `makeDeployer({ previewId, port,\n * hostname })` factory, then run `deployer.deploy()` so the\n * preview lands as a normal release on disk\n * - persist the preview registry so we can list / GC later\n * - on teardown, run a caller-supplied stop callback, remove the\n * DNS record, drop the registry entry\n *\n * Everything tenant-specific (secrets snapshotting, db seeding,\n * stopping the process) is a caller-supplied hook. The fleet owns\n * fleet bookkeeping, not application logic.\n */\n\nimport {\n\texistsSync,\n\tmkdirSync,\n\treadFileSync,\n\trenameSync,\n\twriteFileSync\n} from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type {\n\tDeployer,\n\tDeployResult,\n\tReleaseAnnotations\n} from './deployer';\nimport type { DnsProvider, DnsRecord, DnsRecordSpec } from './dns';\n\n// =============================================================================\n// Registry shape\n// =============================================================================\n\nexport type PreviewRecord = {\n\tpreviewId: string;\n\thostname: string;\n\turl: string;\n\tport: number;\n\tdnsRecordId?: string;\n\treleaseId: string;\n\tcommitSha?: string;\n\tcreatedAt: number;\n\tannotations?: ReleaseAnnotations;\n};\n\nexport type PreviewStore = {\n\tlist: () => Promise<PreviewRecord[]>;\n\tget: (previewId: string) => Promise<PreviewRecord | null>;\n\tput: (record: PreviewRecord) => Promise<void>;\n\tremove: (previewId: string) => Promise<void>;\n};\n\n// =============================================================================\n// Hooks + options\n// =============================================================================\n\nexport type PreviewDeployerContext = {\n\tpreviewId: string;\n\tport: number;\n\thostname: string;\n\turl: string;\n};\n\nexport type PreviewFleetOptions = {\n\t/**\n\t * Apex used to build preview hostnames: `<previewId>.<baseDomain>`.\n\t * `previewId` is slugified before use (alphanumeric + `-`).\n\t */\n\tbaseDomain: string;\n\t/**\n\t * Optional URL scheme. Defaults to `'https'`. Set `'http'` for\n\t * local-loop previews behind a localhost proxy.\n\t */\n\tscheme?: 'http' | 'https';\n\t/**\n\t * DNS provider — `cloudflareProvider`, `route53Provider`, etc.\n\t * Optional: when absent, `fleet.create` skips DNS work and the\n\t * caller is responsible for routing requests at the hostname.\n\t */\n\tdns?: DnsProvider;\n\t/**\n\t * Public IPv4 the A record should point at. Required when `dns`\n\t * is set. The fleet calls `dns.upsert({ name, type: 'A',\n\t * content: ipv4 })`.\n\t */\n\tipv4?: string;\n\t/**\n\t * TTL applied to created A records. Default 60s — previews come\n\t * and go and we want low cache lifetime.\n\t */\n\tdnsTtl?: number;\n\t/**\n\t * Proxied flag (Cloudflare orange-cloud). Default `false` — most\n\t * previews want a real IP, not a Cloudflare proxy.\n\t */\n\tdnsProxied?: boolean;\n\t/**\n\t * Port range that the fleet allocates from. Default `[3100, 3899]`\n\t * (3000 squat is documented in memory).\n\t */\n\tportRange?: { start: number; end: number };\n\t/** Override port allocation entirely (e.g. talk to a port-leaser). */\n\tallocatePort?: (record: {\n\t\tpreviewId: string;\n\t\thostname: string;\n\t}) => Promise<number>;\n\t/**\n\t * REQUIRED. Build a `Deployer` for an individual preview. The\n\t * factory receives the resolved id, port, hostname, and URL —\n\t * use them to set the right env, processManager, and target.\n\t */\n\tmakeDeployer: (\n\t\tctx: PreviewDeployerContext\n\t) => Deployer | Promise<Deployer>;\n\t/**\n\t * Stop callback. Called by `teardown` BEFORE DNS removal so the\n\t * preview process stops accepting connections before the record\n\t * disappears. Use it to call `processManager.stop()`, kill the\n\t * port, etc.\n\t */\n\tstop?: (record: PreviewRecord) => Promise<void> | void;\n\t/**\n\t * After-teardown callback. Called after DNS + registry removal —\n\t * good place to delete the release directory, drop a tenant\n\t * schema, clear secrets, etc.\n\t */\n\tafterTeardown?: (record: PreviewRecord) => Promise<void> | void;\n\t/** Registry. Default = filesystem store at `<root>`. */\n\tstore?: PreviewStore;\n\t/** Directory the file-based default store writes into. */\n\tregistryRoot?: string;\n\t/** Override `Date.now()` for tests. */\n\tclock?: () => number;\n};\n\n// =============================================================================\n// File-based PreviewStore (default)\n// =============================================================================\n\n/**\n * Single-file JSON registry. Reads + writes atomically (temp-file\n * + rename). Adequate for a deploy bot on one host — swap in a\n * Postgres-backed store for distributed deploy bots.\n */\nexport const createFilePreviewStore = (root: string): PreviewStore => {\n\tconst path = join(root, 'previews.json');\n\n\tconst readAll = (): PreviewRecord[] => {\n\t\tif (!existsSync(path)) return [];\n\t\ttry {\n\t\t\tconst raw = readFileSync(path, 'utf8');\n\t\t\tif (raw.trim() === '') return [];\n\t\t\tconst parsed = JSON.parse(raw) as { previews?: PreviewRecord[] };\n\t\t\treturn Array.isArray(parsed.previews) ? parsed.previews : [];\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t};\n\n\tconst writeAll = (records: PreviewRecord[]): void => {\n\t\tmkdirSync(dirname(path), { recursive: true });\n\t\tconst tmp = `${path}.tmp-${process.pid}-${Date.now()}`;\n\t\twriteFileSync(tmp, JSON.stringify({ previews: records }, null, 2));\n\t\trenameSync(tmp, path);\n\t};\n\n\treturn {\n\t\tget: async (previewId) =>\n\t\t\treadAll().find((r) => r.previewId === previewId) ?? null,\n\t\tlist: async () => readAll(),\n\t\tput: async (record) => {\n\t\t\tconst records = readAll().filter(\n\t\t\t\t(r) => r.previewId !== record.previewId\n\t\t\t);\n\t\t\trecords.push(record);\n\t\t\twriteAll(records);\n\t\t},\n\t\tremove: async (previewId) => {\n\t\t\tconst records = readAll().filter((r) => r.previewId !== previewId);\n\t\t\twriteAll(records);\n\t\t}\n\t};\n};\n\n// =============================================================================\n// In-memory store (for tests + ephemeral fleets)\n// =============================================================================\n\nexport const createMemoryPreviewStore = (): PreviewStore => {\n\tconst map = new Map<string, PreviewRecord>();\n\treturn {\n\t\tget: async (previewId) => map.get(previewId) ?? null,\n\t\tlist: async () => Array.from(map.values()),\n\t\tput: async (record) => {\n\t\t\tmap.set(record.previewId, record);\n\t\t},\n\t\tremove: async (previewId) => {\n\t\t\tmap.delete(previewId);\n\t\t}\n\t};\n};\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nconst slugify = (id: string): string =>\n\tid\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9-]+/g, '-')\n\t\t.replace(/^-+|-+$/g, '')\n\t\t.slice(0, 50);\n\nconst defaultAllocatePort = (\n\tused: Set<number>,\n\trange: { start: number; end: number }\n): number => {\n\tfor (let port = range.start; port <= range.end; port += 1) {\n\t\tif (!used.has(port)) return port;\n\t}\n\tthrow new Error(\n\t\t`preview-fleet: no free ports in [${range.start}, ${range.end}] (${used.size} in use)`\n\t);\n};\n\n// =============================================================================\n// Fleet\n// =============================================================================\n\nexport type CreatePreviewInput = {\n\tpreviewId: string;\n\tcommitSha?: string;\n\tannotations?: ReleaseAnnotations;\n\t/**\n\t * Override hostname. Default = `<slug(previewId)>.<baseDomain>`.\n\t * Use this for previews with a vanity name that shouldn't echo\n\t * the PR id directly.\n\t */\n\thostname?: string;\n};\n\nexport type CreatePreviewResult = {\n\trecord: PreviewRecord;\n\tdeploy: DeployResult;\n};\n\nexport type PreviewFleet = {\n\t/**\n\t * Spin up a preview. Idempotent on `previewId` — if a record\n\t * already exists, the fleet re-uses its port + DNS and runs a\n\t * fresh `deployer.deploy()` (so PRs that push new commits roll\n\t * forward).\n\t */\n\tcreate: (input: CreatePreviewInput) => Promise<CreatePreviewResult>;\n\t/** Tear down a single preview (stop → DNS remove → registry remove → afterTeardown). */\n\tteardown: (previewId: string) => Promise<void>;\n\t/** List active previews. */\n\tlist: () => Promise<PreviewRecord[]>;\n\t/** Get one preview by id. */\n\tget: (previewId: string) => Promise<PreviewRecord | null>;\n\t/**\n\t * Tear down all previews older than `olderThanMs`. Returns the\n\t * list of preview ids torn down. Failures on individual previews\n\t * are swallowed and reported on `errors`.\n\t */\n\tgc: (options: { olderThanMs: number }) => Promise<{\n\t\tremoved: string[];\n\t\terrors: { previewId: string; error: Error }[];\n\t}>;\n};\n\nexport const createPreviewFleet = (\n\toptions: PreviewFleetOptions\n): PreviewFleet => {\n\tconst scheme = options.scheme ?? 'https';\n\tconst portRange = options.portRange ?? { end: 3899, start: 3100 };\n\tconst dnsTtl = options.dnsTtl ?? 60;\n\tconst dnsProxied = options.dnsProxied ?? false;\n\tconst clock = options.clock ?? Date.now;\n\tconst store =\n\t\toptions.store ??\n\t\tcreateFilePreviewStore(\n\t\t\toptions.registryRoot ?? join(process.cwd(), '.preview-fleet')\n\t\t);\n\n\tif (options.dns !== undefined && options.ipv4 === undefined) {\n\t\tthrow new Error(\n\t\t\t'preview-fleet: `ipv4` is required when `dns` is configured'\n\t\t);\n\t}\n\n\tconst ensureDns = async (\n\t\thostname: string\n\t): Promise<DnsRecord | undefined> => {\n\t\tif (options.dns === undefined) return undefined;\n\t\tconst spec: DnsRecordSpec = {\n\t\t\tcontent: options.ipv4!,\n\t\t\tname: hostname,\n\t\t\tproxied: dnsProxied,\n\t\t\tttl: dnsTtl,\n\t\t\ttype: 'A'\n\t\t};\n\t\treturn await options.dns.upsert(spec);\n\t};\n\n\tconst removeDns = async (record: PreviewRecord): Promise<void> => {\n\t\tif (options.dns === undefined || record.dnsRecordId === undefined) {\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tawait options.dns.delete(record.dnsRecordId);\n\t\t} catch {\n\t\t\t// Idempotent teardown — the record may already be gone. Don't\n\t\t\t// block the rest of teardown on a stale id.\n\t\t}\n\t};\n\n\tconst buildHostname = (previewId: string, override?: string): string => {\n\t\tif (override !== undefined) return override;\n\t\tconst slug = slugify(previewId);\n\t\tif (slug === '') {\n\t\t\tthrow new Error(\n\t\t\t\t`preview-fleet: previewId ${JSON.stringify(previewId)} slugifies to empty`\n\t\t\t);\n\t\t}\n\t\treturn `${slug}.${options.baseDomain}`;\n\t};\n\n\tconst create = async (\n\t\tinput: CreatePreviewInput\n\t): Promise<CreatePreviewResult> => {\n\t\tconst existing = await store.get(input.previewId);\n\t\tconst hostname = buildHostname(input.previewId, input.hostname);\n\t\tconst url = `${scheme}://${hostname}`;\n\n\t\t// Allocate a port — reuse existing if we're re-deploying.\n\t\tlet port: number;\n\t\tif (existing !== null) {\n\t\t\tport = existing.port;\n\t\t} else if (options.allocatePort !== undefined) {\n\t\t\tport = await options.allocatePort({ hostname, previewId: input.previewId });\n\t\t} else {\n\t\t\tconst used = new Set(\n\t\t\t\t(await store.list()).map((record) => record.port)\n\t\t\t);\n\t\t\tport = defaultAllocatePort(used, portRange);\n\t\t}\n\n\t\tconst deployer = await options.makeDeployer({\n\t\t\thostname,\n\t\t\tport,\n\t\t\tpreviewId: input.previewId,\n\t\t\turl\n\t\t});\n\n\t\tconst deployOptions =\n\t\t\tinput.annotations !== undefined\n\t\t\t\t? { annotations: input.annotations }\n\t\t\t\t: input.commitSha !== undefined\n\t\t\t\t\t? { annotations: { commitSha: input.commitSha } }\n\t\t\t\t\t: undefined;\n\t\tconst deployResult = await deployer.deploy(deployOptions);\n\n\t\t// DNS only after the deploy succeeded — no point flipping the\n\t\t// record at a half-baked release.\n\t\tconst dnsRecord = await ensureDns(hostname);\n\n\t\tconst record: PreviewRecord = {\n\t\t\tcreatedAt: existing?.createdAt ?? clock(),\n\t\t\thostname,\n\t\t\tport,\n\t\t\tpreviewId: input.previewId,\n\t\t\treleaseId: deployResult.releaseId,\n\t\t\turl,\n\t\t\t...(dnsRecord !== undefined ? { dnsRecordId: dnsRecord.id } : {}),\n\t\t\t...(input.commitSha !== undefined ? { commitSha: input.commitSha } : {}),\n\t\t\t...(input.annotations !== undefined\n\t\t\t\t? { annotations: input.annotations }\n\t\t\t\t: {})\n\t\t};\n\n\t\tawait store.put(record);\n\t\treturn { deploy: deployResult, record };\n\t};\n\n\tconst teardown = async (previewId: string): Promise<void> => {\n\t\tconst record = await store.get(previewId);\n\t\tif (record === null) return;\n\n\t\tif (options.stop !== undefined) {\n\t\t\ttry {\n\t\t\t\tawait options.stop(record);\n\t\t\t} catch {\n\t\t\t\t// Don't block DNS removal on a stop failure. The caller\n\t\t\t\t// can see the error via afterTeardown by re-querying.\n\t\t\t}\n\t\t}\n\n\t\tawait removeDns(record);\n\t\tawait store.remove(previewId);\n\n\t\tif (options.afterTeardown !== undefined) {\n\t\t\ttry {\n\t\t\t\tawait options.afterTeardown(record);\n\t\t\t} catch {\n\t\t\t\t// Caller's own teardown errors are their problem; the\n\t\t\t\t// substrate has already removed the record + DNS.\n\t\t\t}\n\t\t}\n\t};\n\n\tconst gc = async ({\n\t\tolderThanMs\n\t}: {\n\t\tolderThanMs: number;\n\t}): Promise<{\n\t\tremoved: string[];\n\t\terrors: { previewId: string; error: Error }[];\n\t}> => {\n\t\tconst cutoff = clock() - olderThanMs;\n\t\tconst all = await store.list();\n\t\tconst expired = all.filter((record) => record.createdAt < cutoff);\n\t\tconst removed: string[] = [];\n\t\tconst errors: { previewId: string; error: Error }[] = [];\n\t\tfor (const record of expired) {\n\t\t\ttry {\n\t\t\t\tawait teardown(record.previewId);\n\t\t\t\tremoved.push(record.previewId);\n\t\t\t} catch (e) {\n\t\t\t\terrors.push({\n\t\t\t\t\terror: e instanceof Error ? e : new Error(String(e)),\n\t\t\t\t\tpreviewId: record.previewId\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn { errors, removed };\n\t};\n\n\treturn {\n\t\tcreate,\n\t\tgc,\n\t\tget: (previewId) => store.get(previewId),\n\t\tlist: () => store.list(),\n\t\tteardown\n\t};\n};\n"
5
+ "/**\n * Preview-deploys fleet for `@absolutejs/deploy`.\n *\n * A `PreviewFleet` is a tenant-aware orchestrator that creates,\n * lists, and tears down ephemeral environments — one per PR /\n * branch / commit. It composes the existing `Deployer` (release\n * dirs + atomic symlink swap + rollback) with a `DnsProvider` and a\n * persistent registry so a deploy bot can:\n *\n * const url = await fleet.create({ previewId: 'pr-42', ... });\n *\n * await fleet.teardown('pr-42');\n *\n * await fleet.gc({ olderThanMs: 7 * 24 * 60 * 60 * 1000 });\n *\n * Substrate responsibilities:\n *\n * - allocate a free port from a configurable pool\n * - build the hostname `<previewId>.<baseDomain>`\n * - upsert an A record for that hostname (DNS provider injected)\n * - call a caller-supplied `makeDeployer({ previewId, port,\n * hostname })` factory, then run `deployer.deploy()` so the\n * preview lands as a normal release on disk\n * - persist the preview registry so we can list / GC later\n * - on teardown, run a caller-supplied stop callback, remove the\n * DNS record, drop the registry entry\n *\n * Everything tenant-specific (secrets snapshotting, db seeding,\n * stopping the process) is a caller-supplied hook. The fleet owns\n * fleet bookkeeping, not application logic.\n */\n\nimport {\n existsSync,\n mkdirSync,\n readFileSync,\n renameSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type { Deployer, DeployResult, ReleaseAnnotations } from \"./deployer\";\nimport type { DnsProvider, DnsRecord, DnsRecordSpec } from \"./dns\";\n\n// =============================================================================\n// Registry shape\n// =============================================================================\n\nexport type PreviewRecord = {\n previewId: string;\n hostname: string;\n url: string;\n port: number;\n dnsRecordId?: string;\n releaseId: string;\n commitSha?: string;\n createdAt: number;\n annotations?: ReleaseAnnotations;\n};\n\nexport type PreviewStore = {\n list: () => Promise<PreviewRecord[]>;\n get: (previewId: string) => Promise<PreviewRecord | null>;\n put: (record: PreviewRecord) => Promise<void>;\n remove: (previewId: string) => Promise<void>;\n};\n\n// =============================================================================\n// Hooks + options\n// =============================================================================\n\nexport type PreviewDeployerContext = {\n previewId: string;\n port: number;\n hostname: string;\n url: string;\n};\n\nexport type PreviewFleetOptions = {\n /**\n * Apex used to build preview hostnames: `<previewId>.<baseDomain>`.\n * `previewId` is slugified before use (alphanumeric + `-`).\n */\n baseDomain: string;\n /**\n * Optional URL scheme. Defaults to `'https'`. Set `'http'` for\n * local-loop previews behind a localhost proxy.\n */\n scheme?: \"http\" | \"https\";\n /**\n * DNS provider — `cloudflareProvider`, `route53Provider`, etc.\n * Optional: when absent, `fleet.create` skips DNS work and the\n * caller is responsible for routing requests at the hostname.\n */\n dns?: DnsProvider;\n /**\n * Public IPv4 the A record should point at. Required when `dns`\n * is set. The fleet calls `dns.upsert({ name, type: 'A',\n * content: ipv4 })`.\n */\n ipv4?: string;\n /**\n * TTL applied to created A records. Default 60s — previews come\n * and go and we want low cache lifetime.\n */\n dnsTtl?: number;\n /**\n * Proxied flag (Cloudflare orange-cloud). Default `false` — most\n * previews want a real IP, not a Cloudflare proxy.\n */\n dnsProxied?: boolean;\n /**\n * Port range that the fleet allocates from. Default `[3100, 3899]`\n * (3000 squat is documented in memory).\n */\n portRange?: { start: number; end: number };\n /** Override port allocation entirely (e.g. talk to a port-leaser). */\n allocatePort?: (record: {\n previewId: string;\n hostname: string;\n }) => Promise<number>;\n /**\n * REQUIRED. Build a `Deployer` for an individual preview. The\n * factory receives the resolved id, port, hostname, and URL —\n * use them to set the right env, processManager, and target.\n */\n makeDeployer: (ctx: PreviewDeployerContext) => Deployer | Promise<Deployer>;\n /**\n * Stop callback. Called by `teardown` BEFORE DNS removal so the\n * preview process stops accepting connections before the record\n * disappears. Use it to call `processManager.stop()`, kill the\n * port, etc.\n */\n stop?: (record: PreviewRecord) => Promise<void> | void;\n /**\n * After-teardown callback. Called after DNS + registry removal —\n * good place to delete the release directory, drop a tenant\n * schema, clear secrets, etc.\n */\n afterTeardown?: (record: PreviewRecord) => Promise<void> | void;\n /** Registry. Default = filesystem store at `<root>`. */\n store?: PreviewStore;\n /** Directory the file-based default store writes into. */\n registryRoot?: string;\n /** Override `Date.now()` for tests. */\n clock?: () => number;\n};\n\n// =============================================================================\n// File-based PreviewStore (default)\n// =============================================================================\n\n/**\n * Single-file JSON registry. Reads + writes atomically (temp-file\n * + rename). Adequate for a deploy bot on one host — swap in a\n * Postgres-backed store for distributed deploy bots.\n */\nexport const createFilePreviewStore = (root: string): PreviewStore => {\n const path = join(root, \"previews.json\");\n\n const readAll = (): PreviewRecord[] => {\n if (!existsSync(path)) return [];\n try {\n const raw = readFileSync(path, \"utf8\");\n if (raw.trim() === \"\") return [];\n const parsed = JSON.parse(raw) as { previews?: PreviewRecord[] };\n return Array.isArray(parsed.previews) ? parsed.previews : [];\n } catch {\n return [];\n }\n };\n\n const writeAll = (records: PreviewRecord[]): void => {\n mkdirSync(dirname(path), { recursive: true });\n const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;\n writeFileSync(tmp, JSON.stringify({ previews: records }, null, 2));\n renameSync(tmp, path);\n };\n\n return {\n get: async (previewId) =>\n readAll().find((r) => r.previewId === previewId) ?? null,\n list: async () => readAll(),\n put: async (record) => {\n const records = readAll().filter((r) => r.previewId !== record.previewId);\n records.push(record);\n writeAll(records);\n },\n remove: async (previewId) => {\n const records = readAll().filter((r) => r.previewId !== previewId);\n writeAll(records);\n },\n };\n};\n\n// =============================================================================\n// In-memory store (for tests + ephemeral fleets)\n// =============================================================================\n\nexport const createMemoryPreviewStore = (): PreviewStore => {\n const map = new Map<string, PreviewRecord>();\n return {\n get: async (previewId) => map.get(previewId) ?? null,\n list: async () => Array.from(map.values()),\n put: async (record) => {\n map.set(record.previewId, record);\n },\n remove: async (previewId) => {\n map.delete(previewId);\n },\n };\n};\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nconst slugify = (id: string): string =>\n id\n .toLowerCase()\n .replace(/[^a-z0-9-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 50);\n\nconst defaultAllocatePort = (\n used: Set<number>,\n range: { start: number; end: number },\n): number => {\n for (let port = range.start; port <= range.end; port += 1) {\n if (!used.has(port)) return port;\n }\n throw new Error(\n `preview-fleet: no free ports in [${range.start}, ${range.end}] (${used.size} in use)`,\n );\n};\n\n// =============================================================================\n// Fleet\n// =============================================================================\n\nexport type CreatePreviewInput = {\n previewId: string;\n commitSha?: string;\n annotations?: ReleaseAnnotations;\n /**\n * Override hostname. Default = `<slug(previewId)>.<baseDomain>`.\n * Use this for previews with a vanity name that shouldn't echo\n * the PR id directly.\n */\n hostname?: string;\n};\n\nexport type CreatePreviewResult = {\n record: PreviewRecord;\n deploy: DeployResult;\n};\n\nexport type PreviewFleet = {\n /**\n * Spin up a preview. Idempotent on `previewId` — if a record\n * already exists, the fleet re-uses its port + DNS and runs a\n * fresh `deployer.deploy()` (so PRs that push new commits roll\n * forward).\n */\n create: (input: CreatePreviewInput) => Promise<CreatePreviewResult>;\n /** Tear down a single preview (stop → DNS remove → registry remove → afterTeardown). */\n teardown: (previewId: string) => Promise<void>;\n /** List active previews. */\n list: () => Promise<PreviewRecord[]>;\n /** Get one preview by id. */\n get: (previewId: string) => Promise<PreviewRecord | null>;\n /**\n * Tear down all previews older than `olderThanMs`. Returns the\n * list of preview ids torn down. Failures on individual previews\n * are swallowed and reported on `errors`.\n */\n gc: (options: { olderThanMs: number }) => Promise<{\n removed: string[];\n errors: { previewId: string; error: Error }[];\n }>;\n};\n\nexport const createPreviewFleet = (\n options: PreviewFleetOptions,\n): PreviewFleet => {\n const scheme = options.scheme ?? \"https\";\n const portRange = options.portRange ?? { end: 3899, start: 3100 };\n const dnsTtl = options.dnsTtl ?? 60;\n const dnsProxied = options.dnsProxied ?? false;\n const clock = options.clock ?? Date.now;\n const store =\n options.store ??\n createFilePreviewStore(\n options.registryRoot ?? join(process.cwd(), \".preview-fleet\"),\n );\n\n if (options.dns !== undefined && options.ipv4 === undefined) {\n throw new Error(\n \"preview-fleet: `ipv4` is required when `dns` is configured\",\n );\n }\n\n const ensureDns = async (\n hostname: string,\n ): Promise<DnsRecord | undefined> => {\n if (options.dns === undefined) return undefined;\n const spec: DnsRecordSpec = {\n content: options.ipv4!,\n name: hostname,\n proxied: dnsProxied,\n ttl: dnsTtl,\n type: \"A\",\n };\n return await options.dns.upsert(spec);\n };\n\n const removeDns = async (record: PreviewRecord): Promise<void> => {\n if (options.dns === undefined || record.dnsRecordId === undefined) {\n return;\n }\n try {\n await options.dns.delete(record.dnsRecordId);\n } catch {\n // Idempotent teardown — the record may already be gone. Don't\n // block the rest of teardown on a stale id.\n }\n };\n\n const buildHostname = (previewId: string, override?: string): string => {\n if (override !== undefined) return override;\n const slug = slugify(previewId);\n if (slug === \"\") {\n throw new Error(\n `preview-fleet: previewId ${JSON.stringify(previewId)} slugifies to empty`,\n );\n }\n return `${slug}.${options.baseDomain}`;\n };\n\n const create = async (\n input: CreatePreviewInput,\n ): Promise<CreatePreviewResult> => {\n const existing = await store.get(input.previewId);\n const hostname = buildHostname(input.previewId, input.hostname);\n const url = `${scheme}://${hostname}`;\n\n // Allocate a port — reuse existing if we're re-deploying.\n let port: number;\n if (existing !== null) {\n port = existing.port;\n } else if (options.allocatePort !== undefined) {\n port = await options.allocatePort({\n hostname,\n previewId: input.previewId,\n });\n } else {\n const used = new Set((await store.list()).map((record) => record.port));\n port = defaultAllocatePort(used, portRange);\n }\n\n const deployer = await options.makeDeployer({\n hostname,\n port,\n previewId: input.previewId,\n url,\n });\n\n const deployOptions =\n input.annotations !== undefined\n ? { annotations: input.annotations }\n : input.commitSha !== undefined\n ? { annotations: { commitSha: input.commitSha } }\n : undefined;\n const deployResult = await deployer.deploy(deployOptions);\n\n // DNS only after the deploy succeeded — no point flipping the\n // record at a half-baked release.\n const dnsRecord = await ensureDns(hostname);\n\n const record: PreviewRecord = {\n createdAt: existing?.createdAt ?? clock(),\n hostname,\n port,\n previewId: input.previewId,\n releaseId: deployResult.releaseId,\n url,\n ...(dnsRecord !== undefined ? { dnsRecordId: dnsRecord.id } : {}),\n ...(input.commitSha !== undefined ? { commitSha: input.commitSha } : {}),\n ...(input.annotations !== undefined\n ? { annotations: input.annotations }\n : {}),\n };\n\n await store.put(record);\n return { deploy: deployResult, record };\n };\n\n const teardown = async (previewId: string): Promise<void> => {\n const record = await store.get(previewId);\n if (record === null) return;\n\n if (options.stop !== undefined) {\n try {\n await options.stop(record);\n } catch {\n // Don't block DNS removal on a stop failure. The caller\n // can see the error via afterTeardown by re-querying.\n }\n }\n\n await removeDns(record);\n await store.remove(previewId);\n\n if (options.afterTeardown !== undefined) {\n try {\n await options.afterTeardown(record);\n } catch {\n // Caller's own teardown errors are their problem; the\n // substrate has already removed the record + DNS.\n }\n }\n };\n\n const gc = async ({\n olderThanMs,\n }: {\n olderThanMs: number;\n }): Promise<{\n removed: string[];\n errors: { previewId: string; error: Error }[];\n }> => {\n const cutoff = clock() - olderThanMs;\n const all = await store.list();\n const expired = all.filter((record) => record.createdAt < cutoff);\n const removed: string[] = [];\n const errors: { previewId: string; error: Error }[] = [];\n for (const record of expired) {\n try {\n await teardown(record.previewId);\n removed.push(record.previewId);\n } catch (e) {\n errors.push({\n error: e instanceof Error ? e : new Error(String(e)),\n previewId: record.previewId,\n });\n }\n }\n return { errors, removed };\n };\n\n return {\n create,\n gc,\n get: (previewId) => store.get(previewId),\n list: () => store.list(),\n teardown,\n };\n};\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "1BF9EBCE13FAA19F64756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "53B7E4B9FACC9F0C64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -8,7 +8,7 @@
8
8
  * `reload` / `status` against a `Target` works. PM2, supervisord, runit,
9
9
  * @absolutejs/runtime all fit if someone writes the adapter.
10
10
  */
11
- import type { Target } from './targets';
11
+ import type { Target } from "./targets";
12
12
  export type ProcessManagerContext = {
13
13
  /** Absolute path on the target to the active release dir (the symlink target). */
14
14
  currentPath: string;
@@ -21,7 +21,7 @@ export type ProcessManagerContext = {
21
21
  /** Optional env to set on the process. */
22
22
  env: Record<string, string>;
23
23
  /** Log sink for any commands the manager runs. */
24
- onLog?: (line: string, stream: 'stdout' | 'stderr') => void;
24
+ onLog?: (line: string, stream: "stdout" | "stderr") => void;
25
25
  };
26
26
  export type ProcessManager = {
27
27
  /** Bring the new release up. Called after the `current` symlink has been swapped. */
@@ -29,7 +29,7 @@ export type ProcessManager = {
29
29
  /** Stop the running process. */
30
30
  stop?: (target: Target, ctx: ProcessManagerContext) => Promise<void>;
31
31
  /** Return current status (best-effort; used by callers for diagnostics). */
32
- status?: (target: Target, ctx: ProcessManagerContext) => Promise<'running' | 'stopped' | 'unknown'>;
32
+ status?: (target: Target, ctx: ProcessManagerContext) => Promise<"running" | "stopped" | "unknown">;
33
33
  };
34
34
  export type BareManagerOptions = {
35
35
  /** Command to run. Default `bun run start`. */
@@ -48,7 +48,7 @@ export type SystemdManagerOptions = {
48
48
  /** Group. Default the deploy user. */
49
49
  group?: string;
50
50
  /** Restart policy. Default `always`. */
51
- restart?: 'always' | 'on-failure' | 'no';
51
+ restart?: "always" | "on-failure" | "no";
52
52
  /** systemctl path. Default `systemctl`. */
53
53
  systemctl?: string;
54
54
  /** Unit file directory. Default `/etc/systemd/system`. */
@@ -19,12 +19,14 @@ var __toESM = (mod, isNodeMode, target) => {
19
19
  }
20
20
  target = mod != null ? __create(__getProtoOf(mod)) : {};
21
21
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
22
- for (let key of __getOwnPropNames(mod))
23
- if (!__hasOwnProp.call(to, key))
24
- __defProp(to, key, {
25
- get: __accessProp.bind(mod, key),
26
- enumerable: true
27
- });
22
+ if (mod && typeof mod === "object" || typeof mod === "function") {
23
+ for (let key of __getOwnPropNames(mod))
24
+ if (!__hasOwnProp.call(to, key))
25
+ __defProp(to, key, {
26
+ get: __accessProp.bind(mod, key),
27
+ enumerable: true
28
+ });
29
+ }
28
30
  if (canCache)
29
31
  cache.set(mod, to);
30
32
  return to;
@@ -164,11 +166,11 @@ var extractReleaseArtifact = async (options) => {
164
166
  return { extracted: true };
165
167
  };
166
168
  export {
167
- receiveReleaseArtifact,
168
- extractReleaseArtifact,
169
+ ReleaseArtifactError,
169
170
  createReleaseArtifact,
170
- ReleaseArtifactError
171
+ extractReleaseArtifact,
172
+ receiveReleaseArtifact
171
173
  };
172
174
 
173
- //# debugId=8414E4F4B329037664756E2164756E21
175
+ //# debugId=A05087FD7A349EAA64756E2164756E21
174
176
  //# sourceMappingURL=releaseArtifact.js.map
@@ -4,7 +4,7 @@
4
4
  "sourcesContent": [
5
5
  "import { mkdir, mkdtemp, rm, stat } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\n\nconst DEFAULT_MAX_BYTES = 2_147_483_648;\nconst ERROR_DETAIL_LIMIT = 500;\nconst SAFE_RELEASE_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;\n\nexport type ReleaseArtifactMetadata = {\n bytes: number;\n releaseId: string;\n sha256: string;\n};\n\nexport type CreatedReleaseArtifact = {\n dispose: () => Promise<void>;\n file: Bun.BunFile;\n metadata: ReleaseArtifactMetadata;\n path: string;\n};\n\nexport class ReleaseArtifactError extends Error {}\n\nconst run = async (command: string[]) => {\n const process = Bun.spawn(command, { stderr: \"pipe\", stdout: \"pipe\" });\n const [exitCode, stderr, stdout] = await Promise.all([\n process.exited,\n new Response(process.stderr).text(),\n new Response(process.stdout).text(),\n ]);\n if (exitCode !== 0)\n throw new ReleaseArtifactError(\n `${command[0]} failed (${exitCode}): ${stderr.slice(0, ERROR_DETAIL_LIMIT)}`,\n );\n\n return stdout;\n};\n\nconst assertReleaseId = (value: string) => {\n if (!SAFE_RELEASE_ID.test(value))\n throw new ReleaseArtifactError(\"Release id is invalid\");\n\n return value;\n};\n\nconst assertExclude = (value: string) => {\n if (\n value.length === 0 ||\n value.startsWith(\"-\") ||\n value.startsWith(\"/\") ||\n value.split(\"/\").some((part) => part === \"..\") ||\n /[\\0\\r\\n]/.test(value)\n )\n throw new ReleaseArtifactError(`Invalid release exclusion: ${value}`);\n\n return value.replace(/^\\.\\//, \"\");\n};\n\nconst sha256File = async (file: Blob) => {\n const hasher = new Bun.CryptoHasher(\"sha256\");\n for await (const chunk of file.stream()) hasher.update(chunk);\n\n return hasher.digest(\"hex\");\n};\n\nexport const createReleaseArtifact = async (options: {\n exclude?: string[];\n releaseId?: string;\n sourceRoot: string;\n temporaryRoot?: string;\n}): Promise<CreatedReleaseArtifact> => {\n const releaseId = assertReleaseId(options.releaseId ?? crypto.randomUUID());\n const source = path.resolve(options.sourceRoot);\n const sourceStats = await stat(source).catch(() => null);\n if (!sourceStats?.isDirectory())\n throw new ReleaseArtifactError(\"Release source root is not a directory\");\n if (!(await Bun.file(path.join(source, \"package.json\")).exists()))\n throw new ReleaseArtifactError(\"Release source has no package.json\");\n const temporary = await mkdtemp(\n path.join(options.temporaryRoot ?? tmpdir(), \"absolutejs-release-\"),\n );\n const archivePath = path.join(temporary, `${releaseId}.tgz`);\n try {\n await run([\n \"tar\",\n \"-czf\",\n archivePath,\n ...(options.exclude ?? []).map(\n (value) => `--exclude=./${assertExclude(value)}`,\n ),\n \"-C\",\n source,\n \".\",\n ]);\n const file = Bun.file(archivePath);\n\n return {\n dispose: () => rm(temporary, { force: true, recursive: true }),\n file,\n metadata: {\n bytes: file.size,\n releaseId,\n sha256: await sha256File(file),\n },\n path: archivePath,\n };\n } catch (error) {\n await rm(temporary, { force: true, recursive: true });\n throw error;\n }\n};\n\nexport const receiveReleaseArtifact = async (options: {\n destination: string;\n expectedBytes: number;\n expectedSha256: string;\n maxBytes?: number;\n stream: ReadableStream<Uint8Array>;\n}) => {\n const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n if (\n !Number.isSafeInteger(options.expectedBytes) ||\n options.expectedBytes < 1 ||\n options.expectedBytes > maxBytes ||\n !/^[a-f0-9]{64}$/.test(options.expectedSha256)\n )\n throw new ReleaseArtifactError(\"Release artifact metadata is invalid\");\n await mkdir(path.dirname(options.destination), { recursive: true });\n const writer = Bun.file(options.destination).writer();\n const hasher = new Bun.CryptoHasher(\"sha256\");\n const reader = options.stream.getReader();\n let bytes = 0;\n try {\n while (true) {\n const { done, value: chunk } = await reader.read();\n if (done) break;\n bytes += chunk.byteLength;\n if (bytes > options.expectedBytes || bytes > maxBytes)\n throw new ReleaseArtifactError(\n \"Release artifact exceeds its declared size\",\n );\n hasher.update(chunk);\n writer.write(chunk);\n }\n } catch (error) {\n await rm(options.destination, { force: true });\n throw error;\n } finally {\n await writer.end();\n }\n if (\n bytes !== options.expectedBytes ||\n hasher.digest(\"hex\") !== options.expectedSha256\n ) {\n await rm(options.destination, { force: true });\n throw new ReleaseArtifactError(\n \"Release artifact integrity verification failed\",\n );\n }\n\n return { bytes, sha256: options.expectedSha256 };\n};\n\nexport const extractReleaseArtifact = async (options: {\n archivePath: string;\n destination: string;\n}) => {\n const [names, verbose] = await Promise.all([\n run([\"tar\", \"-tzf\", options.archivePath]),\n run([\"tar\", \"-tvzf\", options.archivePath]),\n ]);\n const unsafePath = names\n .split(\"\\n\")\n .filter(Boolean)\n .some(\n (entry) =>\n entry.startsWith(\"/\") || entry.split(\"/\").some((part) => part === \"..\"),\n );\n const unsafeType = verbose\n .split(\"\\n\")\n .filter(Boolean)\n .some((entry) => entry[0] !== \"-\" && entry[0] !== \"d\");\n if (unsafePath || unsafeType)\n throw new ReleaseArtifactError(\"Release artifact contains an unsafe entry\");\n await rm(options.destination, { force: true, recursive: true });\n await mkdir(options.destination, { recursive: true });\n await run([\n \"tar\",\n \"-xzf\",\n options.archivePath,\n \"--no-same-owner\",\n \"--no-same-permissions\",\n \"-C\",\n options.destination,\n ]);\n if (\n !(await Bun.file(path.join(options.destination, \"package.json\")).exists())\n )\n throw new ReleaseArtifactError(\"Release artifact has no package.json\");\n\n return { extracted: true } as const;\n};\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "8414E4F4B329037664756E2164756E21",
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AAEA,IAAM,oBAAoB;AAC1B,IAAM,qBAAqB;AAC3B,IAAM,kBAAkB;AAAA;AAejB,MAAM,6BAA6B,MAAM;AAAC;AAEjD,IAAM,MAAM,OAAO,YAAsB;AAAA,EACvC,MAAM,UAAU,IAAI,MAAM,SAAS,EAAE,QAAQ,QAAQ,QAAQ,OAAO,CAAC;AAAA,EACrE,OAAO,UAAU,QAAQ,UAAU,MAAM,QAAQ,IAAI;AAAA,IACnD,QAAQ;AAAA,IACR,IAAI,SAAS,QAAQ,MAAM,EAAE,KAAK;AAAA,IAClC,IAAI,SAAS,QAAQ,MAAM,EAAE,KAAK;AAAA,EACpC,CAAC;AAAA,EACD,IAAI,aAAa;AAAA,IACf,MAAM,IAAI,qBACR,GAAG,QAAQ,cAAc,cAAc,OAAO,MAAM,GAAG,kBAAkB,GAC3E;AAAA,EAEF,OAAO;AAAA;AAGT,IAAM,kBAAkB,CAAC,UAAkB;AAAA,EACzC,IAAI,CAAC,gBAAgB,KAAK,KAAK;AAAA,IAC7B,MAAM,IAAI,qBAAqB,uBAAuB;AAAA,EAExD,OAAO;AAAA;AAGT,IAAM,gBAAgB,CAAC,UAAkB;AAAA,EACvC,IACE,MAAM,WAAW,KACjB,MAAM,WAAW,GAAG,KACpB,MAAM,WAAW,GAAG,KACpB,MAAM,MAAM,GAAG,EAAE,KAAK,CAAC,SAAS,SAAS,IAAI,KAC7C,WAAW,KAAK,KAAK;AAAA,IAErB,MAAM,IAAI,qBAAqB,8BAA8B,OAAO;AAAA,EAEtE,OAAO,MAAM,QAAQ,SAAS,EAAE;AAAA;AAGlC,IAAM,aAAa,OAAO,SAAe;AAAA,EACvC,MAAM,SAAS,IAAI,IAAI,aAAa,QAAQ;AAAA,EAC5C,iBAAiB,SAAS,KAAK,OAAO;AAAA,IAAG,OAAO,OAAO,KAAK;AAAA,EAE5D,OAAO,OAAO,OAAO,KAAK;AAAA;AAGrB,IAAM,wBAAwB,OAAO,YAKL;AAAA,EACrC,MAAM,YAAY,gBAAgB,QAAQ,aAAa,OAAO,WAAW,CAAC;AAAA,EAC1E,MAAM,SAAS,KAAK,QAAQ,QAAQ,UAAU;AAAA,EAC9C,MAAM,cAAc,MAAM,KAAK,MAAM,EAAE,MAAM,MAAM,IAAI;AAAA,EACvD,IAAI,CAAC,aAAa,YAAY;AAAA,IAC5B,MAAM,IAAI,qBAAqB,wCAAwC;AAAA,EACzE,IAAI,CAAE,MAAM,IAAI,KAAK,KAAK,KAAK,QAAQ,cAAc,CAAC,EAAE,OAAO;AAAA,IAC7D,MAAM,IAAI,qBAAqB,oCAAoC;AAAA,EACrE,MAAM,YAAY,MAAM,QACtB,KAAK,KAAK,QAAQ,iBAAiB,OAAO,GAAG,qBAAqB,CACpE;AAAA,EACA,MAAM,cAAc,KAAK,KAAK,WAAW,GAAG,eAAe;AAAA,EAC3D,IAAI;AAAA,IACF,MAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA,IAAI,QAAQ,WAAW,CAAC,GAAG,IACzB,CAAC,UAAU,eAAe,cAAc,KAAK,GAC/C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IACD,MAAM,OAAO,IAAI,KAAK,WAAW;AAAA,IAEjC,OAAO;AAAA,MACL,SAAS,MAAM,GAAG,WAAW,EAAE,OAAO,MAAM,WAAW,KAAK,CAAC;AAAA,MAC7D;AAAA,MACA,UAAU;AAAA,QACR,OAAO,KAAK;AAAA,QACZ;AAAA,QACA,QAAQ,MAAM,WAAW,IAAI;AAAA,MAC/B;AAAA,MACA,MAAM;AAAA,IACR;AAAA,IACA,OAAO,OAAO;AAAA,IACd,MAAM,GAAG,WAAW,EAAE,OAAO,MAAM,WAAW,KAAK,CAAC;AAAA,IACpD,MAAM;AAAA;AAAA;AAIH,IAAM,yBAAyB,OAAO,YAMvC;AAAA,EACJ,MAAM,WAAW,QAAQ,YAAY;AAAA,EACrC,IACE,CAAC,OAAO,cAAc,QAAQ,aAAa,KAC3C,QAAQ,gBAAgB,KACxB,QAAQ,gBAAgB,YACxB,CAAC,iBAAiB,KAAK,QAAQ,cAAc;AAAA,IAE7C,MAAM,IAAI,qBAAqB,sCAAsC;AAAA,EACvE,MAAM,MAAM,KAAK,QAAQ,QAAQ,WAAW,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,EAClE,MAAM,SAAS,IAAI,KAAK,QAAQ,WAAW,EAAE,OAAO;AAAA,EACpD,MAAM,SAAS,IAAI,IAAI,aAAa,QAAQ;AAAA,EAC5C,MAAM,SAAS,QAAQ,OAAO,UAAU;AAAA,EACxC,IAAI,QAAQ;AAAA,EACZ,IAAI;AAAA,IACF,OAAO,MAAM;AAAA,MACX,QAAQ,MAAM,OAAO,UAAU,MAAM,OAAO,KAAK;AAAA,MACjD,IAAI;AAAA,QAAM;AAAA,MACV,SAAS,MAAM;AAAA,MACf,IAAI,QAAQ,QAAQ,iBAAiB,QAAQ;AAAA,QAC3C,MAAM,IAAI,qBACR,4CACF;AAAA,MACF,OAAO,OAAO,KAAK;AAAA,MACnB,OAAO,MAAM,KAAK;AAAA,IACpB;AAAA,IACA,OAAO,OAAO;AAAA,IACd,MAAM,GAAG,QAAQ,aAAa,EAAE,OAAO,KAAK,CAAC;AAAA,IAC7C,MAAM;AAAA,YACN;AAAA,IACA,MAAM,OAAO,IAAI;AAAA;AAAA,EAEnB,IACE,UAAU,QAAQ,iBAClB,OAAO,OAAO,KAAK,MAAM,QAAQ,gBACjC;AAAA,IACA,MAAM,GAAG,QAAQ,aAAa,EAAE,OAAO,KAAK,CAAC;AAAA,IAC7C,MAAM,IAAI,qBACR,gDACF;AAAA,EACF;AAAA,EAEA,OAAO,EAAE,OAAO,QAAQ,QAAQ,eAAe;AAAA;AAG1C,IAAM,yBAAyB,OAAO,YAGvC;AAAA,EACJ,OAAO,OAAO,WAAW,MAAM,QAAQ,IAAI;AAAA,IACzC,IAAI,CAAC,OAAO,QAAQ,QAAQ,WAAW,CAAC;AAAA,IACxC,IAAI,CAAC,OAAO,SAAS,QAAQ,WAAW,CAAC;AAAA,EAC3C,CAAC;AAAA,EACD,MAAM,aAAa,MAChB,MAAM;AAAA,CAAI,EACV,OAAO,OAAO,EACd,KACC,CAAC,UACC,MAAM,WAAW,GAAG,KAAK,MAAM,MAAM,GAAG,EAAE,KAAK,CAAC,SAAS,SAAS,IAAI,CAC1E;AAAA,EACF,MAAM,aAAa,QAChB,MAAM;AAAA,CAAI,EACV,OAAO,OAAO,EACd,KAAK,CAAC,UAAU,MAAM,OAAO,OAAO,MAAM,OAAO,GAAG;AAAA,EACvD,IAAI,cAAc;AAAA,IAChB,MAAM,IAAI,qBAAqB,2CAA2C;AAAA,EAC5E,MAAM,GAAG,QAAQ,aAAa,EAAE,OAAO,MAAM,WAAW,KAAK,CAAC;AAAA,EAC9D,MAAM,MAAM,QAAQ,aAAa,EAAE,WAAW,KAAK,CAAC;AAAA,EACpD,MAAM,IAAI;AAAA,IACR;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV,CAAC;AAAA,EACD,IACE,CAAE,MAAM,IAAI,KAAK,KAAK,KAAK,QAAQ,aAAa,cAAc,CAAC,EAAE,OAAO;AAAA,IAExE,MAAM,IAAI,qBAAqB,sCAAsC;AAAA,EAEvE,OAAO,EAAE,WAAW,KAAK;AAAA;",
8
+ "debugId": "A05087FD7A349EAA64756E2164756E21",
9
9
  "names": []
10
10
  }
package/dist/route53.d.ts CHANGED
@@ -13,7 +13,7 @@
13
13
  * of an `@aws-sdk/client-route-53` dependency. Wire your existing
14
14
  * AWS SDK client with a 4-line shim — see README.
15
15
  */
16
- import type { DnsProvider } from './dns';
16
+ import type { DnsProvider } from "./dns";
17
17
  export type Route53ResourceRecord = {
18
18
  Value: string;
19
19
  };
@@ -30,7 +30,7 @@ export type Route53ResourceRecordSet = {
30
30
  SetIdentifier?: string;
31
31
  };
32
32
  export type Route53Change = {
33
- Action: 'CREATE' | 'DELETE' | 'UPSERT';
33
+ Action: "CREATE" | "DELETE" | "UPSERT";
34
34
  ResourceRecordSet: Route53ResourceRecordSet;
35
35
  };
36
36
  export type Route53ListInput = {