@hot-updater/vercel 1.2.0-rc.4 → 1.2.0-rc.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.
@@ -17667,6 +17667,7 @@ var import_lib$1 = /* @__PURE__ */ __toESM(require_lib$2(), 1);
17667
17667
  const { Pool } = import_lib$1.default;
17668
17668
  const DATABASE_TARGET = Symbol.for("@hot-updater/database-target");
17669
17669
  const targetOf = ({ connectionString, host, port, database }) => {
17670
+ if (typeof connectionString === "function") return void 0;
17670
17671
  if (connectionString !== void 0) try {
17671
17672
  const url = new URL(connectionString);
17672
17673
  return `postgres/${url.hostname}:${url.port || "5432"}/${decodeURIComponent(url.pathname.slice(1))}`;
@@ -17678,7 +17679,14 @@ const targetOf = ({ connectionString, host, port, database }) => {
17678
17679
  const postgres = (config) => {
17679
17680
  const { dialect, ...poolConfig } = config;
17680
17681
  const target = targetOf(poolConfig);
17681
- const db = new Kysely({ dialect: dialect ?? new PostgresDialect({ pool: new Pool(poolConfig) }) });
17682
+ const { connectionString } = poolConfig;
17683
+ const db = new Kysely({ dialect: dialect ?? new PostgresDialect({ pool: typeof connectionString === "function" ? async () => new Pool({
17684
+ ...poolConfig,
17685
+ connectionString: await connectionString()
17686
+ }) : new Pool({
17687
+ ...poolConfig,
17688
+ connectionString
17689
+ }) }) });
17682
17690
  return {
17683
17691
  ...createEngineDatabase({
17684
17692
  name: "postgres",
@@ -17690,7 +17698,7 @@ const postgres = (config) => {
17690
17698
  };
17691
17699
  //#endregion
17692
17700
  //#region ../../packages/server/dist/version.mjs
17693
- const HOT_UPDATER_SERVER_VERSION = "1.2.0-rc.4";
17701
+ const HOT_UPDATER_SERVER_VERSION = "1.2.0-rc.6";
17694
17702
  //#endregion
17695
17703
  //#region ../../packages/server/dist/handlerVersionRoutes.mjs
17696
17704
  const createVersionRouteHandlers = (plugins = []) => {
@@ -53985,9 +53993,17 @@ const storeIdOf = (token) => {
53985
53993
  };
53986
53994
  const access = "private";
53987
53995
  const vercelBlobStorage = (config) => {
53988
- const { token } = config;
53989
- let store;
53990
- const storeId = () => store ??= storeIdOf(token);
53996
+ let resolved;
53997
+ const store = () => resolved ??= (async () => {
53998
+ const token = typeof config.token === "function" ? await config.token() : config.token;
53999
+ return {
54000
+ token,
54001
+ storeId: storeIdOf(token)
54002
+ };
54003
+ })().catch((error) => {
54004
+ resolved = void 0;
54005
+ throw error;
54006
+ });
53991
54007
  const normalizedBasePath = config.basePath?.replace(/^\/+|\/+$/g, "") ?? "";
53992
54008
  const getStorageKey = createStorageKeyBuilder(normalizedBasePath);
53993
54009
  const expiresIn = config.signedUrlExpiresIn ?? 3600;
@@ -53997,6 +54013,7 @@ const vercelBlobStorage = (config) => {
53997
54013
  const delegationUntil = async (validUntil) => {
53998
54014
  const current = await delegation?.catch(() => void 0);
53999
54015
  if (current !== void 0 && current.validUntil >= validUntil) return current;
54016
+ const { token } = await store();
54000
54017
  const issued = issueSignedToken({
54001
54018
  token,
54002
54019
  operations: ["get"],
@@ -54005,10 +54022,14 @@ const vercelBlobStorage = (config) => {
54005
54022
  delegation = issued;
54006
54023
  return issued;
54007
54024
  };
54008
- const parseAndValidate = (storageUri) => {
54025
+ const parseAndValidate = async (storageUri) => {
54009
54026
  const parsed = parseStorageUri(storageUri, PROTOCOL);
54010
- if (parsed.bucket !== storeId()) throw new Error(`Blob store mismatch: expected "${storeId()}", but found "${parsed.bucket}".`);
54011
- return parsed;
54027
+ const { token, storeId } = await store();
54028
+ if (parsed.bucket !== storeId) throw new Error(`Blob store mismatch: expected "${storeId}", but found "${parsed.bucket}".`);
54029
+ return {
54030
+ ...parsed,
54031
+ token
54032
+ };
54012
54033
  };
54013
54034
  const getListPrefix = (prefix = "") => {
54014
54035
  const value = [normalizedBasePath, prefix.replace(/^\/+|\/+$/g, "")].filter(Boolean).join("/");
@@ -54024,9 +54045,10 @@ const vercelBlobStorage = (config) => {
54024
54045
  protocol: PROTOCOL,
54025
54046
  async put({ key, body, contentLength, contentType }) {
54026
54047
  const storageKey = getStorageKey(key);
54048
+ const { token, storeId } = await store();
54027
54049
  const storageUri = createStorageUri({
54028
54050
  protocol: PROTOCOL,
54029
- bucket: storeId(),
54051
+ bucket: storeId,
54030
54052
  key: storageKey
54031
54053
  });
54032
54054
  await put(toPathname(storageKey), body, {
@@ -54041,7 +54063,7 @@ const vercelBlobStorage = (config) => {
54041
54063
  return { storageUri };
54042
54064
  },
54043
54065
  async get({ storageUri }) {
54044
- const { key } = parseAndValidate(storageUri);
54066
+ const { key, token } = await parseAndValidate(storageUri);
54045
54067
  const result = await get(toPathname(key), {
54046
54068
  access,
54047
54069
  token,
@@ -54055,7 +54077,7 @@ const vercelBlobStorage = (config) => {
54055
54077
  } }) };
54056
54078
  },
54057
54079
  async getDownloadUrl({ storageUri }) {
54058
- const { key } = parseAndValidate(storageUri);
54080
+ const { key } = await parseAndValidate(storageUri);
54059
54081
  const pathname = toPathname(key);
54060
54082
  const validUntil = Date.now() + expiresInMs;
54061
54083
  const { presignedUrl } = await presignUrl(await delegationUntil(validUntil), {
@@ -54067,7 +54089,7 @@ const vercelBlobStorage = (config) => {
54067
54089
  return { url: presignedUrl };
54068
54090
  },
54069
54091
  async exists({ storageUri }) {
54070
- const { key } = parseAndValidate(storageUri);
54092
+ const { key, token } = await parseAndValidate(storageUri);
54071
54093
  try {
54072
54094
  await head(toPathname(key), { token });
54073
54095
  return { exists: true };
@@ -54077,11 +54099,12 @@ const vercelBlobStorage = (config) => {
54077
54099
  }
54078
54100
  },
54079
54101
  async delete({ storageUri }) {
54080
- const { key } = parseAndValidate(storageUri);
54102
+ const { key, token } = await parseAndValidate(storageUri);
54081
54103
  await del(toPathname(key), { token });
54082
54104
  return { deleted: true };
54083
54105
  },
54084
54106
  async listObjects(prefix) {
54107
+ const { token, storeId } = await store();
54085
54108
  const objects = [];
54086
54109
  let cursor;
54087
54110
  do {
@@ -54098,7 +54121,7 @@ const vercelBlobStorage = (config) => {
54098
54121
  try {
54099
54122
  storageUri = createStorageUri({
54100
54123
  protocol: PROTOCOL,
54101
- bucket: storeId(),
54124
+ bucket: storeId,
54102
54125
  key
54103
54126
  });
54104
54127
  } catch {
@@ -54116,6 +54139,7 @@ const vercelBlobStorage = (config) => {
54116
54139
  return objects;
54117
54140
  },
54118
54141
  async deleteObjects(relativeKeys) {
54142
+ const { token } = await store();
54119
54143
  const pathnames = relativeKeys.map((key) => toPathname(getStorageKey(key)));
54120
54144
  for (let offset = 0; offset < pathnames.length; offset += DELETE_BATCH_SIZE) await del(pathnames.slice(offset, offset + DELETE_BATCH_SIZE), { token });
54121
54145
  }
package/dist/index.cjs CHANGED
@@ -69,9 +69,17 @@ const access = "private";
69
69
  * that expire, so the store's objects never sit at a public address.
70
70
  */
71
71
  const vercelBlobStorage = (config) => {
72
- const { token } = config;
73
- let store;
74
- const storeId = () => store ??= storeIdOf(token);
72
+ let resolved;
73
+ const store = () => resolved ??= (async () => {
74
+ const token = typeof config.token === "function" ? await config.token() : config.token;
75
+ return {
76
+ token,
77
+ storeId: storeIdOf(token)
78
+ };
79
+ })().catch((error) => {
80
+ resolved = void 0;
81
+ throw error;
82
+ });
75
83
  const normalizedBasePath = config.basePath?.replace(/^\/+|\/+$/g, "") ?? "";
76
84
  const getStorageKey = (0, _hot_updater_plugin_core.createStorageKeyBuilder)(normalizedBasePath);
77
85
  const expiresIn = config.signedUrlExpiresIn ?? 3600;
@@ -82,6 +90,7 @@ const vercelBlobStorage = (config) => {
82
90
  const delegationUntil = async (validUntil) => {
83
91
  const current = await delegation?.catch(() => void 0);
84
92
  if (current !== void 0 && current.validUntil >= validUntil) return current;
93
+ const { token } = await store();
85
94
  const issued = (0, _vercel_blob.issueSignedToken)({
86
95
  token,
87
96
  operations: ["get"],
@@ -90,10 +99,14 @@ const vercelBlobStorage = (config) => {
90
99
  delegation = issued;
91
100
  return issued;
92
101
  };
93
- const parseAndValidate = (storageUri) => {
102
+ const parseAndValidate = async (storageUri) => {
94
103
  const parsed = (0, _hot_updater_plugin_core.parseStorageUri)(storageUri, PROTOCOL);
95
- if (parsed.bucket !== storeId()) throw new Error(`Blob store mismatch: expected "${storeId()}", but found "${parsed.bucket}".`);
96
- return parsed;
104
+ const { token, storeId } = await store();
105
+ if (parsed.bucket !== storeId) throw new Error(`Blob store mismatch: expected "${storeId}", but found "${parsed.bucket}".`);
106
+ return {
107
+ ...parsed,
108
+ token
109
+ };
97
110
  };
98
111
  const getListPrefix = (prefix = "") => {
99
112
  const value = [normalizedBasePath, prefix.replace(/^\/+|\/+$/g, "")].filter(Boolean).join("/");
@@ -109,9 +122,10 @@ const vercelBlobStorage = (config) => {
109
122
  protocol: PROTOCOL,
110
123
  async put({ key, body, contentLength, contentType }) {
111
124
  const storageKey = getStorageKey(key);
125
+ const { token, storeId } = await store();
112
126
  const storageUri = (0, _hot_updater_plugin_core.createStorageUri)({
113
127
  protocol: PROTOCOL,
114
- bucket: storeId(),
128
+ bucket: storeId,
115
129
  key: storageKey
116
130
  });
117
131
  await (0, _vercel_blob.put)(toPathname(storageKey), body, {
@@ -126,7 +140,7 @@ const vercelBlobStorage = (config) => {
126
140
  return { storageUri };
127
141
  },
128
142
  async get({ storageUri }) {
129
- const { key } = parseAndValidate(storageUri);
143
+ const { key, token } = await parseAndValidate(storageUri);
130
144
  const result = await (0, _vercel_blob.get)(toPathname(key), {
131
145
  access,
132
146
  token,
@@ -140,7 +154,7 @@ const vercelBlobStorage = (config) => {
140
154
  } }) };
141
155
  },
142
156
  async getDownloadUrl({ storageUri }) {
143
- const { key } = parseAndValidate(storageUri);
157
+ const { key } = await parseAndValidate(storageUri);
144
158
  const pathname = toPathname(key);
145
159
  const validUntil = Date.now() + expiresInMs;
146
160
  const { presignedUrl } = await (0, _vercel_blob.presignUrl)(await delegationUntil(validUntil), {
@@ -152,7 +166,7 @@ const vercelBlobStorage = (config) => {
152
166
  return { url: presignedUrl };
153
167
  },
154
168
  async exists({ storageUri }) {
155
- const { key } = parseAndValidate(storageUri);
169
+ const { key, token } = await parseAndValidate(storageUri);
156
170
  try {
157
171
  await (0, _vercel_blob.head)(toPathname(key), { token });
158
172
  return { exists: true };
@@ -162,11 +176,12 @@ const vercelBlobStorage = (config) => {
162
176
  }
163
177
  },
164
178
  async delete({ storageUri }) {
165
- const { key } = parseAndValidate(storageUri);
179
+ const { key, token } = await parseAndValidate(storageUri);
166
180
  await (0, _vercel_blob.del)(toPathname(key), { token });
167
181
  return { deleted: true };
168
182
  },
169
183
  async listObjects(prefix) {
184
+ const { token, storeId } = await store();
170
185
  const objects = [];
171
186
  let cursor;
172
187
  do {
@@ -183,7 +198,7 @@ const vercelBlobStorage = (config) => {
183
198
  try {
184
199
  storageUri = (0, _hot_updater_plugin_core.createStorageUri)({
185
200
  protocol: PROTOCOL,
186
- bucket: storeId(),
201
+ bucket: storeId,
187
202
  key
188
203
  });
189
204
  } catch {
@@ -201,6 +216,7 @@ const vercelBlobStorage = (config) => {
201
216
  return objects;
202
217
  },
203
218
  async deleteObjects(relativeKeys) {
219
+ const { token } = await store();
204
220
  const pathnames = relativeKeys.map((key) => toPathname(getStorageKey(key)));
205
221
  for (let offset = 0; offset < pathnames.length; offset += DELETE_BATCH_SIZE) await (0, _vercel_blob.del)(pathnames.slice(offset, offset + DELETE_BATCH_SIZE), { token });
206
222
  }
package/dist/index.d.cts CHANGED
@@ -4,9 +4,11 @@ import { PostgresConfig, postgres } from "@hot-updater/postgres";
4
4
  interface VercelBlobStorageConfig {
5
5
  /**
6
6
  * The Blob store's read-write token, `vercel_blob_rw_<storeId>_<secret>`:
7
- * the `BLOB_READ_WRITE_TOKEN` Vercel adds to a project the store connects to.
7
+ * the `BLOB_READ_WRITE_TOKEN` Vercel adds to a project the store connects
8
+ * to. Or a function that returns it, such as one that reads it with
9
+ * `secretEnv`: called on first use, so a config loads without the token.
8
10
  */
9
- token: string;
11
+ token: string | (() => string | Promise<string>);
10
12
  /** Base path where bundles will be stored in the store. */
11
13
  basePath?: string;
12
14
  /**
package/dist/index.d.mts CHANGED
@@ -4,9 +4,11 @@ import { PostgresConfig, postgres } from "@hot-updater/postgres";
4
4
  interface VercelBlobStorageConfig {
5
5
  /**
6
6
  * The Blob store's read-write token, `vercel_blob_rw_<storeId>_<secret>`:
7
- * the `BLOB_READ_WRITE_TOKEN` Vercel adds to a project the store connects to.
7
+ * the `BLOB_READ_WRITE_TOKEN` Vercel adds to a project the store connects
8
+ * to. Or a function that returns it, such as one that reads it with
9
+ * `secretEnv`: called on first use, so a config loads without the token.
8
10
  */
9
- token: string;
11
+ token: string | (() => string | Promise<string>);
10
12
  /** Base path where bundles will be stored in the store. */
11
13
  basePath?: string;
12
14
  /**
package/dist/index.mjs CHANGED
@@ -68,9 +68,17 @@ const access = "private";
68
68
  * that expire, so the store's objects never sit at a public address.
69
69
  */
70
70
  const vercelBlobStorage = (config) => {
71
- const { token } = config;
72
- let store;
73
- const storeId = () => store ??= storeIdOf(token);
71
+ let resolved;
72
+ const store = () => resolved ??= (async () => {
73
+ const token = typeof config.token === "function" ? await config.token() : config.token;
74
+ return {
75
+ token,
76
+ storeId: storeIdOf(token)
77
+ };
78
+ })().catch((error) => {
79
+ resolved = void 0;
80
+ throw error;
81
+ });
74
82
  const normalizedBasePath = config.basePath?.replace(/^\/+|\/+$/g, "") ?? "";
75
83
  const getStorageKey = createStorageKeyBuilder(normalizedBasePath);
76
84
  const expiresIn = config.signedUrlExpiresIn ?? 3600;
@@ -81,6 +89,7 @@ const vercelBlobStorage = (config) => {
81
89
  const delegationUntil = async (validUntil) => {
82
90
  const current = await delegation?.catch(() => void 0);
83
91
  if (current !== void 0 && current.validUntil >= validUntil) return current;
92
+ const { token } = await store();
84
93
  const issued = issueSignedToken({
85
94
  token,
86
95
  operations: ["get"],
@@ -89,10 +98,14 @@ const vercelBlobStorage = (config) => {
89
98
  delegation = issued;
90
99
  return issued;
91
100
  };
92
- const parseAndValidate = (storageUri) => {
101
+ const parseAndValidate = async (storageUri) => {
93
102
  const parsed = parseStorageUri(storageUri, PROTOCOL);
94
- if (parsed.bucket !== storeId()) throw new Error(`Blob store mismatch: expected "${storeId()}", but found "${parsed.bucket}".`);
95
- return parsed;
103
+ const { token, storeId } = await store();
104
+ if (parsed.bucket !== storeId) throw new Error(`Blob store mismatch: expected "${storeId}", but found "${parsed.bucket}".`);
105
+ return {
106
+ ...parsed,
107
+ token
108
+ };
96
109
  };
97
110
  const getListPrefix = (prefix = "") => {
98
111
  const value = [normalizedBasePath, prefix.replace(/^\/+|\/+$/g, "")].filter(Boolean).join("/");
@@ -108,9 +121,10 @@ const vercelBlobStorage = (config) => {
108
121
  protocol: PROTOCOL,
109
122
  async put({ key, body, contentLength, contentType }) {
110
123
  const storageKey = getStorageKey(key);
124
+ const { token, storeId } = await store();
111
125
  const storageUri = createStorageUri({
112
126
  protocol: PROTOCOL,
113
- bucket: storeId(),
127
+ bucket: storeId,
114
128
  key: storageKey
115
129
  });
116
130
  await put(toPathname(storageKey), body, {
@@ -125,7 +139,7 @@ const vercelBlobStorage = (config) => {
125
139
  return { storageUri };
126
140
  },
127
141
  async get({ storageUri }) {
128
- const { key } = parseAndValidate(storageUri);
142
+ const { key, token } = await parseAndValidate(storageUri);
129
143
  const result = await get(toPathname(key), {
130
144
  access,
131
145
  token,
@@ -139,7 +153,7 @@ const vercelBlobStorage = (config) => {
139
153
  } }) };
140
154
  },
141
155
  async getDownloadUrl({ storageUri }) {
142
- const { key } = parseAndValidate(storageUri);
156
+ const { key } = await parseAndValidate(storageUri);
143
157
  const pathname = toPathname(key);
144
158
  const validUntil = Date.now() + expiresInMs;
145
159
  const { presignedUrl } = await presignUrl(await delegationUntil(validUntil), {
@@ -151,7 +165,7 @@ const vercelBlobStorage = (config) => {
151
165
  return { url: presignedUrl };
152
166
  },
153
167
  async exists({ storageUri }) {
154
- const { key } = parseAndValidate(storageUri);
168
+ const { key, token } = await parseAndValidate(storageUri);
155
169
  try {
156
170
  await head(toPathname(key), { token });
157
171
  return { exists: true };
@@ -161,11 +175,12 @@ const vercelBlobStorage = (config) => {
161
175
  }
162
176
  },
163
177
  async delete({ storageUri }) {
164
- const { key } = parseAndValidate(storageUri);
178
+ const { key, token } = await parseAndValidate(storageUri);
165
179
  await del(toPathname(key), { token });
166
180
  return { deleted: true };
167
181
  },
168
182
  async listObjects(prefix) {
183
+ const { token, storeId } = await store();
169
184
  const objects = [];
170
185
  let cursor;
171
186
  do {
@@ -182,7 +197,7 @@ const vercelBlobStorage = (config) => {
182
197
  try {
183
198
  storageUri = createStorageUri({
184
199
  protocol: PROTOCOL,
185
- bucket: storeId(),
200
+ bucket: storeId,
186
201
  key
187
202
  });
188
203
  } catch {
@@ -200,6 +215,7 @@ const vercelBlobStorage = (config) => {
200
215
  return objects;
201
216
  },
202
217
  async deleteObjects(relativeKeys) {
218
+ const { token } = await store();
203
219
  const pathnames = relativeKeys.map((key) => toPathname(getStorageKey(key)));
204
220
  for (let offset = 0; offset < pathnames.length; offset += DELETE_BATCH_SIZE) await del(pathnames.slice(offset, offset + DELETE_BATCH_SIZE), { token });
205
221
  }
@@ -6268,24 +6268,29 @@ createExeca(mapScriptAsync, {}, deepScriptOptions, setScriptSync);
6268
6268
  const { sendMessage, getOneMessage, getEachMessage, getCancelSignal } = getIpcExport();
6269
6269
  //#endregion
6270
6270
  //#region iac/configTemplate.ts
6271
- const getConfigScaffold = (build) => {
6272
- return (0, _hot_updater_cli_tools.createHotUpdaterConfigScaffoldFromBuilder)(new _hot_updater_cli_tools.ConfigBuilder().setBuildType(build).setStorage({
6271
+ const getConfigScaffold = (build, { secretEnv } = { secretEnv: false }) => {
6272
+ const read = (reader, name) => secretEnv ? `async () =>
6273
+ (await ${reader}()).${name}` : `process.env.${name}!`;
6274
+ const storageConfig = {
6273
6275
  imports: [{
6274
6276
  pkg: "@hot-updater/vercel",
6275
6277
  named: ["vercelBlobStorage"]
6276
6278
  }],
6277
6279
  configString: `vercelBlobStorage({
6278
- token: process.env.HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN!,
6280
+ token: ${read("storageSecrets", "HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN")},
6279
6281
  })`
6280
- }).setDatabase({
6282
+ };
6283
+ const databaseConfig = {
6281
6284
  imports: [{
6282
6285
  pkg: "@hot-updater/vercel",
6283
6286
  named: ["postgres"]
6284
6287
  }],
6285
6288
  configString: `postgres({
6286
- connectionString: process.env.HOT_UPDATER_VERCEL_DATABASE_URL!,
6289
+ connectionString: ${read("databaseSecrets", "HOT_UPDATER_VERCEL_DATABASE_URL")},
6287
6290
  })`
6288
- }).setPlugins({
6291
+ };
6292
+ const helperStatements = secretEnv ? [(0, _hot_updater_cli_tools.secretEnvHelper)("storageSecrets", ["HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN"]), (0, _hot_updater_cli_tools.secretEnvHelper)("databaseSecrets", ["HOT_UPDATER_VERCEL_DATABASE_URL"])] : [];
6293
+ const builder = new _hot_updater_cli_tools.ConfigBuilder().setBuildType(build).setStorage(storageConfig).setDatabase(databaseConfig).setPlugins({
6289
6294
  imports: [{
6290
6295
  pkg: "hot-updater/plugins",
6291
6296
  named: [
@@ -6295,7 +6300,12 @@ const getConfigScaffold = (build) => {
6295
6300
  ]
6296
6301
  }],
6297
6302
  configString: "[apiKeys(), insights(), remoteConfig()]"
6298
- }));
6303
+ });
6304
+ if (secretEnv) builder.addImport({
6305
+ pkg: "hot-updater",
6306
+ named: ["secretEnv"]
6307
+ }).setIntermediateCode(helperStatements.map(({ code }) => code).join("\n\n"));
6308
+ return (0, _hot_updater_cli_tools.createHotUpdaterConfigScaffoldFromBuilder)(builder, { helperStatements });
6299
6309
  };
6300
6310
  //#endregion
6301
6311
  //#region iac/init/index.ts
@@ -6382,7 +6392,8 @@ const initProvider = {
6382
6392
  persistence: "with-consent",
6383
6393
  preflight: false
6384
6394
  }
6385
- }
6395
+ },
6396
+ secrets: ["HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN", "HOT_UPDATER_VERCEL_DATABASE_URL"]
6386
6397
  };
6387
6398
  //#endregion
6388
6399
  //#region iac/vercelApi.ts
@@ -7002,10 +7013,10 @@ const selectDatabaseUrl = async ({ api, cwd, project, savedUrl, scope, token })
7002
7013
  validate: (value) => isPostgresUrl(value) ? void 0 : "Enter a postgres:// or postgresql:// URL."
7003
7014
  }));
7004
7015
  };
7005
- const runInit = async ({ build, envFile }) => {
7016
+ const runInit = async ({ build, envFile, secretsEnv }) => {
7006
7017
  const cwd = (0, _hot_updater_cli_tools.getCwd)();
7007
7018
  const nonInteractive = envFile !== void 0;
7008
- const initEnvSources = await (0, _hot_updater_cli_tools.readHotUpdaterInitEnv)(cwd, envFile);
7019
+ const initEnvSources = await (0, _hot_updater_cli_tools.readHotUpdaterInitEnv)(cwd, envFile, secretsEnv);
7009
7020
  const { managedEnv } = initEnvSources;
7010
7021
  const initInputEnv = (0, _hot_updater_cli_tools.getHotUpdaterInitInputEnv)(initEnvSources, nonInteractive);
7011
7022
  const saved = Object.fromEntries(Object.entries(inputs).map(([name, input]) => [name, initInputEnv[input.envKey]?.trim() || void 0]));
@@ -7133,7 +7144,7 @@ const runInit = async ({ build, envFile }) => {
7133
7144
  await database.dispose?.();
7134
7145
  }
7135
7146
  _hot_updater_cli_tools.p.log.success("Generated '.env.hotupdater' file with Vercel settings.");
7136
- await (0, _hot_updater_cli_tools.writeHotUpdaterFiles)(getConfigScaffold(build), {
7147
+ await (0, _hot_updater_cli_tools.writeHotUpdaterFiles)(getConfigScaffold(build, { secretEnv: true }), {
7137
7148
  cwd,
7138
7149
  settings: "Vercel"
7139
7150
  });
@@ -68,6 +68,7 @@ declare const initProvider: {
68
68
  readonly preflight: false;
69
69
  };
70
70
  };
71
+ readonly secrets: readonly ["HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN", "HOT_UPDATER_VERCEL_DATABASE_URL"];
71
72
  };
72
73
  //#endregion
73
74
  //#region iac/vercelFunction.d.ts
@@ -86,6 +87,6 @@ declare const VERCEL_FUNCTION_CONFIG: {
86
87
  };
87
88
  //#endregion
88
89
  //#region iac/index.d.ts
89
- declare const runInit: ({ build, envFile }: RunInitOptions) => Promise<void>;
90
+ declare const runInit: ({ build, envFile, secretsEnv }: RunInitOptions) => Promise<void>;
90
91
  //#endregion
91
92
  export { VERCEL_FUNCTION_CONFIG, initProvider, runInit };
@@ -68,6 +68,7 @@ declare const initProvider: {
68
68
  readonly preflight: false;
69
69
  };
70
70
  };
71
+ readonly secrets: readonly ["HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN", "HOT_UPDATER_VERCEL_DATABASE_URL"];
71
72
  };
72
73
  //#endregion
73
74
  //#region iac/vercelFunction.d.ts
@@ -86,6 +87,6 @@ declare const VERCEL_FUNCTION_CONFIG: {
86
87
  };
87
88
  //#endregion
88
89
  //#region iac/index.d.ts
89
- declare const runInit: ({ build, envFile }: RunInitOptions) => Promise<void>;
90
+ declare const runInit: ({ build, envFile, secretsEnv }: RunInitOptions) => Promise<void>;
90
91
  //#endregion
91
92
  export { VERCEL_FUNCTION_CONFIG, initProvider, runInit };
@@ -2,7 +2,7 @@ import { createRequire } from "node:module";
2
2
  import fs from "fs/promises";
3
3
  import os from "os";
4
4
  import path from "path";
5
- import { ConfigBuilder, InitError, LegacyInfrastructureError, assembleServer, assertInfrastructureGenerationPayload, confirmInitInputPersistence, createHotUpdaterConfigScaffoldFromBuilder, createMigrator, getCwd, getHotUpdaterInitInputEnv, getInitProviderEnvVars, getInitProviderTextPromptValues, link, makeEnv, p, printAppSetup, provisionClientCredential, readHotUpdaterInitEnv, shouldAutoSelectOnlyInitResource, writeHotUpdaterFiles } from "@hot-updater/cli-tools";
5
+ import { ConfigBuilder, InitError, LegacyInfrastructureError, assembleServer, assertInfrastructureGenerationPayload, confirmInitInputPersistence, createHotUpdaterConfigScaffoldFromBuilder, createMigrator, getCwd, getHotUpdaterInitInputEnv, getInitProviderEnvVars, getInitProviderTextPromptValues, link, makeEnv, p, printAppSetup, provisionClientCredential, readHotUpdaterInitEnv, secretEnvHelper, shouldAutoSelectOnlyInitResource, writeHotUpdaterFiles } from "@hot-updater/cli-tools";
6
6
  import { postgres } from "@hot-updater/postgres";
7
7
  import { apiKeys, insights, remoteConfig } from "@hot-updater/server/plugins";
8
8
  import { fileURLToPath } from "node:url";
@@ -6262,24 +6262,29 @@ createExeca(mapScriptAsync, {}, deepScriptOptions, setScriptSync);
6262
6262
  const { sendMessage, getOneMessage, getEachMessage, getCancelSignal } = getIpcExport();
6263
6263
  //#endregion
6264
6264
  //#region iac/configTemplate.ts
6265
- const getConfigScaffold = (build) => {
6266
- return createHotUpdaterConfigScaffoldFromBuilder(new ConfigBuilder().setBuildType(build).setStorage({
6265
+ const getConfigScaffold = (build, { secretEnv } = { secretEnv: false }) => {
6266
+ const read = (reader, name) => secretEnv ? `async () =>
6267
+ (await ${reader}()).${name}` : `process.env.${name}!`;
6268
+ const storageConfig = {
6267
6269
  imports: [{
6268
6270
  pkg: "@hot-updater/vercel",
6269
6271
  named: ["vercelBlobStorage"]
6270
6272
  }],
6271
6273
  configString: `vercelBlobStorage({
6272
- token: process.env.HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN!,
6274
+ token: ${read("storageSecrets", "HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN")},
6273
6275
  })`
6274
- }).setDatabase({
6276
+ };
6277
+ const databaseConfig = {
6275
6278
  imports: [{
6276
6279
  pkg: "@hot-updater/vercel",
6277
6280
  named: ["postgres"]
6278
6281
  }],
6279
6282
  configString: `postgres({
6280
- connectionString: process.env.HOT_UPDATER_VERCEL_DATABASE_URL!,
6283
+ connectionString: ${read("databaseSecrets", "HOT_UPDATER_VERCEL_DATABASE_URL")},
6281
6284
  })`
6282
- }).setPlugins({
6285
+ };
6286
+ const helperStatements = secretEnv ? [secretEnvHelper("storageSecrets", ["HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN"]), secretEnvHelper("databaseSecrets", ["HOT_UPDATER_VERCEL_DATABASE_URL"])] : [];
6287
+ const builder = new ConfigBuilder().setBuildType(build).setStorage(storageConfig).setDatabase(databaseConfig).setPlugins({
6283
6288
  imports: [{
6284
6289
  pkg: "hot-updater/plugins",
6285
6290
  named: [
@@ -6289,7 +6294,12 @@ const getConfigScaffold = (build) => {
6289
6294
  ]
6290
6295
  }],
6291
6296
  configString: "[apiKeys(), insights(), remoteConfig()]"
6292
- }));
6297
+ });
6298
+ if (secretEnv) builder.addImport({
6299
+ pkg: "hot-updater",
6300
+ named: ["secretEnv"]
6301
+ }).setIntermediateCode(helperStatements.map(({ code }) => code).join("\n\n"));
6302
+ return createHotUpdaterConfigScaffoldFromBuilder(builder, { helperStatements });
6293
6303
  };
6294
6304
  //#endregion
6295
6305
  //#region iac/init/index.ts
@@ -6376,7 +6386,8 @@ const initProvider = {
6376
6386
  persistence: "with-consent",
6377
6387
  preflight: false
6378
6388
  }
6379
- }
6389
+ },
6390
+ secrets: ["HOT_UPDATER_VERCEL_BLOB_READ_WRITE_TOKEN", "HOT_UPDATER_VERCEL_DATABASE_URL"]
6380
6391
  };
6381
6392
  //#endregion
6382
6393
  //#region iac/vercelApi.ts
@@ -6996,10 +7007,10 @@ const selectDatabaseUrl = async ({ api, cwd, project, savedUrl, scope, token })
6996
7007
  validate: (value) => isPostgresUrl(value) ? void 0 : "Enter a postgres:// or postgresql:// URL."
6997
7008
  }));
6998
7009
  };
6999
- const runInit = async ({ build, envFile }) => {
7010
+ const runInit = async ({ build, envFile, secretsEnv }) => {
7000
7011
  const cwd = getCwd();
7001
7012
  const nonInteractive = envFile !== void 0;
7002
- const initEnvSources = await readHotUpdaterInitEnv(cwd, envFile);
7013
+ const initEnvSources = await readHotUpdaterInitEnv(cwd, envFile, secretsEnv);
7003
7014
  const { managedEnv } = initEnvSources;
7004
7015
  const initInputEnv = getHotUpdaterInitInputEnv(initEnvSources, nonInteractive);
7005
7016
  const saved = Object.fromEntries(Object.entries(inputs).map(([name, input]) => [name, initInputEnv[input.envKey]?.trim() || void 0]));
@@ -7127,7 +7138,7 @@ const runInit = async ({ build, envFile }) => {
7127
7138
  await database.dispose?.();
7128
7139
  }
7129
7140
  p.log.success("Generated '.env.hotupdater' file with Vercel settings.");
7130
- await writeHotUpdaterFiles(getConfigScaffold(build), {
7141
+ await writeHotUpdaterFiles(getConfigScaffold(build, { secretEnv: true }), {
7131
7142
  cwd,
7132
7143
  settings: "Vercel"
7133
7144
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hot-updater/vercel",
3
3
  "type": "module",
4
- "version": "1.2.0-rc.4",
4
+ "version": "1.2.0-rc.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.2.0-rc.4",
45
- "@hot-updater/plugin-core": "1.2.0-rc.4",
46
- "@hot-updater/postgres": "1.2.0-rc.4",
47
- "@hot-updater/protocol": "1.2.0-rc.4",
48
- "@hot-updater/server": "1.2.0-rc.4"
44
+ "@hot-updater/cli-tools": "1.2.0-rc.6",
45
+ "@hot-updater/plugin-core": "1.2.0-rc.6",
46
+ "@hot-updater/postgres": "1.2.0-rc.6",
47
+ "@hot-updater/protocol": "1.2.0-rc.6",
48
+ "@hot-updater/server": "1.2.0-rc.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.2.0-rc.4"
57
+ "@hot-updater/test-utils": "1.2.0-rc.6"
58
58
  },
59
59
  "scripts": {
60
60
  "build": "tsdown",