getsyntux 0.1.2 → 0.2.1
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/README.md +42 -85
- package/dist/bin/cli.d.mts +99 -0
- package/dist/bin/cli.mjs +3 -0
- package/dist/bin/cli.mjs.map +1 -0
- package/dist/client.d.mts +23 -0
- package/dist/client.mjs +3 -0
- package/dist/client.mjs.map +1 -0
- package/dist/index.d.mts +26 -52
- package/dist/index.mjs +6 -231
- package/dist/index.mjs.map +1 -1
- package/dist/metafile-esm.json +1 -0
- package/dist/templates/GeneratedUI.tsx +76 -0
- package/dist/templates/spec.md +78 -0
- package/dist/templates/spec.ts +80 -0
- package/dist/types-DejIW5JZ.d.mts +24 -0
- package/package.json +54 -38
- package/dist/index.d.ts +0 -62
- package/dist/index.js +0 -234
- package/dist/index.js.map +0 -1
- package/dist/plugin.d.mts +0 -2
- package/dist/plugin.d.ts +0 -2
- package/dist/plugin.js +0 -75
- package/dist/plugin.js.map +0 -1
- package/dist/plugin.mjs +0 -73
- package/dist/plugin.mjs.map +0 -1
package/package.json
CHANGED
|
@@ -1,38 +1,54 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "getsyntux",
|
|
3
|
-
"version": "0.1
|
|
4
|
-
"description": "The
|
|
5
|
-
"exports": {
|
|
6
|
-
".": {
|
|
7
|
-
"types": "./dist/index.d.ts",
|
|
8
|
-
"import": "./dist/index.mjs",
|
|
9
|
-
"require": "./dist/index.js"
|
|
10
|
-
},
|
|
11
|
-
"./
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
},
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "getsyntux",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "The declarative generative-UI library.",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"import": "./dist/index.mjs",
|
|
9
|
+
"require": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"./client": {
|
|
12
|
+
"types": "./dist/client.d.ts",
|
|
13
|
+
"import": "./dist/client.mjs",
|
|
14
|
+
"require": "./dist/client.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"bin": {
|
|
18
|
+
"getsyntux": "./dist/bin/cli.mjs"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/puffinsoft/syntux.git"
|
|
23
|
+
},
|
|
24
|
+
"author": "ColonelParrot",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/puffinsoft/syntux/issues"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/puffinsoft/syntux#readme",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@ai-sdk/rsc": "^2.0.3",
|
|
32
|
+
"@types/node": "^25.0.2",
|
|
33
|
+
"@types/react": "^19.2.7",
|
|
34
|
+
"ai": "^6.0.3",
|
|
35
|
+
"chalk": "^5.6.2",
|
|
36
|
+
"fs-extra": "^11.3.3",
|
|
37
|
+
"prompts": "^2.4.2",
|
|
38
|
+
"tsup": "^8.5.1",
|
|
39
|
+
"typescript": "^5.9.3"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsup",
|
|
43
|
+
"dev": "tsup --watch",
|
|
44
|
+
"prepublishOnly": "npm run build"
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"/dist/**/*"
|
|
48
|
+
],
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@ai-sdk/anthropic": "^3.0.1",
|
|
51
|
+
"esbuild-plugin-preserve-directives": "^0.0.11",
|
|
52
|
+
"tsx": "^4.21.0"
|
|
53
|
+
}
|
|
54
|
+
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ComponentType } from 'react';
|
|
3
|
-
import { LanguageModel } from 'ai';
|
|
4
|
-
|
|
5
|
-
interface SchemaNode {
|
|
6
|
-
type?: string;
|
|
7
|
-
props?: Record<string, any>;
|
|
8
|
-
children?: (SchemaNode | string)[];
|
|
9
|
-
source?: string;
|
|
10
|
-
template?: SchemaNode;
|
|
11
|
-
$bind?: string;
|
|
12
|
-
}
|
|
13
|
-
interface RendererProps {
|
|
14
|
-
schema: SchemaNode | string;
|
|
15
|
-
global: any;
|
|
16
|
-
local?: any;
|
|
17
|
-
components: Record<string, ComponentType<any> | string>;
|
|
18
|
-
}
|
|
19
|
-
declare function Renderer({ schema, global, local, components }: RendererProps): react_jsx_runtime.JSX.Element;
|
|
20
|
-
|
|
21
|
-
type SyntuxComponent<P = any> = React.ComponentType<P> & {
|
|
22
|
-
userContext?: string;
|
|
23
|
-
llmContext?: string;
|
|
24
|
-
llmName?: string;
|
|
25
|
-
identifier?: Symbol;
|
|
26
|
-
};
|
|
27
|
-
type SyntuxElement<P = any> = React.ReactElement<P, SyntuxComponent<P>>;
|
|
28
|
-
|
|
29
|
-
interface GeneratedPageProps {
|
|
30
|
-
context?: string;
|
|
31
|
-
schema: SyntuxElement;
|
|
32
|
-
onGenerate?: (result: SchemaNode[]) => void;
|
|
33
|
-
cached?: (SchemaNode | string)[];
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
interface GeneratedContentProps {
|
|
37
|
-
values: any;
|
|
38
|
-
components?: (SyntuxComponent<any> | string)[];
|
|
39
|
-
hint?: string;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Section of user interface for LLM to generate.
|
|
43
|
-
* @param values The values (object, primitive, or array) to be displayed.
|
|
44
|
-
* @param components List of allowed components that LLM can use.
|
|
45
|
-
* @param hint Additional custom instructions for the LLM.
|
|
46
|
-
*/
|
|
47
|
-
declare function GeneratedContent(props: GeneratedContentProps): react_jsx_runtime.JSX.Element;
|
|
48
|
-
declare namespace GeneratedContent {
|
|
49
|
-
var identifier: typeof SIGNATURE;
|
|
50
|
-
}
|
|
51
|
-
declare const SIGNATURE: unique symbol;
|
|
52
|
-
|
|
53
|
-
interface SyntuxFactoryConfig {
|
|
54
|
-
model: LanguageModel;
|
|
55
|
-
}
|
|
56
|
-
declare const createSyntuxFactory: (config: SyntuxFactoryConfig) => {
|
|
57
|
-
GeneratedPage: ({ context, schema, cached, onGenerate }: GeneratedPageProps) => Promise<react_jsx_runtime.JSX.Element>;
|
|
58
|
-
GeneratedContent: typeof GeneratedContent;
|
|
59
|
-
Renderer: typeof Renderer;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export { type GeneratedContentProps, type GeneratedPageProps, type SchemaNode, type SyntuxFactoryConfig, createSyntuxFactory };
|
package/dist/index.js
DELETED
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var react = require('react');
|
|
4
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
-
var ai = require('ai');
|
|
6
|
-
|
|
7
|
-
// src/GeneratedPage.tsx
|
|
8
|
-
function GeneratedContent(props) {
|
|
9
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
10
|
-
}
|
|
11
|
-
var SIGNATURE = /* @__PURE__ */ Symbol("GeneratedContent");
|
|
12
|
-
GeneratedContent.identifier = SIGNATURE;
|
|
13
|
-
var resolvePath = (obj, path) => {
|
|
14
|
-
if (path === "$") return obj;
|
|
15
|
-
return path.split(".").reduce((acc, curr) => acc == null ? void 0 : acc[curr], obj);
|
|
16
|
-
};
|
|
17
|
-
var get = (global, local, path) => {
|
|
18
|
-
if (path.startsWith("$item.")) {
|
|
19
|
-
path = path.slice(6);
|
|
20
|
-
return resolvePath(local, path);
|
|
21
|
-
} else {
|
|
22
|
-
if (path === "$item") return local;
|
|
23
|
-
return resolvePath(global, path);
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
var resolveProps = (global, local, props) => {
|
|
27
|
-
if (!props) return;
|
|
28
|
-
if ("$bind" in props) return get(global, local, props.$bind);
|
|
29
|
-
Object.keys(props).forEach((key) => {
|
|
30
|
-
const val = props[key];
|
|
31
|
-
if (typeof val === "object") {
|
|
32
|
-
props[key] = resolveProps(global, local, val);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
return props;
|
|
36
|
-
};
|
|
37
|
-
function Renderer({
|
|
38
|
-
schema,
|
|
39
|
-
global,
|
|
40
|
-
local,
|
|
41
|
-
components
|
|
42
|
-
}) {
|
|
43
|
-
var _a;
|
|
44
|
-
if (typeof schema === "string") return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: schema });
|
|
45
|
-
if (schema.$bind) {
|
|
46
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: get(global, local, schema.$bind) });
|
|
47
|
-
}
|
|
48
|
-
if (schema.type === "__ForEach__" && schema.source && schema.template) {
|
|
49
|
-
const sourceArr = get(global, local, schema.source);
|
|
50
|
-
if (!Array.isArray(sourceArr)) return null;
|
|
51
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: sourceArr.map((item, index) => {
|
|
52
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
53
|
-
Renderer,
|
|
54
|
-
{
|
|
55
|
-
schema: schema.template,
|
|
56
|
-
global,
|
|
57
|
-
local: item,
|
|
58
|
-
components
|
|
59
|
-
},
|
|
60
|
-
index
|
|
61
|
-
);
|
|
62
|
-
}) });
|
|
63
|
-
}
|
|
64
|
-
if (!schema.type) return null;
|
|
65
|
-
const Component = components[schema.type] || schema.type;
|
|
66
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...resolveProps(global, local, schema.props), children: (_a = schema.children) == null ? void 0 : _a.map((item, index) => {
|
|
67
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
68
|
-
Renderer,
|
|
69
|
-
{
|
|
70
|
-
schema: item,
|
|
71
|
-
global,
|
|
72
|
-
local,
|
|
73
|
-
components
|
|
74
|
-
},
|
|
75
|
-
index
|
|
76
|
-
);
|
|
77
|
-
}) });
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// src/util.ts
|
|
81
|
-
var endDelimiter = "</UISchema>";
|
|
82
|
-
function parseResponse(llmResponse) {
|
|
83
|
-
const split = llmResponse.split(/\<UISchema index="\d+">/m).slice(1).map((e) => e.trim());
|
|
84
|
-
const contents = split.map((e) => e.slice(0, -endDelimiter.length));
|
|
85
|
-
const parsed = contents.map((e) => JSON.parse(e));
|
|
86
|
-
return parsed;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// src/prompt.md
|
|
90
|
-
var prompt_default = '<system_persona>\r\nYou are the **UI Schema Generation Engine**, a specialized architect responsible for converting raw data structures into abstract, reusable React Interface Schemas (JSON-DSL).\r\n\r\nYour output is **NOT** code. Your output is a JSON-based Abstract Syntax Tree (AST) that describes the UI structure. The rendering engine will hydrate this schema with data later.\r\n</system_persona>\r\n\r\n<core_philosophy>\r\n1. **Separation of Concerns:** You define the *structure*. You do NOT hardcode *values*.\r\n2. **Strict Adherence:** You may ONLY use components explicitly listed in the `<AllowedComponents>` block of the input. If the block is missing or empty, revert to the <default_component_library>.\r\n3. **Semantic Structure:** Even though you are generating JSON, the resulting UI must be semantically correct (using proper hierarchy, semantic HTML tags, and logical grouping).\r\n4. **Reusability:** Your schema must be valid regardless of the specific values in the data. It must handle list lengths of 0 or 1000 gracefully using the Iterator Protocol.\r\n</core_philosophy>\r\n\r\n<dsl_syntax_rules>\r\nThe output must be a JSON object adhering to this strict recursive interface:\r\n\r\n### 1. The Standard Node\r\nUsed for HTML tags or Custom Components.\r\n```json\r\n{\r\n "type": "div" | "h1" | "MyCustomComponent",\r\n "props": { "className": "...", "customProp": "..." },\r\n "children": [] // Array of Nodes or Strings\r\n}\r\n```\r\n\r\n### 2. The Binding Protocol (`$bind`)\r\n\r\n**NEVER** output raw data values (e.g., "John", "john@email.com") in the schema.\r\nInstead, bind to a path.\r\n\r\n```json\r\n// BAD\r\n{ "type": "span", "children": ["John"] }\r\n\r\n// GOOD\r\n{ "type": "span", "children": [{ "$bind": "user.firstName" }] }\r\n```\r\n\r\nYou have access to exactly **two scopes** at any time:\r\n- **Global Scope (Root)**: Any path **WITHOUT** the `$item` prefix accesses the top-level global data object. This is available at any nesting depth.\r\n - *Example:* `"$bind": "pageTitle"` (Always looks at `data.pageTitle`)\r\n- **Local Scope (Current Item):** Any path **STARTING WITH** `$item` accesses the immediate object currently being iterated in a loop.\r\n - *Example:* `"$bind": "$item.name"` (Looks at `name` on the current loop item).\r\n - *Example:* `"$bind": "$item"` (Renders the current loop item, usually a string).\r\n\r\nIn special cases, you may need to reference a specific, fixed index in an array. To do that, use dot notation to access the index. For instance: `arr.1.property` accesses the `property` property of the 2nd item in `arr`. However, use this conservatively; prefer to use the Iterator Protocol unless it doesn\'t make sense (e.g., it\'s a static array).\r\n\r\n**CRITICAL:** Intermediate scopes are not accessible. Inside a nested loop, `$item` refers *only* to the innermost item.\r\n\r\n### 3. The Iterator Protocol (`__ForEach__`)\r\n\r\nIf the data value is an Array, you MUST use this node. Do not manually unroll lists.\r\n\r\n- **Root Arrays**: If the input value is the array itself, use "source": "$".\r\n- **Nested Arrays**: If the array is a property on the current item, use `"source": "$item.path.to.array"`.\r\n- **Global Arrays**: If the array is a property on the Global Root, use `"source": "path.to.array"`.\r\n\r\n```json\r\n{\r\n "type": "__ForEach__",\r\n "source": "$" | "$item.path.to.array" | "path.to.array",\r\n "template": {\r\n // This is the shape of a SINGLE item.\r\n // Inside here, use "$item" to refer to the current array element.\r\n "type": "li",\r\n "children": [{ "$bind": "$item.name" }]\r\n }\r\n}\r\n```\r\n\r\n</dsl_syntax_rules>\r\n\r\n<default_component_library>\r\nIf no specific allowed components are provided, you have access to this semantic HTML suite:\r\n\r\n * **Layout:** `div`, `section`, `article`, `main`, `aside`, `header`, `footer`\r\n * **Typography:** `h1`, `h2`, `h3`, `p`, `span`, `strong`, `em`, `blockquote`, `pre`, `code`\r\n * **Lists:** `ul`, `ol`, `li`\r\n * **Interaction:** `button`, `a` (use href prop), `details`, `summary`\r\n * **Form:** `input`, `label`, `textarea`, `select`, `option`\r\n * **Media:** `img`, `figure`, `figcaption`\r\n\r\n</default_component_library>\r\n\r\n<input_processing_rules>\r\nThe user will provide one or more `<GeneratedContent>` blocks.\r\n\r\n1. **Parse `AllowedComponents`:** A comma-separated list.\r\n * Lowercase = Native HTML tags.\r\n * Uppercase = Custom React Components.\r\n2. **Parse `ComponentContext`:** Defines the TypeScript interface for Custom Components.\r\n * *CRITICAL:* You must strictly adhere to the prop names and types defined here. Do not hallucinate props for custom components.\r\n * Components are separated by a comma, in the format `ComponentName [props: { ... }, details: "..."]`. The `props` indicate what `props` it must accept, in Typescript format. The `details` is an optional field, and describes what the component does. Use this information in whatever way to improve your generation output. If you encounter a complex type in `props`, look at the input values and make your best guess at what value is the best fit.\r\n3. **Parse `UserContext`:** This is anything the developer believes is relevant for your task. It could describe a specific UI style or the correct way to use a custom component.\r\n * *CRITICAL*: To the best of your ability, respect the developer\'s wishes. If no UserContext is provided, you should accomplish the task as you see fit, with no constraints.\r\n * *CRITICAL*: This is only relevant to the current <GeneratedContent> block!\r\n3. **Parse `Value`:** The JSON data structure you are building the UI for.\r\n\r\nAdditionally, the user may provide a <PageContext> before all <GeneratedContent> blocks. Think of this as a global UserContext. This is meant to provide additional context and guiding when designing the UI, which you should try to adhere to. If none is provided, accomplish the task as you see fit, with no constraints.\r\n\r\n</input_processing_rules>\r\n\r\n<output_formatting>\r\nFor every `<GeneratedContent>` input block, you must generate exactly one `<UISchema>` output block.\r\nThe order must be preserved.\r\n\r\nInput:\r\n<PageContext></PageContext>\r\n<GeneratedContent> ... </GeneratedContent> (Section 1)\r\n<GeneratedContent> ... </GeneratedContent> (Section 2)\r\n\r\nOutput:\r\n<UISchema index="0"> ...JSON... </UISchema>\r\n<UISchema index="1"> ...JSON... </UISchema>\r\n</output_formatting>\r\n\r\n<examples>\r\n**Input:**\r\n<GeneratedContent>\r\n<AllowedComponents>div,span,Avatar</AllowedComponents>\r\n<ComponentContext>Avatar [props: { url: string }]</ComponentContext>\r\n<UserContext>grouped under one div</UserContext>\r\n<Value>{ authors: [{ name: "J.K.", img: "..." }, { name: "Tolkien", img: "..." }] }</Value>\r\n</GeneratedContent>\r\n\r\n**Correct Output:**\r\n<UISchema index="0">\r\n{\r\n "type": "div",\r\n "props": {\r\n "className": "author-list"\r\n },\r\n "children": [\r\n {\r\n "type": "__ForEach__",\r\n "source": "authors",\r\n "template": {\r\n "type": "div",\r\n "props": {\r\n "className": "author-card"\r\n },\r\n "children": [\r\n {\r\n "type": "Avatar",\r\n "props": {\r\n "url": {\r\n "$bind": "$item.img"\r\n }\r\n }\r\n },\r\n {\r\n "type": "span",\r\n "children": [\r\n {\r\n "$bind": "$item.name"\r\n }\r\n ]\r\n }\r\n ]\r\n }\r\n }\r\n ]\r\n}\r\n</UISchema>\r\n</examples>\r\n\r\n<reasoning_requirements>\r\nBefore generating the JSON, briefly analyze the data structure to identify arrays (requiring `__ForEach__`) and custom component opportunities. Use the mental scratchpad if necessary, but keep the final output strictly within `<UISchema>` tags.\r\n</reasoning_requirements>\r\n\r\n<IMPORTANT>\r\nDo NOT output anything except the UISchema.\r\n</IMPORTANT>';
|
|
91
|
-
function extractChildren(element) {
|
|
92
|
-
var _a;
|
|
93
|
-
if ((_a = element == null ? void 0 : element.props) == null ? void 0 : _a.children) {
|
|
94
|
-
let children = element.props.children;
|
|
95
|
-
if (!Array.isArray(children)) children = [children];
|
|
96
|
-
return children;
|
|
97
|
-
}
|
|
98
|
-
return [];
|
|
99
|
-
}
|
|
100
|
-
function searchChildren(element, acc) {
|
|
101
|
-
if (!react.isValidElement(element)) return;
|
|
102
|
-
if (element.type.identifier === SIGNATURE) {
|
|
103
|
-
const { values, components, hint } = element.props;
|
|
104
|
-
const realComponents = [];
|
|
105
|
-
if (components) {
|
|
106
|
-
components.forEach((comp) => {
|
|
107
|
-
if (typeof comp === "string") {
|
|
108
|
-
realComponents.push({
|
|
109
|
-
llmName: comp
|
|
110
|
-
});
|
|
111
|
-
} else {
|
|
112
|
-
realComponents.push({
|
|
113
|
-
llmName: comp.llmName,
|
|
114
|
-
llmContext: comp.llmContext,
|
|
115
|
-
userContext: comp.userContext
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
acc.push({
|
|
121
|
-
values,
|
|
122
|
-
components: realComponents,
|
|
123
|
-
hint: hint || ""
|
|
124
|
-
});
|
|
125
|
-
} else {
|
|
126
|
-
const children = extractChildren(element);
|
|
127
|
-
children.forEach((child) => {
|
|
128
|
-
searchChildren(child, acc);
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
function generateInput(content, context) {
|
|
133
|
-
let str = "";
|
|
134
|
-
if (context) {
|
|
135
|
-
str = `<PageContext>${context}</PageContext>
|
|
136
|
-
`;
|
|
137
|
-
}
|
|
138
|
-
content.forEach((schema) => {
|
|
139
|
-
const allowedComponents = schema.components.map((e) => e.llmName);
|
|
140
|
-
const componentContext = [];
|
|
141
|
-
schema.components.forEach((comp) => {
|
|
142
|
-
if (comp.llmContext) {
|
|
143
|
-
let contextStr;
|
|
144
|
-
if (comp.userContext) {
|
|
145
|
-
contextStr = `${comp.llmName} [${comp.llmContext}, details: ${comp.userContext}]`;
|
|
146
|
-
} else {
|
|
147
|
-
contextStr = `${comp.llmName} [${comp.llmContext}]`;
|
|
148
|
-
}
|
|
149
|
-
componentContext.push(contextStr);
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
const userContext = schema.hint;
|
|
153
|
-
const value = JSON.stringify(schema.values);
|
|
154
|
-
str += `<GeneratedContent>
|
|
155
|
-
<AllowedComponents>${allowedComponents.join(",")}</AllowedComponents>
|
|
156
|
-
<ComponentContext>${componentContext.join(",")}</ComponentContext>
|
|
157
|
-
<UserContext>${userContext}</UserContext>
|
|
158
|
-
<Value>${value}</Value>
|
|
159
|
-
</GeneratedContent>
|
|
160
|
-
`;
|
|
161
|
-
});
|
|
162
|
-
return str;
|
|
163
|
-
}
|
|
164
|
-
function createComponentRegistry(components) {
|
|
165
|
-
if (!components) return {};
|
|
166
|
-
return components.reduce((acc, curr) => {
|
|
167
|
-
if (typeof curr === "string") {
|
|
168
|
-
acc[curr] = curr;
|
|
169
|
-
} else {
|
|
170
|
-
if (curr.llmName) {
|
|
171
|
-
acc[curr.llmName] = curr;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return acc;
|
|
175
|
-
}, {});
|
|
176
|
-
}
|
|
177
|
-
function hydrate(schema, dsl) {
|
|
178
|
-
let componentIndex = 0;
|
|
179
|
-
function swapChildren(element) {
|
|
180
|
-
if (!react.isValidElement(element)) return element;
|
|
181
|
-
if (element.type.identifier === SIGNATURE) {
|
|
182
|
-
const { values, components, hint } = element.props;
|
|
183
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Renderer, { schema: dsl[componentIndex++], global: values, local: values, components: createComponentRegistry(components) }, componentIndex);
|
|
184
|
-
}
|
|
185
|
-
const children = extractChildren(element);
|
|
186
|
-
if (children.length == 0) {
|
|
187
|
-
return element;
|
|
188
|
-
}
|
|
189
|
-
return children.map((child, ind) => {
|
|
190
|
-
return swapChildren(child);
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
return swapChildren(schema);
|
|
194
|
-
}
|
|
195
|
-
var createGeneratedPage = (model) => {
|
|
196
|
-
return async function GeneratedPage({
|
|
197
|
-
context,
|
|
198
|
-
schema,
|
|
199
|
-
cached,
|
|
200
|
-
onGenerate
|
|
201
|
-
}) {
|
|
202
|
-
if (cached) {
|
|
203
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: hydrate(schema, cached) });
|
|
204
|
-
}
|
|
205
|
-
const contents = [];
|
|
206
|
-
searchChildren(schema, contents);
|
|
207
|
-
console.log("contents", contents);
|
|
208
|
-
if (contents.length == 0) return schema;
|
|
209
|
-
const llmInput = generateInput(contents, context);
|
|
210
|
-
const { text: llmResponse } = await ai.generateText({
|
|
211
|
-
model,
|
|
212
|
-
system: prompt_default,
|
|
213
|
-
prompt: llmInput
|
|
214
|
-
});
|
|
215
|
-
const parsedResponse = parseResponse(llmResponse);
|
|
216
|
-
if (onGenerate) {
|
|
217
|
-
onGenerate(parsedResponse);
|
|
218
|
-
}
|
|
219
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: hydrate(schema, parsedResponse) });
|
|
220
|
-
};
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
// src/index.ts
|
|
224
|
-
var createSyntuxFactory = (config) => {
|
|
225
|
-
return {
|
|
226
|
-
GeneratedPage: createGeneratedPage(config.model),
|
|
227
|
-
GeneratedContent,
|
|
228
|
-
Renderer
|
|
229
|
-
};
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
exports.createSyntuxFactory = createSyntuxFactory;
|
|
233
|
-
//# sourceMappingURL=index.js.map
|
|
234
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/GeneratedContent.tsx","../src/Renderer.tsx","../src/util.ts","../src/prompt.md","../src/GeneratedPage.tsx","../src/index.ts"],"names":["jsx","Fragment","isValidElement","generateText"],"mappings":"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","file":"index.js","sourcesContent":["import { ComponentType } from 'react'\r\nimport { SyntuxComponent } from './types';\r\n\r\nexport interface GeneratedContentProps {\r\n values: any;\r\n components?: (SyntuxComponent<any> | string)[];\r\n hint?: string;\r\n}\r\n\r\n/**\r\n * Section of user interface for LLM to generate.\r\n * @param values The values (object, primitive, or array) to be displayed.\r\n * @param components List of allowed components that LLM can use.\r\n * @param hint Additional custom instructions for the LLM.\r\n */\r\nexport function GeneratedContent(props: GeneratedContentProps) {\r\n /**\r\n * This is an empty component.\r\n * It acts as a declarative slot that <GeneratedPage> recognizes\r\n * and replaces with a Renderer during hydration.\r\n */\r\n return <></>;\r\n}\r\nexport const SIGNATURE = Symbol('GeneratedContent');\r\nGeneratedContent.identifier = SIGNATURE;","import { ComponentType } from 'react'\r\n\r\nconst resolvePath = (obj: any, path: string) => {\r\n if(path === '$') return obj;\r\n return path.split('.').reduce((acc, curr) => acc?.[curr], obj)\r\n}\r\n\r\nconst get = (global: any, local: any, path: string) => {\r\n if(path.startsWith(\"$item.\")){\r\n path = path.slice(6)\r\n return resolvePath(local, path);\r\n } else {\r\n if(path === \"$item\") return local;\r\n return resolvePath(global, path);\r\n }\r\n}\r\n\r\nconst resolveProps = (global: any, local: any, props: any) => {\r\n if(!props) return;\r\n if(\"$bind\" in props) return get(global, local, props.$bind); // $bind may be falsy value\r\n Object.keys(props).forEach((key) => {\r\n const val = props[key];\r\n if(typeof val === \"object\"){\r\n props[key] = resolveProps(global, local, val);\r\n }\r\n })\r\n return props;\r\n}\r\n\r\nexport interface SchemaNode {\r\n type?: string;\r\n props?: Record<string, any>;\r\n children?: (SchemaNode | string)[];\r\n source?: string;\r\n template?: SchemaNode;\r\n $bind?: string;\r\n}\r\n\r\nexport interface RendererProps {\r\n schema: SchemaNode | string; // string occurs recursively\r\n global: any;\r\n local?: any;\r\n components: Record<string, ComponentType<any> | string>;\r\n}\r\n\r\nexport function Renderer({\r\n schema, global, local, components\r\n}: RendererProps) {\r\n if(typeof schema === \"string\") return <>{schema}</>;\r\n if(schema.$bind) {\r\n return <>{get(global, local, schema.$bind)}</>\r\n }\r\n\r\n if(schema.type === '__ForEach__' && schema.source && schema.template){\r\n const sourceArr = get(global, local, schema.source);\r\n if(!Array.isArray(sourceArr)) return null;\r\n\r\n return <>\r\n {sourceArr.map((item, index) => {\r\n return <Renderer\r\n key={index}\r\n schema={schema.template!}\r\n global={global}\r\n local={item}\r\n components={components}\r\n />\r\n })}\r\n </>\r\n }\r\n\r\n if(!schema.type) return null;\r\n\r\n const Component = components[schema.type] || schema.type;\r\n return <Component {...resolveProps(global, local, schema.props)}>\r\n {schema.children?.map((item, index) => {\r\n return <Renderer\r\n key={index}\r\n schema={item}\r\n global={global}\r\n local={local}\r\n components={components}\r\n />\r\n })}\r\n </Component>\r\n}\r\n","import { SchemaNode } from \"./Renderer\"\r\n\r\nconst endDelimiter = \"</UISchema>\"\r\nexport function parseResponse(llmResponse: string): SchemaNode[] {\r\n const split = llmResponse.split(/\\<UISchema index=\"\\d+\">/m).slice(1).map(e => e.trim())\r\n const contents = split.map(e => e.slice(0, -endDelimiter.length));\r\n const parsed = contents.map(e => JSON.parse(e))\r\n return parsed\r\n}","<system_persona>\r\nYou are the **UI Schema Generation Engine**, a specialized architect responsible for converting raw data structures into abstract, reusable React Interface Schemas (JSON-DSL).\r\n\r\nYour output is **NOT** code. Your output is a JSON-based Abstract Syntax Tree (AST) that describes the UI structure. The rendering engine will hydrate this schema with data later.\r\n</system_persona>\r\n\r\n<core_philosophy>\r\n1. **Separation of Concerns:** You define the *structure*. You do NOT hardcode *values*.\r\n2. **Strict Adherence:** You may ONLY use components explicitly listed in the `<AllowedComponents>` block of the input. If the block is missing or empty, revert to the <default_component_library>.\r\n3. **Semantic Structure:** Even though you are generating JSON, the resulting UI must be semantically correct (using proper hierarchy, semantic HTML tags, and logical grouping).\r\n4. **Reusability:** Your schema must be valid regardless of the specific values in the data. It must handle list lengths of 0 or 1000 gracefully using the Iterator Protocol.\r\n</core_philosophy>\r\n\r\n<dsl_syntax_rules>\r\nThe output must be a JSON object adhering to this strict recursive interface:\r\n\r\n### 1. The Standard Node\r\nUsed for HTML tags or Custom Components.\r\n```json\r\n{\r\n \"type\": \"div\" | \"h1\" | \"MyCustomComponent\",\r\n \"props\": { \"className\": \"...\", \"customProp\": \"...\" },\r\n \"children\": [] // Array of Nodes or Strings\r\n}\r\n```\r\n\r\n### 2. The Binding Protocol (`$bind`)\r\n\r\n**NEVER** output raw data values (e.g., \"John\", \"john@email.com\") in the schema.\r\nInstead, bind to a path.\r\n\r\n```json\r\n// BAD\r\n{ \"type\": \"span\", \"children\": [\"John\"] }\r\n\r\n// GOOD\r\n{ \"type\": \"span\", \"children\": [{ \"$bind\": \"user.firstName\" }] }\r\n```\r\n\r\nYou have access to exactly **two scopes** at any time:\r\n- **Global Scope (Root)**: Any path **WITHOUT** the `$item` prefix accesses the top-level global data object. This is available at any nesting depth.\r\n - *Example:* `\"$bind\": \"pageTitle\"` (Always looks at `data.pageTitle`)\r\n- **Local Scope (Current Item):** Any path **STARTING WITH** `$item` accesses the immediate object currently being iterated in a loop.\r\n - *Example:* `\"$bind\": \"$item.name\"` (Looks at `name` on the current loop item).\r\n - *Example:* `\"$bind\": \"$item\"` (Renders the current loop item, usually a string).\r\n\r\nIn special cases, you may need to reference a specific, fixed index in an array. To do that, use dot notation to access the index. For instance: `arr.1.property` accesses the `property` property of the 2nd item in `arr`. However, use this conservatively; prefer to use the Iterator Protocol unless it doesn't make sense (e.g., it's a static array).\r\n\r\n**CRITICAL:** Intermediate scopes are not accessible. Inside a nested loop, `$item` refers *only* to the innermost item.\r\n\r\n### 3. The Iterator Protocol (`__ForEach__`)\r\n\r\nIf the data value is an Array, you MUST use this node. Do not manually unroll lists.\r\n\r\n- **Root Arrays**: If the input value is the array itself, use \"source\": \"$\".\r\n- **Nested Arrays**: If the array is a property on the current item, use `\"source\": \"$item.path.to.array\"`.\r\n- **Global Arrays**: If the array is a property on the Global Root, use `\"source\": \"path.to.array\"`.\r\n\r\n```json\r\n{\r\n \"type\": \"__ForEach__\",\r\n \"source\": \"$\" | \"$item.path.to.array\" | \"path.to.array\",\r\n \"template\": {\r\n // This is the shape of a SINGLE item.\r\n // Inside here, use \"$item\" to refer to the current array element.\r\n \"type\": \"li\",\r\n \"children\": [{ \"$bind\": \"$item.name\" }]\r\n }\r\n}\r\n```\r\n\r\n</dsl_syntax_rules>\r\n\r\n<default_component_library>\r\nIf no specific allowed components are provided, you have access to this semantic HTML suite:\r\n\r\n * **Layout:** `div`, `section`, `article`, `main`, `aside`, `header`, `footer`\r\n * **Typography:** `h1`, `h2`, `h3`, `p`, `span`, `strong`, `em`, `blockquote`, `pre`, `code`\r\n * **Lists:** `ul`, `ol`, `li`\r\n * **Interaction:** `button`, `a` (use href prop), `details`, `summary`\r\n * **Form:** `input`, `label`, `textarea`, `select`, `option`\r\n * **Media:** `img`, `figure`, `figcaption`\r\n\r\n</default_component_library>\r\n\r\n<input_processing_rules>\r\nThe user will provide one or more `<GeneratedContent>` blocks.\r\n\r\n1. **Parse `AllowedComponents`:** A comma-separated list.\r\n * Lowercase = Native HTML tags.\r\n * Uppercase = Custom React Components.\r\n2. **Parse `ComponentContext`:** Defines the TypeScript interface for Custom Components.\r\n * *CRITICAL:* You must strictly adhere to the prop names and types defined here. Do not hallucinate props for custom components.\r\n * Components are separated by a comma, in the format `ComponentName [props: { ... }, details: \"...\"]`. The `props` indicate what `props` it must accept, in Typescript format. The `details` is an optional field, and describes what the component does. Use this information in whatever way to improve your generation output. If you encounter a complex type in `props`, look at the input values and make your best guess at what value is the best fit.\r\n3. **Parse `UserContext`:** This is anything the developer believes is relevant for your task. It could describe a specific UI style or the correct way to use a custom component.\r\n * *CRITICAL*: To the best of your ability, respect the developer's wishes. If no UserContext is provided, you should accomplish the task as you see fit, with no constraints.\r\n * *CRITICAL*: This is only relevant to the current <GeneratedContent> block!\r\n3. **Parse `Value`:** The JSON data structure you are building the UI for.\r\n\r\nAdditionally, the user may provide a <PageContext> before all <GeneratedContent> blocks. Think of this as a global UserContext. This is meant to provide additional context and guiding when designing the UI, which you should try to adhere to. If none is provided, accomplish the task as you see fit, with no constraints.\r\n\r\n</input_processing_rules>\r\n\r\n<output_formatting>\r\nFor every `<GeneratedContent>` input block, you must generate exactly one `<UISchema>` output block.\r\nThe order must be preserved.\r\n\r\nInput:\r\n<PageContext></PageContext>\r\n<GeneratedContent> ... </GeneratedContent> (Section 1)\r\n<GeneratedContent> ... </GeneratedContent> (Section 2)\r\n\r\nOutput:\r\n<UISchema index=\"0\"> ...JSON... </UISchema>\r\n<UISchema index=\"1\"> ...JSON... </UISchema>\r\n</output_formatting>\r\n\r\n<examples>\r\n**Input:**\r\n<GeneratedContent>\r\n<AllowedComponents>div,span,Avatar</AllowedComponents>\r\n<ComponentContext>Avatar [props: { url: string }]</ComponentContext>\r\n<UserContext>grouped under one div</UserContext>\r\n<Value>{ authors: [{ name: \"J.K.\", img: \"...\" }, { name: \"Tolkien\", img: \"...\" }] }</Value>\r\n</GeneratedContent>\r\n\r\n**Correct Output:**\r\n<UISchema index=\"0\">\r\n{\r\n \"type\": \"div\",\r\n \"props\": {\r\n \"className\": \"author-list\"\r\n },\r\n \"children\": [\r\n {\r\n \"type\": \"__ForEach__\",\r\n \"source\": \"authors\",\r\n \"template\": {\r\n \"type\": \"div\",\r\n \"props\": {\r\n \"className\": \"author-card\"\r\n },\r\n \"children\": [\r\n {\r\n \"type\": \"Avatar\",\r\n \"props\": {\r\n \"url\": {\r\n \"$bind\": \"$item.img\"\r\n }\r\n }\r\n },\r\n {\r\n \"type\": \"span\",\r\n \"children\": [\r\n {\r\n \"$bind\": \"$item.name\"\r\n }\r\n ]\r\n }\r\n ]\r\n }\r\n }\r\n ]\r\n}\r\n</UISchema>\r\n</examples>\r\n\r\n<reasoning_requirements>\r\nBefore generating the JSON, briefly analyze the data structure to identify arrays (requiring `__ForEach__`) and custom component opportunities. Use the mental scratchpad if necessary, but keep the final output strictly within `<UISchema>` tags.\r\n</reasoning_requirements>\r\n\r\n<IMPORTANT>\r\nDo NOT output anything except the UISchema.\r\n</IMPORTANT>","import { isValidElement } from 'react';\r\nimport { GeneratedContentProps, SIGNATURE } from \"./GeneratedContent\";\r\nimport { Renderer, SchemaNode } from \"./Renderer\";\r\nimport { SyntuxComponent, SyntuxElement } from \"./types\";\r\nimport { parseResponse } from \"./util\";\r\nimport { generateText } from \"ai\";\r\nimport systemPrompt from './prompt.md';\r\n\r\nimport { type LanguageModel } from 'ai';\r\n\r\nexport interface GeneratedPageProps {\r\n context?: string;\r\n schema: SyntuxElement;\r\n onGenerate?: (result: SchemaNode[]) => void;\r\n cached?: (SchemaNode | string)[];\r\n}\r\n\r\nfunction extractChildren(element: any) {\r\n if (element?.props?.children) {\r\n let children = element.props.children;\r\n if (!Array.isArray(children)) children = [children];\r\n return children;\r\n }\r\n return [];\r\n}\r\n\r\nfunction searchChildren(element: SyntuxElement, acc: ContentSchema[]) {\r\n if(!isValidElement(element)) return;\r\n\r\n if(element.type.identifier === SIGNATURE){\r\n const { values, components, hint } = element.props as GeneratedContentProps;\r\n const realComponents: any = []\r\n\r\n if (components) {\r\n components.forEach((comp: string | SyntuxComponent) => {\r\n if (typeof comp === \"string\") {\r\n realComponents.push({\r\n llmName: comp\r\n })\r\n } else {\r\n realComponents.push({\r\n llmName: comp.llmName,\r\n llmContext: comp.llmContext,\r\n userContext: comp.userContext\r\n })\r\n }\r\n })\r\n }\r\n acc.push({\r\n values, components: realComponents, hint: hint || \"\"\r\n })\r\n } else {\r\n const children = extractChildren(element);\r\n children.forEach((child: SyntuxElement) => {\r\n searchChildren(child, acc)\r\n })\r\n }\r\n}\r\n\r\nfunction generateInput(content: ContentSchema[], context?: string) {\r\n let str = '';\r\n if (context) {\r\n str = `<PageContext>${context}</PageContext>\\n`;\r\n }\r\n\r\n content.forEach(schema => {\r\n const allowedComponents = schema.components.map(e => e.llmName);\r\n const componentContext: any = []\r\n schema.components.forEach(comp => {\r\n if (comp.llmContext) {\r\n let contextStr;\r\n if (comp.userContext) {\r\n contextStr = `${comp.llmName} [${comp.llmContext}, details: ${comp.userContext}]`\r\n } else {\r\n contextStr = `${comp.llmName} [${comp.llmContext}]`;\r\n }\r\n componentContext.push(contextStr)\r\n }\r\n })\r\n const userContext = schema.hint;\r\n const value = JSON.stringify(schema.values);\r\n\r\n str += `<GeneratedContent>\r\n <AllowedComponents>${allowedComponents.join(',')}</AllowedComponents>\r\n <ComponentContext>${componentContext.join(',')}</ComponentContext>\r\n <UserContext>${userContext}</UserContext>\r\n <Value>${value}</Value>\r\n</GeneratedContent>\\n`\r\n })\r\n\r\n return str;\r\n}\r\n\r\nfunction createComponentRegistry(components: (SyntuxComponent<any> | string)[] | undefined) {\r\n if (!components) return {};\r\n return components.reduce((acc: Record<string, SyntuxComponent<any> | string>, curr: SyntuxComponent<any> | string) => {\r\n if (typeof curr === \"string\") {\r\n acc[curr] = curr;\r\n } else {\r\n if (curr.llmName) {\r\n acc[curr.llmName] = curr;\r\n }\r\n }\r\n return acc;\r\n }, {})\r\n}\r\n\r\nfunction hydrate(schema: SyntuxElement, dsl: (SchemaNode | string)[]) {\r\n let componentIndex = 0;\r\n function swapChildren(element: SyntuxElement) {\r\n if(!isValidElement(element)) return element;\r\n\r\n if(element.type.identifier === SIGNATURE){\r\n const { values, components, hint } = element.props as GeneratedContentProps;\r\n return <Renderer key={componentIndex} schema={dsl[componentIndex++]} global={values} local={values} components={createComponentRegistry(components)} />;\r\n }\r\n\r\n\r\n const children = extractChildren(element);\r\n\r\n if(children.length == 0){\r\n return element;\r\n }\r\n\r\n return children.map((child: SyntuxElement, ind: number) => {\r\n return swapChildren(child);\r\n })\r\n }\r\n\r\n return swapChildren(schema);\r\n}\r\n\r\ninterface ContentSchema {\r\n values: any;\r\n components: { llmContext?: string, userContext?: string, llmName: string }[];\r\n hint: string;\r\n}\r\n\r\nexport const createGeneratedPage = (model: LanguageModel) => {\r\n /**\r\n * Container for content generation. Batches all <GeneratedContent> blocks into one LLM call.\r\n * \r\n * @param context Custom instructions for the LLM about the page, applicable to all components.\r\n * @param schema The structure of the page. Can be a mix of any type of component.\r\n * @param cached User provided React Interface Schema. Will skip schema generation if one is provided.\r\n * @param onGenerate Callback for receiving React Interface Schema after generation, to be used for caching. \r\n */\r\n return async function GeneratedPage({\r\n context, schema, cached, onGenerate\r\n }: GeneratedPageProps) {\r\n if(cached){\r\n return <>{hydrate(schema, cached)}</>\r\n }\r\n\r\n const contents: ContentSchema[] = [];\r\n searchChildren(schema, contents);\r\n console.log('contents', contents);\r\n \r\n if(contents.length == 0) return schema;\r\n\r\n const llmInput = generateInput(contents, context);\r\n\r\n const { text: llmResponse } = await generateText({\r\n model,\r\n system: systemPrompt,\r\n prompt: llmInput\r\n })\r\n const parsedResponse = parseResponse(llmResponse)\r\n\r\n if(onGenerate){\r\n onGenerate(parsedResponse)\r\n }\r\n \r\n return <>{hydrate(schema, parsedResponse)}</>\r\n }\r\n}","import { LanguageModel } from 'ai';\r\nimport { createGeneratedPage } from './GeneratedPage';\r\nimport { GeneratedContent } from './GeneratedContent';\r\nimport { Renderer } from './Renderer';\r\n\r\nexport { GeneratedContentProps } from './GeneratedContent';\r\nexport { GeneratedPageProps } from './GeneratedPage';\r\nexport {SchemaNode} from './Renderer';\r\n\r\nexport interface SyntuxFactoryConfig {\r\n model: LanguageModel;\r\n}\r\n\r\n\r\nexport const createSyntuxFactory = (config: SyntuxFactoryConfig) => {\r\n return {\r\n GeneratedPage: createGeneratedPage(config.model),\r\n GeneratedContent,\r\n Renderer\r\n }\r\n}"]}
|
package/dist/plugin.d.mts
DELETED
package/dist/plugin.d.ts
DELETED
package/dist/plugin.js
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __commonJS = (cb, mod) => function __require() {
|
|
5
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
// src/plugin.ts
|
|
9
|
-
var require_plugin = __commonJS({
|
|
10
|
-
"src/plugin.ts"(exports$1, module) {
|
|
11
|
-
module.exports = function({ types: t }) {
|
|
12
|
-
function extractProps(state, params) {
|
|
13
|
-
let signature = "props: ( empty )";
|
|
14
|
-
if (params.length > 0) {
|
|
15
|
-
const start = params[0].start;
|
|
16
|
-
const end = params[params.length - 1].end;
|
|
17
|
-
signature = `props: (${state.file.code.slice(start, end)})`;
|
|
18
|
-
}
|
|
19
|
-
return signature;
|
|
20
|
-
}
|
|
21
|
-
function contextAssignment(name, signature) {
|
|
22
|
-
return t.expressionStatement(
|
|
23
|
-
t.assignmentExpression(
|
|
24
|
-
"=",
|
|
25
|
-
t.memberExpression(t.identifier(name), t.identifier("llmContext")),
|
|
26
|
-
t.stringLiteral(signature)
|
|
27
|
-
)
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
function nameAssignment(name) {
|
|
31
|
-
return t.expressionStatement(
|
|
32
|
-
t.assignmentExpression(
|
|
33
|
-
"=",
|
|
34
|
-
t.memberExpression(t.identifier(name), t.identifier("llmName")),
|
|
35
|
-
t.stringLiteral(name)
|
|
36
|
-
)
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
return {
|
|
40
|
-
visitor: {
|
|
41
|
-
/**
|
|
42
|
-
* functional components.
|
|
43
|
-
*/
|
|
44
|
-
FunctionDeclaration(path, state) {
|
|
45
|
-
const { node } = path;
|
|
46
|
-
if (!node.id) return;
|
|
47
|
-
const name = node.id.name;
|
|
48
|
-
if (!/^[A-Z]/.test(name)) return;
|
|
49
|
-
const params = node.params;
|
|
50
|
-
const props = extractProps(state, params);
|
|
51
|
-
path.insertAfter([contextAssignment(name, props), nameAssignment(name)]);
|
|
52
|
-
},
|
|
53
|
-
/**
|
|
54
|
-
* arrow function components.
|
|
55
|
-
*/
|
|
56
|
-
VariableDeclarator(path, state) {
|
|
57
|
-
const { node } = path;
|
|
58
|
-
if (!t.isIdentifier(node.id)) return;
|
|
59
|
-
const name = node.id.name;
|
|
60
|
-
if (!/^[A-Z]/.test(name)) return;
|
|
61
|
-
if (!t.isArrowFunctionExpression(node.init) && !t.isFunctionExpression(node.init)) return;
|
|
62
|
-
const params = node.init.params;
|
|
63
|
-
const props = extractProps(state, params);
|
|
64
|
-
path.parentPath.insertAfter([contextAssignment(name, props), nameAssignment(name)]);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
var plugin = require_plugin();
|
|
72
|
-
|
|
73
|
-
module.exports = plugin;
|
|
74
|
-
//# sourceMappingURL=plugin.js.map
|
|
75
|
-
//# sourceMappingURL=plugin.js.map
|
package/dist/plugin.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/plugin.ts"],"names":["exports"],"mappings":";;;;;;;;AAAA,IAAA,cAAA,GAAA,UAAA,CAAA;AAAA,EAAA,eAAA,CAAAA,SAAA,EAAA,MAAA,EAAA;AAAA,IAAA,MAAA,CAAO,OAAA,GAAU,SAAU,EAAE,KAAA,EAAO,GAAE,EAAG;AAErC,MAAA,SAAS,YAAA,CAAa,OAAO,MAAA,EAAQ;AACnC,QAAA,IAAI,SAAA,GAAY,kBAAA;AAEhB,QAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,UAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,CAAC,CAAA,CAAE,KAAA;AACxB,UAAA,MAAM,GAAA,GAAM,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAC,CAAA,CAAE,GAAA;AACtC,UAAA,SAAA,GAAY,WAAW,KAAA,CAAM,IAAA,CAAK,KAAK,KAAA,CAAM,KAAA,EAAO,GAAG,CAAC,CAAA,CAAA,CAAA;AAAA,QAC1D;AAEA,QAAA,OAAO,SAAA;AAAA,MACT;AAGA,MAAA,SAAS,iBAAA,CAAkB,MAAM,SAAA,EAAW;AAC1C,QAAA,OAAO,CAAA,CAAE,mBAAA;AAAA,UACP,CAAA,CAAE,oBAAA;AAAA,YACA,GAAA;AAAA,YACA,CAAA,CAAE,iBAAiB,CAAA,CAAE,UAAA,CAAW,IAAI,CAAA,EAAG,CAAA,CAAE,UAAA,CAAW,YAAY,CAAC,CAAA;AAAA,YACjE,CAAA,CAAE,cAAc,SAAS;AAAA;AAC3B,SACF;AAAA,MACF;AAGA,MAAA,SAAS,eAAe,IAAA,EAAK;AAC3B,QAAA,OAAO,CAAA,CAAE,mBAAA;AAAA,UACP,CAAA,CAAE,oBAAA;AAAA,YACA,GAAA;AAAA,YACA,CAAA,CAAE,iBAAiB,CAAA,CAAE,UAAA,CAAW,IAAI,CAAA,EAAG,CAAA,CAAE,UAAA,CAAW,SAAS,CAAC,CAAA;AAAA,YAC9D,CAAA,CAAE,cAAc,IAAI;AAAA;AACtB,SACF;AAAA,MACF;AAEA,MAAA,OAAO;AAAA,QACL,OAAA,EAAS;AAAA;AAAA;AAAA;AAAA,UAIP,mBAAA,CAAoB,MAAM,KAAA,EAAO;AAC/B,YAAA,MAAM,EAAE,MAAK,GAAI,IAAA;AACjB,YAAA,IAAI,CAAC,KAAK,EAAA,EAAI;AAEd,YAAA,MAAM,IAAA,GAAO,KAAK,EAAA,CAAG,IAAA;AACrB,YAAA,IAAI,CAAC,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA,EAAG;AAE1B,YAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,YAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,KAAA,EAAO,MAAM,CAAA;AAExC,YAAA,IAAA,CAAK,WAAA,CAAY,CAAC,iBAAA,CAAkB,IAAA,EAAM,KAAK,CAAA,EAAG,cAAA,CAAe,IAAI,CAAC,CAAC,CAAA;AAAA,UACzE,CAAA;AAAA;AAAA;AAAA;AAAA,UAKA,kBAAA,CAAmB,MAAM,KAAA,EAAO;AAC9B,YAAA,MAAM,EAAE,MAAK,GAAI,IAAA;AACjB,YAAA,IAAI,CAAC,CAAA,CAAE,YAAA,CAAa,IAAA,CAAK,EAAE,CAAA,EAAG;AAE9B,YAAA,MAAM,IAAA,GAAO,KAAK,EAAA,CAAG,IAAA;AACrB,YAAA,IAAI,CAAC,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA,EAAG;AAE1B,YAAA,IAAI,CAAC,CAAA,CAAE,yBAAA,CAA0B,IAAA,CAAK,IAAI,CAAA,IACxC,CAAC,CAAA,CAAE,oBAAA,CAAqB,IAAA,CAAK,IAAI,CAAA,EAAG;AAEtC,YAAA,MAAM,MAAA,GAAS,KAAK,IAAA,CAAK,MAAA;AACzB,YAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,KAAA,EAAO,MAAM,CAAA;AAExC,YAAA,IAAA,CAAK,UAAA,CAAW,WAAA,CAAY,CAAC,iBAAA,CAAkB,IAAA,EAAM,KAAK,CAAA,EAAG,cAAA,CAAe,IAAI,CAAC,CAAC,CAAA;AAAA,UACpF;AAAA;AACF,OACF;AAAA,IACF,CAAA;AAAA,EAAA;AAAA,CAAA,CAAA","file":"plugin.js","sourcesContent":["module.exports = function ({ types: t }) {\r\n // pulls props list verbatim from file for maximum context\r\n function extractProps(state, params) {\r\n let signature = \"props: ( empty )\";\r\n \r\n if (params.length > 0) {\r\n const start = params[0].start;\r\n const end = params[params.length - 1].end;\r\n signature = `props: (${state.file.code.slice(start, end)})`;\r\n }\r\n \r\n return signature;\r\n }\r\n \r\n // create expression name.llmContext = signature\r\n function contextAssignment(name, signature) {\r\n return t.expressionStatement(\r\n t.assignmentExpression(\r\n \"=\",\r\n t.memberExpression(t.identifier(name), t.identifier(\"llmContext\")),\r\n t.stringLiteral(signature)\r\n )\r\n );\r\n }\r\n\r\n // create expression name.llmName = name\r\n function nameAssignment(name){\r\n return t.expressionStatement(\r\n t.assignmentExpression(\r\n \"=\",\r\n t.memberExpression(t.identifier(name), t.identifier(\"llmName\")),\r\n t.stringLiteral(name)\r\n )\r\n ); \r\n }\r\n \r\n return {\r\n visitor: {\r\n /**\r\n * functional components.\r\n */\r\n FunctionDeclaration(path, state) {\r\n const { node } = path;\r\n if (!node.id) return;\r\n \r\n const name = node.id.name;\r\n if (!/^[A-Z]/.test(name)) return;\r\n \r\n const params = node.params;\r\n const props = extractProps(state, params);\r\n \r\n path.insertAfter([contextAssignment(name, props), nameAssignment(name)]);\r\n },\r\n \r\n /**\r\n * arrow function components.\r\n */\r\n VariableDeclarator(path, state) {\r\n const { node } = path;\r\n if (!t.isIdentifier(node.id)) return;\r\n \r\n const name = node.id.name;\r\n if (!/^[A-Z]/.test(name)) return;\r\n \r\n if (!t.isArrowFunctionExpression(node.init) &&\r\n !t.isFunctionExpression(node.init)) return;\r\n \r\n const params = node.init.params;\r\n const props = extractProps(state, params);\r\n \r\n path.parentPath.insertAfter([contextAssignment(name, props), nameAssignment(name)]);\r\n },\r\n },\r\n };\r\n };"]}
|
package/dist/plugin.mjs
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
2
|
-
var __commonJS = (cb, mod) => function __require() {
|
|
3
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
// src/plugin.ts
|
|
7
|
-
var require_plugin = __commonJS({
|
|
8
|
-
"src/plugin.ts"(exports$1, module) {
|
|
9
|
-
module.exports = function({ types: t }) {
|
|
10
|
-
function extractProps(state, params) {
|
|
11
|
-
let signature = "props: ( empty )";
|
|
12
|
-
if (params.length > 0) {
|
|
13
|
-
const start = params[0].start;
|
|
14
|
-
const end = params[params.length - 1].end;
|
|
15
|
-
signature = `props: (${state.file.code.slice(start, end)})`;
|
|
16
|
-
}
|
|
17
|
-
return signature;
|
|
18
|
-
}
|
|
19
|
-
function contextAssignment(name, signature) {
|
|
20
|
-
return t.expressionStatement(
|
|
21
|
-
t.assignmentExpression(
|
|
22
|
-
"=",
|
|
23
|
-
t.memberExpression(t.identifier(name), t.identifier("llmContext")),
|
|
24
|
-
t.stringLiteral(signature)
|
|
25
|
-
)
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
function nameAssignment(name) {
|
|
29
|
-
return t.expressionStatement(
|
|
30
|
-
t.assignmentExpression(
|
|
31
|
-
"=",
|
|
32
|
-
t.memberExpression(t.identifier(name), t.identifier("llmName")),
|
|
33
|
-
t.stringLiteral(name)
|
|
34
|
-
)
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
return {
|
|
38
|
-
visitor: {
|
|
39
|
-
/**
|
|
40
|
-
* functional components.
|
|
41
|
-
*/
|
|
42
|
-
FunctionDeclaration(path, state) {
|
|
43
|
-
const { node } = path;
|
|
44
|
-
if (!node.id) return;
|
|
45
|
-
const name = node.id.name;
|
|
46
|
-
if (!/^[A-Z]/.test(name)) return;
|
|
47
|
-
const params = node.params;
|
|
48
|
-
const props = extractProps(state, params);
|
|
49
|
-
path.insertAfter([contextAssignment(name, props), nameAssignment(name)]);
|
|
50
|
-
},
|
|
51
|
-
/**
|
|
52
|
-
* arrow function components.
|
|
53
|
-
*/
|
|
54
|
-
VariableDeclarator(path, state) {
|
|
55
|
-
const { node } = path;
|
|
56
|
-
if (!t.isIdentifier(node.id)) return;
|
|
57
|
-
const name = node.id.name;
|
|
58
|
-
if (!/^[A-Z]/.test(name)) return;
|
|
59
|
-
if (!t.isArrowFunctionExpression(node.init) && !t.isFunctionExpression(node.init)) return;
|
|
60
|
-
const params = node.init.params;
|
|
61
|
-
const props = extractProps(state, params);
|
|
62
|
-
path.parentPath.insertAfter([contextAssignment(name, props), nameAssignment(name)]);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
var plugin = require_plugin();
|
|
70
|
-
|
|
71
|
-
export { plugin as default };
|
|
72
|
-
//# sourceMappingURL=plugin.mjs.map
|
|
73
|
-
//# sourceMappingURL=plugin.mjs.map
|
package/dist/plugin.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/plugin.ts"],"names":["exports"],"mappings":"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","file":"plugin.mjs","sourcesContent":["module.exports = function ({ types: t }) {\r\n // pulls props list verbatim from file for maximum context\r\n function extractProps(state, params) {\r\n let signature = \"props: ( empty )\";\r\n \r\n if (params.length > 0) {\r\n const start = params[0].start;\r\n const end = params[params.length - 1].end;\r\n signature = `props: (${state.file.code.slice(start, end)})`;\r\n }\r\n \r\n return signature;\r\n }\r\n \r\n // create expression name.llmContext = signature\r\n function contextAssignment(name, signature) {\r\n return t.expressionStatement(\r\n t.assignmentExpression(\r\n \"=\",\r\n t.memberExpression(t.identifier(name), t.identifier(\"llmContext\")),\r\n t.stringLiteral(signature)\r\n )\r\n );\r\n }\r\n\r\n // create expression name.llmName = name\r\n function nameAssignment(name){\r\n return t.expressionStatement(\r\n t.assignmentExpression(\r\n \"=\",\r\n t.memberExpression(t.identifier(name), t.identifier(\"llmName\")),\r\n t.stringLiteral(name)\r\n )\r\n ); \r\n }\r\n \r\n return {\r\n visitor: {\r\n /**\r\n * functional components.\r\n */\r\n FunctionDeclaration(path, state) {\r\n const { node } = path;\r\n if (!node.id) return;\r\n \r\n const name = node.id.name;\r\n if (!/^[A-Z]/.test(name)) return;\r\n \r\n const params = node.params;\r\n const props = extractProps(state, params);\r\n \r\n path.insertAfter([contextAssignment(name, props), nameAssignment(name)]);\r\n },\r\n \r\n /**\r\n * arrow function components.\r\n */\r\n VariableDeclarator(path, state) {\r\n const { node } = path;\r\n if (!t.isIdentifier(node.id)) return;\r\n \r\n const name = node.id.name;\r\n if (!/^[A-Z]/.test(name)) return;\r\n \r\n if (!t.isArrowFunctionExpression(node.init) &&\r\n !t.isFunctionExpression(node.init)) return;\r\n \r\n const params = node.init.params;\r\n const props = extractProps(state, params);\r\n \r\n path.parentPath.insertAfter([contextAssignment(name, props), nameAssignment(name)]);\r\n },\r\n },\r\n };\r\n };"]}
|