@machineblocks/cli 0.0.0-stage → 0.1.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/blocks/com/machineblocks/bml/cli/Library.bml +52 -0
- package/blocks/com/machineblocks/bml/cli/README.bml +31 -0
- package/blocks/com/machineblocks/bml/cli/documentation/Commands.bml +88 -0
- package/blocks/com/machineblocks/bml/cli/documentation/Configuration.bml +54 -0
- package/blocks/com/machineblocks/bml/cli/documentation/DualCliModel.bml +48 -0
- package/blocks/com/machineblocks/bml/cli/documentation/Installation.bml +44 -0
- package/blocks/com/machineblocks/bml/cli/documentation/Introduction.bml +39 -0
- package/blocks/com/machineblocks/bml/cli/documentation/Responsibilities.bml +50 -0
- package/blocks/com/machineblocks/bml/cli/documentation/TargetBootstrap.bml +45 -0
- package/dist/args.d.ts +21 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +94 -0
- package/dist/args.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +9 -0
- package/dist/cli.js.map +1 -0
- package/dist/compile-command.d.ts +7 -0
- package/dist/compile-command.d.ts.map +1 -0
- package/dist/compile-command.js +213 -0
- package/dist/compile-command.js.map +1 -0
- package/dist/execute.d.ts +4 -0
- package/dist/execute.d.ts.map +1 -0
- package/dist/execute.js +18 -0
- package/dist/execute.js.map +1 -0
- package/dist/help.d.ts +3 -0
- package/dist/help.d.ts.map +1 -0
- package/dist/help.js +26 -0
- package/dist/help.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/output-gate.d.ts +11 -0
- package/dist/output-gate.d.ts.map +1 -0
- package/dist/output-gate.js +76 -0
- package/dist/output-gate.js.map +1 -0
- package/dist/validate-command.d.ts +4 -0
- package/dist/validate-command.d.ts.map +1 -0
- package/dist/validate-command.js +47 -0
- package/dist/validate-command.js.map +1 -0
- package/package.json +42 -4
- package/README.md +0 -3
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<!--MachineBlocks CLI Library
|
|
2
|
+
FQN: com.machineblocks.bml.cli.Library-->
|
|
3
|
+
<mbcli:Library xmlns="http://blockml.org/bml"
|
|
4
|
+
xmlns:blockml="org.blockml.bml"
|
|
5
|
+
xmlns:core="org.blockml.bml.core"
|
|
6
|
+
xmlns:ucli="org.blockml.bml.cli"
|
|
7
|
+
xmlns:render="com.machineblocks.bml.target.render"
|
|
8
|
+
xmlns:mbcli="com.machineblocks.bml.cli">
|
|
9
|
+
|
|
10
|
+
<baseType>
|
|
11
|
+
core:BlockLibrary
|
|
12
|
+
</baseType>
|
|
13
|
+
<is>
|
|
14
|
+
The MachineBlocks host CLI library catalog
|
|
15
|
+
</is>
|
|
16
|
+
<version>
|
|
17
|
+
0.1.0
|
|
18
|
+
</version>
|
|
19
|
+
<documentation>
|
|
20
|
+
Publishable host-CLI library (com.machineblocks.bml.cli.Library).
|
|
21
|
+
Thin layer over @blockml/cli that registers the MachineBlocks SCAD target
|
|
22
|
+
and supplies MachineBlocks defaults. Recommended entry for MachineBlocks
|
|
23
|
+
users who want BML rendered to SCAD.
|
|
24
|
+
|
|
25
|
+
Membership is the file tree under this Library.bml.
|
|
26
|
+
</documentation>
|
|
27
|
+
<references>
|
|
28
|
+
<see type="mbcli:README" relation="ReadFirst" />
|
|
29
|
+
</references>
|
|
30
|
+
<language>
|
|
31
|
+
<blockml:language.English />
|
|
32
|
+
</language>
|
|
33
|
+
<properties>
|
|
34
|
+
<description override="true">
|
|
35
|
+
<value>MachineBlocks host CLI library</value>
|
|
36
|
+
</description>
|
|
37
|
+
</properties>
|
|
38
|
+
<aggregations>
|
|
39
|
+
<readMe override="true">
|
|
40
|
+
<composition>
|
|
41
|
+
<mbcli:README />
|
|
42
|
+
</composition>
|
|
43
|
+
</readMe>
|
|
44
|
+
<dependencies override="true">
|
|
45
|
+
<composition>
|
|
46
|
+
<blockml:Library />
|
|
47
|
+
<ucli:Library />
|
|
48
|
+
<render:Library />
|
|
49
|
+
</composition>
|
|
50
|
+
</dependencies>
|
|
51
|
+
</aggregations>
|
|
52
|
+
</mbcli:Library>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<!--MachineBlocks CLI — README
|
|
2
|
+
FQN: com.machineblocks.bml.cli.README-->
|
|
3
|
+
<mbcli:README xmlns="http://blockml.org/bml"
|
|
4
|
+
xmlns:core="org.blockml.bml.core"
|
|
5
|
+
xmlns:mbcli="com.machineblocks.bml.cli"
|
|
6
|
+
xmlns:clidoc="com.machineblocks.bml.cli.documentation">
|
|
7
|
+
|
|
8
|
+
<baseType>
|
|
9
|
+
core:ReadMe
|
|
10
|
+
</baseType>
|
|
11
|
+
<is>
|
|
12
|
+
Reading entry for the MachineBlocks host CLI library
|
|
13
|
+
</is>
|
|
14
|
+
<documentation>
|
|
15
|
+
@machineblocks/cli is the command MachineBlocks users run. It is not a second
|
|
16
|
+
compiler. It calls the same @blockml/cli and @blockml/compiler packages, with
|
|
17
|
+
the SCAD target already registered and with paths that match a MachineBlocks
|
|
18
|
+
project.
|
|
19
|
+
|
|
20
|
+
People who have not used BlockML can render .bml files to .scad without
|
|
21
|
+
learning toolchain target names, blockdoc, or xsd. People who want the full
|
|
22
|
+
toolchain still use the blockml command from @blockml/cli.
|
|
23
|
+
|
|
24
|
+
Start at com.machineblocks.bml.cli.documentation.Introduction.
|
|
25
|
+
</documentation>
|
|
26
|
+
<references>
|
|
27
|
+
<see type="clidoc:Introduction" relation="ReadFirst" />
|
|
28
|
+
<see type="clidoc:DualCliModel" relation="SeeAlso" />
|
|
29
|
+
<see type="clidoc:Commands" relation="SeeAlso" />
|
|
30
|
+
</references>
|
|
31
|
+
</mbcli:README>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<!--CLI Documentation — Commands
|
|
2
|
+
FQN: com.machineblocks.bml.cli.documentation.Commands-->
|
|
3
|
+
<clidoc:Commands xmlns="http://blockml.org/bml"
|
|
4
|
+
xmlns:core="org.blockml.bml.core"
|
|
5
|
+
xmlns:clidoc="com.machineblocks.bml.cli.documentation">
|
|
6
|
+
|
|
7
|
+
<baseType>
|
|
8
|
+
core:Documentation
|
|
9
|
+
</baseType>
|
|
10
|
+
<is>
|
|
11
|
+
User-facing commands for rendering BML to SCAD
|
|
12
|
+
</is>
|
|
13
|
+
<documentation><![CDATA[
|
|
14
|
+
The host exposes a short command set. validate matches blockml validate.
|
|
15
|
+
compile takes a BlockML type selector, not a file path and not --out.
|
|
16
|
+
|
|
17
|
+
machineblocks validate [file]
|
|
18
|
+
- Same project validate as blockml validate.
|
|
19
|
+
- Exit 0 success, 1 diagnostics, 2 config or usage.
|
|
20
|
+
- Does not register the SCAD target and does not write SCAD.
|
|
21
|
+
- A file argument validates that file. --all validates the reachable corpus.
|
|
22
|
+
file and --all together exit 2.
|
|
23
|
+
|
|
24
|
+
machineblocks compile <source-selector>
|
|
25
|
+
- Compiles with target machineblocks-v3-scad.
|
|
26
|
+
- The selector is one BlockML type selector: an exact block FQN, a package
|
|
27
|
+
selector ending in .*, or a recursive selector ending in .**.
|
|
28
|
+
Resolution is scanTypes from the BlockML framework. This host does not
|
|
29
|
+
define a second selector language.
|
|
30
|
+
- --source-package <FQN> is the source package root for an explicit mapping.
|
|
31
|
+
- --target-package <FQN> is the target package root. It is not a directory
|
|
32
|
+
and not the FQN of one output file.
|
|
33
|
+
- --help shows this command.
|
|
34
|
+
- There is no --out and no --all. The output root is the configured srcDir
|
|
35
|
+
(default blocks).
|
|
36
|
+
- A selector only chooses blocks. It does not by itself choose the target
|
|
37
|
+
package, except that a package selector (a final .* or .** segment)
|
|
38
|
+
supplies the source root when --target-package is set and
|
|
39
|
+
--source-package is omitted. An exact block FQN does not supply a source
|
|
40
|
+
root.
|
|
41
|
+
- --source-package without --target-package exits 2 with
|
|
42
|
+
MB_SOURCE_PACKAGE_ALONE.
|
|
43
|
+
- --target-package without a derivable source root exits 2 with
|
|
44
|
+
MB_SOURCE_PACKAGE_REQUIRED.
|
|
45
|
+
- A missing selector, an unknown flag, or a selector scanTypes rejects
|
|
46
|
+
exits 2.
|
|
47
|
+
- Types whose baseType chain is neither com.machineblocks.bml.core.Block
|
|
48
|
+
nor com.machineblocks.bml.core.Set are skipped. If none remain, the host
|
|
49
|
+
exits 1 with MB_SELECTOR_EMPTY and the selector text.
|
|
50
|
+
- Mapping failures, collisions, and paths that leave srcDir or would
|
|
51
|
+
overwrite a .bml file exit 1. No output file is written unless every
|
|
52
|
+
selected block has a target FQN and a legal path, and every compile
|
|
53
|
+
succeeded.
|
|
54
|
+
- Exit 0 writes the SCAD or preset JSON files and a sibling .map when the
|
|
55
|
+
target attached a source map.
|
|
56
|
+
|
|
57
|
+
Host diagnostic codes:
|
|
58
|
+
|
|
59
|
+
- MB_SOURCE_PACKAGE_ALONE — --source-package without --target-package.
|
|
60
|
+
- MB_SOURCE_PACKAGE_REQUIRED — --target-package and the source root is not
|
|
61
|
+
determined. The message names --source-package.
|
|
62
|
+
- MB_SELECTOR_EMPTY — the selector matched no Block or Set.
|
|
63
|
+
- MB_TARGET_COLLISION — two selected blocks share a target FQN or output path.
|
|
64
|
+
- MB_OUTPUT_ESCAPES_SRC — a resolved path is outside srcDir.
|
|
65
|
+
- MB_OUTPUT_OVERWRITES_BML — a resolved path is an existing .bml file.
|
|
66
|
+
|
|
67
|
+
Mapping codes MB_TARGET_PACKAGE_UNDETERMINED, MB_TARGET_PACKAGE_AMBIGUOUS,
|
|
68
|
+
and MB_SOURCE_OUTSIDE_ROOT are defined with the manifestation rules.
|
|
69
|
+
|
|
70
|
+
machineblocks --help
|
|
71
|
+
- Lists these commands.
|
|
72
|
+
- Points advanced users to blockml --help for search, inspect, graph,
|
|
73
|
+
transform, new, and init.
|
|
74
|
+
|
|
75
|
+
Not in this host surface (still available via blockml if that package
|
|
76
|
+
is installed): watch, search, inspect, graph, transform, scaffolding, xsd
|
|
77
|
+
toggle, thumbnail generation.
|
|
78
|
+
|
|
79
|
+
Per-target matrix entry this host satisfies:
|
|
80
|
+
|
|
81
|
+
machineblocks-v3-scad — document target; selected by type selector;
|
|
82
|
+
written under srcDir; registered by @machineblocks/cli, not by @blockml/cli.
|
|
83
|
+
|
|
84
|
+
]]></documentation>
|
|
85
|
+
<references>
|
|
86
|
+
<see type="clidoc:Configuration" relation="ReadNext" />
|
|
87
|
+
</references>
|
|
88
|
+
</clidoc:Commands>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<!--CLI Documentation — Configuration
|
|
2
|
+
FQN: com.machineblocks.bml.cli.documentation.Configuration-->
|
|
3
|
+
<clidoc:Configuration xmlns="http://blockml.org/bml"
|
|
4
|
+
xmlns:core="org.blockml.bml.core"
|
|
5
|
+
xmlns:clidoc="com.machineblocks.bml.cli.documentation">
|
|
6
|
+
|
|
7
|
+
<baseType>
|
|
8
|
+
core:Documentation
|
|
9
|
+
</baseType>
|
|
10
|
+
<is>
|
|
11
|
+
MachineBlocks defaults and blockml.config.json fields this host reads
|
|
12
|
+
</is>
|
|
13
|
+
<documentation>
|
|
14
|
+
The host reads blockml.config.json from the project root, the same file
|
|
15
|
+
@blockml/cli reads. It understands the universal keys and these MachineBlocks
|
|
16
|
+
keys. The universal CLI documents the MachineBlocks keys as unread in its V1;
|
|
17
|
+
this host is the reader.
|
|
18
|
+
|
|
19
|
+
Universal keys this host honours:
|
|
20
|
+
|
|
21
|
+
- srcDir — default blocks. Project BML sources, and the only compile output
|
|
22
|
+
root. Target FQNs are resolved to paths inside this directory. Compile
|
|
23
|
+
does not read outDir and does not accept --out.
|
|
24
|
+
- libraries — extra Library.bml seeds, appended to package.json blockml.library.
|
|
25
|
+
- targetOptions — opaque bag. Key machineblocks-v3-scad may carry
|
|
26
|
+
settingsFormat (pseudo-map or object). V1 emit is pseudo-map; object is
|
|
27
|
+
rejected with a diagnostic until the SCAD library accepts it.
|
|
28
|
+
- defaultTarget — this host treats machineblocks-v3-scad as the default even
|
|
29
|
+
when the key is omitted. If the key is set to another name, the host
|
|
30
|
+
reports that this command only compiles the SCAD target.
|
|
31
|
+
|
|
32
|
+
MachineBlocks keys:
|
|
33
|
+
|
|
34
|
+
- mbLibPath — root used to compute relative use/include paths to the SCAD
|
|
35
|
+
library (lib/block.scad, config/mb_config.scad, service .scad files).
|
|
36
|
+
Default: the installed @machineblocks/core package root.
|
|
37
|
+
- openscadPath — OpenSCAD executable for later thumbnail or preview commands.
|
|
38
|
+
Not required for compile.
|
|
39
|
+
- thumbsDir — output directory for later thumbnail generation.
|
|
40
|
+
- activeConfig — named config profile inside the SCAD library. Optional.
|
|
41
|
+
- bmlExtensions — extra filename suffixes treated as BML. Default .bml.
|
|
42
|
+
|
|
43
|
+
targets[] on the universal CLI defaults to ["blockdoc"] and must not be
|
|
44
|
+
required for this host. The host registers machineblocks-v3-scad itself.
|
|
45
|
+
Unknown toolchain target names are not an error here; they are ignored
|
|
46
|
+
because this command does not bootstrap them.
|
|
47
|
+
|
|
48
|
+
bom-cli.config.json renaming is not part of this package.
|
|
49
|
+
|
|
50
|
+
</documentation>
|
|
51
|
+
<references>
|
|
52
|
+
<see type="clidoc:TargetBootstrap" relation="ReadNext" />
|
|
53
|
+
</references>
|
|
54
|
+
</clidoc:Configuration>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<!--CLI Documentation — DualCliModel
|
|
2
|
+
FQN: com.machineblocks.bml.cli.documentation.DualCliModel-->
|
|
3
|
+
<clidoc:DualCliModel xmlns="http://blockml.org/bml"
|
|
4
|
+
xmlns:core="org.blockml.bml.core"
|
|
5
|
+
xmlns:clidoc="com.machineblocks.bml.cli.documentation">
|
|
6
|
+
|
|
7
|
+
<baseType>
|
|
8
|
+
core:Documentation
|
|
9
|
+
</baseType>
|
|
10
|
+
<is>
|
|
11
|
+
Universal CLI versus the MachineBlocks host
|
|
12
|
+
</is>
|
|
13
|
+
<documentation>
|
|
14
|
+
Two commands, one compiler.
|
|
15
|
+
|
|
16
|
+
@blockml/cli (command: blockml), library org.blockml.bml.cli.*:
|
|
17
|
+
- Universal toolchain: validate, compile blockdoc or xsd or fatblock, search,
|
|
18
|
+
graph, inspect, transform, new, init.
|
|
19
|
+
- Domain-agnostic. No MachineBlocks paths, no machineblocks-v3-scad built-in.
|
|
20
|
+
- Reads blockml.config.json targets[] for toolchain targets.
|
|
21
|
+
- Scope exclusions in that library list machineblocks-v3-scad registration
|
|
22
|
+
as out of scope on purpose.
|
|
23
|
+
|
|
24
|
+
@machineblocks/cli (this package), library com.machineblocks.bml.cli.*:
|
|
25
|
+
- Thin host. Recommended entry for MachineBlocks users.
|
|
26
|
+
- Registers machineblocks-v3-scad by constructing the render target with a
|
|
27
|
+
BlockRenderEngine.
|
|
28
|
+
- Same validate and compile facade underneath. Defaults differ.
|
|
29
|
+
- Does not reimplement parse, validate, or emit.
|
|
30
|
+
|
|
31
|
+
Interop: a later plugin load (targetPackages in blockml.config.json mapping
|
|
32
|
+
machineblocks-v3-scad to @machineblocks/render-target) may let the universal
|
|
33
|
+
CLI see the target. Product UX stays on this host either way. The universal
|
|
34
|
+
CLI must keep working for projects that never install MachineBlocks.
|
|
35
|
+
|
|
36
|
+
Ownership:
|
|
37
|
+
- This package owns the host bin, MachineBlocks defaults, and target registration.
|
|
38
|
+
- @blockml/compiler owns compileToOutput, CompileRequest, and the registry API.
|
|
39
|
+
- @machineblocks/render-target owns processors and SCAD emit.
|
|
40
|
+
- @blockml/block-render-engine owns strategy infrastructure.
|
|
41
|
+
- Thumbnail generation (OpenSCAD plus image tooling) is a host concern when
|
|
42
|
+
it is built; it is not part of @blockml/cli V1.
|
|
43
|
+
|
|
44
|
+
</documentation>
|
|
45
|
+
<references>
|
|
46
|
+
<see type="clidoc:Responsibilities" relation="ReadNext" />
|
|
47
|
+
</references>
|
|
48
|
+
</clidoc:DualCliModel>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<!--CLI Documentation — Installation
|
|
2
|
+
FQN: com.machineblocks.bml.cli.documentation.Installation-->
|
|
3
|
+
<clidoc:Installation xmlns="http://blockml.org/bml"
|
|
4
|
+
xmlns:core="org.blockml.bml.core"
|
|
5
|
+
xmlns:clidoc="com.machineblocks.bml.cli.documentation">
|
|
6
|
+
|
|
7
|
+
<baseType>
|
|
8
|
+
core:Documentation
|
|
9
|
+
</baseType>
|
|
10
|
+
<is>
|
|
11
|
+
How MachineBlocks users install the host
|
|
12
|
+
</is>
|
|
13
|
+
<documentation>
|
|
14
|
+
Consumer project (the usual path):
|
|
15
|
+
|
|
16
|
+
npm install @machineblocks/cli
|
|
17
|
+
npx machineblocks validate
|
|
18
|
+
npx machineblocks compile com.example.bml.bricks.MyBrick
|
|
19
|
+
|
|
20
|
+
That install brings @machineblocks/render-target, @blockml/block-render-engine,
|
|
21
|
+
@machineblocks/core, and the BlockML compiler packages. The user does not
|
|
22
|
+
install @blockml/cli unless they also want the universal command.
|
|
23
|
+
|
|
24
|
+
From this monorepo while the bin is not published:
|
|
25
|
+
|
|
26
|
+
npm install
|
|
27
|
+
npx blockml validate
|
|
28
|
+
|
|
29
|
+
The second command checks these BML libraries. It is the toolchain CLI used
|
|
30
|
+
to develop this repo, not the MachineBlocks user command.
|
|
31
|
+
|
|
32
|
+
Requires Node.js 20 or newer.
|
|
33
|
+
|
|
34
|
+
Domain users should not be sent to npm link of the blockml monorepo. The
|
|
35
|
+
universal installation note that says "install @machineblocks/cli from the
|
|
36
|
+
MachineBlocks mono-repo" now means this package (@machineblocks/cli in the
|
|
37
|
+
machineblocks-renderer repository). @machineblocks/core remains the separate
|
|
38
|
+
domain library.
|
|
39
|
+
|
|
40
|
+
</documentation>
|
|
41
|
+
<references>
|
|
42
|
+
<see type="clidoc:Introduction" relation="SeeAlso" />
|
|
43
|
+
</references>
|
|
44
|
+
</clidoc:Installation>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!--CLI Documentation — Introduction
|
|
2
|
+
FQN: com.machineblocks.bml.cli.documentation.Introduction-->
|
|
3
|
+
<clidoc:Introduction xmlns="http://blockml.org/bml"
|
|
4
|
+
xmlns:core="org.blockml.bml.core"
|
|
5
|
+
xmlns:clidoc="com.machineblocks.bml.cli.documentation">
|
|
6
|
+
|
|
7
|
+
<baseType>
|
|
8
|
+
core:Documentation
|
|
9
|
+
</baseType>
|
|
10
|
+
<is>
|
|
11
|
+
Purpose of the MachineBlocks host CLI
|
|
12
|
+
</is>
|
|
13
|
+
<documentation>
|
|
14
|
+
MachineBlocks users want BML turned into OpenSCAD that matches the V3 SCAD
|
|
15
|
+
library. They should not have to install the BlockML toolchain repository or
|
|
16
|
+
learn every compiler target.
|
|
17
|
+
|
|
18
|
+
This package is that simplified view:
|
|
19
|
+
|
|
20
|
+
- It depends on published @blockml/* packages (universal CLI and compiler).
|
|
21
|
+
- It depends on @machineblocks/render-target and therefore on
|
|
22
|
+
@blockml/block-render-engine and @machineblocks/core.
|
|
23
|
+
- It registers registry name machineblocks-v3-scad.
|
|
24
|
+
- It fills MachineBlocks defaults: where the SCAD library lives, where
|
|
25
|
+
OpenSCAD is, where .scad files are written.
|
|
26
|
+
|
|
27
|
+
The universal command remains blockml from @blockml/cli. That command must
|
|
28
|
+
not hardcode MachineBlocks. Product UX for this domain is this package.
|
|
29
|
+
|
|
30
|
+
Analogy: tsc is the language tool; a product CLI can wrap it. MachineBlocks
|
|
31
|
+
users install this CLI. They do not clone blockml.
|
|
32
|
+
|
|
33
|
+
V1 of this library is the contract. The bin follows these blocks.
|
|
34
|
+
|
|
35
|
+
</documentation>
|
|
36
|
+
<references>
|
|
37
|
+
<see type="clidoc:DualCliModel" relation="ReadNext" />
|
|
38
|
+
</references>
|
|
39
|
+
</clidoc:Introduction>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<!--CLI Documentation — Responsibilities
|
|
2
|
+
FQN: com.machineblocks.bml.cli.documentation.Responsibilities-->
|
|
3
|
+
<clidoc:Responsibilities xmlns="http://blockml.org/bml"
|
|
4
|
+
xmlns:core="org.blockml.bml.core"
|
|
5
|
+
xmlns:clidoc="com.machineblocks.bml.cli.documentation">
|
|
6
|
+
|
|
7
|
+
<baseType>
|
|
8
|
+
core:Documentation
|
|
9
|
+
</baseType>
|
|
10
|
+
<is>
|
|
11
|
+
What the host does and what it leaves to other packages
|
|
12
|
+
</is>
|
|
13
|
+
<documentation>
|
|
14
|
+
This host does:
|
|
15
|
+
|
|
16
|
+
- Bootstrap a TypeRegistry from @blockml/core (org.blockml.bml.*) plus
|
|
17
|
+
@machineblocks/core (com.machineblocks.bml.*), using the same project
|
|
18
|
+
bootstrap the universal CLI uses.
|
|
19
|
+
- Register the render target before compile. The universal bootstrapTargets
|
|
20
|
+
path is not used for this name. validate does not need the target registry;
|
|
21
|
+
compile does.
|
|
22
|
+
- Pass mbLibPath so generated SCAD can import lib/block.scad and
|
|
23
|
+
config/mb_config.scad from the installed @machineblocks/core (or an
|
|
24
|
+
override path).
|
|
25
|
+
- Default the compile target to machineblocks-v3-scad. The command does not
|
|
26
|
+
take a target name.
|
|
27
|
+
- Resolve the type selector with the framework scan, keep blocks whose
|
|
28
|
+
baseType chain includes Block or Set, and pass the resolved mapping
|
|
29
|
+
(automatic, or sourcePackage plus targetPackage) on targetOptions.
|
|
30
|
+
- Compute every target FQN and output path before writing. One failure
|
|
31
|
+
writes nothing.
|
|
32
|
+
- Write .scad files, preset JSON, and source maps under the configured
|
|
33
|
+
srcDir. The published writer does not enforce that root; this host checks
|
|
34
|
+
the resolved real paths, then calls it with cleaning disabled.
|
|
35
|
+
|
|
36
|
+
This host does not:
|
|
37
|
+
|
|
38
|
+
- Parse or validate with its own code.
|
|
39
|
+
- Register blockdoc, xsd, or fatblock. Users who need those run blockml.
|
|
40
|
+
- Hardcode MBOM property lists. Those stay in NativeBlock.bml.
|
|
41
|
+
- Ship the SCAD library. That is @machineblocks/core lib/ and blocks/.
|
|
42
|
+
|
|
43
|
+
Node.js 20 or newer. The host bin is Node-only. The render target and the
|
|
44
|
+
engine remain browser-capable; only this package may use Node file APIs.
|
|
45
|
+
|
|
46
|
+
</documentation>
|
|
47
|
+
<references>
|
|
48
|
+
<see type="clidoc:Commands" relation="ReadNext" />
|
|
49
|
+
</references>
|
|
50
|
+
</clidoc:Responsibilities>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<!--CLI Documentation — TargetBootstrap
|
|
2
|
+
FQN: com.machineblocks.bml.cli.documentation.TargetBootstrap-->
|
|
3
|
+
<clidoc:TargetBootstrap xmlns="http://blockml.org/bml"
|
|
4
|
+
xmlns:core="org.blockml.bml.core"
|
|
5
|
+
xmlns:clidoc="com.machineblocks.bml.cli.documentation">
|
|
6
|
+
|
|
7
|
+
<baseType>
|
|
8
|
+
core:Documentation
|
|
9
|
+
</baseType>
|
|
10
|
+
<is>
|
|
11
|
+
How the host registers machineblocks-v3-scad
|
|
12
|
+
</is>
|
|
13
|
+
<documentation>
|
|
14
|
+
Before compile, the host performs the equivalent of:
|
|
15
|
+
|
|
16
|
+
import { registerTarget } from "@blockml/compiler";
|
|
17
|
+
import { BlockRenderEngine } from "@blockml/block-render-engine";
|
|
18
|
+
import { MachineBlocksRenderTarget } from "@machineblocks/render-target";
|
|
19
|
+
|
|
20
|
+
registerTarget(new MachineBlocksRenderTarget(new BlockRenderEngine()));
|
|
21
|
+
|
|
22
|
+
The target name property is the string machineblocks-v3-scad.
|
|
23
|
+
Registration is idempotent for the process.
|
|
24
|
+
|
|
25
|
+
The universal CLI's bootstrapTargets loads blockdoc, xsd, and fatblock only.
|
|
26
|
+
It throws on an unknown name in targets[]. This host must not add
|
|
27
|
+
machineblocks-v3-scad to that built-in list inside @blockml/cli. It calls
|
|
28
|
+
registerTarget directly (or registerTargetFactory from the host API).
|
|
29
|
+
|
|
30
|
+
validate and inspect do not register the target.
|
|
31
|
+
|
|
32
|
+
Browser callers and tests that use the render target without this CLI call
|
|
33
|
+
registerTarget themselves with the same constructor pair.
|
|
34
|
+
|
|
35
|
+
CompileOptions passed into the compiler set outputBasePath to the real path
|
|
36
|
+
of srcDir. targetOptions["machineblocks-v3-scad"] carries mbLibPath,
|
|
37
|
+
settingsFormat when set, and, for an explicit mapping, sourcePackage and
|
|
38
|
+
targetPackage. Automatic mapping omits those two keys. activeConfig is
|
|
39
|
+
unused by compile.
|
|
40
|
+
|
|
41
|
+
</documentation>
|
|
42
|
+
<references>
|
|
43
|
+
<see type="clidoc:Installation" relation="ReadNext" />
|
|
44
|
+
</references>
|
|
45
|
+
</clidoc:TargetBootstrap>
|
package/dist/args.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface ValidateArgs {
|
|
2
|
+
command: "validate";
|
|
3
|
+
file?: string;
|
|
4
|
+
all: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface CompileArgs {
|
|
7
|
+
command: "compile";
|
|
8
|
+
selector: string;
|
|
9
|
+
sourcePackage?: string;
|
|
10
|
+
targetPackage?: string;
|
|
11
|
+
}
|
|
12
|
+
export type HostCommand = {
|
|
13
|
+
command: "help";
|
|
14
|
+
} | ValidateArgs | CompileArgs | {
|
|
15
|
+
command: "usage";
|
|
16
|
+
message: string;
|
|
17
|
+
};
|
|
18
|
+
export declare function parseArgs(argv: readonly string[]): HostCommand;
|
|
19
|
+
/** A final .* or .** segment denotes a package. An exact type FQN does not. */
|
|
20
|
+
export declare function sourcePackageFromSelector(selector: string): string | undefined;
|
|
21
|
+
//# sourceMappingURL=args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,UAAU,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,SAAS,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GACnB,YAAY,GACZ,WAAW,GACX;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,WAAW,CAY9D;AAyED,+EAA+E;AAC/E,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAO9E"}
|
package/dist/args.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { COMPILE_HELP } from "./help.js";
|
|
2
|
+
export function parseArgs(argv) {
|
|
3
|
+
if (argv.length === 0 || argv[0] === "--help" || argv[0] === "help") {
|
|
4
|
+
return { command: "help" };
|
|
5
|
+
}
|
|
6
|
+
const [command, ...rest] = argv;
|
|
7
|
+
if (command === "validate") {
|
|
8
|
+
return parseValidate(rest);
|
|
9
|
+
}
|
|
10
|
+
if (command === "compile") {
|
|
11
|
+
return parseCompile(rest);
|
|
12
|
+
}
|
|
13
|
+
return { command: "usage", message: `Unknown command: ${command ?? ""}` };
|
|
14
|
+
}
|
|
15
|
+
function parseValidate(args) {
|
|
16
|
+
let file;
|
|
17
|
+
let all = false;
|
|
18
|
+
for (const arg of args) {
|
|
19
|
+
if (arg === "--help") {
|
|
20
|
+
return { command: "help" };
|
|
21
|
+
}
|
|
22
|
+
if (arg === "--all") {
|
|
23
|
+
all = true;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (arg.startsWith("--")) {
|
|
27
|
+
return { command: "usage", message: `Unknown option: ${arg}` };
|
|
28
|
+
}
|
|
29
|
+
if (file !== undefined) {
|
|
30
|
+
return { command: "usage", message: "validate accepts one file." };
|
|
31
|
+
}
|
|
32
|
+
file = arg;
|
|
33
|
+
}
|
|
34
|
+
if (file !== undefined && all) {
|
|
35
|
+
return { command: "usage", message: "Specify either <file> or --all, not both." };
|
|
36
|
+
}
|
|
37
|
+
return file === undefined ? { command: "validate", all } : { command: "validate", all, file };
|
|
38
|
+
}
|
|
39
|
+
function parseCompile(args) {
|
|
40
|
+
if (args.includes("--help")) {
|
|
41
|
+
return { command: "help" };
|
|
42
|
+
}
|
|
43
|
+
let selector;
|
|
44
|
+
let sourcePackage;
|
|
45
|
+
let targetPackage;
|
|
46
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
47
|
+
const arg = args[index];
|
|
48
|
+
if (arg === undefined) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (arg === "--source-package" || arg === "--target-package") {
|
|
52
|
+
const value = args[index + 1];
|
|
53
|
+
if (value === undefined || value.startsWith("--")) {
|
|
54
|
+
return { command: "usage", message: `${arg} requires a package FQN.` };
|
|
55
|
+
}
|
|
56
|
+
if (arg === "--source-package") {
|
|
57
|
+
sourcePackage = value;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
targetPackage = value;
|
|
61
|
+
}
|
|
62
|
+
index += 1;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (arg.startsWith("--")) {
|
|
66
|
+
return { command: "usage", message: `Unknown option: ${arg}` };
|
|
67
|
+
}
|
|
68
|
+
if (selector !== undefined) {
|
|
69
|
+
return { command: "usage", message: "compile accepts one source selector." };
|
|
70
|
+
}
|
|
71
|
+
selector = arg;
|
|
72
|
+
}
|
|
73
|
+
if (selector === undefined) {
|
|
74
|
+
return { command: "usage", message: `compile requires a source selector.\n\n${COMPILE_HELP}` };
|
|
75
|
+
}
|
|
76
|
+
const parsed = { command: "compile", selector };
|
|
77
|
+
if (sourcePackage !== undefined) {
|
|
78
|
+
parsed.sourcePackage = sourcePackage;
|
|
79
|
+
}
|
|
80
|
+
if (targetPackage !== undefined) {
|
|
81
|
+
parsed.targetPackage = targetPackage;
|
|
82
|
+
}
|
|
83
|
+
return parsed;
|
|
84
|
+
}
|
|
85
|
+
/** A final .* or .** segment denotes a package. An exact type FQN does not. */
|
|
86
|
+
export function sourcePackageFromSelector(selector) {
|
|
87
|
+
const parts = selector.split(".");
|
|
88
|
+
const last = parts[parts.length - 1];
|
|
89
|
+
if ((last !== "*" && last !== "**") || parts.length < 2) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
return parts.slice(0, -1).join(".");
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=args.js.map
|
package/dist/args.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execute } from "./execute.js";
|
|
3
|
+
const result = execute(process.argv.slice(2), process.cwd());
|
|
4
|
+
const write = result.code === 0 ? console.log : console.error;
|
|
5
|
+
for (const line of result.lines) {
|
|
6
|
+
write(line);
|
|
7
|
+
}
|
|
8
|
+
process.exit(result.code);
|
|
9
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;AAC9D,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;IAChC,KAAK,CAAC,IAAI,CAAC,CAAC;AACd,CAAC;AACD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile-command.d.ts","sourceRoot":"","sources":["../src/compile-command.ts"],"names":[],"mappings":"AAoBA,OAAO,EAA6B,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAKxE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CA8HzE"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { bootstrapProjectTypeRegistry, loadConfig, writeOutputFiles } from "@blockml/cli";
|
|
5
|
+
import { compileToOutput, registerTarget } from "@blockml/compiler";
|
|
6
|
+
import { scanTypes } from "@blockml/framework";
|
|
7
|
+
import { BlockRenderEngine } from "@blockml/block-render-engine";
|
|
8
|
+
import { MachineBlocksRenderTarget, SELECTOR_EMPTY, SOURCE_PACKAGE_ALONE, SOURCE_PACKAGE_REQUIRED, TARGET_COLLISION, artifactExtension, isRenderBlock, mapManifestation, pathForManifestation, } from "@machineblocks/render-target";
|
|
9
|
+
import { sourcePackageFromSelector } from "./args.js";
|
|
10
|
+
import { resolveOutputPath } from "./output-gate.js";
|
|
11
|
+
const TARGET_NAME = "machineblocks-v3-scad";
|
|
12
|
+
export function runCompile(args, rootDir) {
|
|
13
|
+
const mapping = resolveMapping(args);
|
|
14
|
+
if (!mapping.ok) {
|
|
15
|
+
return { code: 2, lines: [`${mapping.code}: ${mapping.message}`] };
|
|
16
|
+
}
|
|
17
|
+
let config;
|
|
18
|
+
try {
|
|
19
|
+
config = loadConfig(rootDir);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
return { code: 2, lines: [error instanceof Error ? error.message : String(error)] };
|
|
23
|
+
}
|
|
24
|
+
const srcDirName = config.srcDir ?? "blocks";
|
|
25
|
+
const srcDir = resolve(rootDir, srcDirName);
|
|
26
|
+
const libPath = resolveMbLibPath(rootDir, config);
|
|
27
|
+
if (!libPath) {
|
|
28
|
+
return { code: 2, lines: ["mbLibPath is not set and @machineblocks/core is not installed."] };
|
|
29
|
+
}
|
|
30
|
+
const bootstrap = bootstrapProjectTypeRegistry({ config, rootDir });
|
|
31
|
+
const bootstrapErrors = bootstrap.diagnostics.filter((diagnostic) => diagnostic.severity === "error");
|
|
32
|
+
if (bootstrapErrors.length > 0) {
|
|
33
|
+
return { code: 1, lines: bootstrapErrors.map(formatDiagnostic) };
|
|
34
|
+
}
|
|
35
|
+
const scan = scanTypes([args.selector], bootstrap.registry);
|
|
36
|
+
if (!scan.ok) {
|
|
37
|
+
return { code: 2, lines: [scan.message] };
|
|
38
|
+
}
|
|
39
|
+
const selected = scan.hits.flatMap((fqn) => {
|
|
40
|
+
const document = bootstrap.registry.get(fqn);
|
|
41
|
+
if (!document || !isRenderBlock(document.block, bootstrap.registry)) {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
return [document];
|
|
45
|
+
});
|
|
46
|
+
if (selected.length === 0) {
|
|
47
|
+
return {
|
|
48
|
+
code: 1,
|
|
49
|
+
lines: [`${SELECTOR_EMPTY}: No block matches selector ${args.selector}.`],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const planned = [];
|
|
53
|
+
const targetOwners = new Map();
|
|
54
|
+
const pathOwners = new Map();
|
|
55
|
+
for (const document of selected) {
|
|
56
|
+
const manifested = mapManifestation(document.block.type, mapping.mapping, "selected");
|
|
57
|
+
if (!manifested.ok) {
|
|
58
|
+
return { code: 1, lines: [`${manifested.code}: ${manifested.message}`] };
|
|
59
|
+
}
|
|
60
|
+
const outputPath = pathForManifestation(manifested.fqn, artifactExtension(document.block));
|
|
61
|
+
const targetClash = targetOwners.get(manifested.fqn);
|
|
62
|
+
if (targetClash !== undefined) {
|
|
63
|
+
return { code: 1, lines: [collision(TARGET_COLLISION, manifested.fqn, targetClash, document.block.type)] };
|
|
64
|
+
}
|
|
65
|
+
const pathClash = pathOwners.get(outputPath);
|
|
66
|
+
if (pathClash !== undefined) {
|
|
67
|
+
return { code: 1, lines: [collision(TARGET_COLLISION, outputPath, pathClash, document.block.type)] };
|
|
68
|
+
}
|
|
69
|
+
targetOwners.set(manifested.fqn, document.block.type);
|
|
70
|
+
pathOwners.set(outputPath, document.block.type);
|
|
71
|
+
const gated = resolveOutputPath(srcDir, outputPath);
|
|
72
|
+
if (!gated.ok) {
|
|
73
|
+
return { code: 1, lines: [`${gated.code}: ${gated.message}`] };
|
|
74
|
+
}
|
|
75
|
+
const filePath = document.source.filePath;
|
|
76
|
+
if (!filePath) {
|
|
77
|
+
return { code: 1, lines: [`${document.block.type} has no source file.`] };
|
|
78
|
+
}
|
|
79
|
+
planned.push({
|
|
80
|
+
sourceFqn: document.block.type,
|
|
81
|
+
targetFqn: manifested.fqn,
|
|
82
|
+
path: outputPath,
|
|
83
|
+
filePath,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
registerTarget(new MachineBlocksRenderTarget(new BlockRenderEngine()));
|
|
87
|
+
const targetOptions = buildTargetOptions(config, libPath, mapping.mapping);
|
|
88
|
+
const emitted = [];
|
|
89
|
+
for (const item of planned) {
|
|
90
|
+
const source = readFileSync(item.filePath, "utf8");
|
|
91
|
+
const result = compileToOutput({
|
|
92
|
+
scope: { kind: "document", document: { source, filePath: item.filePath } },
|
|
93
|
+
targetOptions,
|
|
94
|
+
}, TARGET_NAME, {
|
|
95
|
+
typeRegistry: bootstrap.registry,
|
|
96
|
+
rootDir,
|
|
97
|
+
outputBasePath: srcDir,
|
|
98
|
+
});
|
|
99
|
+
const errors = result.diagnostics.filter((diagnostic) => diagnostic.severity === "error");
|
|
100
|
+
if (!result.success || errors.length > 0 || !result.output || result.output.files.length === 0) {
|
|
101
|
+
const lines = errors.map(formatDiagnostic);
|
|
102
|
+
if (lines.length === 0) {
|
|
103
|
+
lines.push(`${item.sourceFqn} produced no output.`);
|
|
104
|
+
}
|
|
105
|
+
return { code: 1, lines };
|
|
106
|
+
}
|
|
107
|
+
emitted.push(...result.output.files);
|
|
108
|
+
}
|
|
109
|
+
const files = withSourceMaps(emitted);
|
|
110
|
+
const writtenPaths = new Set();
|
|
111
|
+
for (const file of files) {
|
|
112
|
+
if (writtenPaths.has(file.path)) {
|
|
113
|
+
return {
|
|
114
|
+
code: 1,
|
|
115
|
+
lines: [`${TARGET_COLLISION}: ${file.path} is claimed by more than one artifact.`],
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
writtenPaths.add(file.path);
|
|
119
|
+
const gated = resolveOutputPath(srcDir, file.path);
|
|
120
|
+
if (!gated.ok) {
|
|
121
|
+
return { code: 1, lines: [`${gated.code}: ${gated.message}`] };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
writeOutputFiles({ files }, srcDir, rootDir, { cleanOutDir: false });
|
|
125
|
+
return { code: 0, lines: [`Wrote ${files.length} file(s) to ${srcDir}`] };
|
|
126
|
+
}
|
|
127
|
+
function resolveMapping(args) {
|
|
128
|
+
if (args.sourcePackage !== undefined && args.targetPackage === undefined) {
|
|
129
|
+
return {
|
|
130
|
+
ok: false,
|
|
131
|
+
code: SOURCE_PACKAGE_ALONE,
|
|
132
|
+
message: "--source-package requires --target-package.",
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (args.targetPackage !== undefined) {
|
|
136
|
+
const sourcePackage = args.sourcePackage ?? sourcePackageFromSelector(args.selector);
|
|
137
|
+
if (sourcePackage === undefined) {
|
|
138
|
+
return {
|
|
139
|
+
ok: false,
|
|
140
|
+
code: SOURCE_PACKAGE_REQUIRED,
|
|
141
|
+
message: [
|
|
142
|
+
"--target-package needs a source package.",
|
|
143
|
+
"",
|
|
144
|
+
`The selector ${args.selector} is a single block, so the source root is not determined.`,
|
|
145
|
+
"",
|
|
146
|
+
"Specify --source-package.",
|
|
147
|
+
].join("\n"),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
ok: true,
|
|
152
|
+
mapping: { kind: "explicit", sourcePackage, targetPackage: args.targetPackage },
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
return { ok: true, mapping: { kind: "automatic" } };
|
|
156
|
+
}
|
|
157
|
+
function buildTargetOptions(config, mbLibPath, mapping) {
|
|
158
|
+
const configured = config.targetOptions?.[TARGET_NAME];
|
|
159
|
+
const nested = {};
|
|
160
|
+
if (configured !== null && typeof configured === "object") {
|
|
161
|
+
for (const [key, value] of Object.entries(configured)) {
|
|
162
|
+
if (key !== "sourcePackage" && key !== "targetPackage" && key !== "mbLibPath") {
|
|
163
|
+
nested[key] = value;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
nested.mbLibPath = mbLibPath;
|
|
168
|
+
if (mapping.kind === "explicit") {
|
|
169
|
+
nested.sourcePackage = mapping.sourcePackage;
|
|
170
|
+
nested.targetPackage = mapping.targetPackage;
|
|
171
|
+
}
|
|
172
|
+
return { [TARGET_NAME]: nested };
|
|
173
|
+
}
|
|
174
|
+
function resolveMbLibPath(rootDir, config) {
|
|
175
|
+
const configured = config.mbLibPath;
|
|
176
|
+
if (typeof configured === "string" && configured.length > 0) {
|
|
177
|
+
return resolve(rootDir, configured);
|
|
178
|
+
}
|
|
179
|
+
const nested = config.targetOptions?.[TARGET_NAME];
|
|
180
|
+
if (nested !== null && typeof nested === "object" && "mbLibPath" in nested) {
|
|
181
|
+
const fromTarget = nested.mbLibPath;
|
|
182
|
+
if (typeof fromTarget === "string" && fromTarget.length > 0) {
|
|
183
|
+
return resolve(rootDir, fromTarget);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
try {
|
|
187
|
+
const require = createRequire(import.meta.url);
|
|
188
|
+
return dirname(require.resolve("@machineblocks/core/package.json"));
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return undefined;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function withSourceMaps(files) {
|
|
195
|
+
const out = [];
|
|
196
|
+
for (const file of files) {
|
|
197
|
+
out.push({ path: file.path, content: file.content });
|
|
198
|
+
const sourceMap = file.sourceMap;
|
|
199
|
+
if (typeof sourceMap === "string") {
|
|
200
|
+
out.push({ path: `${file.path}.map`, content: sourceMap });
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return out;
|
|
204
|
+
}
|
|
205
|
+
function collision(code, target, firstSource, secondSource) {
|
|
206
|
+
return `${code}: ${target} is the target of both ${firstSource} and ${secondSource}.`;
|
|
207
|
+
}
|
|
208
|
+
function formatDiagnostic(diagnostic) {
|
|
209
|
+
const source = diagnostic.source;
|
|
210
|
+
const where = source?.file ? `${source.file}:${source.line}:${source.column} ` : "";
|
|
211
|
+
return `${where}${diagnostic.code}: ${diagnostic.message}`;
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=compile-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile-command.js","sourceRoot":"","sources":["../src/compile-command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAInE,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,wBAAgB,OAAO,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CAY5E"}
|
package/dist/execute.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { parseArgs } from "./args.js";
|
|
2
|
+
import { runCompile } from "./compile-command.js";
|
|
3
|
+
import { HELP } from "./help.js";
|
|
4
|
+
import { runValidate } from "./validate-command.js";
|
|
5
|
+
export function execute(argv, rootDir) {
|
|
6
|
+
const parsed = parseArgs(argv);
|
|
7
|
+
if (parsed.command === "help") {
|
|
8
|
+
return { code: 0, lines: [HELP] };
|
|
9
|
+
}
|
|
10
|
+
if (parsed.command === "usage") {
|
|
11
|
+
return { code: 2, lines: [parsed.message, "", HELP] };
|
|
12
|
+
}
|
|
13
|
+
if (parsed.command === "validate") {
|
|
14
|
+
return runValidate(parsed, rootDir);
|
|
15
|
+
}
|
|
16
|
+
return runCompile(parsed, rootDir);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=execute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAmB,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,UAAU,OAAO,CAAC,IAAuB,EAAE,OAAe;IAC9D,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,MAAM,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;QAC9B,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;IACpC,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;QAC/B,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;IACxD,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAClC,OAAO,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACrC,CAAC"}
|
package/dist/help.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const HELP = "Usage: machineblocks validate [file] [--all]\n machineblocks compile <source-selector> [--source-package <FQN>] [--target-package <FQN>]\n machineblocks --help\n\nvalidate\n Same project check as blockml validate. Does not write SCAD.\n\ncompile\n Renders selected Block and Set types to SCAD with machineblocks-v3-scad.\n The selector is a BlockML type selector: an exact FQN, pkg.*, or pkg.**.\n Output is written under the configured srcDir (default blocks).\n --target-package names a package root, not a directory.\n A package selector supplies the source root when --source-package is omitted.\n An exact block FQN does not.\n\nExit 0 success, 1 diagnostics, 2 usage or config.\nSearch, inspect, graph, and the other toolchain commands stay on blockml.\n";
|
|
2
|
+
export declare const COMPILE_HELP = "Usage: machineblocks compile <source-selector> [--source-package <FQN>] [--target-package <FQN>]\n machineblocks compile --help\n\n<source-selector> Block FQN, or a package selector ending in .* or .**\n--source-package Source package root for an explicit mapping\n--target-package Target package root. Not a directory and not one output file.\n";
|
|
3
|
+
//# sourceMappingURL=help.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,gxBAiBhB,CAAC;AAEF,eAAO,MAAM,YAAY,yWAMxB,CAAC"}
|
package/dist/help.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const HELP = `Usage: machineblocks validate [file] [--all]
|
|
2
|
+
machineblocks compile <source-selector> [--source-package <FQN>] [--target-package <FQN>]
|
|
3
|
+
machineblocks --help
|
|
4
|
+
|
|
5
|
+
validate
|
|
6
|
+
Same project check as blockml validate. Does not write SCAD.
|
|
7
|
+
|
|
8
|
+
compile
|
|
9
|
+
Renders selected Block and Set types to SCAD with machineblocks-v3-scad.
|
|
10
|
+
The selector is a BlockML type selector: an exact FQN, pkg.*, or pkg.**.
|
|
11
|
+
Output is written under the configured srcDir (default blocks).
|
|
12
|
+
--target-package names a package root, not a directory.
|
|
13
|
+
A package selector supplies the source root when --source-package is omitted.
|
|
14
|
+
An exact block FQN does not.
|
|
15
|
+
|
|
16
|
+
Exit 0 success, 1 diagnostics, 2 usage or config.
|
|
17
|
+
Search, inspect, graph, and the other toolchain commands stay on blockml.
|
|
18
|
+
`;
|
|
19
|
+
export const COMPILE_HELP = `Usage: machineblocks compile <source-selector> [--source-package <FQN>] [--target-package <FQN>]
|
|
20
|
+
machineblocks compile --help
|
|
21
|
+
|
|
22
|
+
<source-selector> Block FQN, or a package selector ending in .* or .**
|
|
23
|
+
--source-package Source package root for an explicit mapping
|
|
24
|
+
--target-package Target package root. Not a directory and not one output file.
|
|
25
|
+
`;
|
|
26
|
+
//# sourceMappingURL=help.js.map
|
package/dist/help.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;CAiBnB,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;CAM3B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAmB,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface OutputPath {
|
|
2
|
+
ok: true;
|
|
3
|
+
absolutePath: string;
|
|
4
|
+
}
|
|
5
|
+
export interface OutputPathFailure {
|
|
6
|
+
ok: false;
|
|
7
|
+
code: string;
|
|
8
|
+
message: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function resolveOutputPath(srcDir: string, filePath: string): OutputPath | OutputPathFailure;
|
|
11
|
+
//# sourceMappingURL=output-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-gate.d.ts","sourceRoot":"","sources":["../src/output-gate.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,IAAI,CAAC;IACT,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,KAAK,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,iBAAiB,CAiClG"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { existsSync, lstatSync, realpathSync } from "node:fs";
|
|
2
|
+
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
3
|
+
import { OUTPUT_ESCAPES_SRC, OUTPUT_OVERWRITES_BML } from "@machineblocks/render-target";
|
|
4
|
+
export function resolveOutputPath(srcDir, filePath) {
|
|
5
|
+
const srcReal = realpathSync(srcDir);
|
|
6
|
+
const portable = filePath.replaceAll("\\", "/");
|
|
7
|
+
if (portable.length === 0 || isAbsolute(filePath) || portable.split("/").includes("..")) {
|
|
8
|
+
return {
|
|
9
|
+
ok: false,
|
|
10
|
+
code: OUTPUT_ESCAPES_SRC,
|
|
11
|
+
message: `${filePath} is outside ${srcReal}.`,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const absolute = resolve(srcReal, portable);
|
|
15
|
+
if (!isInside(srcReal, absolute)) {
|
|
16
|
+
return {
|
|
17
|
+
ok: false,
|
|
18
|
+
code: OUTPUT_ESCAPES_SRC,
|
|
19
|
+
message: `${filePath} is outside ${srcReal}.`,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
if (symlinkEscapes(srcReal, absolute)) {
|
|
23
|
+
return {
|
|
24
|
+
ok: false,
|
|
25
|
+
code: OUTPUT_ESCAPES_SRC,
|
|
26
|
+
message: `${filePath} resolves outside ${srcReal}.`,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (overwritesBml(absolute)) {
|
|
30
|
+
return {
|
|
31
|
+
ok: false,
|
|
32
|
+
code: OUTPUT_OVERWRITES_BML,
|
|
33
|
+
message: `${filePath} would overwrite a .bml file.`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return { ok: true, absolutePath: absolute };
|
|
37
|
+
}
|
|
38
|
+
function symlinkEscapes(srcReal, absolute) {
|
|
39
|
+
let existing = absolute;
|
|
40
|
+
while (!existsSync(existing)) {
|
|
41
|
+
const parent = dirname(existing);
|
|
42
|
+
if (parent === existing) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
existing = parent;
|
|
46
|
+
}
|
|
47
|
+
const realExisting = realpathSync(existing);
|
|
48
|
+
if (!isInside(srcReal, realExisting)) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
if (existsSync(absolute)) {
|
|
52
|
+
const stat = lstatSync(absolute);
|
|
53
|
+
if (stat.isSymbolicLink() && !isInside(srcReal, realpathSync(absolute))) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
function overwritesBml(absolute) {
|
|
60
|
+
if (!existsSync(absolute)) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
if (absolute.endsWith(".bml")) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
const stat = lstatSync(absolute);
|
|
67
|
+
if (!stat.isSymbolicLink()) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
return realpathSync(absolute).endsWith(".bml");
|
|
71
|
+
}
|
|
72
|
+
function isInside(root, candidate) {
|
|
73
|
+
const fromRoot = relative(root, candidate);
|
|
74
|
+
return fromRoot === "" || (!fromRoot.startsWith("..") && !isAbsolute(fromRoot));
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=output-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-gate.js","sourceRoot":"","sources":["../src/output-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-command.d.ts","sourceRoot":"","sources":["../src/validate-command.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CA8B3E"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { loadConfig } from "@blockml/cli";
|
|
4
|
+
import { compileBmlToBom, validateRegistryDocuments } from "@blockml/compiler";
|
|
5
|
+
import { bootstrapFullProjectRegistry, projectSourceRoots, registryFilesUnderRoots, rootFqnByFilePath, } from "@blockml/framework";
|
|
6
|
+
export function runValidate(args, rootDir) {
|
|
7
|
+
let config;
|
|
8
|
+
try {
|
|
9
|
+
config = loadConfig(rootDir);
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
return { code: 2, lines: [error instanceof Error ? error.message : String(error)] };
|
|
13
|
+
}
|
|
14
|
+
const srcDir = config.srcDir ?? "blocks";
|
|
15
|
+
const bootstrap = bootstrapFullProjectRegistry({
|
|
16
|
+
rootDir,
|
|
17
|
+
srcDir,
|
|
18
|
+
libraries: config.libraries ?? [],
|
|
19
|
+
});
|
|
20
|
+
if (args.file !== undefined) {
|
|
21
|
+
const filePath = resolve(rootDir, args.file);
|
|
22
|
+
if (!existsSync(filePath)) {
|
|
23
|
+
return { code: 2, lines: [`File not found: ${args.file}`] };
|
|
24
|
+
}
|
|
25
|
+
const parsed = compileBmlToBom({ source: readFileSync(filePath, "utf8"), filePath }, { typeRegistry: bootstrap.registry, rootDir });
|
|
26
|
+
return outcome([...bootstrap.diagnostics, ...parsed.diagnostics], 1);
|
|
27
|
+
}
|
|
28
|
+
const registryFiles = [...rootFqnByFilePath(bootstrap.registry).keys()];
|
|
29
|
+
const files = args.all
|
|
30
|
+
? registryFiles
|
|
31
|
+
: registryFilesUnderRoots(bootstrap.registry, projectSourceRoots(rootDir, srcDir));
|
|
32
|
+
const validated = validateRegistryDocuments(bootstrap.registry, files);
|
|
33
|
+
return outcome([...bootstrap.diagnostics, ...validated.diagnostics], validated.blocksTested);
|
|
34
|
+
}
|
|
35
|
+
function outcome(diagnostics, blocksTested) {
|
|
36
|
+
const failed = diagnostics.some((diagnostic) => diagnostic.severity === "error");
|
|
37
|
+
const lines = diagnostics.map((diagnostic) => {
|
|
38
|
+
const source = diagnostic.source;
|
|
39
|
+
const where = source?.file ? `${source.file}:${source.line}:${source.column} ` : "";
|
|
40
|
+
return `${where}${diagnostic.code}: ${diagnostic.message}`;
|
|
41
|
+
});
|
|
42
|
+
lines.push(failed
|
|
43
|
+
? `Validated ${blocksTested} block(s) with errors.`
|
|
44
|
+
: `Validated ${blocksTested} block(s).`);
|
|
45
|
+
return { code: failed ? 1 : 0, lines };
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=validate-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-command.js","sourceRoot":"","sources":["../src/validate-command.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@machineblocks/cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MachineBlocks host CLI — simplified BlockML entry that renders BML to SCAD",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"bin": {
|
|
11
|
+
"machineblocks": "./dist/cli.js"
|
|
12
|
+
},
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"blockml": {
|
|
15
|
+
"library": "./blocks/com/machineblocks/bml/cli/Library.bml"
|
|
16
|
+
},
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"blocks"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc --build",
|
|
29
|
+
"prepublishOnly": "npm run build",
|
|
30
|
+
"test": "vitest run --root ../.. packages/machineblocks-cli/test"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@blockml/block-render-engine": "^0.1.0",
|
|
34
|
+
"@blockml/cli": "^0.9.13",
|
|
35
|
+
"@blockml/compiler": "^0.9.13",
|
|
36
|
+
"@blockml/core": "^1.4.2",
|
|
37
|
+
"@blockml/framework": "^0.9.13",
|
|
38
|
+
"@machineblocks/core": "^3.0.0-A4",
|
|
39
|
+
"@machineblocks/render-target": "^0.1.0"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=20"
|
|
43
|
+
}
|
|
44
|
+
}
|
package/README.md
DELETED