@platforma-sdk/block-tools 2.10.13 → 2.10.15

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 (169) hide show
  1. package/dist/cli.js +23 -2
  2. package/dist/cli.js.map +1 -1
  3. package/dist/cli.mjs +1944 -100
  4. package/dist/cli.mjs.map +1 -1
  5. package/dist/cmd/index.d.ts +10 -4
  6. package/dist/cmd/structure/check.d.ts +10 -0
  7. package/dist/cmd/structure/init.d.ts +18 -0
  8. package/dist/cmd/structure/refresh.d.ts +11 -0
  9. package/dist/cmd/update-deps.d.ts +7 -0
  10. package/dist/structure/cli/run-structure.d.ts +19 -0
  11. package/dist/structure/engine/api.d.ts +55 -0
  12. package/dist/structure/engine/builders.d.ts +95 -0
  13. package/dist/structure/engine/content-rules.d.ts +148 -0
  14. package/dist/structure/engine/ctx.d.ts +34 -0
  15. package/dist/structure/engine/discovery-fs.d.ts +22 -0
  16. package/dist/structure/engine/discovery.d.ts +39 -0
  17. package/dist/structure/engine/flatten.d.ts +3 -0
  18. package/dist/structure/engine/fs/api.d.ts +27 -0
  19. package/dist/structure/engine/fs/memory.d.ts +16 -0
  20. package/dist/structure/engine/fs/node.d.ts +14 -0
  21. package/dist/structure/engine/glob.d.ts +4 -0
  22. package/dist/structure/engine/ir.d.ts +124 -0
  23. package/dist/structure/engine/parsers/json.d.ts +37 -0
  24. package/dist/structure/engine/parsers/lines.d.ts +9 -0
  25. package/dist/structure/engine/parsers/yaml.d.ts +18 -0
  26. package/dist/structure/engine/registry-client.d.ts +34 -0
  27. package/dist/structure/engine/runner.d.ts +45 -0
  28. package/dist/structure/engine/templates.d.ts +30 -0
  29. package/dist/structure/engine/testing.d.ts +34 -0
  30. package/dist/structure/engine/version.d.ts +18 -0
  31. package/dist/structure/init-block-constructor.d.ts +32 -0
  32. package/dist/structure/rules/block-package-json.d.ts +9 -0
  33. package/dist/structure/rules/block.d.ts +1 -0
  34. package/dist/structure/rules/migrations.d.ts +2 -0
  35. package/dist/structure/rules/model-package-json.d.ts +3 -0
  36. package/dist/structure/rules/model.d.ts +1 -0
  37. package/dist/structure/rules/root-catalog-bump.d.ts +1 -0
  38. package/dist/structure/rules/root-gitignore.d.ts +2 -0
  39. package/dist/structure/rules/root-package-json.d.ts +3 -0
  40. package/dist/structure/rules/root-pnpm-workspace.d.ts +15 -0
  41. package/dist/structure/rules/root.d.ts +1 -0
  42. package/dist/structure/rules/shared/colocated-tests.d.ts +2 -0
  43. package/dist/structure/rules/shared/key-order.d.ts +1 -0
  44. package/dist/structure/rules/software-package-json.d.ts +3 -0
  45. package/dist/structure/rules/software.d.ts +1 -0
  46. package/dist/structure/rules/test-package-json.d.ts +3 -0
  47. package/dist/structure/rules/test.d.ts +1 -0
  48. package/dist/structure/rules/ui-package-json.d.ts +3 -0
  49. package/dist/structure/rules/ui.d.ts +1 -0
  50. package/dist/structure/rules/workflow-package-json.d.ts +3 -0
  51. package/dist/structure/rules/workflow.d.ts +1 -0
  52. package/dist/structure/structure-definition.d.ts +1 -0
  53. package/package.json +8 -6
  54. package/src/cmd/index.ts +10 -4
  55. package/src/cmd/structure/check.ts +51 -0
  56. package/src/cmd/structure/init.ts +65 -0
  57. package/src/cmd/structure/refresh.ts +44 -0
  58. package/src/cmd/update-deps.ts +15 -3
  59. package/src/structure/__tests__/colocated-test-wiring.test.ts +107 -0
  60. package/src/structure/__tests__/floor-version.test.ts +52 -0
  61. package/src/structure/__tests__/init-catalog-resolution.test.ts +82 -0
  62. package/src/structure/__tests__/init-check-parity.test.ts +59 -0
  63. package/src/structure/__tests__/model-package-json.snapshot.test.ts +60 -0
  64. package/src/structure/__tests__/oxfmt-clean-init.test.ts +64 -0
  65. package/src/structure/__tests__/root-catalog-bump.test.ts +110 -0
  66. package/src/structure/__tests__/seed-disjointness.test.ts +79 -0
  67. package/src/structure/cli/run-structure.ts +89 -0
  68. package/src/structure/engine/__tests__/content-rules/active-state-guards.test.ts +61 -0
  69. package/src/structure/engine/__tests__/content-rules/catalog-pin.test.ts +46 -0
  70. package/src/structure/engine/__tests__/content-rules/enforce-alphabetical-order.test.ts +55 -0
  71. package/src/structure/engine/__tests__/content-rules/enforce-field-order.test.ts +73 -0
  72. package/src/structure/engine/__tests__/content-rules/ensure-catalog-absent.test.ts +29 -0
  73. package/src/structure/engine/__tests__/content-rules/ensure-catalog-latest.test.ts +70 -0
  74. package/src/structure/engine/__tests__/content-rules/ensure-dep.test.ts +63 -0
  75. package/src/structure/engine/__tests__/content-rules/ensure-deps-bulk.test.ts +46 -0
  76. package/src/structure/engine/__tests__/content-rules/ensure-field-entries.test.ts +35 -0
  77. package/src/structure/engine/__tests__/content-rules/ensure-field.test.ts +56 -0
  78. package/src/structure/engine/__tests__/content-rules/ensure-script.test.ts +39 -0
  79. package/src/structure/engine/__tests__/content-rules/ensure-workspace-scope-deps.test.ts +92 -0
  80. package/src/structure/engine/__tests__/content-rules/gitignore.test.ts +50 -0
  81. package/src/structure/engine/__tests__/content-rules/pin-catalog-to.test.ts +64 -0
  82. package/src/structure/engine/__tests__/content-rules/prune-keys.test.ts +59 -0
  83. package/src/structure/engine/__tests__/content-rules/registry-client.test.ts +116 -0
  84. package/src/structure/engine/__tests__/content-rules/remove-field.test.ts +49 -0
  85. package/src/structure/engine/__tests__/content-rules/require-field.test.ts +40 -0
  86. package/src/structure/engine/__tests__/content-rules/transform-at.test.ts +33 -0
  87. package/src/structure/engine/__tests__/content-rules/when-inner.test.ts +244 -0
  88. package/src/structure/engine/__tests__/content-rules/workspace-module-paths.test.ts +53 -0
  89. package/src/structure/engine/__tests__/discovery.test.ts +160 -0
  90. package/src/structure/engine/__tests__/fs-memory.test.ts +59 -0
  91. package/src/structure/engine/__tests__/glob.test.ts +43 -0
  92. package/src/structure/engine/__tests__/parsers-json.test.ts +189 -0
  93. package/src/structure/engine/__tests__/parsers-lines.test.ts +44 -0
  94. package/src/structure/engine/__tests__/parsers-yaml.test.ts +90 -0
  95. package/src/structure/engine/__tests__/recheck.test.ts +99 -0
  96. package/src/structure/engine/__tests__/registry-lookup.test.ts +49 -0
  97. package/src/structure/engine/__tests__/runner-when-inside-managed.test.ts +136 -0
  98. package/src/structure/engine/__tests__/runner.test.ts +136 -0
  99. package/src/structure/engine/__tests__/synthetic.test.ts +153 -0
  100. package/src/structure/engine/__tests__/version.test.ts +44 -0
  101. package/src/structure/engine/__tests__/when-files-exist.test.ts +89 -0
  102. package/src/structure/engine/api.ts +131 -0
  103. package/src/structure/engine/builders.ts +341 -0
  104. package/src/structure/engine/content-rules.ts +616 -0
  105. package/src/structure/engine/ctx.ts +94 -0
  106. package/src/structure/engine/discovery-fs.ts +209 -0
  107. package/src/structure/engine/discovery.ts +168 -0
  108. package/src/structure/engine/flatten.ts +117 -0
  109. package/src/structure/engine/fs/api.ts +40 -0
  110. package/src/structure/engine/fs/memory.ts +132 -0
  111. package/src/structure/engine/fs/node.ts +89 -0
  112. package/src/structure/engine/glob.ts +42 -0
  113. package/src/structure/engine/ir.ts +149 -0
  114. package/src/structure/engine/parsers/json.ts +212 -0
  115. package/src/structure/engine/parsers/lines.ts +42 -0
  116. package/src/structure/engine/parsers/yaml.ts +72 -0
  117. package/src/structure/engine/registry-client.ts +140 -0
  118. package/src/structure/engine/runner.ts +519 -0
  119. package/src/structure/engine/templates.ts +74 -0
  120. package/src/structure/engine/testing.ts +93 -0
  121. package/src/structure/engine/version.ts +60 -0
  122. package/src/structure/init-block-constructor.ts +164 -0
  123. package/src/structure/rules/block-package-json.ts +156 -0
  124. package/src/structure/rules/block.ts +29 -0
  125. package/src/structure/rules/migrations.ts +63 -0
  126. package/src/structure/rules/model-package-json.ts +123 -0
  127. package/src/structure/rules/model.ts +65 -0
  128. package/src/structure/rules/root-catalog-bump.ts +77 -0
  129. package/src/structure/rules/root-gitignore.ts +27 -0
  130. package/src/structure/rules/root-package-json.ts +119 -0
  131. package/src/structure/rules/root-pnpm-workspace.ts +103 -0
  132. package/src/structure/rules/root.ts +43 -0
  133. package/src/structure/rules/shared/colocated-tests.ts +11 -0
  134. package/src/structure/rules/shared/key-order.ts +34 -0
  135. package/src/structure/rules/software-package-json.ts +86 -0
  136. package/src/structure/rules/software.ts +33 -0
  137. package/src/structure/rules/test-package-json.ts +70 -0
  138. package/src/structure/rules/test.ts +40 -0
  139. package/src/structure/rules/ui-package-json.ts +108 -0
  140. package/src/structure/rules/ui.ts +75 -0
  141. package/src/structure/rules/workflow-package-json.ts +92 -0
  142. package/src/structure/rules/workflow.ts +51 -0
  143. package/src/structure/structure-definition.ts +28 -0
  144. package/src/structure/templates/static/block/index.d.ts +6 -0
  145. package/src/structure/templates/static/block/index.js +8 -0
  146. package/src/structure/templates/static/block/logos/block-logo.png +0 -0
  147. package/src/structure/templates/static/block/logos/organization-logo.png +0 -0
  148. package/src/structure/templates/static/model/.oxfmtrc.json +4 -0
  149. package/src/structure/templates/static/model/.oxlintrc.json +3 -0
  150. package/src/structure/templates/static/model/src/index.ts +13 -0
  151. package/src/structure/templates/static/model/tsconfig.json +4 -0
  152. package/src/structure/templates/static/root/.gitignore +13 -0
  153. package/src/structure/templates/static/root/.vscode/settings.json +3 -0
  154. package/src/structure/templates/static/root/turbo.json +35 -0
  155. package/src/structure/templates/static/test/tsconfig.json +5 -0
  156. package/src/structure/templates/static/test/vitest.config.mts +8 -0
  157. package/src/structure/templates/static/ui/.oxfmtrc.json +3 -0
  158. package/src/structure/templates/static/ui/.oxlintrc.json +3 -0
  159. package/src/structure/templates/static/ui/index.html +12 -0
  160. package/src/structure/templates/static/ui/src/main.ts +5 -0
  161. package/src/structure/templates/static/ui/tsconfig.json +4 -0
  162. package/src/structure/templates/static/workflow/format.el +42 -0
  163. package/src/structure/templates/static/workflow/tsconfig.json +16 -0
  164. package/src/structure/templates/static/workflow/vitest.config.mts +9 -0
  165. package/src/structure/templates/text/README.md +5 -0
  166. package/src/structure/templates/text/docs/description.md +3 -0
  167. package/src/structure/templates/text/ui/src/MainPage.tpl.vue +9 -0
  168. package/src/structure/templates/text/ui/src/app.tpl.ts +11 -0
  169. package/src/structure/templates/text/workflow/src/main.tpl.tengo +10 -0
@@ -0,0 +1,108 @@
1
+ // UI `package.json`: the initial generator and the drift-correcting body
2
+ // rules, co-located.
3
+ //
4
+ // Authored oxfmt-clean: the ui is one of the two scopes `ts-builder check`
5
+ // runs oxfmt on, so neither half enforces ordering beyond what oxfmt
6
+ // produces — the enforce* calls match oxfmt's order exactly, so refreshing a
7
+ // legacy block yields oxfmt-clean output and the build→check gate (oxfmt
8
+ // --check) passes without a prior `pnpm fmt`.
9
+
10
+ import {
11
+ ensureField,
12
+ ensureScript,
13
+ ensureDep,
14
+ ensureDevDep,
15
+ ensureDevDeps,
16
+ ensurePeerDeps,
17
+ ensureWorkspaceScopeDeps,
18
+ removeDep,
19
+ enforceAlphabeticalOrder,
20
+ enforceFieldOrder,
21
+ when,
22
+ whenFilesExist,
23
+ type RunContext,
24
+ } from "../engine/api";
25
+ import { scopeDepMap } from "../engine/ctx";
26
+ import { canonicalPackageJsonOrder } from "./shared/key-order";
27
+ import { COLOCATED_TEST_GLOB } from "./shared/colocated-tests";
28
+
29
+ export function uiPackageJsonInitial(ctx: RunContext): Record<string, unknown> {
30
+ const v = ctx.blockVars;
31
+ return {
32
+ name: `${v.facadeName}.ui`,
33
+ version: "1.0.0",
34
+ type: "module",
35
+ scripts: {
36
+ fmt: "ts-builder format",
37
+ dev: "ts-builder serve --target block-ui",
38
+ watch: "ts-builder build --target block-ui --watch",
39
+ build: "ts-builder build --target block-ui",
40
+ check: "ts-builder check --target block-ui",
41
+ // No `test`: the vitest `test` script is wired by the body rule ONLY
42
+ // when co-located test files exist (a freshly-init'd ui has none).
43
+ },
44
+ dependencies: {
45
+ "@platforma-sdk/ui-vue": "sdk:",
46
+ vue: "catalog:",
47
+ // The seeded ui (app.ts) imports the block's model package; depend on
48
+ // it — mirrors the body rule's `ensureWorkspaceScopeDeps("model")`.
49
+ ...scopeDepMap(ctx, "model"),
50
+ },
51
+ devDependencies: {
52
+ "@milaboratories/ts-builder": "sdk:",
53
+ "@milaboratories/ts-configs": "sdk:",
54
+ vitest: "catalog:",
55
+ },
56
+ peerDependencies: {
57
+ typescript: "*",
58
+ },
59
+ };
60
+ }
61
+
62
+ export function uiPackageJsonRules(): void {
63
+ ensureField("type", "module");
64
+
65
+ ensureScript("fmt", "ts-builder format");
66
+ ensureScript("dev", "ts-builder serve --target block-ui");
67
+ ensureScript("watch", "ts-builder build --target block-ui --watch");
68
+ ensureScript("build", "ts-builder build --target block-ui");
69
+ ensureScript("check", "ts-builder check --target block-ui");
70
+
71
+ ensureDep("@platforma-sdk/ui-vue", "sdk:");
72
+ // The seeded ui (main.ts) imports `createApp` from vue.
73
+ ensureDep("vue", "catalog:");
74
+ // The seeded ui (app.ts) imports the block's model package.
75
+ ensureWorkspaceScopeDeps("model");
76
+
77
+ ensureDevDeps({
78
+ "@milaboratories/ts-builder": "sdk:",
79
+ "@milaboratories/ts-configs": "sdk:",
80
+ vitest: "catalog:",
81
+ });
82
+
83
+ // The ui builds with `--target block-ui` (types: []), so by default it
84
+ // carries no browser/vitest/node ambient types — only the `typescript`
85
+ // peer for IDE type resolution. Drop any stray `@types/node` a legacy
86
+ // block declares...
87
+ ensurePeerDeps({
88
+ typescript: "*",
89
+ });
90
+ removeDep("@types/node");
91
+
92
+ // ...but a ui WITH co-located unit tests (`src/**/*.test.ts`) needs the
93
+ // vitest `test` script AND node ambient types: re-add `@types/node` as a
94
+ // devDep so `types: ["node"]` in ui/tsconfig (wired under the same
95
+ // predicate) resolves the tests' `node:*` imports. A test-less ui keeps
96
+ // the lean default (no test script, no @types/node) and stays a fixpoint.
97
+ // Runs AFTER removeDep so the dev dep is not stripped.
98
+ when(whenFilesExist(COLOCATED_TEST_GLOB), () => {
99
+ ensureScript("test", "vitest run --passWithNoTests");
100
+ ensureDevDep("@types/node", "*");
101
+ });
102
+
103
+ enforceAlphabeticalOrder("dependencies");
104
+ enforceAlphabeticalOrder("devDependencies");
105
+ enforceAlphabeticalOrder("peerDependencies");
106
+ enforceAlphabeticalOrder("optionalDependencies");
107
+ enforceFieldOrder([...canonicalPackageJsonOrder]);
108
+ }
@@ -0,0 +1,75 @@
1
+ // UI-scope rules. Author owns src/main.ts and components; static config
2
+ // files are engine-managed.
3
+
4
+ import {
5
+ scope,
6
+ fixed,
7
+ managed,
8
+ scaffold,
9
+ seed,
10
+ file,
11
+ tpl,
12
+ generate,
13
+ blockVars,
14
+ when,
15
+ whenFilesExist,
16
+ ensureField,
17
+ removeField,
18
+ pruneKeysMatching,
19
+ } from "../engine/api";
20
+ import { getActiveRunContext } from "../engine/builders";
21
+ import { uiPackageJsonInitial, uiPackageJsonRules } from "./ui-package-json";
22
+ import { COLOCATED_TEST_GLOB } from "./shared/colocated-tests";
23
+
24
+ export function uiRules(): void {
25
+ scope("ui", () => {
26
+ // tsconfig is managed (not fixed) so node ambient types can be provided
27
+ // CONDITIONALLY. The body still enforces the canonical shape —
28
+ // `{extends, include}` with NO stray keys — and, ONLY when the ui
29
+ // carries co-located unit tests (`src/**/*.test.ts`), adds
30
+ // `compilerOptions.types: ["node"]` so tests importing `node:*`
31
+ // type-check under vue-tsc: provide node types, do NOT exclude the
32
+ // tests. A test-less ui is canonicalised to
33
+ // bare `{extends, include}` and stays a refresh fixpoint. The matching
34
+ // `@types/node` devDep is wired by the package.json rule under the same
35
+ // predicate.
36
+ managed("tsconfig.json", file("ui/tsconfig.json"), () => {
37
+ ensureField("extends", "@milaboratories/ts-configs/block/ui");
38
+ removeField("compilerOptions");
39
+ when(whenFilesExist(COLOCATED_TEST_GLOB), () => {
40
+ ensureField("compilerOptions.types", ["node"]);
41
+ });
42
+ ensureField("include", ["src/**/*"]);
43
+ pruneKeysMatching((k) => k !== "extends" && k !== "include" && k !== "compilerOptions");
44
+ });
45
+ fixed(".oxlintrc.json", file("ui/.oxlintrc.json"));
46
+ // Block-local oxfmt config — the ui is oxfmt-checked (`ts-builder check
47
+ // --target block-ui`).
48
+ fixed(".oxfmtrc.json", file("ui/.oxfmtrc.json"));
49
+ // scaffold (not fixed): index.html carries a block-specific CSP. Write
50
+ // the canonical default only when absent; never overwrite an author's.
51
+ scaffold("index.html", file("ui/index.html"));
52
+
53
+ // A minimal-but-real UI: mount (main.ts), app wiring the block model
54
+ // (app.ts), and a landing page (MainPage.vue). An empty main.ts would
55
+ // trip oxlint `unicorn(no-empty-file)`. Author-owned seeds: written once
56
+ // at init, untouched on refresh.
57
+ seed("src/main.ts", file("ui/src/main.ts"));
58
+ seed(
59
+ "src/app.ts",
60
+ tpl("ui/src/app.tpl.ts", () => ({ modelPkg: `${blockVars().facadeName}.model` })),
61
+ );
62
+ seed(
63
+ "src/MainPage.vue",
64
+ tpl("ui/src/MainPage.tpl.vue", () => ({ shortName: blockVars().shortName })),
65
+ );
66
+
67
+ managed(
68
+ "package.json",
69
+ generate(() => uiPackageJsonInitial(getActiveRunContext())),
70
+ () => {
71
+ uiPackageJsonRules();
72
+ },
73
+ );
74
+ });
75
+ }
@@ -0,0 +1,92 @@
1
+ // Workflow `package.json`: the initial generator and the drift-correcting
2
+ // body rules, co-located. Workflow packages reference software modules at
3
+ // workspace level when the block has any; the generator fills them from the
4
+ // discovered modules and the body rule re-asserts them.
5
+
6
+ import {
7
+ ensureField,
8
+ ensureScript,
9
+ ensureDep,
10
+ ensureDevDeps,
11
+ ensureWorkspaceScopeDeps,
12
+ enforceAlphabeticalOrder,
13
+ enforceFieldOrder,
14
+ when,
15
+ whenFilesExist,
16
+ type RunContext,
17
+ } from "../engine/api";
18
+ import { scopeDepMaps } from "../engine/ctx";
19
+ import { canonicalPackageJsonOrder } from "./shared/key-order";
20
+ import { COLOCATED_TEST_GLOB } from "./shared/colocated-tests";
21
+
22
+ export function workflowPackageJsonInitial(ctx: RunContext): Record<string, unknown> {
23
+ const v = ctx.blockVars;
24
+ return {
25
+ name: `${v.facadeName}.workflow`,
26
+ version: "1.0.0",
27
+ type: "module",
28
+ scripts: {
29
+ // No `fmt`: the workflow is Tengo, not TS — nothing for oxlint/oxfmt
30
+ // to process. Tengo is built and checked by pl-tengo.
31
+ build: "shx rm -rf dist && pl-tengo build",
32
+ check: "pl-tengo check",
33
+ // No `test`: the vitest `test` script is wired by the body rule ONLY
34
+ // when co-located test files exist (a freshly-init'd workflow has none).
35
+ // Tengo source formatter (emacs batch). Falls back to a notice when
36
+ // emacs is absent, so the script never hard-fails the environment.
37
+ format: "/usr/bin/env emacs --script ./format.el || echo 'No emacs.'",
38
+ },
39
+ dependencies: {
40
+ "@platforma-sdk/workflow-tengo": "sdk:",
41
+ // Every block-local software module as a workspace dep (zero or more).
42
+ ...scopeDepMaps(ctx, "software"),
43
+ },
44
+ devDependencies: {
45
+ "@platforma-sdk/tengo-builder": "sdk:",
46
+ "@platforma-sdk/test": "sdk:",
47
+ vitest: "catalog:",
48
+ shx: "catalog:",
49
+ },
50
+ };
51
+ }
52
+
53
+ export function workflowPackageJsonRules(): void {
54
+ ensureField("type", "module");
55
+
56
+ // No `fmt`: the workflow is Tengo, not TS. Build + check go through
57
+ // pl-tengo. shx powers the cross-platform build clean-up.
58
+ ensureScript("build", "shx rm -rf dist && pl-tengo build");
59
+ ensureScript("check", "pl-tengo check");
60
+ // Tengo source formatter (emacs batch); no-op notice when emacs is absent.
61
+ ensureScript("format", "/usr/bin/env emacs --script ./format.el || echo 'No emacs.'");
62
+ // The vitest `test` script is wired ONLY when the workflow carries
63
+ // co-located integration tests (`src/**/*.test.ts`, incl. `src/test/`).
64
+ // A test-less workflow gets no `test` task and stays a refresh fixpoint.
65
+ // (Workflow tests type-check via the standalone workflow/tsconfig with
66
+ // `types: []` — they pull their types from `@platforma-sdk/test` — so no
67
+ // node-types wiring is needed here, unlike model/ui.)
68
+ when(whenFilesExist(COLOCATED_TEST_GLOB), () => {
69
+ ensureScript("test", "vitest run --passWithNoTests");
70
+ });
71
+
72
+ ensureDep("@platforma-sdk/workflow-tengo", "sdk:");
73
+
74
+ // Pulls in every block-local software module as a workspace dep so the
75
+ // workflow can reference the produced runenv assets.
76
+ ensureWorkspaceScopeDeps("software");
77
+
78
+ // @platforma-sdk/test: workflow integration tests (e.g. mixcr's
79
+ // workflow/src/test/columns.test.ts) import it.
80
+ ensureDevDeps({
81
+ "@platforma-sdk/tengo-builder": "sdk:",
82
+ "@platforma-sdk/test": "sdk:",
83
+ vitest: "catalog:",
84
+ shx: "catalog:",
85
+ });
86
+
87
+ enforceAlphabeticalOrder("dependencies");
88
+ enforceAlphabeticalOrder("devDependencies");
89
+ enforceAlphabeticalOrder("peerDependencies");
90
+ enforceAlphabeticalOrder("optionalDependencies");
91
+ enforceFieldOrder([...canonicalPackageJsonOrder]);
92
+ }
@@ -0,0 +1,51 @@
1
+ // Workflow-scope rules. The Tengo entry point is a templated seed
2
+ // (substitutes ${shortName}); other config files are static.
3
+
4
+ import {
5
+ scope,
6
+ managed,
7
+ fixed,
8
+ scaffold,
9
+ seed,
10
+ file,
11
+ tpl,
12
+ generate,
13
+ remove,
14
+ blockVars,
15
+ } from "../engine/api";
16
+ import { getActiveRunContext } from "../engine/builders";
17
+ import { workflowPackageJsonInitial, workflowPackageJsonRules } from "./workflow-package-json";
18
+
19
+ export function workflowRules(): void {
20
+ scope("workflow", () => {
21
+ // tsconfig for the TypeScript vitest integration tests under src/test
22
+ // (e.g. mixcr's workflow/src/test/columns.test.ts). types:[] keeps the
23
+ // isomorphic workflow free of ambient Node/DOM types.
24
+ fixed("tsconfig.json", file("workflow/tsconfig.json"));
25
+ // Tengo source formatter (emacs batch); the `format` script invokes it.
26
+ fixed("format.el", file("workflow/format.el"));
27
+ // scaffold (not fixed): tengo test config is author-tunable.
28
+ scaffold("vitest.config.mts", file("workflow/vitest.config.mts"));
29
+ // No workflow facade (index.js / index.d.ts): the block loader resolves the
30
+ // workflow via the `block:` components dist path (workflow/dist/.../main.plj.gz),
31
+ // never the JS facade. It was orphaned in production — dropped. Actively
32
+ // removed so existing blocks that carry it get cleaned (idempotent on absence).
33
+ remove("index.js");
34
+ remove("index.d.ts");
35
+
36
+ seed(
37
+ "src/main.tpl.tengo",
38
+ tpl("workflow/src/main.tpl.tengo", () => ({
39
+ shortName: blockVars().shortName,
40
+ })),
41
+ );
42
+
43
+ managed(
44
+ "package.json",
45
+ generate(() => workflowPackageJsonInitial(getActiveRunContext())),
46
+ () => {
47
+ workflowPackageJsonRules();
48
+ },
49
+ );
50
+ });
51
+ }
@@ -0,0 +1,28 @@
1
+ // Canonical block structure — composes every scope's `*Rules()` function
2
+ // inside a single `defineStructure(() => { ... })`. Re-evaluated by the
3
+ // engine on every run; rule modules are imported by name so the
4
+ // structure stays inspectable and the dep graph is explicit.
5
+
6
+ import { defineStructure } from "./engine/api";
7
+ import { rootRules } from "./rules/root";
8
+ import { blockRules } from "./rules/block";
9
+ import { modelRules } from "./rules/model";
10
+ import { uiRules } from "./rules/ui";
11
+ import { workflowRules } from "./rules/workflow";
12
+ import { testRules } from "./rules/test";
13
+ import { softwareRules } from "./rules/software";
14
+ import { testFrameworkMigration, legacyCleanup } from "./rules/migrations";
15
+ import { rootCatalogBumpRules } from "./rules/root-catalog-bump";
16
+
17
+ export const STRUCTURE = defineStructure(() => {
18
+ rootRules();
19
+ blockRules();
20
+ modelRules();
21
+ uiRules();
22
+ workflowRules();
23
+ testRules();
24
+ softwareRules();
25
+ testFrameworkMigration();
26
+ legacyCleanup();
27
+ rootCatalogBumpRules();
28
+ });
@@ -0,0 +1,6 @@
1
+ declare const blockSpec: {
2
+ type: "dev-v2";
3
+ folder: string;
4
+ };
5
+
6
+ export { blockSpec };
@@ -0,0 +1,8 @@
1
+ const blockSpec = {
2
+ type: "dev-v2",
3
+ folder: __dirname,
4
+ };
5
+
6
+ module.exports = {
7
+ blockSpec,
8
+ };
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": ["node_modules/@milaboratories/ts-builder/configs/oxfmt.json"],
3
+ "ignorePatterns": ["dist", "coverage", "CHANGELOG.md"]
4
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": ["node_modules/@milaboratories/ts-builder/dist/configs/oxlint-block-model.json"]
3
+ }
@@ -0,0 +1,13 @@
1
+ import type { InferOutputsType } from "@platforma-sdk/model";
2
+ import { BlockModelV3, DataModelBuilder } from "@platforma-sdk/model";
3
+
4
+ export type BlockArgs = Record<string, never>;
5
+
6
+ const dataModel = new DataModelBuilder().from<BlockArgs>("v1").init(() => ({}));
7
+
8
+ export const platforma = BlockModelV3.create(dataModel)
9
+ .args(() => ({}))
10
+ .sections(() => [{ type: "link", href: "/", label: "Main" }])
11
+ .done();
12
+
13
+ export type BlockOutputs = InferOutputsType<typeof platforma>;
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "@milaboratories/ts-configs/block/model",
3
+ "include": ["src/**/*"]
4
+ }
@@ -0,0 +1,13 @@
1
+ .test_auth.json
2
+ node_modules/
3
+ dist/
4
+ block-pack/
5
+ dev/
6
+ work/
7
+ log/
8
+ .turbo
9
+ vite.config.*.timestamp-*
10
+ software/**/*.tgz
11
+ .DS_Store
12
+ .vscode/sftp.json
13
+ test-dry-run.json
@@ -0,0 +1,3 @@
1
+ {
2
+ "typescript.tsdk": "node_modules/typescript/lib"
3
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "$schema": "https://turbo.build/schema.json",
3
+ "globalDependencies": ["tsconfig.json"],
4
+ "tasks": {
5
+ "fmt": {
6
+ "cache": false
7
+ },
8
+ "check": {
9
+ "dependsOn": ["^build"],
10
+ "outputs": []
11
+ },
12
+ "build": {
13
+ "dependsOn": ["^build", "check"],
14
+ "inputs": ["$TURBO_DEFAULT$"],
15
+ "env": ["PL_PKG_DEV", "PL_DOCKER_REGISTRY_PUSH_TO"],
16
+ "outputs": ["./dist/**", "./block-pack/**", "./pkg-*.tgz"]
17
+ },
18
+ "build:dev": {
19
+ "dependsOn": ["build"],
20
+ "outputs": ["./dist/**"]
21
+ },
22
+ "do-pack": {
23
+ "dependsOn": ["build"],
24
+ "outputs": ["package.tgz"]
25
+ },
26
+ "test": {
27
+ "dependsOn": ["build", "check"],
28
+ "passThroughEnv": ["PL_ADDRESS", "PL_TEST_PASSWORD", "PL_TEST_USER", "PL_TEST_PROXY", "DEBUG"]
29
+ },
30
+ "mark-stable": {
31
+ "passThroughEnv": ["PL_REGISTRY", "AWS_*"],
32
+ "cache": false
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "@milaboratories/ts-configs/block/test",
3
+ "include": ["src/**/*"],
4
+ "files": []
5
+ }
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ watch: false,
6
+ testTimeout: 30000,
7
+ },
8
+ });
@@ -0,0 +1,3 @@
1
+ {
2
+ "ignorePatterns": ["dist", "CHANGELOG.md"]
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": ["node_modules/@milaboratories/ts-builder/dist/configs/oxlint-block-ui.json"]
3
+ }
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' blob:" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ </head>
8
+ <body>
9
+ <div id="app"></div>
10
+ <script type="module" src="/src/main.ts"></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1,5 @@
1
+ import { createApp } from "vue";
2
+ import { sdkPlugin } from "./app";
3
+ import { BlockLayout } from "@platforma-sdk/ui-vue";
4
+
5
+ createApp(BlockLayout).use(sdkPlugin).mount("#app");
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "@milaboratories/ts-configs/block/ui",
3
+ "include": ["src/**/*"]
4
+ }
@@ -0,0 +1,42 @@
1
+ ;; This program formats all files inside src directory. Usage: emacs --script ./format.el
2
+
3
+ (defun install-go-mode ()
4
+ "Installs go-mode"
5
+ (require 'package)
6
+ (add-to-list 'package-archives
7
+ '("melpa-stable" . "https://stable.melpa.org/packages/"))
8
+ (package-initialize)
9
+ (unless package-archive-contents
10
+ (package-refresh-contents))
11
+
12
+ (package-install 'go-mode t)
13
+ (require 'go-mode))
14
+
15
+ ;; spaces -> tabs only at the beginning of lines
16
+ (setq tabify-regexp "^\t* [ \t]+")
17
+
18
+ (defun format-file (file)
19
+ "Formats a file according to slightly changed Go rules"
20
+ (message "Format %s" file)
21
+ (save-excursion
22
+ (find-file file)
23
+ (delete-trailing-whitespace) ;; deletes whitespaces
24
+ (go-mode) ;; sets golang rules for indentation
25
+ (tabify (point-min) (point-max)) ;; spaces -> tabs in the whole file
26
+ (indent-region (point-min) (point-max)) ;; indentation in the whole file
27
+ (save-buffer))) ;; save file
28
+
29
+ (install-go-mode)
30
+
31
+ ;; change syntax of a standard go-mode a bit
32
+ (advice-add
33
+ 'go--in-composite-literal-p
34
+ :filter-return
35
+ (lambda (&rest r) t))
36
+
37
+ ;; find all files in src
38
+ (setq files (directory-files-recursively "src" "\\.tengo\\'"))
39
+
40
+ ;; call format on every file.
41
+ (dolist (file files)
42
+ (format-file file))
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2022",
4
+ "module": "commonjs",
5
+ "moduleResolution": "node",
6
+ "esModuleInterop": true,
7
+ "strict": true,
8
+ "outDir": "./dist",
9
+ "rootDir": "./src",
10
+ "sourceMap": true,
11
+ "declaration": true
12
+ },
13
+ "types": [],
14
+ "include": ["src/**/*"],
15
+ "exclude": ["node_modules", "dist"]
16
+ }
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ watch: false,
6
+ maxConcurrency: 3,
7
+ testTimeout: 5000,
8
+ },
9
+ });
@@ -0,0 +1,5 @@
1
+ # ${shortName}
2
+
3
+ Platforma block in the `${orgScope}` org.
4
+
5
+ Package: `${facadeName}`
@@ -0,0 +1,3 @@
1
+ # ${shortName}
2
+
3
+ Short description of the `${shortName}` block goes here.
@@ -0,0 +1,9 @@
1
+ <script setup lang="ts">
2
+ import { PlBlockPage } from "@platforma-sdk/ui-vue";
3
+ </script>
4
+
5
+ <template>
6
+ <PlBlockPage>
7
+ <h1>${shortName}</h1>
8
+ </PlBlockPage>
9
+ </template>
@@ -0,0 +1,11 @@
1
+ import { platforma } from "${modelPkg}";
2
+ import { defineAppV3 } from "@platforma-sdk/ui-vue";
3
+ import MainPage from "./MainPage.vue";
4
+
5
+ export const sdkPlugin = defineAppV3(platforma, () => ({
6
+ routes: {
7
+ "/": () => MainPage,
8
+ },
9
+ }));
10
+
11
+ export const useApp = sdkPlugin.useApp;
@@ -0,0 +1,10 @@
1
+ // Workflow entry point for ${shortName}.
2
+
3
+ wf := import("@platforma-sdk/workflow-tengo:workflow")
4
+
5
+ wf.body(func(args) {
6
+ return {
7
+ outputs: {},
8
+ exports: {}
9
+ }
10
+ })