@basaltkit/cli 1.0.0 → 1.1.0
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/LICENSE +1 -1
- package/README.md +8 -2
- package/dist/index.d.ts +109 -1
- package/dist/index.js +267 -2
- package/package.json +1 -1
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -87,8 +87,14 @@ Without registering anything, `runCli` always provides:
|
|
|
87
87
|
| `basalt list` (or `basalt` with no arguments) | Lists all available commands, with their descriptions |
|
|
88
88
|
| `basalt routes` | Lists the HTTP routes registered by the application (read from the `http:routes` metadata bucket, populated by HTTP adapters such as `@basaltkit/fastify`) |
|
|
89
89
|
| `basalt schedule:list` | Lists scheduled tasks and their cron expressions (read from the `schedule:entries` bucket, populated by `@basaltkit/scheduler`) |
|
|
90
|
+
| `basalt dev [--entry=<file>]` | Runs the app with file watching + auto-restart (delegates to `tsx watch` when available, otherwise `node --watch`) |
|
|
91
|
+
| `basalt upgrade [--dry] [--only=<id>]` | Applies framework upgrade codemods (ships the `@machize/*` → `@basaltkit/*` scope rename; `--dry` previews) |
|
|
92
|
+
| `basalt publish [<id>] [--force]` | Copies a bundled stub group into the app — `dockerfile`, `ci`, `editorconfig` (run with no id to list) |
|
|
90
93
|
|
|
91
|
-
If you also install `@basaltkit/generator`, you gain the `make:*` commands
|
|
94
|
+
If you also install `@basaltkit/generator`, you gain the `make:*` commands. Feature
|
|
95
|
+
plugins register their own: `queue:work|stats|retry` (`@basaltkit/queue`),
|
|
96
|
+
`tenant:list|create|migrate|seed|run` (`@basaltkit/tenancy`), `generate:docs`
|
|
97
|
+
(`@basaltkit/http`), and `mail:preview` (`@basaltkit/mailer`).
|
|
92
98
|
|
|
93
99
|
### Defining a command with arguments and flags
|
|
94
100
|
|
|
@@ -211,7 +217,7 @@ Renders the rows as an aligned text table, with no external dependencies. Return
|
|
|
211
217
|
|
|
212
218
|
### `builtinCommands(): CommandDefinition[]`
|
|
213
219
|
|
|
214
|
-
Returns `[routesCommand, scheduleListCommand]`. *(Advanced — `runCli` already includes them automatically.)*
|
|
220
|
+
Returns `[routesCommand, scheduleListCommand, devCommand, upgradeCommand, publishCommand]`. *(Advanced — `runCli` already includes them automatically.)*
|
|
215
221
|
|
|
216
222
|
### `routesCommand` / `scheduleListCommand`
|
|
217
223
|
|
package/dist/index.d.ts
CHANGED
|
@@ -82,4 +82,112 @@ declare const routesCommand: CommandDefinition;
|
|
|
82
82
|
declare const scheduleListCommand: CommandDefinition;
|
|
83
83
|
declare function builtinCommands(): CommandDefinition[];
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
/** Default entry files probed in order when `--entry` is not given. */
|
|
86
|
+
declare const DEV_ENTRY_CANDIDATES: string[];
|
|
87
|
+
/**
|
|
88
|
+
* Picks the first candidate that exists. Pure — `exists` is injected so the
|
|
89
|
+
* resolution is testable without touching disk.
|
|
90
|
+
*/
|
|
91
|
+
declare function resolveDevEntry(candidates: string[], exists: (path: string) => boolean): string | undefined;
|
|
92
|
+
interface DevRunner {
|
|
93
|
+
command: string;
|
|
94
|
+
args: string[];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Chooses how to run the entry with watch/restart, delegating the actual
|
|
98
|
+
* watching to the runtime (no bespoke watcher). Pure and testable:
|
|
99
|
+
*
|
|
100
|
+
* - `.ts` with tsx available → `tsx watch <entry>`
|
|
101
|
+
* - `.ts` without tsx → `node --watch --experimental-strip-types <entry>` (Node ≥ 22.6)
|
|
102
|
+
* - `.js` → `node --watch <entry>`
|
|
103
|
+
*/
|
|
104
|
+
declare function resolveDevRunner(entry: string, options?: {
|
|
105
|
+
tsx?: boolean;
|
|
106
|
+
}): DevRunner;
|
|
107
|
+
/** `basalt dev [--entry=<file>]` — run the app with watch + restart. */
|
|
108
|
+
declare const devCommand: CommandDefinition;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Filesystem surface an upgrade migration works against. Injected so migrations
|
|
112
|
+
* (and `runUpgrade`) are testable with an in-memory tree — no disk needed.
|
|
113
|
+
*/
|
|
114
|
+
interface UpgradeFs {
|
|
115
|
+
/** Recursively lists files under `dir` (relative paths). Skips node_modules/dist/.git. */
|
|
116
|
+
list(dir: string): Promise<string[]>;
|
|
117
|
+
read(path: string): Promise<string>;
|
|
118
|
+
write(path: string, content: string): Promise<void>;
|
|
119
|
+
}
|
|
120
|
+
/** A single edit a migration wants to make — surfaced for `--dry` before writing. */
|
|
121
|
+
interface Edit {
|
|
122
|
+
path: string;
|
|
123
|
+
before: string;
|
|
124
|
+
after: string;
|
|
125
|
+
}
|
|
126
|
+
/** A versioned, idempotent codemod. `plan` computes edits without writing them. */
|
|
127
|
+
interface Migration {
|
|
128
|
+
id: string;
|
|
129
|
+
description: string;
|
|
130
|
+
plan(fs: UpgradeFs, dir: string): Promise<Edit[]>;
|
|
131
|
+
}
|
|
132
|
+
interface UpgradeReport {
|
|
133
|
+
migration: string;
|
|
134
|
+
changed: string[];
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* A codemod that rewrites the deprecated `@machize/*` npm scope to `@basaltkit/*`
|
|
138
|
+
* across package.json and source imports. Unambiguous (scoped rename), so a plain
|
|
139
|
+
* text replace is safe and idempotent.
|
|
140
|
+
*/
|
|
141
|
+
declare const renameMachizeScope: Migration;
|
|
142
|
+
/** All migrations shipped with the CLI, in application order. */
|
|
143
|
+
declare const MIGRATIONS: Migration[];
|
|
144
|
+
/**
|
|
145
|
+
* Runs the selected migrations. With `dry`, computes and reports edits without
|
|
146
|
+
* writing. Returns a per-migration report of the files it changed.
|
|
147
|
+
*/
|
|
148
|
+
declare function runUpgrade(migrations: Migration[], fs: UpgradeFs, options: {
|
|
149
|
+
dir: string;
|
|
150
|
+
dry?: boolean;
|
|
151
|
+
only?: string;
|
|
152
|
+
}): Promise<UpgradeReport[]>;
|
|
153
|
+
/** Node-backed {@link UpgradeFs}. Recursive, skipping build/vcs directories. */
|
|
154
|
+
declare function nodeUpgradeFs(): UpgradeFs;
|
|
155
|
+
/** `basalt upgrade [--dir=<path>] [--dry] [--only=<migration-id>]` */
|
|
156
|
+
declare const upgradeCommand: CommandDefinition;
|
|
157
|
+
|
|
158
|
+
/** One file a publishable drops into the app. */
|
|
159
|
+
interface PublishableFile {
|
|
160
|
+
/** Path relative to the target dir, e.g. `Dockerfile` or `.github/workflows/ci.yml`. */
|
|
161
|
+
path: string;
|
|
162
|
+
content: string;
|
|
163
|
+
}
|
|
164
|
+
/** A named group of stub files an app can copy in and then own (à la vendor:publish). */
|
|
165
|
+
interface Publishable {
|
|
166
|
+
id: string;
|
|
167
|
+
description: string;
|
|
168
|
+
files(): PublishableFile[];
|
|
169
|
+
}
|
|
170
|
+
/** Filesystem surface for publishing — injected so `runPublish` is testable. */
|
|
171
|
+
interface PublishFs {
|
|
172
|
+
exists(path: string): Promise<boolean>;
|
|
173
|
+
write(path: string, content: string): Promise<void>;
|
|
174
|
+
}
|
|
175
|
+
interface PublishResult {
|
|
176
|
+
written: string[];
|
|
177
|
+
skipped: string[];
|
|
178
|
+
}
|
|
179
|
+
/** Stubs bundled with the CLI. Apps can register more via the metadata bucket. */
|
|
180
|
+
declare const PUBLISHABLES: Publishable[];
|
|
181
|
+
/**
|
|
182
|
+
* Copies a publishable's files into the target, skipping any that already exist
|
|
183
|
+
* unless `force` is set. Returns which files were written vs skipped.
|
|
184
|
+
*/
|
|
185
|
+
declare function runPublish(publishable: Publishable, fs: PublishFs, options?: {
|
|
186
|
+
force?: boolean;
|
|
187
|
+
}): Promise<PublishResult>;
|
|
188
|
+
/** Node-backed {@link PublishFs} rooted at `dir` (creates parent directories). */
|
|
189
|
+
declare function nodePublishFs(dir: string): PublishFs;
|
|
190
|
+
/** `basalt publish [<id>] [--dir=<path>] [--force]` — list, or copy a stub group. */
|
|
191
|
+
declare const publishCommand: CommandDefinition;
|
|
192
|
+
|
|
193
|
+
export { type CommandContext, type CommandDefinition, type CommandIo, DEV_ENTRY_CANDIDATES, type DevRunner, type Edit, MIGRATIONS, type Migration, PUBLISHABLES, type ParsedArgv, type PublishFs, type PublishResult, type Publishable, type PublishableFile, type RouteMetadata, type RunCliOptions, type ScheduleMetadata, type UpgradeFs, type UpgradeReport, builtinCommands, commandsPlugin, consoleIo, defineCommand, devCommand, memoryIo, nodePublishFs, nodeUpgradeFs, parseArgv, publishCommand, renameMachizeScope, renderTable, resolveDevEntry, resolveDevRunner, routesCommand, runCli, runPublish, runUpgrade, scheduleListCommand, upgradeCommand };
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,258 @@ import { ensureMetadata } from "@basaltkit/core";
|
|
|
8
8
|
|
|
9
9
|
// src/builtins.ts
|
|
10
10
|
import { METADATA } from "@basaltkit/core";
|
|
11
|
+
|
|
12
|
+
// src/dev.ts
|
|
13
|
+
var DEV_ENTRY_CANDIDATES = ["src/main.ts", "src/server.ts", "src/index.ts", "src/main.js", "src/index.js"];
|
|
14
|
+
function resolveDevEntry(candidates, exists) {
|
|
15
|
+
return candidates.find(exists);
|
|
16
|
+
}
|
|
17
|
+
function resolveDevRunner(entry, options = {}) {
|
|
18
|
+
const isTs = /\.tsx?$/.test(entry);
|
|
19
|
+
if (isTs && options.tsx) return { command: "tsx", args: ["watch", entry] };
|
|
20
|
+
if (isTs) return { command: "node", args: ["--watch", "--experimental-strip-types", entry] };
|
|
21
|
+
return { command: "node", args: ["--watch", entry] };
|
|
22
|
+
}
|
|
23
|
+
var devCommand = defineCommand({
|
|
24
|
+
name: "dev",
|
|
25
|
+
description: "Run the app with file watching and auto-restart",
|
|
26
|
+
async handle({ io, flags }) {
|
|
27
|
+
const { existsSync } = await import("fs");
|
|
28
|
+
const entry = typeof flags["entry"] === "string" ? flags["entry"] : resolveDevEntry(DEV_ENTRY_CANDIDATES, existsSync);
|
|
29
|
+
if (!entry) {
|
|
30
|
+
io.error(
|
|
31
|
+
`No entry file found. Looked for ${DEV_ENTRY_CANDIDATES.join(", ")}. Pass --entry=<file>.`
|
|
32
|
+
);
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
35
|
+
const tsx = await canResolve("tsx");
|
|
36
|
+
const runner = resolveDevRunner(entry, { tsx });
|
|
37
|
+
io.log(`Starting: ${runner.command} ${runner.args.join(" ")}`);
|
|
38
|
+
const { spawn } = await import("child_process");
|
|
39
|
+
return await new Promise((resolve) => {
|
|
40
|
+
const child = spawn(runner.command, runner.args, { stdio: "inherit" });
|
|
41
|
+
const stop = () => child.kill("SIGINT");
|
|
42
|
+
process.once("SIGINT", stop);
|
|
43
|
+
child.on("exit", (code) => {
|
|
44
|
+
process.removeListener("SIGINT", stop);
|
|
45
|
+
resolve(code ?? 0);
|
|
46
|
+
});
|
|
47
|
+
child.on("error", (error) => {
|
|
48
|
+
io.error(`Failed to start dev runner: ${error.message}`);
|
|
49
|
+
resolve(1);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
async function canResolve(specifier) {
|
|
55
|
+
try {
|
|
56
|
+
const { createRequire } = await import("module");
|
|
57
|
+
createRequire(`${process.cwd()}/`).resolve(specifier);
|
|
58
|
+
return true;
|
|
59
|
+
} catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/upgrade.ts
|
|
65
|
+
var renameMachizeScope = {
|
|
66
|
+
id: "rename-machize-scope",
|
|
67
|
+
description: "Rewrite the deprecated @machize/* scope to @basaltkit/*",
|
|
68
|
+
async plan(fs, dir) {
|
|
69
|
+
const files = (await fs.list(dir)).filter((p) => /\.(t|j)sx?$|\.json$/.test(p));
|
|
70
|
+
const edits = [];
|
|
71
|
+
for (const path of files) {
|
|
72
|
+
const before = await fs.read(path);
|
|
73
|
+
if (!before.includes("@machize/")) continue;
|
|
74
|
+
const after = before.split("@machize/").join("@basaltkit/");
|
|
75
|
+
if (after !== before) edits.push({ path, before, after });
|
|
76
|
+
}
|
|
77
|
+
return edits;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
var MIGRATIONS = [renameMachizeScope];
|
|
81
|
+
async function runUpgrade(migrations, fs, options) {
|
|
82
|
+
const selected = options.only ? migrations.filter((m) => m.id === options.only) : migrations;
|
|
83
|
+
const reports = [];
|
|
84
|
+
for (const migration of selected) {
|
|
85
|
+
const edits = await migration.plan(fs, options.dir);
|
|
86
|
+
if (!options.dry) {
|
|
87
|
+
for (const edit of edits) await fs.write(edit.path, edit.after);
|
|
88
|
+
}
|
|
89
|
+
reports.push({ migration: migration.id, changed: edits.map((e) => e.path) });
|
|
90
|
+
}
|
|
91
|
+
return reports;
|
|
92
|
+
}
|
|
93
|
+
function nodeUpgradeFs() {
|
|
94
|
+
const SKIP = /* @__PURE__ */ new Set(["node_modules", "dist", ".git", ".next", "build", "coverage"]);
|
|
95
|
+
return {
|
|
96
|
+
async list(dir) {
|
|
97
|
+
const { readdir } = await import("fs/promises");
|
|
98
|
+
const { join, relative } = await import("path");
|
|
99
|
+
const out = [];
|
|
100
|
+
const walk = async (current) => {
|
|
101
|
+
const entries = await readdir(current, { withFileTypes: true });
|
|
102
|
+
for (const entry of entries) {
|
|
103
|
+
if (entry.isDirectory()) {
|
|
104
|
+
if (!SKIP.has(entry.name)) await walk(join(current, entry.name));
|
|
105
|
+
} else {
|
|
106
|
+
out.push(relative(dir, join(current, entry.name)));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
await walk(dir);
|
|
111
|
+
return out;
|
|
112
|
+
},
|
|
113
|
+
async read(path) {
|
|
114
|
+
const { readFile } = await import("fs/promises");
|
|
115
|
+
const { isAbsolute, join } = await import("path");
|
|
116
|
+
return readFile(isAbsolute(path) ? path : join(process.cwd(), path), "utf8");
|
|
117
|
+
},
|
|
118
|
+
async write(path, content) {
|
|
119
|
+
const { writeFile } = await import("fs/promises");
|
|
120
|
+
const { isAbsolute, join } = await import("path");
|
|
121
|
+
await writeFile(isAbsolute(path) ? path : join(process.cwd(), path), content, "utf8");
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
var upgradeCommand = defineCommand({
|
|
126
|
+
name: "upgrade",
|
|
127
|
+
description: "Apply framework upgrade codemods (--dry to preview, --only=<id>)",
|
|
128
|
+
async handle({ io, flags }) {
|
|
129
|
+
const dir = typeof flags["dir"] === "string" ? flags["dir"] : process.cwd();
|
|
130
|
+
const dry = flags["dry"] === true;
|
|
131
|
+
const only = typeof flags["only"] === "string" ? flags["only"] : void 0;
|
|
132
|
+
if (only && !MIGRATIONS.some((m) => m.id === only)) {
|
|
133
|
+
io.error(`Unknown migration "${only}". Available: ${MIGRATIONS.map((m) => m.id).join(", ")}.`);
|
|
134
|
+
return 1;
|
|
135
|
+
}
|
|
136
|
+
const reports = await runUpgrade(MIGRATIONS, nodeUpgradeFs(), {
|
|
137
|
+
dir,
|
|
138
|
+
dry,
|
|
139
|
+
...only ? { only } : {}
|
|
140
|
+
});
|
|
141
|
+
let total = 0;
|
|
142
|
+
for (const report of reports) {
|
|
143
|
+
if (report.changed.length === 0) continue;
|
|
144
|
+
total += report.changed.length;
|
|
145
|
+
io.log(`${dry ? "[dry] " : ""}${report.migration}: ${report.changed.length} file(s)`);
|
|
146
|
+
for (const path of report.changed) io.log(` ${path}`);
|
|
147
|
+
}
|
|
148
|
+
if (total === 0) io.log("Nothing to upgrade \u2014 everything is up to date.");
|
|
149
|
+
else if (dry) io.log(`
|
|
150
|
+
${total} file(s) would change. Re-run without --dry to apply.`);
|
|
151
|
+
else io.log(`
|
|
152
|
+
Applied ${total} change(s).`);
|
|
153
|
+
return 0;
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// src/publish.ts
|
|
158
|
+
var DOCKERFILE = `# syntax=docker/dockerfile:1
|
|
159
|
+
FROM node:22-slim AS base
|
|
160
|
+
ENV NODE_ENV=production
|
|
161
|
+
WORKDIR /app
|
|
162
|
+
|
|
163
|
+
FROM base AS deps
|
|
164
|
+
COPY package.json pnpm-lock.yaml* ./
|
|
165
|
+
RUN corepack enable && pnpm install --prod --frozen-lockfile
|
|
166
|
+
|
|
167
|
+
FROM base AS run
|
|
168
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
169
|
+
COPY . .
|
|
170
|
+
EXPOSE 3000
|
|
171
|
+
CMD ["node", "dist/main.js"]
|
|
172
|
+
`;
|
|
173
|
+
var CI_WORKFLOW = `name: ci
|
|
174
|
+
on:
|
|
175
|
+
push: { branches: [main] }
|
|
176
|
+
pull_request:
|
|
177
|
+
jobs:
|
|
178
|
+
build:
|
|
179
|
+
runs-on: ubuntu-latest
|
|
180
|
+
steps:
|
|
181
|
+
- uses: actions/checkout@v4
|
|
182
|
+
- uses: pnpm/action-setup@v4
|
|
183
|
+
- uses: actions/setup-node@v4
|
|
184
|
+
with: { node-version: 22, cache: pnpm }
|
|
185
|
+
- run: pnpm install --frozen-lockfile
|
|
186
|
+
- run: pnpm run build
|
|
187
|
+
- run: pnpm run test
|
|
188
|
+
`;
|
|
189
|
+
var EDITORCONFIG = `root = true
|
|
190
|
+
|
|
191
|
+
[*]
|
|
192
|
+
charset = utf-8
|
|
193
|
+
end_of_line = lf
|
|
194
|
+
insert_final_newline = true
|
|
195
|
+
indent_style = space
|
|
196
|
+
indent_size = 2
|
|
197
|
+
trim_trailing_whitespace = true
|
|
198
|
+
`;
|
|
199
|
+
var PUBLISHABLES = [
|
|
200
|
+
{ id: "dockerfile", description: "Production multi-stage Dockerfile", files: () => [{ path: "Dockerfile", content: DOCKERFILE }] },
|
|
201
|
+
{ id: "ci", description: "GitHub Actions CI workflow", files: () => [{ path: ".github/workflows/ci.yml", content: CI_WORKFLOW }] },
|
|
202
|
+
{ id: "editorconfig", description: "Shared .editorconfig", files: () => [{ path: ".editorconfig", content: EDITORCONFIG }] }
|
|
203
|
+
];
|
|
204
|
+
async function runPublish(publishable, fs, options = {}) {
|
|
205
|
+
const written = [];
|
|
206
|
+
const skipped = [];
|
|
207
|
+
for (const file of publishable.files()) {
|
|
208
|
+
if (!options.force && await fs.exists(file.path)) {
|
|
209
|
+
skipped.push(file.path);
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
await fs.write(file.path, file.content);
|
|
213
|
+
written.push(file.path);
|
|
214
|
+
}
|
|
215
|
+
return { written, skipped };
|
|
216
|
+
}
|
|
217
|
+
function nodePublishFs(dir) {
|
|
218
|
+
return {
|
|
219
|
+
async exists(path) {
|
|
220
|
+
const { access } = await import("fs/promises");
|
|
221
|
+
const { join } = await import("path");
|
|
222
|
+
return access(join(dir, path)).then(
|
|
223
|
+
() => true,
|
|
224
|
+
() => false
|
|
225
|
+
);
|
|
226
|
+
},
|
|
227
|
+
async write(path, content) {
|
|
228
|
+
const { mkdir, writeFile } = await import("fs/promises");
|
|
229
|
+
const { dirname, join } = await import("path");
|
|
230
|
+
const target = join(dir, path);
|
|
231
|
+
await mkdir(dirname(target), { recursive: true });
|
|
232
|
+
await writeFile(target, content, "utf8");
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
var publishCommand = defineCommand({
|
|
237
|
+
name: "publish",
|
|
238
|
+
description: "Copy a publishable stub group into the app (run with no id to list)",
|
|
239
|
+
async handle({ io, args, flags }) {
|
|
240
|
+
const id = args[0];
|
|
241
|
+
if (!id) {
|
|
242
|
+
io.log("Publishable groups:");
|
|
243
|
+
io.table(PUBLISHABLES.map((p) => ({ id: p.id, description: p.description })));
|
|
244
|
+
return 0;
|
|
245
|
+
}
|
|
246
|
+
const publishable = PUBLISHABLES.find((p) => p.id === id);
|
|
247
|
+
if (!publishable) {
|
|
248
|
+
io.error(`Unknown publishable "${id}". Available: ${PUBLISHABLES.map((p) => p.id).join(", ")}.`);
|
|
249
|
+
return 1;
|
|
250
|
+
}
|
|
251
|
+
const dir = typeof flags["dir"] === "string" ? flags["dir"] : process.cwd();
|
|
252
|
+
const result = await runPublish(publishable, nodePublishFs(dir), { force: flags["force"] === true });
|
|
253
|
+
for (const path of result.written) io.log(` wrote ${path}`);
|
|
254
|
+
for (const path of result.skipped) io.log(` skipped ${path} (exists \u2014 use --force to overwrite)`);
|
|
255
|
+
if (result.written.length === 0 && result.skipped.length > 0) {
|
|
256
|
+
io.log("Nothing written. Re-run with --force to overwrite existing files.");
|
|
257
|
+
}
|
|
258
|
+
return 0;
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
// src/builtins.ts
|
|
11
263
|
var routesCommand = defineCommand({
|
|
12
264
|
name: "routes",
|
|
13
265
|
description: "List the HTTP routes registered by the app",
|
|
@@ -33,7 +285,7 @@ var scheduleListCommand = defineCommand({
|
|
|
33
285
|
}
|
|
34
286
|
});
|
|
35
287
|
function builtinCommands() {
|
|
36
|
-
return [routesCommand, scheduleListCommand];
|
|
288
|
+
return [routesCommand, scheduleListCommand, devCommand, upgradeCommand, publishCommand];
|
|
37
289
|
}
|
|
38
290
|
|
|
39
291
|
// src/io.ts
|
|
@@ -142,14 +394,27 @@ function commandsPlugin(commands) {
|
|
|
142
394
|
});
|
|
143
395
|
}
|
|
144
396
|
export {
|
|
397
|
+
DEV_ENTRY_CANDIDATES,
|
|
398
|
+
MIGRATIONS,
|
|
399
|
+
PUBLISHABLES,
|
|
145
400
|
builtinCommands,
|
|
146
401
|
commandsPlugin,
|
|
147
402
|
consoleIo,
|
|
148
403
|
defineCommand,
|
|
404
|
+
devCommand,
|
|
149
405
|
memoryIo,
|
|
406
|
+
nodePublishFs,
|
|
407
|
+
nodeUpgradeFs,
|
|
150
408
|
parseArgv,
|
|
409
|
+
publishCommand,
|
|
410
|
+
renameMachizeScope,
|
|
151
411
|
renderTable,
|
|
412
|
+
resolveDevEntry,
|
|
413
|
+
resolveDevRunner,
|
|
152
414
|
routesCommand,
|
|
153
415
|
runCli,
|
|
154
|
-
|
|
416
|
+
runPublish,
|
|
417
|
+
runUpgrade,
|
|
418
|
+
scheduleListCommand,
|
|
419
|
+
upgradeCommand
|
|
155
420
|
};
|
package/package.json
CHANGED