@nodegx/export 0.0.0-stage โ†’ 0.2.6

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 (53) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +76 -2
  3. package/dist/analyze/appState.d.ts +303 -0
  4. package/dist/analyze/plan.d.ts +3904 -0
  5. package/dist/analyze/querySettings.d.ts +75 -0
  6. package/dist/analyze/reach.d.ts +41 -0
  7. package/dist/analyze/scriptUses.d.ts +29 -0
  8. package/dist/catalog.d.ts +129 -0
  9. package/dist/cli/args.d.ts +100 -0
  10. package/dist/cli/exitCodes.d.ts +125 -0
  11. package/dist/cli/run.d.ts +30 -0
  12. package/dist/cli.inputs.json +203 -0
  13. package/dist/cli.mjs +62547 -0
  14. package/dist/cli.mjs.map +7 -0
  15. package/dist/emit/animateLib.d.ts +43 -0
  16. package/dist/emit/component.d.ts +166 -0
  17. package/dist/emit/dateLib.d.ts +45 -0
  18. package/dist/emit/emitApp.d.ts +38 -0
  19. package/dist/emit/idLib.d.ts +68 -0
  20. package/dist/emit/kits.d.ts +91 -0
  21. package/dist/emit/mediaLib.d.ts +75 -0
  22. package/dist/emit/naming.d.ts +76 -0
  23. package/dist/emit/parseLib.d.ts +108 -0
  24. package/dist/emit/preflight.d.ts +174 -0
  25. package/dist/emit/readme.d.ts +51 -0
  26. package/dist/emit/report.d.ts +309 -0
  27. package/dist/emit/scaffold.d.ts +83 -0
  28. package/dist/emit/statesLib.d.ts +52 -0
  29. package/dist/emit/style.d.ts +181 -0
  30. package/dist/emit/utilLib.d.ts +78 -0
  31. package/dist/errorMessage.d.ts +28 -0
  32. package/dist/index.cjs +61649 -0
  33. package/dist/index.cjs.map +7 -0
  34. package/dist/index.d.ts +37 -0
  35. package/dist/index.mjs +61570 -0
  36. package/dist/index.mjs.map +7 -0
  37. package/dist/ir/types.d.ts +567 -0
  38. package/dist/ledger.cjs +971 -0
  39. package/dist/ledger.cjs.map +7 -0
  40. package/dist/ledger.d.ts +75 -0
  41. package/dist/ledger.mjs +948 -0
  42. package/dist/ledger.mjs.map +7 -0
  43. package/dist/node-catalog.json +65370 -0
  44. package/dist/parse/kitSource.d.ts +135 -0
  45. package/dist/parse/parseModules.d.ts +42 -0
  46. package/dist/parse/parseProject.d.ts +13 -0
  47. package/dist/react19/VERSION +2 -0
  48. package/dist/react19/react-dom.production.min.js +51 -0
  49. package/dist/react19/react.production.min.js +21 -0
  50. package/dist/scriptFiles.d.ts +30 -0
  51. package/dist/structurePorts.d.ts +70 -0
  52. package/dist/write/writeExport.d.ts +67 -0
  53. package/package.json +53 -4
@@ -0,0 +1,70 @@
1
+ /**
2
+ * The export's defer tables, and the type โ†’ render-role map above them.
3
+ *
4
+ * ๐Ÿ”ด **These live outside `analyze/plan.ts` because a second reader needs them.** FLD-013 (#37):
5
+ * an agent choosing nodes for an app it intends to export asks `get_node_type` *before* it
6
+ * designs, and the only honest answer to *"will this node export?"* is per **parameter source**,
7
+ * not per type. `Circle` is `status: "translated"` in the coverage ledger and still refuses on a
8
+ * wire into any of thirteen ports โ€” so the ledger status alone, which is what #37 asked for, would
9
+ * have read green on the exact node that produced the twenty-three refusals it was filed about.
10
+ *
11
+ * `noodl-mcp` reads these through `@nodegx/export`'s index; `plan.ts` imports them back and
12
+ * remains their only writer. **Moved out of `plan.ts`, not copied into a second file** โ€” this repo
13
+ * has already paid for a second copy of a table that drifted.
14
+ */
15
+ import type { RenderRole } from './analyze/plan';
16
+ /**
17
+ * Ports whose value shapes the emitted *structure* (tracks, options, marks, initial state) โ€”
18
+ * a wire into one means the node's static translation would lie, so the node defers whole
19
+ * (VISUALS-TARGET). Ports that merely carry content (src, label text) stay bindable.
20
+ */
21
+ export declare const STRUCTURE_PORTS: Partial<Record<RenderRole, string[]>>;
22
+ /**
23
+ * Ports that carry *content* into a control โ€” text, bounds, increments. A wire into one does
24
+ * not move the rendered structure: `label` is the single text child of `<label>`
25
+ * (Checkbox.tsx:191, RadioButton.tsx:200) and `min`/`max`/`step` are plain attributes the
26
+ * emitter already orders (CONTENT_ATTR_ORDER), with nothing in the emitted CSS derived from
27
+ * them (style.ts's `range` rule reads `thumbColor` and `width` only).
28
+ *
29
+ * They still defer, because omitting an unknown bound renders a 0โ€“100 slider where the running
30
+ * app renders the row's โ€” wrong output, confidently emitted. But the wall is the *source*, not
31
+ * the port, and every one of them in the corpus resolves to one of the two walls already on the
32
+ * list: a `Model2` row property, or a component-record property only a runtime script writes.
33
+ * Naming the source is what lets the census group them there instead of inventing a third wall
34
+ * (RECORD-VERBS ยง19).
35
+ */
36
+ export declare const CONTENT_BOUND_PORTS: Partial<Record<RenderRole, string[]>>;
37
+ /**
38
+ * Type name โ†’ render role, for every type whose role is fixed by its name.
39
+ *
40
+ * ๐Ÿ”ด **This is `renderRole`'s switch, moved.** It was a `switch (node.type)` inside `plan.ts` and
41
+ * nothing outside the exporter could read it, which left the MCP server with no way to say which
42
+ * ports a *named* type refuses on. `plan.ts` now looks the answer up here, so there is one table
43
+ * and not two. The three cases the switch decides before consulting a name โ€” a component instance
44
+ * (`/`-prefixed), a kit node, and the `catalog.isVisual` fallback โ€” stay in `renderRole`, because
45
+ * they are decided by the graph and the catalog rather than by the type name.
46
+ *
47
+ * `null` is a real answer and not a miss: a `Router` has a role of none, exactly as a `Variable`
48
+ * does. Callers must distinguish `null` (this type draws nothing) from `undefined` (this table
49
+ * does not decide this type).
50
+ */
51
+ export declare const ROLE_OF_TYPE: Readonly<Partial<Record<string, RenderRole | null>>>;
52
+ /**
53
+ * The ports of a named type that shape its emitted structure โ€” *"a wire into any of these and this
54
+ * node is left out of the export"*.
55
+ *
56
+ * Always an array, never `undefined`, for a type this table decides: **an empty list and an absent
57
+ * field are different answers**, and a caller that cannot tell them apart learns nothing from the
58
+ * empty one.
59
+ */
60
+ export declare function structurePortsOf(typeName: string): string[];
61
+ /**
62
+ * The ports of a named type that carry *content* into a control and still refuse it.
63
+ *
64
+ * ๐Ÿ”ด **Reported apart from {@link structurePortsOf} because they are not the same claim.** A wire
65
+ * into `Range.min` does not move the rendered structure โ€” the node is left out because the bound
66
+ * is not statically known and a 0โ€“100 slider is the wrong output, confidently emitted. Folding
67
+ * these into a field called `structurePorts` would tell an agent something about this product that
68
+ * is not true; the consequence is identical, the reason is not.
69
+ */
70
+ export declare function contentPortsOf(typeName: string): string[];
@@ -0,0 +1,67 @@
1
+ /**
2
+ * The half of the code export that touches the disk โ€” every file written, every asset copied,
3
+ * and the one refusal that has to happen before any of it.
4
+ *
5
+ * `emitApp` is pure: it returns generated strings (`files`) and a list of project assets to copy
6
+ * byte-for-byte (`copies`), and writes nothing. This module is the caller that writes. It takes
7
+ * `fs` as an argument rather than importing it, which is what lets the same code run under the
8
+ * editor's renderer, under a plain-Node CLI, and against a real temp directory in a spec.
9
+ *
10
+ * ## Why it lives in the package (HLS-002)
11
+ *
12
+ * It was written for EXP-012 inside `noodl-editor`, as the disk half of the editor's menu item.
13
+ * HLS-002 gives the export a second front door โ€” `nodegx export` โ€” and the whole point of that
14
+ * task is that the two doors produce the *same* export. Two copies of the write loop is the
15
+ * cheapest way to make that untrue, and the copy that would drift is the one nobody clicks:
16
+ * `scripts/emit-app.ts` had its own write loop and dropped `copies` on the floor for a whole
17
+ * phase (P18 ยง19.6) while every gate stayed green. So there is one write loop now, here, and
18
+ * both doors call it.
19
+ *
20
+ * ๐Ÿ”ด **`copies` is a second channel.** `files` are strings and `copies` are bytes โ€” a kit's
21
+ * script, an icon set's `.woff2`, Inter's four `.ttf`. They are separate precisely *because* a
22
+ * font is not a string: reading one into UTF-8 to put it in `files` corrupts it silently, and the
23
+ * failure renders as blank glyphs rather than as an error. Both counts are reported so a caller
24
+ * can say what it did.
25
+ *
26
+ * ๐Ÿ”ด **The target may not be inside the project.** The editor's loader reads every file under the
27
+ * project directory with no skip list (P82: `readBundleDirectory`), and the MCP server's scanner
28
+ * walks it too โ€” an export dropped into the project would be read back as project content on the
29
+ * next open. `checkTarget` refuses that before anything is written.
30
+ */
31
+ import type * as fsType from 'fs';
32
+ /** The shape `emitApp` returns; structural, so this module does not import the package. */
33
+ export interface ExportOutput {
34
+ /** Output-relative path โ†’ generated content. */
35
+ files: Record<string, string>;
36
+ /** Project-relative source โ†’ output-relative destination, copied byte-for-byte. */
37
+ copies: ReadonlyArray<{
38
+ from: string;
39
+ to: string;
40
+ }>;
41
+ }
42
+ export type FsLike = Pick<typeof fsType, 'existsSync' | 'readdirSync' | 'mkdirSync' | 'writeFileSync' | 'copyFileSync' | 'statSync'>;
43
+ export type TargetVerdict = {
44
+ ok: true; /** Entries already in the folder; > 0 means the caller should confirm. */
45
+ existing: number;
46
+ } | {
47
+ ok: false;
48
+ reason: string;
49
+ };
50
+ /**
51
+ * Whether `outDir` is a folder the export may write into. Refuses the project directory and
52
+ * anything under it; otherwise reports how many entries the folder already holds so the caller
53
+ * can ask before overwriting.
54
+ */
55
+ export declare function checkTarget(projectDir: string, outDir: string, fs: FsLike): TargetVerdict;
56
+ export interface WriteResult {
57
+ files: number;
58
+ copies: number;
59
+ }
60
+ /**
61
+ * Writes an emitted app into `outDir`: every generated file, then every asset copy. Existing
62
+ * files with the same names are overwritten; nothing else in the folder is touched.
63
+ *
64
+ * Throws on the first failed write โ€” the caller reports it as a part-way failure rather than a
65
+ * success with a smaller number, because a folder that is half an app builds nothing.
66
+ */
67
+ export declare function writeExport(projectDir: string, outDir: string, output: ExportOutput, fs: FsLike): WriteResult;
package/package.json CHANGED
@@ -1,6 +1,55 @@
1
1
  {
2
2
  "name": "@nodegx/export",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.6",
4
+ "description": "Export a NodeGX project as source you own: a React + Vite app, or plain HTML, CSS and JavaScript files any static server serves.",
5
+ "author": "The Low Code Foundation <contact@thelowcodefoundation.com>",
6
+ "license": "GPL-3.0",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/The-Low-Code-Foundation/NodeGX.git",
10
+ "directory": "packages/nodegx-export"
11
+ },
12
+ "bin": {
13
+ "nodegx": "./dist/cli.mjs"
14
+ },
15
+ "main": "./dist/index.cjs",
16
+ "module": "./dist/index.mjs",
17
+ "types": "./dist/index.d.ts",
18
+ "sideEffects": false,
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.mjs",
23
+ "require": "./dist/index.cjs"
24
+ },
25
+ "./ledger": {
26
+ "types": "./dist/ledger.d.ts",
27
+ "import": "./dist/ledger.mjs",
28
+ "require": "./dist/ledger.cjs"
29
+ },
30
+ "./package.json": "./package.json"
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "README.md"
35
+ ],
36
+ "engines": {
37
+ "node": ">=22"
38
+ },
39
+ "scripts": {
40
+ "build": "node build.mjs",
41
+ "test": "jest",
42
+ "typecheck": "tsc --noEmit"
43
+ },
44
+ "devDependencies": {
45
+ "@nodegx/module-inject": "file:../nodegx-module-inject",
46
+ "@nodegx/project-contract": "file:../nodegx-project-contract",
47
+ "@noodl/backend-contract": "file:../nodegx-backend-contract",
48
+ "@types/jest": "^29.0.1",
49
+ "jest": "^29.7.0",
50
+ "ts-jest": "^29.4.1"
51
+ },
52
+ "publishConfig": {
53
+ "access": "public"
54
+ }
55
+ }