@hot-updater/cloudflare 1.2.0-rc.3 → 1.2.0-rc.5
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/index.cjs +7 -2
- package/dist/index.d.cts +6 -1
- package/dist/index.d.mts +6 -1
- package/dist/index.mjs +7 -2
- package/dist/init/index.cjs +74 -17
- package/dist/init/index.d.cts +2 -1
- package/dist/init/index.d.mts +2 -1
- package/dist/init/index.mjs +75 -18
- package/package.json +6 -6
- package/src/d1Rest.ts +20 -4
- package/worker/dist/README.md +1 -1
- package/worker/dist/index.js +1 -1
- package/worker/dist/index.js.map +1 -1
package/dist/index.cjs
CHANGED
|
@@ -86,7 +86,12 @@ const encode = ({ sql, params }) => ({
|
|
|
86
86
|
* time, or a batch D1 runs in one transaction.
|
|
87
87
|
*/
|
|
88
88
|
const d1RestRunner = (config) => {
|
|
89
|
-
const
|
|
89
|
+
const { cloudflareApiToken } = config;
|
|
90
|
+
let client;
|
|
91
|
+
const connect = () => client ??= (async () => new cloudflare.default({ apiToken: typeof cloudflareApiToken === "function" ? await cloudflareApiToken() : cloudflareApiToken }))().catch((error) => {
|
|
92
|
+
client = void 0;
|
|
93
|
+
throw error;
|
|
94
|
+
});
|
|
90
95
|
const batch = async (statements) => {
|
|
91
96
|
const [first] = statements;
|
|
92
97
|
if (first === void 0) return [];
|
|
@@ -97,7 +102,7 @@ const d1RestRunner = (config) => {
|
|
|
97
102
|
account_id: config.accountId,
|
|
98
103
|
batch: statements.map(encode)
|
|
99
104
|
};
|
|
100
|
-
const page = await
|
|
105
|
+
const page = await (await connect()).d1.database.query(config.databaseId, body);
|
|
101
106
|
const results = [];
|
|
102
107
|
for await (const resultPage of page.iterPages()) for (const result of resultPage.result) results.push(toSqlResult(result));
|
|
103
108
|
if (results.length !== statements.length) throw new D1ExecutionError();
|
package/dist/index.d.cts
CHANGED
|
@@ -4,7 +4,12 @@ import { S3ClientConfig } from "@aws-sdk/client-s3";
|
|
|
4
4
|
interface D1RestConfig {
|
|
5
5
|
readonly databaseId: string;
|
|
6
6
|
readonly accountId: string;
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* An API token with D1 edit permission, or a function that returns it,
|
|
9
|
+
* such as one that reads it with `secretEnv`: called on the first query,
|
|
10
|
+
* so a config loads without the token.
|
|
11
|
+
*/
|
|
12
|
+
readonly cloudflareApiToken: string | (() => string | Promise<string>);
|
|
8
13
|
}
|
|
9
14
|
//#endregion
|
|
10
15
|
//#region src/d1Executor.d.ts
|
package/dist/index.d.mts
CHANGED
|
@@ -4,7 +4,12 @@ import { S3ClientConfig } from "@aws-sdk/client-s3";
|
|
|
4
4
|
interface D1RestConfig {
|
|
5
5
|
readonly databaseId: string;
|
|
6
6
|
readonly accountId: string;
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* An API token with D1 edit permission, or a function that returns it,
|
|
9
|
+
* such as one that reads it with `secretEnv`: called on the first query,
|
|
10
|
+
* so a config loads without the token.
|
|
11
|
+
*/
|
|
12
|
+
readonly cloudflareApiToken: string | (() => string | Promise<string>);
|
|
8
13
|
}
|
|
9
14
|
//#endregion
|
|
10
15
|
//#region src/d1Executor.d.ts
|
package/dist/index.mjs
CHANGED
|
@@ -62,7 +62,12 @@ const encode = ({ sql, params }) => ({
|
|
|
62
62
|
* time, or a batch D1 runs in one transaction.
|
|
63
63
|
*/
|
|
64
64
|
const d1RestRunner = (config) => {
|
|
65
|
-
const
|
|
65
|
+
const { cloudflareApiToken } = config;
|
|
66
|
+
let client;
|
|
67
|
+
const connect = () => client ??= (async () => new Cloudflare({ apiToken: typeof cloudflareApiToken === "function" ? await cloudflareApiToken() : cloudflareApiToken }))().catch((error) => {
|
|
68
|
+
client = void 0;
|
|
69
|
+
throw error;
|
|
70
|
+
});
|
|
66
71
|
const batch = async (statements) => {
|
|
67
72
|
const [first] = statements;
|
|
68
73
|
if (first === void 0) return [];
|
|
@@ -73,7 +78,7 @@ const d1RestRunner = (config) => {
|
|
|
73
78
|
account_id: config.accountId,
|
|
74
79
|
batch: statements.map(encode)
|
|
75
80
|
};
|
|
76
|
-
const page = await
|
|
81
|
+
const page = await (await connect()).d1.database.query(config.databaseId, body);
|
|
77
82
|
const results = [];
|
|
78
83
|
for await (const resultPage of page.iterPages()) for (const result of resultPage.result) results.push(toSqlResult(result));
|
|
79
84
|
if (results.length !== statements.length) throw new D1ExecutionError();
|
package/dist/init/index.cjs
CHANGED
|
@@ -113,7 +113,12 @@ const encode = ({ sql, params }) => ({
|
|
|
113
113
|
* time, or a batch D1 runs in one transaction.
|
|
114
114
|
*/
|
|
115
115
|
const d1RestRunner = (config) => {
|
|
116
|
-
const
|
|
116
|
+
const { cloudflareApiToken } = config;
|
|
117
|
+
let client;
|
|
118
|
+
const connect = () => client ??= (async () => new cloudflare.default({ apiToken: typeof cloudflareApiToken === "function" ? await cloudflareApiToken() : cloudflareApiToken }))().catch((error) => {
|
|
119
|
+
client = void 0;
|
|
120
|
+
throw error;
|
|
121
|
+
});
|
|
117
122
|
const batch = async (statements) => {
|
|
118
123
|
const [first] = statements;
|
|
119
124
|
if (first === void 0) return [];
|
|
@@ -124,7 +129,7 @@ const d1RestRunner = (config) => {
|
|
|
124
129
|
account_id: config.accountId,
|
|
125
130
|
batch: statements.map(encode)
|
|
126
131
|
};
|
|
127
|
-
const page = await
|
|
132
|
+
const page = await (await connect()).d1.database.query(config.databaseId, body);
|
|
128
133
|
const results = [];
|
|
129
134
|
for await (const resultPage of page.iterPages()) for (const result of resultPage.result) results.push(toSqlResult(result));
|
|
130
135
|
if (results.length !== statements.length) throw new D1ExecutionError();
|
|
@@ -11320,7 +11325,12 @@ const initProvider = {
|
|
|
11320
11325
|
},
|
|
11321
11326
|
validate: (value) => value === "true" || value === "false"
|
|
11322
11327
|
}
|
|
11323
|
-
}
|
|
11328
|
+
},
|
|
11329
|
+
secrets: [
|
|
11330
|
+
"HOT_UPDATER_CLOUDFLARE_API_TOKEN",
|
|
11331
|
+
"HOT_UPDATER_CLOUDFLARE_R2_ACCESS_KEY_ID",
|
|
11332
|
+
"HOT_UPDATER_CLOUDFLARE_R2_SECRET_ACCESS_KEY"
|
|
11333
|
+
]
|
|
11324
11334
|
};
|
|
11325
11335
|
//#endregion
|
|
11326
11336
|
//#region iac/cloudflareInitInputs.ts
|
|
@@ -11408,8 +11418,26 @@ const inputCloudflareInitSecrets = async ({ accountId, bucketName, apiToken, acc
|
|
|
11408
11418
|
};
|
|
11409
11419
|
//#endregion
|
|
11410
11420
|
//#region iac/configTemplate.ts
|
|
11411
|
-
|
|
11412
|
-
|
|
11421
|
+
/**
|
|
11422
|
+
* The config init writes. With the `resources` init set up, it names them,
|
|
11423
|
+
* and reads the API token and R2 keys with `secretEnv`, from the
|
|
11424
|
+
* environment and `.env.hotupdater`, then the config's `secrets` adapter.
|
|
11425
|
+
* Without them, as the agent scaffold writes it, it reads every value from
|
|
11426
|
+
* the environment.
|
|
11427
|
+
*/
|
|
11428
|
+
const getConfigScaffold = (build, resources) => {
|
|
11429
|
+
const builder = new _hot_updater_cli_tools.ConfigBuilder().setBuildType(build).setPlugins({
|
|
11430
|
+
imports: [{
|
|
11431
|
+
pkg: "hot-updater/plugins",
|
|
11432
|
+
named: [
|
|
11433
|
+
"apiKeys",
|
|
11434
|
+
"insights",
|
|
11435
|
+
"remoteConfig"
|
|
11436
|
+
]
|
|
11437
|
+
}],
|
|
11438
|
+
configString: "[apiKeys(), insights(), remoteConfig()]"
|
|
11439
|
+
});
|
|
11440
|
+
if (resources === void 0) return (0, _hot_updater_cli_tools.createHotUpdaterConfigScaffoldFromBuilder)(builder.setStorage({
|
|
11413
11441
|
imports: [{
|
|
11414
11442
|
pkg: "@hot-updater/cloudflare",
|
|
11415
11443
|
named: ["r2Storage"]
|
|
@@ -11432,17 +11460,42 @@ const getConfigScaffold = (build) => {
|
|
|
11432
11460
|
accountId: process.env.HOT_UPDATER_CLOUDFLARE_ACCOUNT_ID!,
|
|
11433
11461
|
cloudflareApiToken: process.env.HOT_UPDATER_CLOUDFLARE_API_TOKEN!,
|
|
11434
11462
|
})`
|
|
11435
|
-
})
|
|
11463
|
+
}));
|
|
11464
|
+
const accountId = JSON.stringify(resources.accountId);
|
|
11465
|
+
const storageConfig = {
|
|
11436
11466
|
imports: [{
|
|
11437
|
-
pkg: "hot-updater/
|
|
11438
|
-
named: [
|
|
11439
|
-
"apiKeys",
|
|
11440
|
-
"insights",
|
|
11441
|
-
"remoteConfig"
|
|
11442
|
-
]
|
|
11467
|
+
pkg: "@hot-updater/cloudflare",
|
|
11468
|
+
named: ["r2Storage"]
|
|
11443
11469
|
}],
|
|
11444
|
-
configString:
|
|
11445
|
-
|
|
11470
|
+
configString: `r2Storage({
|
|
11471
|
+
bucketName: ${JSON.stringify(resources.bucketName)},
|
|
11472
|
+
accountId: ${accountId},
|
|
11473
|
+
credentials: async () => {
|
|
11474
|
+
const env = await storageSecrets();
|
|
11475
|
+
return {
|
|
11476
|
+
accessKeyId: env.HOT_UPDATER_CLOUDFLARE_R2_ACCESS_KEY_ID,
|
|
11477
|
+
secretAccessKey: env.HOT_UPDATER_CLOUDFLARE_R2_SECRET_ACCESS_KEY,
|
|
11478
|
+
};
|
|
11479
|
+
},
|
|
11480
|
+
})`
|
|
11481
|
+
};
|
|
11482
|
+
const databaseConfig = {
|
|
11483
|
+
imports: [{
|
|
11484
|
+
pkg: "@hot-updater/cloudflare",
|
|
11485
|
+
named: ["d1Database"]
|
|
11486
|
+
}],
|
|
11487
|
+
configString: `d1Database({
|
|
11488
|
+
databaseId: ${JSON.stringify(resources.d1DatabaseId)},
|
|
11489
|
+
accountId: ${accountId},
|
|
11490
|
+
cloudflareApiToken: async () =>
|
|
11491
|
+
(await databaseSecrets()).HOT_UPDATER_CLOUDFLARE_API_TOKEN,
|
|
11492
|
+
})`
|
|
11493
|
+
};
|
|
11494
|
+
const helperStatements = [(0, _hot_updater_cli_tools.secretEnvHelper)("storageSecrets", ["HOT_UPDATER_CLOUDFLARE_R2_ACCESS_KEY_ID", "HOT_UPDATER_CLOUDFLARE_R2_SECRET_ACCESS_KEY"]), (0, _hot_updater_cli_tools.secretEnvHelper)("databaseSecrets", ["HOT_UPDATER_CLOUDFLARE_API_TOKEN"])];
|
|
11495
|
+
return (0, _hot_updater_cli_tools.createHotUpdaterConfigScaffoldFromBuilder)(builder.setStorage(storageConfig).setDatabase(databaseConfig).addImport({
|
|
11496
|
+
pkg: "hot-updater",
|
|
11497
|
+
named: ["secretEnv"]
|
|
11498
|
+
}).setIntermediateCode(helperStatements.map(({ code }) => code).join("\n\n")), { helperStatements });
|
|
11446
11499
|
};
|
|
11447
11500
|
//#endregion
|
|
11448
11501
|
//#region iac/managedWorker.ts
|
|
@@ -11514,10 +11567,10 @@ const deployWorker = async (apiToken, accountId, { credentialSource, d1DatabaseI
|
|
|
11514
11567
|
await removeTmpDir();
|
|
11515
11568
|
}
|
|
11516
11569
|
};
|
|
11517
|
-
const runInit = async ({ build, envFile }) => {
|
|
11570
|
+
const runInit = async ({ build, envFile, secretsEnv }) => {
|
|
11518
11571
|
const cwd = (0, _hot_updater_cli_tools.getCwd)();
|
|
11519
11572
|
const nonInteractive = envFile !== void 0;
|
|
11520
|
-
const initEnvSources = await (0, _hot_updater_cli_tools.readHotUpdaterInitEnv)(cwd, envFile);
|
|
11573
|
+
const initEnvSources = await (0, _hot_updater_cli_tools.readHotUpdaterInitEnv)(cwd, envFile, secretsEnv);
|
|
11521
11574
|
const { managedEnv } = initEnvSources;
|
|
11522
11575
|
const initInputEnv = (0, _hot_updater_cli_tools.getHotUpdaterInitInputEnv)(initEnvSources, nonInteractive);
|
|
11523
11576
|
const existingInputs = resolveCloudflareInitInputs(initInputEnv);
|
|
@@ -11867,7 +11920,11 @@ const runInit = async ({ build, envFile }) => {
|
|
|
11867
11920
|
await database.dispose?.();
|
|
11868
11921
|
}
|
|
11869
11922
|
_hot_updater_cli_tools.p.log.success("Generated '.env.hotupdater' file with Cloudflare settings.");
|
|
11870
|
-
await (0, _hot_updater_cli_tools.writeHotUpdaterFiles)(getConfigScaffold(build
|
|
11923
|
+
await (0, _hot_updater_cli_tools.writeHotUpdaterFiles)(getConfigScaffold(build, {
|
|
11924
|
+
accountId,
|
|
11925
|
+
bucketName: selectedBucketName,
|
|
11926
|
+
d1DatabaseId: selectedD1DatabaseId
|
|
11927
|
+
}), {
|
|
11871
11928
|
cwd,
|
|
11872
11929
|
settings: "Cloudflare"
|
|
11873
11930
|
});
|
package/dist/init/index.d.cts
CHANGED
|
@@ -82,9 +82,10 @@ declare const initProvider: {
|
|
|
82
82
|
readonly validate: (value: string | undefined) => value is "true" | "false";
|
|
83
83
|
};
|
|
84
84
|
};
|
|
85
|
+
readonly secrets: readonly ["HOT_UPDATER_CLOUDFLARE_API_TOKEN", "HOT_UPDATER_CLOUDFLARE_R2_ACCESS_KEY_ID", "HOT_UPDATER_CLOUDFLARE_R2_SECRET_ACCESS_KEY"];
|
|
85
86
|
};
|
|
86
87
|
//#endregion
|
|
87
88
|
//#region iac/index.d.ts
|
|
88
|
-
declare const runInit: ({ build, envFile }: RunInitOptions) => Promise<void>;
|
|
89
|
+
declare const runInit: ({ build, envFile, secretsEnv }: RunInitOptions) => Promise<void>;
|
|
89
90
|
//#endregion
|
|
90
91
|
export { initProvider, runInit };
|
package/dist/init/index.d.mts
CHANGED
|
@@ -82,9 +82,10 @@ declare const initProvider: {
|
|
|
82
82
|
readonly validate: (value: string | undefined) => value is "true" | "false";
|
|
83
83
|
};
|
|
84
84
|
};
|
|
85
|
+
readonly secrets: readonly ["HOT_UPDATER_CLOUDFLARE_API_TOKEN", "HOT_UPDATER_CLOUDFLARE_R2_ACCESS_KEY_ID", "HOT_UPDATER_CLOUDFLARE_R2_SECRET_ACCESS_KEY"];
|
|
85
86
|
};
|
|
86
87
|
//#endregion
|
|
87
88
|
//#region iac/index.d.ts
|
|
88
|
-
declare const runInit: ({ build, envFile }: RunInitOptions) => Promise<void>;
|
|
89
|
+
declare const runInit: ({ build, envFile, secretsEnv }: RunInitOptions) => Promise<void>;
|
|
89
90
|
//#endregion
|
|
90
91
|
export { initProvider, runInit };
|
package/dist/init/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import { ConfigBuilder, InitError, LegacyInfrastructureError, assembleServer, assertInfrastructureGenerationAtUrl, assertInitInputs, assertInitProviderInputs, confirmInitInputPersistence, copyDirToTmp, createHotUpdaterConfigScaffoldFromBuilder, getCwd, getHotUpdaterInitInputEnv, getInitProviderEnvVars, getInitProviderTextPromptValues, link, makeEnv, p, printAppSetup, provisionClientCredential, readHotUpdaterInitEnv, resolveInitProviderInput, writeHotUpdaterFiles } from "@hot-updater/cli-tools";
|
|
3
|
+
import { ConfigBuilder, InitError, LegacyInfrastructureError, assembleServer, assertInfrastructureGenerationAtUrl, assertInitInputs, assertInitProviderInputs, confirmInitInputPersistence, copyDirToTmp, createHotUpdaterConfigScaffoldFromBuilder, getCwd, getHotUpdaterInitInputEnv, getInitProviderEnvVars, getInitProviderTextPromptValues, link, makeEnv, p, printAppSetup, provisionClientCredential, readHotUpdaterInitEnv, resolveInitProviderInput, secretEnvHelper, writeHotUpdaterFiles } from "@hot-updater/cli-tools";
|
|
4
4
|
import { apiKeys, insights, remoteConfig } from "@hot-updater/server/plugins";
|
|
5
5
|
import Cloudflare$1, { Cloudflare } from "cloudflare";
|
|
6
6
|
import { WRITE_GUARD_TABLE, coreSettings, coreTarget, createEngineDatabase, createSqlAdapter, createTableStatements, generateEngineSql } from "@hot-updater/plugin-core";
|
|
@@ -106,7 +106,12 @@ const encode = ({ sql, params }) => ({
|
|
|
106
106
|
* time, or a batch D1 runs in one transaction.
|
|
107
107
|
*/
|
|
108
108
|
const d1RestRunner = (config) => {
|
|
109
|
-
const
|
|
109
|
+
const { cloudflareApiToken } = config;
|
|
110
|
+
let client;
|
|
111
|
+
const connect = () => client ??= (async () => new Cloudflare$1({ apiToken: typeof cloudflareApiToken === "function" ? await cloudflareApiToken() : cloudflareApiToken }))().catch((error) => {
|
|
112
|
+
client = void 0;
|
|
113
|
+
throw error;
|
|
114
|
+
});
|
|
110
115
|
const batch = async (statements) => {
|
|
111
116
|
const [first] = statements;
|
|
112
117
|
if (first === void 0) return [];
|
|
@@ -117,7 +122,7 @@ const d1RestRunner = (config) => {
|
|
|
117
122
|
account_id: config.accountId,
|
|
118
123
|
batch: statements.map(encode)
|
|
119
124
|
};
|
|
120
|
-
const page = await
|
|
125
|
+
const page = await (await connect()).d1.database.query(config.databaseId, body);
|
|
121
126
|
const results = [];
|
|
122
127
|
for await (const resultPage of page.iterPages()) for (const result of resultPage.result) results.push(toSqlResult(result));
|
|
123
128
|
if (results.length !== statements.length) throw new D1ExecutionError();
|
|
@@ -11313,7 +11318,12 @@ const initProvider = {
|
|
|
11313
11318
|
},
|
|
11314
11319
|
validate: (value) => value === "true" || value === "false"
|
|
11315
11320
|
}
|
|
11316
|
-
}
|
|
11321
|
+
},
|
|
11322
|
+
secrets: [
|
|
11323
|
+
"HOT_UPDATER_CLOUDFLARE_API_TOKEN",
|
|
11324
|
+
"HOT_UPDATER_CLOUDFLARE_R2_ACCESS_KEY_ID",
|
|
11325
|
+
"HOT_UPDATER_CLOUDFLARE_R2_SECRET_ACCESS_KEY"
|
|
11326
|
+
]
|
|
11317
11327
|
};
|
|
11318
11328
|
//#endregion
|
|
11319
11329
|
//#region iac/cloudflareInitInputs.ts
|
|
@@ -11401,8 +11411,26 @@ const inputCloudflareInitSecrets = async ({ accountId, bucketName, apiToken, acc
|
|
|
11401
11411
|
};
|
|
11402
11412
|
//#endregion
|
|
11403
11413
|
//#region iac/configTemplate.ts
|
|
11404
|
-
|
|
11405
|
-
|
|
11414
|
+
/**
|
|
11415
|
+
* The config init writes. With the `resources` init set up, it names them,
|
|
11416
|
+
* and reads the API token and R2 keys with `secretEnv`, from the
|
|
11417
|
+
* environment and `.env.hotupdater`, then the config's `secrets` adapter.
|
|
11418
|
+
* Without them, as the agent scaffold writes it, it reads every value from
|
|
11419
|
+
* the environment.
|
|
11420
|
+
*/
|
|
11421
|
+
const getConfigScaffold = (build, resources) => {
|
|
11422
|
+
const builder = new ConfigBuilder().setBuildType(build).setPlugins({
|
|
11423
|
+
imports: [{
|
|
11424
|
+
pkg: "hot-updater/plugins",
|
|
11425
|
+
named: [
|
|
11426
|
+
"apiKeys",
|
|
11427
|
+
"insights",
|
|
11428
|
+
"remoteConfig"
|
|
11429
|
+
]
|
|
11430
|
+
}],
|
|
11431
|
+
configString: "[apiKeys(), insights(), remoteConfig()]"
|
|
11432
|
+
});
|
|
11433
|
+
if (resources === void 0) return createHotUpdaterConfigScaffoldFromBuilder(builder.setStorage({
|
|
11406
11434
|
imports: [{
|
|
11407
11435
|
pkg: "@hot-updater/cloudflare",
|
|
11408
11436
|
named: ["r2Storage"]
|
|
@@ -11425,17 +11453,42 @@ const getConfigScaffold = (build) => {
|
|
|
11425
11453
|
accountId: process.env.HOT_UPDATER_CLOUDFLARE_ACCOUNT_ID!,
|
|
11426
11454
|
cloudflareApiToken: process.env.HOT_UPDATER_CLOUDFLARE_API_TOKEN!,
|
|
11427
11455
|
})`
|
|
11428
|
-
})
|
|
11456
|
+
}));
|
|
11457
|
+
const accountId = JSON.stringify(resources.accountId);
|
|
11458
|
+
const storageConfig = {
|
|
11429
11459
|
imports: [{
|
|
11430
|
-
pkg: "hot-updater/
|
|
11431
|
-
named: [
|
|
11432
|
-
"apiKeys",
|
|
11433
|
-
"insights",
|
|
11434
|
-
"remoteConfig"
|
|
11435
|
-
]
|
|
11460
|
+
pkg: "@hot-updater/cloudflare",
|
|
11461
|
+
named: ["r2Storage"]
|
|
11436
11462
|
}],
|
|
11437
|
-
configString:
|
|
11438
|
-
|
|
11463
|
+
configString: `r2Storage({
|
|
11464
|
+
bucketName: ${JSON.stringify(resources.bucketName)},
|
|
11465
|
+
accountId: ${accountId},
|
|
11466
|
+
credentials: async () => {
|
|
11467
|
+
const env = await storageSecrets();
|
|
11468
|
+
return {
|
|
11469
|
+
accessKeyId: env.HOT_UPDATER_CLOUDFLARE_R2_ACCESS_KEY_ID,
|
|
11470
|
+
secretAccessKey: env.HOT_UPDATER_CLOUDFLARE_R2_SECRET_ACCESS_KEY,
|
|
11471
|
+
};
|
|
11472
|
+
},
|
|
11473
|
+
})`
|
|
11474
|
+
};
|
|
11475
|
+
const databaseConfig = {
|
|
11476
|
+
imports: [{
|
|
11477
|
+
pkg: "@hot-updater/cloudflare",
|
|
11478
|
+
named: ["d1Database"]
|
|
11479
|
+
}],
|
|
11480
|
+
configString: `d1Database({
|
|
11481
|
+
databaseId: ${JSON.stringify(resources.d1DatabaseId)},
|
|
11482
|
+
accountId: ${accountId},
|
|
11483
|
+
cloudflareApiToken: async () =>
|
|
11484
|
+
(await databaseSecrets()).HOT_UPDATER_CLOUDFLARE_API_TOKEN,
|
|
11485
|
+
})`
|
|
11486
|
+
};
|
|
11487
|
+
const helperStatements = [secretEnvHelper("storageSecrets", ["HOT_UPDATER_CLOUDFLARE_R2_ACCESS_KEY_ID", "HOT_UPDATER_CLOUDFLARE_R2_SECRET_ACCESS_KEY"]), secretEnvHelper("databaseSecrets", ["HOT_UPDATER_CLOUDFLARE_API_TOKEN"])];
|
|
11488
|
+
return createHotUpdaterConfigScaffoldFromBuilder(builder.setStorage(storageConfig).setDatabase(databaseConfig).addImport({
|
|
11489
|
+
pkg: "hot-updater",
|
|
11490
|
+
named: ["secretEnv"]
|
|
11491
|
+
}).setIntermediateCode(helperStatements.map(({ code }) => code).join("\n\n")), { helperStatements });
|
|
11439
11492
|
};
|
|
11440
11493
|
//#endregion
|
|
11441
11494
|
//#region iac/managedWorker.ts
|
|
@@ -11507,10 +11560,10 @@ const deployWorker = async (apiToken, accountId, { credentialSource, d1DatabaseI
|
|
|
11507
11560
|
await removeTmpDir();
|
|
11508
11561
|
}
|
|
11509
11562
|
};
|
|
11510
|
-
const runInit = async ({ build, envFile }) => {
|
|
11563
|
+
const runInit = async ({ build, envFile, secretsEnv }) => {
|
|
11511
11564
|
const cwd = getCwd();
|
|
11512
11565
|
const nonInteractive = envFile !== void 0;
|
|
11513
|
-
const initEnvSources = await readHotUpdaterInitEnv(cwd, envFile);
|
|
11566
|
+
const initEnvSources = await readHotUpdaterInitEnv(cwd, envFile, secretsEnv);
|
|
11514
11567
|
const { managedEnv } = initEnvSources;
|
|
11515
11568
|
const initInputEnv = getHotUpdaterInitInputEnv(initEnvSources, nonInteractive);
|
|
11516
11569
|
const existingInputs = resolveCloudflareInitInputs(initInputEnv);
|
|
@@ -11860,7 +11913,11 @@ const runInit = async ({ build, envFile }) => {
|
|
|
11860
11913
|
await database.dispose?.();
|
|
11861
11914
|
}
|
|
11862
11915
|
p.log.success("Generated '.env.hotupdater' file with Cloudflare settings.");
|
|
11863
|
-
await writeHotUpdaterFiles(getConfigScaffold(build
|
|
11916
|
+
await writeHotUpdaterFiles(getConfigScaffold(build, {
|
|
11917
|
+
accountId,
|
|
11918
|
+
bucketName: selectedBucketName,
|
|
11919
|
+
d1DatabaseId: selectedD1DatabaseId
|
|
11920
|
+
}), {
|
|
11864
11921
|
cwd,
|
|
11865
11922
|
settings: "Cloudflare"
|
|
11866
11923
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hot-updater/cloudflare",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.2.0-rc.
|
|
4
|
+
"version": "1.2.0-rc.5",
|
|
5
5
|
"description": "React Native OTA solution for self-hosted",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
7
7
|
"module": "dist/index.mjs",
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
"cloudflare": "4.2.0",
|
|
56
56
|
"hono": "4.12.34",
|
|
57
57
|
"uuidv7": "^1.0.2",
|
|
58
|
-
"@hot-updater/cli-tools": "1.2.0-rc.
|
|
59
|
-
"@hot-updater/
|
|
60
|
-
"@hot-updater/
|
|
61
|
-
"@hot-updater/server": "1.2.0-rc.
|
|
58
|
+
"@hot-updater/cli-tools": "1.2.0-rc.5",
|
|
59
|
+
"@hot-updater/protocol": "1.2.0-rc.5",
|
|
60
|
+
"@hot-updater/plugin-core": "1.2.0-rc.5",
|
|
61
|
+
"@hot-updater/server": "1.2.0-rc.5"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@cloudflare/vitest-pool-workers": "0.13.0",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"vitest": "4.1.4",
|
|
75
75
|
"wrangler": "^4.69.0",
|
|
76
76
|
"xdg-app-paths": "^8.3.0",
|
|
77
|
-
"@hot-updater/test-utils": "1.2.0-rc.
|
|
77
|
+
"@hot-updater/test-utils": "1.2.0-rc.5"
|
|
78
78
|
},
|
|
79
79
|
"scripts": {
|
|
80
80
|
"build": "tsdown && pnpm build:worker",
|
package/src/d1Rest.ts
CHANGED
|
@@ -6,7 +6,12 @@ import { D1ExecutionError, type D1ResultLike, toSqlResult } from "./d1Executor";
|
|
|
6
6
|
export interface D1RestConfig {
|
|
7
7
|
readonly databaseId: string;
|
|
8
8
|
readonly accountId: string;
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* An API token with D1 edit permission, or a function that returns it,
|
|
11
|
+
* such as one that reads it with `secretEnv`: called on the first query,
|
|
12
|
+
* so a config loads without the token.
|
|
13
|
+
*/
|
|
14
|
+
readonly cloudflareApiToken: string | (() => string | Promise<string>);
|
|
10
15
|
}
|
|
11
16
|
|
|
12
17
|
/** The REST API binds text: each value goes as JSON and is read back with `json_extract`. */
|
|
@@ -21,9 +26,19 @@ const encode = ({ sql, params }: SqlStatement) => ({
|
|
|
21
26
|
* time, or a batch D1 runs in one transaction.
|
|
22
27
|
*/
|
|
23
28
|
export const d1RestRunner = (config: D1RestConfig) => {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
const { cloudflareApiToken } = config;
|
|
30
|
+
let client: Promise<Cloudflare> | undefined;
|
|
31
|
+
const connect = () =>
|
|
32
|
+
(client ??= (async () =>
|
|
33
|
+
new Cloudflare({
|
|
34
|
+
apiToken:
|
|
35
|
+
typeof cloudflareApiToken === "function"
|
|
36
|
+
? await cloudflareApiToken()
|
|
37
|
+
: cloudflareApiToken,
|
|
38
|
+
}))().catch((error: unknown) => {
|
|
39
|
+
client = undefined;
|
|
40
|
+
throw error;
|
|
41
|
+
}));
|
|
27
42
|
const batch = async (
|
|
28
43
|
statements: readonly SqlStatement[],
|
|
29
44
|
): Promise<SqlResult[]> => {
|
|
@@ -33,6 +48,7 @@ export const d1RestRunner = (config: D1RestConfig) => {
|
|
|
33
48
|
statements.length === 1
|
|
34
49
|
? { account_id: config.accountId, ...encode(first) }
|
|
35
50
|
: { account_id: config.accountId, batch: statements.map(encode) };
|
|
51
|
+
const cloudflare = await connect();
|
|
36
52
|
// cloudflare@4 predates the D1 REST API's parameterized batch body type.
|
|
37
53
|
const page = await cloudflare.d1.database.query(
|
|
38
54
|
config.databaseId,
|
package/worker/dist/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
This folder contains the built output assets for the worker "hot-updater" generated at 2026-10-
|
|
1
|
+
This folder contains the built output assets for the worker "hot-updater" generated at 2026-10-28T17:24:58.490Z.
|
package/worker/dist/index.js
CHANGED
|
@@ -4632,7 +4632,7 @@ var createSqlAdapter = /* @__PURE__ */ __name(({ executor, tablePrefix = "", max
|
|
|
4632
4632
|
}, "createSqlAdapter");
|
|
4633
4633
|
|
|
4634
4634
|
// ../../packages/server/dist/package.mjs
|
|
4635
|
-
var version = "1.2.0-rc.
|
|
4635
|
+
var version = "1.2.0-rc.5";
|
|
4636
4636
|
|
|
4637
4637
|
// ../../packages/server/dist/version.mjs
|
|
4638
4638
|
var HOT_UPDATER_SERVER_VERSION = version;
|