@hot-updater/supabase 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.
- package/dist/edge.cjs +1 -1
- package/dist/edge.d.cts +1 -1
- package/dist/edge.d.mts +1 -1
- package/dist/edge.mjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/init/index.cjs +52 -20
- package/dist/init/index.d.cts +1 -0
- package/dist/init/index.d.mts +1 -0
- package/dist/init/index.mjs +53 -21
- package/dist/{supabaseStorage-D4jcGa-l.mjs → supabaseStorage-8VAuNYHy.mjs} +24 -12
- package/dist/{supabaseStorage-BryXQ72m.d.cts → supabaseStorage-B131_auF.d.cts} +6 -1
- package/dist/{supabaseStorage-BryXQ72m.d.mts → supabaseStorage-B131_auF.d.mts} +6 -1
- package/dist/{supabaseStorage-MqoRcaii.cjs → supabaseStorage-BV6GuUz_.cjs} +24 -12
- package/package.json +8 -8
package/dist/edge.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_supabaseStorage = require("./supabaseStorage-
|
|
2
|
+
const require_supabaseStorage = require("./supabaseStorage-BV6GuUz_.cjs");
|
|
3
3
|
exports.supabaseDatabase = require_supabaseStorage.supabaseDatabase;
|
|
4
4
|
exports.supabaseStorage = require_supabaseStorage.supabaseStorage;
|
package/dist/edge.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as supabaseDatabase, n as supabaseStorage, r as SupabaseDatabaseConfig, t as SupabaseStorageConfig } from "./supabaseStorage-
|
|
1
|
+
import { i as supabaseDatabase, n as supabaseStorage, r as SupabaseDatabaseConfig, t as SupabaseStorageConfig } from "./supabaseStorage-B131_auF.cjs";
|
|
2
2
|
export { type SupabaseDatabaseConfig, type SupabaseStorageConfig, supabaseDatabase, supabaseStorage };
|
package/dist/edge.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as supabaseDatabase, n as supabaseStorage, r as SupabaseDatabaseConfig, t as SupabaseStorageConfig } from "./supabaseStorage-
|
|
1
|
+
import { i as supabaseDatabase, n as supabaseStorage, r as SupabaseDatabaseConfig, t as SupabaseStorageConfig } from "./supabaseStorage-B131_auF.mjs";
|
|
2
2
|
export { type SupabaseDatabaseConfig, type SupabaseStorageConfig, supabaseDatabase, supabaseStorage };
|
package/dist/edge.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as supabaseDatabase, t as supabaseStorage } from "./supabaseStorage-
|
|
1
|
+
import { n as supabaseDatabase, t as supabaseStorage } from "./supabaseStorage-8VAuNYHy.mjs";
|
|
2
2
|
export { supabaseDatabase, supabaseStorage };
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_supabaseStorage = require("./supabaseStorage-
|
|
2
|
+
const require_supabaseStorage = require("./supabaseStorage-BV6GuUz_.cjs");
|
|
3
3
|
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
4
4
|
//#region src/supabaseSchema.ts
|
|
5
5
|
/** Every table the apply RPC may name: models, index tables, settings, and the write guard. */
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as supabaseStorage, r as SupabaseDatabaseConfig, t as SupabaseStorageConfig } from "./supabaseStorage-
|
|
1
|
+
import { n as supabaseStorage, r as SupabaseDatabaseConfig, t as SupabaseStorageConfig } from "./supabaseStorage-B131_auF.cjs";
|
|
2
2
|
import { ToolingDatabase } from "@hot-updater/plugin-core";
|
|
3
3
|
//#region src/supabaseMigration.d.ts
|
|
4
4
|
/**
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as supabaseStorage, r as SupabaseDatabaseConfig, t as SupabaseStorageConfig } from "./supabaseStorage-
|
|
1
|
+
import { n as supabaseStorage, r as SupabaseDatabaseConfig, t as SupabaseStorageConfig } from "./supabaseStorage-B131_auF.mjs";
|
|
2
2
|
import { ToolingDatabase } from "@hot-updater/plugin-core";
|
|
3
3
|
//#region src/supabaseMigration.d.ts
|
|
4
4
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as SUPABASE_TABLE_PREFIX, n as supabaseDatabase$1, r as SUPABASE_APPLY_FUNCTION, t as supabaseStorage } from "./supabaseStorage-
|
|
1
|
+
import { i as SUPABASE_TABLE_PREFIX, n as supabaseDatabase$1, r as SUPABASE_APPLY_FUNCTION, t as supabaseStorage } from "./supabaseStorage-8VAuNYHy.mjs";
|
|
2
2
|
import { SETTINGS_TABLE, WRITE_GUARD_TABLE, coreSettings, coreTarget, createTableStatements, generateEngineSql, isMultiIndex } from "@hot-updater/plugin-core";
|
|
3
3
|
//#region src/supabaseSchema.ts
|
|
4
4
|
/** Every table the apply RPC may name: models, index tables, settings, and the write guard. */
|
package/dist/init/index.cjs
CHANGED
|
@@ -6333,9 +6333,11 @@ createExeca(mapScriptAsync, {}, deepScriptOptions, setScriptSync);
|
|
|
6333
6333
|
const { sendMessage, getOneMessage, getEachMessage, getCancelSignal } = getIpcExport();
|
|
6334
6334
|
//#endregion
|
|
6335
6335
|
//#region src/supabaseConfig.ts
|
|
6336
|
-
const resolveSupabaseServiceRoleKey = (config) => {
|
|
6337
|
-
|
|
6338
|
-
|
|
6336
|
+
const resolveSupabaseServiceRoleKey = async (config) => {
|
|
6337
|
+
const { supabaseServiceRoleKey } = config;
|
|
6338
|
+
const key = typeof supabaseServiceRoleKey === "function" ? await supabaseServiceRoleKey() : supabaseServiceRoleKey;
|
|
6339
|
+
if (!key) throw new Error("Supabase service role key is required. Set supabaseServiceRoleKey.");
|
|
6340
|
+
return key;
|
|
6339
6341
|
};
|
|
6340
6342
|
//#endregion
|
|
6341
6343
|
//#region src/supabaseInfrastructureNames.ts
|
|
@@ -6375,9 +6377,16 @@ const withCode = (error) => Object.assign(new Error(error.message, { cause: erro
|
|
|
6375
6377
|
*/
|
|
6376
6378
|
const supabaseExecutor = (client) => {
|
|
6377
6379
|
let created;
|
|
6378
|
-
const clientOf = () =>
|
|
6380
|
+
const clientOf = async () => {
|
|
6381
|
+
if (typeof client !== "function") return client;
|
|
6382
|
+
created ??= Promise.resolve().then(client).catch((error) => {
|
|
6383
|
+
created = void 0;
|
|
6384
|
+
throw error;
|
|
6385
|
+
});
|
|
6386
|
+
return created;
|
|
6387
|
+
};
|
|
6379
6388
|
const apply = async (statements) => {
|
|
6380
|
-
const { data, error } = await clientOf().rpc(SUPABASE_APPLY_FUNCTION, { p_statements: statements.map(toApplyStatement) });
|
|
6389
|
+
const { data, error } = await (await clientOf()).rpc(SUPABASE_APPLY_FUNCTION, { p_statements: statements.map(toApplyStatement) });
|
|
6381
6390
|
if (error) throw withCode(error);
|
|
6382
6391
|
return data;
|
|
6383
6392
|
};
|
|
@@ -6400,7 +6409,7 @@ const supabaseExecutor = (client) => {
|
|
|
6400
6409
|
*/
|
|
6401
6410
|
const supabaseDatabase = (config) => {
|
|
6402
6411
|
const { migrations: _migrations, ...adapter } = (0, _hot_updater_plugin_core.createSqlAdapter)({
|
|
6403
|
-
executor: supabaseExecutor(() => (0, _supabase_supabase_js.createClient)(config.supabaseUrl, resolveSupabaseServiceRoleKey(config))),
|
|
6412
|
+
executor: supabaseExecutor(async () => (0, _supabase_supabase_js.createClient)(config.supabaseUrl, await resolveSupabaseServiceRoleKey(config))),
|
|
6404
6413
|
tablePrefix: SUPABASE_TABLE_PREFIX
|
|
6405
6414
|
});
|
|
6406
6415
|
return (0, _hot_updater_plugin_core.createEngineDatabase)({
|
|
@@ -6410,27 +6419,39 @@ const supabaseDatabase = (config) => {
|
|
|
6410
6419
|
};
|
|
6411
6420
|
//#endregion
|
|
6412
6421
|
//#region iac/configTemplate.ts
|
|
6413
|
-
|
|
6414
|
-
|
|
6422
|
+
/**
|
|
6423
|
+
* The config init writes. With the `resources` init set up, it names them,
|
|
6424
|
+
* and reads the service role key with `secretEnv`, from the environment and
|
|
6425
|
+
* `.env.hotupdater`, then the config's `secrets` adapter. Without them, as
|
|
6426
|
+
* the agent scaffold writes it, it reads every value from the environment.
|
|
6427
|
+
*/
|
|
6428
|
+
const getConfigScaffold = (build, resources) => {
|
|
6429
|
+
const supabaseUrl = resources === void 0 ? "process.env.HOT_UPDATER_SUPABASE_URL!" : JSON.stringify(resources.supabaseUrl);
|
|
6430
|
+
const serviceRoleKey = resources === void 0 ? "process.env.HOT_UPDATER_SUPABASE_SERVICE_ROLE_KEY!" : `async () =>
|
|
6431
|
+
(await deploySecrets()).HOT_UPDATER_SUPABASE_SERVICE_ROLE_KEY`;
|
|
6432
|
+
const storageConfig = {
|
|
6415
6433
|
imports: [{
|
|
6416
6434
|
pkg: "@hot-updater/supabase",
|
|
6417
6435
|
named: ["supabaseStorage"]
|
|
6418
6436
|
}],
|
|
6419
6437
|
configString: `supabaseStorage({
|
|
6420
|
-
supabaseUrl:
|
|
6421
|
-
supabaseServiceRoleKey:
|
|
6422
|
-
bucketName: process.env.HOT_UPDATER_SUPABASE_BUCKET_NAME
|
|
6438
|
+
supabaseUrl: ${supabaseUrl},
|
|
6439
|
+
supabaseServiceRoleKey: ${serviceRoleKey},
|
|
6440
|
+
bucketName: ${resources === void 0 ? "process.env.HOT_UPDATER_SUPABASE_BUCKET_NAME!" : JSON.stringify(resources.bucketName)},
|
|
6423
6441
|
})`
|
|
6424
|
-
}
|
|
6442
|
+
};
|
|
6443
|
+
const databaseConfig = {
|
|
6425
6444
|
imports: [{
|
|
6426
6445
|
pkg: "@hot-updater/supabase",
|
|
6427
6446
|
named: ["supabaseDatabase"]
|
|
6428
6447
|
}],
|
|
6429
6448
|
configString: `supabaseDatabase({
|
|
6430
|
-
supabaseUrl:
|
|
6431
|
-
supabaseServiceRoleKey:
|
|
6449
|
+
supabaseUrl: ${supabaseUrl},
|
|
6450
|
+
supabaseServiceRoleKey: ${serviceRoleKey},
|
|
6432
6451
|
})`
|
|
6433
|
-
}
|
|
6452
|
+
};
|
|
6453
|
+
const helperStatements = resources === void 0 ? [] : [(0, _hot_updater_cli_tools.secretEnvHelper)("deploySecrets", ["HOT_UPDATER_SUPABASE_SERVICE_ROLE_KEY"])];
|
|
6454
|
+
const builder = new _hot_updater_cli_tools.ConfigBuilder().setBuildType(build).setStorage(storageConfig).setDatabase(databaseConfig).setPlugins({
|
|
6434
6455
|
imports: [{
|
|
6435
6456
|
pkg: "hot-updater/plugins",
|
|
6436
6457
|
named: [
|
|
@@ -6440,7 +6461,12 @@ const getConfigScaffold = (build) => {
|
|
|
6440
6461
|
]
|
|
6441
6462
|
}],
|
|
6442
6463
|
configString: "[apiKeys(), insights(), remoteConfig()]"
|
|
6443
|
-
})
|
|
6464
|
+
});
|
|
6465
|
+
if (resources !== void 0) builder.addImport({
|
|
6466
|
+
pkg: "hot-updater",
|
|
6467
|
+
named: ["secretEnv"]
|
|
6468
|
+
}).setIntermediateCode(helperStatements.map(({ code }) => code).join("\n\n"));
|
|
6469
|
+
return (0, _hot_updater_cli_tools.createHotUpdaterConfigScaffoldFromBuilder)(builder, { helperStatements });
|
|
6444
6470
|
};
|
|
6445
6471
|
//#endregion
|
|
6446
6472
|
//#region iac/init/index.ts
|
|
@@ -6546,7 +6572,8 @@ const initProvider = {
|
|
|
6546
6572
|
type: "password"
|
|
6547
6573
|
}
|
|
6548
6574
|
}
|
|
6549
|
-
}
|
|
6575
|
+
},
|
|
6576
|
+
secrets: ["HOT_UPDATER_SUPABASE_SERVICE_ROLE_KEY"]
|
|
6550
6577
|
};
|
|
6551
6578
|
//#endregion
|
|
6552
6579
|
//#region iac/supabaseApi.ts
|
|
@@ -7515,9 +7542,9 @@ const withSupabaseCliMetadataCleanup = async (cwd, operation) => {
|
|
|
7515
7542
|
});
|
|
7516
7543
|
}
|
|
7517
7544
|
};
|
|
7518
|
-
const runInitWithoutCliMetadata = async ({ build, envFile }) => {
|
|
7545
|
+
const runInitWithoutCliMetadata = async ({ build, envFile, secretsEnv }) => {
|
|
7519
7546
|
const nonInteractive = envFile !== void 0;
|
|
7520
|
-
const initEnvSources = await (0, _hot_updater_cli_tools.readHotUpdaterInitEnv)(process.cwd(), envFile);
|
|
7547
|
+
const initEnvSources = await (0, _hot_updater_cli_tools.readHotUpdaterInitEnv)(process.cwd(), envFile, secretsEnv);
|
|
7521
7548
|
const { inputEnv, managedEnv } = initEnvSources;
|
|
7522
7549
|
const initInputEnv = (0, _hot_updater_cli_tools.getHotUpdaterInitInputEnv)(initEnvSources, nonInteractive);
|
|
7523
7550
|
const savedInputs = resolveSupabaseInitInputs(initInputEnv, {
|
|
@@ -7596,6 +7623,7 @@ const runInitWithoutCliMetadata = async ({ build, envFile }) => {
|
|
|
7596
7623
|
const { tmpDir, removeTmpDir } = await (0, _hot_updater_cli_tools.copyDirToTmp)(scaffoldLibPath, "supabase");
|
|
7597
7624
|
let credential;
|
|
7598
7625
|
let clientPlugins = [];
|
|
7626
|
+
let resources;
|
|
7599
7627
|
try {
|
|
7600
7628
|
await stageEdgeFunction({
|
|
7601
7629
|
bucketName: bucketSelection.name,
|
|
@@ -7637,6 +7665,10 @@ const runInitWithoutCliMetadata = async ({ build, envFile }) => {
|
|
|
7637
7665
|
[initProvider.inputs.bucketName.envKey]: bucket.name,
|
|
7638
7666
|
HOT_UPDATER_SUPABASE_URL: `https://${project.id}.supabase.co`
|
|
7639
7667
|
});
|
|
7668
|
+
resources = {
|
|
7669
|
+
supabaseUrl: `https://${project.id}.supabase.co`,
|
|
7670
|
+
bucketName: bucket.name
|
|
7671
|
+
};
|
|
7640
7672
|
await linkSupabase(tmpDir, {
|
|
7641
7673
|
accessToken,
|
|
7642
7674
|
projectId: project.id,
|
|
@@ -7674,7 +7706,7 @@ const runInitWithoutCliMetadata = async ({ build, envFile }) => {
|
|
|
7674
7706
|
await removeTmpDir();
|
|
7675
7707
|
}
|
|
7676
7708
|
_hot_updater_cli_tools.p.log.success("Generated '.env.hotupdater' file with Supabase settings.");
|
|
7677
|
-
await (0, _hot_updater_cli_tools.writeHotUpdaterFiles)(getConfigScaffold(build), {
|
|
7709
|
+
await (0, _hot_updater_cli_tools.writeHotUpdaterFiles)(getConfigScaffold(build, resources), {
|
|
7678
7710
|
cwd: process.cwd(),
|
|
7679
7711
|
settings: "Supabase"
|
|
7680
7712
|
});
|
package/dist/init/index.d.cts
CHANGED
package/dist/init/index.d.mts
CHANGED
package/dist/init/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import fs from "fs/promises";
|
|
3
3
|
import path from "path";
|
|
4
|
-
import { ConfigBuilder, InitError, MissingInitInputsError, assembleServer, assertInfrastructureGenerationAtUrl, assertInitInputs, assertInitProviderInputs, confirmInitInputPersistence, copyDirToTmp, createHotUpdaterConfigScaffoldFromBuilder, getHotUpdaterEnvValue, getHotUpdaterInitInputEnv, getInitProviderEnvVars, getInitProviderTextPromptValues, link, makeEnv, moduleSpecifiersOf, p, printAppSetup, provisionClientCredential, readHotUpdaterInitEnv, resolveInitProviderInput, resolvePackageVersion, transformEnv, transformTemplate, writeHotUpdaterFiles } from "@hot-updater/cli-tools";
|
|
4
|
+
import { ConfigBuilder, InitError, MissingInitInputsError, assembleServer, assertInfrastructureGenerationAtUrl, assertInitInputs, assertInitProviderInputs, confirmInitInputPersistence, copyDirToTmp, createHotUpdaterConfigScaffoldFromBuilder, getHotUpdaterEnvValue, getHotUpdaterInitInputEnv, getInitProviderEnvVars, getInitProviderTextPromptValues, link, makeEnv, moduleSpecifiersOf, p, printAppSetup, provisionClientCredential, readHotUpdaterInitEnv, resolveInitProviderInput, resolvePackageVersion, secretEnvHelper, transformEnv, transformTemplate, writeHotUpdaterFiles } from "@hot-updater/cli-tools";
|
|
5
5
|
import { apiKeys, insights, remoteConfig } from "@hot-updater/server/plugins";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { ChildProcess, execFile, spawn, spawnSync } from "node:child_process";
|
|
@@ -6328,9 +6328,11 @@ createExeca(mapScriptAsync, {}, deepScriptOptions, setScriptSync);
|
|
|
6328
6328
|
const { sendMessage, getOneMessage, getEachMessage, getCancelSignal } = getIpcExport();
|
|
6329
6329
|
//#endregion
|
|
6330
6330
|
//#region src/supabaseConfig.ts
|
|
6331
|
-
const resolveSupabaseServiceRoleKey = (config) => {
|
|
6332
|
-
|
|
6333
|
-
|
|
6331
|
+
const resolveSupabaseServiceRoleKey = async (config) => {
|
|
6332
|
+
const { supabaseServiceRoleKey } = config;
|
|
6333
|
+
const key = typeof supabaseServiceRoleKey === "function" ? await supabaseServiceRoleKey() : supabaseServiceRoleKey;
|
|
6334
|
+
if (!key) throw new Error("Supabase service role key is required. Set supabaseServiceRoleKey.");
|
|
6335
|
+
return key;
|
|
6334
6336
|
};
|
|
6335
6337
|
//#endregion
|
|
6336
6338
|
//#region src/supabaseInfrastructureNames.ts
|
|
@@ -6370,9 +6372,16 @@ const withCode = (error) => Object.assign(new Error(error.message, { cause: erro
|
|
|
6370
6372
|
*/
|
|
6371
6373
|
const supabaseExecutor = (client) => {
|
|
6372
6374
|
let created;
|
|
6373
|
-
const clientOf = () =>
|
|
6375
|
+
const clientOf = async () => {
|
|
6376
|
+
if (typeof client !== "function") return client;
|
|
6377
|
+
created ??= Promise.resolve().then(client).catch((error) => {
|
|
6378
|
+
created = void 0;
|
|
6379
|
+
throw error;
|
|
6380
|
+
});
|
|
6381
|
+
return created;
|
|
6382
|
+
};
|
|
6374
6383
|
const apply = async (statements) => {
|
|
6375
|
-
const { data, error } = await clientOf().rpc(SUPABASE_APPLY_FUNCTION, { p_statements: statements.map(toApplyStatement) });
|
|
6384
|
+
const { data, error } = await (await clientOf()).rpc(SUPABASE_APPLY_FUNCTION, { p_statements: statements.map(toApplyStatement) });
|
|
6376
6385
|
if (error) throw withCode(error);
|
|
6377
6386
|
return data;
|
|
6378
6387
|
};
|
|
@@ -6395,7 +6404,7 @@ const supabaseExecutor = (client) => {
|
|
|
6395
6404
|
*/
|
|
6396
6405
|
const supabaseDatabase = (config) => {
|
|
6397
6406
|
const { migrations: _migrations, ...adapter } = createSqlAdapter({
|
|
6398
|
-
executor: supabaseExecutor(() => createClient(config.supabaseUrl, resolveSupabaseServiceRoleKey(config))),
|
|
6407
|
+
executor: supabaseExecutor(async () => createClient(config.supabaseUrl, await resolveSupabaseServiceRoleKey(config))),
|
|
6399
6408
|
tablePrefix: SUPABASE_TABLE_PREFIX
|
|
6400
6409
|
});
|
|
6401
6410
|
return createEngineDatabase({
|
|
@@ -6405,27 +6414,39 @@ const supabaseDatabase = (config) => {
|
|
|
6405
6414
|
};
|
|
6406
6415
|
//#endregion
|
|
6407
6416
|
//#region iac/configTemplate.ts
|
|
6408
|
-
|
|
6409
|
-
|
|
6417
|
+
/**
|
|
6418
|
+
* The config init writes. With the `resources` init set up, it names them,
|
|
6419
|
+
* and reads the service role key with `secretEnv`, from the environment and
|
|
6420
|
+
* `.env.hotupdater`, then the config's `secrets` adapter. Without them, as
|
|
6421
|
+
* the agent scaffold writes it, it reads every value from the environment.
|
|
6422
|
+
*/
|
|
6423
|
+
const getConfigScaffold = (build, resources) => {
|
|
6424
|
+
const supabaseUrl = resources === void 0 ? "process.env.HOT_UPDATER_SUPABASE_URL!" : JSON.stringify(resources.supabaseUrl);
|
|
6425
|
+
const serviceRoleKey = resources === void 0 ? "process.env.HOT_UPDATER_SUPABASE_SERVICE_ROLE_KEY!" : `async () =>
|
|
6426
|
+
(await deploySecrets()).HOT_UPDATER_SUPABASE_SERVICE_ROLE_KEY`;
|
|
6427
|
+
const storageConfig = {
|
|
6410
6428
|
imports: [{
|
|
6411
6429
|
pkg: "@hot-updater/supabase",
|
|
6412
6430
|
named: ["supabaseStorage"]
|
|
6413
6431
|
}],
|
|
6414
6432
|
configString: `supabaseStorage({
|
|
6415
|
-
supabaseUrl:
|
|
6416
|
-
supabaseServiceRoleKey:
|
|
6417
|
-
bucketName: process.env.HOT_UPDATER_SUPABASE_BUCKET_NAME
|
|
6433
|
+
supabaseUrl: ${supabaseUrl},
|
|
6434
|
+
supabaseServiceRoleKey: ${serviceRoleKey},
|
|
6435
|
+
bucketName: ${resources === void 0 ? "process.env.HOT_UPDATER_SUPABASE_BUCKET_NAME!" : JSON.stringify(resources.bucketName)},
|
|
6418
6436
|
})`
|
|
6419
|
-
}
|
|
6437
|
+
};
|
|
6438
|
+
const databaseConfig = {
|
|
6420
6439
|
imports: [{
|
|
6421
6440
|
pkg: "@hot-updater/supabase",
|
|
6422
6441
|
named: ["supabaseDatabase"]
|
|
6423
6442
|
}],
|
|
6424
6443
|
configString: `supabaseDatabase({
|
|
6425
|
-
supabaseUrl:
|
|
6426
|
-
supabaseServiceRoleKey:
|
|
6444
|
+
supabaseUrl: ${supabaseUrl},
|
|
6445
|
+
supabaseServiceRoleKey: ${serviceRoleKey},
|
|
6427
6446
|
})`
|
|
6428
|
-
}
|
|
6447
|
+
};
|
|
6448
|
+
const helperStatements = resources === void 0 ? [] : [secretEnvHelper("deploySecrets", ["HOT_UPDATER_SUPABASE_SERVICE_ROLE_KEY"])];
|
|
6449
|
+
const builder = new ConfigBuilder().setBuildType(build).setStorage(storageConfig).setDatabase(databaseConfig).setPlugins({
|
|
6429
6450
|
imports: [{
|
|
6430
6451
|
pkg: "hot-updater/plugins",
|
|
6431
6452
|
named: [
|
|
@@ -6435,7 +6456,12 @@ const getConfigScaffold = (build) => {
|
|
|
6435
6456
|
]
|
|
6436
6457
|
}],
|
|
6437
6458
|
configString: "[apiKeys(), insights(), remoteConfig()]"
|
|
6438
|
-
})
|
|
6459
|
+
});
|
|
6460
|
+
if (resources !== void 0) builder.addImport({
|
|
6461
|
+
pkg: "hot-updater",
|
|
6462
|
+
named: ["secretEnv"]
|
|
6463
|
+
}).setIntermediateCode(helperStatements.map(({ code }) => code).join("\n\n"));
|
|
6464
|
+
return createHotUpdaterConfigScaffoldFromBuilder(builder, { helperStatements });
|
|
6439
6465
|
};
|
|
6440
6466
|
//#endregion
|
|
6441
6467
|
//#region iac/init/index.ts
|
|
@@ -6541,7 +6567,8 @@ const initProvider = {
|
|
|
6541
6567
|
type: "password"
|
|
6542
6568
|
}
|
|
6543
6569
|
}
|
|
6544
|
-
}
|
|
6570
|
+
},
|
|
6571
|
+
secrets: ["HOT_UPDATER_SUPABASE_SERVICE_ROLE_KEY"]
|
|
6545
6572
|
};
|
|
6546
6573
|
//#endregion
|
|
6547
6574
|
//#region iac/supabaseApi.ts
|
|
@@ -7510,9 +7537,9 @@ const withSupabaseCliMetadataCleanup = async (cwd, operation) => {
|
|
|
7510
7537
|
});
|
|
7511
7538
|
}
|
|
7512
7539
|
};
|
|
7513
|
-
const runInitWithoutCliMetadata = async ({ build, envFile }) => {
|
|
7540
|
+
const runInitWithoutCliMetadata = async ({ build, envFile, secretsEnv }) => {
|
|
7514
7541
|
const nonInteractive = envFile !== void 0;
|
|
7515
|
-
const initEnvSources = await readHotUpdaterInitEnv(process.cwd(), envFile);
|
|
7542
|
+
const initEnvSources = await readHotUpdaterInitEnv(process.cwd(), envFile, secretsEnv);
|
|
7516
7543
|
const { inputEnv, managedEnv } = initEnvSources;
|
|
7517
7544
|
const initInputEnv = getHotUpdaterInitInputEnv(initEnvSources, nonInteractive);
|
|
7518
7545
|
const savedInputs = resolveSupabaseInitInputs(initInputEnv, {
|
|
@@ -7591,6 +7618,7 @@ const runInitWithoutCliMetadata = async ({ build, envFile }) => {
|
|
|
7591
7618
|
const { tmpDir, removeTmpDir } = await copyDirToTmp(scaffoldLibPath, "supabase");
|
|
7592
7619
|
let credential;
|
|
7593
7620
|
let clientPlugins = [];
|
|
7621
|
+
let resources;
|
|
7594
7622
|
try {
|
|
7595
7623
|
await stageEdgeFunction({
|
|
7596
7624
|
bucketName: bucketSelection.name,
|
|
@@ -7632,6 +7660,10 @@ const runInitWithoutCliMetadata = async ({ build, envFile }) => {
|
|
|
7632
7660
|
[initProvider.inputs.bucketName.envKey]: bucket.name,
|
|
7633
7661
|
HOT_UPDATER_SUPABASE_URL: `https://${project.id}.supabase.co`
|
|
7634
7662
|
});
|
|
7663
|
+
resources = {
|
|
7664
|
+
supabaseUrl: `https://${project.id}.supabase.co`,
|
|
7665
|
+
bucketName: bucket.name
|
|
7666
|
+
};
|
|
7635
7667
|
await linkSupabase(tmpDir, {
|
|
7636
7668
|
accessToken,
|
|
7637
7669
|
projectId: project.id,
|
|
@@ -7669,7 +7701,7 @@ const runInitWithoutCliMetadata = async ({ build, envFile }) => {
|
|
|
7669
7701
|
await removeTmpDir();
|
|
7670
7702
|
}
|
|
7671
7703
|
p.log.success("Generated '.env.hotupdater' file with Supabase settings.");
|
|
7672
|
-
await writeHotUpdaterFiles(getConfigScaffold(build), {
|
|
7704
|
+
await writeHotUpdaterFiles(getConfigScaffold(build, resources), {
|
|
7673
7705
|
cwd: process.cwd(),
|
|
7674
7706
|
settings: "Supabase"
|
|
7675
7707
|
});
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { SETTINGS_TABLE, createEngineDatabase, createSqlAdapter, createStorageAdapter, createStorageKeyBuilder, createStorageUri, parseStorageUri } from "@hot-updater/plugin-core";
|
|
2
2
|
import { createClient } from "@supabase/supabase-js";
|
|
3
3
|
//#region src/supabaseConfig.ts
|
|
4
|
-
const resolveSupabaseServiceRoleKey = (config) => {
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
const resolveSupabaseServiceRoleKey = async (config) => {
|
|
5
|
+
const { supabaseServiceRoleKey } = config;
|
|
6
|
+
const key = typeof supabaseServiceRoleKey === "function" ? await supabaseServiceRoleKey() : supabaseServiceRoleKey;
|
|
7
|
+
if (!key) throw new Error("Supabase service role key is required. Set supabaseServiceRoleKey.");
|
|
8
|
+
return key;
|
|
7
9
|
};
|
|
8
10
|
//#endregion
|
|
9
11
|
//#region src/supabaseInfrastructureNames.ts
|
|
@@ -42,9 +44,16 @@ const withCode = (error) => Object.assign(new Error(error.message, { cause: erro
|
|
|
42
44
|
*/
|
|
43
45
|
const supabaseExecutor = (client) => {
|
|
44
46
|
let created;
|
|
45
|
-
const clientOf = () =>
|
|
47
|
+
const clientOf = async () => {
|
|
48
|
+
if (typeof client !== "function") return client;
|
|
49
|
+
created ??= Promise.resolve().then(client).catch((error) => {
|
|
50
|
+
created = void 0;
|
|
51
|
+
throw error;
|
|
52
|
+
});
|
|
53
|
+
return created;
|
|
54
|
+
};
|
|
46
55
|
const apply = async (statements) => {
|
|
47
|
-
const { data, error } = await clientOf().rpc(SUPABASE_APPLY_FUNCTION, { p_statements: statements.map(toApplyStatement) });
|
|
56
|
+
const { data, error } = await (await clientOf()).rpc(SUPABASE_APPLY_FUNCTION, { p_statements: statements.map(toApplyStatement) });
|
|
48
57
|
if (error) throw withCode(error);
|
|
49
58
|
return data;
|
|
50
59
|
};
|
|
@@ -67,7 +76,7 @@ const supabaseExecutor = (client) => {
|
|
|
67
76
|
*/
|
|
68
77
|
const supabaseDatabase = (config) => {
|
|
69
78
|
const { migrations: _migrations, ...adapter } = createSqlAdapter({
|
|
70
|
-
executor: supabaseExecutor(() => createClient(config.supabaseUrl, resolveSupabaseServiceRoleKey(config))),
|
|
79
|
+
executor: supabaseExecutor(async () => createClient(config.supabaseUrl, await resolveSupabaseServiceRoleKey(config))),
|
|
71
80
|
tablePrefix: SUPABASE_TABLE_PREFIX
|
|
72
81
|
});
|
|
73
82
|
return createEngineDatabase({
|
|
@@ -170,10 +179,13 @@ const utf8 = new TextEncoder();
|
|
|
170
179
|
const toObjectName = (key) => key.replace(ESCAPED_CHARACTER, (character) => Array.from(utf8.encode(character), (byte) => `!${byte.toString(16).toUpperCase().padStart(2, "0")}`).join(""));
|
|
171
180
|
const supabaseStorage = (config) => {
|
|
172
181
|
let client;
|
|
173
|
-
const bucket = () => (client ??= createClient(config.supabaseUrl,
|
|
182
|
+
const bucket = async () => (await (client ??= resolveSupabaseServiceRoleKey(config).then((key) => createClient(config.supabaseUrl, key), (error) => {
|
|
183
|
+
client = void 0;
|
|
184
|
+
throw error;
|
|
185
|
+
}))).storage.from(config.bucketName);
|
|
174
186
|
const getStorageKey = createStorageKeyBuilder(config.basePath);
|
|
175
187
|
const resolveSignedUrl = createSupabaseSignedUrlBatcher({
|
|
176
|
-
createSignedUrls: (_bucketName, keys, expiresIn) => bucket().createSignedUrls(keys, expiresIn),
|
|
188
|
+
createSignedUrls: async (_bucketName, keys, expiresIn) => (await bucket()).createSignedUrls(keys, expiresIn),
|
|
177
189
|
expiresIn: config.signedUrlExpiresIn ?? 3600,
|
|
178
190
|
formatObjectPath: (_bucketName, key) => key
|
|
179
191
|
});
|
|
@@ -187,7 +199,7 @@ const supabaseStorage = (config) => {
|
|
|
187
199
|
protocol: "supabase-storage",
|
|
188
200
|
async put({ key, body, contentLength, contentType }) {
|
|
189
201
|
const storageKey = getStorageKey(key);
|
|
190
|
-
const { error } = await bucket().upload(toObjectName(storageKey), body, {
|
|
202
|
+
const { error } = await (await bucket()).upload(toObjectName(storageKey), body, {
|
|
191
203
|
contentType,
|
|
192
204
|
cacheControl: "max-age=31536000",
|
|
193
205
|
upsert: true,
|
|
@@ -203,7 +215,7 @@ const supabaseStorage = (config) => {
|
|
|
203
215
|
},
|
|
204
216
|
async get({ storageUri }) {
|
|
205
217
|
const { key } = parseAndValidate(storageUri);
|
|
206
|
-
const { data, error } = await bucket().download(toObjectName(key));
|
|
218
|
+
const { data, error } = await (await bucket()).download(toObjectName(key));
|
|
207
219
|
if (error) {
|
|
208
220
|
if (await isMissingObjectError(error)) return { response: null };
|
|
209
221
|
throw new Error(`Failed to download storage object: ${error.message}`);
|
|
@@ -216,7 +228,7 @@ const supabaseStorage = (config) => {
|
|
|
216
228
|
},
|
|
217
229
|
async exists({ storageUri }) {
|
|
218
230
|
const { key } = parseAndValidate(storageUri);
|
|
219
|
-
const { data, error } = await bucket().exists(toObjectName(key));
|
|
231
|
+
const { data, error } = await (await bucket()).exists(toObjectName(key));
|
|
220
232
|
if (error) {
|
|
221
233
|
if (isMissingExistsError(error)) return { exists: false };
|
|
222
234
|
throw error;
|
|
@@ -225,7 +237,7 @@ const supabaseStorage = (config) => {
|
|
|
225
237
|
},
|
|
226
238
|
async delete({ storageUri }) {
|
|
227
239
|
const { key } = parseAndValidate(storageUri);
|
|
228
|
-
const { error } = await bucket().remove([toObjectName(key)]);
|
|
240
|
+
const { error } = await (await bucket()).remove([toObjectName(key)]);
|
|
229
241
|
if (error && !isNotFoundError(error)) throw new Error(`Failed to delete storage object: ${error.message}`);
|
|
230
242
|
return { deleted: true };
|
|
231
243
|
}
|
|
@@ -2,7 +2,12 @@ import { EngineDatabase, StorageAdapterWith } from "@hot-updater/plugin-core";
|
|
|
2
2
|
//#region src/supabaseConfig.d.ts
|
|
3
3
|
type SupabaseServiceRoleConfig = {
|
|
4
4
|
supabaseUrl: string;
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* The project's service role key, or a function that returns it, such as
|
|
7
|
+
* one that reads it with `secretEnv`: called on the first request, so a
|
|
8
|
+
* config loads without the key.
|
|
9
|
+
*/
|
|
10
|
+
supabaseServiceRoleKey: string | (() => string | Promise<string>);
|
|
6
11
|
};
|
|
7
12
|
//#endregion
|
|
8
13
|
//#region src/supabaseDatabase.d.ts
|
|
@@ -2,7 +2,12 @@ import { EngineDatabase, StorageAdapterWith } from "@hot-updater/plugin-core";
|
|
|
2
2
|
//#region src/supabaseConfig.d.ts
|
|
3
3
|
type SupabaseServiceRoleConfig = {
|
|
4
4
|
supabaseUrl: string;
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* The project's service role key, or a function that returns it, such as
|
|
7
|
+
* one that reads it with `secretEnv`: called on the first request, so a
|
|
8
|
+
* config loads without the key.
|
|
9
|
+
*/
|
|
10
|
+
supabaseServiceRoleKey: string | (() => string | Promise<string>);
|
|
6
11
|
};
|
|
7
12
|
//#endregion
|
|
8
13
|
//#region src/supabaseDatabase.d.ts
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
2
2
|
let _supabase_supabase_js = require("@supabase/supabase-js");
|
|
3
3
|
//#region src/supabaseConfig.ts
|
|
4
|
-
const resolveSupabaseServiceRoleKey = (config) => {
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
const resolveSupabaseServiceRoleKey = async (config) => {
|
|
5
|
+
const { supabaseServiceRoleKey } = config;
|
|
6
|
+
const key = typeof supabaseServiceRoleKey === "function" ? await supabaseServiceRoleKey() : supabaseServiceRoleKey;
|
|
7
|
+
if (!key) throw new Error("Supabase service role key is required. Set supabaseServiceRoleKey.");
|
|
8
|
+
return key;
|
|
7
9
|
};
|
|
8
10
|
//#endregion
|
|
9
11
|
//#region src/supabaseInfrastructureNames.ts
|
|
@@ -42,9 +44,16 @@ const withCode = (error) => Object.assign(new Error(error.message, { cause: erro
|
|
|
42
44
|
*/
|
|
43
45
|
const supabaseExecutor = (client) => {
|
|
44
46
|
let created;
|
|
45
|
-
const clientOf = () =>
|
|
47
|
+
const clientOf = async () => {
|
|
48
|
+
if (typeof client !== "function") return client;
|
|
49
|
+
created ??= Promise.resolve().then(client).catch((error) => {
|
|
50
|
+
created = void 0;
|
|
51
|
+
throw error;
|
|
52
|
+
});
|
|
53
|
+
return created;
|
|
54
|
+
};
|
|
46
55
|
const apply = async (statements) => {
|
|
47
|
-
const { data, error } = await clientOf().rpc(SUPABASE_APPLY_FUNCTION, { p_statements: statements.map(toApplyStatement) });
|
|
56
|
+
const { data, error } = await (await clientOf()).rpc(SUPABASE_APPLY_FUNCTION, { p_statements: statements.map(toApplyStatement) });
|
|
48
57
|
if (error) throw withCode(error);
|
|
49
58
|
return data;
|
|
50
59
|
};
|
|
@@ -67,7 +76,7 @@ const supabaseExecutor = (client) => {
|
|
|
67
76
|
*/
|
|
68
77
|
const supabaseDatabase = (config) => {
|
|
69
78
|
const { migrations: _migrations, ...adapter } = (0, _hot_updater_plugin_core.createSqlAdapter)({
|
|
70
|
-
executor: supabaseExecutor(() => (0, _supabase_supabase_js.createClient)(config.supabaseUrl, resolveSupabaseServiceRoleKey(config))),
|
|
79
|
+
executor: supabaseExecutor(async () => (0, _supabase_supabase_js.createClient)(config.supabaseUrl, await resolveSupabaseServiceRoleKey(config))),
|
|
71
80
|
tablePrefix: SUPABASE_TABLE_PREFIX
|
|
72
81
|
});
|
|
73
82
|
return (0, _hot_updater_plugin_core.createEngineDatabase)({
|
|
@@ -170,10 +179,13 @@ const utf8 = new TextEncoder();
|
|
|
170
179
|
const toObjectName = (key) => key.replace(ESCAPED_CHARACTER, (character) => Array.from(utf8.encode(character), (byte) => `!${byte.toString(16).toUpperCase().padStart(2, "0")}`).join(""));
|
|
171
180
|
const supabaseStorage = (config) => {
|
|
172
181
|
let client;
|
|
173
|
-
const bucket = () => (client ??= (0, _supabase_supabase_js.createClient)(config.supabaseUrl,
|
|
182
|
+
const bucket = async () => (await (client ??= resolveSupabaseServiceRoleKey(config).then((key) => (0, _supabase_supabase_js.createClient)(config.supabaseUrl, key), (error) => {
|
|
183
|
+
client = void 0;
|
|
184
|
+
throw error;
|
|
185
|
+
}))).storage.from(config.bucketName);
|
|
174
186
|
const getStorageKey = (0, _hot_updater_plugin_core.createStorageKeyBuilder)(config.basePath);
|
|
175
187
|
const resolveSignedUrl = createSupabaseSignedUrlBatcher({
|
|
176
|
-
createSignedUrls: (_bucketName, keys, expiresIn) => bucket().createSignedUrls(keys, expiresIn),
|
|
188
|
+
createSignedUrls: async (_bucketName, keys, expiresIn) => (await bucket()).createSignedUrls(keys, expiresIn),
|
|
177
189
|
expiresIn: config.signedUrlExpiresIn ?? 3600,
|
|
178
190
|
formatObjectPath: (_bucketName, key) => key
|
|
179
191
|
});
|
|
@@ -187,7 +199,7 @@ const supabaseStorage = (config) => {
|
|
|
187
199
|
protocol: "supabase-storage",
|
|
188
200
|
async put({ key, body, contentLength, contentType }) {
|
|
189
201
|
const storageKey = getStorageKey(key);
|
|
190
|
-
const { error } = await bucket().upload(toObjectName(storageKey), body, {
|
|
202
|
+
const { error } = await (await bucket()).upload(toObjectName(storageKey), body, {
|
|
191
203
|
contentType,
|
|
192
204
|
cacheControl: "max-age=31536000",
|
|
193
205
|
upsert: true,
|
|
@@ -203,7 +215,7 @@ const supabaseStorage = (config) => {
|
|
|
203
215
|
},
|
|
204
216
|
async get({ storageUri }) {
|
|
205
217
|
const { key } = parseAndValidate(storageUri);
|
|
206
|
-
const { data, error } = await bucket().download(toObjectName(key));
|
|
218
|
+
const { data, error } = await (await bucket()).download(toObjectName(key));
|
|
207
219
|
if (error) {
|
|
208
220
|
if (await isMissingObjectError(error)) return { response: null };
|
|
209
221
|
throw new Error(`Failed to download storage object: ${error.message}`);
|
|
@@ -216,7 +228,7 @@ const supabaseStorage = (config) => {
|
|
|
216
228
|
},
|
|
217
229
|
async exists({ storageUri }) {
|
|
218
230
|
const { key } = parseAndValidate(storageUri);
|
|
219
|
-
const { data, error } = await bucket().exists(toObjectName(key));
|
|
231
|
+
const { data, error } = await (await bucket()).exists(toObjectName(key));
|
|
220
232
|
if (error) {
|
|
221
233
|
if (isMissingExistsError(error)) return { exists: false };
|
|
222
234
|
throw error;
|
|
@@ -225,7 +237,7 @@ const supabaseStorage = (config) => {
|
|
|
225
237
|
},
|
|
226
238
|
async delete({ storageUri }) {
|
|
227
239
|
const { key } = parseAndValidate(storageUri);
|
|
228
|
-
const { error } = await bucket().remove([toObjectName(key)]);
|
|
240
|
+
const { error } = await (await bucket()).remove([toObjectName(key)]);
|
|
229
241
|
if (error && !isNotFoundError(error)) throw new Error(`Failed to delete storage object: ${error.message}`);
|
|
230
242
|
return { deleted: true };
|
|
231
243
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hot-updater/supabase",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.2.0-rc.
|
|
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",
|
|
@@ -51,10 +51,10 @@
|
|
|
51
51
|
"@supabase/supabase-js": "2.76.1",
|
|
52
52
|
"hono": "4.12.34",
|
|
53
53
|
"uuidv7": "^1.0.2",
|
|
54
|
-
"@hot-updater/
|
|
55
|
-
"@hot-updater/
|
|
56
|
-
"@hot-updater/
|
|
57
|
-
"@hot-updater/
|
|
54
|
+
"@hot-updater/protocol": "1.2.0-rc.6",
|
|
55
|
+
"@hot-updater/plugin-core": "1.2.0-rc.6",
|
|
56
|
+
"@hot-updater/cli-tools": "1.2.0-rc.6",
|
|
57
|
+
"@hot-updater/server": "1.2.0-rc.6"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@electric-sql/pglite": "0.4.1",
|
|
@@ -64,9 +64,9 @@
|
|
|
64
64
|
"execa": "9.5.2",
|
|
65
65
|
"@types/node": "^20",
|
|
66
66
|
"mime": "^4.0.4",
|
|
67
|
-
"@hot-updater/mock": "1.2.0-rc.
|
|
68
|
-
"@hot-updater/test-utils": "1.2.0-rc.
|
|
69
|
-
"@hot-updater/postgres": "1.2.0-rc.
|
|
67
|
+
"@hot-updater/mock": "1.2.0-rc.6",
|
|
68
|
+
"@hot-updater/test-utils": "1.2.0-rc.6",
|
|
69
|
+
"@hot-updater/postgres": "1.2.0-rc.6"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build": "tsdown",
|