@platforma-sdk/block-tools 2.10.18 → 2.10.19
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/cli.js +9 -9
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +314 -288
- package/dist/cli.mjs.map +1 -1
- package/dist/structure/rules/shared/retired-deps.d.ts +7 -0
- package/dist/v2/registry/schema_public.d.ts +150 -150
- package/package.json +7 -7
- package/src/structure/CLAUDE.md +28 -0
- package/src/structure/rules/migrations.ts +15 -16
- package/src/structure/rules/model-package-json.ts +4 -5
- package/src/structure/rules/root-package-json.ts +8 -6
- package/src/structure/rules/root-pnpm-workspace.ts +4 -7
- package/src/structure/rules/root.ts +0 -1
- package/src/structure/rules/shared/retired-deps.ts +42 -0
- package/src/structure/rules/test-package-json.ts +12 -9
- package/src/structure/rules/test.ts +4 -0
- package/src/structure/rules/ui-package-json.ts +15 -21
- package/src/structure/rules/workflow-package-json.ts +7 -3
- package/src/structure/rules/workflow.ts +17 -12
- package/src/structure/templates/static/test/.oxfmtrc.json +4 -0
- package/src/structure/templates/static/test/.oxlintrc.json +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/block-tools",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.19",
|
|
4
4
|
"description": "Utility to manipulate Platforma Blocks and Block Registry",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"bin": {
|
|
@@ -34,13 +34,13 @@
|
|
|
34
34
|
"yaml": "^2.8.0",
|
|
35
35
|
"zod": "~3.25.76",
|
|
36
36
|
"@milaboratories/pl-http": "1.2.4",
|
|
37
|
-
"@milaboratories/pl-model-middle-layer": "1.30.6",
|
|
38
37
|
"@milaboratories/pl-model-common": "1.46.1",
|
|
38
|
+
"@milaboratories/pl-model-middle-layer": "1.30.6",
|
|
39
39
|
"@milaboratories/resolve-helper": "1.1.3",
|
|
40
|
-
"@milaboratories/pl-model-backend": "1.4.7",
|
|
41
|
-
"@milaboratories/ts-helpers": "1.8.3",
|
|
42
40
|
"@milaboratories/ts-helpers-oclif": "1.1.42",
|
|
43
|
-
"@platforma-sdk/blocks-deps-updater": "2.2.0"
|
|
41
|
+
"@platforma-sdk/blocks-deps-updater": "2.2.0",
|
|
42
|
+
"@milaboratories/ts-helpers": "1.8.3",
|
|
43
|
+
"@milaboratories/pl-model-backend": "1.4.7"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
@@ -56,10 +56,10 @@
|
|
|
56
56
|
"vite": "^8.0.6",
|
|
57
57
|
"vite-plugin-dts": "^4.5.3",
|
|
58
58
|
"vitest": "^4.1.3",
|
|
59
|
+
"@milaboratories/build-configs": "2.0.0",
|
|
59
60
|
"@milaboratories/oclif-index": "1.1.1",
|
|
60
|
-
"@milaboratories/ts-configs": "1.2.3",
|
|
61
61
|
"@milaboratories/ts-builder": "1.5.2",
|
|
62
|
-
"@milaboratories/
|
|
62
|
+
"@milaboratories/ts-configs": "1.2.3"
|
|
63
63
|
},
|
|
64
64
|
"oclif": {
|
|
65
65
|
"bin": "block-tools",
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# structurer — mental model
|
|
2
|
+
|
|
3
|
+
A declarative reconciler for a block's scaffolding. `rules/` DECLARE the
|
|
4
|
+
canonical end-state of every non-source file in a block (package.json, configs,
|
|
5
|
+
tsconfig, scripts, catalog); `engine/` reconciles any block toward that state.
|
|
6
|
+
To change what "canonical" means, edit `rules/`; the engine is block-agnostic.
|
|
7
|
+
|
|
8
|
+
## Boundaries
|
|
9
|
+
|
|
10
|
+
- `engine/` — generic reconciliation primitives, module discovery, IR. Knows nothing about blocks.
|
|
11
|
+
- `rules/` — the only home of block-specific layout knowledge. `templates/` holds the verbatim file bodies the rules reference.
|
|
12
|
+
- Owns: the shape of a block's scaffolding. Is NOT a build tool, and NOT the author of a block's source — seeded/scaffolded files become author-owned once written.
|
|
13
|
+
|
|
14
|
+
## Reading posture
|
|
15
|
+
|
|
16
|
+
- Each `rules/*` file pairs a generator (init: full initial content) with a body (refresh: drift-correcting assertions). Read as "what the file should be" + "how to nudge an existing file there", not as sequential logic.
|
|
17
|
+
- The primitive choice IS the design: `fixed` (overwrite verbatim, engine-owned), `managed` (reconcile named fields, author keeps the rest), `scaffold` (write-once default, author may tune), `seed` (written once at init, author owns forever), `remove` (one-way). Wrong primitive is the main design error — `fixed` on an author-tunable file clobbers their work; `seed` on engine-owned content lets drift accumulate.
|
|
18
|
+
|
|
19
|
+
## Invariants
|
|
20
|
+
|
|
21
|
+
- Fixpoint: `refresh` on an already-canonical block makes zero changes. Every rule must converge.
|
|
22
|
+
- Generators emit oxfmt-clean output (the `enforce*` calls mirror oxfmt's order), so build→check passes with no prior `fmt`.
|
|
23
|
+
- sdk-internal blocks (`etc/blocks/*`) skip root-scope and standalone test wiring — the monorepo owns that infra; the structurer must neither impose nor strip it.
|
|
24
|
+
|
|
25
|
+
## Gotchas
|
|
26
|
+
|
|
27
|
+
- A rule change also changes the canonical for `etc/blocks/*`: refresh them in the SAME PR (`pnpm run check-blocks`) or CI fails.
|
|
28
|
+
- Dep/peer changes need a `pnpm i` lockfile sync — pnpm records peers and per-importer deps in pnpm-lock.yaml; frozen-install CI fails otherwise.
|
|
@@ -23,40 +23,39 @@ export function testFrameworkMigration(): void {
|
|
|
23
23
|
// Unconditional legacy-cleanup rules. Each is a no-op on an
|
|
24
24
|
// already-canonical block (remove on an absent path, removeScript /
|
|
25
25
|
// removeDep on an absent key) and idempotent, so they sit at top level
|
|
26
|
-
// with no `when` gate.
|
|
27
|
-
// block(s) that carry the artefact being cleaned.
|
|
26
|
+
// with no `when` gate.
|
|
28
27
|
//
|
|
29
28
|
// Root-scope cleanup is skipped for `--sdk-internal` blocks (no root
|
|
30
29
|
// module in that mode), so it never touches in-monorepo blocks.
|
|
31
30
|
export function legacyCleanup(): void {
|
|
32
|
-
//
|
|
33
|
-
//
|
|
31
|
+
// Retired per-scope config files: flat eslint configs and vite-era build /
|
|
32
|
+
// split-tsconfig files, replaced by the oxlint/oxfmt + ts-builder layout.
|
|
34
33
|
scope("model", () => {
|
|
35
|
-
remove("eslint.config.mjs");
|
|
36
|
-
remove("vite.config.mts");
|
|
34
|
+
remove("eslint.config.mjs");
|
|
35
|
+
remove("vite.config.mts");
|
|
37
36
|
});
|
|
38
37
|
scope("ui", () => {
|
|
39
|
-
remove("eslint.config.mjs");
|
|
40
|
-
remove("vite.config.ts");
|
|
41
|
-
remove("tsconfig.app.json");
|
|
42
|
-
remove("tsconfig.node.json");
|
|
38
|
+
remove("eslint.config.mjs");
|
|
39
|
+
remove("vite.config.ts");
|
|
40
|
+
remove("tsconfig.app.json");
|
|
41
|
+
remove("tsconfig.node.json");
|
|
43
42
|
});
|
|
44
43
|
scope("test", () => {
|
|
45
|
-
remove("eslint.config.mjs");
|
|
44
|
+
remove("eslint.config.mjs");
|
|
46
45
|
});
|
|
47
46
|
|
|
48
47
|
// Root-scope cleanup. The second `managed("package.json")` body composes
|
|
49
48
|
// after rootRules.
|
|
50
49
|
scope("root", () => {
|
|
51
|
-
remove(".prettierrc");
|
|
50
|
+
remove(".prettierrc");
|
|
52
51
|
managed(
|
|
53
52
|
"package.json",
|
|
54
53
|
generate(() => rootPackageJsonInitial(getActiveRunContext())),
|
|
55
54
|
() => {
|
|
56
|
-
// `pretty` (prettier) is superseded by
|
|
57
|
-
//
|
|
58
|
-
removeScript("pretty");
|
|
59
|
-
removeDep("@platforma-sdk/blocks-deps-updater");
|
|
55
|
+
// `pretty` (prettier) is superseded by `fmt` (oxfmt); the standalone
|
|
56
|
+
// deps-updater is now part of block-tools.
|
|
57
|
+
removeScript("pretty");
|
|
58
|
+
removeDep("@platforma-sdk/blocks-deps-updater");
|
|
60
59
|
},
|
|
61
60
|
);
|
|
62
61
|
});
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
ensureDevDep,
|
|
17
17
|
ensureDevDeps,
|
|
18
18
|
removeDep,
|
|
19
|
+
removeScript,
|
|
19
20
|
removeField,
|
|
20
21
|
ensurePeerDeps,
|
|
21
22
|
enforceAlphabeticalOrder,
|
|
@@ -26,6 +27,7 @@ import {
|
|
|
26
27
|
} from "../engine/api";
|
|
27
28
|
import { canonicalPackageJsonOrder } from "./shared/key-order";
|
|
28
29
|
import { COLOCATED_TEST_GLOB } from "./shared/colocated-tests";
|
|
30
|
+
import { removeRetiredToolchainDeps } from "./shared/retired-deps";
|
|
29
31
|
|
|
30
32
|
export function modelPackageJsonInitial(ctx: RunContext): Record<string, unknown> {
|
|
31
33
|
const v = ctx.blockVars;
|
|
@@ -127,12 +129,9 @@ export function modelPackageJsonRules(): void {
|
|
|
127
129
|
),
|
|
128
130
|
);
|
|
129
131
|
|
|
130
|
-
|
|
131
|
-
// legacy `tsup`/`vite` devDeps and the top-level `tsup` bundler config block
|
|
132
|
-
// are dropped.
|
|
133
|
-
removeDep("tsup");
|
|
134
|
-
removeDep("vite");
|
|
132
|
+
removeRetiredToolchainDeps();
|
|
135
133
|
removeField("tsup");
|
|
134
|
+
removeScript("lint");
|
|
136
135
|
|
|
137
136
|
enforceAlphabeticalOrder("dependencies");
|
|
138
137
|
enforceAlphabeticalOrder("devDependencies");
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
ensureScript,
|
|
9
9
|
ensureDevDeps,
|
|
10
10
|
ensurePeerDeps,
|
|
11
|
+
removeScript,
|
|
11
12
|
removeField,
|
|
12
13
|
pruneKeysMatching,
|
|
13
14
|
enforceAlphabeticalOrder,
|
|
@@ -34,10 +35,9 @@ export function rootPackageJsonInitial(_ctx: RunContext): Record<string, unknown
|
|
|
34
35
|
watch: "turbo watch build",
|
|
35
36
|
changeset: "changeset",
|
|
36
37
|
"version-packages": "changeset version",
|
|
37
|
-
// Deprecated
|
|
38
|
-
// refresh → format flow); kept for compatibility.
|
|
38
|
+
// Deprecated alias of `upgrade-sdk`; kept for compatibility.
|
|
39
39
|
"update-sdk": "block-tools structure refresh --update-deps-only",
|
|
40
|
-
|
|
40
|
+
"upgrade-sdk":
|
|
41
41
|
"block-tools structure refresh --update-deps-only && pnpm i && block-tools structure refresh && pnpm i && pnpm fmt",
|
|
42
42
|
},
|
|
43
43
|
peerDependencies: {
|
|
@@ -76,16 +76,18 @@ export function rootPackageJsonRules(): void {
|
|
|
76
76
|
ensureScript("watch", "turbo watch build");
|
|
77
77
|
ensureScript("changeset", "changeset");
|
|
78
78
|
ensureScript("version-packages", "changeset version");
|
|
79
|
-
//
|
|
79
|
+
// `update-sdk` is a deprecated alias of `upgrade-sdk`, kept for compatibility;
|
|
80
|
+
// `update` is the pre-rename name — drop it so refreshed blocks converge.
|
|
80
81
|
ensureScript("update-sdk", "block-tools structure refresh --update-deps-only");
|
|
81
|
-
|
|
82
|
+
removeScript("update");
|
|
83
|
+
// Full SDK-upgrade flow: bump catalog (deps-only) → install → re-apply
|
|
82
84
|
// structure against the freshly-pulled deps → install AGAIN (the structural
|
|
83
85
|
// pass can add new devDeps — e.g. ts-builder/oxlint/oxfmt on a first
|
|
84
86
|
// migration — that `pnpm fmt` then needs on PATH) → format. Wrapped as one
|
|
85
87
|
// script. `pnpm fmt` (turbo run fmt) leaves the tree oxfmt-clean after the
|
|
86
88
|
// structural rewrite so a follow-up `pnpm check` passes.
|
|
87
89
|
ensureScript(
|
|
88
|
-
"
|
|
90
|
+
"upgrade-sdk",
|
|
89
91
|
"block-tools structure refresh --update-deps-only && pnpm i && block-tools structure refresh && pnpm i && pnpm fmt",
|
|
90
92
|
);
|
|
91
93
|
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
import { ensureWorkspaceModulePaths, ensureCatalogAbsent, type RunContext } from "../engine/api";
|
|
22
22
|
import { matchesBumpPattern, type DerivedCatalogPin } from "../engine/registry-client";
|
|
23
|
+
import { RETIRED_TOOLCHAIN_DEPS } from "./shared/retired-deps";
|
|
23
24
|
|
|
24
25
|
/** SDK packages that live in the catalog (membership only — no versions).
|
|
25
26
|
* Init fetches npm latest for each; refresh leaves them as the lockfile has
|
|
@@ -109,11 +110,7 @@ export function rootPnpmWorkspaceInitial(ctx: RunContext): Record<string, unknow
|
|
|
109
110
|
|
|
110
111
|
export function rootPnpmWorkspaceRules(): void {
|
|
111
112
|
ensureWorkspaceModulePaths();
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
|
|
115
|
-
// so a migrated block sheds both the dep and its catalog entry.
|
|
116
|
-
ensureCatalogAbsent("vite");
|
|
117
|
-
ensureCatalogAbsent("tsup");
|
|
118
|
-
ensureCatalogAbsent("vue-tsc");
|
|
113
|
+
// Catalog side of the retired-dep cleanup — the per-package side sheds the
|
|
114
|
+
// matching `catalog:` references.
|
|
115
|
+
for (const name of RETIRED_TOOLCHAIN_DEPS) ensureCatalogAbsent(name);
|
|
119
116
|
}
|
|
@@ -14,7 +14,6 @@ export function rootRules(): void {
|
|
|
14
14
|
when(
|
|
15
15
|
({ ctx }) => !ctx.isSdkInternal,
|
|
16
16
|
() => {
|
|
17
|
-
// see templates/static/root/turbo.json — verbatim canonical content.
|
|
18
17
|
fixed("turbo.json", file("root/turbo.json"));
|
|
19
18
|
fixed(".vscode/settings.json", file("root/.vscode/settings.json"));
|
|
20
19
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Retired toolchain dependencies — a SINGLE source of truth.
|
|
2
|
+
//
|
|
3
|
+
// These packages are superseded by the canonical toolchain (ts-builder owns
|
|
4
|
+
// the build, vue-tsc, and the vite plugins; oxlint/oxfmt replace eslint) and
|
|
5
|
+
// must be shed from a migrated block in BOTH places at once:
|
|
6
|
+
// - the root catalog → `ensureCatalogAbsent` (root-pnpm-workspace)
|
|
7
|
+
// - every package.json scope → `removeDep` (via removeRetiredToolchainDeps)
|
|
8
|
+
//
|
|
9
|
+
// Removing from only one side is a latent bug: a catalog entry dropped while a
|
|
10
|
+
// package still references `<dep>: "catalog:"` leaves a dangling reference that
|
|
11
|
+
// breaks `pnpm install`. Driving both from this one list makes that impossible
|
|
12
|
+
// — add (or un-retire) a dependency HERE, once.
|
|
13
|
+
//
|
|
14
|
+
// Per-entry rationale:
|
|
15
|
+
// vite / tsup — bundling now goes through ts-builder + rolldown.
|
|
16
|
+
// vue-tsc — ts-builder runs vue-tsc internally for `block-ui`; a
|
|
17
|
+
// direct dep resolves a different version than the
|
|
18
|
+
// toolchain pins, causing type clashes in main.ts.
|
|
19
|
+
// @vitejs/plugin-vue — bundled by ts-builder's internal vite config.
|
|
20
|
+
// vite-plugin-dts — .d.ts emit is handled by ts-builder.
|
|
21
|
+
// @platforma-sdk/eslint-config — eslint is retired; linting runs via oxlint
|
|
22
|
+
// inside `ts-builder check`.
|
|
23
|
+
|
|
24
|
+
import { removeDep } from "../../engine/api";
|
|
25
|
+
|
|
26
|
+
export const RETIRED_TOOLCHAIN_DEPS: readonly string[] = [
|
|
27
|
+
"vite",
|
|
28
|
+
"tsup",
|
|
29
|
+
"vue-tsc",
|
|
30
|
+
"@vitejs/plugin-vue",
|
|
31
|
+
"vite-plugin-dts",
|
|
32
|
+
"@platforma-sdk/eslint-config",
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
/** Drop every retired toolchain dep from the current package.json scope.
|
|
36
|
+
* Idempotent (a `removeDep` on an absent key is a no-op), so it is safe to
|
|
37
|
+
* call uniformly from every package.json rules body regardless of which deps
|
|
38
|
+
* a given scope ever carried. Pairs with the catalog-side removal in
|
|
39
|
+
* `rootPnpmWorkspaceRules`. */
|
|
40
|
+
export function removeRetiredToolchainDeps(): void {
|
|
41
|
+
for (const name of RETIRED_TOOLCHAIN_DEPS) removeDep(name);
|
|
42
|
+
}
|
|
@@ -7,11 +7,13 @@ import {
|
|
|
7
7
|
ensureDevDeps,
|
|
8
8
|
ensurePeerDeps,
|
|
9
9
|
removeDep,
|
|
10
|
+
removeScript,
|
|
10
11
|
enforceAlphabeticalOrder,
|
|
11
12
|
enforceFieldOrder,
|
|
12
13
|
type RunContext,
|
|
13
14
|
} from "../engine/api";
|
|
14
15
|
import { canonicalPackageJsonOrder } from "./shared/key-order";
|
|
16
|
+
import { removeRetiredToolchainDeps } from "./shared/retired-deps";
|
|
15
17
|
|
|
16
18
|
export function testPackageJsonInitial(ctx: RunContext): Record<string, unknown> {
|
|
17
19
|
const v = ctx.blockVars;
|
|
@@ -21,9 +23,9 @@ export function testPackageJsonInitial(ctx: RunContext): Record<string, unknown>
|
|
|
21
23
|
private: true,
|
|
22
24
|
type: "module",
|
|
23
25
|
scripts: {
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
check: "ts-builder
|
|
26
|
+
fmt: "ts-builder format",
|
|
27
|
+
// `ts-builder check` runs type-check + lint (oxlint) + fmt-check (oxfmt).
|
|
28
|
+
check: "ts-builder check --target block-test",
|
|
27
29
|
test: "vitest run --passWithNoTests",
|
|
28
30
|
},
|
|
29
31
|
peerDependencies: {
|
|
@@ -41,12 +43,13 @@ export function testPackageJsonInitial(ctx: RunContext): Record<string, unknown>
|
|
|
41
43
|
export function testPackageJsonRules(): void {
|
|
42
44
|
ensureField("type", "module");
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
//
|
|
46
|
-
ensureScript("check", "ts-builder
|
|
46
|
+
ensureScript("fmt", "ts-builder format");
|
|
47
|
+
// `ts-builder check` runs type-check + lint (oxlint) + fmt-check (oxfmt).
|
|
48
|
+
ensureScript("check", "ts-builder check --target block-test");
|
|
47
49
|
ensureScript("test", "vitest run --passWithNoTests");
|
|
50
|
+
// Linting runs inside `ts-builder check` — no separate `lint` script.
|
|
51
|
+
removeScript("lint");
|
|
48
52
|
|
|
49
|
-
// @platforma-sdk/test is a test-time dep → devDependencies (matches prod).
|
|
50
53
|
ensureDevDeps({
|
|
51
54
|
"@platforma-sdk/test": "sdk:",
|
|
52
55
|
"@milaboratories/ts-builder": "sdk:",
|
|
@@ -55,12 +58,12 @@ export function testPackageJsonRules(): void {
|
|
|
55
58
|
});
|
|
56
59
|
|
|
57
60
|
// The test tsconfig (@milaboratories/ts-configs/block/test) supplies the
|
|
58
|
-
// ambient types
|
|
59
|
-
// `@types/node` peer a legacy block declares.
|
|
61
|
+
// ambient types, so only the `typescript` peer is needed — no `@types/node`.
|
|
60
62
|
ensurePeerDeps({
|
|
61
63
|
typescript: "*",
|
|
62
64
|
});
|
|
63
65
|
removeDep("@types/node");
|
|
66
|
+
removeRetiredToolchainDeps();
|
|
64
67
|
|
|
65
68
|
enforceAlphabeticalOrder("dependencies");
|
|
66
69
|
enforceAlphabeticalOrder("devDependencies");
|
|
@@ -11,6 +11,10 @@ export function testRules(): void {
|
|
|
11
11
|
// lets the check pass on a test-less block while `include` still
|
|
12
12
|
// type-checks real tests once present.
|
|
13
13
|
fixed("tsconfig.json", file("test/tsconfig.json"));
|
|
14
|
+
// Block-local oxlint/oxfmt config — test sources are lint + fmt-checked
|
|
15
|
+
// (the `check` script runs `ts-builder check --target block-test`).
|
|
16
|
+
fixed(".oxlintrc.json", file("test/.oxlintrc.json"));
|
|
17
|
+
fixed(".oxfmtrc.json", file("test/.oxfmtrc.json"));
|
|
14
18
|
// scaffold (not fixed): integration tests legitimately tune timeout /
|
|
15
19
|
// retry per block. Write the canonical default if absent; never
|
|
16
20
|
// overwrite an author's config.
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
import { scopeDepMap } from "../engine/ctx";
|
|
27
27
|
import { canonicalPackageJsonOrder } from "./shared/key-order";
|
|
28
28
|
import { COLOCATED_TEST_GLOB } from "./shared/colocated-tests";
|
|
29
|
+
import { removeRetiredToolchainDeps } from "./shared/retired-deps";
|
|
29
30
|
|
|
30
31
|
export function uiPackageJsonInitial(ctx: RunContext): Record<string, unknown> {
|
|
31
32
|
const v = ctx.blockVars;
|
|
@@ -52,6 +53,7 @@ export function uiPackageJsonInitial(ctx: RunContext): Record<string, unknown> {
|
|
|
52
53
|
"@milaboratories/ts-configs": "sdk:",
|
|
53
54
|
},
|
|
54
55
|
peerDependencies: {
|
|
56
|
+
"@types/node": "*",
|
|
55
57
|
typescript: "*",
|
|
56
58
|
},
|
|
57
59
|
};
|
|
@@ -77,33 +79,25 @@ export function uiPackageJsonRules(): void {
|
|
|
77
79
|
"@milaboratories/ts-configs": "sdk:",
|
|
78
80
|
});
|
|
79
81
|
|
|
80
|
-
|
|
81
|
-
// `--target block-ui`), so the ui must NOT declare its own. A direct
|
|
82
|
-
// `vue-tsc` dep is the vestigial vite/vue-tsc-era artefact: it resolves
|
|
83
|
-
// independently of the version ts-builder pins, which is how a block ended
|
|
84
|
-
// up type-checking under a different vue-tsc than the toolchain intends.
|
|
85
|
-
removeDep("vue-tsc");
|
|
86
|
-
|
|
87
|
-
// vite-era artefacts: the canonical ui builds + dev-serves via ts-builder,
|
|
88
|
-
// so a legacy `vite` dep and the `preview` (vite preview) script are dropped.
|
|
89
|
-
removeDep("vite");
|
|
82
|
+
removeRetiredToolchainDeps();
|
|
90
83
|
removeScript("preview");
|
|
84
|
+
removeScript("lint");
|
|
91
85
|
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
//
|
|
86
|
+
// `@types/node` is declared as a peer by default — mirrors the model scope
|
|
87
|
+
// (the block author resolves it from the workspace root). The ui builds with
|
|
88
|
+
// `--target block-ui` (types: []), so it pulls no node ambient types into the
|
|
89
|
+
// build; the peer only satisfies IDE / type resolution, alongside `typescript`.
|
|
96
90
|
ensurePeerDeps({
|
|
91
|
+
"@types/node": "*",
|
|
97
92
|
typescript: "*",
|
|
98
93
|
});
|
|
99
|
-
removeDep("@types/node");
|
|
100
94
|
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
//
|
|
95
|
+
// A ui WITH co-located unit tests (`src/**/*.test.ts`) needs the vitest
|
|
96
|
+
// `test` script, the `vitest` devDep, AND node ambient types promoted from
|
|
97
|
+
// peer to a devDep (the single-section invariant drops the peer) so that
|
|
98
|
+
// `types: ["node"]` in ui/tsconfig — wired under the same predicate —
|
|
99
|
+
// resolves the tests' `node:*` imports. A test-less ui keeps `@types/node`
|
|
100
|
+
// as a peer and carries no vitest, staying a refresh fixpoint.
|
|
107
101
|
//
|
|
108
102
|
// Skipped entirely for sdk-internal (in-monorepo) blocks: they own their test
|
|
109
103
|
// wiring under the monorepo's shared infrastructure — see model-package-json.
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
import { scopeDepMaps } from "../engine/ctx";
|
|
20
20
|
import { canonicalPackageJsonOrder } from "./shared/key-order";
|
|
21
21
|
import { COLOCATED_TEST_GLOB } from "./shared/colocated-tests";
|
|
22
|
+
import { removeRetiredToolchainDeps } from "./shared/retired-deps";
|
|
22
23
|
|
|
23
24
|
export function workflowPackageJsonInitial(ctx: RunContext): Record<string, unknown> {
|
|
24
25
|
const v = ctx.blockVars;
|
|
@@ -55,11 +56,10 @@ export function workflowPackageJsonInitial(ctx: RunContext): Record<string, unkn
|
|
|
55
56
|
export function workflowPackageJsonRules(): void {
|
|
56
57
|
ensureField("type", "module");
|
|
57
58
|
|
|
58
|
-
// No `fmt
|
|
59
|
-
// pl-tengo
|
|
59
|
+
// No `fmt` script: the workflow is Tengo, not TS — build + check run via
|
|
60
|
+
// pl-tengo; `format` runs the emacs-batch Tengo formatter (no-op when absent).
|
|
60
61
|
ensureScript("build", "shx rm -rf dist && pl-tengo build");
|
|
61
62
|
ensureScript("check", "pl-tengo check");
|
|
62
|
-
// Tengo source formatter (emacs batch); no-op notice when emacs is absent.
|
|
63
63
|
ensureScript("format", "/usr/bin/env emacs --script ./format.el || echo 'No emacs.'");
|
|
64
64
|
// The vitest `test` script AND the `vitest` devDep are wired ONLY when the
|
|
65
65
|
// workflow carries co-located integration tests (`src/**/*.test.ts`, incl.
|
|
@@ -98,6 +98,10 @@ export function workflowPackageJsonRules(): void {
|
|
|
98
98
|
shx: "catalog:",
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
+
// No-op for a canonical Tengo workflow; called uniformly across every scope
|
|
102
|
+
// for safety.
|
|
103
|
+
removeRetiredToolchainDeps();
|
|
104
|
+
|
|
101
105
|
enforceAlphabeticalOrder("dependencies");
|
|
102
106
|
enforceAlphabeticalOrder("devDependencies");
|
|
103
107
|
enforceAlphabeticalOrder("peerDependencies");
|
|
@@ -21,16 +21,15 @@ import { COLOCATED_TEST_GLOB } from "./shared/colocated-tests";
|
|
|
21
21
|
|
|
22
22
|
export function workflowRules(): void {
|
|
23
23
|
scope("workflow", () => {
|
|
24
|
-
// tsconfig for the TypeScript vitest integration tests under src/test
|
|
25
|
-
// (e.g. mixcr's workflow/src/test/columns.test.ts). types:[] keeps the
|
|
26
|
-
// isomorphic workflow free of ambient Node/DOM types.
|
|
27
|
-
fixed("tsconfig.json", file("workflow/tsconfig.json"));
|
|
28
24
|
// Tengo source formatter (emacs batch); the `format` script invokes it.
|
|
29
25
|
fixed("format.el", file("workflow/format.el"));
|
|
30
|
-
// vitest config
|
|
31
|
-
// (`src/**/*.test.ts`, incl. `src/test/`
|
|
32
|
-
//
|
|
33
|
-
//
|
|
26
|
+
// The TS-test tsconfig + vitest config exist ONLY when the workflow carries
|
|
27
|
+
// co-located tests (`src/**/*.test.ts`, incl. `src/test/` — e.g. mixcr's
|
|
28
|
+
// workflow/src/test/columns.test.ts). They pair with the conditional
|
|
29
|
+
// `vitest` devDep + `test` script in workflow-package-json. tsconfig is
|
|
30
|
+
// `fixed` (structural: types:[] keeps the isomorphic workflow free of
|
|
31
|
+
// ambient Node/DOM types); vitest.config is `scaffold` (author-tunable once
|
|
32
|
+
// present). A test-less workflow gets neither and stays a refresh fixpoint.
|
|
34
33
|
//
|
|
35
34
|
// Skipped entirely for sdk-internal (in-monorepo) blocks: they own their
|
|
36
35
|
// test config under the monorepo's shared infrastructure (e.g. a bespoke
|
|
@@ -41,14 +40,20 @@ export function workflowRules(): void {
|
|
|
41
40
|
() =>
|
|
42
41
|
when(
|
|
43
42
|
whenFilesExist(COLOCATED_TEST_GLOB),
|
|
44
|
-
() =>
|
|
45
|
-
|
|
43
|
+
() => {
|
|
44
|
+
fixed("tsconfig.json", file("workflow/tsconfig.json"));
|
|
45
|
+
scaffold("vitest.config.mts", file("workflow/vitest.config.mts"));
|
|
46
|
+
},
|
|
47
|
+
() => {
|
|
48
|
+
remove("tsconfig.json");
|
|
49
|
+
remove("vitest.config.mts");
|
|
50
|
+
},
|
|
46
51
|
),
|
|
47
52
|
);
|
|
48
53
|
// No workflow facade (index.js / index.d.ts): the block loader resolves the
|
|
49
54
|
// workflow via the `block:` components dist path (workflow/dist/.../main.plj.gz),
|
|
50
|
-
// never the JS facade.
|
|
51
|
-
//
|
|
55
|
+
// never the JS facade. Removed so blocks that carry one get cleaned
|
|
56
|
+
// (idempotent on absence).
|
|
52
57
|
remove("index.js");
|
|
53
58
|
remove("index.d.ts");
|
|
54
59
|
|