everything-dev 1.26.0 → 1.27.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/dist/api-contract.cjs.map +1 -1
- package/dist/api-contract.mjs.map +1 -1
- package/dist/cli/catalog.cjs.map +1 -1
- package/dist/cli/catalog.mjs.map +1 -1
- package/dist/cli/framework-version.cjs.map +1 -1
- package/dist/cli/framework-version.mjs.map +1 -1
- package/dist/cli/infra.cjs.map +1 -1
- package/dist/cli/infra.mjs.map +1 -1
- package/dist/cli/init.cjs +127 -114
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts +7 -6
- package/dist/cli/init.d.cts.map +1 -1
- package/dist/cli/init.d.mts +7 -6
- package/dist/cli/init.d.mts.map +1 -1
- package/dist/cli/init.mjs +124 -114
- package/dist/cli/init.mjs.map +1 -1
- package/dist/cli/parse.cjs.map +1 -1
- package/dist/cli/parse.mjs.map +1 -1
- package/dist/cli/prompts.cjs +3 -3
- package/dist/cli/prompts.cjs.map +1 -1
- package/dist/cli/prompts.mjs +2 -2
- package/dist/cli/prompts.mjs.map +1 -1
- package/dist/cli/status.cjs.map +1 -1
- package/dist/cli/status.mjs.map +1 -1
- package/dist/cli/sync.cjs +42 -92
- package/dist/cli/sync.cjs.map +1 -1
- package/dist/cli/sync.mjs +45 -95
- package/dist/cli/sync.mjs.map +1 -1
- package/dist/cli/timing.cjs.map +1 -1
- package/dist/cli/timing.mjs.map +1 -1
- package/dist/cli/upgrade.cjs +43 -22
- package/dist/cli/upgrade.cjs.map +1 -1
- package/dist/cli/upgrade.mjs +44 -23
- package/dist/cli/upgrade.mjs.map +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/cli.mjs.map +1 -1
- package/dist/components/dev-view.cjs.map +1 -1
- package/dist/components/dev-view.mjs.map +1 -1
- package/dist/components/streaming-view.cjs.map +1 -1
- package/dist/components/streaming-view.mjs.map +1 -1
- package/dist/config.cjs.map +1 -1
- package/dist/config.mjs.map +1 -1
- package/dist/contract.cjs +174 -173
- package/dist/contract.cjs.map +1 -1
- package/dist/contract.d.cts +3 -3
- package/dist/contract.d.cts.map +1 -1
- package/dist/contract.d.mts +3 -3
- package/dist/contract.d.mts.map +1 -1
- package/dist/contract.meta.cjs +1 -1
- package/dist/contract.meta.cjs.map +1 -1
- package/dist/contract.meta.d.cts +1 -1
- package/dist/contract.meta.d.mts +1 -1
- package/dist/contract.meta.mjs +1 -1
- package/dist/contract.meta.mjs.map +1 -1
- package/dist/contract.mjs +2 -1
- package/dist/contract.mjs.map +1 -1
- package/dist/dev-logs.cjs.map +1 -1
- package/dist/dev-logs.mjs.map +1 -1
- package/dist/fastkv.cjs.map +1 -1
- package/dist/fastkv.mjs.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/integrity.cjs.map +1 -1
- package/dist/integrity.mjs.map +1 -1
- package/dist/internal/manifest-normalizer.cjs.map +1 -1
- package/dist/internal/manifest-normalizer.mjs.map +1 -1
- package/dist/merge.cjs.map +1 -1
- package/dist/merge.mjs.map +1 -1
- package/dist/near-cli.cjs.map +1 -1
- package/dist/near-cli.mjs.map +1 -1
- package/dist/orchestrator.cjs.map +1 -1
- package/dist/orchestrator.mjs.map +1 -1
- package/dist/plugin.cjs +72 -50
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +2 -2
- package/dist/plugin.d.cts.map +1 -1
- package/dist/plugin.d.mts +2 -2
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +53 -32
- package/dist/plugin.mjs.map +1 -1
- package/dist/sdk.cjs +2 -2
- package/dist/sdk.d.cts +1 -1
- package/dist/sdk.d.mts +1 -1
- package/dist/sdk.mjs +1 -1
- package/dist/shared.cjs.map +1 -1
- package/dist/shared.mjs.map +1 -1
- package/dist/types.cjs +184 -184
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +3 -3
- package/dist/types.d.mts +3 -3
- package/dist/types.mjs +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/ui/types.d.cts +1 -0
- package/dist/ui/types.d.cts.map +1 -1
- package/dist/ui/types.d.mts +1 -0
- package/dist/ui/types.d.mts.map +1 -1
- package/dist/utils/banner.cjs.map +1 -1
- package/dist/utils/banner.mjs.map +1 -1
- package/dist/utils/run.cjs.map +1 -1
- package/dist/utils/run.mjs.map +1 -1
- package/package.json +2 -2
- package/skills/init-upgrade/SKILL.md +22 -16
- package/skills/publish-sync/SKILL.md +7 -18
- package/src/cli/init.ts +149 -195
- package/src/cli/prompts.ts +1 -1
- package/src/cli/sync.ts +48 -137
- package/src/cli/upgrade.ts +66 -25
- package/src/contract.meta.ts +1 -1
- package/src/contract.ts +2 -1
- package/src/plugin.ts +69 -34
- package/src/sdk.ts +1 -1
- package/src/types.ts +1 -1
- package/src/ui/types.ts +1 -0
- package/dist/utils/path-match.cjs +0 -18
- package/dist/utils/path-match.cjs.map +0 -1
- package/dist/utils/path-match.mjs +0 -17
- package/dist/utils/path-match.mjs.map +0 -1
package/src/cli/sync.ts
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import {
|
|
3
|
-
copyFileSync,
|
|
4
|
-
existsSync,
|
|
5
|
-
lstatSync,
|
|
6
|
-
mkdirSync,
|
|
7
|
-
readFileSync,
|
|
8
|
-
writeFileSync,
|
|
9
|
-
} from "node:fs";
|
|
2
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
10
3
|
import { dirname, join } from "node:path";
|
|
11
|
-
import { glob } from "glob";
|
|
12
4
|
import { loadConfig } from "../config";
|
|
13
5
|
import type { SyncOptions, SyncResult } from "../contract";
|
|
14
6
|
import {
|
|
@@ -16,32 +8,38 @@ import {
|
|
|
16
8
|
mergeBosConfigWithTemplate,
|
|
17
9
|
resolveExtendsRef,
|
|
18
10
|
} from "../merge";
|
|
19
|
-
import { isPathExcluded } from "../utils/path-match";
|
|
20
11
|
import { writeGeneratedInfra } from "./infra";
|
|
21
12
|
import {
|
|
22
13
|
personalizeConfig,
|
|
23
|
-
readTemplatekeep,
|
|
24
14
|
resolveSourceDir,
|
|
25
15
|
runBunInstall,
|
|
26
16
|
runTypesGen,
|
|
17
|
+
sourcePathToDestinationPath,
|
|
27
18
|
} from "./init";
|
|
28
|
-
import {
|
|
19
|
+
import { writeSnapshot } from "./snapshot";
|
|
29
20
|
|
|
30
21
|
const FRAMEWORK_OWNED_SYNC_FILES = new Set([
|
|
31
22
|
".env.example",
|
|
32
23
|
".gitignore",
|
|
24
|
+
"AGENTS.md",
|
|
33
25
|
"biome.json",
|
|
34
26
|
"bos.config.json",
|
|
27
|
+
"bunfig.toml",
|
|
28
|
+
"CONTRIBUTING.md",
|
|
35
29
|
"package.json",
|
|
30
|
+
".changeset/config.json",
|
|
31
|
+
".changeset/README.md",
|
|
36
32
|
"docker-compose.yml",
|
|
37
33
|
".github/renovate.json",
|
|
38
34
|
".github/workflows/ci.yml",
|
|
39
35
|
".github/workflows/release-sync.yml",
|
|
36
|
+
".opencode/skills/everything-dev/SKILL.md",
|
|
40
37
|
"ui/package.json",
|
|
41
38
|
"ui/postcss.config.mjs",
|
|
42
39
|
"ui/rsbuild.config.ts",
|
|
43
40
|
"ui/tsconfig.json",
|
|
44
41
|
"ui/src/app.ts",
|
|
42
|
+
"ui/src/globals.d.ts",
|
|
45
43
|
"ui/src/hydrate.tsx",
|
|
46
44
|
"ui/src/lib/api.ts",
|
|
47
45
|
"ui/src/lib/auth.ts",
|
|
@@ -62,23 +60,6 @@ export function isFrameworkOwnedSyncFile(filePath: string): boolean {
|
|
|
62
60
|
return FRAMEWORK_OWNED_SYNC_FILES.has(filePath);
|
|
63
61
|
}
|
|
64
62
|
|
|
65
|
-
function readExcludeFile(filePath: string): string[] {
|
|
66
|
-
if (!existsSync(filePath)) return [];
|
|
67
|
-
const content = readFileSync(filePath, "utf-8");
|
|
68
|
-
return content
|
|
69
|
-
.split("\n")
|
|
70
|
-
.map((line) => line.trim())
|
|
71
|
-
.filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export async function readTemplatesyncExclude(sourceDir: string): Promise<string[]> {
|
|
75
|
-
return readExcludeFile(join(sourceDir, ".templatesync-exclude"));
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function readLocalSyncExcludes(projectDir: string): string[] {
|
|
79
|
-
return readExcludeFile(join(projectDir, ".bos", "sync-local-exclude"));
|
|
80
|
-
}
|
|
81
|
-
|
|
82
63
|
function computeLocalHash(projectDir: string, filePath: string): string | null {
|
|
83
64
|
const fullPath = join(projectDir, filePath);
|
|
84
65
|
if (!existsSync(fullPath)) return null;
|
|
@@ -232,9 +213,23 @@ export function mergePackageJson(
|
|
|
232
213
|
}
|
|
233
214
|
|
|
234
215
|
function toDestPath(filePath: string): string {
|
|
235
|
-
return filePath
|
|
236
|
-
|
|
237
|
-
|
|
216
|
+
return sourcePathToDestinationPath(filePath);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function toSourcePath(sourceDir: string, destPath: string): string | null {
|
|
220
|
+
const directPath = join(sourceDir, destPath);
|
|
221
|
+
if (existsSync(directPath)) {
|
|
222
|
+
return destPath;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (destPath.startsWith(".github/")) {
|
|
226
|
+
const templatePath = destPath.replace(/^\.github\//, ".github/templates/");
|
|
227
|
+
if (existsSync(join(sourceDir, templatePath))) {
|
|
228
|
+
return templatePath;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return null;
|
|
238
233
|
}
|
|
239
234
|
|
|
240
235
|
function writeSyncedFile(sourceDir: string, projectDir: string, filePath: string): void {
|
|
@@ -319,90 +314,31 @@ export async function syncTemplate(projectDir: string, options: SyncOptions): Pr
|
|
|
319
314
|
});
|
|
320
315
|
|
|
321
316
|
try {
|
|
322
|
-
const patterns = await readTemplatekeep(sourceDir);
|
|
323
|
-
if (patterns.length === 0) {
|
|
324
|
-
return {
|
|
325
|
-
status: "error",
|
|
326
|
-
updated: [],
|
|
327
|
-
skipped: [],
|
|
328
|
-
added: [],
|
|
329
|
-
error: "No .templatekeep found in template source",
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
const parentExcludes = await readTemplatesyncExclude(sourceDir);
|
|
334
|
-
const localExcludes = readLocalSyncExcludes(projectDir);
|
|
335
|
-
const excludePatterns = [...parentExcludes, ...localExcludes];
|
|
336
|
-
|
|
337
|
-
const allTemplateFiles = new Set<string>();
|
|
338
|
-
for (const pattern of patterns) {
|
|
339
|
-
const matches = await glob(pattern, {
|
|
340
|
-
cwd: sourceDir,
|
|
341
|
-
nodir: true,
|
|
342
|
-
dot: true,
|
|
343
|
-
absolute: false,
|
|
344
|
-
});
|
|
345
|
-
for (const match of matches) {
|
|
346
|
-
allTemplateFiles.add(match);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
317
|
const childPlugins =
|
|
351
318
|
localConfig.plugins && typeof localConfig.plugins === "object"
|
|
352
319
|
? Object.keys(localConfig.plugins as Record<string, unknown>)
|
|
353
320
|
: [];
|
|
354
|
-
|
|
355
|
-
const
|
|
356
|
-
const
|
|
357
|
-
for (const [key, plugin] of Object.entries(parentRuntime?.runtime.plugins ?? {})) {
|
|
358
|
-
if (plugin.routes && plugin.routes.length > 0) {
|
|
359
|
-
pluginRoutes[key] = plugin.routes;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
const excludedRoutePatterns: string[] = [];
|
|
364
|
-
for (const [pluginKey, routePatterns] of Object.entries(pluginRoutes)) {
|
|
365
|
-
if (!childPlugins.includes(pluginKey)) {
|
|
366
|
-
excludedRoutePatterns.push(...routePatterns);
|
|
367
|
-
}
|
|
368
|
-
}
|
|
321
|
+
const withUi = existsSync(join(projectDir, "ui", "package.json"));
|
|
322
|
+
const withApi = existsSync(join(projectDir, "api", "package.json"));
|
|
323
|
+
const withHost = existsSync(join(projectDir, "host", "package.json"));
|
|
369
324
|
|
|
370
325
|
const filteredFiles = new Set<string>();
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
if (
|
|
374
|
-
if (
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
for (const rp of routePatterns) {
|
|
381
|
-
const matches = await glob(rp, {
|
|
382
|
-
cwd: sourceDir,
|
|
383
|
-
nodir: true,
|
|
384
|
-
dot: true,
|
|
385
|
-
absolute: false,
|
|
386
|
-
});
|
|
387
|
-
for (const match of matches) {
|
|
388
|
-
if (!isPathExcluded(match, excludedRoutePatterns)) {
|
|
389
|
-
filteredFiles.add(match);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
326
|
+
const destToSource = new Map<string, string>();
|
|
327
|
+
for (const destPath of FRAMEWORK_OWNED_SYNC_FILES) {
|
|
328
|
+
if (destPath.startsWith("ui/") && !withUi) continue;
|
|
329
|
+
if (destPath.startsWith("api/") && !withApi) continue;
|
|
330
|
+
if (destPath.startsWith("host/") && !withHost) continue;
|
|
331
|
+
const sourcePath = toSourcePath(sourceDir, destPath);
|
|
332
|
+
if (!sourcePath) continue;
|
|
333
|
+
filteredFiles.add(sourcePath);
|
|
334
|
+
destToSource.set(destPath, sourcePath);
|
|
393
335
|
}
|
|
394
336
|
|
|
395
|
-
const snapshot = await readSnapshot(projectDir);
|
|
396
|
-
|
|
397
337
|
const updated: string[] = [];
|
|
398
338
|
const skipped: string[] = [];
|
|
399
339
|
const added: string[] = [];
|
|
400
340
|
|
|
401
|
-
for (const filePath of
|
|
402
|
-
const destPath = toDestPath(filePath);
|
|
403
|
-
const frameworkOwned = isFrameworkOwnedSyncFile(destPath);
|
|
404
|
-
if (isPathExcluded(destPath, excludePatterns) && !frameworkOwned) continue;
|
|
405
|
-
|
|
341
|
+
for (const [destPath, filePath] of destToSource.entries()) {
|
|
406
342
|
const localHash = computeLocalHash(projectDir, destPath);
|
|
407
343
|
const sourceContent = readFileSync(join(sourceDir, filePath));
|
|
408
344
|
const sourceHash = createHash("sha256").update(sourceContent).digest("hex").substring(0, 16);
|
|
@@ -412,28 +348,8 @@ export async function syncTemplate(projectDir: string, options: SyncOptions): Pr
|
|
|
412
348
|
continue;
|
|
413
349
|
}
|
|
414
350
|
|
|
415
|
-
if (localHash
|
|
416
|
-
|
|
417
|
-
if (frameworkOwned) {
|
|
351
|
+
if (localHash !== sourceHash) {
|
|
418
352
|
updated.push(destPath);
|
|
419
|
-
continue;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
const snapshotHash = snapshot?.files[destPath];
|
|
423
|
-
|
|
424
|
-
if (snapshotHash === undefined) {
|
|
425
|
-
updated.push(destPath);
|
|
426
|
-
continue;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
if (localHash === snapshotHash) {
|
|
430
|
-
updated.push(destPath);
|
|
431
|
-
} else {
|
|
432
|
-
if (options.force) {
|
|
433
|
-
updated.push(destPath);
|
|
434
|
-
} else {
|
|
435
|
-
skipped.push(destPath);
|
|
436
|
-
}
|
|
437
353
|
}
|
|
438
354
|
}
|
|
439
355
|
|
|
@@ -446,14 +362,7 @@ export async function syncTemplate(projectDir: string, options: SyncOptions): Pr
|
|
|
446
362
|
};
|
|
447
363
|
}
|
|
448
364
|
|
|
449
|
-
const filesToWrite = [...updated, ...added]
|
|
450
|
-
(f) => isFrameworkOwnedSyncFile(f) || !isPathExcluded(f, excludePatterns),
|
|
451
|
-
);
|
|
452
|
-
|
|
453
|
-
const destToSource = new Map<string, string>();
|
|
454
|
-
for (const filePath of filteredFiles) {
|
|
455
|
-
destToSource.set(toDestPath(filePath), filePath);
|
|
456
|
-
}
|
|
365
|
+
const filesToWrite = [...updated, ...added];
|
|
457
366
|
|
|
458
367
|
if (filesToWrite.length > 0) {
|
|
459
368
|
backupFiles(projectDir, filesToWrite);
|
|
@@ -467,8 +376,6 @@ export async function syncTemplate(projectDir: string, options: SyncOptions): Pr
|
|
|
467
376
|
const newSnapshotFiles: Record<string, string> = {};
|
|
468
377
|
for (const filePath of filteredFiles) {
|
|
469
378
|
const src = join(sourceDir, filePath);
|
|
470
|
-
const stat = lstatSync(src);
|
|
471
|
-
if (!stat.isFile()) continue;
|
|
472
379
|
const content = readFileSync(src);
|
|
473
380
|
newSnapshotFiles[toDestPath(filePath)] = createHash("sha256")
|
|
474
381
|
.update(content)
|
|
@@ -483,15 +390,19 @@ export async function syncTemplate(projectDir: string, options: SyncOptions): Pr
|
|
|
483
390
|
|
|
484
391
|
const account = (localConfig.account as string) || extendsAccount;
|
|
485
392
|
const domain = (localConfig.domain as string) || extendsGateway;
|
|
393
|
+
const overrides: Array<"ui" | "api" | "host" | "plugins"> = [];
|
|
394
|
+
if (withUi) overrides.push("ui");
|
|
395
|
+
if (withApi) overrides.push("api");
|
|
396
|
+
if (withHost) overrides.push("host");
|
|
397
|
+
if (childPlugins.length > 0) overrides.push("plugins");
|
|
486
398
|
|
|
487
399
|
await personalizeConfig(projectDir, {
|
|
488
400
|
extendsAccount,
|
|
489
401
|
extendsGateway,
|
|
490
402
|
account,
|
|
491
403
|
domain,
|
|
404
|
+
overrides,
|
|
492
405
|
plugins: childPlugins,
|
|
493
|
-
pluginRoutes,
|
|
494
|
-
overrides: ["ui", "api", "host", "plugins"],
|
|
495
406
|
workspaceOpts: { sourceDir },
|
|
496
407
|
mode: "sync",
|
|
497
408
|
});
|
package/src/cli/upgrade.ts
CHANGED
|
@@ -4,10 +4,10 @@ import process from "node:process";
|
|
|
4
4
|
import * as p from "@clack/prompts";
|
|
5
5
|
import { glob } from "glob";
|
|
6
6
|
import type { PhaseTiming, UpgradeOptions, UpgradeResult } from "../contract";
|
|
7
|
-
import { resolveExtendsRef } from "../merge";
|
|
7
|
+
import { isPlainObject as isPlainObjectFromMerge, resolveExtendsRef } from "../merge";
|
|
8
8
|
import { saveBosConfig } from "../utils/save-config";
|
|
9
9
|
import { readInstalledFrameworkVersion } from "./framework-version";
|
|
10
|
-
import { fetchParentConfig, runBunInstallForUpgrade, runTypesGen } from "./init";
|
|
10
|
+
import { fetchParentConfig, resolveSourceDir, runBunInstallForUpgrade, runTypesGen } from "./init";
|
|
11
11
|
import { syncTemplate } from "./sync";
|
|
12
12
|
import { timePhase } from "./timing";
|
|
13
13
|
|
|
@@ -25,6 +25,14 @@ const CATALOG_TOOL_PACKAGES = [
|
|
|
25
25
|
"@module-federation/sdk",
|
|
26
26
|
"@module-federation/dts-plugin",
|
|
27
27
|
] as const;
|
|
28
|
+
const PINNED_CATALOG_TOOL_VERSIONS: Partial<
|
|
29
|
+
Record<(typeof CATALOG_TOOL_PACKAGES)[number], string>
|
|
30
|
+
> = {
|
|
31
|
+
"@rspack/core": "1.7.11",
|
|
32
|
+
"@rspack/cli": "1.7.11",
|
|
33
|
+
"@rsbuild/core": "1.7.5",
|
|
34
|
+
"@rsbuild/plugin-react": "1.4.6",
|
|
35
|
+
};
|
|
28
36
|
const LEGACY_UI_IMPORT_REWRITES = [
|
|
29
37
|
['from "@/auth"', 'from "@/app"'],
|
|
30
38
|
["from '@/auth'", "from '@/app'"],
|
|
@@ -46,10 +54,53 @@ const OBSOLETE_FILES = [
|
|
|
46
54
|
".github/dependabot.yml",
|
|
47
55
|
".github/templates/dependabot.yml",
|
|
48
56
|
"packages/everything-dev/cli.js",
|
|
57
|
+
".templatekeep",
|
|
58
|
+
".templatesync-exclude",
|
|
49
59
|
];
|
|
50
60
|
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
function extractVersion(value: string | undefined): string | null {
|
|
62
|
+
if (!value) return null;
|
|
63
|
+
const match = value.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/);
|
|
64
|
+
return match?.[0] ?? null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function readExtendedRootCatalog(projectDir: string): Promise<Record<string, string>> {
|
|
68
|
+
const configPath = join(projectDir, "bos.config.json");
|
|
69
|
+
if (!existsSync(configPath)) {
|
|
70
|
+
return {};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const localConfig = JSON.parse(readFileSync(configPath, "utf-8")) as Record<string, unknown>;
|
|
74
|
+
let extendsRef: string | undefined;
|
|
75
|
+
if (typeof localConfig.extends === "string") {
|
|
76
|
+
extendsRef = localConfig.extends;
|
|
77
|
+
} else if (isPlainObjectFromMerge(localConfig.extends)) {
|
|
78
|
+
extendsRef = resolveExtendsRef(localConfig.extends as Record<string, string>, "production");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const parsed = extendsRef ? parseBosRef(extendsRef) : null;
|
|
82
|
+
if (!parsed) {
|
|
83
|
+
return {};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const { sourceDir, cleanup } = await resolveSourceDir({
|
|
87
|
+
extendsAccount: parsed.account,
|
|
88
|
+
extendsGateway: parsed.gateway,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const sourcePkgPath = join(sourceDir, "package.json");
|
|
93
|
+
if (!existsSync(sourcePkgPath)) {
|
|
94
|
+
return {};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const sourcePkg = JSON.parse(readFileSync(sourcePkgPath, "utf-8")) as {
|
|
98
|
+
workspaces?: { catalog?: Record<string, string> };
|
|
99
|
+
};
|
|
100
|
+
return { ...(sourcePkg.workspaces?.catalog ?? {}) };
|
|
101
|
+
} finally {
|
|
102
|
+
await cleanup();
|
|
103
|
+
}
|
|
53
104
|
}
|
|
54
105
|
|
|
55
106
|
function getExtendsRef(config: Record<string, unknown>): string | undefined {
|
|
@@ -468,20 +519,6 @@ async function addSelectedParentPlugins(projectDir: string): Promise<string[]> {
|
|
|
468
519
|
return selected;
|
|
469
520
|
}
|
|
470
521
|
|
|
471
|
-
async function fetchLatestNpmVersion(packageName: string): Promise<string | null> {
|
|
472
|
-
try {
|
|
473
|
-
const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {
|
|
474
|
-
headers: { Accept: "application/json" },
|
|
475
|
-
signal: AbortSignal.timeout(10_000),
|
|
476
|
-
});
|
|
477
|
-
if (!response.ok) return null;
|
|
478
|
-
const data = (await response.json()) as NpmPackageInfo;
|
|
479
|
-
return data.version;
|
|
480
|
-
} catch {
|
|
481
|
-
return null;
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
|
|
485
522
|
function readInstalledVersion(projectDir: string, packageName: string): string | undefined {
|
|
486
523
|
return readInstalledFrameworkVersion(projectDir, packageName);
|
|
487
524
|
}
|
|
@@ -537,7 +574,7 @@ function updateRootPackageVersion(
|
|
|
537
574
|
modified = true;
|
|
538
575
|
}
|
|
539
576
|
|
|
540
|
-
const nextVersion =
|
|
577
|
+
const nextVersion = newVersion;
|
|
541
578
|
if (workspaces.catalog[packageName] !== nextVersion) {
|
|
542
579
|
workspaces.catalog[packageName] = nextVersion;
|
|
543
580
|
modified = true;
|
|
@@ -566,7 +603,7 @@ function updateRootCatalogVersion(
|
|
|
566
603
|
workspaces.catalog = {};
|
|
567
604
|
}
|
|
568
605
|
|
|
569
|
-
const nextVersion =
|
|
606
|
+
const nextVersion = newVersion;
|
|
570
607
|
if (workspaces.catalog[packageName] === nextVersion) return false;
|
|
571
608
|
|
|
572
609
|
workspaces.catalog[packageName] = nextVersion;
|
|
@@ -662,6 +699,8 @@ export async function upgradeTemplate(
|
|
|
662
699
|
};
|
|
663
700
|
}
|
|
664
701
|
|
|
702
|
+
const sourceRootCatalog = await readExtendedRootCatalog(projectDir);
|
|
703
|
+
|
|
665
704
|
const { packages, catalogVersionUpdates } = await timePhase(
|
|
666
705
|
timings,
|
|
667
706
|
"check package versions",
|
|
@@ -670,7 +709,7 @@ export async function upgradeTemplate(
|
|
|
670
709
|
|
|
671
710
|
for (const name of FRAMEWORK_PACKAGES) {
|
|
672
711
|
const installed = readInstalledVersion(projectDir, name);
|
|
673
|
-
const latest =
|
|
712
|
+
const latest = extractVersion(sourceRootCatalog[name]);
|
|
674
713
|
|
|
675
714
|
if (!latest) {
|
|
676
715
|
nextPackages.push({ name, from: installed, to: installed ?? "unknown" });
|
|
@@ -688,10 +727,12 @@ export async function upgradeTemplate(
|
|
|
688
727
|
for (const name of CATALOG_TOOL_PACKAGES) {
|
|
689
728
|
const installed = readInstalledVersion(projectDir, name);
|
|
690
729
|
if (!installed) continue;
|
|
691
|
-
const
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
730
|
+
const targetVersion =
|
|
731
|
+
PINNED_CATALOG_TOOL_VERSIONS[name] ??
|
|
732
|
+
extractVersion(sourceRootCatalog[name]) ??
|
|
733
|
+
installed;
|
|
734
|
+
if (installed === targetVersion) continue;
|
|
735
|
+
nextCatalogVersionUpdates.push({ name, from: installed, to: targetVersion });
|
|
695
736
|
}
|
|
696
737
|
|
|
697
738
|
return { packages: nextPackages, catalogVersionUpdates: nextCatalogVersionUpdates };
|
package/src/contract.meta.ts
CHANGED
|
@@ -96,7 +96,7 @@ export const cliCommandMeta = {
|
|
|
96
96
|
description: "Comma-separated plugin keys to include (requires --overrides=plugins)",
|
|
97
97
|
},
|
|
98
98
|
overrides: {
|
|
99
|
-
description: "Comma-separated sections to
|
|
99
|
+
description: "Comma-separated sections to customize locally: ui,api,host,plugins",
|
|
100
100
|
},
|
|
101
101
|
noInteractive: { description: "Skip prompts, use flags only" },
|
|
102
102
|
noInstall: { description: "Skip bun install" },
|
package/src/contract.ts
CHANGED
package/src/plugin.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { basename, dirname, join, resolve } from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
3
4
|
import * as p from "@clack/prompts";
|
|
4
5
|
import { Effect } from "effect";
|
|
5
6
|
import { syncApiContractBridge } from "./api-contract";
|
|
6
7
|
import { buildRuntimeConfig, detectLocalPackages, prepareDevelopmentRuntimeConfig } from "./app";
|
|
7
8
|
import { ensureEnvFile, writeGeneratedInfra } from "./cli/infra";
|
|
8
9
|
import {
|
|
10
|
+
buildInitPatterns,
|
|
9
11
|
copyFilteredFiles,
|
|
10
12
|
detectGitRemoteUrl,
|
|
11
13
|
fetchParentConfig,
|
|
12
14
|
generateDatabaseMigrations,
|
|
13
15
|
personalizeConfig,
|
|
14
|
-
|
|
16
|
+
removeInitLockfile,
|
|
15
17
|
resolveSourceDir,
|
|
16
18
|
runBunInstall,
|
|
17
19
|
runDockerComposeUp,
|
|
@@ -1235,6 +1237,8 @@ export default createPlugin({
|
|
|
1235
1237
|
|
|
1236
1238
|
if (!input.noInteractive) {
|
|
1237
1239
|
s.stop("Config fetched");
|
|
1240
|
+
const initialExtendsAccount = extendsAccount;
|
|
1241
|
+
const initialExtendsGateway = extendsGateway;
|
|
1238
1242
|
const prompted = await promptInitOptions({
|
|
1239
1243
|
extends: `bos://${extendsAccount}/${extendsGateway}`,
|
|
1240
1244
|
directory,
|
|
@@ -1251,6 +1255,58 @@ export default createPlugin({
|
|
|
1251
1255
|
domain = prompted.domain;
|
|
1252
1256
|
plugins = prompted.plugins;
|
|
1253
1257
|
overrides = prompted.overrides;
|
|
1258
|
+
|
|
1259
|
+
if (
|
|
1260
|
+
!parentConfig ||
|
|
1261
|
+
prompted.extendsAccount !== initialExtendsAccount ||
|
|
1262
|
+
prompted.extendsGateway !== initialExtendsGateway
|
|
1263
|
+
) {
|
|
1264
|
+
try {
|
|
1265
|
+
parentConfig = await timePhase(
|
|
1266
|
+
timings,
|
|
1267
|
+
"parent config",
|
|
1268
|
+
() => fetchParentConfig(prompted.extendsAccount, prompted.extendsGateway),
|
|
1269
|
+
s,
|
|
1270
|
+
);
|
|
1271
|
+
if (parentConfig?.plugins && typeof parentConfig.plugins === "object") {
|
|
1272
|
+
parentPluginKeys = Object.keys(parentConfig.plugins);
|
|
1273
|
+
} else {
|
|
1274
|
+
parentPluginKeys = [];
|
|
1275
|
+
}
|
|
1276
|
+
} catch {
|
|
1277
|
+
return {
|
|
1278
|
+
status: "error" as const,
|
|
1279
|
+
directory,
|
|
1280
|
+
extendsRef: `bos://${prompted.extendsAccount}/${prompted.extendsGateway}`,
|
|
1281
|
+
account,
|
|
1282
|
+
domain,
|
|
1283
|
+
extends: `bos://${prompted.extendsAccount}/${prompted.extendsGateway}`,
|
|
1284
|
+
plugins,
|
|
1285
|
+
overrides,
|
|
1286
|
+
filesCopied: 0,
|
|
1287
|
+
timings,
|
|
1288
|
+
error: `No config found at bos://${prompted.extendsAccount}/${prompted.extendsGateway} — are you sure this is the right parent?`,
|
|
1289
|
+
};
|
|
1290
|
+
}
|
|
1291
|
+
s.stop("Config fetched");
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
if (
|
|
1295
|
+
typeof parentConfig?.title === "string" &&
|
|
1296
|
+
parentConfig.title.trim() &&
|
|
1297
|
+
typeof parentConfig.description === "string" &&
|
|
1298
|
+
parentConfig.description.trim()
|
|
1299
|
+
) {
|
|
1300
|
+
const shouldContinue = await p.confirm({
|
|
1301
|
+
message: `You will be extending ${parentConfig.title} - ${parentConfig.description}. Continue?`,
|
|
1302
|
+
initialValue: true,
|
|
1303
|
+
});
|
|
1304
|
+
|
|
1305
|
+
if (p.isCancel(shouldContinue) || !shouldContinue) {
|
|
1306
|
+
process.exit(0);
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1254
1310
|
s.start("Setting up project");
|
|
1255
1311
|
}
|
|
1256
1312
|
|
|
@@ -1334,6 +1390,8 @@ export default createPlugin({
|
|
|
1334
1390
|
plugins,
|
|
1335
1391
|
overrides,
|
|
1336
1392
|
repository,
|
|
1393
|
+
title: parentConfig?.title,
|
|
1394
|
+
description: parentConfig?.description,
|
|
1337
1395
|
}),
|
|
1338
1396
|
s,
|
|
1339
1397
|
);
|
|
@@ -1351,40 +1409,15 @@ export default createPlugin({
|
|
|
1351
1409
|
overrides,
|
|
1352
1410
|
mode: "init",
|
|
1353
1411
|
repository,
|
|
1412
|
+
title: parentConfig?.title,
|
|
1413
|
+
description: parentConfig?.description,
|
|
1414
|
+
testnet: parentConfig?.testnet,
|
|
1415
|
+
staging: parentConfig?.staging,
|
|
1354
1416
|
}),
|
|
1355
1417
|
s,
|
|
1356
1418
|
);
|
|
1357
1419
|
} else {
|
|
1358
|
-
const patterns =
|
|
1359
|
-
if (patterns.length === 0) {
|
|
1360
|
-
s.stop("Failed");
|
|
1361
|
-
return {
|
|
1362
|
-
status: "error" as const,
|
|
1363
|
-
directory,
|
|
1364
|
-
extendsRef,
|
|
1365
|
-
account,
|
|
1366
|
-
domain,
|
|
1367
|
-
extends: extendsRef,
|
|
1368
|
-
plugins,
|
|
1369
|
-
overrides,
|
|
1370
|
-
filesCopied: 0,
|
|
1371
|
-
error: "No .templatekeep found in template source",
|
|
1372
|
-
};
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
|
-
const pluginRoutes: Record<string, string[]> = {};
|
|
1376
|
-
if (overrides.includes("plugins")) {
|
|
1377
|
-
const parentRuntimePlugins = await buildRuntimePluginsForConfig(
|
|
1378
|
-
parentConfig as BosConfig,
|
|
1379
|
-
sourceDir,
|
|
1380
|
-
"production",
|
|
1381
|
-
);
|
|
1382
|
-
for (const [key, plugin] of Object.entries(parentRuntimePlugins ?? {})) {
|
|
1383
|
-
if (plugin.routes && plugin.routes.length > 0) {
|
|
1384
|
-
pluginRoutes[key] = plugin.routes;
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1420
|
+
const patterns = buildInitPatterns(overrides, plugins);
|
|
1388
1421
|
|
|
1389
1422
|
filesCopied = await timePhase(
|
|
1390
1423
|
timings,
|
|
@@ -1393,7 +1426,6 @@ export default createPlugin({
|
|
|
1393
1426
|
copyFilteredFiles(sourceDir, targetDir, patterns, {
|
|
1394
1427
|
overrides,
|
|
1395
1428
|
plugins,
|
|
1396
|
-
pluginRoutes,
|
|
1397
1429
|
}),
|
|
1398
1430
|
s,
|
|
1399
1431
|
);
|
|
@@ -1409,9 +1441,12 @@ export default createPlugin({
|
|
|
1409
1441
|
domain: domain || extendsGateway,
|
|
1410
1442
|
plugins,
|
|
1411
1443
|
overrides,
|
|
1412
|
-
pluginRoutes,
|
|
1413
1444
|
workspaceOpts: { sourceDir },
|
|
1414
1445
|
repository,
|
|
1446
|
+
title: parentConfig?.title,
|
|
1447
|
+
description: parentConfig?.description,
|
|
1448
|
+
testnet: parentConfig?.testnet,
|
|
1449
|
+
staging: parentConfig?.staging,
|
|
1415
1450
|
}),
|
|
1416
1451
|
s,
|
|
1417
1452
|
);
|
|
@@ -1423,7 +1458,6 @@ export default createPlugin({
|
|
|
1423
1458
|
writeInitSnapshot(targetDir, extendsAccount, extendsGateway, sourceDir, patterns, {
|
|
1424
1459
|
overrides,
|
|
1425
1460
|
plugins,
|
|
1426
|
-
pluginRoutes,
|
|
1427
1461
|
}),
|
|
1428
1462
|
s,
|
|
1429
1463
|
);
|
|
@@ -1432,6 +1466,7 @@ export default createPlugin({
|
|
|
1432
1466
|
const lockfilePath = join(targetDir, "bun.lock");
|
|
1433
1467
|
const allowedWorkspaces = computeAllowedWorkspaces(overrides, plugins);
|
|
1434
1468
|
stripOrphanedWorkspacesFromLockfile(lockfilePath, allowedWorkspaces);
|
|
1469
|
+
removeInitLockfile(lockfilePath);
|
|
1435
1470
|
|
|
1436
1471
|
const initConfig = await timePhase(
|
|
1437
1472
|
timings,
|
package/src/sdk.ts
CHANGED
package/src/types.ts
CHANGED
package/src/ui/types.ts
CHANGED
|
@@ -40,6 +40,7 @@ export interface RenderOptions<TSession = unknown> {
|
|
|
40
40
|
export interface RenderOptionsWithApi<TApiClient = unknown, TSession = unknown>
|
|
41
41
|
extends RenderOptions<TSession> {
|
|
42
42
|
apiClient: TApiClient;
|
|
43
|
+
authClient?: unknown;
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
export interface RenderResult {
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
//#region src/utils/path-match.ts
|
|
3
|
-
function isPathExcluded(filePath, excludePatterns) {
|
|
4
|
-
if (excludePatterns.length === 0) return false;
|
|
5
|
-
for (const pattern of excludePatterns) if (pattern.endsWith("/**")) {
|
|
6
|
-
const prefix = pattern.slice(0, -3);
|
|
7
|
-
if (filePath.startsWith(`${prefix}/`) || filePath === prefix) return true;
|
|
8
|
-
} else if (pattern.endsWith("/*")) {
|
|
9
|
-
const prefix = pattern.slice(0, -2);
|
|
10
|
-
const slashIdx = filePath.indexOf("/", prefix.length + 1);
|
|
11
|
-
if (filePath.startsWith(`${prefix}/`) && slashIdx === -1) return true;
|
|
12
|
-
} else if (filePath === pattern || filePath.startsWith(`${pattern}/`)) return true;
|
|
13
|
-
return false;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
//#endregion
|
|
17
|
-
exports.isPathExcluded = isPathExcluded;
|
|
18
|
-
//# sourceMappingURL=path-match.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"path-match.cjs","names":[],"sources":["../../src/utils/path-match.ts"],"sourcesContent":["export function isPathExcluded(filePath: string, excludePatterns: string[]): boolean {\n if (excludePatterns.length === 0) return false;\n for (const pattern of excludePatterns) {\n if (pattern.endsWith(\"/**\")) {\n const prefix = pattern.slice(0, -3);\n if (filePath.startsWith(`${prefix}/`) || filePath === prefix) return true;\n } else if (pattern.endsWith(\"/*\")) {\n const prefix = pattern.slice(0, -2);\n const slashIdx = filePath.indexOf(\"/\", prefix.length + 1);\n if (filePath.startsWith(`${prefix}/`) && slashIdx === -1) return true;\n } else if (filePath === pattern || filePath.startsWith(`${pattern}/`)) {\n return true;\n }\n }\n return false;\n}\n"],"mappings":";;AAAA,SAAgB,eAAe,UAAkB,iBAAoC;AACnF,KAAI,gBAAgB,WAAW,EAAG,QAAO;AACzC,MAAK,MAAM,WAAW,gBACpB,KAAI,QAAQ,SAAS,MAAM,EAAE;EAC3B,MAAM,SAAS,QAAQ,MAAM,GAAG,GAAG;AACnC,MAAI,SAAS,WAAW,GAAG,OAAO,GAAG,IAAI,aAAa,OAAQ,QAAO;YAC5D,QAAQ,SAAS,KAAK,EAAE;EACjC,MAAM,SAAS,QAAQ,MAAM,GAAG,GAAG;EACnC,MAAM,WAAW,SAAS,QAAQ,KAAK,OAAO,SAAS,EAAE;AACzD,MAAI,SAAS,WAAW,GAAG,OAAO,GAAG,IAAI,aAAa,GAAI,QAAO;YACxD,aAAa,WAAW,SAAS,WAAW,GAAG,QAAQ,GAAG,CACnE,QAAO;AAGX,QAAO"}
|