@platforma-sdk/block-tools 2.11.10 → 2.12.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.
Files changed (37) hide show
  1. package/dist/cli.js +13 -13
  2. package/dist/cli.js.map +1 -1
  3. package/dist/cli.mjs +845 -625
  4. package/dist/cli.mjs.map +1 -1
  5. package/dist/cmd/software/build.d.ts +2 -0
  6. package/dist/cmd/software/ecr-login.d.ts +3 -0
  7. package/dist/cmd/software/env.d.ts +5 -0
  8. package/dist/cmd/software/index.d.ts +2 -0
  9. package/dist/cmd/software/knobs.d.ts +26 -0
  10. package/dist/cmd/software/run-build.d.ts +19 -0
  11. package/dist/structure/engine/version.d.ts +5 -4
  12. package/dist/structure/rules/root-package-json.d.ts +1 -2
  13. package/dist/structure/rules/root-pnpm-workspace.d.ts +7 -1
  14. package/package.json +7 -5
  15. package/src/cli.test.ts +20 -1
  16. package/src/cli.ts +2 -0
  17. package/src/cmd/software/build.ts +175 -0
  18. package/src/cmd/software/ecr-login.test.ts +92 -0
  19. package/src/cmd/software/ecr-login.ts +75 -0
  20. package/src/cmd/software/env.test.ts +17 -0
  21. package/src/cmd/software/env.ts +22 -0
  22. package/src/cmd/software/index.ts +9 -0
  23. package/src/cmd/software/knobs.test.ts +52 -0
  24. package/src/cmd/software/knobs.ts +61 -0
  25. package/src/cmd/software/run-build.test.ts +291 -0
  26. package/src/cmd/software/run-build.ts +156 -0
  27. package/src/structure/__tests__/floor-version.test.ts +2 -2
  28. package/src/structure/engine/__tests__/version.test.ts +14 -17
  29. package/src/structure/engine/discovery-fs.ts +4 -13
  30. package/src/structure/engine/runner.ts +4 -4
  31. package/src/structure/engine/version.ts +11 -13
  32. package/src/structure/rules/migrations.ts +1 -1
  33. package/src/structure/rules/root-package-json.ts +38 -14
  34. package/src/structure/rules/root-pnpm-workspace.ts +8 -1
  35. package/src/structure/rules/root.ts +1 -1
  36. package/src/structure/rules/software-package-json.ts +23 -10
  37. package/src/structure/templates/static/root/turbo.json +15 -1
@@ -3,30 +3,28 @@
3
3
  // Single JSON file at the block root holding the layout-version
4
4
  // integer and (in future) any other structurer metadata. Two
5
5
  // constants govern lifecycle gates:
6
- // - STRUCTURE_VERSION : latest known. Initial value 1.
6
+ // - STRUCTURE_VERSION : latest known. v2 = software-build layout.
7
7
  // - STRUCTURE_MIN_SUPPORTED : floor. Initial value 0.
8
8
  // Both are bumped by structurer releases; rule predicates may consult
9
9
  // `ctx.version` for one-shot version-gated transitions.
10
10
 
11
11
  import type { FileSystem } from "./fs/api";
12
12
 
13
- export const STRUCTURE_VERSION = 1;
13
+ export const STRUCTURE_VERSION = 2;
14
14
  export const STRUCTURE_MIN_SUPPORTED = 0;
15
15
  /** Block-relative path of the structurer metadata file. */
16
16
  export const STRUCTURE_META_FILE = ".structure";
17
17
 
18
18
  export type StructureMeta = { version: number };
19
19
 
20
- /** Read `.structure`. Missing file or invalid payload → 0. */
21
- export function readStructureVersion(fs: FileSystem): number {
22
- if (!fs.exists(STRUCTURE_META_FILE)) return 0;
20
+ /** Read `.structure`. Missing file or invalid payload → version 0. */
21
+ export function readStructureMeta(fs: FileSystem): StructureMeta {
22
+ if (!fs.exists(STRUCTURE_META_FILE)) return { version: 0 };
23
23
  try {
24
- const raw = fs.read(STRUCTURE_META_FILE);
25
- const parsed = JSON.parse(raw) as Partial<StructureMeta>;
26
- if (typeof parsed?.version === "number") return parsed.version;
27
- return 0;
24
+ const parsed = JSON.parse(fs.read(STRUCTURE_META_FILE)) as Partial<StructureMeta>;
25
+ return { version: typeof parsed?.version === "number" ? parsed.version : 0 };
28
26
  } catch {
29
- return 0;
27
+ return { version: 0 };
30
28
  }
31
29
  }
32
30
 
@@ -53,8 +51,8 @@ export class StructureVersionFloorError extends Error {
53
51
  }
54
52
  }
55
53
 
56
- export function writeStructureVersion(fs: FileSystem, version: number = STRUCTURE_VERSION): void {
57
- const payload: StructureMeta = { version };
54
+ /** Write `.structure`. Writes a fresh payload rather than merging. */
55
+ export function writeStructureMeta(fs: FileSystem, meta: StructureMeta): void {
58
56
  // Compact, single-line — this is a tiny machine file, no pretty-print.
59
- fs.write(STRUCTURE_META_FILE, JSON.stringify(payload));
57
+ fs.write(STRUCTURE_META_FILE, JSON.stringify(meta));
60
58
  }
@@ -49,7 +49,7 @@ export function legacyCleanup(): void {
49
49
  remove(".prettierrc");
50
50
  managed(
51
51
  "package.json",
52
- generate((ctx) => rootPackageJsonInitial(ctx)),
52
+ generate(() => rootPackageJsonInitial()),
53
53
  () => {
54
54
  // `pretty` (prettier) is superseded by `fmt` (oxfmt); the standalone
55
55
  // deps-updater is now part of block-tools.
@@ -13,11 +13,32 @@ import {
13
13
  pruneKeysMatching,
14
14
  enforceAlphabeticalOrder,
15
15
  enforceFieldOrder,
16
- type RunContext,
17
16
  } from "../engine/api";
18
17
  import { canonicalPackageJsonOrder } from "./shared/key-order";
19
18
 
20
- export function rootPackageJsonInitial(_ctx: RunContext): Record<string, unknown> {
19
+ // `variant=all` builds every variant the software declares — docker-vs-binary is not a per-script
20
+ // choice. `no-software` builds placeholder software for validators.
21
+
22
+ const BUILD_SCRIPTS: Record<string, string> = {
23
+ "build:dev-local":
24
+ "env PL_BUILD_CHANNEL=dev PL_BUILD_VARIANT=all PL_BUILD_LOCATION=local turbo run build",
25
+ "build:dev-remote":
26
+ "env PL_BUILD_CHANNEL=dev PL_BUILD_VARIANT=all PL_BUILD_LOCATION=remote turbo run build",
27
+ "build:dev-no-software": "env PL_BUILD_CHANNEL=dev PL_BUILD_VARIANT=none turbo run build",
28
+ "build:dev-binary-existing":
29
+ "env PL_BUILD_CHANNEL=dev PL_BUILD_USE_PUBLISHED=true turbo run build",
30
+ "build:release":
31
+ "env PL_BUILD_CHANNEL=release PL_BUILD_VARIANT=all PL_BUILD_LOCATION=remote turbo run build",
32
+ };
33
+
34
+ // `test` / `test:dry-run` run the build-then-test DAG in the dev-binary-local target; the live
35
+ // backend's env reaches the integration tests via the turbo `test` task's passThroughEnv.
36
+ const TEST_SCRIPTS: Record<string, string> = {
37
+ test: `env PL_BUILD_CHANNEL=dev PL_BUILD_VARIANT=binary PL_BUILD_LOCATION=local turbo run test --concurrency 1`,
38
+ "test:dry-run": `env PL_BUILD_CHANNEL=dev PL_BUILD_VARIANT=binary PL_BUILD_LOCATION=local turbo run test --dry-run=json`,
39
+ };
40
+
41
+ export function rootPackageJsonInitial(): Record<string, unknown> {
21
42
  // No `name`: the root is never published. Body rules re-assert
22
43
  // (removeField("name")) as a drift-corrector.
23
44
  return {
@@ -26,10 +47,8 @@ export function rootPackageJsonInitial(_ctx: RunContext): Record<string, unknown
26
47
  scripts: {
27
48
  fmt: "turbo run fmt",
28
49
  check: "turbo run check",
29
- build: "turbo run build",
30
- "build:dev": "env PL_PKG_DEV=local turbo run build",
31
- test: "env PL_PKG_DEV=local turbo run test --concurrency 1",
32
- "test:dry-run": "env PL_PKG_DEV=local turbo run test --dry-run=json",
50
+ ...BUILD_SCRIPTS,
51
+ ...TEST_SCRIPTS,
33
52
  "mark-stable": "turbo run mark-stable",
34
53
  "do-pack": "turbo run do-pack",
35
54
  watch: "turbo watch build",
@@ -61,16 +80,21 @@ export function rootPackageJsonRules(): void {
61
80
  // Root is never published — it carries no `name`; delete any stray one.
62
81
  removeField("name");
63
82
 
64
- // Canonical lifecycle script set. `test` / `test:dry-run` carry the
65
- // PL_PKG_DEV wrapper; the live backend's env reaches the integration
66
- // tests via the turbo `test` task's passThroughEnv (no --env-mode=loose
67
- // needed).
83
+ // Canonical lifecycle script set. The live backend's env reaches the
84
+ // integration tests via the turbo `test` task's passThroughEnv (no
85
+ // --env-mode=loose needed).
68
86
  ensureScript("fmt", "turbo run fmt");
69
87
  ensureScript("check", "turbo run check");
70
- ensureScript("build", "turbo run build");
71
- ensureScript("build:dev", "env PL_PKG_DEV=local turbo run build");
72
- ensureScript("test", "env PL_PKG_DEV=local turbo run test --concurrency 1");
73
- ensureScript("test:dry-run", "env PL_PKG_DEV=local turbo run test --dry-run=json");
88
+ for (const [name, command] of Object.entries(BUILD_SCRIPTS)) {
89
+ ensureScript(name, command);
90
+ }
91
+ for (const [name, command] of Object.entries(TEST_SCRIPTS)) {
92
+ ensureScript(name, command);
93
+ }
94
+ // No bare `build` — a developer must pick a scenario (`build:dev-local`, `build:release`,
95
+ // …). Drop the legacy plain `build` and the old single `build:dev` so migrated blocks converge.
96
+ removeScript("build");
97
+ removeScript("build:dev");
74
98
  ensureScript("mark-stable", "turbo run mark-stable");
75
99
  ensureScript("do-pack", "turbo run do-pack");
76
100
  ensureScript("watch", "turbo watch build");
@@ -75,9 +75,16 @@ export const INFRA_CATALOG_FLOOR: Record<string, string> = {
75
75
  * 3.5.x than ui-vue's, yielding two vue instances and a SdkPluginV3-vs-Plugin
76
76
  * type clash in `main.ts`. Deriving the pin from ui-vue's declared dep keeps
77
77
  * the block in lockstep with whatever vue ui-vue's npm-latest pins, with no
78
- * hand-maintained version here. */
78
+ * hand-maintained version here.
79
+ *
80
+ * `@milaboratories/helpers`: the block's model/ui depend on it (catalog:) and
81
+ * `@platforma-sdk/model` pins it as an EXACT regular dependency. A hand-pinned
82
+ * floor that lags a model bump yields two helpers instances — the model's
83
+ * inferred `platforma` type then references the SDK's copy, not the block's,
84
+ * failing `tsc` with TS2742. Deriving from model keeps them in lockstep. */
79
85
  export const DERIVED_CATALOG_PINS: readonly DerivedCatalogPin[] = [
80
86
  { entry: "vue", of: "@platforma-sdk/ui-vue" },
87
+ { entry: "@milaboratories/helpers", of: "@platforma-sdk/model" },
81
88
  ];
82
89
 
83
90
  /** Catalog name of the python runenv. Added to a block's catalog only when
@@ -18,7 +18,7 @@ export function rootRules(): void {
18
18
 
19
19
  managed(
20
20
  "package.json",
21
- generate((ctx) => rootPackageJsonInitial(ctx)),
21
+ generate(() => rootPackageJsonInitial()),
22
22
  () => {
23
23
  rootPackageJsonRules();
24
24
  },
@@ -12,13 +12,21 @@ import {
12
12
  ensureField,
13
13
  removeField,
14
14
  ensureScript,
15
- ensureDevDeps,
15
+ removeScript,
16
+ ensureDevDep,
17
+ removeDep,
16
18
  enforceAlphabeticalOrder,
17
19
  enforceFieldOrder,
18
20
  type RunContext,
19
21
  } from "../engine/api";
20
22
  import { canonicalPackageJsonOrder } from "./shared/key-order";
21
23
 
24
+ // The software-build build/pack commands, shared by the generator and the reconciler. block-tools
25
+ // bundles the build engine, so these are the only build-tool commands a software-build block runs.
26
+ const BUILD_CMD = "block-tools software build";
27
+ const DO_PACK_CMD =
28
+ "shx rm -f *.tgz && block-tools software build && pnpm pack && shx mv platforma-open*.tgz package.tgz";
29
+
22
30
  /** The `block-software` package-builder descriptor for a python
23
31
  * entrypoint. Kept opaque by the engine; rule authors edit it via
24
32
  * `transformAt("block-software", ...)`. The `:3.12.10` tag inside
@@ -45,21 +53,22 @@ function pythonBlockSoftware(): Record<string, unknown> {
45
53
 
46
54
  export function softwarePackageJsonInitial(ctx: RunContext): Record<string, unknown> {
47
55
  const v = ctx.blockVars;
56
+
48
57
  return {
49
58
  name: `${v.facadeName}.software`,
50
59
  type: "module",
51
60
  description: "Block Software",
52
61
  files: ["./dist/**/*"],
53
62
  scripts: {
54
- build: "pl-pkg build",
55
- prepublishOnly: "pl-pkg prepublish",
63
+ build: BUILD_CMD,
64
+ "do-pack": DO_PACK_CMD,
56
65
  changeset: "changeset",
57
66
  "version-packages": "changeset version",
58
67
  },
59
68
  "block-software": pythonBlockSoftware(),
60
69
  devDependencies: {
61
70
  "@platforma-open/milaboratories.runenv-python-3": "catalog:",
62
- "@platforma-sdk/package-builder": "sdk:",
71
+ "@platforma-sdk/block-tools": "sdk:",
63
72
  },
64
73
  };
65
74
  }
@@ -74,15 +83,19 @@ export function softwarePackageJsonRules(): void {
74
83
  ensureField("type", "module");
75
84
  ensureField("files", ["./dist/**/*"]);
76
85
 
77
- ensureScript("build", "pl-pkg build");
78
- ensureScript("prepublishOnly", "pl-pkg prepublish");
86
+ // Lifecycle scripts. block-tools builds and packs; a block migrated off pl-pkg converges on
87
+ // refresh — the old `pl-pkg prepublish` upload step is dropped (build + push happen in `build`).
88
+ ensureScript("build", BUILD_CMD);
89
+ ensureScript("do-pack", DO_PACK_CMD);
90
+ removeScript("prepublishOnly");
79
91
  ensureScript("changeset", "changeset");
80
92
  ensureScript("version-packages", "changeset version");
81
93
 
82
- ensureDevDeps({
83
- "@platforma-open/milaboratories.runenv-python-3": "catalog:",
84
- "@platforma-sdk/package-builder": "sdk:",
85
- });
94
+ // Canonical devDeps. block-tools bundles the build engine, so the pl-pkg
95
+ // `@platforma-sdk/package-builder` dependency is dropped.
96
+ ensureDevDep("@platforma-open/milaboratories.runenv-python-3", "catalog:");
97
+ ensureDevDep("@platforma-sdk/block-tools", "sdk:");
98
+ removeDep("@platforma-sdk/package-builder");
86
99
 
87
100
  enforceAlphabeticalOrder("dependencies");
88
101
  enforceAlphabeticalOrder("devDependencies");
@@ -12,7 +12,21 @@
12
12
  "build": {
13
13
  "dependsOn": ["^build", "check"],
14
14
  "inputs": ["$TURBO_DEFAULT$"],
15
- "env": ["PL_PKG_DEV", "PL_DOCKER_REGISTRY_PUSH_TO"],
15
+ "env": [
16
+ "PL_DOCKER_REGISTRY_PUSH_TO",
17
+ "PL_BUILD_CHANNEL",
18
+ "PL_BUILD_VARIANT",
19
+ "PL_BUILD_LOCATION",
20
+ "PL_BUILD_USE_PUBLISHED",
21
+ "PL_DEV_DOCKER_PUSH_URL",
22
+ "PL_DEV_DOCKER_PULL_URL",
23
+ "PL_DEV_BINARY_UPLOAD_URL",
24
+ "PL_RELEASE_DOCKER_PUSH_URL",
25
+ "PL_RELEASE_DOCKER_PULL_URL",
26
+ "PL_RELEASE_BINARY_UPLOAD_URL",
27
+ "PL_REGISTRY_PLATFORMA_OPEN_UPLOAD_URL"
28
+ ],
29
+ "passThroughEnv": ["AWS_*", "PL_AWS_*"],
16
30
  "outputs": ["./dist/**", "./block-pack/**", "./pkg-*.tgz"]
17
31
  },
18
32
  "build:dev": {