@json-render/codegen 0.4.2 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -4,7 +4,7 @@ import { Spec, UIElement } from '@json-render/core';
4
4
  * Visitor function for spec traversal
5
5
  */
6
6
  interface TreeVisitor {
7
- (element: UIElement, depth: number, parent: UIElement | null): void;
7
+ (element: UIElement, key: string, depth: number, parent: UIElement | null): void;
8
8
  }
9
9
  /**
10
10
  * Traverse a UI spec depth-first
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ import { Spec, UIElement } from '@json-render/core';
4
4
  * Visitor function for spec traversal
5
5
  */
6
6
  interface TreeVisitor {
7
- (element: UIElement, depth: number, parent: UIElement | null): void;
7
+ (element: UIElement, key: string, depth: number, parent: UIElement | null): void;
8
8
  }
9
9
  /**
10
10
  * Traverse a UI spec depth-first
package/dist/index.js CHANGED
@@ -39,7 +39,7 @@ function traverseSpec(spec, visitor, startKey) {
39
39
  function visit(key, depth, parent) {
40
40
  const element = spec.elements[key];
41
41
  if (!element) return;
42
- visitor(element, depth, parent);
42
+ visitor(element, key, depth, parent);
43
43
  if (element.children) {
44
44
  for (const childKey of element.children) {
45
45
  visit(childKey, depth + 1, element);
@@ -50,14 +50,14 @@ function traverseSpec(spec, visitor, startKey) {
50
50
  }
51
51
  function collectUsedComponents(spec) {
52
52
  const components = /* @__PURE__ */ new Set();
53
- traverseSpec(spec, (element) => {
53
+ traverseSpec(spec, (element, _key) => {
54
54
  components.add(element.type);
55
55
  });
56
56
  return components;
57
57
  }
58
58
  function collectDataPaths(spec) {
59
59
  const paths = /* @__PURE__ */ new Set();
60
- traverseSpec(spec, (element) => {
60
+ traverseSpec(spec, (element, _key) => {
61
61
  for (const [propName, propValue] of Object.entries(element.props)) {
62
62
  if (typeof propValue === "string") {
63
63
  if (propName.endsWith("Path") || propName === "bindPath" || propName === "dataPath") {
@@ -105,7 +105,7 @@ function collectPathsFromCondition(condition, paths) {
105
105
  }
106
106
  function collectActions(spec) {
107
107
  const actions = /* @__PURE__ */ new Set();
108
- traverseSpec(spec, (element) => {
108
+ traverseSpec(spec, (element, _key) => {
109
109
  for (const propValue of Object.values(element.props)) {
110
110
  if (typeof propValue === "string" && propValue.startsWith("action:")) {
111
111
  actions.add(propValue.slice(7));
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/traverse.ts","../src/serialize.ts"],"sourcesContent":["export {\n traverseSpec,\n collectUsedComponents,\n collectDataPaths,\n collectActions,\n type TreeVisitor,\n} from \"./traverse\";\n\nexport {\n serializePropValue,\n serializeProps,\n escapeString,\n type SerializeOptions,\n} from \"./serialize\";\n\nexport type { GeneratedFile, CodeGenerator } from \"./types\";\n","import type { Spec, UIElement } from \"@json-render/core\";\n\n/**\n * Visitor function for spec traversal\n */\nexport interface TreeVisitor {\n (element: UIElement, depth: number, parent: UIElement | null): void;\n}\n\n/**\n * Traverse a UI spec depth-first\n */\nexport function traverseSpec(\n spec: Spec,\n visitor: TreeVisitor,\n startKey?: string,\n): void {\n if (!spec || !spec.root) return;\n\n const rootKey = startKey ?? spec.root;\n const rootElement = spec.elements[rootKey];\n if (!rootElement) return;\n\n function visit(key: string, depth: number, parent: UIElement | null): void {\n const element = spec.elements[key];\n if (!element) return;\n\n visitor(element, depth, parent);\n\n if (element.children) {\n for (const childKey of element.children) {\n visit(childKey, depth + 1, element);\n }\n }\n }\n\n visit(rootKey, 0, null);\n}\n\n/**\n * Collect all unique component types used in a spec\n */\nexport function collectUsedComponents(spec: Spec): Set<string> {\n const components = new Set<string>();\n\n traverseSpec(spec, (element) => {\n components.add(element.type);\n });\n\n return components;\n}\n\n/**\n * Collect all data paths referenced in a spec\n */\nexport function collectDataPaths(spec: Spec): Set<string> {\n const paths = new Set<string>();\n\n traverseSpec(spec, (element) => {\n // Check props for data paths\n for (const [propName, propValue] of Object.entries(element.props)) {\n // Check for path props (e.g., valuePath, dataPath, bindPath)\n if (typeof propValue === \"string\") {\n if (\n propName.endsWith(\"Path\") ||\n propName === \"bindPath\" ||\n propName === \"dataPath\"\n ) {\n paths.add(propValue);\n }\n }\n\n // Check for dynamic value objects with path\n if (\n propValue &&\n typeof propValue === \"object\" &&\n \"path\" in propValue &&\n typeof (propValue as { path: unknown }).path === \"string\"\n ) {\n paths.add((propValue as { path: string }).path);\n }\n }\n\n // Check visibility conditions for paths\n if (element.visible && typeof element.visible === \"object\") {\n collectPathsFromCondition(element.visible, paths);\n }\n });\n\n return paths;\n}\n\nfunction collectPathsFromCondition(\n condition: unknown,\n paths: Set<string>,\n): void {\n if (!condition || typeof condition !== \"object\") return;\n\n const cond = condition as Record<string, unknown>;\n\n if (\"path\" in cond && typeof cond.path === \"string\") {\n paths.add(cond.path);\n }\n\n if (\"and\" in cond && Array.isArray(cond.and)) {\n for (const sub of cond.and) {\n collectPathsFromCondition(sub, paths);\n }\n }\n\n if (\"or\" in cond && Array.isArray(cond.or)) {\n for (const sub of cond.or) {\n collectPathsFromCondition(sub, paths);\n }\n }\n\n if (\"not\" in cond) {\n collectPathsFromCondition(cond.not, paths);\n }\n\n // Check comparison operators\n for (const op of [\"eq\", \"neq\", \"gt\", \"gte\", \"lt\", \"lte\"]) {\n if (op in cond && Array.isArray(cond[op])) {\n for (const operand of cond[op] as unknown[]) {\n if (\n operand &&\n typeof operand === \"object\" &&\n \"path\" in operand &&\n typeof (operand as { path: unknown }).path === \"string\"\n ) {\n paths.add((operand as { path: string }).path);\n }\n }\n }\n }\n}\n\n/**\n * Collect all action names used in a spec\n */\nexport function collectActions(spec: Spec): Set<string> {\n const actions = new Set<string>();\n\n traverseSpec(spec, (element) => {\n for (const propValue of Object.values(element.props)) {\n // Check for action prop (string action name)\n if (typeof propValue === \"string\" && propValue.startsWith(\"action:\")) {\n actions.add(propValue.slice(7));\n }\n\n // Check for action objects\n if (\n propValue &&\n typeof propValue === \"object\" &&\n \"name\" in propValue &&\n typeof (propValue as { name: unknown }).name === \"string\"\n ) {\n actions.add((propValue as { name: string }).name);\n }\n }\n\n // Also check direct action prop\n const actionProp = element.props.action;\n if (typeof actionProp === \"string\") {\n actions.add(actionProp);\n }\n });\n\n return actions;\n}\n","/**\n * Options for serialization\n */\nexport interface SerializeOptions {\n /** Quote style for strings */\n quotes?: \"single\" | \"double\";\n /** Indent for objects/arrays */\n indent?: number;\n}\n\nconst DEFAULT_OPTIONS: Required<SerializeOptions> = {\n quotes: \"double\",\n indent: 2,\n};\n\n/**\n * Escape a string for use in code\n */\nexport function escapeString(\n str: string,\n quotes: \"single\" | \"double\" = \"double\",\n): string {\n const quoteChar = quotes === \"single\" ? \"'\" : '\"';\n const escaped = str\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\t/g, \"\\\\t\");\n\n if (quotes === \"single\") {\n return escaped.replace(/'/g, \"\\\\'\");\n }\n return escaped.replace(/\"/g, '\\\\\"');\n}\n\n/**\n * Serialize a single prop value to a code string\n *\n * @returns Object with `value` (the serialized string) and `needsBraces` (whether JSX needs {})\n */\nexport function serializePropValue(\n value: unknown,\n options: SerializeOptions = {},\n): { value: string; needsBraces: boolean } {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const q = opts.quotes === \"single\" ? \"'\" : '\"';\n\n if (value === null) {\n return { value: \"null\", needsBraces: true };\n }\n\n if (value === undefined) {\n return { value: \"undefined\", needsBraces: true };\n }\n\n if (typeof value === \"string\") {\n return {\n value: `${q}${escapeString(value, opts.quotes)}${q}`,\n needsBraces: false,\n };\n }\n\n if (typeof value === \"number\") {\n return { value: String(value), needsBraces: true };\n }\n\n if (typeof value === \"boolean\") {\n if (value === true) {\n return { value: \"true\", needsBraces: false }; // Can use shorthand\n }\n return { value: \"false\", needsBraces: true };\n }\n\n if (Array.isArray(value)) {\n const items = value.map((v) => serializePropValue(v, opts).value);\n return { value: `[${items.join(\", \")}]`, needsBraces: true };\n }\n\n if (typeof value === \"object\") {\n // Check for path reference\n if (\n \"path\" in value &&\n typeof (value as { path: unknown }).path === \"string\"\n ) {\n return {\n value: `{ path: ${q}${escapeString((value as { path: string }).path, opts.quotes)}${q} }`,\n needsBraces: true,\n };\n }\n\n const entries = Object.entries(value)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => {\n const serialized = serializePropValue(v, opts).value;\n // Use shorthand if key matches value for simple identifiers\n return `${k}: ${serialized}`;\n });\n\n return { value: `{ ${entries.join(\", \")} }`, needsBraces: true };\n }\n\n return { value: String(value), needsBraces: true };\n}\n\n/**\n * Serialize props object to JSX attributes string\n */\nexport function serializeProps(\n props: Record<string, unknown>,\n options: SerializeOptions = {},\n): string {\n const parts: string[] = [];\n\n for (const [key, value] of Object.entries(props)) {\n if (value === undefined || value === null) continue;\n\n const serialized = serializePropValue(value, options);\n\n // Boolean true can be shorthand\n if (typeof value === \"boolean\" && value === true) {\n parts.push(key);\n } else if (serialized.needsBraces) {\n parts.push(`${key}={${serialized.value}}`);\n } else {\n parts.push(`${key}=${serialized.value}`);\n }\n }\n\n return parts.join(\" \");\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/traverse.ts","../src/serialize.ts"],"sourcesContent":["export {\n traverseSpec,\n collectUsedComponents,\n collectDataPaths,\n collectActions,\n type TreeVisitor,\n} from \"./traverse\";\n\nexport {\n serializePropValue,\n serializeProps,\n escapeString,\n type SerializeOptions,\n} from \"./serialize\";\n\nexport type { GeneratedFile, CodeGenerator } from \"./types\";\n","import type { Spec, UIElement } from \"@json-render/core\";\n\n/**\n * Visitor function for spec traversal\n */\nexport interface TreeVisitor {\n (\n element: UIElement,\n key: string,\n depth: number,\n parent: UIElement | null,\n ): void;\n}\n\n/**\n * Traverse a UI spec depth-first\n */\nexport function traverseSpec(\n spec: Spec,\n visitor: TreeVisitor,\n startKey?: string,\n): void {\n if (!spec || !spec.root) return;\n\n const rootKey = startKey ?? spec.root;\n const rootElement = spec.elements[rootKey];\n if (!rootElement) return;\n\n function visit(key: string, depth: number, parent: UIElement | null): void {\n const element = spec.elements[key];\n if (!element) return;\n\n visitor(element, key, depth, parent);\n\n if (element.children) {\n for (const childKey of element.children) {\n visit(childKey, depth + 1, element);\n }\n }\n }\n\n visit(rootKey, 0, null);\n}\n\n/**\n * Collect all unique component types used in a spec\n */\nexport function collectUsedComponents(spec: Spec): Set<string> {\n const components = new Set<string>();\n\n traverseSpec(spec, (element, _key) => {\n components.add(element.type);\n });\n\n return components;\n}\n\n/**\n * Collect all data paths referenced in a spec\n */\nexport function collectDataPaths(spec: Spec): Set<string> {\n const paths = new Set<string>();\n\n traverseSpec(spec, (element, _key) => {\n // Check props for data paths\n for (const [propName, propValue] of Object.entries(element.props)) {\n // Check for path props (e.g., valuePath, dataPath, bindPath)\n if (typeof propValue === \"string\") {\n if (\n propName.endsWith(\"Path\") ||\n propName === \"bindPath\" ||\n propName === \"dataPath\"\n ) {\n paths.add(propValue);\n }\n }\n\n // Check for dynamic value objects with path\n if (\n propValue &&\n typeof propValue === \"object\" &&\n \"path\" in propValue &&\n typeof (propValue as { path: unknown }).path === \"string\"\n ) {\n paths.add((propValue as { path: string }).path);\n }\n }\n\n // Check visibility conditions for paths\n if (element.visible && typeof element.visible === \"object\") {\n collectPathsFromCondition(element.visible, paths);\n }\n });\n\n return paths;\n}\n\nfunction collectPathsFromCondition(\n condition: unknown,\n paths: Set<string>,\n): void {\n if (!condition || typeof condition !== \"object\") return;\n\n const cond = condition as Record<string, unknown>;\n\n if (\"path\" in cond && typeof cond.path === \"string\") {\n paths.add(cond.path);\n }\n\n if (\"and\" in cond && Array.isArray(cond.and)) {\n for (const sub of cond.and) {\n collectPathsFromCondition(sub, paths);\n }\n }\n\n if (\"or\" in cond && Array.isArray(cond.or)) {\n for (const sub of cond.or) {\n collectPathsFromCondition(sub, paths);\n }\n }\n\n if (\"not\" in cond) {\n collectPathsFromCondition(cond.not, paths);\n }\n\n // Check comparison operators\n for (const op of [\"eq\", \"neq\", \"gt\", \"gte\", \"lt\", \"lte\"]) {\n if (op in cond && Array.isArray(cond[op])) {\n for (const operand of cond[op] as unknown[]) {\n if (\n operand &&\n typeof operand === \"object\" &&\n \"path\" in operand &&\n typeof (operand as { path: unknown }).path === \"string\"\n ) {\n paths.add((operand as { path: string }).path);\n }\n }\n }\n }\n}\n\n/**\n * Collect all action names used in a spec\n */\nexport function collectActions(spec: Spec): Set<string> {\n const actions = new Set<string>();\n\n traverseSpec(spec, (element, _key) => {\n for (const propValue of Object.values(element.props)) {\n // Check for action prop (string action name)\n if (typeof propValue === \"string\" && propValue.startsWith(\"action:\")) {\n actions.add(propValue.slice(7));\n }\n\n // Check for action objects\n if (\n propValue &&\n typeof propValue === \"object\" &&\n \"name\" in propValue &&\n typeof (propValue as { name: unknown }).name === \"string\"\n ) {\n actions.add((propValue as { name: string }).name);\n }\n }\n\n // Also check direct action prop\n const actionProp = element.props.action;\n if (typeof actionProp === \"string\") {\n actions.add(actionProp);\n }\n });\n\n return actions;\n}\n","/**\n * Options for serialization\n */\nexport interface SerializeOptions {\n /** Quote style for strings */\n quotes?: \"single\" | \"double\";\n /** Indent for objects/arrays */\n indent?: number;\n}\n\nconst DEFAULT_OPTIONS: Required<SerializeOptions> = {\n quotes: \"double\",\n indent: 2,\n};\n\n/**\n * Escape a string for use in code\n */\nexport function escapeString(\n str: string,\n quotes: \"single\" | \"double\" = \"double\",\n): string {\n const quoteChar = quotes === \"single\" ? \"'\" : '\"';\n const escaped = str\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\t/g, \"\\\\t\");\n\n if (quotes === \"single\") {\n return escaped.replace(/'/g, \"\\\\'\");\n }\n return escaped.replace(/\"/g, '\\\\\"');\n}\n\n/**\n * Serialize a single prop value to a code string\n *\n * @returns Object with `value` (the serialized string) and `needsBraces` (whether JSX needs {})\n */\nexport function serializePropValue(\n value: unknown,\n options: SerializeOptions = {},\n): { value: string; needsBraces: boolean } {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const q = opts.quotes === \"single\" ? \"'\" : '\"';\n\n if (value === null) {\n return { value: \"null\", needsBraces: true };\n }\n\n if (value === undefined) {\n return { value: \"undefined\", needsBraces: true };\n }\n\n if (typeof value === \"string\") {\n return {\n value: `${q}${escapeString(value, opts.quotes)}${q}`,\n needsBraces: false,\n };\n }\n\n if (typeof value === \"number\") {\n return { value: String(value), needsBraces: true };\n }\n\n if (typeof value === \"boolean\") {\n if (value === true) {\n return { value: \"true\", needsBraces: false }; // Can use shorthand\n }\n return { value: \"false\", needsBraces: true };\n }\n\n if (Array.isArray(value)) {\n const items = value.map((v) => serializePropValue(v, opts).value);\n return { value: `[${items.join(\", \")}]`, needsBraces: true };\n }\n\n if (typeof value === \"object\") {\n // Check for path reference\n if (\n \"path\" in value &&\n typeof (value as { path: unknown }).path === \"string\"\n ) {\n return {\n value: `{ path: ${q}${escapeString((value as { path: string }).path, opts.quotes)}${q} }`,\n needsBraces: true,\n };\n }\n\n const entries = Object.entries(value)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => {\n const serialized = serializePropValue(v, opts).value;\n // Use shorthand if key matches value for simple identifiers\n return `${k}: ${serialized}`;\n });\n\n return { value: `{ ${entries.join(\", \")} }`, needsBraces: true };\n }\n\n return { value: String(value), needsBraces: true };\n}\n\n/**\n * Serialize props object to JSX attributes string\n */\nexport function serializeProps(\n props: Record<string, unknown>,\n options: SerializeOptions = {},\n): string {\n const parts: string[] = [];\n\n for (const [key, value] of Object.entries(props)) {\n if (value === undefined || value === null) continue;\n\n const serialized = serializePropValue(value, options);\n\n // Boolean true can be shorthand\n if (typeof value === \"boolean\" && value === true) {\n parts.push(key);\n } else if (serialized.needsBraces) {\n parts.push(`${key}={${serialized.value}}`);\n } else {\n parts.push(`${key}=${serialized.value}`);\n }\n }\n\n return parts.join(\" \");\n}\n"],"mappings":"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","names":[]}
package/dist/index.mjs CHANGED
@@ -7,7 +7,7 @@ function traverseSpec(spec, visitor, startKey) {
7
7
  function visit(key, depth, parent) {
8
8
  const element = spec.elements[key];
9
9
  if (!element) return;
10
- visitor(element, depth, parent);
10
+ visitor(element, key, depth, parent);
11
11
  if (element.children) {
12
12
  for (const childKey of element.children) {
13
13
  visit(childKey, depth + 1, element);
@@ -18,14 +18,14 @@ function traverseSpec(spec, visitor, startKey) {
18
18
  }
19
19
  function collectUsedComponents(spec) {
20
20
  const components = /* @__PURE__ */ new Set();
21
- traverseSpec(spec, (element) => {
21
+ traverseSpec(spec, (element, _key) => {
22
22
  components.add(element.type);
23
23
  });
24
24
  return components;
25
25
  }
26
26
  function collectDataPaths(spec) {
27
27
  const paths = /* @__PURE__ */ new Set();
28
- traverseSpec(spec, (element) => {
28
+ traverseSpec(spec, (element, _key) => {
29
29
  for (const [propName, propValue] of Object.entries(element.props)) {
30
30
  if (typeof propValue === "string") {
31
31
  if (propName.endsWith("Path") || propName === "bindPath" || propName === "dataPath") {
@@ -73,7 +73,7 @@ function collectPathsFromCondition(condition, paths) {
73
73
  }
74
74
  function collectActions(spec) {
75
75
  const actions = /* @__PURE__ */ new Set();
76
- traverseSpec(spec, (element) => {
76
+ traverseSpec(spec, (element, _key) => {
77
77
  for (const propValue of Object.values(element.props)) {
78
78
  if (typeof propValue === "string" && propValue.startsWith("action:")) {
79
79
  actions.add(propValue.slice(7));
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/traverse.ts","../src/serialize.ts"],"sourcesContent":["import type { Spec, UIElement } from \"@json-render/core\";\n\n/**\n * Visitor function for spec traversal\n */\nexport interface TreeVisitor {\n (element: UIElement, depth: number, parent: UIElement | null): void;\n}\n\n/**\n * Traverse a UI spec depth-first\n */\nexport function traverseSpec(\n spec: Spec,\n visitor: TreeVisitor,\n startKey?: string,\n): void {\n if (!spec || !spec.root) return;\n\n const rootKey = startKey ?? spec.root;\n const rootElement = spec.elements[rootKey];\n if (!rootElement) return;\n\n function visit(key: string, depth: number, parent: UIElement | null): void {\n const element = spec.elements[key];\n if (!element) return;\n\n visitor(element, depth, parent);\n\n if (element.children) {\n for (const childKey of element.children) {\n visit(childKey, depth + 1, element);\n }\n }\n }\n\n visit(rootKey, 0, null);\n}\n\n/**\n * Collect all unique component types used in a spec\n */\nexport function collectUsedComponents(spec: Spec): Set<string> {\n const components = new Set<string>();\n\n traverseSpec(spec, (element) => {\n components.add(element.type);\n });\n\n return components;\n}\n\n/**\n * Collect all data paths referenced in a spec\n */\nexport function collectDataPaths(spec: Spec): Set<string> {\n const paths = new Set<string>();\n\n traverseSpec(spec, (element) => {\n // Check props for data paths\n for (const [propName, propValue] of Object.entries(element.props)) {\n // Check for path props (e.g., valuePath, dataPath, bindPath)\n if (typeof propValue === \"string\") {\n if (\n propName.endsWith(\"Path\") ||\n propName === \"bindPath\" ||\n propName === \"dataPath\"\n ) {\n paths.add(propValue);\n }\n }\n\n // Check for dynamic value objects with path\n if (\n propValue &&\n typeof propValue === \"object\" &&\n \"path\" in propValue &&\n typeof (propValue as { path: unknown }).path === \"string\"\n ) {\n paths.add((propValue as { path: string }).path);\n }\n }\n\n // Check visibility conditions for paths\n if (element.visible && typeof element.visible === \"object\") {\n collectPathsFromCondition(element.visible, paths);\n }\n });\n\n return paths;\n}\n\nfunction collectPathsFromCondition(\n condition: unknown,\n paths: Set<string>,\n): void {\n if (!condition || typeof condition !== \"object\") return;\n\n const cond = condition as Record<string, unknown>;\n\n if (\"path\" in cond && typeof cond.path === \"string\") {\n paths.add(cond.path);\n }\n\n if (\"and\" in cond && Array.isArray(cond.and)) {\n for (const sub of cond.and) {\n collectPathsFromCondition(sub, paths);\n }\n }\n\n if (\"or\" in cond && Array.isArray(cond.or)) {\n for (const sub of cond.or) {\n collectPathsFromCondition(sub, paths);\n }\n }\n\n if (\"not\" in cond) {\n collectPathsFromCondition(cond.not, paths);\n }\n\n // Check comparison operators\n for (const op of [\"eq\", \"neq\", \"gt\", \"gte\", \"lt\", \"lte\"]) {\n if (op in cond && Array.isArray(cond[op])) {\n for (const operand of cond[op] as unknown[]) {\n if (\n operand &&\n typeof operand === \"object\" &&\n \"path\" in operand &&\n typeof (operand as { path: unknown }).path === \"string\"\n ) {\n paths.add((operand as { path: string }).path);\n }\n }\n }\n }\n}\n\n/**\n * Collect all action names used in a spec\n */\nexport function collectActions(spec: Spec): Set<string> {\n const actions = new Set<string>();\n\n traverseSpec(spec, (element) => {\n for (const propValue of Object.values(element.props)) {\n // Check for action prop (string action name)\n if (typeof propValue === \"string\" && propValue.startsWith(\"action:\")) {\n actions.add(propValue.slice(7));\n }\n\n // Check for action objects\n if (\n propValue &&\n typeof propValue === \"object\" &&\n \"name\" in propValue &&\n typeof (propValue as { name: unknown }).name === \"string\"\n ) {\n actions.add((propValue as { name: string }).name);\n }\n }\n\n // Also check direct action prop\n const actionProp = element.props.action;\n if (typeof actionProp === \"string\") {\n actions.add(actionProp);\n }\n });\n\n return actions;\n}\n","/**\n * Options for serialization\n */\nexport interface SerializeOptions {\n /** Quote style for strings */\n quotes?: \"single\" | \"double\";\n /** Indent for objects/arrays */\n indent?: number;\n}\n\nconst DEFAULT_OPTIONS: Required<SerializeOptions> = {\n quotes: \"double\",\n indent: 2,\n};\n\n/**\n * Escape a string for use in code\n */\nexport function escapeString(\n str: string,\n quotes: \"single\" | \"double\" = \"double\",\n): string {\n const quoteChar = quotes === \"single\" ? \"'\" : '\"';\n const escaped = str\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\t/g, \"\\\\t\");\n\n if (quotes === \"single\") {\n return escaped.replace(/'/g, \"\\\\'\");\n }\n return escaped.replace(/\"/g, '\\\\\"');\n}\n\n/**\n * Serialize a single prop value to a code string\n *\n * @returns Object with `value` (the serialized string) and `needsBraces` (whether JSX needs {})\n */\nexport function serializePropValue(\n value: unknown,\n options: SerializeOptions = {},\n): { value: string; needsBraces: boolean } {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const q = opts.quotes === \"single\" ? \"'\" : '\"';\n\n if (value === null) {\n return { value: \"null\", needsBraces: true };\n }\n\n if (value === undefined) {\n return { value: \"undefined\", needsBraces: true };\n }\n\n if (typeof value === \"string\") {\n return {\n value: `${q}${escapeString(value, opts.quotes)}${q}`,\n needsBraces: false,\n };\n }\n\n if (typeof value === \"number\") {\n return { value: String(value), needsBraces: true };\n }\n\n if (typeof value === \"boolean\") {\n if (value === true) {\n return { value: \"true\", needsBraces: false }; // Can use shorthand\n }\n return { value: \"false\", needsBraces: true };\n }\n\n if (Array.isArray(value)) {\n const items = value.map((v) => serializePropValue(v, opts).value);\n return { value: `[${items.join(\", \")}]`, needsBraces: true };\n }\n\n if (typeof value === \"object\") {\n // Check for path reference\n if (\n \"path\" in value &&\n typeof (value as { path: unknown }).path === \"string\"\n ) {\n return {\n value: `{ path: ${q}${escapeString((value as { path: string }).path, opts.quotes)}${q} }`,\n needsBraces: true,\n };\n }\n\n const entries = Object.entries(value)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => {\n const serialized = serializePropValue(v, opts).value;\n // Use shorthand if key matches value for simple identifiers\n return `${k}: ${serialized}`;\n });\n\n return { value: `{ ${entries.join(\", \")} }`, needsBraces: true };\n }\n\n return { value: String(value), needsBraces: true };\n}\n\n/**\n * Serialize props object to JSX attributes string\n */\nexport function serializeProps(\n props: Record<string, unknown>,\n options: SerializeOptions = {},\n): string {\n const parts: string[] = [];\n\n for (const [key, value] of Object.entries(props)) {\n if (value === undefined || value === null) continue;\n\n const serialized = serializePropValue(value, options);\n\n // Boolean true can be shorthand\n if (typeof value === \"boolean\" && value === true) {\n parts.push(key);\n } else if (serialized.needsBraces) {\n parts.push(`${key}={${serialized.value}}`);\n } else {\n parts.push(`${key}=${serialized.value}`);\n }\n }\n\n return parts.join(\" \");\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/traverse.ts","../src/serialize.ts"],"sourcesContent":["import type { Spec, UIElement } from \"@json-render/core\";\n\n/**\n * Visitor function for spec traversal\n */\nexport interface TreeVisitor {\n (\n element: UIElement,\n key: string,\n depth: number,\n parent: UIElement | null,\n ): void;\n}\n\n/**\n * Traverse a UI spec depth-first\n */\nexport function traverseSpec(\n spec: Spec,\n visitor: TreeVisitor,\n startKey?: string,\n): void {\n if (!spec || !spec.root) return;\n\n const rootKey = startKey ?? spec.root;\n const rootElement = spec.elements[rootKey];\n if (!rootElement) return;\n\n function visit(key: string, depth: number, parent: UIElement | null): void {\n const element = spec.elements[key];\n if (!element) return;\n\n visitor(element, key, depth, parent);\n\n if (element.children) {\n for (const childKey of element.children) {\n visit(childKey, depth + 1, element);\n }\n }\n }\n\n visit(rootKey, 0, null);\n}\n\n/**\n * Collect all unique component types used in a spec\n */\nexport function collectUsedComponents(spec: Spec): Set<string> {\n const components = new Set<string>();\n\n traverseSpec(spec, (element, _key) => {\n components.add(element.type);\n });\n\n return components;\n}\n\n/**\n * Collect all data paths referenced in a spec\n */\nexport function collectDataPaths(spec: Spec): Set<string> {\n const paths = new Set<string>();\n\n traverseSpec(spec, (element, _key) => {\n // Check props for data paths\n for (const [propName, propValue] of Object.entries(element.props)) {\n // Check for path props (e.g., valuePath, dataPath, bindPath)\n if (typeof propValue === \"string\") {\n if (\n propName.endsWith(\"Path\") ||\n propName === \"bindPath\" ||\n propName === \"dataPath\"\n ) {\n paths.add(propValue);\n }\n }\n\n // Check for dynamic value objects with path\n if (\n propValue &&\n typeof propValue === \"object\" &&\n \"path\" in propValue &&\n typeof (propValue as { path: unknown }).path === \"string\"\n ) {\n paths.add((propValue as { path: string }).path);\n }\n }\n\n // Check visibility conditions for paths\n if (element.visible && typeof element.visible === \"object\") {\n collectPathsFromCondition(element.visible, paths);\n }\n });\n\n return paths;\n}\n\nfunction collectPathsFromCondition(\n condition: unknown,\n paths: Set<string>,\n): void {\n if (!condition || typeof condition !== \"object\") return;\n\n const cond = condition as Record<string, unknown>;\n\n if (\"path\" in cond && typeof cond.path === \"string\") {\n paths.add(cond.path);\n }\n\n if (\"and\" in cond && Array.isArray(cond.and)) {\n for (const sub of cond.and) {\n collectPathsFromCondition(sub, paths);\n }\n }\n\n if (\"or\" in cond && Array.isArray(cond.or)) {\n for (const sub of cond.or) {\n collectPathsFromCondition(sub, paths);\n }\n }\n\n if (\"not\" in cond) {\n collectPathsFromCondition(cond.not, paths);\n }\n\n // Check comparison operators\n for (const op of [\"eq\", \"neq\", \"gt\", \"gte\", \"lt\", \"lte\"]) {\n if (op in cond && Array.isArray(cond[op])) {\n for (const operand of cond[op] as unknown[]) {\n if (\n operand &&\n typeof operand === \"object\" &&\n \"path\" in operand &&\n typeof (operand as { path: unknown }).path === \"string\"\n ) {\n paths.add((operand as { path: string }).path);\n }\n }\n }\n }\n}\n\n/**\n * Collect all action names used in a spec\n */\nexport function collectActions(spec: Spec): Set<string> {\n const actions = new Set<string>();\n\n traverseSpec(spec, (element, _key) => {\n for (const propValue of Object.values(element.props)) {\n // Check for action prop (string action name)\n if (typeof propValue === \"string\" && propValue.startsWith(\"action:\")) {\n actions.add(propValue.slice(7));\n }\n\n // Check for action objects\n if (\n propValue &&\n typeof propValue === \"object\" &&\n \"name\" in propValue &&\n typeof (propValue as { name: unknown }).name === \"string\"\n ) {\n actions.add((propValue as { name: string }).name);\n }\n }\n\n // Also check direct action prop\n const actionProp = element.props.action;\n if (typeof actionProp === \"string\") {\n actions.add(actionProp);\n }\n });\n\n return actions;\n}\n","/**\n * Options for serialization\n */\nexport interface SerializeOptions {\n /** Quote style for strings */\n quotes?: \"single\" | \"double\";\n /** Indent for objects/arrays */\n indent?: number;\n}\n\nconst DEFAULT_OPTIONS: Required<SerializeOptions> = {\n quotes: \"double\",\n indent: 2,\n};\n\n/**\n * Escape a string for use in code\n */\nexport function escapeString(\n str: string,\n quotes: \"single\" | \"double\" = \"double\",\n): string {\n const quoteChar = quotes === \"single\" ? \"'\" : '\"';\n const escaped = str\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\t/g, \"\\\\t\");\n\n if (quotes === \"single\") {\n return escaped.replace(/'/g, \"\\\\'\");\n }\n return escaped.replace(/\"/g, '\\\\\"');\n}\n\n/**\n * Serialize a single prop value to a code string\n *\n * @returns Object with `value` (the serialized string) and `needsBraces` (whether JSX needs {})\n */\nexport function serializePropValue(\n value: unknown,\n options: SerializeOptions = {},\n): { value: string; needsBraces: boolean } {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const q = opts.quotes === \"single\" ? \"'\" : '\"';\n\n if (value === null) {\n return { value: \"null\", needsBraces: true };\n }\n\n if (value === undefined) {\n return { value: \"undefined\", needsBraces: true };\n }\n\n if (typeof value === \"string\") {\n return {\n value: `${q}${escapeString(value, opts.quotes)}${q}`,\n needsBraces: false,\n };\n }\n\n if (typeof value === \"number\") {\n return { value: String(value), needsBraces: true };\n }\n\n if (typeof value === \"boolean\") {\n if (value === true) {\n return { value: \"true\", needsBraces: false }; // Can use shorthand\n }\n return { value: \"false\", needsBraces: true };\n }\n\n if (Array.isArray(value)) {\n const items = value.map((v) => serializePropValue(v, opts).value);\n return { value: `[${items.join(\", \")}]`, needsBraces: true };\n }\n\n if (typeof value === \"object\") {\n // Check for path reference\n if (\n \"path\" in value &&\n typeof (value as { path: unknown }).path === \"string\"\n ) {\n return {\n value: `{ path: ${q}${escapeString((value as { path: string }).path, opts.quotes)}${q} }`,\n needsBraces: true,\n };\n }\n\n const entries = Object.entries(value)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => {\n const serialized = serializePropValue(v, opts).value;\n // Use shorthand if key matches value for simple identifiers\n return `${k}: ${serialized}`;\n });\n\n return { value: `{ ${entries.join(\", \")} }`, needsBraces: true };\n }\n\n return { value: String(value), needsBraces: true };\n}\n\n/**\n * Serialize props object to JSX attributes string\n */\nexport function serializeProps(\n props: Record<string, unknown>,\n options: SerializeOptions = {},\n): string {\n const parts: string[] = [];\n\n for (const [key, value] of Object.entries(props)) {\n if (value === undefined || value === null) continue;\n\n const serialized = serializePropValue(value, options);\n\n // Boolean true can be shorthand\n if (typeof value === \"boolean\" && value === true) {\n parts.push(key);\n } else if (serialized.needsBraces) {\n parts.push(`${key}={${serialized.value}}`);\n } else {\n parts.push(`${key}=${serialized.value}`);\n }\n }\n\n return parts.join(\" \");\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@json-render/codegen",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Utilities for generating code from json-render UI trees",
6
6
  "keywords": [
@@ -36,7 +36,7 @@
36
36
  "dist"
37
37
  ],
38
38
  "dependencies": {
39
- "@json-render/core": "0.4.2"
39
+ "@json-render/core": "0.4.4"
40
40
  },
41
41
  "devDependencies": {
42
42
  "tsup": "^8.0.2",