wrangler 0.0.0-e30d1013 → 0.0.0-e311bbbf
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/bin/wrangler.js +30 -10
- package/miniflare-dist/index.mjs +126 -74
- package/package.json +26 -19
- package/src/__tests__/api-dev.test.ts +65 -36
- package/src/__tests__/api-devregistry.test.ts +121 -0
- package/src/__tests__/api.test.ts +27 -5
- package/src/__tests__/configuration.test.ts +567 -39
- package/src/__tests__/d1/d1.test.ts +82 -0
- package/src/__tests__/d1/execute.test.ts +66 -0
- package/src/__tests__/d1/migrate.test.ts +157 -0
- package/src/__tests__/d1/splitter.test.ts +255 -0
- package/src/__tests__/delete.test.ts +91 -49
- package/src/__tests__/deployments.test.ts +330 -52
- package/src/__tests__/dev.test.tsx +198 -90
- package/src/__tests__/generate.test.ts +8 -5
- 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-auth-domain.ts +20 -0
- package/src/__tests__/helpers/mock-console.ts +6 -0
- package/src/__tests__/helpers/mock-dialogs.ts +71 -85
- package/src/__tests__/helpers/mock-get-pages-upload-token.ts +25 -0
- package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -5
- package/src/__tests__/helpers/mock-known-routes.ts +7 -2
- package/src/__tests__/helpers/mock-kv.ts +29 -16
- package/src/__tests__/helpers/mock-oauth-flow.ts +103 -92
- package/src/__tests__/helpers/mock-process.ts +8 -13
- package/src/__tests__/helpers/mock-set-timeout.ts +16 -0
- package/src/__tests__/helpers/msw/blob-worker.cjs +19 -0
- package/src/__tests__/helpers/msw/handlers/deployments.ts +127 -26
- package/src/__tests__/helpers/msw/handlers/namespaces.ts +18 -41
- package/src/__tests__/helpers/msw/handlers/oauth.ts +13 -18
- package/src/__tests__/helpers/msw/handlers/r2.ts +14 -34
- package/src/__tests__/helpers/msw/handlers/script.ts +9 -28
- package/src/__tests__/helpers/msw/handlers/user.ts +13 -24
- package/src/__tests__/helpers/msw/handlers/zones.ts +6 -8
- package/src/__tests__/helpers/msw/index.ts +32 -1
- package/src/__tests__/helpers/msw/read-file-sync.js +61 -0
- package/src/__tests__/helpers/string-dynamic-values-matcher.ts +28 -0
- package/src/__tests__/helpers/worker-scripts/parent-worker.js +4 -1
- package/src/__tests__/index.test.ts +90 -72
- package/src/__tests__/init.test.ts +927 -631
- package/src/__tests__/jest.setup.ts +19 -42
- package/src/__tests__/kv.test.ts +355 -231
- package/src/__tests__/logger.test.ts +68 -2
- package/src/__tests__/logout.test.ts +47 -0
- package/src/__tests__/metrics.test.ts +94 -51
- package/src/__tests__/middleware.scheduled.test.ts +42 -32
- package/src/__tests__/middleware.test.ts +212 -122
- package/src/__tests__/mtls-certificates.test.ts +588 -0
- package/src/__tests__/pages/deployment-list.test.ts +80 -0
- package/src/__tests__/pages/functions-build.test.ts +452 -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 +110 -0
- package/src/__tests__/pages/project-upload.test.ts +500 -0
- package/src/__tests__/pages/publish.test.ts +2864 -0
- package/src/__tests__/pages-deployment-tail.test.ts +955 -0
- package/src/__tests__/parse.test.ts +106 -0
- package/src/__tests__/publish.test.ts +1620 -830
- package/src/__tests__/pubsub.test.ts +226 -100
- package/src/__tests__/queues.test.ts +237 -76
- package/src/__tests__/r2.test.ts +37 -56
- package/src/__tests__/secret.test.ts +179 -130
- package/src/__tests__/tail.test.ts +267 -109
- package/src/__tests__/test-old-node-version.js +3 -3
- package/src/__tests__/traverse-module-graph.test.ts +220 -0
- package/src/__tests__/tsconfig-sanity.ts +12 -0
- package/src/__tests__/tsconfig.json +8 -0
- package/src/__tests__/tsconfig.tsbuildinfo +1 -0
- package/src/__tests__/type-generation.test.ts +11 -2
- package/src/__tests__/user.test.ts +35 -72
- package/src/__tests__/whoami.test.tsx +8 -114
- package/src/__tests__/worker-namespace.test.ts +83 -69
- package/src/api/dev.ts +168 -60
- package/src/api/index.ts +10 -1
- package/src/api/mtls-certificate.ts +148 -0
- package/src/api/pages/create-worker-bundle-contents.ts +76 -0
- package/src/api/pages/index.ts +5 -0
- package/src/api/pages/publish.tsx +355 -0
- package/src/bundle.ts +221 -128
- package/src/cfetch/index.ts +0 -2
- package/src/cfetch/internal.ts +16 -21
- package/src/cli.ts +4 -4
- package/src/config/config.ts +14 -7
- package/src/config/environment.ts +73 -16
- package/src/config/index.ts +99 -30
- package/src/config/validation-helpers.ts +1 -1
- package/src/config/validation.ts +248 -9
- package/src/create-worker-preview.ts +19 -8
- package/src/create-worker-upload-form.ts +48 -5
- package/src/d1/backups.tsx +43 -42
- package/src/d1/create.tsx +26 -21
- package/src/d1/{delete.tsx → delete.ts} +11 -14
- package/src/d1/execute.tsx +183 -170
- package/src/d1/index.ts +7 -6
- package/src/d1/list.tsx +22 -10
- package/src/d1/migrations/apply.tsx +212 -0
- package/src/d1/migrations/create.tsx +79 -0
- package/src/d1/migrations/helpers.ts +172 -0
- package/src/d1/migrations/index.ts +3 -0
- package/src/d1/migrations/list.tsx +95 -0
- package/src/d1/migrations/options.ts +23 -0
- package/src/d1/options.ts +3 -3
- package/src/d1/splitter.ts +161 -0
- package/src/d1/{types.tsx → types.ts} +1 -0
- package/src/d1/utils.ts +2 -1
- package/src/delete.ts +8 -16
- package/src/deployments.ts +333 -42
- package/src/deprecated/index.ts +8 -302
- package/src/dev/dev.tsx +57 -44
- package/src/dev/local.tsx +248 -74
- package/src/dev/remote.tsx +32 -3
- package/src/dev/start-server.ts +81 -66
- package/src/dev/use-esbuild.ts +17 -18
- package/src/dev/validate-dev-props.ts +9 -0
- package/src/{dev-registry.tsx → dev-registry.ts} +2 -1
- package/src/dev.tsx +178 -117
- package/src/dialogs.ts +136 -0
- package/src/dispatch-namespace.ts +21 -17
- package/src/docs/index.ts +97 -0
- package/src/entry.ts +19 -11
- package/src/environment-variables/factory.ts +88 -0
- package/src/environment-variables/misc-variables.ts +30 -0
- package/src/generate/index.ts +298 -0
- package/src/git-client.ts +15 -4
- package/src/{index.tsx → index.ts} +134 -59
- package/src/init.ts +249 -187
- package/src/inspect.ts +16 -1
- package/src/jest.d.ts +4 -0
- package/src/kv/index.ts +15 -17
- package/src/logger.ts +32 -5
- package/src/metrics/metrics-config.ts +3 -3
- package/src/metrics/send-event.ts +6 -1
- package/src/miniflare-cli/assets.ts +64 -28
- package/src/miniflare-cli/index.ts +4 -7
- package/src/miniflare-cli/tsconfig.json +9 -0
- package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
- package/src/miniflare-cli/types.ts +11 -0
- package/src/module-collection.ts +91 -25
- package/src/mtls-certificate/cli.ts +155 -0
- package/src/pages/build.ts +410 -0
- package/src/pages/buildFunctions.ts +140 -0
- package/src/pages/deployment-tails.ts +281 -0
- package/src/pages/deployments.tsx +11 -33
- package/src/pages/{dev.tsx → dev.ts} +147 -139
- package/src/pages/errors.ts +1 -0
- package/src/pages/functions/buildPlugin.ts +61 -54
- package/src/pages/functions/buildWorker.ts +159 -33
- package/src/pages/functions/tsconfig.json +8 -0
- package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
- package/src/pages/{functions.tsx → functions.ts} +8 -4
- package/src/pages/{index.tsx → index.ts} +11 -3
- package/src/pages/projects.tsx +12 -22
- package/src/pages/prompt-select-project.tsx +31 -0
- package/src/pages/publish.tsx +46 -225
- package/src/pages/types.ts +6 -9
- package/src/pages/upload.tsx +58 -14
- package/src/pages/utils.ts +12 -1
- package/src/parse.ts +23 -1
- package/src/paths.ts +1 -1
- package/src/proxy.ts +5 -0
- package/src/publish/index.ts +20 -16
- package/src/publish/publish.ts +71 -46
- package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +19 -20
- package/src/queues/cli/commands/consumer/add.ts +24 -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 +6 -4
- package/src/queues/cli/commands/list.ts +8 -8
- package/src/queues/client.ts +1 -0
- package/src/queues/utils.ts +18 -0
- package/src/r2/helpers.ts +1 -0
- package/src/r2/index.ts +28 -28
- package/src/secret/index.ts +14 -16
- package/src/{sites.tsx → sites.ts} +1 -1
- package/src/tail/createTail.ts +94 -3
- package/src/tail/filters.ts +1 -1
- package/src/tail/index.ts +8 -11
- package/src/tail/printing.ts +15 -0
- package/src/traverse-module-graph.ts +53 -0
- package/src/tsconfig-sanity.ts +16 -0
- package/src/type-generation.ts +28 -20
- package/src/user/access.ts +0 -1
- package/src/user/auth-variables.ts +113 -0
- package/src/user/choose-account.tsx +1 -31
- package/src/user/index.ts +0 -1
- package/src/user/{user.tsx → user.ts} +123 -82
- package/src/utils/render.ts +93 -0
- package/src/{whoami.tsx → whoami.ts} +37 -71
- package/src/worker.ts +30 -1
- package/src/yargs-types.ts +22 -5
- package/templates/__tests__/tsconfig-sanity.ts +12 -0
- package/templates/__tests__/tsconfig.json +8 -0
- package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
- package/templates/checked-fetch.js +9 -3
- package/templates/d1-beta-facade.js +51 -3
- package/templates/facade.d.ts +14 -0
- package/templates/first-party-worker-module-facade.ts +4 -3
- package/templates/format-dev-errors.ts +8 -6
- package/templates/gitignore +1 -0
- package/templates/init-tests/test-jest-new-worker.js +3 -5
- package/templates/init-tests/test-vitest-new-worker.js +3 -5
- package/templates/init-tests/test-vitest-new-worker.ts +25 -0
- package/templates/middleware/loader-modules.ts +2 -2
- package/templates/middleware/loader-sw.ts +51 -31
- package/templates/middleware/middleware-miniflare3-json-error.ts +32 -0
- package/templates/new-worker.ts +3 -0
- package/templates/pages-dev-pipeline.ts +4 -1
- package/templates/pages-shim.ts +4 -1
- package/templates/pages-template-plugin.ts +19 -10
- package/templates/serve-static-assets.ts +17 -14
- package/templates/service-bindings-module-facade.js +1 -0
- package/templates/tsconfig-sanity.ts +11 -0
- package/templates/tsconfig.init.json +105 -0
- package/templates/tsconfig.json +5 -103
- package/templates/tsconfig.tsbuildinfo +1 -0
- package/wrangler-dist/cli.d.ts +820 -70
- package/wrangler-dist/cli.js +68161 -78780
- package/wrangler-dist/wasm-sync.wasm +0 -0
- package/src/__tests__/api-devregistry.test.js +0 -56
- package/src/__tests__/d1.test.ts +0 -74
- package/src/__tests__/dialogs.test.tsx +0 -40
- package/src/__tests__/helpers/mock-cfetch.ts +0 -333
- package/src/__tests__/pages.test.ts +0 -2387
- package/src/d1/migrations.tsx +0 -446
- package/src/dialogs.tsx +0 -169
- package/src/environment-variables.ts +0 -50
- package/src/pages/build.tsx +0 -270
- package/src/user/env-vars.ts +0 -46
- package/templates/experimental-local-cache-stubs.js +0 -27
- /package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
- /package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
- /package/src/pages/{hash.tsx → hash.ts} +0 -0
package/src/d1/execute.tsx
CHANGED
|
@@ -1,52 +1,33 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { mkdir } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import { Static, Text } from "ink";
|
|
5
6
|
import Table from "ink-table";
|
|
6
7
|
import { npxImport } from "npx-import";
|
|
7
8
|
import React from "react";
|
|
8
9
|
import { fetchResult } from "../cfetch";
|
|
9
|
-
import {
|
|
10
|
+
import { readConfig } from "../config";
|
|
10
11
|
import { getLocalPersistencePath } from "../dev/get-local-persistence-path";
|
|
11
|
-
import { confirm
|
|
12
|
+
import { confirm } from "../dialogs";
|
|
12
13
|
import { logger } from "../logger";
|
|
14
|
+
import { readFileSync } from "../parse";
|
|
13
15
|
import { readableRelative } from "../paths";
|
|
14
16
|
import { requireAuth } from "../user";
|
|
17
|
+
import { renderToString } from "../utils/render";
|
|
15
18
|
import * as options from "./options";
|
|
19
|
+
import splitSqlQuery from "./splitter";
|
|
16
20
|
import {
|
|
17
21
|
d1BetaWarning,
|
|
18
22
|
getDatabaseByNameOrBinding,
|
|
19
23
|
getDatabaseInfoFromConfig,
|
|
20
24
|
} from "./utils";
|
|
21
25
|
import type { Config, ConfigFields, DevConfig, Environment } from "../config";
|
|
26
|
+
import type {
|
|
27
|
+
CommonYargsArgv,
|
|
28
|
+
StrictYargsOptionsToInterface,
|
|
29
|
+
} from "../yargs-types";
|
|
22
30
|
import type { Database } from "./types";
|
|
23
|
-
import type splitSqlQuery from "@databases/split-sql-query";
|
|
24
|
-
import type { SQL, SQLQuery } from "@databases/sql";
|
|
25
|
-
import type { Statement as StatementType } from "@miniflare/d1";
|
|
26
|
-
import type { createSQLiteDB as createSQLiteDBType } from "@miniflare/shared";
|
|
27
|
-
import type { Argv } from "yargs";
|
|
28
|
-
|
|
29
|
-
type MiniflareNpxImportTypes = [
|
|
30
|
-
{
|
|
31
|
-
Statement: typeof StatementType;
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
createSQLiteDB: typeof createSQLiteDBType;
|
|
35
|
-
}
|
|
36
|
-
];
|
|
37
|
-
|
|
38
|
-
export type BaseSqlExecuteArgs = {
|
|
39
|
-
config?: string;
|
|
40
|
-
database: string;
|
|
41
|
-
local?: boolean;
|
|
42
|
-
"persist-to"?: string;
|
|
43
|
-
yes?: boolean;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
type ExecuteArgs = BaseSqlExecuteArgs & {
|
|
47
|
-
file?: string;
|
|
48
|
-
command?: string;
|
|
49
|
-
};
|
|
50
31
|
|
|
51
32
|
export type QueryResult = {
|
|
52
33
|
results: Record<string, string | number | boolean>[];
|
|
@@ -56,10 +37,10 @@ export type QueryResult = {
|
|
|
56
37
|
};
|
|
57
38
|
query?: string;
|
|
58
39
|
};
|
|
59
|
-
// Max number of
|
|
40
|
+
// Max number of statements to send in a single /execute call
|
|
60
41
|
const QUERY_LIMIT = 10_000;
|
|
61
42
|
|
|
62
|
-
export function Options(yargs:
|
|
43
|
+
export function Options(yargs: CommonYargsArgv) {
|
|
63
44
|
return options
|
|
64
45
|
.Database(yargs)
|
|
65
46
|
.option("yes", {
|
|
@@ -73,7 +54,7 @@ export function Options(yargs: Argv): Argv<ExecuteArgs> {
|
|
|
73
54
|
type: "boolean",
|
|
74
55
|
})
|
|
75
56
|
.option("file", {
|
|
76
|
-
describe: "A .sql file to
|
|
57
|
+
describe: "A .sql file to ingest",
|
|
77
58
|
type: "string",
|
|
78
59
|
})
|
|
79
60
|
.option("command", {
|
|
@@ -84,82 +65,54 @@ export function Options(yargs: Argv): Argv<ExecuteArgs> {
|
|
|
84
65
|
describe: "Specify directory to use for local persistence (for --local)",
|
|
85
66
|
type: "string",
|
|
86
67
|
requiresArg: true,
|
|
68
|
+
})
|
|
69
|
+
.option("json", {
|
|
70
|
+
describe: "Return output as clean JSON",
|
|
71
|
+
type: "boolean",
|
|
72
|
+
default: false,
|
|
73
|
+
})
|
|
74
|
+
.option("preview", {
|
|
75
|
+
describe: "Execute commands/files against a preview D1 DB",
|
|
76
|
+
type: "boolean",
|
|
77
|
+
default: false,
|
|
87
78
|
});
|
|
88
79
|
}
|
|
89
80
|
|
|
90
|
-
|
|
91
|
-
return query && query.length > length
|
|
92
|
-
? query.slice(0, length) + "..."
|
|
93
|
-
: query;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export async function executeSql(
|
|
97
|
-
local: undefined | boolean,
|
|
98
|
-
config: ConfigFields<DevConfig> & Environment,
|
|
99
|
-
name: string,
|
|
100
|
-
shouldPrompt: boolean | undefined,
|
|
101
|
-
persistTo: undefined | string,
|
|
102
|
-
file?: string,
|
|
103
|
-
command?: string
|
|
104
|
-
) {
|
|
105
|
-
const { parser, splitter } = await loadSqlUtils();
|
|
106
|
-
|
|
107
|
-
const sql = file
|
|
108
|
-
? parser.file(file)
|
|
109
|
-
: command
|
|
110
|
-
? parser.__dangerous__rawValue(command)
|
|
111
|
-
: null;
|
|
112
|
-
|
|
113
|
-
if (!sql) throw new Error(`Error: must provide --command or --file.`);
|
|
114
|
-
if (persistTo && !local)
|
|
115
|
-
throw new Error(`Error: can't use --persist-to without --local`);
|
|
81
|
+
type HandlerOptions = StrictYargsOptionsToInterface<typeof Options>;
|
|
116
82
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
83
|
+
export const Handler = async (args: HandlerOptions): Promise<void> => {
|
|
84
|
+
const { local, database, yes, persistTo, file, command, json, preview } =
|
|
85
|
+
args;
|
|
86
|
+
const existingLogLevel = logger.loggerLevel;
|
|
87
|
+
if (json) {
|
|
88
|
+
// set loggerLevel to error to avoid readConfig warnings appearing in JSON output
|
|
89
|
+
logger.loggerLevel = "error";
|
|
125
90
|
}
|
|
91
|
+
const config = readConfig(args.config, args);
|
|
92
|
+
logger.log(d1BetaWarning);
|
|
93
|
+
if (file && command)
|
|
94
|
+
return logger.error(`Error: can't provide both --command and --file.`);
|
|
126
95
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export const Handler = withConfig<ExecuteArgs>(
|
|
133
|
-
async ({
|
|
96
|
+
const isInteractive = process.stdout.isTTY;
|
|
97
|
+
const response: QueryResult[] | null = await executeSql({
|
|
98
|
+
local,
|
|
134
99
|
config,
|
|
135
|
-
database,
|
|
100
|
+
name: database,
|
|
101
|
+
shouldPrompt: isInteractive && !yes,
|
|
102
|
+
persistTo,
|
|
136
103
|
file,
|
|
137
104
|
command,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}): Promise<void> => {
|
|
142
|
-
logger.log(d1BetaWarning);
|
|
143
|
-
if (file && command)
|
|
144
|
-
return console.error(`Error: can't provide both --command and --file.`);
|
|
145
|
-
|
|
146
|
-
const isInteractive = process.stdout.isTTY;
|
|
147
|
-
const response: QueryResult[] | null = await executeSql(
|
|
148
|
-
local,
|
|
149
|
-
config,
|
|
150
|
-
database,
|
|
151
|
-
isInteractive && !yes,
|
|
152
|
-
persistTo,
|
|
153
|
-
file,
|
|
154
|
-
command
|
|
155
|
-
);
|
|
105
|
+
json,
|
|
106
|
+
preview,
|
|
107
|
+
});
|
|
156
108
|
|
|
157
|
-
|
|
158
|
-
|
|
109
|
+
// Early exit if prompt rejected
|
|
110
|
+
if (!response) return;
|
|
159
111
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
112
|
+
if (isInteractive && !json) {
|
|
113
|
+
// Render table if single result
|
|
114
|
+
logger.log(
|
|
115
|
+
renderToString(
|
|
163
116
|
<Static items={response}>
|
|
164
117
|
{(result) => {
|
|
165
118
|
// batch results
|
|
@@ -178,20 +131,88 @@ export const Handler = withConfig<ExecuteArgs>(
|
|
|
178
131
|
}
|
|
179
132
|
}}
|
|
180
133
|
</Static>
|
|
134
|
+
)
|
|
135
|
+
);
|
|
136
|
+
} else {
|
|
137
|
+
// set loggerLevel back to what it was before to actually output the JSON in stdout
|
|
138
|
+
logger.loggerLevel = existingLogLevel;
|
|
139
|
+
logger.log(JSON.stringify(response, null, 2));
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
export async function executeSql({
|
|
144
|
+
local,
|
|
145
|
+
config,
|
|
146
|
+
name,
|
|
147
|
+
shouldPrompt,
|
|
148
|
+
persistTo,
|
|
149
|
+
file,
|
|
150
|
+
command,
|
|
151
|
+
json,
|
|
152
|
+
preview,
|
|
153
|
+
}: {
|
|
154
|
+
local: boolean | undefined;
|
|
155
|
+
config: ConfigFields<DevConfig> & Environment;
|
|
156
|
+
name: string;
|
|
157
|
+
shouldPrompt: boolean | undefined;
|
|
158
|
+
persistTo: string | undefined;
|
|
159
|
+
file: string | undefined;
|
|
160
|
+
command: string | undefined;
|
|
161
|
+
json: boolean | undefined;
|
|
162
|
+
preview: boolean | undefined;
|
|
163
|
+
}) {
|
|
164
|
+
const sql = file ? readFileSync(file) : command;
|
|
165
|
+
if (!sql) throw new Error(`Error: must provide --command or --file.`);
|
|
166
|
+
if (preview && local)
|
|
167
|
+
throw new Error(`Error: can't use --preview with --local`);
|
|
168
|
+
if (persistTo && !local)
|
|
169
|
+
throw new Error(`Error: can't use --persist-to without --local`);
|
|
170
|
+
logger.log(`🌀 Mapping SQL input into an array of statements`);
|
|
171
|
+
const queries = splitSqlQuery(sql);
|
|
172
|
+
|
|
173
|
+
if (file && sql) {
|
|
174
|
+
if (queries[0].startsWith("SQLite format 3")) {
|
|
175
|
+
//TODO: update this error to recommend using `wrangler d1 restore` when it exists
|
|
176
|
+
throw new Error(
|
|
177
|
+
"Provided file is a binary SQLite database file instead of an SQL text file.\nThe execute command can only process SQL text files.\nPlease export an SQL file from your SQLite database and try again."
|
|
181
178
|
);
|
|
182
|
-
} else {
|
|
183
|
-
console.log(JSON.stringify(response, null, 2));
|
|
184
179
|
}
|
|
185
180
|
}
|
|
186
|
-
);
|
|
187
181
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
182
|
+
return local
|
|
183
|
+
? await executeLocally({
|
|
184
|
+
config,
|
|
185
|
+
name,
|
|
186
|
+
shouldPrompt,
|
|
187
|
+
queries,
|
|
188
|
+
persistTo,
|
|
189
|
+
json,
|
|
190
|
+
})
|
|
191
|
+
: await executeRemotely({
|
|
192
|
+
config,
|
|
193
|
+
name,
|
|
194
|
+
shouldPrompt,
|
|
195
|
+
batches: batchSplit(queries),
|
|
196
|
+
json,
|
|
197
|
+
preview,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async function executeLocally({
|
|
202
|
+
config,
|
|
203
|
+
name,
|
|
204
|
+
shouldPrompt,
|
|
205
|
+
queries,
|
|
206
|
+
persistTo,
|
|
207
|
+
json,
|
|
208
|
+
}: {
|
|
209
|
+
config: Config;
|
|
210
|
+
name: string;
|
|
211
|
+
shouldPrompt: boolean | undefined;
|
|
212
|
+
queries: string[];
|
|
213
|
+
persistTo: string | undefined;
|
|
214
|
+
json: boolean | undefined;
|
|
215
|
+
}) {
|
|
195
216
|
const localDB = getDatabaseInfoFromConfig(config, name);
|
|
196
217
|
if (!localDB) {
|
|
197
218
|
throw new Error(
|
|
@@ -207,40 +228,46 @@ async function executeLocally(
|
|
|
207
228
|
|
|
208
229
|
const dbDir = path.join(persistencePath, "d1");
|
|
209
230
|
const dbPath = path.join(dbDir, `${localDB.binding}.sqlite3`);
|
|
210
|
-
const [{
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
231
|
+
const [{ D1Database, D1DatabaseAPI }, { createSQLiteDB }] = await npxImport<
|
|
232
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
233
|
+
[typeof import("@miniflare/d1"), typeof import("@miniflare/shared")]
|
|
234
|
+
>(["@miniflare/d1", "@miniflare/shared"], logger.log);
|
|
235
|
+
|
|
236
|
+
if (!existsSync(dbDir)) {
|
|
237
|
+
const ok =
|
|
238
|
+
json ||
|
|
239
|
+
!shouldPrompt ||
|
|
240
|
+
(await confirm(`About to create ${readableRelative(dbPath)}, ok?`));
|
|
220
241
|
if (!ok) return null;
|
|
221
242
|
await mkdir(dbDir, { recursive: true });
|
|
222
243
|
}
|
|
223
244
|
|
|
224
245
|
logger.log(`🌀 Loading DB at ${readableRelative(dbPath)}`);
|
|
225
|
-
const db = await createSQLiteDB(dbPath);
|
|
226
|
-
|
|
227
|
-
const results: QueryResult[] = [];
|
|
228
|
-
for (const sql of queries) {
|
|
229
|
-
const statement = new Statement(db, sql);
|
|
230
|
-
results.push((await statement.all()) as QueryResult);
|
|
231
|
-
}
|
|
232
246
|
|
|
233
|
-
|
|
247
|
+
const sqliteDb = await createSQLiteDB(dbPath);
|
|
248
|
+
const db = new D1Database(new D1DatabaseAPI(sqliteDb));
|
|
249
|
+
const stmts = queries.map((query) => db.prepare(query));
|
|
250
|
+
return (await db.batch(stmts)) as QueryResult[];
|
|
234
251
|
}
|
|
235
252
|
|
|
236
|
-
async function executeRemotely(
|
|
237
|
-
config
|
|
238
|
-
name
|
|
239
|
-
shouldPrompt
|
|
240
|
-
batches
|
|
241
|
-
|
|
253
|
+
async function executeRemotely({
|
|
254
|
+
config,
|
|
255
|
+
name,
|
|
256
|
+
shouldPrompt,
|
|
257
|
+
batches,
|
|
258
|
+
json,
|
|
259
|
+
preview,
|
|
260
|
+
}: {
|
|
261
|
+
config: Config;
|
|
262
|
+
name: string;
|
|
263
|
+
shouldPrompt: boolean | undefined;
|
|
264
|
+
batches: string[];
|
|
265
|
+
json: boolean | undefined;
|
|
266
|
+
preview: boolean | undefined;
|
|
267
|
+
}) {
|
|
242
268
|
const multiple_batches = batches.length > 1;
|
|
243
|
-
|
|
269
|
+
// in JSON mode, we don't want a prompt here
|
|
270
|
+
if (multiple_batches && !json) {
|
|
244
271
|
const warning = `⚠️ Too much SQL to send at once, this execution will be sent as ${batches.length} batches.`;
|
|
245
272
|
|
|
246
273
|
if (shouldPrompt) {
|
|
@@ -250,7 +277,7 @@ async function executeRemotely(
|
|
|
250
277
|
if (!ok) return null;
|
|
251
278
|
logger.log(`🌀 Let's go`);
|
|
252
279
|
} else {
|
|
253
|
-
|
|
280
|
+
logger.error(warning);
|
|
254
281
|
}
|
|
255
282
|
}
|
|
256
283
|
|
|
@@ -260,20 +287,23 @@ async function executeRemotely(
|
|
|
260
287
|
accountId,
|
|
261
288
|
name
|
|
262
289
|
);
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
// Don't output if shouldPrompt is undefined
|
|
268
|
-
} else if (shouldPrompt !== undefined) {
|
|
269
|
-
// Pipe to error so we don't break jq
|
|
270
|
-
console.error(`Executing on ${name} (${db.uuid}):`);
|
|
290
|
+
if (preview && !db.previewDatabaseUuid) {
|
|
291
|
+
throw logger.error(
|
|
292
|
+
"Please define a `preview_database_id` in your wrangler.toml to execute your queries against a preview database"
|
|
293
|
+
);
|
|
271
294
|
}
|
|
295
|
+
const dbUuid = preview ? db.previewDatabaseUuid : db.uuid;
|
|
296
|
+
logger.log(`🌀 Executing on ${name} (${dbUuid}):`);
|
|
272
297
|
|
|
273
298
|
const results: QueryResult[] = [];
|
|
274
299
|
for (const sql of batches) {
|
|
300
|
+
if (multiple_batches)
|
|
301
|
+
logger.log(
|
|
302
|
+
chalk.gray(` ${sql.slice(0, 70)}${sql.length > 70 ? "..." : ""}`)
|
|
303
|
+
);
|
|
304
|
+
|
|
275
305
|
const result = await fetchResult<QueryResult[]>(
|
|
276
|
-
`/accounts/${accountId}/d1/database/${
|
|
306
|
+
`/accounts/${accountId}/d1/database/${dbUuid}/query`,
|
|
277
307
|
{
|
|
278
308
|
method: "POST",
|
|
279
309
|
headers: {
|
|
@@ -303,42 +333,25 @@ function logResult(r: QueryResult | QueryResult[]) {
|
|
|
303
333
|
);
|
|
304
334
|
}
|
|
305
335
|
|
|
306
|
-
function splitSql(splitter: (query: SQLQuery) => SQLQuery[], sql: SQLQuery) {
|
|
307
|
-
// We have no interpolations, so convert everything to text
|
|
308
|
-
logger.log(`🌀 Mapping SQL input into an array of statements`);
|
|
309
|
-
return splitter(sql).map(
|
|
310
|
-
(q) =>
|
|
311
|
-
q.format({
|
|
312
|
-
escapeIdentifier: (_) => "",
|
|
313
|
-
formatValue: (_, __) => ({ placeholder: "", value: "" }),
|
|
314
|
-
}).text
|
|
315
|
-
);
|
|
316
|
-
}
|
|
317
|
-
|
|
318
336
|
function batchSplit(queries: string[]) {
|
|
319
337
|
logger.log(`🌀 Parsing ${queries.length} statements`);
|
|
320
|
-
const batches: string[] = [];
|
|
321
338
|
const num_batches = Math.ceil(queries.length / QUERY_LIMIT);
|
|
339
|
+
const batches: string[] = [];
|
|
322
340
|
for (let i = 0; i < num_batches; i++) {
|
|
323
341
|
batches.push(
|
|
324
342
|
queries.slice(i * QUERY_LIMIT, (i + 1) * QUERY_LIMIT).join("; ")
|
|
325
343
|
);
|
|
326
344
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
345
|
+
if (num_batches > 1) {
|
|
346
|
+
logger.log(
|
|
347
|
+
`🌀 We are sending ${num_batches} batch(es) to D1 (limited to ${QUERY_LIMIT} statements per batch)`
|
|
348
|
+
);
|
|
349
|
+
}
|
|
330
350
|
return batches;
|
|
331
351
|
}
|
|
332
352
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
// No idea why this is doubly-nested, see https://github.com/ForbesLindesay/atdatabases/issues/255
|
|
338
|
-
default: { default: splitter },
|
|
339
|
-
},
|
|
340
|
-
] = await npxImport<
|
|
341
|
-
[{ default: SQL }, { default: { default: typeof splitSqlQuery } }]
|
|
342
|
-
>(["@databases/sql@3.2.0", "@databases/split-sql-query@1.0.3"], logDim);
|
|
343
|
-
return { parser, splitter };
|
|
353
|
+
function shorten(query: string | undefined, length: number) {
|
|
354
|
+
return query && query.length > length
|
|
355
|
+
? query.slice(0, length) + "..."
|
|
356
|
+
: query;
|
|
344
357
|
}
|
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,9 @@ 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
|
|
28
|
+
.demandCommand()
|
|
29
29
|
.command(
|
|
30
30
|
"list <name>",
|
|
31
31
|
"List your D1 backups",
|
|
@@ -74,6 +74,7 @@ export const d1 = (yargs: Argv<CommonYargsOptions>) => {
|
|
|
74
74
|
)
|
|
75
75
|
.command("migrations", "Interact with D1 Migrations", (yargs2) =>
|
|
76
76
|
yargs2
|
|
77
|
+
.demandCommand()
|
|
77
78
|
.command(
|
|
78
79
|
"list <database>",
|
|
79
80
|
"List your D1 migrations",
|
|
@@ -96,4 +97,4 @@ export const d1 = (yargs: Argv<CommonYargsOptions>) => {
|
|
|
96
97
|
)
|
|
97
98
|
.epilogue(d1BetaWarning)
|
|
98
99
|
);
|
|
99
|
-
}
|
|
100
|
+
}
|
package/src/d1/list.tsx
CHANGED
|
@@ -1,26 +1,38 @@
|
|
|
1
|
-
import { render } from "ink";
|
|
2
1
|
import Table from "ink-table";
|
|
3
2
|
import React from "react";
|
|
4
3
|
import { fetchResult } from "../cfetch";
|
|
5
4
|
import { logger } from "../logger";
|
|
6
5
|
import { requireAuth } from "../user";
|
|
6
|
+
import { renderToString } from "../utils/render";
|
|
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
|
+
logger.log(renderToString(<Table data={dbs}></Table>));
|
|
35
|
+
}
|
|
24
36
|
}
|
|
25
37
|
|
|
26
38
|
export const listDatabases = async (
|