@hot-updater/vercel 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/function/index.mjs +134 -4
- package/dist/init/index.cjs +7 -50
- package/dist/init/index.mjs +7 -50
- package/package.json +7 -7
package/dist/function/index.mjs
CHANGED
|
@@ -17558,7 +17558,7 @@ const postgres = (config) => {
|
|
|
17558
17558
|
};
|
|
17559
17559
|
//#endregion
|
|
17560
17560
|
//#region ../../packages/server/dist/version.mjs
|
|
17561
|
-
const HOT_UPDATER_SERVER_VERSION = "1.0.
|
|
17561
|
+
const HOT_UPDATER_SERVER_VERSION = "1.0.6";
|
|
17562
17562
|
//#endregion
|
|
17563
17563
|
//#region ../../packages/server/dist/handlerVersionRoutes.mjs
|
|
17564
17564
|
const createVersionRouteHandlers = (plugins = []) => {
|
|
@@ -17847,6 +17847,85 @@ async function resolveManifestArtifacts({ currentBundle, resolveFileUrl, readSto
|
|
|
17847
17847
|
...archiveUrl ? { archiveUrl } : {}
|
|
17848
17848
|
};
|
|
17849
17849
|
}
|
|
17850
|
+
async function loadTargetPlan({ currentBundle, readStorageText, targetBundle }) {
|
|
17851
|
+
const manifestStorageUri = getManifestStorageUri(targetBundle);
|
|
17852
|
+
const manifestFileHash = getManifestFileHash(targetBundle);
|
|
17853
|
+
const assetBaseStorageUri = getAssetBaseStorageUri(targetBundle);
|
|
17854
|
+
if (!manifestStorageUri || !manifestFileHash || !assetBaseStorageUri) return null;
|
|
17855
|
+
const targetManifest = await fetchBundleManifest(manifestStorageUri, readStorageText);
|
|
17856
|
+
if (!targetManifest) return null;
|
|
17857
|
+
return {
|
|
17858
|
+
manifestFileHash,
|
|
17859
|
+
manifestStorageUri,
|
|
17860
|
+
plan: createManifestArtifactPlan({
|
|
17861
|
+
assetBaseStorageUri,
|
|
17862
|
+
currentBundle,
|
|
17863
|
+
targetBundle,
|
|
17864
|
+
targetManifest
|
|
17865
|
+
}),
|
|
17866
|
+
targetManifest
|
|
17867
|
+
};
|
|
17868
|
+
}
|
|
17869
|
+
async function resolveManifestArtifactsV2({ currentBundle, resolveFileUrl, readStorageText, targetBundle }) {
|
|
17870
|
+
const target = await loadTargetPlan({
|
|
17871
|
+
currentBundle,
|
|
17872
|
+
readStorageText,
|
|
17873
|
+
targetBundle
|
|
17874
|
+
});
|
|
17875
|
+
if (!target) return null;
|
|
17876
|
+
const manifestUrl = await resolveFileUrl(target.manifestStorageUri);
|
|
17877
|
+
if (!manifestUrl) return null;
|
|
17878
|
+
const patched = target.plan.assets.find((asset) => asset.patch !== null);
|
|
17879
|
+
let patch;
|
|
17880
|
+
if (patched?.patch && !(patched.file.byteSize !== null && patched.patch.byteSize !== null && patched.patch.byteSize >= patched.file.byteSize)) try {
|
|
17881
|
+
const patchUrl = await resolveFileUrl(patched.patch.storageUri);
|
|
17882
|
+
if (patchUrl) patch = {
|
|
17883
|
+
algorithm: "bsdiff",
|
|
17884
|
+
assetPath: patched.assetPath,
|
|
17885
|
+
baseBundleId: patched.patch.baseBundleId,
|
|
17886
|
+
baseFileHash: patched.patch.baseFileHash,
|
|
17887
|
+
patchFileHash: patched.patch.patchFileHash,
|
|
17888
|
+
patchUrl,
|
|
17889
|
+
...patched.patch.byteSize === null ? {} : { byteSize: patched.patch.byteSize }
|
|
17890
|
+
};
|
|
17891
|
+
} catch {}
|
|
17892
|
+
let archiveUrl = null;
|
|
17893
|
+
const archive = target.targetManifest.archive;
|
|
17894
|
+
if (archive && isContentAddressedAssetFileHash(archive.downloadFileHash) && (asByteSize(archive.downloadByteSize) ?? 0) > 0 && (asByteSize(archive.tarByteSize) ?? 0) > 0) try {
|
|
17895
|
+
archiveUrl = await resolveFileUrl(getBundleArchiveStorageUri({
|
|
17896
|
+
manifestStorageUri: target.manifestStorageUri,
|
|
17897
|
+
bundleId: targetBundle.id
|
|
17898
|
+
}));
|
|
17899
|
+
} catch {}
|
|
17900
|
+
return {
|
|
17901
|
+
artifactProtocolVersion: 2,
|
|
17902
|
+
manifestFileHash: target.manifestFileHash,
|
|
17903
|
+
manifestUrl,
|
|
17904
|
+
...archiveUrl ? { archiveUrl } : {},
|
|
17905
|
+
...patch ? { patch } : {}
|
|
17906
|
+
};
|
|
17907
|
+
}
|
|
17908
|
+
async function resolveManifestArtifactFiles({ paths, resolveFileUrl, readStorageText, targetBundle }) {
|
|
17909
|
+
if (paths.length === 0 || paths.length > 100 || new Set(paths).size !== paths.length) return null;
|
|
17910
|
+
const target = await loadTargetPlan({
|
|
17911
|
+
currentBundle: null,
|
|
17912
|
+
readStorageText,
|
|
17913
|
+
targetBundle
|
|
17914
|
+
});
|
|
17915
|
+
if (!target) return null;
|
|
17916
|
+
const planned = new Map(target.plan.assets.map((asset) => [asset.assetPath, asset]));
|
|
17917
|
+
const requested = paths.map((path) => planned.get(path));
|
|
17918
|
+
if (requested.some((asset) => asset === void 0)) return null;
|
|
17919
|
+
const files = await Promise.all(requested.map(async (asset) => {
|
|
17920
|
+
const url = await resolveFileUrl(asset.file.storageUri);
|
|
17921
|
+
if (!url) return null;
|
|
17922
|
+
const file = { url };
|
|
17923
|
+
if (asset.file.compression) file.compression = asset.file.compression;
|
|
17924
|
+
return [asset.assetPath, file];
|
|
17925
|
+
}));
|
|
17926
|
+
if (files.some((file) => file === null)) return null;
|
|
17927
|
+
return { files: Object.fromEntries(files.filter((file) => file !== null)) };
|
|
17928
|
+
}
|
|
17850
17929
|
//#endregion
|
|
17851
17930
|
//#region ../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.js
|
|
17852
17931
|
const LETTER_DASH_NUMBER = "[a-zA-Z0-9-]";
|
|
@@ -18308,20 +18387,33 @@ const createCoreReads = (db, storage) => {
|
|
|
18308
18387
|
const row = await db.findOne("release_catalogs", { scope_key: scopeKey });
|
|
18309
18388
|
return projectReleaseCatalogRow(row === null ? null : toCatalogRow(row), input, scopeKey);
|
|
18310
18389
|
},
|
|
18311
|
-
async
|
|
18390
|
+
getArtifactInfo: (async (targetBundleId, currentBundleId, artifactProtocolVersion) => {
|
|
18312
18391
|
const { readStorageText } = storage;
|
|
18313
|
-
if (artifactProtocolVersion !== 1 || readStorageText === void 0) return null;
|
|
18392
|
+
if (artifactProtocolVersion !== 1 && artifactProtocolVersion !== 2 || readStorageText === void 0) return null;
|
|
18314
18393
|
const withCurrent = currentBundleId !== NIL_UUID;
|
|
18315
18394
|
const [[target, current], patch] = await Promise.all([db.findByKeys("bundles", withCurrent ? [{ id: targetBundleId }, { id: currentBundleId }] : [{ id: targetBundleId }]), withCurrent ? db.findOne("bundle_patches", {
|
|
18316
18395
|
bundle_id: targetBundleId,
|
|
18317
18396
|
base_bundle_id: currentBundleId
|
|
18318
18397
|
}) : null]);
|
|
18319
18398
|
if (target === null || target === void 0) return null;
|
|
18320
|
-
|
|
18399
|
+
const input = {
|
|
18321
18400
|
currentBundle: current ? rowToBundle(toBundleRow(current)) : null,
|
|
18322
18401
|
readStorageText,
|
|
18323
18402
|
resolveFileUrl: storage.resolveFileUrl,
|
|
18324
18403
|
targetBundle: rowToBundle(toBundleRow(target), patch === null ? [] : [toPatchRow(patch)])
|
|
18404
|
+
};
|
|
18405
|
+
return artifactProtocolVersion === 2 ? resolveManifestArtifactsV2(input) : resolveManifestArtifacts(input);
|
|
18406
|
+
}),
|
|
18407
|
+
async getArtifactFiles(bundleId, paths) {
|
|
18408
|
+
const { readStorageText } = storage;
|
|
18409
|
+
if (readStorageText === void 0) return null;
|
|
18410
|
+
const row = await db.findOne("bundles", { id: bundleId });
|
|
18411
|
+
if (row === null) return null;
|
|
18412
|
+
return resolveManifestArtifactFiles({
|
|
18413
|
+
paths,
|
|
18414
|
+
readStorageText,
|
|
18415
|
+
resolveFileUrl: storage.resolveFileUrl,
|
|
18416
|
+
targetBundle: rowToBundle(toBundleRow(row))
|
|
18325
18417
|
});
|
|
18326
18418
|
},
|
|
18327
18419
|
async getBundle(id) {
|
|
@@ -19598,11 +19690,23 @@ const ADMIN_ROUTES = [
|
|
|
19598
19690
|
//#region ../../packages/server/dist/handlerReleaseCatalogRoutes.mjs
|
|
19599
19691
|
const CATALOG_CONTENT_TYPE = "application/vnd.hot-updater.release-catalog+json; version=1";
|
|
19600
19692
|
const ARTIFACT_CONTENT_TYPE = "application/vnd.hot-updater.artifact+json; version=1";
|
|
19693
|
+
const ARTIFACT_V2_CONTENT_TYPE = "application/vnd.hot-updater.artifact+json; version=2";
|
|
19601
19694
|
const ORIGIN_CACHE_TTL_MS = 5e3;
|
|
19602
19695
|
const ORIGIN_CACHE_MAX_ENTRIES = 128;
|
|
19603
19696
|
const NO_CATALOG_HEADER = "x-hot-updater-catalog";
|
|
19604
19697
|
const CATALOG_CACHE_CONTROL = "public, max-age=0, s-maxage=5";
|
|
19605
19698
|
const CATALOG_CDN_CACHE_CONTROL = "public, max-age=5, stale-while-revalidate=5, stale-if-error=0";
|
|
19699
|
+
const readArtifactFilePaths = async (request) => {
|
|
19700
|
+
let body;
|
|
19701
|
+
try {
|
|
19702
|
+
body = await request.json();
|
|
19703
|
+
} catch {
|
|
19704
|
+
return null;
|
|
19705
|
+
}
|
|
19706
|
+
const paths = body?.paths;
|
|
19707
|
+
if (!Array.isArray(paths) || paths.length === 0 || paths.length > 100 || !paths.every((path) => typeof path === "string" && path.length > 0) || new Set(paths).size !== paths.length) return null;
|
|
19708
|
+
return paths;
|
|
19709
|
+
};
|
|
19606
19710
|
const privateNotFound = () => Response.json({ error: "Not found" }, {
|
|
19607
19711
|
status: 404,
|
|
19608
19712
|
headers: { "cache-control": "private, no-store" }
|
|
@@ -19712,6 +19816,30 @@ const createReleaseCatalogRouteHandlers = () => {
|
|
|
19712
19816
|
if (invalid) return invalid;
|
|
19713
19817
|
return catalogResponse(await loadCatalog(`fingerprint:${JSON.stringify(input)}`, () => core.getReleaseCatalog(input)), request);
|
|
19714
19818
|
},
|
|
19819
|
+
artifactV2: async (params, _request, { core }) => {
|
|
19820
|
+
const info = await core.getArtifactInfo(requireRouteParam(params, "targetBundleId"), requireRouteParam(params, "currentBundleId"), 2);
|
|
19821
|
+
if (info === null) return privateNotFound();
|
|
19822
|
+
return new Response(JSON.stringify(info), {
|
|
19823
|
+
status: 200,
|
|
19824
|
+
headers: {
|
|
19825
|
+
"cache-control": "private, no-store",
|
|
19826
|
+
"content-type": ARTIFACT_V2_CONTENT_TYPE
|
|
19827
|
+
}
|
|
19828
|
+
});
|
|
19829
|
+
},
|
|
19830
|
+
artifactFilesV2: async (params, request, { core }) => {
|
|
19831
|
+
const paths = await readArtifactFilePaths(request);
|
|
19832
|
+
if (paths === null) return badRequest(`paths must be 1 to 100 unique strings`);
|
|
19833
|
+
const files = await core.getArtifactFiles(requireRouteParam(params, "targetBundleId"), paths);
|
|
19834
|
+
if (files === null) return privateNotFound();
|
|
19835
|
+
return new Response(JSON.stringify(files), {
|
|
19836
|
+
status: 200,
|
|
19837
|
+
headers: {
|
|
19838
|
+
"cache-control": "private, no-store",
|
|
19839
|
+
"content-type": ARTIFACT_V2_CONTENT_TYPE
|
|
19840
|
+
}
|
|
19841
|
+
});
|
|
19842
|
+
},
|
|
19715
19843
|
artifactV1: async (params, _request, { core }) => {
|
|
19716
19844
|
const info = await core.getArtifactInfo(requireRouteParam(params, "targetBundleId"), requireRouteParam(params, "currentBundleId"), 1);
|
|
19717
19845
|
if (info === null) return privateNotFound();
|
|
@@ -19862,6 +19990,8 @@ function createHotUpdaterHandlers({ api, clientPolicy, endpoints = [], plugins =
|
|
|
19862
19990
|
addClientRoute("GET", "/release-catalogs/app-version/:platform/:channelKey/:appVersion", "appVersionReleaseCatalog");
|
|
19863
19991
|
addClientRoute("GET", "/release-catalogs/fingerprint/:platform/:channelKey/:fingerprintHash", "fingerprintReleaseCatalog");
|
|
19864
19992
|
addClientRoute("GET", "/artifacts/v1/:targetBundleId/from/:currentBundleId", "artifactV1");
|
|
19993
|
+
addClientRoute("GET", "/artifacts/v2/:targetBundleId/from/:currentBundleId", "artifactV2");
|
|
19994
|
+
addClientRoute("POST", "/artifacts/v2/:targetBundleId/files", "artifactFilesV2");
|
|
19865
19995
|
const adminRouter = createRouter();
|
|
19866
19996
|
const addAdminRoute = mount(adminRouter, true);
|
|
19867
19997
|
addAdminRoute("GET", "/version", "adminVersion");
|
package/dist/init/index.cjs
CHANGED
|
@@ -6536,10 +6536,6 @@ const createVercelApi = ({ token, teamId, fetch: fetchImpl = fetch }) => {
|
|
|
6536
6536
|
envVarPrefix: input.envVarPrefix
|
|
6537
6537
|
} });
|
|
6538
6538
|
},
|
|
6539
|
-
/** Removes a store's connection, and the variables it added, from a project. */
|
|
6540
|
-
async disconnectBlobStore(storeId, connectionId) {
|
|
6541
|
-
await request("DELETE", `/v1/storage/stores/${encodeURIComponent(storeId)}/connections/${encodeURIComponent(connectionId)}`);
|
|
6542
|
-
},
|
|
6543
6539
|
async listProjectEnv(projectId) {
|
|
6544
6540
|
return (await paginate(`/v10/projects/${encodeURIComponent(projectId)}/env`, "envs")).flatMap((env) => isRecord(env) && typeof env.id === "string" && typeof env.key === "string" ? [{
|
|
6545
6541
|
id: env.id,
|
|
@@ -6838,38 +6834,13 @@ const resolveProjectName = async (savedName, nonInteractive) => {
|
|
|
6838
6834
|
}));
|
|
6839
6835
|
};
|
|
6840
6836
|
/**
|
|
6841
|
-
* The saved store, or one the user selects or creates
|
|
6842
|
-
*
|
|
6837
|
+
* The saved private store, or one the user selects or creates. Bundles
|
|
6838
|
+
* download only through signed URLs, so a public store is never used.
|
|
6843
6839
|
*/
|
|
6844
6840
|
const selectBlobStore = async ({ nonInteractive, savedId, savedName, stores }) => {
|
|
6845
|
-
const found = stores.find((store) => store.id === savedId) ?? (savedId === void 0 ? stores.find((store) => store.name === savedName) : void 0);
|
|
6846
|
-
const publicStore = found?.access === "public" ? found : void 0;
|
|
6847
|
-
const replacement = publicStore && `Blob store ${publicStore.name} is public. Hot Updater keeps bundles in a private store, and the bundles deployed to ${publicStore.name} stop downloading until you deploy them again.`;
|
|
6848
|
-
const saved = publicStore ? void 0 : found;
|
|
6849
6841
|
const privateStores = stores.filter((store) => store.access === "private");
|
|
6842
|
+
const saved = privateStores.find((store) => store.id === savedId) ?? (savedId === void 0 ? privateStores.find((store) => store.name === savedName) : void 0);
|
|
6850
6843
|
if (nonInteractive) {
|
|
6851
|
-
if (publicStore) {
|
|
6852
|
-
const named = stores.find((store) => store.name === savedName);
|
|
6853
|
-
if (savedName && savedName !== publicStore.name) {
|
|
6854
|
-
if (named?.access === "private") {
|
|
6855
|
-
_hot_updater_cli_tools.p.log.warn(replacement);
|
|
6856
|
-
return {
|
|
6857
|
-
kind: "existing",
|
|
6858
|
-
store: named,
|
|
6859
|
-
replaces: publicStore
|
|
6860
|
-
};
|
|
6861
|
-
}
|
|
6862
|
-
if (!named) {
|
|
6863
|
-
_hot_updater_cli_tools.p.log.warn(replacement);
|
|
6864
|
-
return {
|
|
6865
|
-
kind: "create",
|
|
6866
|
-
name: savedName,
|
|
6867
|
-
replaces: publicStore
|
|
6868
|
-
};
|
|
6869
|
-
}
|
|
6870
|
-
}
|
|
6871
|
-
throw new _hot_updater_cli_tools.InitError(`${replacement} Set ${inputs.blobStoreName.envKey} to a private or new store to replace it.`);
|
|
6872
|
-
}
|
|
6873
6844
|
if (saved) return {
|
|
6874
6845
|
kind: "existing",
|
|
6875
6846
|
store: saved
|
|
@@ -6880,13 +6851,7 @@ const selectBlobStore = async ({ nonInteractive, savedId, savedName, stores }) =
|
|
|
6880
6851
|
};
|
|
6881
6852
|
throw new _hot_updater_cli_tools.InitError(`${inputs.blobStoreName.envKey} is required to select the Blob store.`);
|
|
6882
6853
|
}
|
|
6883
|
-
if (
|
|
6884
|
-
_hot_updater_cli_tools.p.log.warn(replacement);
|
|
6885
|
-
if (!exitIfCancelled(await _hot_updater_cli_tools.p.confirm({
|
|
6886
|
-
message: `Replace ${publicStore.name} with a private Blob store?`,
|
|
6887
|
-
initialValue: false
|
|
6888
|
-
}))) process.exit(1);
|
|
6889
|
-
} else if ((savedId || savedName) && !saved) _hot_updater_cli_tools.p.log.warn("The saved Blob store was not found. Select a store again.");
|
|
6854
|
+
if ((savedId || savedName) && !saved) _hot_updater_cli_tools.p.log.warn("The saved Blob store was not found. Select a store again.");
|
|
6890
6855
|
const createKey = "\0create";
|
|
6891
6856
|
const selected = exitIfCancelled(await _hot_updater_cli_tools.p.select({
|
|
6892
6857
|
message: "Select the Blob store for bundles",
|
|
@@ -6900,21 +6865,18 @@ const selectBlobStore = async ({ nonInteractive, savedId, savedName, stores }) =
|
|
|
6900
6865
|
}]
|
|
6901
6866
|
}));
|
|
6902
6867
|
const store = privateStores.find((candidate) => candidate.id === selected);
|
|
6903
|
-
const replaces = publicStore ? { replaces: publicStore } : {};
|
|
6904
6868
|
if (store) return {
|
|
6905
6869
|
kind: "existing",
|
|
6906
|
-
store
|
|
6907
|
-
...replaces
|
|
6870
|
+
store
|
|
6908
6871
|
};
|
|
6909
6872
|
const prompt = inputs.blobStoreName.prompt;
|
|
6910
6873
|
return {
|
|
6911
6874
|
kind: "create",
|
|
6912
6875
|
name: exitIfCancelled(await _hot_updater_cli_tools.p.text({
|
|
6913
|
-
...(0, _hot_updater_cli_tools.getInitProviderTextPromptValues)(prompt, savedName
|
|
6876
|
+
...(0, _hot_updater_cli_tools.getInitProviderTextPromptValues)(prompt, savedName),
|
|
6914
6877
|
message: prompt.message,
|
|
6915
6878
|
validate: (value) => isVercelBlobStoreName(value) ? void 0 : "Use up to 32 letters, digits, '_', or '-'."
|
|
6916
|
-
}))
|
|
6917
|
-
...replaces
|
|
6879
|
+
}))
|
|
6918
6880
|
};
|
|
6919
6881
|
};
|
|
6920
6882
|
/**
|
|
@@ -7086,11 +7048,6 @@ const runInit = async ({ build, envFile }) => {
|
|
|
7086
7048
|
...saved.databaseUrl ? { savedUrl: saved.databaseUrl } : {}
|
|
7087
7049
|
});
|
|
7088
7050
|
assertPostgresCanInitialize(await readHotUpdaterTables(databaseUrl));
|
|
7089
|
-
for (const connection of storeSelection.replaces?.connections ?? []) {
|
|
7090
|
-
if (connection.projectId !== project.id) continue;
|
|
7091
|
-
await api.disconnectBlobStore(storeSelection.replaces.id, connection.id);
|
|
7092
|
-
_hot_updater_cli_tools.p.log.info(`Disconnected Blob store ${storeSelection.replaces.name} from ${project.name}`);
|
|
7093
|
-
}
|
|
7094
7051
|
let store;
|
|
7095
7052
|
if (storeSelection.kind === "existing") {
|
|
7096
7053
|
store = storeSelection.store;
|
package/dist/init/index.mjs
CHANGED
|
@@ -6530,10 +6530,6 @@ const createVercelApi = ({ token, teamId, fetch: fetchImpl = fetch }) => {
|
|
|
6530
6530
|
envVarPrefix: input.envVarPrefix
|
|
6531
6531
|
} });
|
|
6532
6532
|
},
|
|
6533
|
-
/** Removes a store's connection, and the variables it added, from a project. */
|
|
6534
|
-
async disconnectBlobStore(storeId, connectionId) {
|
|
6535
|
-
await request("DELETE", `/v1/storage/stores/${encodeURIComponent(storeId)}/connections/${encodeURIComponent(connectionId)}`);
|
|
6536
|
-
},
|
|
6537
6533
|
async listProjectEnv(projectId) {
|
|
6538
6534
|
return (await paginate(`/v10/projects/${encodeURIComponent(projectId)}/env`, "envs")).flatMap((env) => isRecord(env) && typeof env.id === "string" && typeof env.key === "string" ? [{
|
|
6539
6535
|
id: env.id,
|
|
@@ -6832,38 +6828,13 @@ const resolveProjectName = async (savedName, nonInteractive) => {
|
|
|
6832
6828
|
}));
|
|
6833
6829
|
};
|
|
6834
6830
|
/**
|
|
6835
|
-
* The saved store, or one the user selects or creates
|
|
6836
|
-
*
|
|
6831
|
+
* The saved private store, or one the user selects or creates. Bundles
|
|
6832
|
+
* download only through signed URLs, so a public store is never used.
|
|
6837
6833
|
*/
|
|
6838
6834
|
const selectBlobStore = async ({ nonInteractive, savedId, savedName, stores }) => {
|
|
6839
|
-
const found = stores.find((store) => store.id === savedId) ?? (savedId === void 0 ? stores.find((store) => store.name === savedName) : void 0);
|
|
6840
|
-
const publicStore = found?.access === "public" ? found : void 0;
|
|
6841
|
-
const replacement = publicStore && `Blob store ${publicStore.name} is public. Hot Updater keeps bundles in a private store, and the bundles deployed to ${publicStore.name} stop downloading until you deploy them again.`;
|
|
6842
|
-
const saved = publicStore ? void 0 : found;
|
|
6843
6835
|
const privateStores = stores.filter((store) => store.access === "private");
|
|
6836
|
+
const saved = privateStores.find((store) => store.id === savedId) ?? (savedId === void 0 ? privateStores.find((store) => store.name === savedName) : void 0);
|
|
6844
6837
|
if (nonInteractive) {
|
|
6845
|
-
if (publicStore) {
|
|
6846
|
-
const named = stores.find((store) => store.name === savedName);
|
|
6847
|
-
if (savedName && savedName !== publicStore.name) {
|
|
6848
|
-
if (named?.access === "private") {
|
|
6849
|
-
p.log.warn(replacement);
|
|
6850
|
-
return {
|
|
6851
|
-
kind: "existing",
|
|
6852
|
-
store: named,
|
|
6853
|
-
replaces: publicStore
|
|
6854
|
-
};
|
|
6855
|
-
}
|
|
6856
|
-
if (!named) {
|
|
6857
|
-
p.log.warn(replacement);
|
|
6858
|
-
return {
|
|
6859
|
-
kind: "create",
|
|
6860
|
-
name: savedName,
|
|
6861
|
-
replaces: publicStore
|
|
6862
|
-
};
|
|
6863
|
-
}
|
|
6864
|
-
}
|
|
6865
|
-
throw new InitError(`${replacement} Set ${inputs.blobStoreName.envKey} to a private or new store to replace it.`);
|
|
6866
|
-
}
|
|
6867
6838
|
if (saved) return {
|
|
6868
6839
|
kind: "existing",
|
|
6869
6840
|
store: saved
|
|
@@ -6874,13 +6845,7 @@ const selectBlobStore = async ({ nonInteractive, savedId, savedName, stores }) =
|
|
|
6874
6845
|
};
|
|
6875
6846
|
throw new InitError(`${inputs.blobStoreName.envKey} is required to select the Blob store.`);
|
|
6876
6847
|
}
|
|
6877
|
-
if (
|
|
6878
|
-
p.log.warn(replacement);
|
|
6879
|
-
if (!exitIfCancelled(await p.confirm({
|
|
6880
|
-
message: `Replace ${publicStore.name} with a private Blob store?`,
|
|
6881
|
-
initialValue: false
|
|
6882
|
-
}))) process.exit(1);
|
|
6883
|
-
} else if ((savedId || savedName) && !saved) p.log.warn("The saved Blob store was not found. Select a store again.");
|
|
6848
|
+
if ((savedId || savedName) && !saved) p.log.warn("The saved Blob store was not found. Select a store again.");
|
|
6884
6849
|
const createKey = "\0create";
|
|
6885
6850
|
const selected = exitIfCancelled(await p.select({
|
|
6886
6851
|
message: "Select the Blob store for bundles",
|
|
@@ -6894,21 +6859,18 @@ const selectBlobStore = async ({ nonInteractive, savedId, savedName, stores }) =
|
|
|
6894
6859
|
}]
|
|
6895
6860
|
}));
|
|
6896
6861
|
const store = privateStores.find((candidate) => candidate.id === selected);
|
|
6897
|
-
const replaces = publicStore ? { replaces: publicStore } : {};
|
|
6898
6862
|
if (store) return {
|
|
6899
6863
|
kind: "existing",
|
|
6900
|
-
store
|
|
6901
|
-
...replaces
|
|
6864
|
+
store
|
|
6902
6865
|
};
|
|
6903
6866
|
const prompt = inputs.blobStoreName.prompt;
|
|
6904
6867
|
return {
|
|
6905
6868
|
kind: "create",
|
|
6906
6869
|
name: exitIfCancelled(await p.text({
|
|
6907
|
-
...getInitProviderTextPromptValues(prompt, savedName
|
|
6870
|
+
...getInitProviderTextPromptValues(prompt, savedName),
|
|
6908
6871
|
message: prompt.message,
|
|
6909
6872
|
validate: (value) => isVercelBlobStoreName(value) ? void 0 : "Use up to 32 letters, digits, '_', or '-'."
|
|
6910
|
-
}))
|
|
6911
|
-
...replaces
|
|
6873
|
+
}))
|
|
6912
6874
|
};
|
|
6913
6875
|
};
|
|
6914
6876
|
/**
|
|
@@ -7080,11 +7042,6 @@ const runInit = async ({ build, envFile }) => {
|
|
|
7080
7042
|
...saved.databaseUrl ? { savedUrl: saved.databaseUrl } : {}
|
|
7081
7043
|
});
|
|
7082
7044
|
assertPostgresCanInitialize(await readHotUpdaterTables(databaseUrl));
|
|
7083
|
-
for (const connection of storeSelection.replaces?.connections ?? []) {
|
|
7084
|
-
if (connection.projectId !== project.id) continue;
|
|
7085
|
-
await api.disconnectBlobStore(storeSelection.replaces.id, connection.id);
|
|
7086
|
-
p.log.info(`Disconnected Blob store ${storeSelection.replaces.name} from ${project.name}`);
|
|
7087
|
-
}
|
|
7088
7045
|
let store;
|
|
7089
7046
|
if (storeSelection.kind === "existing") {
|
|
7090
7047
|
store = storeSelection.store;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hot-updater/vercel",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.6",
|
|
5
5
|
"description": "React Native OTA solution for self-hosted",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
7
7
|
"module": "dist/index.mjs",
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
"@vercel/cli-auth": "0.3.10",
|
|
42
42
|
"@vercel/cli-config": "0.3.1",
|
|
43
43
|
"pg": "8.13.1",
|
|
44
|
-
"@hot-updater/cli-tools": "1.0.
|
|
45
|
-
"@hot-updater/plugin-core": "1.0.
|
|
46
|
-
"@hot-updater/
|
|
47
|
-
"@hot-updater/
|
|
48
|
-
"@hot-updater/
|
|
44
|
+
"@hot-updater/cli-tools": "1.0.6",
|
|
45
|
+
"@hot-updater/plugin-core": "1.0.6",
|
|
46
|
+
"@hot-updater/server": "1.0.6",
|
|
47
|
+
"@hot-updater/postgres": "1.0.6",
|
|
48
|
+
"@hot-updater/protocol": "1.0.6"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/node": "^20",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"execa": "9.5.2",
|
|
55
55
|
"kysely": "0.28.17",
|
|
56
56
|
"vitest": "4.1.4",
|
|
57
|
-
"@hot-updater/test-utils": "1.0.
|
|
57
|
+
"@hot-updater/test-utils": "1.0.6"
|
|
58
58
|
},
|
|
59
59
|
"scripts": {
|
|
60
60
|
"build": "tsdown",
|