@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.
- package/README.md +199 -121
- package/dist/appStoreConnect.d.ts +182 -0
- package/dist/appStoreConnect.js +585 -0
- package/dist/appStoreConnect.js.map +10 -0
- package/dist/googlePlay.d.ts +180 -0
- package/dist/googlePlay.js +10897 -0
- package/dist/googlePlay.js.map +90 -0
- package/dist/index.d.ts +16 -12
- package/dist/index.js +11460 -14
- package/dist/index.js.map +86 -4
- package/dist/nativeRelease.d.ts +18 -1
- package/dist/nativeRelease.js +53 -13
- package/dist/nativeRelease.js.map +3 -3
- package/package.json +12 -2
package/dist/nativeRelease.d.ts
CHANGED
|
@@ -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
|
|
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;
|
package/dist/nativeRelease.js
CHANGED
|
@@ -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 (
|
|
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
|
-
|
|
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: "
|
|
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
|
-
|
|
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: "
|
|
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 !== `
|
|
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:
|
|
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(
|
|
162
|
-
if (!SHA256_PATTERN.test(digest) || input.releaseId !== `
|
|
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=
|
|
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": "
|
|
7
|
+
"mappings": "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",
|
|
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.
|
|
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",
|