@hot-updater/vercel 1.0.2 → 1.0.4
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 +4 -10
- package/dist/index.cjs +12 -5
- package/dist/index.d.cts +6 -7
- package/dist/index.d.mts +6 -7
- package/dist/index.mjs +7 -6
- package/dist/init/index.cjs +62 -42
- package/dist/init/index.d.cts +0 -10
- package/dist/init/index.d.mts +0 -10
- package/dist/init/index.mjs +62 -42
- 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.4";
|
|
17562
17562
|
//#endregion
|
|
17563
17563
|
//#region ../../packages/server/dist/handlerVersionRoutes.mjs
|
|
17564
17564
|
const createVersionRouteHandlers = (plugins = []) => {
|
|
@@ -53404,10 +53404,10 @@ const storeIdOf = (token) => {
|
|
|
53404
53404
|
if (prefix !== "vercel" || kind !== "blob" || rw !== "rw" || !id) throw new Error("vercelBlobStorage needs the store's read-write token (vercel_blob_rw_...).");
|
|
53405
53405
|
return `store_${id}`;
|
|
53406
53406
|
};
|
|
53407
|
+
const access = "private";
|
|
53407
53408
|
const vercelBlobStorage = (config) => {
|
|
53408
|
-
const { token
|
|
53409
|
+
const { token } = config;
|
|
53409
53410
|
const storeId = storeIdOf(token);
|
|
53410
|
-
const host = `${storeId.slice(6).toLowerCase()}.${access}.blob.vercel-storage.com`;
|
|
53411
53411
|
const normalizedBasePath = config.basePath?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
53412
53412
|
const getStorageKey = createStorageKeyBuilder(normalizedBasePath);
|
|
53413
53413
|
const expiresIn = config.signedUrlExpiresIn ?? 3600;
|
|
@@ -53477,7 +53477,6 @@ const vercelBlobStorage = (config) => {
|
|
|
53477
53477
|
async getDownloadUrl({ storageUri }) {
|
|
53478
53478
|
const { key } = parseAndValidate(storageUri);
|
|
53479
53479
|
const pathname = toPathname(key);
|
|
53480
|
-
if (access === "public") return { url: `https://${host}/${pathname.split("/").map(encodeURIComponent).join("/")}` };
|
|
53481
53480
|
const validUntil = Date.now() + expiresInMs;
|
|
53482
53481
|
const { presignedUrl } = await presignUrl(await delegationUntil(validUntil), {
|
|
53483
53482
|
access,
|
|
@@ -53564,8 +53563,6 @@ const requireEnv = (name) => {
|
|
|
53564
53563
|
if (!value) throw new Error(`${name} is not set on the Vercel project. Run \`hot-updater init\` again to configure it.`);
|
|
53565
53564
|
return value;
|
|
53566
53565
|
};
|
|
53567
|
-
const access = requireEnv("HOT_UPDATER_VERCEL_BLOB_ACCESS");
|
|
53568
|
-
if (access !== "public" && access !== "private") throw new Error("HOT_UPDATER_VERCEL_BLOB_ACCESS must be \"public\" or \"private\".");
|
|
53569
53566
|
const pool = new import_lib$1.default.Pool({
|
|
53570
53567
|
connectionString: requireEnv("HOT_UPDATER_VERCEL_DATABASE_URL"),
|
|
53571
53568
|
idleTimeoutMillis: 5e3,
|
|
@@ -53579,10 +53576,7 @@ const hotUpdater = createHotUpdater({
|
|
|
53579
53576
|
apiKeys(),
|
|
53580
53577
|
remoteConfig()
|
|
53581
53578
|
],
|
|
53582
|
-
storage: vercelBlobStorage({
|
|
53583
|
-
access,
|
|
53584
|
-
token: requireEnv("HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN")
|
|
53585
|
-
})
|
|
53579
|
+
storage: vercelBlobStorage({ token: requireEnv("HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN") })
|
|
53586
53580
|
});
|
|
53587
53581
|
const handler = async (request) => withoutEncodingVary(await hotUpdater.handlers.client(request));
|
|
53588
53582
|
//#endregion
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
3
3
|
let _vercel_blob = require("@vercel/blob");
|
|
4
|
+
let _hot_updater_postgres = require("@hot-updater/postgres");
|
|
4
5
|
//#region src/vercelBlobStorage.ts
|
|
5
6
|
const PROTOCOL = "vercel-blob";
|
|
6
7
|
const ONE_YEAR_IN_SECONDS = 31536e3;
|
|
@@ -61,14 +62,15 @@ const storeIdOf = (token) => {
|
|
|
61
62
|
if (prefix !== "vercel" || kind !== "blob" || rw !== "rw" || !id) throw new Error("vercelBlobStorage needs the store's read-write token (vercel_blob_rw_...).");
|
|
62
63
|
return `store_${id}`;
|
|
63
64
|
};
|
|
65
|
+
/** A private store's objects: only an API key holder's signed URL reaches them. */
|
|
66
|
+
const access = "private";
|
|
64
67
|
/**
|
|
65
|
-
* Bundles in a Vercel Blob store.
|
|
66
|
-
*
|
|
68
|
+
* Bundles in a private Vercel Blob store. Devices download from presigned URLs
|
|
69
|
+
* that expire, so the store's objects never sit at a public address.
|
|
67
70
|
*/
|
|
68
71
|
const vercelBlobStorage = (config) => {
|
|
69
|
-
const { token
|
|
72
|
+
const { token } = config;
|
|
70
73
|
const storeId = storeIdOf(token);
|
|
71
|
-
const host = `${storeId.slice(6).toLowerCase()}.${access}.blob.vercel-storage.com`;
|
|
72
74
|
const normalizedBasePath = config.basePath?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
73
75
|
const getStorageKey = (0, _hot_updater_plugin_core.createStorageKeyBuilder)(normalizedBasePath);
|
|
74
76
|
const expiresIn = config.signedUrlExpiresIn ?? 3600;
|
|
@@ -139,7 +141,6 @@ const vercelBlobStorage = (config) => {
|
|
|
139
141
|
async getDownloadUrl({ storageUri }) {
|
|
140
142
|
const { key } = parseAndValidate(storageUri);
|
|
141
143
|
const pathname = toPathname(key);
|
|
142
|
-
if (access === "public") return { url: `https://${host}/${pathname.split("/").map(encodeURIComponent).join("/")}` };
|
|
143
144
|
const validUntil = Date.now() + expiresInMs;
|
|
144
145
|
const { presignedUrl } = await (0, _vercel_blob.presignUrl)(await delegationUntil(validUntil), {
|
|
145
146
|
access,
|
|
@@ -205,4 +206,10 @@ const vercelBlobStorage = (config) => {
|
|
|
205
206
|
});
|
|
206
207
|
};
|
|
207
208
|
//#endregion
|
|
209
|
+
Object.defineProperty(exports, "postgres", {
|
|
210
|
+
enumerable: true,
|
|
211
|
+
get: function() {
|
|
212
|
+
return _hot_updater_postgres.postgres;
|
|
213
|
+
}
|
|
214
|
+
});
|
|
208
215
|
exports.vercelBlobStorage = vercelBlobStorage;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { StorageAdapterWith } from "@hot-updater/plugin-core";
|
|
2
|
+
import { PostgresConfig, postgres } from "@hot-updater/postgres";
|
|
2
3
|
//#region src/vercelBlobStorage.d.ts
|
|
3
4
|
interface VercelBlobStorageConfig {
|
|
4
5
|
/**
|
|
@@ -6,21 +7,19 @@ interface VercelBlobStorageConfig {
|
|
|
6
7
|
* the `BLOB_READ_WRITE_TOKEN` Vercel adds to a project the store connects to.
|
|
7
8
|
*/
|
|
8
9
|
token: string;
|
|
9
|
-
/** The store's access, which Vercel fixes when it creates the store. */
|
|
10
|
-
access: "public" | "private";
|
|
11
10
|
/** Base path where bundles will be stored in the store. */
|
|
12
11
|
basePath?: string;
|
|
13
12
|
/**
|
|
14
|
-
* Lifetime of
|
|
15
|
-
*
|
|
13
|
+
* Lifetime of the download URLs in seconds, at most seven days, Vercel's
|
|
14
|
+
* limit. @default 3600
|
|
16
15
|
*/
|
|
17
16
|
signedUrlExpiresIn?: number;
|
|
18
17
|
}
|
|
19
18
|
type VercelBlobStorageOperations = "put" | "get" | "getDownloadUrl" | "exists" | "delete" | "listObjects" | "deleteObjects";
|
|
20
19
|
/**
|
|
21
|
-
* Bundles in a Vercel Blob store.
|
|
22
|
-
*
|
|
20
|
+
* Bundles in a private Vercel Blob store. Devices download from presigned URLs
|
|
21
|
+
* that expire, so the store's objects never sit at a public address.
|
|
23
22
|
*/
|
|
24
23
|
declare const vercelBlobStorage: (config: VercelBlobStorageConfig) => StorageAdapterWith<VercelBlobStorageOperations>;
|
|
25
24
|
//#endregion
|
|
26
|
-
export { VercelBlobStorageConfig, vercelBlobStorage };
|
|
25
|
+
export { type PostgresConfig, VercelBlobStorageConfig, postgres, vercelBlobStorage };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { StorageAdapterWith } from "@hot-updater/plugin-core";
|
|
2
|
+
import { PostgresConfig, postgres } from "@hot-updater/postgres";
|
|
2
3
|
//#region src/vercelBlobStorage.d.ts
|
|
3
4
|
interface VercelBlobStorageConfig {
|
|
4
5
|
/**
|
|
@@ -6,21 +7,19 @@ interface VercelBlobStorageConfig {
|
|
|
6
7
|
* the `BLOB_READ_WRITE_TOKEN` Vercel adds to a project the store connects to.
|
|
7
8
|
*/
|
|
8
9
|
token: string;
|
|
9
|
-
/** The store's access, which Vercel fixes when it creates the store. */
|
|
10
|
-
access: "public" | "private";
|
|
11
10
|
/** Base path where bundles will be stored in the store. */
|
|
12
11
|
basePath?: string;
|
|
13
12
|
/**
|
|
14
|
-
* Lifetime of
|
|
15
|
-
*
|
|
13
|
+
* Lifetime of the download URLs in seconds, at most seven days, Vercel's
|
|
14
|
+
* limit. @default 3600
|
|
16
15
|
*/
|
|
17
16
|
signedUrlExpiresIn?: number;
|
|
18
17
|
}
|
|
19
18
|
type VercelBlobStorageOperations = "put" | "get" | "getDownloadUrl" | "exists" | "delete" | "listObjects" | "deleteObjects";
|
|
20
19
|
/**
|
|
21
|
-
* Bundles in a Vercel Blob store.
|
|
22
|
-
*
|
|
20
|
+
* Bundles in a private Vercel Blob store. Devices download from presigned URLs
|
|
21
|
+
* that expire, so the store's objects never sit at a public address.
|
|
23
22
|
*/
|
|
24
23
|
declare const vercelBlobStorage: (config: VercelBlobStorageConfig) => StorageAdapterWith<VercelBlobStorageOperations>;
|
|
25
24
|
//#endregion
|
|
26
|
-
export { VercelBlobStorageConfig, vercelBlobStorage };
|
|
25
|
+
export { type PostgresConfig, VercelBlobStorageConfig, postgres, vercelBlobStorage };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createStorageAdapter, createStorageKeyBuilder, createStorageUri, parseStorageUri } from "@hot-updater/plugin-core";
|
|
2
2
|
import { BlobNotFoundError, del, get, head, issueSignedToken, list, presignUrl, put } from "@vercel/blob";
|
|
3
|
+
import { postgres } from "@hot-updater/postgres";
|
|
3
4
|
//#region src/vercelBlobStorage.ts
|
|
4
5
|
const PROTOCOL = "vercel-blob";
|
|
5
6
|
const ONE_YEAR_IN_SECONDS = 31536e3;
|
|
@@ -60,14 +61,15 @@ const storeIdOf = (token) => {
|
|
|
60
61
|
if (prefix !== "vercel" || kind !== "blob" || rw !== "rw" || !id) throw new Error("vercelBlobStorage needs the store's read-write token (vercel_blob_rw_...).");
|
|
61
62
|
return `store_${id}`;
|
|
62
63
|
};
|
|
64
|
+
/** A private store's objects: only an API key holder's signed URL reaches them. */
|
|
65
|
+
const access = "private";
|
|
63
66
|
/**
|
|
64
|
-
* Bundles in a Vercel Blob store.
|
|
65
|
-
*
|
|
67
|
+
* Bundles in a private Vercel Blob store. Devices download from presigned URLs
|
|
68
|
+
* that expire, so the store's objects never sit at a public address.
|
|
66
69
|
*/
|
|
67
70
|
const vercelBlobStorage = (config) => {
|
|
68
|
-
const { token
|
|
71
|
+
const { token } = config;
|
|
69
72
|
const storeId = storeIdOf(token);
|
|
70
|
-
const host = `${storeId.slice(6).toLowerCase()}.${access}.blob.vercel-storage.com`;
|
|
71
73
|
const normalizedBasePath = config.basePath?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
72
74
|
const getStorageKey = createStorageKeyBuilder(normalizedBasePath);
|
|
73
75
|
const expiresIn = config.signedUrlExpiresIn ?? 3600;
|
|
@@ -138,7 +140,6 @@ const vercelBlobStorage = (config) => {
|
|
|
138
140
|
async getDownloadUrl({ storageUri }) {
|
|
139
141
|
const { key } = parseAndValidate(storageUri);
|
|
140
142
|
const pathname = toPathname(key);
|
|
141
|
-
if (access === "public") return { url: `https://${host}/${pathname.split("/").map(encodeURIComponent).join("/")}` };
|
|
142
143
|
const validUntil = Date.now() + expiresInMs;
|
|
143
144
|
const { presignedUrl } = await presignUrl(await delegationUntil(validUntil), {
|
|
144
145
|
access,
|
|
@@ -204,4 +205,4 @@ const vercelBlobStorage = (config) => {
|
|
|
204
205
|
});
|
|
205
206
|
};
|
|
206
207
|
//#endregion
|
|
207
|
-
export { vercelBlobStorage };
|
|
208
|
+
export { postgres, vercelBlobStorage };
|
package/dist/init/index.cjs
CHANGED
|
@@ -6276,14 +6276,10 @@ const getConfigScaffold = (build) => {
|
|
|
6276
6276
|
}],
|
|
6277
6277
|
configString: `vercelBlobStorage({
|
|
6278
6278
|
token: process.env.HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN!,
|
|
6279
|
-
access:
|
|
6280
|
-
process.env.HOT_UPDATER_VERCEL_BLOB_ACCESS === "public"
|
|
6281
|
-
? "public"
|
|
6282
|
-
: "private",
|
|
6283
6279
|
})`
|
|
6284
6280
|
}).setDatabase({
|
|
6285
6281
|
imports: [{
|
|
6286
|
-
pkg: "@hot-updater/
|
|
6282
|
+
pkg: "@hot-updater/vercel",
|
|
6287
6283
|
named: ["postgres"]
|
|
6288
6284
|
}],
|
|
6289
6285
|
configString: `postgres({
|
|
@@ -6310,7 +6306,6 @@ const getConfigScaffold = (build) => {
|
|
|
6310
6306
|
const isVercelProjectName = (value) => value !== void 0 && /^[a-z0-9][a-z0-9._-]{0,99}$/.test(value) && !value.includes("---");
|
|
6311
6307
|
/** A Blob store name: letters, digits, `_`, and `-`. */
|
|
6312
6308
|
const isVercelBlobStoreName = (value) => value !== void 0 && /^[A-Za-z0-9][A-Za-z0-9_-]{0,31}$/.test(value);
|
|
6313
|
-
const isVercelBlobAccess = (value) => value === "public" || value === "private";
|
|
6314
6309
|
const isPostgresUrl = (value) => {
|
|
6315
6310
|
if (value === void 0) return false;
|
|
6316
6311
|
try {
|
|
@@ -6363,16 +6358,6 @@ const initProvider = {
|
|
|
6363
6358
|
help: "Blob store ID (store_...), saved by init",
|
|
6364
6359
|
optional: true
|
|
6365
6360
|
},
|
|
6366
|
-
blobAccess: {
|
|
6367
|
-
envKey: "HOT_UPDATER_VERCEL_BLOB_ACCESS",
|
|
6368
|
-
help: "The Blob store's access: private (the default) or public",
|
|
6369
|
-
optional: true,
|
|
6370
|
-
prompt: {
|
|
6371
|
-
message: "Make the new Blob store private?",
|
|
6372
|
-
type: "confirm"
|
|
6373
|
-
},
|
|
6374
|
-
validate: isVercelBlobAccess
|
|
6375
|
-
},
|
|
6376
6361
|
blobReadWriteToken: {
|
|
6377
6362
|
envKey: "HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN",
|
|
6378
6363
|
help: "The Blob store's read-write token, which init reads from the project",
|
|
@@ -6551,6 +6536,10 @@ const createVercelApi = ({ token, teamId, fetch: fetchImpl = fetch }) => {
|
|
|
6551
6536
|
envVarPrefix: input.envVarPrefix
|
|
6552
6537
|
} });
|
|
6553
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
|
+
},
|
|
6554
6543
|
async listProjectEnv(projectId) {
|
|
6555
6544
|
return (await paginate(`/v10/projects/${encodeURIComponent(projectId)}/env`, "envs")).flatMap((env) => isRecord(env) && typeof env.id === "string" && typeof env.key === "string" ? [{
|
|
6556
6545
|
id: env.id,
|
|
@@ -6791,7 +6780,6 @@ const inputs = initProvider.inputs;
|
|
|
6791
6780
|
const BLOB_ENV_PREFIX = "HOT_UPDATER_VERCEL_BLOB";
|
|
6792
6781
|
const BLOB_TOKEN_ENV = inputs.blobReadWriteToken.envKey;
|
|
6793
6782
|
const DATABASE_URL_ENV = inputs.databaseUrl.envKey;
|
|
6794
|
-
const BLOB_ACCESS_ENV = inputs.blobAccess.envKey;
|
|
6795
6783
|
/** Project env vars a Marketplace Postgres database adds, such as Neon's `DATABASE_URL`. */
|
|
6796
6784
|
const DATABASE_URL_ENV_PATTERN = /(?:^|_)(?:DATABASE_URL|POSTGRES_URL)$/;
|
|
6797
6785
|
const cancelled = (value) => _hot_updater_cli_tools.p.isCancel(value);
|
|
@@ -6849,10 +6837,39 @@ const resolveProjectName = async (savedName, nonInteractive) => {
|
|
|
6849
6837
|
validate: (value) => isVercelProjectName(value) ? void 0 : "Use up to 100 lowercase letters, digits, '.', '_', or '-', without '---'."
|
|
6850
6838
|
}));
|
|
6851
6839
|
};
|
|
6852
|
-
/**
|
|
6840
|
+
/**
|
|
6841
|
+
* The saved store, or one the user selects or creates; `replaces` is a saved
|
|
6842
|
+
* public store the selection takes the place of.
|
|
6843
|
+
*/
|
|
6853
6844
|
const selectBlobStore = async ({ nonInteractive, savedId, savedName, stores }) => {
|
|
6854
|
-
const
|
|
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
|
+
const privateStores = stores.filter((store) => store.access === "private");
|
|
6855
6850
|
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
|
+
}
|
|
6856
6873
|
if (saved) return {
|
|
6857
6874
|
kind: "existing",
|
|
6858
6875
|
store: saved
|
|
@@ -6863,42 +6880,43 @@ const selectBlobStore = async ({ nonInteractive, savedId, savedName, stores }) =
|
|
|
6863
6880
|
};
|
|
6864
6881
|
throw new _hot_updater_cli_tools.InitError(`${inputs.blobStoreName.envKey} is required to select the Blob store.`);
|
|
6865
6882
|
}
|
|
6866
|
-
if (
|
|
6883
|
+
if (publicStore) {
|
|
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.");
|
|
6867
6890
|
const createKey = "\0create";
|
|
6868
6891
|
const selected = exitIfCancelled(await _hot_updater_cli_tools.p.select({
|
|
6869
6892
|
message: "Select the Blob store for bundles",
|
|
6870
|
-
initialValue: saved?.id ??
|
|
6871
|
-
options: [...
|
|
6893
|
+
initialValue: saved?.id ?? privateStores[0]?.id ?? createKey,
|
|
6894
|
+
options: [...privateStores.map((store) => ({
|
|
6872
6895
|
value: store.id,
|
|
6873
|
-
label: `${store.name}
|
|
6896
|
+
label: `${store.name}${store.region ? ` (${store.region})` : ""}`
|
|
6874
6897
|
})), {
|
|
6875
6898
|
value: createKey,
|
|
6876
6899
|
label: "Create a new Blob store"
|
|
6877
6900
|
}]
|
|
6878
6901
|
}));
|
|
6879
|
-
const store =
|
|
6902
|
+
const store = privateStores.find((candidate) => candidate.id === selected);
|
|
6903
|
+
const replaces = publicStore ? { replaces: publicStore } : {};
|
|
6880
6904
|
if (store) return {
|
|
6881
6905
|
kind: "existing",
|
|
6882
|
-
store
|
|
6906
|
+
store,
|
|
6907
|
+
...replaces
|
|
6883
6908
|
};
|
|
6884
6909
|
const prompt = inputs.blobStoreName.prompt;
|
|
6885
6910
|
return {
|
|
6886
6911
|
kind: "create",
|
|
6887
6912
|
name: exitIfCancelled(await _hot_updater_cli_tools.p.text({
|
|
6888
|
-
...(0, _hot_updater_cli_tools.getInitProviderTextPromptValues)(prompt, savedName),
|
|
6913
|
+
...(0, _hot_updater_cli_tools.getInitProviderTextPromptValues)(prompt, savedName === publicStore?.name ? void 0 : savedName),
|
|
6889
6914
|
message: prompt.message,
|
|
6890
6915
|
validate: (value) => isVercelBlobStoreName(value) ? void 0 : "Use up to 32 letters, digits, '_', or '-'."
|
|
6891
|
-
}))
|
|
6916
|
+
})),
|
|
6917
|
+
...replaces
|
|
6892
6918
|
};
|
|
6893
6919
|
};
|
|
6894
|
-
const resolveNewStoreAccess = async (savedAccess, nonInteractive) => {
|
|
6895
|
-
if (isVercelBlobAccess(savedAccess) && nonInteractive) return savedAccess;
|
|
6896
|
-
if (nonInteractive) return "private";
|
|
6897
|
-
return exitIfCancelled(await _hot_updater_cli_tools.p.confirm({
|
|
6898
|
-
message: inputs.blobAccess.prompt.message,
|
|
6899
|
-
initialValue: savedAccess !== "public"
|
|
6900
|
-
})) ? "private" : "public";
|
|
6901
|
-
};
|
|
6902
6920
|
/**
|
|
6903
6921
|
* The store's read-write token: from its connection to the project, which
|
|
6904
6922
|
* init makes when there is none.
|
|
@@ -6917,6 +6935,7 @@ const resolveBlobToken = async (api, project, store) => {
|
|
|
6917
6935
|
const env = (await api.listProjectEnv(project.id)).find((candidate) => candidate.key === tokenEnv && candidate.target.includes("production"));
|
|
6918
6936
|
const token = env === void 0 ? void 0 : await api.getProjectEnvValue(project.id, env.id);
|
|
6919
6937
|
if (!token?.startsWith("vercel_blob_rw_")) throw new _hot_updater_cli_tools.InitError(`Blob store ${store.name} is connected to project ${project.name} without a read-write token for production. Reconnect it from the project's Storage tab with a read-write token, then rerun init.`);
|
|
6938
|
+
if (`store_${token.split("_")[3]}` !== store.id) throw new _hot_updater_cli_tools.InitError(`The production ${tokenEnv} of project ${project.name} belongs to another Blob store, not ${store.name}. Disconnect that store from the project's Storage tab, then rerun init.`);
|
|
6920
6939
|
return token;
|
|
6921
6940
|
};
|
|
6922
6941
|
/**
|
|
@@ -7051,7 +7070,6 @@ const runInit = async ({ build, envFile }) => {
|
|
|
7051
7070
|
...saved.blobStoreId ? { savedId: saved.blobStoreId } : {},
|
|
7052
7071
|
...saved.blobStoreName ? { savedName: saved.blobStoreName } : {}
|
|
7053
7072
|
});
|
|
7054
|
-
const newStoreAccess = storeSelection.kind === "create" ? await resolveNewStoreAccess(saved.blobAccess, nonInteractive) : void 0;
|
|
7055
7073
|
let databaseUrl = nonInteractive ? saved.databaseUrl : void 0;
|
|
7056
7074
|
if (nonInteractive && !isPostgresUrl(databaseUrl)) throw new _hot_updater_cli_tools.InitError(`${DATABASE_URL_ENV} must be a postgres:// or postgresql:// URL.`);
|
|
7057
7075
|
const project = existingProject ?? await (async () => {
|
|
@@ -7068,28 +7086,31 @@ const runInit = async ({ build, envFile }) => {
|
|
|
7068
7086
|
...saved.databaseUrl ? { savedUrl: saved.databaseUrl } : {}
|
|
7069
7087
|
});
|
|
7070
7088
|
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
|
+
}
|
|
7071
7094
|
let store;
|
|
7072
7095
|
if (storeSelection.kind === "existing") {
|
|
7073
7096
|
store = storeSelection.store;
|
|
7074
7097
|
_hot_updater_cli_tools.p.log.info(`Selected Blob store: ${store.name}`);
|
|
7075
7098
|
} else {
|
|
7076
|
-
const access = newStoreAccess ?? "private";
|
|
7077
7099
|
const { id } = await api.createBlobStore({
|
|
7078
|
-
access,
|
|
7100
|
+
access: "private",
|
|
7079
7101
|
name: storeSelection.name
|
|
7080
7102
|
});
|
|
7081
7103
|
store = {
|
|
7082
|
-
access,
|
|
7104
|
+
access: "private",
|
|
7083
7105
|
connections: [],
|
|
7084
7106
|
id,
|
|
7085
7107
|
name: storeSelection.name,
|
|
7086
7108
|
region: void 0
|
|
7087
7109
|
};
|
|
7088
|
-
_hot_updater_cli_tools.p.log.info(`Created Blob store: ${store.name} (
|
|
7110
|
+
_hot_updater_cli_tools.p.log.info(`Created Blob store: ${store.name} (private)`);
|
|
7089
7111
|
}
|
|
7090
7112
|
const blobToken = await resolveBlobToken(api, project, store);
|
|
7091
7113
|
const resolvedInputs = {
|
|
7092
|
-
blobAccess: store.access,
|
|
7093
7114
|
blobReadWriteToken: blobToken,
|
|
7094
7115
|
blobStoreId: store.id,
|
|
7095
7116
|
blobStoreName: store.name,
|
|
@@ -7124,7 +7145,6 @@ const runInit = async ({ build, envFile }) => {
|
|
|
7124
7145
|
title: "Setting the Function's environment variables...",
|
|
7125
7146
|
task: async () => {
|
|
7126
7147
|
await api.setProductionEnv(project.id, DATABASE_URL_ENV, databaseUrl);
|
|
7127
|
-
await api.setProductionEnv(project.id, BLOB_ACCESS_ENV, store.access);
|
|
7128
7148
|
await syncFunctionBlobToken(api, project, store, blobToken);
|
|
7129
7149
|
return "Set the Function's environment variables";
|
|
7130
7150
|
}
|
package/dist/init/index.d.cts
CHANGED
|
@@ -43,16 +43,6 @@ declare const initProvider: {
|
|
|
43
43
|
readonly help: "Blob store ID (store_...), saved by init";
|
|
44
44
|
readonly optional: true;
|
|
45
45
|
};
|
|
46
|
-
readonly blobAccess: {
|
|
47
|
-
readonly envKey: "HOT_UPDATER_VERCEL_BLOB_ACCESS";
|
|
48
|
-
readonly help: "The Blob store's access: private (the default) or public";
|
|
49
|
-
readonly optional: true;
|
|
50
|
-
readonly prompt: {
|
|
51
|
-
readonly message: "Make the new Blob store private?";
|
|
52
|
-
readonly type: "confirm";
|
|
53
|
-
};
|
|
54
|
-
readonly validate: (value: string | undefined) => value is "public" | "private";
|
|
55
|
-
};
|
|
56
46
|
readonly blobReadWriteToken: {
|
|
57
47
|
readonly envKey: "HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN";
|
|
58
48
|
readonly help: "The Blob store's read-write token, which init reads from the project";
|
package/dist/init/index.d.mts
CHANGED
|
@@ -43,16 +43,6 @@ declare const initProvider: {
|
|
|
43
43
|
readonly help: "Blob store ID (store_...), saved by init";
|
|
44
44
|
readonly optional: true;
|
|
45
45
|
};
|
|
46
|
-
readonly blobAccess: {
|
|
47
|
-
readonly envKey: "HOT_UPDATER_VERCEL_BLOB_ACCESS";
|
|
48
|
-
readonly help: "The Blob store's access: private (the default) or public";
|
|
49
|
-
readonly optional: true;
|
|
50
|
-
readonly prompt: {
|
|
51
|
-
readonly message: "Make the new Blob store private?";
|
|
52
|
-
readonly type: "confirm";
|
|
53
|
-
};
|
|
54
|
-
readonly validate: (value: string | undefined) => value is "public" | "private";
|
|
55
|
-
};
|
|
56
46
|
readonly blobReadWriteToken: {
|
|
57
47
|
readonly envKey: "HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN";
|
|
58
48
|
readonly help: "The Blob store's read-write token, which init reads from the project";
|
package/dist/init/index.mjs
CHANGED
|
@@ -6270,14 +6270,10 @@ const getConfigScaffold = (build) => {
|
|
|
6270
6270
|
}],
|
|
6271
6271
|
configString: `vercelBlobStorage({
|
|
6272
6272
|
token: process.env.HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN!,
|
|
6273
|
-
access:
|
|
6274
|
-
process.env.HOT_UPDATER_VERCEL_BLOB_ACCESS === "public"
|
|
6275
|
-
? "public"
|
|
6276
|
-
: "private",
|
|
6277
6273
|
})`
|
|
6278
6274
|
}).setDatabase({
|
|
6279
6275
|
imports: [{
|
|
6280
|
-
pkg: "@hot-updater/
|
|
6276
|
+
pkg: "@hot-updater/vercel",
|
|
6281
6277
|
named: ["postgres"]
|
|
6282
6278
|
}],
|
|
6283
6279
|
configString: `postgres({
|
|
@@ -6304,7 +6300,6 @@ const getConfigScaffold = (build) => {
|
|
|
6304
6300
|
const isVercelProjectName = (value) => value !== void 0 && /^[a-z0-9][a-z0-9._-]{0,99}$/.test(value) && !value.includes("---");
|
|
6305
6301
|
/** A Blob store name: letters, digits, `_`, and `-`. */
|
|
6306
6302
|
const isVercelBlobStoreName = (value) => value !== void 0 && /^[A-Za-z0-9][A-Za-z0-9_-]{0,31}$/.test(value);
|
|
6307
|
-
const isVercelBlobAccess = (value) => value === "public" || value === "private";
|
|
6308
6303
|
const isPostgresUrl = (value) => {
|
|
6309
6304
|
if (value === void 0) return false;
|
|
6310
6305
|
try {
|
|
@@ -6357,16 +6352,6 @@ const initProvider = {
|
|
|
6357
6352
|
help: "Blob store ID (store_...), saved by init",
|
|
6358
6353
|
optional: true
|
|
6359
6354
|
},
|
|
6360
|
-
blobAccess: {
|
|
6361
|
-
envKey: "HOT_UPDATER_VERCEL_BLOB_ACCESS",
|
|
6362
|
-
help: "The Blob store's access: private (the default) or public",
|
|
6363
|
-
optional: true,
|
|
6364
|
-
prompt: {
|
|
6365
|
-
message: "Make the new Blob store private?",
|
|
6366
|
-
type: "confirm"
|
|
6367
|
-
},
|
|
6368
|
-
validate: isVercelBlobAccess
|
|
6369
|
-
},
|
|
6370
6355
|
blobReadWriteToken: {
|
|
6371
6356
|
envKey: "HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN",
|
|
6372
6357
|
help: "The Blob store's read-write token, which init reads from the project",
|
|
@@ -6545,6 +6530,10 @@ const createVercelApi = ({ token, teamId, fetch: fetchImpl = fetch }) => {
|
|
|
6545
6530
|
envVarPrefix: input.envVarPrefix
|
|
6546
6531
|
} });
|
|
6547
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
|
+
},
|
|
6548
6537
|
async listProjectEnv(projectId) {
|
|
6549
6538
|
return (await paginate(`/v10/projects/${encodeURIComponent(projectId)}/env`, "envs")).flatMap((env) => isRecord(env) && typeof env.id === "string" && typeof env.key === "string" ? [{
|
|
6550
6539
|
id: env.id,
|
|
@@ -6785,7 +6774,6 @@ const inputs = initProvider.inputs;
|
|
|
6785
6774
|
const BLOB_ENV_PREFIX = "HOT_UPDATER_VERCEL_BLOB";
|
|
6786
6775
|
const BLOB_TOKEN_ENV = inputs.blobReadWriteToken.envKey;
|
|
6787
6776
|
const DATABASE_URL_ENV = inputs.databaseUrl.envKey;
|
|
6788
|
-
const BLOB_ACCESS_ENV = inputs.blobAccess.envKey;
|
|
6789
6777
|
/** Project env vars a Marketplace Postgres database adds, such as Neon's `DATABASE_URL`. */
|
|
6790
6778
|
const DATABASE_URL_ENV_PATTERN = /(?:^|_)(?:DATABASE_URL|POSTGRES_URL)$/;
|
|
6791
6779
|
const cancelled = (value) => p.isCancel(value);
|
|
@@ -6843,10 +6831,39 @@ const resolveProjectName = async (savedName, nonInteractive) => {
|
|
|
6843
6831
|
validate: (value) => isVercelProjectName(value) ? void 0 : "Use up to 100 lowercase letters, digits, '.', '_', or '-', without '---'."
|
|
6844
6832
|
}));
|
|
6845
6833
|
};
|
|
6846
|
-
/**
|
|
6834
|
+
/**
|
|
6835
|
+
* The saved store, or one the user selects or creates; `replaces` is a saved
|
|
6836
|
+
* public store the selection takes the place of.
|
|
6837
|
+
*/
|
|
6847
6838
|
const selectBlobStore = async ({ nonInteractive, savedId, savedName, stores }) => {
|
|
6848
|
-
const
|
|
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
|
+
const privateStores = stores.filter((store) => store.access === "private");
|
|
6849
6844
|
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
|
+
}
|
|
6850
6867
|
if (saved) return {
|
|
6851
6868
|
kind: "existing",
|
|
6852
6869
|
store: saved
|
|
@@ -6857,42 +6874,43 @@ const selectBlobStore = async ({ nonInteractive, savedId, savedName, stores }) =
|
|
|
6857
6874
|
};
|
|
6858
6875
|
throw new InitError(`${inputs.blobStoreName.envKey} is required to select the Blob store.`);
|
|
6859
6876
|
}
|
|
6860
|
-
if (
|
|
6877
|
+
if (publicStore) {
|
|
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.");
|
|
6861
6884
|
const createKey = "\0create";
|
|
6862
6885
|
const selected = exitIfCancelled(await p.select({
|
|
6863
6886
|
message: "Select the Blob store for bundles",
|
|
6864
|
-
initialValue: saved?.id ??
|
|
6865
|
-
options: [...
|
|
6887
|
+
initialValue: saved?.id ?? privateStores[0]?.id ?? createKey,
|
|
6888
|
+
options: [...privateStores.map((store) => ({
|
|
6866
6889
|
value: store.id,
|
|
6867
|
-
label: `${store.name}
|
|
6890
|
+
label: `${store.name}${store.region ? ` (${store.region})` : ""}`
|
|
6868
6891
|
})), {
|
|
6869
6892
|
value: createKey,
|
|
6870
6893
|
label: "Create a new Blob store"
|
|
6871
6894
|
}]
|
|
6872
6895
|
}));
|
|
6873
|
-
const store =
|
|
6896
|
+
const store = privateStores.find((candidate) => candidate.id === selected);
|
|
6897
|
+
const replaces = publicStore ? { replaces: publicStore } : {};
|
|
6874
6898
|
if (store) return {
|
|
6875
6899
|
kind: "existing",
|
|
6876
|
-
store
|
|
6900
|
+
store,
|
|
6901
|
+
...replaces
|
|
6877
6902
|
};
|
|
6878
6903
|
const prompt = inputs.blobStoreName.prompt;
|
|
6879
6904
|
return {
|
|
6880
6905
|
kind: "create",
|
|
6881
6906
|
name: exitIfCancelled(await p.text({
|
|
6882
|
-
...getInitProviderTextPromptValues(prompt, savedName),
|
|
6907
|
+
...getInitProviderTextPromptValues(prompt, savedName === publicStore?.name ? void 0 : savedName),
|
|
6883
6908
|
message: prompt.message,
|
|
6884
6909
|
validate: (value) => isVercelBlobStoreName(value) ? void 0 : "Use up to 32 letters, digits, '_', or '-'."
|
|
6885
|
-
}))
|
|
6910
|
+
})),
|
|
6911
|
+
...replaces
|
|
6886
6912
|
};
|
|
6887
6913
|
};
|
|
6888
|
-
const resolveNewStoreAccess = async (savedAccess, nonInteractive) => {
|
|
6889
|
-
if (isVercelBlobAccess(savedAccess) && nonInteractive) return savedAccess;
|
|
6890
|
-
if (nonInteractive) return "private";
|
|
6891
|
-
return exitIfCancelled(await p.confirm({
|
|
6892
|
-
message: inputs.blobAccess.prompt.message,
|
|
6893
|
-
initialValue: savedAccess !== "public"
|
|
6894
|
-
})) ? "private" : "public";
|
|
6895
|
-
};
|
|
6896
6914
|
/**
|
|
6897
6915
|
* The store's read-write token: from its connection to the project, which
|
|
6898
6916
|
* init makes when there is none.
|
|
@@ -6911,6 +6929,7 @@ const resolveBlobToken = async (api, project, store) => {
|
|
|
6911
6929
|
const env = (await api.listProjectEnv(project.id)).find((candidate) => candidate.key === tokenEnv && candidate.target.includes("production"));
|
|
6912
6930
|
const token = env === void 0 ? void 0 : await api.getProjectEnvValue(project.id, env.id);
|
|
6913
6931
|
if (!token?.startsWith("vercel_blob_rw_")) throw new InitError(`Blob store ${store.name} is connected to project ${project.name} without a read-write token for production. Reconnect it from the project's Storage tab with a read-write token, then rerun init.`);
|
|
6932
|
+
if (`store_${token.split("_")[3]}` !== store.id) throw new InitError(`The production ${tokenEnv} of project ${project.name} belongs to another Blob store, not ${store.name}. Disconnect that store from the project's Storage tab, then rerun init.`);
|
|
6914
6933
|
return token;
|
|
6915
6934
|
};
|
|
6916
6935
|
/**
|
|
@@ -7045,7 +7064,6 @@ const runInit = async ({ build, envFile }) => {
|
|
|
7045
7064
|
...saved.blobStoreId ? { savedId: saved.blobStoreId } : {},
|
|
7046
7065
|
...saved.blobStoreName ? { savedName: saved.blobStoreName } : {}
|
|
7047
7066
|
});
|
|
7048
|
-
const newStoreAccess = storeSelection.kind === "create" ? await resolveNewStoreAccess(saved.blobAccess, nonInteractive) : void 0;
|
|
7049
7067
|
let databaseUrl = nonInteractive ? saved.databaseUrl : void 0;
|
|
7050
7068
|
if (nonInteractive && !isPostgresUrl(databaseUrl)) throw new InitError(`${DATABASE_URL_ENV} must be a postgres:// or postgresql:// URL.`);
|
|
7051
7069
|
const project = existingProject ?? await (async () => {
|
|
@@ -7062,28 +7080,31 @@ const runInit = async ({ build, envFile }) => {
|
|
|
7062
7080
|
...saved.databaseUrl ? { savedUrl: saved.databaseUrl } : {}
|
|
7063
7081
|
});
|
|
7064
7082
|
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
|
+
}
|
|
7065
7088
|
let store;
|
|
7066
7089
|
if (storeSelection.kind === "existing") {
|
|
7067
7090
|
store = storeSelection.store;
|
|
7068
7091
|
p.log.info(`Selected Blob store: ${store.name}`);
|
|
7069
7092
|
} else {
|
|
7070
|
-
const access = newStoreAccess ?? "private";
|
|
7071
7093
|
const { id } = await api.createBlobStore({
|
|
7072
|
-
access,
|
|
7094
|
+
access: "private",
|
|
7073
7095
|
name: storeSelection.name
|
|
7074
7096
|
});
|
|
7075
7097
|
store = {
|
|
7076
|
-
access,
|
|
7098
|
+
access: "private",
|
|
7077
7099
|
connections: [],
|
|
7078
7100
|
id,
|
|
7079
7101
|
name: storeSelection.name,
|
|
7080
7102
|
region: void 0
|
|
7081
7103
|
};
|
|
7082
|
-
p.log.info(`Created Blob store: ${store.name} (
|
|
7104
|
+
p.log.info(`Created Blob store: ${store.name} (private)`);
|
|
7083
7105
|
}
|
|
7084
7106
|
const blobToken = await resolveBlobToken(api, project, store);
|
|
7085
7107
|
const resolvedInputs = {
|
|
7086
|
-
blobAccess: store.access,
|
|
7087
7108
|
blobReadWriteToken: blobToken,
|
|
7088
7109
|
blobStoreId: store.id,
|
|
7089
7110
|
blobStoreName: store.name,
|
|
@@ -7118,7 +7139,6 @@ const runInit = async ({ build, envFile }) => {
|
|
|
7118
7139
|
title: "Setting the Function's environment variables...",
|
|
7119
7140
|
task: async () => {
|
|
7120
7141
|
await api.setProductionEnv(project.id, DATABASE_URL_ENV, databaseUrl);
|
|
7121
|
-
await api.setProductionEnv(project.id, BLOB_ACCESS_ENV, store.access);
|
|
7122
7142
|
await syncFunctionBlobToken(api, project, store, blobToken);
|
|
7123
7143
|
return "Set the Function's environment variables";
|
|
7124
7144
|
}
|
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.4",
|
|
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/postgres": "1.0.
|
|
47
|
-
"@hot-updater/protocol": "1.0.
|
|
48
|
-
"@hot-updater/server": "1.0.
|
|
44
|
+
"@hot-updater/cli-tools": "1.0.4",
|
|
45
|
+
"@hot-updater/plugin-core": "1.0.4",
|
|
46
|
+
"@hot-updater/postgres": "1.0.4",
|
|
47
|
+
"@hot-updater/protocol": "1.0.4",
|
|
48
|
+
"@hot-updater/server": "1.0.4"
|
|
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.4"
|
|
58
58
|
},
|
|
59
59
|
"scripts": {
|
|
60
60
|
"build": "tsdown",
|