wrangler 0.0.0-e6c9c5c0 → 0.0.0-e6e1daba
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/README.md +3 -3
- package/miniflare-dist/index.mjs +22 -18
- package/package.json +12 -12
- package/src/__tests__/configuration.test.ts +70 -0
- package/src/__tests__/d1/d1.test.ts +13 -58
- package/src/__tests__/d1/execute.test.ts +64 -0
- package/src/__tests__/d1/migrate.test.ts +155 -0
- package/src/__tests__/deployments.test.ts +40 -16
- package/src/__tests__/dev.test.tsx +8 -7
- package/src/__tests__/generate.test.ts +1 -1
- package/src/__tests__/guess-worker-format.test.ts +35 -0
- package/src/__tests__/helpers/end-event-loop.ts +6 -0
- package/src/__tests__/helpers/mock-get-pages-upload-token.ts +25 -0
- package/src/__tests__/helpers/mock-set-timeout.ts +16 -0
- package/src/__tests__/helpers/msw/handlers/deployments.ts +40 -16
- package/src/__tests__/helpers/string-dynamic-values-matcher.ts +28 -0
- package/src/__tests__/index.test.ts +38 -32
- package/src/__tests__/init.test.ts +1 -1
- package/src/__tests__/kv.test.ts +63 -52
- package/src/__tests__/middleware.test.ts +65 -0
- package/src/__tests__/mtls-certificates.test.ts +585 -0
- package/src/__tests__/pages/deployment-list.test.ts +78 -0
- package/src/__tests__/pages/functions-build.test.ts +402 -0
- package/src/__tests__/pages/pages.test.ts +81 -0
- package/src/__tests__/pages/project-create.test.ts +63 -0
- package/src/__tests__/pages/project-list.test.ts +108 -0
- package/src/__tests__/pages/project-upload.test.ts +481 -0
- package/src/__tests__/pages/publish.test.ts +2745 -0
- package/src/__tests__/parse.test.ts +106 -0
- package/src/__tests__/publish.test.ts +80 -30
- package/src/__tests__/pubsub.test.ts +15 -12
- package/src/__tests__/queues.test.ts +37 -30
- package/src/__tests__/r2.test.ts +25 -20
- package/src/__tests__/secret.test.ts +4 -4
- package/src/__tests__/tsconfig.tsbuildinfo +1 -1
- package/src/__tests__/user.test.ts +1 -1
- package/src/__tests__/whoami.test.tsx +1 -1
- package/src/__tests__/worker-namespace.test.ts +26 -21
- package/src/api/dev.ts +80 -11
- package/src/api/index.ts +8 -0
- package/src/api/mtls-certificate.ts +148 -0
- package/src/api/pages/create-worker-bundle-contents.ts +75 -0
- package/src/api/pages/publish.tsx +59 -12
- package/src/bundle.ts +9 -7
- package/src/config/config.ts +14 -7
- package/src/config/environment.ts +9 -2
- package/src/config/index.ts +37 -20
- package/src/config/validation.ts +50 -3
- package/src/create-worker-preview.ts +19 -8
- package/src/create-worker-upload-form.ts +9 -0
- package/src/d1/backups.tsx +20 -24
- package/src/d1/create.tsx +6 -5
- package/src/d1/delete.ts +7 -10
- package/src/d1/execute.tsx +174 -143
- package/src/d1/index.ts +5 -6
- package/src/d1/list.tsx +21 -9
- package/src/d1/migrations/apply.tsx +42 -33
- package/src/d1/migrations/create.tsx +16 -17
- package/src/d1/migrations/helpers.ts +63 -38
- package/src/d1/migrations/list.tsx +37 -24
- package/src/d1/migrations/options.ts +7 -2
- package/src/d1/options.ts +3 -3
- package/src/d1/types.ts +1 -0
- package/src/d1/utils.ts +2 -1
- package/src/delete.ts +5 -8
- package/src/deployments.ts +62 -39
- package/src/deprecated/index.ts +7 -8
- package/src/dev/dev.tsx +1 -15
- package/src/dev/local.tsx +5 -6
- package/src/dev/remote.tsx +2 -2
- package/src/dev.tsx +51 -86
- package/src/dispatch-namespace.ts +20 -16
- package/src/docs/index.ts +7 -8
- package/src/entry.ts +1 -2
- package/src/generate/index.ts +6 -8
- package/src/index.ts +37 -26
- package/src/init.ts +5 -7
- package/src/inspect.ts +16 -1
- package/src/kv/index.ts +15 -17
- package/src/miniflare-cli/assets.ts +9 -8
- package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -1
- package/src/mtls-certificate/cli.ts +155 -0
- package/src/pages/build.ts +109 -27
- package/src/pages/buildFunctions.ts +32 -31
- package/src/pages/deployment-tails.ts +7 -10
- package/src/pages/deployments.tsx +6 -4
- package/src/pages/dev.ts +19 -19
- package/src/pages/functions/tsconfig.tsbuildinfo +1 -1
- package/src/pages/functions.ts +8 -4
- package/src/pages/index.ts +3 -3
- package/src/pages/projects.tsx +7 -12
- package/src/pages/publish.tsx +18 -5
- package/src/pages/types.ts +5 -0
- package/src/pages/upload.tsx +6 -4
- package/src/pages/utils.ts +1 -1
- package/src/parse.ts +23 -1
- package/src/publish/index.ts +19 -15
- package/src/publish/publish.ts +5 -4
- package/src/pubsub/pubsub-commands.ts +18 -19
- package/src/queues/cli/commands/consumer/add.ts +18 -24
- package/src/queues/cli/commands/consumer/index.ts +3 -6
- package/src/queues/cli/commands/consumer/remove.ts +11 -18
- package/src/queues/cli/commands/create.ts +8 -8
- package/src/queues/cli/commands/delete.ts +8 -8
- package/src/queues/cli/commands/index.ts +3 -4
- package/src/queues/cli/commands/list.ts +8 -8
- package/src/r2/helpers.ts +1 -0
- package/src/r2/index.ts +28 -28
- package/src/secret/index.ts +10 -14
- package/src/sites.ts +1 -1
- package/src/tail/filters.ts +1 -1
- package/src/tail/index.ts +6 -8
- package/src/user/user.ts +4 -3
- package/src/worker.ts +6 -0
- package/src/yargs-types.ts +18 -5
- package/templates/checked-fetch.js +9 -1
- package/templates/format-dev-errors.ts +1 -0
- package/templates/new-worker.ts +3 -0
- package/templates/pages-template-plugin.ts +7 -3
- package/templates/serve-static-assets.ts +1 -0
- package/templates/service-bindings-module-facade.js +1 -0
- package/templates/tsconfig.init.json +1 -1
- package/templates/tsconfig.tsbuildinfo +1 -1
- package/wrangler-dist/cli.d.ts +596 -3
- package/wrangler-dist/cli.js +14276 -6748
- package/src/__tests__/pages.test.ts +0 -2898
package/src/d1/execute.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import Table from "ink-table";
|
|
|
7
7
|
import { npxImport } from "npx-import";
|
|
8
8
|
import React from "react";
|
|
9
9
|
import { fetchResult } from "../cfetch";
|
|
10
|
-
import {
|
|
10
|
+
import { readConfig } from "../config";
|
|
11
11
|
import { getLocalPersistencePath } from "../dev/get-local-persistence-path";
|
|
12
12
|
import { confirm } from "../dialogs";
|
|
13
13
|
import { logger } from "../logger";
|
|
@@ -22,32 +22,11 @@ import {
|
|
|
22
22
|
getDatabaseInfoFromConfig,
|
|
23
23
|
} from "./utils";
|
|
24
24
|
import type { Config, ConfigFields, DevConfig, Environment } from "../config";
|
|
25
|
+
import type {
|
|
26
|
+
CommonYargsArgv,
|
|
27
|
+
StrictYargsOptionsToInterface,
|
|
28
|
+
} from "../yargs-types";
|
|
25
29
|
import type { Database } from "./types";
|
|
26
|
-
import type { Statement as StatementType } from "@miniflare/d1";
|
|
27
|
-
import type { createSQLiteDB as createSQLiteDBType } from "@miniflare/shared";
|
|
28
|
-
import type { Argv } from "yargs";
|
|
29
|
-
|
|
30
|
-
type MiniflareNpxImportTypes = [
|
|
31
|
-
{
|
|
32
|
-
Statement: typeof StatementType;
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
createSQLiteDB: typeof createSQLiteDBType;
|
|
36
|
-
}
|
|
37
|
-
];
|
|
38
|
-
|
|
39
|
-
export type BaseSqlExecuteArgs = {
|
|
40
|
-
config?: string;
|
|
41
|
-
database: string;
|
|
42
|
-
local?: boolean;
|
|
43
|
-
"persist-to"?: string;
|
|
44
|
-
yes?: boolean;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
type ExecuteArgs = BaseSqlExecuteArgs & {
|
|
48
|
-
file?: string;
|
|
49
|
-
command?: string;
|
|
50
|
-
};
|
|
51
30
|
|
|
52
31
|
export type QueryResult = {
|
|
53
32
|
results: Record<string, string | number | boolean>[];
|
|
@@ -60,7 +39,7 @@ export type QueryResult = {
|
|
|
60
39
|
// Max number of bytes to send in a single /execute call
|
|
61
40
|
const QUERY_LIMIT = 10_000;
|
|
62
41
|
|
|
63
|
-
export function Options(yargs:
|
|
42
|
+
export function Options(yargs: CommonYargsArgv) {
|
|
64
43
|
return options
|
|
65
44
|
.Database(yargs)
|
|
66
45
|
.option("yes", {
|
|
@@ -74,7 +53,7 @@ export function Options(yargs: Argv): Argv<ExecuteArgs> {
|
|
|
74
53
|
type: "boolean",
|
|
75
54
|
})
|
|
76
55
|
.option("file", {
|
|
77
|
-
describe: "A .sql file to
|
|
56
|
+
describe: "A .sql file to ingest",
|
|
78
57
|
type: "string",
|
|
79
58
|
})
|
|
80
59
|
.option("command", {
|
|
@@ -85,30 +64,106 @@ export function Options(yargs: Argv): Argv<ExecuteArgs> {
|
|
|
85
64
|
describe: "Specify directory to use for local persistence (for --local)",
|
|
86
65
|
type: "string",
|
|
87
66
|
requiresArg: true,
|
|
67
|
+
})
|
|
68
|
+
.option("json", {
|
|
69
|
+
describe: "Return output as clean JSON",
|
|
70
|
+
type: "boolean",
|
|
71
|
+
default: false,
|
|
72
|
+
})
|
|
73
|
+
.option("preview", {
|
|
74
|
+
describe: "Execute commands/files against a preview D1 DB",
|
|
75
|
+
type: "boolean",
|
|
76
|
+
default: false,
|
|
88
77
|
});
|
|
89
78
|
}
|
|
90
79
|
|
|
91
|
-
|
|
92
|
-
return query && query.length > length
|
|
93
|
-
? query.slice(0, length) + "..."
|
|
94
|
-
: query;
|
|
95
|
-
}
|
|
80
|
+
type HandlerOptions = StrictYargsOptionsToInterface<typeof Options>;
|
|
96
81
|
|
|
97
|
-
export async
|
|
98
|
-
local
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
)
|
|
106
|
-
|
|
82
|
+
export const Handler = async (args: HandlerOptions): Promise<void> => {
|
|
83
|
+
const { local, database, yes, persistTo, file, command, json, preview } =
|
|
84
|
+
args;
|
|
85
|
+
const existingLogLevel = logger.loggerLevel;
|
|
86
|
+
if (json) {
|
|
87
|
+
// set loggerLevel to error to avoid readConfig warnings appearing in JSON output
|
|
88
|
+
logger.loggerLevel = "error";
|
|
89
|
+
}
|
|
90
|
+
const config = readConfig(args.config, args);
|
|
91
|
+
logger.log(d1BetaWarning);
|
|
92
|
+
if (file && command)
|
|
93
|
+
return logger.error(`Error: can't provide both --command and --file.`);
|
|
107
94
|
|
|
95
|
+
const isInteractive = process.stdout.isTTY;
|
|
96
|
+
const response: QueryResult[] | null = await executeSql({
|
|
97
|
+
local,
|
|
98
|
+
config,
|
|
99
|
+
name: database,
|
|
100
|
+
shouldPrompt: isInteractive && !yes,
|
|
101
|
+
persistTo,
|
|
102
|
+
file,
|
|
103
|
+
command,
|
|
104
|
+
json,
|
|
105
|
+
preview,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Early exit if prompt rejected
|
|
109
|
+
if (!response) return;
|
|
110
|
+
|
|
111
|
+
if (isInteractive && !json) {
|
|
112
|
+
// Render table if single result
|
|
113
|
+
render(
|
|
114
|
+
<Static items={response}>
|
|
115
|
+
{(result) => {
|
|
116
|
+
// batch results
|
|
117
|
+
if (!Array.isArray(result)) {
|
|
118
|
+
const { results, query } = result;
|
|
119
|
+
|
|
120
|
+
if (Array.isArray(results) && results.length > 0) {
|
|
121
|
+
const shortQuery = shorten(query, 48);
|
|
122
|
+
return (
|
|
123
|
+
<>
|
|
124
|
+
{shortQuery ? <Text dimColor>{shortQuery}</Text> : null}
|
|
125
|
+
<Table data={results}></Table>
|
|
126
|
+
</>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}}
|
|
131
|
+
</Static>
|
|
132
|
+
);
|
|
133
|
+
} else {
|
|
134
|
+
// set loggerLevel back to what it was before to actually output the JSON in stdout
|
|
135
|
+
logger.loggerLevel = existingLogLevel;
|
|
136
|
+
logger.log(JSON.stringify(response, null, 2));
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export async function executeSql({
|
|
141
|
+
local,
|
|
142
|
+
config,
|
|
143
|
+
name,
|
|
144
|
+
shouldPrompt,
|
|
145
|
+
persistTo,
|
|
146
|
+
file,
|
|
147
|
+
command,
|
|
148
|
+
json,
|
|
149
|
+
preview,
|
|
150
|
+
}: {
|
|
151
|
+
local: boolean | undefined;
|
|
152
|
+
config: ConfigFields<DevConfig> & Environment;
|
|
153
|
+
name: string;
|
|
154
|
+
shouldPrompt: boolean | undefined;
|
|
155
|
+
persistTo: string | undefined;
|
|
156
|
+
file: string | undefined;
|
|
157
|
+
command: string | undefined;
|
|
158
|
+
json: boolean | undefined;
|
|
159
|
+
preview: boolean | undefined;
|
|
160
|
+
}) {
|
|
161
|
+
const sql = file ? readFileSync(file) : command;
|
|
108
162
|
if (!sql) throw new Error(`Error: must provide --command or --file.`);
|
|
163
|
+
if (preview && local)
|
|
164
|
+
throw new Error(`Error: can't use --preview with --local`);
|
|
109
165
|
if (persistTo && !local)
|
|
110
166
|
throw new Error(`Error: can't use --persist-to without --local`);
|
|
111
|
-
|
|
112
167
|
logger.log(`🌀 Mapping SQL input into an array of statements`);
|
|
113
168
|
const queries = splitSqlQuery(sql);
|
|
114
169
|
|
|
@@ -122,73 +177,39 @@ export async function executeSql(
|
|
|
122
177
|
}
|
|
123
178
|
|
|
124
179
|
return local
|
|
125
|
-
? await executeLocally(
|
|
126
|
-
|
|
180
|
+
? await executeLocally({
|
|
181
|
+
config,
|
|
182
|
+
name,
|
|
183
|
+
shouldPrompt,
|
|
184
|
+
queries,
|
|
185
|
+
persistTo,
|
|
186
|
+
json,
|
|
187
|
+
})
|
|
188
|
+
: await executeRemotely({
|
|
189
|
+
config,
|
|
190
|
+
name,
|
|
191
|
+
shouldPrompt,
|
|
192
|
+
batches: batchSplit(queries),
|
|
193
|
+
json,
|
|
194
|
+
preview,
|
|
195
|
+
});
|
|
127
196
|
}
|
|
128
197
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const response: QueryResult[] | null = await executeSql(
|
|
145
|
-
local,
|
|
146
|
-
config,
|
|
147
|
-
database,
|
|
148
|
-
isInteractive && !yes,
|
|
149
|
-
persistTo,
|
|
150
|
-
file,
|
|
151
|
-
command
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
// Early exit if prompt rejected
|
|
155
|
-
if (!response) return;
|
|
156
|
-
|
|
157
|
-
if (isInteractive) {
|
|
158
|
-
// Render table if single result
|
|
159
|
-
render(
|
|
160
|
-
<Static items={response}>
|
|
161
|
-
{(result) => {
|
|
162
|
-
// batch results
|
|
163
|
-
if (!Array.isArray(result)) {
|
|
164
|
-
const { results, query } = result;
|
|
165
|
-
|
|
166
|
-
if (Array.isArray(results) && results.length > 0) {
|
|
167
|
-
const shortQuery = shorten(query, 48);
|
|
168
|
-
return (
|
|
169
|
-
<>
|
|
170
|
-
{shortQuery ? <Text dimColor>{shortQuery}</Text> : null}
|
|
171
|
-
<Table data={results}></Table>
|
|
172
|
-
</>
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}}
|
|
177
|
-
</Static>
|
|
178
|
-
);
|
|
179
|
-
} else {
|
|
180
|
-
logger.log(JSON.stringify(response, null, 2));
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
async function executeLocally(
|
|
186
|
-
config: Config,
|
|
187
|
-
name: string,
|
|
188
|
-
shouldPrompt: boolean | undefined,
|
|
189
|
-
queries: string[],
|
|
190
|
-
persistTo: string | undefined
|
|
191
|
-
) {
|
|
198
|
+
async function executeLocally({
|
|
199
|
+
config,
|
|
200
|
+
name,
|
|
201
|
+
shouldPrompt,
|
|
202
|
+
queries,
|
|
203
|
+
persistTo,
|
|
204
|
+
json,
|
|
205
|
+
}: {
|
|
206
|
+
config: Config;
|
|
207
|
+
name: string;
|
|
208
|
+
shouldPrompt: boolean | undefined;
|
|
209
|
+
queries: string[];
|
|
210
|
+
persistTo: string | undefined;
|
|
211
|
+
json: boolean | undefined;
|
|
212
|
+
}) {
|
|
192
213
|
const localDB = getDatabaseInfoFromConfig(config, name);
|
|
193
214
|
if (!localDB) {
|
|
194
215
|
throw new Error(
|
|
@@ -204,40 +225,46 @@ async function executeLocally(
|
|
|
204
225
|
|
|
205
226
|
const dbDir = path.join(persistencePath, "d1");
|
|
206
227
|
const dbPath = path.join(dbDir, `${localDB.binding}.sqlite3`);
|
|
207
|
-
const [{
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
228
|
+
const [{ D1Database, D1DatabaseAPI }, { createSQLiteDB }] = await npxImport<
|
|
229
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
230
|
+
[typeof import("@miniflare/d1"), typeof import("@miniflare/shared")]
|
|
231
|
+
>(["@miniflare/d1", "@miniflare/shared"], logger.log);
|
|
232
|
+
|
|
233
|
+
if (!existsSync(dbDir)) {
|
|
234
|
+
const ok =
|
|
235
|
+
json ||
|
|
236
|
+
!shouldPrompt ||
|
|
237
|
+
(await confirm(`About to create ${readableRelative(dbPath)}, ok?`));
|
|
217
238
|
if (!ok) return null;
|
|
218
239
|
await mkdir(dbDir, { recursive: true });
|
|
219
240
|
}
|
|
220
241
|
|
|
221
242
|
logger.log(`🌀 Loading DB at ${readableRelative(dbPath)}`);
|
|
222
|
-
const db = await createSQLiteDB(dbPath);
|
|
223
|
-
|
|
224
|
-
const results: QueryResult[] = [];
|
|
225
|
-
for (const sql of queries) {
|
|
226
|
-
const statement = new Statement(db, sql);
|
|
227
|
-
results.push((await statement.all()) as QueryResult);
|
|
228
|
-
}
|
|
229
243
|
|
|
230
|
-
|
|
244
|
+
const sqliteDb = await createSQLiteDB(dbPath);
|
|
245
|
+
const db = new D1Database(new D1DatabaseAPI(sqliteDb));
|
|
246
|
+
const stmts = queries.map((query) => db.prepare(query));
|
|
247
|
+
return (await db.batch(stmts)) as QueryResult[];
|
|
231
248
|
}
|
|
232
249
|
|
|
233
|
-
async function executeRemotely(
|
|
234
|
-
config
|
|
235
|
-
name
|
|
236
|
-
shouldPrompt
|
|
237
|
-
batches
|
|
238
|
-
|
|
250
|
+
async function executeRemotely({
|
|
251
|
+
config,
|
|
252
|
+
name,
|
|
253
|
+
shouldPrompt,
|
|
254
|
+
batches,
|
|
255
|
+
json,
|
|
256
|
+
preview,
|
|
257
|
+
}: {
|
|
258
|
+
config: Config;
|
|
259
|
+
name: string;
|
|
260
|
+
shouldPrompt: boolean | undefined;
|
|
261
|
+
batches: string[];
|
|
262
|
+
json: boolean | undefined;
|
|
263
|
+
preview: boolean | undefined;
|
|
264
|
+
}) {
|
|
239
265
|
const multiple_batches = batches.length > 1;
|
|
240
|
-
|
|
266
|
+
// in JSON mode, we don't want a prompt here
|
|
267
|
+
if (multiple_batches && !json) {
|
|
241
268
|
const warning = `⚠️ Too much SQL to send at once, this execution will be sent as ${batches.length} batches.`;
|
|
242
269
|
|
|
243
270
|
if (shouldPrompt) {
|
|
@@ -257,15 +284,13 @@ async function executeRemotely(
|
|
|
257
284
|
accountId,
|
|
258
285
|
name
|
|
259
286
|
);
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
// Don't output if shouldPrompt is undefined
|
|
265
|
-
} else if (shouldPrompt !== undefined) {
|
|
266
|
-
// Pipe to error so we don't break jq
|
|
267
|
-
logger.error(`Executing on ${name} (${db.uuid}):`);
|
|
287
|
+
if (preview && !db.previewDatabaseUuid) {
|
|
288
|
+
throw logger.error(
|
|
289
|
+
"Please define a `preview_database_id` in your wrangler.toml to execute your queries against a preview database"
|
|
290
|
+
);
|
|
268
291
|
}
|
|
292
|
+
const dbUuid = preview ? db.previewDatabaseUuid : db.uuid;
|
|
293
|
+
logger.log(`🌀 Executing on ${name} (${dbUuid}):`);
|
|
269
294
|
|
|
270
295
|
const results: QueryResult[] = [];
|
|
271
296
|
for (const sql of batches) {
|
|
@@ -275,7 +300,7 @@ async function executeRemotely(
|
|
|
275
300
|
);
|
|
276
301
|
|
|
277
302
|
const result = await fetchResult<QueryResult[]>(
|
|
278
|
-
`/accounts/${accountId}/d1/database/${
|
|
303
|
+
`/accounts/${accountId}/d1/database/${dbUuid}/query`,
|
|
279
304
|
{
|
|
280
305
|
method: "POST",
|
|
281
306
|
headers: {
|
|
@@ -321,3 +346,9 @@ function batchSplit(queries: string[]) {
|
|
|
321
346
|
}
|
|
322
347
|
return batches;
|
|
323
348
|
}
|
|
349
|
+
|
|
350
|
+
function shorten(query: string | undefined, length: number) {
|
|
351
|
+
return query && query.length > length
|
|
352
|
+
? query.slice(0, length) + "..."
|
|
353
|
+
: query;
|
|
354
|
+
}
|
package/src/d1/index.ts
CHANGED
|
@@ -5,10 +5,9 @@ import * as Execute from "./execute";
|
|
|
5
5
|
import * as List from "./list";
|
|
6
6
|
import * as Migrations from "./migrations";
|
|
7
7
|
import { d1BetaWarning } from "./utils";
|
|
8
|
-
import type {
|
|
9
|
-
import type { Argv } from "yargs";
|
|
8
|
+
import type { CommonYargsArgv } from "../yargs-types";
|
|
10
9
|
|
|
11
|
-
export
|
|
10
|
+
export function d1(yargs: CommonYargsArgv) {
|
|
12
11
|
return (
|
|
13
12
|
yargs
|
|
14
13
|
.command("list", "List D1 databases", List.Options, List.Handler)
|
|
@@ -24,8 +23,8 @@ export const d1 = (yargs: Argv<CommonYargsOptions>) => {
|
|
|
24
23
|
Delete.Options,
|
|
25
24
|
Delete.Handler
|
|
26
25
|
)
|
|
27
|
-
.command("backup", "Interact with D1 Backups", (
|
|
28
|
-
|
|
26
|
+
.command("backup", "Interact with D1 Backups", (backupArgs) =>
|
|
27
|
+
backupArgs
|
|
29
28
|
.demandCommand()
|
|
30
29
|
.command(
|
|
31
30
|
"list <name>",
|
|
@@ -98,4 +97,4 @@ export const d1 = (yargs: Argv<CommonYargsOptions>) => {
|
|
|
98
97
|
)
|
|
99
98
|
.epilogue(d1BetaWarning)
|
|
100
99
|
);
|
|
101
|
-
}
|
|
100
|
+
}
|
package/src/d1/list.tsx
CHANGED
|
@@ -5,22 +5,34 @@ import { fetchResult } from "../cfetch";
|
|
|
5
5
|
import { logger } from "../logger";
|
|
6
6
|
import { requireAuth } from "../user";
|
|
7
7
|
import { d1BetaWarning } from "./utils";
|
|
8
|
+
import type {
|
|
9
|
+
CommonYargsArgv,
|
|
10
|
+
StrictYargsOptionsToInterface,
|
|
11
|
+
} from "../yargs-types";
|
|
8
12
|
import type { Database } from "./types";
|
|
9
|
-
import type { ArgumentsCamelCase, Argv } from "yargs";
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
export function Options(d1ListYargs: CommonYargsArgv) {
|
|
15
|
+
return d1ListYargs
|
|
16
|
+
.option("json", {
|
|
17
|
+
describe: "return output as clean JSON",
|
|
18
|
+
type: "boolean",
|
|
19
|
+
default: false,
|
|
20
|
+
})
|
|
21
|
+
.epilogue(d1BetaWarning);
|
|
15
22
|
}
|
|
16
23
|
|
|
17
|
-
export async function Handler(
|
|
24
|
+
export async function Handler({
|
|
25
|
+
json,
|
|
26
|
+
}: StrictYargsOptionsToInterface<typeof Options>): Promise<void> {
|
|
18
27
|
const accountId = await requireAuth({});
|
|
19
|
-
logger.log(d1BetaWarning);
|
|
20
|
-
|
|
21
28
|
const dbs: Array<Database> = await listDatabases(accountId);
|
|
22
29
|
|
|
23
|
-
|
|
30
|
+
if (json) {
|
|
31
|
+
logger.log(JSON.stringify(dbs, null, 2));
|
|
32
|
+
} else {
|
|
33
|
+
logger.log(d1BetaWarning);
|
|
34
|
+
render(<Table data={dbs}></Table>);
|
|
35
|
+
}
|
|
24
36
|
}
|
|
25
37
|
|
|
26
38
|
export const listDatabases = async (
|
|
@@ -19,20 +19,24 @@ import {
|
|
|
19
19
|
getUnappliedMigrations,
|
|
20
20
|
initMigrationsTable,
|
|
21
21
|
} from "./helpers";
|
|
22
|
-
import {
|
|
22
|
+
import { MigrationOptions } from "./options";
|
|
23
23
|
import type { ParseError } from "../../parse";
|
|
24
|
-
import type {
|
|
25
|
-
|
|
24
|
+
import type {
|
|
25
|
+
CommonYargsArgv,
|
|
26
|
+
StrictYargsOptionsToInterface,
|
|
27
|
+
} from "../../yargs-types";
|
|
26
28
|
|
|
27
|
-
export function ApplyOptions(yargs:
|
|
28
|
-
return
|
|
29
|
+
export function ApplyOptions(yargs: CommonYargsArgv) {
|
|
30
|
+
return MigrationOptions(yargs);
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
type ApplyHandlerOptions = StrictYargsOptionsToInterface<typeof ApplyOptions>;
|
|
34
|
+
|
|
35
|
+
export const ApplyHandler = withConfig<ApplyHandlerOptions>(
|
|
36
|
+
async ({ config, database, local, persistTo, preview }): Promise<void> => {
|
|
33
37
|
logger.log(d1BetaWarning);
|
|
34
38
|
|
|
35
|
-
const databaseInfo =
|
|
39
|
+
const databaseInfo = getDatabaseInfoFromConfig(config, database);
|
|
36
40
|
if (!databaseInfo && !local) {
|
|
37
41
|
throw new Error(
|
|
38
42
|
`Can't find a DB with name/binding '${database}' in local config. Check info in wrangler.toml...`
|
|
@@ -43,31 +47,34 @@ export const ApplyHandler = withConfig<BaseSqlExecuteArgs>(
|
|
|
43
47
|
return;
|
|
44
48
|
}
|
|
45
49
|
|
|
46
|
-
const migrationsPath = await getMigrationsPath(
|
|
47
|
-
path.dirname(config.configPath),
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
const migrationsPath = await getMigrationsPath({
|
|
51
|
+
projectPath: path.dirname(config.configPath),
|
|
52
|
+
migrationsFolderPath:
|
|
53
|
+
databaseInfo?.migrationsFolderPath ?? DEFAULT_MIGRATION_PATH,
|
|
54
|
+
createIfMissing: false,
|
|
55
|
+
});
|
|
51
56
|
|
|
52
|
-
const
|
|
57
|
+
const migrationsTableName =
|
|
53
58
|
databaseInfo?.migrationsTableName ?? DEFAULT_MIGRATION_TABLE;
|
|
54
|
-
await initMigrationsTable(
|
|
55
|
-
|
|
59
|
+
await initMigrationsTable({
|
|
60
|
+
migrationsTableName,
|
|
56
61
|
local,
|
|
57
62
|
config,
|
|
58
|
-
database,
|
|
59
|
-
persistTo
|
|
60
|
-
|
|
63
|
+
name: database,
|
|
64
|
+
persistTo,
|
|
65
|
+
preview,
|
|
66
|
+
});
|
|
61
67
|
|
|
62
68
|
const unappliedMigrations = (
|
|
63
|
-
await getUnappliedMigrations(
|
|
64
|
-
|
|
69
|
+
await getUnappliedMigrations({
|
|
70
|
+
migrationsTableName,
|
|
65
71
|
migrationsPath,
|
|
66
72
|
local,
|
|
67
73
|
config,
|
|
68
|
-
database,
|
|
69
|
-
persistTo
|
|
70
|
-
|
|
74
|
+
name: database,
|
|
75
|
+
persistTo,
|
|
76
|
+
preview,
|
|
77
|
+
})
|
|
71
78
|
)
|
|
72
79
|
.map((migration) => {
|
|
73
80
|
return {
|
|
@@ -105,8 +112,8 @@ Your database may not be available to serve requests during the migration, conti
|
|
|
105
112
|
);
|
|
106
113
|
if (!ok) return;
|
|
107
114
|
|
|
108
|
-
// don't backup prod db when applying migrations locally
|
|
109
|
-
if (!local) {
|
|
115
|
+
// don't backup prod db when applying migrations locally or in preview
|
|
116
|
+
if (!local && !preview) {
|
|
110
117
|
assert(
|
|
111
118
|
databaseInfo,
|
|
112
119
|
"In non-local mode `databaseInfo` should be defined."
|
|
@@ -122,22 +129,24 @@ Your database may not be available to serve requests during the migration, conti
|
|
|
122
129
|
"utf8"
|
|
123
130
|
);
|
|
124
131
|
query += `
|
|
125
|
-
INSERT INTO ${
|
|
132
|
+
INSERT INTO ${migrationsTableName} (name)
|
|
126
133
|
values ('${migration.Name}');
|
|
127
134
|
`;
|
|
128
135
|
|
|
129
136
|
let success = true;
|
|
130
137
|
let errorNotes: Array<string> = [];
|
|
131
138
|
try {
|
|
132
|
-
const response = await executeSql(
|
|
139
|
+
const response = await executeSql({
|
|
133
140
|
local,
|
|
134
141
|
config,
|
|
135
|
-
database,
|
|
136
|
-
isInteractive() && !CI.isCI(),
|
|
142
|
+
name: database,
|
|
143
|
+
shouldPrompt: isInteractive() && !CI.isCI(),
|
|
137
144
|
persistTo,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
145
|
+
command: query,
|
|
146
|
+
file: undefined,
|
|
147
|
+
json: undefined,
|
|
148
|
+
preview,
|
|
149
|
+
});
|
|
141
150
|
|
|
142
151
|
if (response === null) {
|
|
143
152
|
// TODO: return error
|
|
@@ -4,19 +4,16 @@ import { Box, render, Text } from "ink";
|
|
|
4
4
|
import React from "react";
|
|
5
5
|
import { withConfig } from "../../config";
|
|
6
6
|
import { logger } from "../../logger";
|
|
7
|
-
import {
|
|
7
|
+
import { DEFAULT_MIGRATION_PATH } from "../constants";
|
|
8
8
|
import { Database } from "../options";
|
|
9
9
|
import { d1BetaWarning, getDatabaseInfoFromConfig } from "../utils";
|
|
10
10
|
import { getMigrationsPath, getNextMigrationNumber } from "./helpers";
|
|
11
|
-
import type {
|
|
11
|
+
import type {
|
|
12
|
+
CommonYargsArgv,
|
|
13
|
+
StrictYargsOptionsToInterface,
|
|
14
|
+
} from "../../yargs-types";
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
config?: string;
|
|
15
|
-
database: string;
|
|
16
|
-
message: string;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export function CreateOptions(yargs: Argv): Argv<MigrationsCreateArgs> {
|
|
16
|
+
export function CreateOptions(yargs: CommonYargsArgv) {
|
|
20
17
|
return Database(yargs).positional("message", {
|
|
21
18
|
describe: "The Migration message",
|
|
22
19
|
type: "string",
|
|
@@ -24,12 +21,13 @@ export function CreateOptions(yargs: Argv): Argv<MigrationsCreateArgs> {
|
|
|
24
21
|
});
|
|
25
22
|
}
|
|
26
23
|
|
|
27
|
-
|
|
24
|
+
type CreateHandlerOptions = StrictYargsOptionsToInterface<typeof CreateOptions>;
|
|
25
|
+
|
|
26
|
+
export const CreateHandler = withConfig<CreateHandlerOptions>(
|
|
28
27
|
async ({ config, database, message }): Promise<void> => {
|
|
29
|
-
await requireAuth({});
|
|
30
28
|
logger.log(d1BetaWarning);
|
|
31
29
|
|
|
32
|
-
const databaseInfo =
|
|
30
|
+
const databaseInfo = getDatabaseInfoFromConfig(config, database);
|
|
33
31
|
if (!databaseInfo) {
|
|
34
32
|
throw new Error(
|
|
35
33
|
`Can't find a DB with name/binding '${database}' in local config. Check info in wrangler.toml...`
|
|
@@ -40,11 +38,12 @@ export const CreateHandler = withConfig<MigrationsCreateArgs>(
|
|
|
40
38
|
return;
|
|
41
39
|
}
|
|
42
40
|
|
|
43
|
-
const migrationsPath = await getMigrationsPath(
|
|
44
|
-
path.dirname(config.configPath),
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
41
|
+
const migrationsPath = await getMigrationsPath({
|
|
42
|
+
projectPath: path.dirname(config.configPath),
|
|
43
|
+
migrationsFolderPath:
|
|
44
|
+
databaseInfo.migrationsFolderPath ?? DEFAULT_MIGRATION_PATH,
|
|
45
|
+
createIfMissing: true,
|
|
46
|
+
});
|
|
48
47
|
const nextMigrationNumber = pad(getNextMigrationNumber(migrationsPath), 4);
|
|
49
48
|
const migrationName = message.replaceAll(" ", "_");
|
|
50
49
|
|