@absolutejs/deploy 0.22.0 → 0.24.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.
@@ -12,8 +12,25 @@ export type AndroidNativeReleaseMetadata = {
12
12
  sha256: string;
13
13
  signed: boolean;
14
14
  type: "aab";
15
+ versionCode?: number;
15
16
  };
16
- export type NativeReleaseMetadata = AndroidNativeReleaseMetadata;
17
+ export type IosNativeReleaseMetadata = {
18
+ appBuild: string;
19
+ appId: string;
20
+ artifact: "App.ipa";
21
+ buildNumber?: number;
22
+ bytes: number;
23
+ engine: "capacitor";
24
+ format: 1;
25
+ marketingVersion: string;
26
+ platform: "ios";
27
+ releaseId: string;
28
+ runtime: string;
29
+ sha256: string;
30
+ signed: boolean;
31
+ type: "ipa";
32
+ };
33
+ export type NativeReleaseMetadata = AndroidNativeReleaseMetadata | IosNativeReleaseMetadata;
17
34
  export type NativeReleaseRecord = {
18
35
  artifactKey: string;
19
36
  format: typeof NATIVE_RELEASE_REGISTRY_FORMAT;
@@ -61,23 +61,49 @@ var parseMetadata = (value) => {
61
61
  throw new NativeReleaseRegistryError("Native release appId is invalid");
62
62
  if (!SHA256_PATTERN.test(sha256))
63
63
  throw new NativeReleaseRegistryError("Native release sha256 is invalid");
64
- if (releaseId !== `amobile_android_${sha256}`)
64
+ if (value.platform !== "android" && value.platform !== "ios")
65
+ throw new NativeReleaseRegistryError("Native release metadata is invalid");
66
+ if (releaseId !== `amobile_${value.platform}_${sha256}`)
65
67
  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)
68
+ const commonInvalid = value.engine !== "capacitor" || value.format !== 1 || typeof value.signed !== "boolean" || !Number.isSafeInteger(value.bytes) || Number(value.bytes) < 1;
69
+ if (commonInvalid)
70
+ throw new NativeReleaseRegistryError("Native release metadata is invalid");
71
+ if (value.platform === "android") {
72
+ if (value.artifact !== "app-release.aab" || value.type !== "aab" || value.versionCode !== undefined && (!Number.isSafeInteger(value.versionCode) || Number(value.versionCode) < 1 || Number(value.versionCode) > 2100000000))
73
+ throw new NativeReleaseRegistryError("Native release metadata is invalid");
74
+ return {
75
+ appBuild: requireString(value.appBuild, "appBuild"),
76
+ appId,
77
+ artifact: "app-release.aab",
78
+ bytes: Number(value.bytes),
79
+ engine: "capacitor",
80
+ format: 1,
81
+ platform: "android",
82
+ releaseId,
83
+ runtime: requireString(value.runtime, "runtime"),
84
+ sha256,
85
+ signed: value.signed === true,
86
+ type: "aab",
87
+ ...value.versionCode === undefined ? {} : { versionCode: Number(value.versionCode) }
88
+ };
89
+ }
90
+ 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
91
  throw new NativeReleaseRegistryError("Native release metadata is invalid");
68
92
  return {
69
93
  appBuild: requireString(value.appBuild, "appBuild"),
70
94
  appId,
71
- artifact: "app-release.aab",
95
+ artifact: "App.ipa",
96
+ ...value.buildNumber === undefined ? {} : { buildNumber: Number(value.buildNumber) },
72
97
  bytes: Number(value.bytes),
73
98
  engine: "capacitor",
74
99
  format: 1,
75
- platform: "android",
100
+ marketingVersion: value.marketingVersion,
101
+ platform: "ios",
76
102
  releaseId,
77
103
  runtime: requireString(value.runtime, "runtime"),
78
104
  sha256,
79
- signed: value.signed,
80
- type: "aab"
105
+ signed: value.signed === true,
106
+ type: "ipa"
81
107
  };
82
108
  };
83
109
  var normalizedPrefix = (value) => {
@@ -119,7 +145,7 @@ var parseRecord = (value) => {
119
145
  };
120
146
  };
121
147
  var parseChannel = (value) => {
122
- if (!isRecord(value) || value.format !== NATIVE_RELEASE_REGISTRY_FORMAT || value.platform !== "android" || !isIsoTimestamp(value.promotedAt))
148
+ if (!isRecord(value) || value.format !== NATIVE_RELEASE_REGISTRY_FORMAT || value.platform !== "android" && value.platform !== "ios" || !isIsoTimestamp(value.promotedAt))
123
149
  throw new NativeReleaseRegistryError("Native release channel is invalid");
124
150
  const appId = requireString(value.appId, "channel appId");
125
151
  const channel = requireChannel(requireString(value.channel, "channel"));
@@ -127,13 +153,13 @@ var parseChannel = (value) => {
127
153
  const releaseId = requireString(value.releaseId, "channel releaseId");
128
154
  if (!APP_ID_PATTERN.test(appId) || !SHA256_PATTERN.test(sha256))
129
155
  throw new NativeReleaseRegistryError("Native release channel is invalid");
130
- if (releaseId !== `amobile_android_${sha256}`)
156
+ if (releaseId !== `amobile_${value.platform}_${sha256}`)
131
157
  throw new NativeReleaseRegistryError("Native release channel identity does not match");
132
158
  return {
133
159
  appId,
134
160
  channel,
135
161
  format: NATIVE_RELEASE_REGISTRY_FORMAT,
136
- platform: "android",
162
+ platform: value.platform,
137
163
  promotedAt: value.promotedAt,
138
164
  releaseId,
139
165
  sha256
@@ -158,10 +184,10 @@ var createNativeReleaseRegistry = (options) => {
158
184
  const read = async (input) => {
159
185
  if (!APP_ID_PATTERN.test(input.appId))
160
186
  throw new NativeReleaseRegistryError("Native release appId is invalid");
161
- const digest = input.releaseId.replace(/^amobile_android_/, "");
162
- if (!SHA256_PATTERN.test(digest) || input.releaseId !== `amobile_android_${digest}`)
187
+ const digest = input.releaseId.replace(new RegExp(`^amobile_${input.platform}_`), "");
188
+ if (!SHA256_PATTERN.test(digest) || input.releaseId !== `amobile_${input.platform}_${digest}`)
163
189
  throw new NativeReleaseRegistryError("Native release id is invalid");
164
- const identity = {
190
+ const identity = input.platform === "android" ? {
165
191
  appBuild: "lookup",
166
192
  appId: input.appId,
167
193
  artifact: "app-release.aab",
@@ -174,6 +200,20 @@ var createNativeReleaseRegistry = (options) => {
174
200
  sha256: digest,
175
201
  signed: true,
176
202
  type: "aab"
203
+ } : {
204
+ appBuild: "lookup",
205
+ appId: input.appId,
206
+ artifact: "App.ipa",
207
+ bytes: 1,
208
+ engine: "capacitor",
209
+ format: 1,
210
+ marketingVersion: "1.0.0",
211
+ platform: "ios",
212
+ releaseId: input.releaseId,
213
+ runtime: "lookup",
214
+ sha256: digest,
215
+ signed: true,
216
+ type: "ipa"
177
217
  };
178
218
  const key = recordKey(identity);
179
219
  const bytes = await options.store.get(key);
@@ -339,5 +379,5 @@ export {
339
379
  NATIVE_RELEASE_REGISTRY_FORMAT
340
380
  };
341
381
 
342
- //# debugId=1FEEE1047DE9DB9664756E2164756E21
382
+ //# debugId=242BF8653CD0343D64756E2164756E21
343
383
  //# 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};\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 )\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 };\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": "1FEEE1047DE9DB9664756E2164756E21",
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AAEA,IAAM,iBAAiB;AACvB,IAAM,6BAA6B;AAC5B,IAAM,iCAAiC;AAC9C,IAAM,iBAAiB;AACvB,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AAAA;AAwHjB,MAAM,mCAAmC,MAAM;AAAC;AAEvD,IAAM,WAAW,CAAC,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,IAAM,gBAAgB,CAAC,OAAgB,UAAkB;AAAA,EACvD,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW;AAAA,IAChD,MAAM,IAAI,2BAA2B,kBAAkB,kBAAkB;AAAA,EAE3E,OAAO;AAAA;AAGT,IAAM,gBAAgB,CAAC,UAA0C;AAAA,EAC/D,IAAI,CAAC,SAAS,KAAK;AAAA,IACjB,MAAM,IAAI,2BAA2B,oCAAoC;AAAA,EAC3E,MAAM,QAAQ,cAAc,MAAM,OAAO,OAAO;AAAA,EAChD,MAAM,SAAS,cAAc,MAAM,QAAQ,QAAQ;AAAA,EACnD,MAAM,YAAY,cAAc,MAAM,WAAW,WAAW;AAAA,EAC5D,IAAI,CAAC,eAAe,KAAK,KAAK;AAAA,IAC5B,MAAM,IAAI,2BAA2B,iCAAiC;AAAA,EACxE,IAAI,CAAC,eAAe,KAAK,MAAM;AAAA,IAC7B,MAAM,IAAI,2BAA2B,kCAAkC;AAAA,EACzE,IAAI,MAAM,aAAa,aAAa,MAAM,aAAa;AAAA,IACrD,MAAM,IAAI,2BAA2B,oCAAoC;AAAA,EAC3E,IAAI,cAAc,WAAW,MAAM,YAAY;AAAA,IAC7C,MAAM,IAAI,2BACR,sDACF;AAAA,EACF,MAAM,gBACJ,MAAM,WAAW,eACjB,MAAM,WAAW,KACjB,OAAO,MAAM,WAAW,aACxB,CAAC,OAAO,cAAc,MAAM,KAAK,KACjC,OAAO,MAAM,KAAK,IAAI;AAAA,EACxB,IAAI;AAAA,IACF,MAAM,IAAI,2BAA2B,oCAAoC;AAAA,EAC3E,IAAI,MAAM,aAAa,WAAW;AAAA,IAChC,IACE,MAAM,aAAa,qBACnB,MAAM,SAAS,SACd,MAAM,gBAAgB,cACpB,CAAC,OAAO,cAAc,MAAM,WAAW,KACtC,OAAO,MAAM,WAAW,IAAI,KAC5B,OAAO,MAAM,WAAW,IAAI;AAAA,MAEhC,MAAM,IAAI,2BACR,oCACF;AAAA,IAEF,OAAO;AAAA,MACL,UAAU,cAAc,MAAM,UAAU,UAAU;AAAA,MAClD;AAAA,MACA,UAAU;AAAA,MACV,OAAO,OAAO,MAAM,KAAK;AAAA,MACzB,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,UAAU;AAAA,MACV;AAAA,MACA,SAAS,cAAc,MAAM,SAAS,SAAS;AAAA,MAC/C;AAAA,MACA,QAAQ,MAAM,WAAW;AAAA,MACzB,MAAM;AAAA,SACF,MAAM,gBAAgB,YACtB,CAAC,IACD,EAAE,aAAa,OAAO,MAAM,WAAW,EAAE;AAAA,IAC/C;AAAA,EACF;AAAA,EACA,IACE,MAAM,aAAa,aACnB,MAAM,SAAS,SACf,OAAO,MAAM,qBAAqB,YAClC,CAAC,sBAAsB,KAAK,MAAM,gBAAgB,KACjD,MAAM,gBAAgB,cACpB,CAAC,OAAO,cAAc,MAAM,WAAW,KACtC,OAAO,MAAM,WAAW,IAAI;AAAA,IAEhC,MAAM,IAAI,2BAA2B,oCAAoC;AAAA,EAE3E,OAAO;AAAA,IACL,UAAU,cAAc,MAAM,UAAU,UAAU;AAAA,IAClD;AAAA,IACA,UAAU;AAAA,OACN,MAAM,gBAAgB,YACtB,CAAC,IACD,EAAE,aAAa,OAAO,MAAM,WAAW,EAAE;AAAA,IAC7C,OAAO,OAAO,MAAM,KAAK;AAAA,IACzB,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,kBAAkB,MAAM;AAAA,IACxB,UAAU;AAAA,IACV;AAAA,IACA,SAAS,cAAc,MAAM,SAAS,SAAS;AAAA,IAC/C;AAAA,IACA,QAAQ,MAAM,WAAW;AAAA,IACzB,MAAM;AAAA,EACR;AAAA;AAGF,IAAM,mBAAmB,CAAC,UAAkB;AAAA,EAC1C,MAAM,SAAS,MAAM,QAAQ,cAAc,EAAE;AAAA,EAC7C,IACE,OAAO,WAAW,KAClB,OAAO,MAAM,GAAG,EAAE,KAAK,CAAC,YAAY,YAAY,OAAO,YAAY,IAAI;AAAA,IAEvE,MAAM,IAAI,2BAA2B,kCAAkC;AAAA,EAEzE,OAAO;AAAA;AAGT,IAAM,iBAAiB,CAAC,UAAkB;AAAA,EACxC,IAAI,CAAC,gBAAgB,KAAK,KAAK;AAAA,IAC7B,MAAM,IAAI,2BAA2B,mCAAmC;AAAA,EAE1E,OAAO;AAAA;AAGT,IAAM,cAAc,CAAC,UACnB,WAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK;AAEjD,IAAM,cAAc,CAAC,UACnB,WAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK;AAEjD,IAAM,iBAAiB,CAAC,UAAoC;AAAA,EAC1D,IAAI,OAAO,UAAU,YAAY,OAAO,MAAM,KAAK,MAAM,KAAK,CAAC;AAAA,IAC7D,OAAO;AAAA,EAET,OAAO,IAAI,KAAK,KAAK,EAAE,YAAY,MAAM;AAAA;AAG3C,IAAM,aAAa,OAAO,SAAsB;AAAA,EAC9C,MAAM,SAAS,IAAI,IAAI,aAAa,QAAQ;AAAA,EAC5C,iBAAiB,SAAS,KAAK,OAAO;AAAA,IAAG,OAAO,OAAO,KAAK;AAAA,EAE5D,OAAO,OAAO,OAAO,KAAK;AAAA;AAG5B,IAAM,cAAc,CAAC,UACnB,IAAI,YAAY,EAAE,OAAO,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC;AAAA,CAAK;AAEhE,IAAM,cAAc,CAAC,UACnB,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,KAAK,CAAC;AAE5C,IAAM,eAAe,CACnB,MACA,UACG,KAAK,UAAU,IAAI,MAAM,KAAK,UAAU,KAAK;AAElD,IAAM,cAAc,CAAC,UAAwC;AAAA,EAC3D,IACE,CAAC,SAAS,KAAK,KACf,MAAM,WAAW,kCACjB,OAAO,MAAM,gBAAgB;AAAA,IAE7B,MAAM,IAAI,2BAA2B,kCAAkC;AAAA,EACzE,MAAM,WAAW,cAAc,MAAM,QAAQ;AAAA,EAE7C,OAAO;AAAA,IACL,aAAa,MAAM;AAAA,IACnB,QAAQ;AAAA,IACR;AAAA,EACF;AAAA;AAGF,IAAM,eAAe,CAAC,UAAyC;AAAA,EAC7D,IACE,CAAC,SAAS,KAAK,KACf,MAAM,WAAW,kCAChB,MAAM,aAAa,aAAa,MAAM,aAAa,SACpD,CAAC,eAAe,MAAM,UAAU;AAAA,IAEhC,MAAM,IAAI,2BAA2B,mCAAmC;AAAA,EAC1E,MAAM,QAAQ,cAAc,MAAM,OAAO,eAAe;AAAA,EACxD,MAAM,UAAU,eAAe,cAAc,MAAM,SAAS,SAAS,CAAC;AAAA,EACtE,MAAM,SAAS,cAAc,MAAM,QAAQ,gBAAgB;AAAA,EAC3D,MAAM,YAAY,cAAc,MAAM,WAAW,mBAAmB;AAAA,EACpE,IAAI,CAAC,eAAe,KAAK,KAAK,KAAK,CAAC,eAAe,KAAK,MAAM;AAAA,IAC5D,MAAM,IAAI,2BAA2B,mCAAmC;AAAA,EAC1E,IAAI,cAAc,WAAW,MAAM,YAAY;AAAA,IAC7C,MAAM,IAAI,2BACR,gDACF;AAAA,EAEF,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,UAAU,MAAM;AAAA,IAChB,YAAY,MAAM;AAAA,IAClB;AAAA,IACA;AAAA,EACF;AAAA;AAGK,IAAM,8BAA8B,CACzC,YAC0B;AAAA,EAC1B,MAAM,SAAS,iBAAiB,QAAQ,UAAU,cAAc;AAAA,EAChE,MAAM,mBACJ,QAAQ,oBAAoB;AAAA,EAC9B,IAAI,CAAC,OAAO,cAAc,gBAAgB,KAAK,mBAAmB;AAAA,IAChE,MAAM,IAAI,2BACR,4CACF;AAAA,EACF,MAAM,QAAQ,QAAQ,UAAU,MAAM,IAAI;AAAA,EAC1C,MAAM,UAAU,CACd,OACA,aACG,GAAG,UAAU,YAAY,KAAK,KAAK;AAAA,EACxC,MAAM,cAAc,CAAC,aACnB,GAAG,QAAQ,SAAS,OAAO,SAAS,QAAQ,cAAc,SAAS;AAAA,EACrE,MAAM,YAAY,CAAC,aACjB,GAAG,YAAY,QAAQ;AAAA,EACzB,MAAM,cAAc,CAAC,aACnB,GAAG,YAAY,QAAQ,KAAK,SAAS;AAAA,EACvC,MAAM,aAAa,CACjB,OACA,UACA,YACG,GAAG,QAAQ,OAAO,QAAQ,cAAc,eAAe,OAAO;AAAA,EAEnE,MAAM,wBAAwB,OAC5B,KACA,aACG;AAAA,IACH,MAAM,SAAS,MAAM,QAAQ,MAAM,KAAK,GAAG;AAAA,IAC3C,IACE,CAAC,UACD,OAAO,SAAS,SAAS,SACzB,OAAO,UAAU,WAAW,SAAS,UACrC,OAAO,UAAU,cAAc,SAAS;AAAA,MAExC,MAAM,IAAI,2BACR,sEACF;AAAA;AAAA,EAGJ,MAAM,OAAO,OAAO,UAId;AAAA,IACJ,IAAI,CAAC,eAAe,KAAK,MAAM,KAAK;AAAA,MAClC,MAAM,IAAI,2BAA2B,iCAAiC;AAAA,IACxE,MAAM,SAAS,MAAM,UAAU,QAC7B,IAAI,OAAO,YAAY,MAAM,WAAW,GACxC,EACF;AAAA,IACA,IACE,CAAC,eAAe,KAAK,MAAM,KAC3B,MAAM,cAAc,WAAW,MAAM,YAAY;AAAA,MAEjD,MAAM,IAAI,2BAA2B,8BAA8B;AAAA,IACrE,MAAM,WACJ,MAAM,aAAa,YACf;AAAA,MACE,UAAU;AAAA,MACV,OAAO,MAAM;AAAA,MACb,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,WAAW,MAAM;AAAA,MACjB,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,IACA;AAAA,MACE,UAAU;AAAA,MACV,OAAO,MAAM;AAAA,MACb,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,kBAAkB;AAAA,MAClB,UAAU;AAAA,MACV,WAAW,MAAM;AAAA,MACjB,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,MAAM;AAAA,IACR;AAAA,IACN,MAAM,MAAM,UAAU,QAAQ;AAAA,IAC9B,MAAM,QAAQ,MAAM,QAAQ,MAAM,IAAI,GAAG;AAAA,IACzC,IAAI,CAAC;AAAA,MAAO,OAAO;AAAA,IACnB,MAAM,eAAe,MAAM,QAAQ,MAAM,KAAK,GAAG;AAAA,IACjD,IACE,CAAC,gBACD,aAAa,SAAS,MAAM,cAC5B,aAAa,UAAU,cAAc,MAAM,aAC3C,aAAa,UAAU,WAAW,YAAY,KAAK;AAAA,MAEnD,MAAM,IAAI,2BACR,oEACF;AAAA,IACF,MAAM,SAAS,YAAY,YAAY,KAAK,CAAC;AAAA,IAC7C,IACE,OAAO,SAAS,UAAU,MAAM,SAChC,OAAO,SAAS,aAAa,MAAM,YACnC,OAAO,SAAS,cAAc,MAAM,aACpC,OAAO,gBAAgB,YAAY,OAAO,QAAQ;AAAA,MAElD,MAAM,IAAI,2BACR,sDACF;AAAA,IACF,MAAM,sBAAsB,OAAO,aAAa,OAAO,QAAQ;AAAA,IAE/D,OAAO;AAAA;AAAA,EAGT,MAAM,UAA4C,OAAO,UAAU;AAAA,IACjE,MAAM,QAAQ,eAAe;AAAA,IAC7B,MAAM,SAAS,MAAM,KAAK,KAAK;AAAA,IAC/B,IAAI,CAAC;AAAA,MACH,MAAM,IAAI,2BAA2B,kCAAkC;AAAA,IACzE,IAAI,CAAC,OAAO,SAAS,UAAU,CAAC,MAAM;AAAA,MACpC,MAAM,IAAI,2BACR,6CACF;AAAA,IACF,MAAM,MAAM,WAAW,MAAM,OAAO,MAAM,UAAU,MAAM,OAAO;AAAA,IACjE,MAAM,gBAAgB,MAAM,QAAQ,MAAM,IAAI,GAAG;AAAA,IACjD,IAAI,eAAe;AAAA,MACjB,MAAM,WAAW,aAAa,YAAY,aAAa,CAAC;AAAA,MACxD,IACE,SAAS,UAAU,MAAM,SACzB,SAAS,aAAa,MAAM,YAC5B,SAAS,YAAY,MAAM;AAAA,QAE3B,MAAM,IAAI,2BACR,uDACF;AAAA,MACF,IAAI,SAAS,cAAc,MAAM;AAAA,QAAW,OAAO;AAAA,IACrD;AAAA,IACA,MAAM,UAAgC;AAAA,MACpC,OAAO,MAAM;AAAA,MACb,SAAS,eAAe,MAAM,OAAO;AAAA,MACrC,QAAQ;AAAA,MACR,UAAU,MAAM;AAAA,MAChB,YAAY,MAAM,EAAE,YAAY;AAAA,MAChC,WAAW,OAAO,SAAS;AAAA,MAC3B,QAAQ,OAAO,SAAS;AAAA,IAC1B;AAAA,IACA,MAAM,aAAa,YAAY,OAAO;AAAA,IACtC,MAAM,QAAQ,MAAM,IAAI,KAAK,YAAY;AAAA,MACvC,cAAc;AAAA,MACd,aAAa;AAAA,MACb,UAAU,WAAW;AAAA,MACrB,UAAU;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,MAClB;AAAA,MACA,QAAQ,MAAM;AAAA,IAChB,CAAC;AAAA,IACD,MAAM,SAAS,MAAM,QAAQ,MAAM,IAAI,GAAG;AAAA,IAC1C,IACE,CAAC,UACD,KAAK,UAAU,aAAa,YAAY,MAAM,CAAC,CAAC,MAC9C,KAAK,UAAU,OAAO;AAAA,MAExB,MAAM,IAAI,2BACR,4CACF;AAAA,IAEF,OAAO;AAAA;AAAA,EAGT,OAAO;AAAA,IACL;AAAA,IACA,SAAS,OAAO,UAAU;AAAA,MACxB,MAAM,QAAQ,eAAe;AAAA,MAC7B,MAAM,YAAY,KAAK,QAAQ,MAAM,WAAW;AAAA,MAChD,MAAM,WAAW,cACf,KAAK,MACH,MAAM,SAAS,KAAK,KAAK,WAAW,cAAc,GAAG,MAAM,CAC7D,CACF;AAAA,MACA,IAAI,SAAS,QAAQ;AAAA,QACnB,MAAM,IAAI,2BACR,sDACF;AAAA,MACF,IAAI,CAAC,SAAS,UAAU,CAAC,MAAM;AAAA,QAC7B,MAAM,IAAI,2BACR,8CACF;AAAA,MACF,MAAM,gBAAgB,KAAK,KAAK,WAAW,SAAS,QAAQ;AAAA,MAC5D,MAAM,gBAAgB,MAAM,KAAK,aAAa,EAAE,MAAM,MAAM,IAAI;AAAA,MAChE,IAAI,CAAC,eAAe,OAAO,KAAK,cAAc,SAAS,SAAS;AAAA,QAC9D,MAAM,IAAI,2BACR,0DACF;AAAA,MACF,IAAK,MAAM,WAAW,IAAI,KAAK,aAAa,CAAC,MAAO,SAAS;AAAA,QAC3D,MAAM,IAAI,2BACR,4DACF;AAAA,MACF,MAAM,WAAW,MAAM,KAAK;AAAA,QAC1B,OAAO,SAAS;AAAA,QAChB,UAAU,SAAS;AAAA,QACnB,WAAW,SAAS;AAAA,MACtB,CAAC;AAAA,MACD,IAAI;AAAA,MACJ,IAAI,SAAS;AAAA,MACb,IAAI,UAAU;AAAA,QACZ,IAAI,CAAC,aAAa,SAAS,UAAU,QAAQ;AAAA,UAC3C,MAAM,IAAI,2BACR,gDACF;AAAA,QACF,SAAS;AAAA,QACT,SAAS;AAAA,MACX,EAAO;AAAA,QACL,MAAM,MAAM,YAAY,QAAQ;AAAA,QAChC,MAAM,iBAAiB,MAAM,QAAQ,MAAM,KAAK,GAAG;AAAA,QACnD,IAAI,gBAAgB;AAAA,UAClB,MAAM,sBAAsB,KAAK,QAAQ;AAAA,QAC3C,EAAO;AAAA,UACL,MAAM,QAAQ,MAAM,IAAI,KAAK,IAAI,KAAK,aAAa,EAAE,OAAO,GAAG;AAAA,YAC7D,cAAc;AAAA,YACd,aAAa;AAAA,YACb,UAAU,SAAS;AAAA,YACnB,UAAU;AAAA,cACR,OAAO,SAAS;AAAA,cAChB,WAAW,SAAS;AAAA,cACpB,QAAQ,SAAS;AAAA,YACnB;AAAA,YACA,QAAQ,MAAM;AAAA,UAChB,CAAC;AAAA,UACD,MAAM,sBAAsB,KAAK,QAAQ;AAAA;AAAA,QAE3C,SAAS;AAAA,UACP,aAAa;AAAA,UACb,QAAQ;AAAA,UACR;AAAA,QACF;AAAA,QACA,MAAM,aAAa,YAAY,MAAM;AAAA,QACrC,MAAM,QAAQ,MAAM,IAAI,UAAU,QAAQ,GAAG,YAAY;AAAA,UACvD,cAAc;AAAA,UACd,aAAa;AAAA,UACb,UAAU,WAAW;AAAA,UACrB,UAAU;AAAA,YACR,WAAW,SAAS;AAAA,YACpB,QAAQ,YAAY,UAAU;AAAA,UAChC;AAAA,UACA,QAAQ,MAAM;AAAA,QAChB,CAAC;AAAA,QACD,MAAM,WAAW,MAAM,KAAK;AAAA,UAC1B,OAAO,SAAS;AAAA,UAChB,UAAU,SAAS;AAAA,UACnB,WAAW,SAAS;AAAA,QACtB,CAAC;AAAA,QACD,IAAI,CAAC,YAAY,KAAK,UAAU,QAAQ,MAAM,KAAK,UAAU,MAAM;AAAA,UACjE,MAAM,IAAI,2BACR,gDACF;AAAA;AAAA,MAEJ,MAAM,UAAU,MAAM,UAClB,MAAM,QAAQ;AAAA,QACZ,eAAe,MAAM;AAAA,QACrB,OAAO,SAAS;AAAA,QAChB,SAAS,MAAM;AAAA,QACf,UAAU,SAAS;AAAA,QACnB,WAAW,SAAS;AAAA,QACpB,QAAQ,MAAM;AAAA,MAChB,CAAC,IACD;AAAA,MAEJ,OAAO,KAAM,UAAU,EAAE,QAAQ,IAAI,CAAC,GAAI,QAAQ,OAAO;AAAA;AAAA,IAE3D;AAAA,IACA,SAAS,OAAO,UAAU;AAAA,MACxB,IAAI,CAAC,eAAe,KAAK,MAAM,KAAK;AAAA,QAClC,MAAM,IAAI,2BAA2B,iCAAiC;AAAA,MACxE,MAAM,MAAM,WAAW,MAAM,OAAO,MAAM,UAAU,MAAM,OAAO;AAAA,MACjE,MAAM,QAAQ,MAAM,QAAQ,MAAM,IAAI,GAAG;AAAA,MACzC,IAAI,CAAC;AAAA,QAAO,OAAO;AAAA,MACnB,MAAM,UAAU,aAAa,YAAY,KAAK,CAAC;AAAA,MAC/C,IACE,QAAQ,UAAU,MAAM,SACxB,QAAQ,aAAa,MAAM,YAC3B,QAAQ,YAAY,MAAM;AAAA,QAE1B,MAAM,IAAI,2BACR,uDACF;AAAA,MACF,MAAM,SAAS,MAAM,KAAK;AAAA,QACxB,OAAO,QAAQ;AAAA,QACf,UAAU,QAAQ;AAAA,QAClB,WAAW,QAAQ;AAAA,MACrB,CAAC;AAAA,MACD,IAAI,CAAC,UAAU,OAAO,SAAS,WAAW,QAAQ;AAAA,QAChD,MAAM,IAAI,2BACR,+DACF;AAAA,MAEF,OAAO,EAAE,SAAS,OAAO;AAAA;AAAA,EAE7B;AAAA;",
8
+ "debugId": "242BF8653CD0343D64756E2164756E21",
9
9
  "names": []
10
10
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/deploy",
3
- "version": "0.22.0",
3
+ "version": "0.24.0",
4
4
  "description": "Generic Bun-project deploy pipeline. A Target (localTarget / sshTarget) is anywhere you can exec + upload — DigitalOcean droplets, Linode, Hetzner, Vultr, your own boxes. Bundled pipeline: prepare → upload → install → build → link → restart → verify. Atomic symlink swap, release history, prune, hooks. SSH shells out to system ssh/rsync — zero ssh2 deps.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -30,7 +30,7 @@
30
30
  "release"
31
31
  ],
32
32
  "scripts": {
33
- "build": "rm -rf dist && bun build src/index.ts src/releaseArtifact.ts src/nativeRelease.ts src/infrastructure.ts src/ephemeralInfrastructure.ts src/edgeIngress.ts src/digitalocean.ts src/digitaloceanInfrastructure.ts src/digitaloceanEphemeralInfrastructure.ts src/digitaloceanIngress.ts src/gcp.ts src/gcpIngress.ts src/hetzner.ts src/hetznerInfrastructure.ts src/linode.ts src/linodeInfrastructure.ts src/vultr.ts src/vultrInfrastructure.ts src/dns.ts src/cloudflare.ts src/digitaloceanDns.ts src/hetznerDns.ts src/route53.ts src/tls.ts src/env.ts src/preview.ts src/managedPreview.ts --outdir dist --root src --sourcemap --target=bun && tsc --project tsconfig.build.json",
33
+ "build": "rm -rf dist && bun build src/index.ts src/releaseArtifact.ts src/nativeRelease.ts src/googlePlay.ts src/appStoreConnect.ts src/infrastructure.ts src/ephemeralInfrastructure.ts src/edgeIngress.ts src/digitalocean.ts src/digitaloceanInfrastructure.ts src/digitaloceanEphemeralInfrastructure.ts src/digitaloceanIngress.ts src/gcp.ts src/gcpIngress.ts src/hetzner.ts src/hetznerInfrastructure.ts src/linode.ts src/linodeInfrastructure.ts src/vultr.ts src/vultrInfrastructure.ts src/dns.ts src/cloudflare.ts src/digitaloceanDns.ts src/hetznerDns.ts src/route53.ts src/tls.ts src/env.ts src/preview.ts src/managedPreview.ts --outdir dist --root src --sourcemap --target=bun && tsc --project tsconfig.build.json",
34
34
  "test": "bun test tests/",
35
35
  "typecheck": "tsc --noEmit",
36
36
  "format": "prettier --write \"./**/*.{ts,json,md}\"",
@@ -91,6 +91,16 @@
91
91
  "import": "./dist/nativeRelease.js",
92
92
  "default": "./dist/nativeRelease.js"
93
93
  },
94
+ "./google-play": {
95
+ "types": "./dist/googlePlay.d.ts",
96
+ "import": "./dist/googlePlay.js",
97
+ "default": "./dist/googlePlay.js"
98
+ },
99
+ "./app-store-connect": {
100
+ "types": "./dist/appStoreConnect.d.ts",
101
+ "import": "./dist/appStoreConnect.js",
102
+ "default": "./dist/appStoreConnect.js"
103
+ },
94
104
  "./digitalocean-ingress": {
95
105
  "types": "./dist/digitaloceanIngress.d.ts",
96
106
  "import": "./dist/digitaloceanIngress.js",