@checkstack/scripts 0.1.1 → 0.2.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/package.json +26 -5
- package/src/cli.ts +31 -5
- package/src/commands/create.ts +17 -0
- package/src/commands/dev-deps-resolver.test.ts +411 -0
- package/src/commands/dev-deps-resolver.ts +215 -0
- package/src/commands/dev-frontend.test.ts +148 -0
- package/src/commands/dev-frontend.ts +198 -0
- package/src/commands/dev-internals.test.ts +506 -0
- package/src/commands/dev-internals.ts +278 -0
- package/src/commands/dev-lifecycle.test.ts +327 -0
- package/src/commands/dev-lifecycle.ts +173 -0
- package/src/commands/dev-server.ts +197 -0
- package/src/commands/plugin-pack.ts +397 -0
- package/src/templates/backend/package.json.hbs +39 -11
- package/src/templates/common/package.json.hbs +32 -7
- package/src/templates/frontend/package.json.hbs +41 -12
- package/src/templates.test.ts +48 -1
- package/CHANGELOG.md +0 -83
- package/tsconfig.json +0 -6
package/package.json
CHANGED
|
@@ -1,19 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@checkstack/scripts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Checkstack tooling: plugin scaffolding, codegen, and the plugin-pack CLI used by external plugin authors.",
|
|
5
|
+
"license": "Elastic-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"checkstack": {
|
|
8
|
+
"type": "tooling"
|
|
9
|
+
},
|
|
4
10
|
"bin": {
|
|
5
11
|
"checkstack-scripts": "./src/cli.ts"
|
|
6
12
|
},
|
|
13
|
+
"files": [
|
|
14
|
+
"src",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
7
20
|
"scripts": {
|
|
8
21
|
"sync": "bun run src/sync.ts",
|
|
9
|
-
"typecheck": "
|
|
22
|
+
"typecheck": "tsgo -b"
|
|
10
23
|
},
|
|
11
24
|
"dependencies": {
|
|
12
|
-
"
|
|
13
|
-
"
|
|
25
|
+
"@checkstack/common": "0.7.0",
|
|
26
|
+
"@checkstack/backend": "0.8.2",
|
|
27
|
+
"@checkstack/frontend": "0.4.2",
|
|
28
|
+
"@checkstack/frontend-api": "0.4.1",
|
|
29
|
+
"@checkstack/ui": "1.7.0",
|
|
30
|
+
"@vitejs/plugin-react": "^4.3.4",
|
|
31
|
+
"inquirer": "^13.4.1",
|
|
32
|
+
"handlebars": "^4.7.8",
|
|
33
|
+
"tar": "^7.4.3",
|
|
34
|
+
"vite": "^5.4.0"
|
|
14
35
|
},
|
|
15
36
|
"devDependencies": {
|
|
16
|
-
"@checkstack/tsconfig": "0.0.
|
|
37
|
+
"@checkstack/tsconfig": "0.0.6",
|
|
17
38
|
"@types/inquirer": "^8.2.10",
|
|
18
39
|
"@types/handlebars": "^4.1.0",
|
|
19
40
|
"typescript": "^5.0.0"
|
package/src/cli.ts
CHANGED
|
@@ -7,11 +7,13 @@ const command = process.argv[2];
|
|
|
7
7
|
if (!command) {
|
|
8
8
|
console.log("Usage: checkstack-scripts <command>");
|
|
9
9
|
console.log("\nCommands:");
|
|
10
|
-
console.log(" create
|
|
11
|
-
console.log(" sync
|
|
12
|
-
console.log(" generate
|
|
13
|
-
console.log("
|
|
14
|
-
console.log("
|
|
10
|
+
console.log(" create - Create a new plugin interactively");
|
|
11
|
+
console.log(" sync - Synchronize package configurations");
|
|
12
|
+
console.log(" generate - Generate migrations and strip public schema");
|
|
13
|
+
console.log(" plugin-pack - Pack a plugin (or bundle) into a .tgz for distribution");
|
|
14
|
+
console.log(" dev - Run a local Checkstack dev server with the current directory's plugin loaded");
|
|
15
|
+
console.log(" typecheck - Run TypeScript type checking");
|
|
16
|
+
console.log(" lint - Run linting checks");
|
|
15
17
|
process.exit(1);
|
|
16
18
|
}
|
|
17
19
|
|
|
@@ -51,6 +53,30 @@ if (command === "generate") {
|
|
|
51
53
|
process.exit(result.status ?? 0);
|
|
52
54
|
}
|
|
53
55
|
|
|
56
|
+
if (command === "plugin-pack") {
|
|
57
|
+
// Dispatch to the plugin-pack module. We invoke it via `bun run` so it
|
|
58
|
+
// works whether the user runs `bunx @checkstack/scripts plugin-pack`
|
|
59
|
+
// (resolves to node_modules), `bun run cli plugin-pack`
|
|
60
|
+
// (relative path from repo), or via the bin script.
|
|
61
|
+
const scriptPath = path.resolve(
|
|
62
|
+
new URL("commands/plugin-pack.ts", import.meta.url).pathname,
|
|
63
|
+
);
|
|
64
|
+
const result = spawnSync("bun", ["run", scriptPath, ...process.argv.slice(3)], {
|
|
65
|
+
stdio: "inherit",
|
|
66
|
+
});
|
|
67
|
+
process.exit(result.status ?? 0);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (command === "dev") {
|
|
71
|
+
const scriptPath = path.resolve(
|
|
72
|
+
new URL("commands/dev-server.ts", import.meta.url).pathname,
|
|
73
|
+
);
|
|
74
|
+
const result = spawnSync("bun", ["run", scriptPath, ...process.argv.slice(3)], {
|
|
75
|
+
stdio: "inherit",
|
|
76
|
+
});
|
|
77
|
+
process.exit(result.status ?? 0);
|
|
78
|
+
}
|
|
79
|
+
|
|
54
80
|
// Fallback for other scripts if we want to centralize their execution logic
|
|
55
81
|
console.error(`Unknown command: ${command}`);
|
|
56
82
|
process.exit(1);
|
package/src/commands/create.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import inquirer from "inquirer";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { spawnSync } from "node:child_process";
|
|
4
5
|
import {
|
|
5
6
|
validatePluginName,
|
|
6
7
|
pluginExists,
|
|
@@ -217,6 +218,22 @@ export async function createCommand() {
|
|
|
217
218
|
}
|
|
218
219
|
|
|
219
220
|
// Success message with next steps
|
|
221
|
+
// Refresh project-references in every package's tsconfig + the root
|
|
222
|
+
// solution tsconfig so the new package is wired into the typecheck
|
|
223
|
+
// graph. Affects only tsconfig.json files; safe to rerun any time.
|
|
224
|
+
console.log("\n🔗 Refreshing TypeScript project references...");
|
|
225
|
+
const refResult = spawnSync(
|
|
226
|
+
"bun",
|
|
227
|
+
["run", "typecheck:references:generate"],
|
|
228
|
+
{ stdio: "inherit" },
|
|
229
|
+
);
|
|
230
|
+
if (refResult.status !== 0) {
|
|
231
|
+
console.warn(
|
|
232
|
+
"⚠️ Failed to refresh references automatically. " +
|
|
233
|
+
"Run `bun run typecheck:references:generate` manually before typechecking.",
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
220
237
|
console.log(
|
|
221
238
|
`\n✅ ${
|
|
222
239
|
locationLabel.charAt(0).toUpperCase() + locationLabel.slice(1)
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { resolveCorePluginDeps } from "./dev-deps-resolver";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* In-memory fixture for a virtual node_modules tree. Maps a fully
|
|
7
|
+
* qualified file path to its file contents (typically package.json
|
|
8
|
+
* stringified JSON).
|
|
9
|
+
*/
|
|
10
|
+
type Fs = Record<string, string>;
|
|
11
|
+
|
|
12
|
+
const ROOT = "/plugin-author/repo";
|
|
13
|
+
const NM = `${ROOT}/node_modules`;
|
|
14
|
+
|
|
15
|
+
function makeFs(packages: Record<string, unknown>): Fs {
|
|
16
|
+
const out: Fs = {};
|
|
17
|
+
for (const [name, pkg] of Object.entries(packages)) {
|
|
18
|
+
out[`${NM}/${name}/package.json`] = JSON.stringify(pkg);
|
|
19
|
+
}
|
|
20
|
+
return out;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function makeResolver(fs: Fs) {
|
|
24
|
+
return (_from: string, request: string): string | undefined => {
|
|
25
|
+
// Only handle requests of the form `<pkg>/package.json` — that's all
|
|
26
|
+
// resolveCorePluginDeps issues. A real `createRequire` resolves any
|
|
27
|
+
// entry, but we don't need that fidelity here.
|
|
28
|
+
if (!request.endsWith("/package.json")) return undefined;
|
|
29
|
+
const pkgName = request.replace(/\/package\.json$/, "");
|
|
30
|
+
const candidate = `${NM}/${pkgName}/package.json`;
|
|
31
|
+
return fs[candidate] === undefined ? undefined : candidate;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function readFileFromFs(fs: Fs) {
|
|
36
|
+
return (p: string): string => {
|
|
37
|
+
const text = fs[p];
|
|
38
|
+
if (text === undefined) throw new Error(`ENOENT: ${p}`);
|
|
39
|
+
return text;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
describe("resolveCorePluginDeps", () => {
|
|
44
|
+
it("returns only the auto-included providers for a plugin with no @checkstack/* backend deps", () => {
|
|
45
|
+
const fs: Fs = {
|
|
46
|
+
[`${ROOT}/package.json`]: JSON.stringify({
|
|
47
|
+
name: "@my-org/widget-backend",
|
|
48
|
+
dependencies: {
|
|
49
|
+
"@checkstack/backend-api": "^1.0.0",
|
|
50
|
+
lodash: "^4.0.0",
|
|
51
|
+
},
|
|
52
|
+
checkstack: { type: "backend", pluginId: "widget" },
|
|
53
|
+
}),
|
|
54
|
+
...makeFs({
|
|
55
|
+
"@checkstack/backend-api": {
|
|
56
|
+
name: "@checkstack/backend-api",
|
|
57
|
+
checkstack: { type: "common" },
|
|
58
|
+
},
|
|
59
|
+
"@checkstack/queue-memory-backend": {
|
|
60
|
+
name: "@checkstack/queue-memory-backend",
|
|
61
|
+
main: "src/index.ts",
|
|
62
|
+
checkstack: { type: "backend", pluginId: "queue-memory" },
|
|
63
|
+
},
|
|
64
|
+
"@checkstack/cache-memory-backend": {
|
|
65
|
+
name: "@checkstack/cache-memory-backend",
|
|
66
|
+
main: "src/index.ts",
|
|
67
|
+
checkstack: { type: "backend", pluginId: "cache-memory" },
|
|
68
|
+
},
|
|
69
|
+
}),
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const resolved = resolveCorePluginDeps({
|
|
73
|
+
pluginDir: ROOT,
|
|
74
|
+
readFile: readFileFromFs(fs),
|
|
75
|
+
resolveFrom: makeResolver(fs),
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const names = resolved.map((r) => r.name).toSorted();
|
|
79
|
+
expect(names).toEqual([
|
|
80
|
+
"@checkstack/cache-memory-backend",
|
|
81
|
+
"@checkstack/queue-memory-backend",
|
|
82
|
+
]);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("includes a single backend dep declared in dependencies", () => {
|
|
86
|
+
const fs: Fs = {
|
|
87
|
+
[`${ROOT}/package.json`]: JSON.stringify({
|
|
88
|
+
name: "@my-org/healthcheck-rcon-backend",
|
|
89
|
+
dependencies: {
|
|
90
|
+
"@checkstack/healthcheck-backend": "^1.0.0",
|
|
91
|
+
},
|
|
92
|
+
checkstack: { type: "backend", pluginId: "healthcheck-rcon" },
|
|
93
|
+
}),
|
|
94
|
+
...makeFs({
|
|
95
|
+
"@checkstack/healthcheck-backend": {
|
|
96
|
+
name: "@checkstack/healthcheck-backend",
|
|
97
|
+
main: "src/index.ts",
|
|
98
|
+
checkstack: { type: "backend", pluginId: "healthcheck" },
|
|
99
|
+
dependencies: {},
|
|
100
|
+
},
|
|
101
|
+
"@checkstack/queue-memory-backend": {
|
|
102
|
+
name: "@checkstack/queue-memory-backend",
|
|
103
|
+
main: "src/index.ts",
|
|
104
|
+
checkstack: { type: "backend", pluginId: "queue-memory" },
|
|
105
|
+
},
|
|
106
|
+
"@checkstack/cache-memory-backend": {
|
|
107
|
+
name: "@checkstack/cache-memory-backend",
|
|
108
|
+
main: "src/index.ts",
|
|
109
|
+
checkstack: { type: "backend", pluginId: "cache-memory" },
|
|
110
|
+
},
|
|
111
|
+
}),
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const resolved = resolveCorePluginDeps({
|
|
115
|
+
pluginDir: ROOT,
|
|
116
|
+
readFile: readFileFromFs(fs),
|
|
117
|
+
resolveFrom: makeResolver(fs),
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
expect(resolved.map((r) => r.name).toSorted()).toEqual([
|
|
121
|
+
"@checkstack/cache-memory-backend",
|
|
122
|
+
"@checkstack/healthcheck-backend",
|
|
123
|
+
"@checkstack/queue-memory-backend",
|
|
124
|
+
]);
|
|
125
|
+
|
|
126
|
+
const hc = resolved.find((r) => r.name === "@checkstack/healthcheck-backend");
|
|
127
|
+
expect(hc?.modulePath).toBe(
|
|
128
|
+
path.resolve(`${NM}/@checkstack/healthcheck-backend/src/index.ts`),
|
|
129
|
+
);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("walks transitive @checkstack/* backend deps", () => {
|
|
133
|
+
// Plugin → notification-discord-backend → notification-backend → catalog-backend
|
|
134
|
+
const fs: Fs = {
|
|
135
|
+
[`${ROOT}/package.json`]: JSON.stringify({
|
|
136
|
+
name: "@my-org/widget-backend",
|
|
137
|
+
dependencies: {
|
|
138
|
+
"@checkstack/notification-discord-backend": "^1.0.0",
|
|
139
|
+
},
|
|
140
|
+
checkstack: { type: "backend", pluginId: "widget" },
|
|
141
|
+
}),
|
|
142
|
+
...makeFs({
|
|
143
|
+
"@checkstack/notification-discord-backend": {
|
|
144
|
+
name: "@checkstack/notification-discord-backend",
|
|
145
|
+
main: "src/index.ts",
|
|
146
|
+
checkstack: { type: "backend", pluginId: "notification-discord" },
|
|
147
|
+
dependencies: {
|
|
148
|
+
"@checkstack/notification-backend": "^1.0.0",
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
"@checkstack/notification-backend": {
|
|
152
|
+
name: "@checkstack/notification-backend",
|
|
153
|
+
main: "src/index.ts",
|
|
154
|
+
checkstack: { type: "backend", pluginId: "notification" },
|
|
155
|
+
dependencies: {
|
|
156
|
+
"@checkstack/catalog-backend": "^1.0.0",
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
"@checkstack/catalog-backend": {
|
|
160
|
+
name: "@checkstack/catalog-backend",
|
|
161
|
+
main: "src/index.ts",
|
|
162
|
+
checkstack: { type: "backend", pluginId: "catalog" },
|
|
163
|
+
},
|
|
164
|
+
"@checkstack/queue-memory-backend": {
|
|
165
|
+
name: "@checkstack/queue-memory-backend",
|
|
166
|
+
main: "src/index.ts",
|
|
167
|
+
checkstack: { type: "backend", pluginId: "queue-memory" },
|
|
168
|
+
},
|
|
169
|
+
"@checkstack/cache-memory-backend": {
|
|
170
|
+
name: "@checkstack/cache-memory-backend",
|
|
171
|
+
main: "src/index.ts",
|
|
172
|
+
checkstack: { type: "backend", pluginId: "cache-memory" },
|
|
173
|
+
},
|
|
174
|
+
}),
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const resolved = resolveCorePluginDeps({
|
|
178
|
+
pluginDir: ROOT,
|
|
179
|
+
readFile: readFileFromFs(fs),
|
|
180
|
+
resolveFrom: makeResolver(fs),
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
expect(resolved.map((r) => r.name).toSorted()).toEqual([
|
|
184
|
+
"@checkstack/cache-memory-backend",
|
|
185
|
+
"@checkstack/catalog-backend",
|
|
186
|
+
"@checkstack/notification-backend",
|
|
187
|
+
"@checkstack/notification-discord-backend",
|
|
188
|
+
"@checkstack/queue-memory-backend",
|
|
189
|
+
]);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it("walks through common-type packages to find transitive backend deps", () => {
|
|
193
|
+
// Plugin → my-shared-common (type: common) → healthcheck-backend
|
|
194
|
+
// (Unusual but possible; common packages can list runtime deps.)
|
|
195
|
+
const fs: Fs = {
|
|
196
|
+
[`${ROOT}/package.json`]: JSON.stringify({
|
|
197
|
+
name: "@my-org/widget-backend",
|
|
198
|
+
dependencies: {
|
|
199
|
+
"@checkstack/widget-common": "^1.0.0",
|
|
200
|
+
},
|
|
201
|
+
checkstack: { type: "backend", pluginId: "widget" },
|
|
202
|
+
}),
|
|
203
|
+
...makeFs({
|
|
204
|
+
"@checkstack/widget-common": {
|
|
205
|
+
name: "@checkstack/widget-common",
|
|
206
|
+
checkstack: { type: "common" },
|
|
207
|
+
dependencies: {
|
|
208
|
+
"@checkstack/healthcheck-backend": "^1.0.0",
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
"@checkstack/healthcheck-backend": {
|
|
212
|
+
name: "@checkstack/healthcheck-backend",
|
|
213
|
+
main: "src/index.ts",
|
|
214
|
+
checkstack: { type: "backend", pluginId: "healthcheck" },
|
|
215
|
+
},
|
|
216
|
+
"@checkstack/queue-memory-backend": {
|
|
217
|
+
name: "@checkstack/queue-memory-backend",
|
|
218
|
+
main: "src/index.ts",
|
|
219
|
+
checkstack: { type: "backend", pluginId: "queue-memory" },
|
|
220
|
+
},
|
|
221
|
+
"@checkstack/cache-memory-backend": {
|
|
222
|
+
name: "@checkstack/cache-memory-backend",
|
|
223
|
+
main: "src/index.ts",
|
|
224
|
+
checkstack: { type: "backend", pluginId: "cache-memory" },
|
|
225
|
+
},
|
|
226
|
+
}),
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
const resolved = resolveCorePluginDeps({
|
|
230
|
+
pluginDir: ROOT,
|
|
231
|
+
readFile: readFileFromFs(fs),
|
|
232
|
+
resolveFrom: makeResolver(fs),
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
expect(resolved.map((r) => r.name)).toContain(
|
|
236
|
+
"@checkstack/healthcheck-backend",
|
|
237
|
+
);
|
|
238
|
+
// The common pkg itself isn't loaded as a plugin
|
|
239
|
+
expect(resolved.map((r) => r.name)).not.toContain(
|
|
240
|
+
"@checkstack/widget-common",
|
|
241
|
+
);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it("excludes the plugin under dev itself even when listed transitively", () => {
|
|
245
|
+
const fs: Fs = {
|
|
246
|
+
[`${ROOT}/package.json`]: JSON.stringify({
|
|
247
|
+
name: "@my-org/widget-backend",
|
|
248
|
+
dependencies: {
|
|
249
|
+
"@checkstack/healthcheck-backend": "^1.0.0",
|
|
250
|
+
},
|
|
251
|
+
checkstack: { type: "backend", pluginId: "widget" },
|
|
252
|
+
}),
|
|
253
|
+
...makeFs({
|
|
254
|
+
"@checkstack/healthcheck-backend": {
|
|
255
|
+
name: "@checkstack/healthcheck-backend",
|
|
256
|
+
main: "src/index.ts",
|
|
257
|
+
checkstack: { type: "backend", pluginId: "healthcheck" },
|
|
258
|
+
// Pretend the platform plugin pulls back into the user's plugin
|
|
259
|
+
// (this would never happen in practice, but the resolver must
|
|
260
|
+
// never try to load the plugin under dev as a sibling).
|
|
261
|
+
dependencies: {
|
|
262
|
+
"@my-org/widget-backend": "^1.0.0",
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
"@checkstack/queue-memory-backend": {
|
|
266
|
+
name: "@checkstack/queue-memory-backend",
|
|
267
|
+
main: "src/index.ts",
|
|
268
|
+
checkstack: { type: "backend", pluginId: "queue-memory" },
|
|
269
|
+
},
|
|
270
|
+
"@checkstack/cache-memory-backend": {
|
|
271
|
+
name: "@checkstack/cache-memory-backend",
|
|
272
|
+
main: "src/index.ts",
|
|
273
|
+
checkstack: { type: "backend", pluginId: "cache-memory" },
|
|
274
|
+
},
|
|
275
|
+
}),
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const resolved = resolveCorePluginDeps({
|
|
279
|
+
pluginDir: ROOT,
|
|
280
|
+
readFile: readFileFromFs(fs),
|
|
281
|
+
resolveFrom: makeResolver(fs),
|
|
282
|
+
});
|
|
283
|
+
expect(resolved.map((r) => r.name)).not.toContain("@my-org/widget-backend");
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
it("skips queue-memory auto-include when bullmq is already in the dep graph", () => {
|
|
287
|
+
const fs: Fs = {
|
|
288
|
+
[`${ROOT}/package.json`]: JSON.stringify({
|
|
289
|
+
name: "@my-org/widget-backend",
|
|
290
|
+
dependencies: {
|
|
291
|
+
"@checkstack/queue-bullmq-backend": "^1.0.0",
|
|
292
|
+
},
|
|
293
|
+
checkstack: { type: "backend", pluginId: "widget" },
|
|
294
|
+
}),
|
|
295
|
+
...makeFs({
|
|
296
|
+
"@checkstack/queue-bullmq-backend": {
|
|
297
|
+
name: "@checkstack/queue-bullmq-backend",
|
|
298
|
+
main: "src/index.ts",
|
|
299
|
+
checkstack: { type: "backend", pluginId: "queue-bullmq" },
|
|
300
|
+
},
|
|
301
|
+
"@checkstack/queue-memory-backend": {
|
|
302
|
+
name: "@checkstack/queue-memory-backend",
|
|
303
|
+
main: "src/index.ts",
|
|
304
|
+
checkstack: { type: "backend", pluginId: "queue-memory" },
|
|
305
|
+
},
|
|
306
|
+
"@checkstack/cache-memory-backend": {
|
|
307
|
+
name: "@checkstack/cache-memory-backend",
|
|
308
|
+
main: "src/index.ts",
|
|
309
|
+
checkstack: { type: "backend", pluginId: "cache-memory" },
|
|
310
|
+
},
|
|
311
|
+
}),
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
const resolved = resolveCorePluginDeps({
|
|
315
|
+
pluginDir: ROOT,
|
|
316
|
+
readFile: readFileFromFs(fs),
|
|
317
|
+
resolveFrom: makeResolver(fs),
|
|
318
|
+
});
|
|
319
|
+
const names = resolved.map((r) => r.name);
|
|
320
|
+
expect(names).toContain("@checkstack/queue-bullmq-backend");
|
|
321
|
+
expect(names).not.toContain("@checkstack/queue-memory-backend");
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it("does not include @checkstack/* frontend or tooling packages", () => {
|
|
325
|
+
const fs: Fs = {
|
|
326
|
+
[`${ROOT}/package.json`]: JSON.stringify({
|
|
327
|
+
name: "@my-org/widget-backend",
|
|
328
|
+
dependencies: {
|
|
329
|
+
"@checkstack/healthcheck-backend": "^1.0.0",
|
|
330
|
+
"@checkstack/healthcheck-frontend": "^1.0.0",
|
|
331
|
+
"@checkstack/scripts": "^0.1.0",
|
|
332
|
+
},
|
|
333
|
+
checkstack: { type: "backend", pluginId: "widget" },
|
|
334
|
+
}),
|
|
335
|
+
...makeFs({
|
|
336
|
+
"@checkstack/healthcheck-backend": {
|
|
337
|
+
name: "@checkstack/healthcheck-backend",
|
|
338
|
+
main: "src/index.ts",
|
|
339
|
+
checkstack: { type: "backend", pluginId: "healthcheck" },
|
|
340
|
+
},
|
|
341
|
+
"@checkstack/healthcheck-frontend": {
|
|
342
|
+
name: "@checkstack/healthcheck-frontend",
|
|
343
|
+
main: "src/index.tsx",
|
|
344
|
+
checkstack: { type: "frontend", pluginId: "healthcheck" },
|
|
345
|
+
},
|
|
346
|
+
"@checkstack/scripts": {
|
|
347
|
+
name: "@checkstack/scripts",
|
|
348
|
+
checkstack: { type: "tooling" },
|
|
349
|
+
},
|
|
350
|
+
"@checkstack/queue-memory-backend": {
|
|
351
|
+
name: "@checkstack/queue-memory-backend",
|
|
352
|
+
main: "src/index.ts",
|
|
353
|
+
checkstack: { type: "backend", pluginId: "queue-memory" },
|
|
354
|
+
},
|
|
355
|
+
"@checkstack/cache-memory-backend": {
|
|
356
|
+
name: "@checkstack/cache-memory-backend",
|
|
357
|
+
main: "src/index.ts",
|
|
358
|
+
checkstack: { type: "backend", pluginId: "cache-memory" },
|
|
359
|
+
},
|
|
360
|
+
}),
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
const resolved = resolveCorePluginDeps({
|
|
364
|
+
pluginDir: ROOT,
|
|
365
|
+
readFile: readFileFromFs(fs),
|
|
366
|
+
resolveFrom: makeResolver(fs),
|
|
367
|
+
});
|
|
368
|
+
const names = resolved.map((r) => r.name);
|
|
369
|
+
expect(names).toContain("@checkstack/healthcheck-backend");
|
|
370
|
+
expect(names).not.toContain("@checkstack/healthcheck-frontend");
|
|
371
|
+
expect(names).not.toContain("@checkstack/scripts");
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
it("silently skips a declared dep that isn't actually installed", () => {
|
|
375
|
+
const fs: Fs = {
|
|
376
|
+
[`${ROOT}/package.json`]: JSON.stringify({
|
|
377
|
+
name: "@my-org/widget-backend",
|
|
378
|
+
dependencies: {
|
|
379
|
+
"@checkstack/missing-backend": "^1.0.0",
|
|
380
|
+
},
|
|
381
|
+
checkstack: { type: "backend", pluginId: "widget" },
|
|
382
|
+
}),
|
|
383
|
+
...makeFs({
|
|
384
|
+
"@checkstack/queue-memory-backend": {
|
|
385
|
+
name: "@checkstack/queue-memory-backend",
|
|
386
|
+
main: "src/index.ts",
|
|
387
|
+
checkstack: { type: "backend", pluginId: "queue-memory" },
|
|
388
|
+
},
|
|
389
|
+
"@checkstack/cache-memory-backend": {
|
|
390
|
+
name: "@checkstack/cache-memory-backend",
|
|
391
|
+
main: "src/index.ts",
|
|
392
|
+
checkstack: { type: "backend", pluginId: "cache-memory" },
|
|
393
|
+
},
|
|
394
|
+
}),
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
const resolved = resolveCorePluginDeps({
|
|
398
|
+
pluginDir: ROOT,
|
|
399
|
+
readFile: readFileFromFs(fs),
|
|
400
|
+
resolveFrom: makeResolver(fs),
|
|
401
|
+
});
|
|
402
|
+
expect(resolved.map((r) => r.name)).not.toContain(
|
|
403
|
+
"@checkstack/missing-backend",
|
|
404
|
+
);
|
|
405
|
+
// Auto-included providers still present — boot needs them.
|
|
406
|
+
expect(resolved.map((r) => r.name).toSorted()).toEqual([
|
|
407
|
+
"@checkstack/cache-memory-backend",
|
|
408
|
+
"@checkstack/queue-memory-backend",
|
|
409
|
+
]);
|
|
410
|
+
});
|
|
411
|
+
});
|