@xyd-js/composer 0.1.0-xyd.2

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/CHANGELOG.md ADDED
@@ -0,0 +1,69 @@
1
+ # @xyd-js/themes
2
+
3
+ ## 0.1.0-xyd.2
4
+
5
+ ### Patch Changes
6
+
7
+ - test
8
+ - Updated dependencies
9
+ - @xyd-js/atlas@0.1.0-xyd.18
10
+ - @xyd-js/content@0.1.0-xyd.16
11
+ - @xyd-js/context@0.1.0-xyd.2
12
+ - @xyd-js/core@0.1.0-xyd.15
13
+ - @xyd-js/uniform@0.1.0-xyd.17
14
+
15
+ ## 0.1.0-xyd.1
16
+
17
+ ### Patch Changes
18
+
19
+ - update packages
20
+ - Updated dependencies
21
+ - @xyd-js/atlas@0.1.0-xyd.17
22
+ - @xyd-js/content@0.1.0-xyd.15
23
+ - @xyd-js/context@0.1.0-xyd.1
24
+ - @xyd-js/core@0.1.0-xyd.14
25
+ - @xyd-js/uniform@0.1.0-xyd.16
26
+
27
+ ## 0.1.1-xyd.3
28
+
29
+ ### Patch Changes
30
+
31
+ - version
32
+ - Updated dependencies
33
+ - @xyd-js/atlas@0.1.0-xyd.16
34
+ - @xyd-js/components@0.1.0-xyd.11
35
+ - @xyd-js/framework@0.1.0-xyd.32
36
+ - @xyd-js/ui@0.1.0-xyd.16
37
+
38
+ ## 0.1.1-xyd.2
39
+
40
+ ### Patch Changes
41
+
42
+ - fix again
43
+ - Updated dependencies
44
+ - @xyd-js/atlas@0.1.0-xyd.15
45
+ - @xyd-js/components@0.1.0-xyd.10
46
+ - @xyd-js/framework@0.1.0-xyd.30
47
+ - @xyd-js/ui@0.1.0-xyd.15
48
+
49
+ ## 0.1.1-xyd.1
50
+
51
+ ### Patch Changes
52
+
53
+ - fix for theme
54
+ - Updated dependencies
55
+ - @xyd-js/atlas@0.1.0-xyd.14
56
+ - @xyd-js/components@0.1.0-xyd.9
57
+ - @xyd-js/framework@0.1.0-xyd.29
58
+ - @xyd-js/ui@0.1.0-xyd.14
59
+
60
+ ## 0.1.1-xyd.0
61
+
62
+ ### Patch Changes
63
+
64
+ - refactor, ui tweaks
65
+ - Updated dependencies
66
+ - @xyd-js/atlas@0.1.0-xyd.13
67
+ - @xyd-js/components@0.1.0-xyd.8
68
+ - @xyd-js/framework@0.1.0-xyd.28
69
+ - @xyd-js/ui@0.1.0-xyd.13
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 xyd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,7 @@
1
+ * gusto - general purpose docs theme
2
+
3
+ * poetry - theme for docs with unique minimalistic design
4
+
5
+ * plato - designed for API and SDK heavy products
6
+
7
+ * picasso - theme used for creating a design system docs
@@ -0,0 +1,5 @@
1
+ declare class Composer {
2
+ private atlasMetaComponent;
3
+ }
4
+
5
+ export { Composer };
package/dist/index.js ADDED
@@ -0,0 +1,440 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
5
+ var __typeError = (msg) => {
6
+ throw TypeError(msg);
7
+ };
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
10
+ var __decoratorStart = (base) => [, , , __create((base == null ? void 0 : base[__knownSymbol("metadata")]) ?? null)];
11
+ var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
12
+ var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn;
13
+ var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) });
14
+ var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
15
+ var __runInitializers = (array, flags, self, value) => {
16
+ for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);
17
+ return value;
18
+ };
19
+ var __decorateElement = (array, flags, name, decorators, target, extra) => {
20
+ var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);
21
+ var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings[k + 5];
22
+ var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
23
+ var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc(k < 4 ? target : { get [name]() {
24
+ return __privateGet(this, extra);
25
+ }, set [name](x) {
26
+ return __privateSet(this, extra, x);
27
+ } }, name));
28
+ k ? p && k < 4 && __name(extra, (k > 2 ? "set " : k > 1 ? "get " : "") + name) : __name(target, name);
29
+ for (var i = decorators.length - 1; i >= 0; i--) {
30
+ ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
31
+ if (k) {
32
+ ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn(target, x) : (x) => name in x };
33
+ if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet : __privateMethod)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name];
34
+ if (k > 2) access.set = p ? (x, y) => __privateSet(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y;
35
+ }
36
+ it = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key] : k > 4 ? void 0 : { get: desc.get, set: desc.set } : target, ctx), done._ = 1;
37
+ if (k ^ 4 || it === void 0) __expectFn(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it);
38
+ else if (typeof it !== "object" || it === null) __typeError("Object expected");
39
+ else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn);
40
+ }
41
+ return k || __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
42
+ };
43
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
44
+ var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use the "in" operator on this value') : member.has(obj);
45
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
46
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
47
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
48
+
49
+ // src/Composer.ts
50
+ import * as React from "react";
51
+ import { toMarkdown } from "mdast-util-to-markdown";
52
+ import { mdxToMarkdown } from "mdast-util-mdx";
53
+ import { toHast } from "mdast-util-to-hast";
54
+ import { toHtml } from "hast-util-to-html";
55
+ import { parse } from "@babel/parser";
56
+ import { highlight } from "codehike/code";
57
+ import { marked } from "marked";
58
+ import { fromMarkdown } from "mdast-util-from-markdown";
59
+ import { htmlToJsx } from "html-to-jsx-transform";
60
+
61
+ // src/decorators.ts
62
+ import { registerMetaComponent } from "@xyd-js/context";
63
+ function metaComponent(name, componentName) {
64
+ return function(target, context) {
65
+ registerMetaComponent(
66
+ name,
67
+ componentName || name,
68
+ target
69
+ );
70
+ };
71
+ }
72
+
73
+ // src/Composer.ts
74
+ var _atlasMetaComponent_dec, _init;
75
+ _atlasMetaComponent_dec = [metaComponent("atlas", "Atlas")];
76
+ var Composer = class {
77
+ constructor() {
78
+ __runInitializers(_init, 5, this);
79
+ }
80
+ async atlasMetaComponent(themeSettings, props, vars, treeChilds) {
81
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
82
+ const outputVarExamples = {
83
+ groups: []
84
+ };
85
+ const oneExample = ((_a = vars.examples) == null ? void 0 : _a.length) === 1 && !Array.isArray(vars.examples[0]);
86
+ function createExampleObject(example) {
87
+ const highlighted = example.highlighted || example;
88
+ return {
89
+ codeblock: {
90
+ title: example.meta,
91
+ tabs: [
92
+ {
93
+ title: example.meta,
94
+ language: example.lang,
95
+ code: example.code,
96
+ highlighted
97
+ }
98
+ ]
99
+ }
100
+ };
101
+ }
102
+ if (oneExample) {
103
+ const example = (_b = vars.examples) == null ? void 0 : _b[0];
104
+ if (Array.isArray(example) || !example) {
105
+ return;
106
+ }
107
+ outputVarExamples.groups.push({
108
+ examples: [createExampleObject(example)]
109
+ });
110
+ } else {
111
+ (_c = vars.examples) == null ? void 0 : _c.forEach((item) => {
112
+ if (Array.isArray(item)) {
113
+ const groupTitle = item[0];
114
+ const groupExamples = item.slice(1);
115
+ const exampleGroup = {
116
+ examples: []
117
+ };
118
+ groupExamples.forEach((example) => {
119
+ if (example && typeof example === "object") {
120
+ exampleGroup.examples.push(createExampleObject(example));
121
+ }
122
+ });
123
+ if (exampleGroup.examples.length > 0) {
124
+ outputVarExamples.groups.push(exampleGroup);
125
+ }
126
+ } else if (item && typeof item === "object") {
127
+ const exampleGroup = {
128
+ examples: [createExampleObject(item)]
129
+ };
130
+ outputVarExamples.groups.push(exampleGroup);
131
+ }
132
+ });
133
+ }
134
+ const reactElements = [];
135
+ for (const child of treeChilds) {
136
+ if (isStandardMdastType(child.type)) {
137
+ const hast = toHast(child);
138
+ const html = toHtml(hast);
139
+ if (child.type === "heading" && child.depth === 1) {
140
+ const firstChild = child.children[0];
141
+ if (firstChild.type === "text") {
142
+ props.references[0].title = firstChild.value;
143
+ }
144
+ } else {
145
+ const jsx = htmlToJsx(html);
146
+ const reactTree = jsxStringToReactTree(jsx);
147
+ if (reactTree) {
148
+ reactElements.push(reactTree);
149
+ }
150
+ }
151
+ continue;
152
+ } else if (isMdxElement(child.type)) {
153
+ const jsxString = toMarkdown(child, {
154
+ extensions: [mdxToMarkdown()],
155
+ handlers: {
156
+ // TODO: find better solution how to convert such as structure?
157
+ list(node, parent, context) {
158
+ const items = node.children.map((item) => context.containerFlow(item, node)).join("\n");
159
+ return `<ul>
160
+ ${items}
161
+ </ul>`;
162
+ },
163
+ listItem(node, parent, context) {
164
+ const content = context.containerFlow(node, parent).trim();
165
+ return `<li>${content}</li>`;
166
+ }
167
+ }
168
+ });
169
+ const reactTree = jsxStringToReactTree(jsxString);
170
+ if (reactTree) {
171
+ reactElements.push(reactTree);
172
+ }
173
+ }
174
+ }
175
+ const propDescription = (_e = (_d = props.references) == null ? void 0 : _d[0]) == null ? void 0 : _e.description;
176
+ if (propDescription) {
177
+ if (typeof propDescription === "string") {
178
+ const content = propDescription.replace(/^---[\s\S]*?---\n/, "");
179
+ const md = fromMarkdown(content);
180
+ const hast = toHast(md);
181
+ const html = toHtml(hast);
182
+ const jsx = htmlToJsx(html);
183
+ const reactTree = jsxStringToReactTree(jsx);
184
+ if (reactTree) {
185
+ props.references[0].description = reactTree;
186
+ } else {
187
+ props.references[0].description = content;
188
+ }
189
+ }
190
+ }
191
+ if (reactElements.length > 0) {
192
+ if ((_g = (_f = props.references) == null ? void 0 : _f[0]) == null ? void 0 : _g.description) {
193
+ reactElements.unshift(props.references[0].description);
194
+ }
195
+ const combinedReactTree = React.createElement(React.Fragment, null, ...reactElements);
196
+ if ((_h = props.references) == null ? void 0 : _h[0]) {
197
+ props.references[0].description = combinedReactTree;
198
+ }
199
+ }
200
+ if (!outputVarExamples.groups.length && ((_j = (_i = props.references[0]) == null ? void 0 : _i.examples.groups) == null ? void 0 : _j.length)) {
201
+ const promises = [];
202
+ (_k = props.references[0].examples) == null ? void 0 : _k.groups.forEach((group) => {
203
+ group.examples.forEach((example) => {
204
+ example.codeblock.tabs.forEach((tab) => {
205
+ async function highlightCode() {
206
+ var _a2;
207
+ const highlighted = await highlight({
208
+ value: tab.code,
209
+ lang: tab.language,
210
+ meta: tab.title
211
+ }, ((_a2 = themeSettings == null ? void 0 : themeSettings.coder) == null ? void 0 : _a2.syntaxHighlight) || "github-dark");
212
+ tab.highlighted = highlighted;
213
+ }
214
+ promises.push(highlightCode());
215
+ });
216
+ });
217
+ });
218
+ await Promise.all(promises);
219
+ } else {
220
+ if ((_l = props.references) == null ? void 0 : _l[0]) {
221
+ props.references[0].examples = outputVarExamples;
222
+ }
223
+ }
224
+ if ((_n = (_m = props.references) == null ? void 0 : _m[0]) == null ? void 0 : _n.definitions) {
225
+ props.references[0].definitions = processDefinitionProperties(props.references[0].definitions);
226
+ }
227
+ return props;
228
+ }
229
+ };
230
+ _init = __decoratorStart(null);
231
+ __decorateElement(_init, 1, "atlasMetaComponent", _atlasMetaComponent_dec, Composer);
232
+ __decoratorMetadata(_init, Composer);
233
+ function buildElement(node) {
234
+ if (!node) return null;
235
+ switch (node.type) {
236
+ case "JSXElement": {
237
+ let type;
238
+ const nameNode = node.openingElement.name;
239
+ if (nameNode.type === "JSXMemberExpression") {
240
+ const parts = [];
241
+ let curr = nameNode;
242
+ while (curr) {
243
+ if (curr.property) parts.unshift(curr.property.name);
244
+ curr = curr.object;
245
+ }
246
+ type = parts.join(".");
247
+ } else {
248
+ type = nameNode.name;
249
+ }
250
+ const props = {};
251
+ for (const attr of node.openingElement.attributes) {
252
+ if (attr.type === "JSXSpreadAttribute") {
253
+ Object.assign(props, evaluateExpression(attr.argument));
254
+ continue;
255
+ }
256
+ const key = attr.name.name;
257
+ let value;
258
+ if (!attr.value) {
259
+ value = true;
260
+ } else if (attr.value.type === "StringLiteral" || attr.value.type === "NumericLiteral" || attr.value.type === "BooleanLiteral") {
261
+ value = attr.value.value;
262
+ } else if (attr.value.type === "JSXExpressionContainer") {
263
+ value = evaluateExpression(attr.value.expression);
264
+ }
265
+ props[key] = value;
266
+ }
267
+ const children = node.children.map((child) => {
268
+ if (child.type === "JSXText") {
269
+ const text = child.value.replace(/\s+/g, " ");
270
+ return text.trim() ? text : null;
271
+ }
272
+ if (child.type === "JSXExpressionContainer") {
273
+ return child.expression.type === "JSXElement" || child.expression.type === "JSXFragment" ? buildElement(child.expression) : evaluateExpression(child.expression);
274
+ }
275
+ if (child.type === "JSXElement" || child.type === "JSXFragment") {
276
+ return buildElement(child);
277
+ }
278
+ return null;
279
+ }).filter((c) => c !== null);
280
+ return React.createElement(type, props, ...children);
281
+ }
282
+ case "JSXFragment": {
283
+ const children = node.children.map(
284
+ (child) => child.type === "JSXElement" || child.type === "JSXFragment" ? buildElement(child) : child.type === "JSXText" ? child.value.trim() || null : null
285
+ ).filter(Boolean);
286
+ return React.createElement(React.Fragment, null, ...children);
287
+ }
288
+ default:
289
+ return null;
290
+ }
291
+ }
292
+ function evaluateExpression(expr) {
293
+ switch (expr.type) {
294
+ case "StringLiteral":
295
+ return expr.value;
296
+ case "NumericLiteral":
297
+ return expr.value;
298
+ case "BooleanLiteral":
299
+ return expr.value;
300
+ case "ObjectExpression": {
301
+ const obj = {};
302
+ for (const prop of expr.properties) {
303
+ if (prop.type === "ObjectProperty" && prop.key.type === "Identifier") {
304
+ obj[prop.key.name] = evaluateExpression(prop.value);
305
+ }
306
+ }
307
+ return obj;
308
+ }
309
+ // Add more cases (Identifier, CallExpression, etc.) as needed
310
+ default:
311
+ return void 0;
312
+ }
313
+ }
314
+ function findJSX(node) {
315
+ if (!node || typeof node !== "object") return null;
316
+ if (node.type === "JSXElement" || node.type === "JSXFragment") return node;
317
+ for (const key of Object.keys(node)) {
318
+ const val = node[key];
319
+ if (Array.isArray(val)) {
320
+ for (const child of val) {
321
+ const found = findJSX(child);
322
+ if (found) return found;
323
+ }
324
+ } else {
325
+ const found = findJSX(val);
326
+ if (found) return found;
327
+ }
328
+ }
329
+ return null;
330
+ }
331
+ function jsxStringToReactTree(jsxString = "") {
332
+ const ast = parse(jsxString, { sourceType: "module", plugins: ["jsx"] });
333
+ const rootJSX = findJSX(ast);
334
+ if (!rootJSX) {
335
+ return null;
336
+ }
337
+ const reactTree = buildElement(rootJSX);
338
+ return reactTree;
339
+ }
340
+ function processDefinitionProperties(definitions) {
341
+ if (!definitions || !Array.isArray(definitions)) {
342
+ return definitions;
343
+ }
344
+ return definitions.map((definition) => {
345
+ if (definition.variants && Array.isArray(definition.variants)) {
346
+ for (const variant of definition.variants) {
347
+ if (variant.properties && Array.isArray(variant.properties)) {
348
+ variant.properties = processDefinitionProperty(variant.properties);
349
+ }
350
+ }
351
+ }
352
+ if (definition.properties && Array.isArray(definition.properties)) {
353
+ definition.properties = processDefinitionProperty(definition.properties);
354
+ }
355
+ if (definition.description && typeof definition.description === "string") {
356
+ const md = fromMarkdown(definition.description);
357
+ const hast = toHast(md);
358
+ const html = toHtml(hast);
359
+ const jsx = htmlToJsx(html);
360
+ const reactTree = jsxStringToReactTree(jsx);
361
+ if (reactTree) {
362
+ definition.description = reactTree;
363
+ }
364
+ }
365
+ return definition;
366
+ });
367
+ }
368
+ function processDefinitionProperty(properties) {
369
+ if (!properties || !Array.isArray(properties)) {
370
+ return properties;
371
+ }
372
+ return properties.map((property) => {
373
+ const newProperty = {
374
+ ...property
375
+ };
376
+ if (typeof newProperty.description === "string" && isMarkdownText(newProperty.description)) {
377
+ const mdast = fromMarkdown(newProperty.description);
378
+ const hast = toHast(mdast);
379
+ const html = toHtml(hast);
380
+ const jsx = htmlToJsx(html);
381
+ const reactTree = jsxStringToReactTree(jsx);
382
+ if (reactTree) {
383
+ newProperty.description = reactTree;
384
+ }
385
+ }
386
+ if (property.properties && Array.isArray(property.properties)) {
387
+ newProperty.properties = processDefinitionProperty(property.properties);
388
+ }
389
+ return newProperty;
390
+ });
391
+ }
392
+ function isMarkdownText(text) {
393
+ const tokens = marked.lexer(text);
394
+ let found = false;
395
+ marked.walkTokens(tokens, (token) => {
396
+ if (!["text", "paragraph", "space", "newline"].includes(token.type)) {
397
+ found = true;
398
+ }
399
+ });
400
+ return found;
401
+ }
402
+ var standardMdastTypes = [
403
+ "root",
404
+ "paragraph",
405
+ "heading",
406
+ "text",
407
+ "emphasis",
408
+ "strong",
409
+ "delete",
410
+ "blockquote",
411
+ "code",
412
+ "link",
413
+ "image",
414
+ "list",
415
+ "listItem",
416
+ "table",
417
+ "tableRow",
418
+ "tableCell",
419
+ "html",
420
+ "break",
421
+ "thematicBreak",
422
+ "definition",
423
+ "footnoteDefinition",
424
+ "footnoteReference",
425
+ "inlineCode",
426
+ "linkReference",
427
+ "imageReference",
428
+ "footnote",
429
+ "tableCaption"
430
+ ];
431
+ function isStandardMdastType(type) {
432
+ return standardMdastTypes.includes(type);
433
+ }
434
+ function isMdxElement(type) {
435
+ return type === "mdxJsxFlowElement";
436
+ }
437
+ export {
438
+ Composer
439
+ };
440
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Composer.ts","../src/decorators.ts"],"sourcesContent":["import * as React from \"react\"\nimport type { RootContent } from \"mdast\";\nimport { toMarkdown } from \"mdast-util-to-markdown\";\nimport { mdxToMarkdown } from \"mdast-util-mdx\";\nimport { toHast } from 'mdast-util-to-hast'\nimport { toHtml } from 'hast-util-to-html'\nimport { parse } from '@babel/parser';\nimport { highlight } from \"codehike/code\";\nimport { marked } from 'marked';\nimport { fromMarkdown } from 'mdast-util-from-markdown';\nimport { htmlToJsx } from \"html-to-jsx-transform\";\n\nimport { type AtlasProps } from \"@xyd-js/atlas\";\nimport { type Theme as ThemeSettings } from \"@xyd-js/core\"\n\nimport { VarCode } from \"@xyd-js/content\";\nimport { ExampleRoot, Definition, DefinitionProperty } from \"@xyd-js/uniform\";\n\nimport { metaComponent } from './decorators';\n\n// TODO: !!!! REFACTOR !!!\n\ninterface AtlasVars {\n examples?: VarCode\n}\n\n// TODO: get object from atlas\n// Define the type for an example object\ninterface ExampleObject {\n codeblock: {\n title: string;\n tabs: {\n title: string;\n language: string;\n code: string;\n highlighted: any; // TODO: fix\n }[];\n };\n}\n\n// Define the type for an example group\ninterface ExampleGroup {\n examples: ExampleObject[];\n}\n\nexport class Composer {\n // TODO: !!! COMPOSE API !!!!\n // TODO: this.themeSettings but currently issues with decorators\n @metaComponent(\"atlas\", \"Atlas\")\n private async atlasMetaComponent(\n themeSettings: ThemeSettings,\n props: AtlasProps,\n vars: AtlasVars,\n treeChilds: readonly RootContent[]\n ) {\n //@ts-ignore\n const outputVarExamples: ExampleRoot = {\n groups: []\n }\n\n const oneExample = vars.examples?.length === 1 && !Array.isArray(vars.examples[0])\n\n // Helper function to create an example object\n function createExampleObject(example: any): ExampleObject {\n // Extract the highlighted property correctly\n const highlighted = example.highlighted || example;\n\n return {\n codeblock: {\n title: example.meta,\n tabs: [\n {\n title: example.meta,\n language: example.lang,\n code: example.code,\n highlighted: highlighted\n }\n ]\n }\n };\n }\n\n if (oneExample) {\n const example = vars.examples?.[0]\n if (Array.isArray(example) || !example) {\n return\n }\n\n outputVarExamples.groups.push({\n examples: [createExampleObject(example)]\n })\n } else {\n // Process each example or group of examples\n vars.examples?.forEach((item) => {\n if (Array.isArray(item)) {\n // This is a group with a title as the first element\n const groupTitle = item[0];\n const groupExamples = item.slice(1);\n\n const exampleGroup: ExampleGroup = {\n examples: []\n };\n\n // Process each example in the group\n groupExamples.forEach((example) => {\n if (example && typeof example === 'object') {\n exampleGroup.examples.push(createExampleObject(example));\n }\n });\n\n if (exampleGroup.examples.length > 0) {\n outputVarExamples.groups.push(exampleGroup);\n }\n } else if (item && typeof item === 'object') {\n // This is a single example\n const exampleGroup: ExampleGroup = {\n examples: [createExampleObject(item)]\n };\n\n outputVarExamples.groups.push(exampleGroup);\n }\n });\n }\n\n const reactElements: React.ReactNode[] = []\n\n // TODO: !! IMPORTANT !! BETTER COMPOSE TRANSFORMATION\n for (const child of treeChilds) {\n if (isStandardMdastType(child.type)) {\n const hast = toHast(child)\n const html = toHtml(hast)\n\n if (child.type === \"heading\" && child.depth === 1) {\n const firstChild = child.children[0];\n if (firstChild.type === 'text') {\n props.references[0].title = firstChild.value;\n }\n } else {\n const jsx = htmlToJsx(html);\n const reactTree = jsxStringToReactTree(jsx);\n if (reactTree) {\n reactElements.push(reactTree)\n }\n }\n\n continue\n } else if (isMdxElement(child.type)) {\n const jsxString = toMarkdown(child, {\n extensions: [mdxToMarkdown()],\n handlers: {// TODO: find better solution how to convert such as structure?\n list(node, parent, context) {\n // call containerFlow as a method on context, so `this` stays correct\n const items = node.children\n .map(item => context.containerFlow(item, node))\n .join('\\n')\n return `<ul>\\n${items}\\n</ul>`\n },\n listItem(node, parent, context) {\n // Use a type assertion to handle the parent parameter\n const content = context.containerFlow(node, parent as any).trim()\n return `<li>${content}</li>`\n },\n }\n });\n\n const reactTree = jsxStringToReactTree(jsxString)\n if (reactTree) {\n reactElements.push(reactTree)\n }\n }\n }\n\n const propDescription = props.references?.[0]?.description\n if (propDescription) {\n // Sanitize frontmatter description\n if (typeof propDescription === \"string\") {\n // Remove frontmatter using regex\n const content = propDescription.replace(/^---[\\s\\S]*?---\\n/, '');\n\n const md = fromMarkdown(content)\n const hast = toHast(md)\n const html = toHtml(hast)\n const jsx = htmlToJsx(html);\n const reactTree = jsxStringToReactTree(jsx);\n if (reactTree) {\n props.references[0].description = reactTree;\n } else {\n props.references[0].description = content\n }\n }\n }\n\n if (reactElements.length > 0) {\n if (props.references?.[0]?.description) {\n reactElements.unshift(props.references[0].description)\n }\n // Create a combined React element from all the elements\n const combinedReactTree = React.createElement(React.Fragment, null, ...reactElements)\n\n if (props.references?.[0]) {\n props.references[0].description = combinedReactTree\n }\n }\n\n if (\n !outputVarExamples.groups.length &&\n props.references[0]?.examples.groups?.length\n ) {\n const promises: Promise<void>[] = []\n\n props.references[0].examples?.groups.forEach(group => {\n group.examples.forEach(example => {\n example.codeblock.tabs.forEach(tab => {\n\n async function highlightCode() {\n const highlighted = await highlight({\n value: tab.code,\n lang: tab.language,\n meta: tab.title,\n }, themeSettings?.coder?.syntaxHighlight || \"github-dark\")\n\n tab.highlighted = highlighted\n }\n\n promises.push(highlightCode());\n });\n });\n });\n\n await Promise.all(promises);\n } else {\n if (props.references?.[0]) {\n props.references[0].examples = outputVarExamples;\n }\n }\n\n // Process definition properties recursively to convert markdown descriptions to React trees\n if (props.references?.[0]?.definitions) {\n props.references[0].definitions = processDefinitionProperties(props.references[0].definitions);\n }\n\n return props\n // TODO: in the future return a component directly here but we need good mechanism for transpiling?\n }\n}\n\nfunction buildElement(node) {\n if (!node) return null;\n switch (node.type) {\n case 'JSXElement': {\n // Resolve type (string for custom components)\n let type;\n const nameNode = node.openingElement.name;\n if (nameNode.type === 'JSXMemberExpression') {\n // flatten Foo.Bar to \"Foo.Bar\"\n const parts: string[] = [];\n let curr = nameNode;\n while (curr) {\n if (curr.property) parts.unshift(curr.property.name);\n curr = curr.object;\n }\n type = parts.join('.');\n } else {\n type = nameNode.name;\n }\n\n // Props\n const props = {};\n for (const attr of node.openingElement.attributes) {\n if (attr.type === 'JSXSpreadAttribute') {\n Object.assign(props, evaluateExpression(attr.argument));\n continue;\n }\n const key = attr.name.name;\n let value;\n if (!attr.value) {\n value = true;\n } else if (attr.value.type === 'StringLiteral' || attr.value.type === 'NumericLiteral' || attr.value.type === 'BooleanLiteral') {\n value = attr.value.value;\n } else if (attr.value.type === 'JSXExpressionContainer') {\n value = evaluateExpression(attr.value.expression);\n }\n props[key] = value;\n }\n\n // Children\n const children = node.children\n .map(child => {\n if (child.type === 'JSXText') {\n const text = child.value.replace(/\\s+/g, ' ');\n return text.trim() ? text : null;\n }\n if (child.type === 'JSXExpressionContainer') {\n return child.expression.type === 'JSXElement' || child.expression.type === 'JSXFragment'\n ? buildElement(child.expression)\n : evaluateExpression(child.expression);\n }\n if (child.type === 'JSXElement' || child.type === 'JSXFragment') {\n return buildElement(child);\n }\n return null;\n })\n .filter(c => c !== null);\n\n // Create React element\n return React.createElement(type, props, ...children);\n }\n\n case 'JSXFragment': {\n const children = node.children\n .map(child => (child.type === 'JSXElement' || child.type === 'JSXFragment')\n ? buildElement(child)\n : (child.type === 'JSXText' ? child.value.trim() || null : null)\n )\n .filter(Boolean);\n return React.createElement(React.Fragment, null, ...children);\n }\n\n default:\n return null;\n }\n}\n\n// Simplistic evaluator for static expressions: identifiers -> undefined, literals -> value, objects -> {}\nfunction evaluateExpression(expr) {\n switch (expr.type) {\n case 'StringLiteral': return expr.value;\n case 'NumericLiteral': return expr.value;\n case 'BooleanLiteral': return expr.value;\n case 'ObjectExpression': {\n const obj = {};\n for (const prop of expr.properties) {\n if (prop.type === 'ObjectProperty' && prop.key.type === 'Identifier') {\n obj[prop.key.name] = evaluateExpression(prop.value);\n }\n }\n return obj;\n }\n // Add more cases (Identifier, CallExpression, etc.) as needed\n default:\n return undefined;\n }\n}\n\n// 4) Locate first JSX node\nfunction findJSX(node) {\n if (!node || typeof node !== 'object') return null;\n if (node.type === 'JSXElement' || node.type === 'JSXFragment') return node;\n for (const key of Object.keys(node)) {\n const val = node[key];\n if (Array.isArray(val)) {\n for (const child of val) {\n const found = findJSX(child);\n if (found) return found;\n }\n } else {\n const found = findJSX(val);\n if (found) return found;\n }\n }\n return null;\n}\n\nfunction jsxStringToReactTree(jsxString: string = \"\") {\n const ast = parse(jsxString, { sourceType: 'module', plugins: ['jsx'] });\n const rootJSX = findJSX(ast);\n if (!rootJSX) {\n return null\n }\n\n const reactTree = buildElement(rootJSX)\n\n return reactTree\n}\n\n/**\n * Recursively processes definition properties to convert markdown descriptions to React trees\n * @param definitions The definitions to process\n * @returns The processed definitions with markdown descriptions converted to React trees\n */\nfunction processDefinitionProperties(definitions: Definition[]): Definition[] {\n if (!definitions || !Array.isArray(definitions)) {\n return definitions;\n }\n\n return definitions.map(definition => {\n // Process variants recursively\n if (definition.variants && Array.isArray(definition.variants)) {\n for (const variant of definition.variants) {\n if (variant.properties && Array.isArray(variant.properties)) {\n variant.properties = processDefinitionProperty(variant.properties);\n }\n }\n }\n\n // Process the definition's properties recursively\n if (definition.properties && Array.isArray(definition.properties)) {\n definition.properties = processDefinitionProperty(definition.properties);\n }\n\n if (definition.description && typeof definition.description === \"string\") {\n const md = fromMarkdown(definition.description)\n const hast = toHast(md)\n const html = toHtml(hast)\n const jsx = htmlToJsx(html);\n const reactTree = jsxStringToReactTree(jsx);\n if (reactTree) {\n definition.description = reactTree;\n }\n }\n return definition;\n });\n}\n\n/**\n * Recursively processes definition properties to convert markdown descriptions to React trees\n * @param properties The properties to process\n * @returns The processed properties with markdown descriptions converted to React trees\n */\nfunction processDefinitionProperty(properties: DefinitionProperty[]): DefinitionProperty[] {\n if (!properties || !Array.isArray(properties)) {\n return properties;\n }\n\n return properties.map(property => {\n const newProperty: DefinitionProperty = {\n ...property,\n };\n\n if (typeof newProperty.description === 'string' && isMarkdownText(newProperty.description)) {\n const mdast = fromMarkdown(newProperty.description);\n const hast = toHast(mdast);\n const html = toHtml(hast);\n const jsx = htmlToJsx(html);\n const reactTree = jsxStringToReactTree(jsx);\n if (reactTree) {\n newProperty.description = reactTree;\n }\n }\n\n if (property.properties && Array.isArray(property.properties)) {\n newProperty.properties = processDefinitionProperty(property.properties);\n }\n\n return newProperty;\n });\n}\n\n/**\n * Returns true if the input contains any non-plain-text Markdown tokens.\n */\nfunction isMarkdownText(text: string) {\n // 1) Lex into a token tree\n const tokens = marked.lexer(text);\n let found = false;\n\n // 2) Traverse *every* token (including nested) and flag any non-plain-text kinds\n marked.walkTokens(tokens, token => {\n // ignore pure text/whitespace\n if (!['text', 'paragraph', 'space', 'newline'].includes(token.type)) {\n found = true;\n }\n });\n\n return found;\n}\n\n\n\n/**\n * List of standard MDAST node types\n */\nconst standardMdastTypes = [\n 'root',\n 'paragraph',\n 'heading',\n 'text',\n 'emphasis',\n 'strong',\n 'delete',\n 'blockquote',\n 'code',\n 'link',\n 'image',\n 'list',\n 'listItem',\n 'table',\n 'tableRow',\n 'tableCell',\n 'html',\n 'break',\n 'thematicBreak',\n 'definition',\n 'footnoteDefinition',\n 'footnoteReference',\n 'inlineCode',\n 'linkReference',\n 'imageReference',\n 'footnote',\n 'tableCaption'\n];\n\n\n/**\n * Checks if a given type is a standard MDAST type\n * @param type The node type to check\n * @returns True if the type is a standard MDAST type, false otherwise\n */\nfunction isStandardMdastType(type: string): boolean {\n return standardMdastTypes.includes(type);\n}\n\nfunction isMdxElement(type: string): boolean {\n return type === 'mdxJsxFlowElement'\n}\n","import { registerMetaComponent } from \"@xyd-js/context\";\n\nexport function metaComponent<P, V>(\n name: string,\n componentName?: string\n) {\n return function (\n target: any,\n context: any\n ) {\n registerMetaComponent(\n name,\n componentName || name,\n target\n );\n };\n}\n\n"],"mappings":"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","names":["_a"]}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@xyd-js/composer",
3
+ "version": "0.1.0-xyd.2",
4
+ "description": "xyd composer API",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "exports": {
8
+ "./package.json": "./package.json",
9
+ ".": {
10
+ "import": "./dist/index.js"
11
+ }
12
+ },
13
+ "dependencies": {
14
+ "@babel/parser": "^7.27.2",
15
+ "codehike": "^1.0.7",
16
+ "hast-util-to-html": "^9.0.5",
17
+ "html-to-jsx-transform": "^1.2.0",
18
+ "marked": "^15.0.11",
19
+ "mdast": "^3.0.0",
20
+ "mdast-util-from-markdown": "^2.0.2",
21
+ "mdast-util-mdx": "^3.0.0",
22
+ "mdast-util-to-hast": "^13.2.0",
23
+ "mdast-util-to-markdown": "^2.1.2"
24
+ },
25
+ "peerDependencies": {
26
+ "react": "^19.0.0",
27
+ "@xyd-js/atlas": "0.1.0-xyd.18",
28
+ "@xyd-js/core": "0.1.0-xyd.15",
29
+ "@xyd-js/uniform": "0.1.0-xyd.17",
30
+ "@xyd-js/content": "0.1.0-xyd.16",
31
+ "@xyd-js/context": "0.1.0-xyd.2"
32
+ },
33
+ "devDependencies": {
34
+ "tsup": "^8.3.0",
35
+ "typescript": "5.6.2"
36
+ },
37
+ "scripts": {
38
+ "build": "tsup"
39
+ }
40
+ }
@@ -0,0 +1,515 @@
1
+ import * as React from "react"
2
+ import type { RootContent } from "mdast";
3
+ import { toMarkdown } from "mdast-util-to-markdown";
4
+ import { mdxToMarkdown } from "mdast-util-mdx";
5
+ import { toHast } from 'mdast-util-to-hast'
6
+ import { toHtml } from 'hast-util-to-html'
7
+ import { parse } from '@babel/parser';
8
+ import { highlight } from "codehike/code";
9
+ import { marked } from 'marked';
10
+ import { fromMarkdown } from 'mdast-util-from-markdown';
11
+ import { htmlToJsx } from "html-to-jsx-transform";
12
+
13
+ import { type AtlasProps } from "@xyd-js/atlas";
14
+ import { type Theme as ThemeSettings } from "@xyd-js/core"
15
+
16
+ import { VarCode } from "@xyd-js/content";
17
+ import { ExampleRoot, Definition, DefinitionProperty } from "@xyd-js/uniform";
18
+
19
+ import { metaComponent } from './decorators';
20
+
21
+ // TODO: !!!! REFACTOR !!!
22
+
23
+ interface AtlasVars {
24
+ examples?: VarCode
25
+ }
26
+
27
+ // TODO: get object from atlas
28
+ // Define the type for an example object
29
+ interface ExampleObject {
30
+ codeblock: {
31
+ title: string;
32
+ tabs: {
33
+ title: string;
34
+ language: string;
35
+ code: string;
36
+ highlighted: any; // TODO: fix
37
+ }[];
38
+ };
39
+ }
40
+
41
+ // Define the type for an example group
42
+ interface ExampleGroup {
43
+ examples: ExampleObject[];
44
+ }
45
+
46
+ export class Composer {
47
+ // TODO: !!! COMPOSE API !!!!
48
+ // TODO: this.themeSettings but currently issues with decorators
49
+ @metaComponent("atlas", "Atlas")
50
+ private async atlasMetaComponent(
51
+ themeSettings: ThemeSettings,
52
+ props: AtlasProps,
53
+ vars: AtlasVars,
54
+ treeChilds: readonly RootContent[]
55
+ ) {
56
+ //@ts-ignore
57
+ const outputVarExamples: ExampleRoot = {
58
+ groups: []
59
+ }
60
+
61
+ const oneExample = vars.examples?.length === 1 && !Array.isArray(vars.examples[0])
62
+
63
+ // Helper function to create an example object
64
+ function createExampleObject(example: any): ExampleObject {
65
+ // Extract the highlighted property correctly
66
+ const highlighted = example.highlighted || example;
67
+
68
+ return {
69
+ codeblock: {
70
+ title: example.meta,
71
+ tabs: [
72
+ {
73
+ title: example.meta,
74
+ language: example.lang,
75
+ code: example.code,
76
+ highlighted: highlighted
77
+ }
78
+ ]
79
+ }
80
+ };
81
+ }
82
+
83
+ if (oneExample) {
84
+ const example = vars.examples?.[0]
85
+ if (Array.isArray(example) || !example) {
86
+ return
87
+ }
88
+
89
+ outputVarExamples.groups.push({
90
+ examples: [createExampleObject(example)]
91
+ })
92
+ } else {
93
+ // Process each example or group of examples
94
+ vars.examples?.forEach((item) => {
95
+ if (Array.isArray(item)) {
96
+ // This is a group with a title as the first element
97
+ const groupTitle = item[0];
98
+ const groupExamples = item.slice(1);
99
+
100
+ const exampleGroup: ExampleGroup = {
101
+ examples: []
102
+ };
103
+
104
+ // Process each example in the group
105
+ groupExamples.forEach((example) => {
106
+ if (example && typeof example === 'object') {
107
+ exampleGroup.examples.push(createExampleObject(example));
108
+ }
109
+ });
110
+
111
+ if (exampleGroup.examples.length > 0) {
112
+ outputVarExamples.groups.push(exampleGroup);
113
+ }
114
+ } else if (item && typeof item === 'object') {
115
+ // This is a single example
116
+ const exampleGroup: ExampleGroup = {
117
+ examples: [createExampleObject(item)]
118
+ };
119
+
120
+ outputVarExamples.groups.push(exampleGroup);
121
+ }
122
+ });
123
+ }
124
+
125
+ const reactElements: React.ReactNode[] = []
126
+
127
+ // TODO: !! IMPORTANT !! BETTER COMPOSE TRANSFORMATION
128
+ for (const child of treeChilds) {
129
+ if (isStandardMdastType(child.type)) {
130
+ const hast = toHast(child)
131
+ const html = toHtml(hast)
132
+
133
+ if (child.type === "heading" && child.depth === 1) {
134
+ const firstChild = child.children[0];
135
+ if (firstChild.type === 'text') {
136
+ props.references[0].title = firstChild.value;
137
+ }
138
+ } else {
139
+ const jsx = htmlToJsx(html);
140
+ const reactTree = jsxStringToReactTree(jsx);
141
+ if (reactTree) {
142
+ reactElements.push(reactTree)
143
+ }
144
+ }
145
+
146
+ continue
147
+ } else if (isMdxElement(child.type)) {
148
+ const jsxString = toMarkdown(child, {
149
+ extensions: [mdxToMarkdown()],
150
+ handlers: {// TODO: find better solution how to convert such as structure?
151
+ list(node, parent, context) {
152
+ // call containerFlow as a method on context, so `this` stays correct
153
+ const items = node.children
154
+ .map(item => context.containerFlow(item, node))
155
+ .join('\n')
156
+ return `<ul>\n${items}\n</ul>`
157
+ },
158
+ listItem(node, parent, context) {
159
+ // Use a type assertion to handle the parent parameter
160
+ const content = context.containerFlow(node, parent as any).trim()
161
+ return `<li>${content}</li>`
162
+ },
163
+ }
164
+ });
165
+
166
+ const reactTree = jsxStringToReactTree(jsxString)
167
+ if (reactTree) {
168
+ reactElements.push(reactTree)
169
+ }
170
+ }
171
+ }
172
+
173
+ const propDescription = props.references?.[0]?.description
174
+ if (propDescription) {
175
+ // Sanitize frontmatter description
176
+ if (typeof propDescription === "string") {
177
+ // Remove frontmatter using regex
178
+ const content = propDescription.replace(/^---[\s\S]*?---\n/, '');
179
+
180
+ const md = fromMarkdown(content)
181
+ const hast = toHast(md)
182
+ const html = toHtml(hast)
183
+ const jsx = htmlToJsx(html);
184
+ const reactTree = jsxStringToReactTree(jsx);
185
+ if (reactTree) {
186
+ props.references[0].description = reactTree;
187
+ } else {
188
+ props.references[0].description = content
189
+ }
190
+ }
191
+ }
192
+
193
+ if (reactElements.length > 0) {
194
+ if (props.references?.[0]?.description) {
195
+ reactElements.unshift(props.references[0].description)
196
+ }
197
+ // Create a combined React element from all the elements
198
+ const combinedReactTree = React.createElement(React.Fragment, null, ...reactElements)
199
+
200
+ if (props.references?.[0]) {
201
+ props.references[0].description = combinedReactTree
202
+ }
203
+ }
204
+
205
+ if (
206
+ !outputVarExamples.groups.length &&
207
+ props.references[0]?.examples.groups?.length
208
+ ) {
209
+ const promises: Promise<void>[] = []
210
+
211
+ props.references[0].examples?.groups.forEach(group => {
212
+ group.examples.forEach(example => {
213
+ example.codeblock.tabs.forEach(tab => {
214
+
215
+ async function highlightCode() {
216
+ const highlighted = await highlight({
217
+ value: tab.code,
218
+ lang: tab.language,
219
+ meta: tab.title,
220
+ }, themeSettings?.coder?.syntaxHighlight || "github-dark")
221
+
222
+ tab.highlighted = highlighted
223
+ }
224
+
225
+ promises.push(highlightCode());
226
+ });
227
+ });
228
+ });
229
+
230
+ await Promise.all(promises);
231
+ } else {
232
+ if (props.references?.[0]) {
233
+ props.references[0].examples = outputVarExamples;
234
+ }
235
+ }
236
+
237
+ // Process definition properties recursively to convert markdown descriptions to React trees
238
+ if (props.references?.[0]?.definitions) {
239
+ props.references[0].definitions = processDefinitionProperties(props.references[0].definitions);
240
+ }
241
+
242
+ return props
243
+ // TODO: in the future return a component directly here but we need good mechanism for transpiling?
244
+ }
245
+ }
246
+
247
+ function buildElement(node) {
248
+ if (!node) return null;
249
+ switch (node.type) {
250
+ case 'JSXElement': {
251
+ // Resolve type (string for custom components)
252
+ let type;
253
+ const nameNode = node.openingElement.name;
254
+ if (nameNode.type === 'JSXMemberExpression') {
255
+ // flatten Foo.Bar to "Foo.Bar"
256
+ const parts: string[] = [];
257
+ let curr = nameNode;
258
+ while (curr) {
259
+ if (curr.property) parts.unshift(curr.property.name);
260
+ curr = curr.object;
261
+ }
262
+ type = parts.join('.');
263
+ } else {
264
+ type = nameNode.name;
265
+ }
266
+
267
+ // Props
268
+ const props = {};
269
+ for (const attr of node.openingElement.attributes) {
270
+ if (attr.type === 'JSXSpreadAttribute') {
271
+ Object.assign(props, evaluateExpression(attr.argument));
272
+ continue;
273
+ }
274
+ const key = attr.name.name;
275
+ let value;
276
+ if (!attr.value) {
277
+ value = true;
278
+ } else if (attr.value.type === 'StringLiteral' || attr.value.type === 'NumericLiteral' || attr.value.type === 'BooleanLiteral') {
279
+ value = attr.value.value;
280
+ } else if (attr.value.type === 'JSXExpressionContainer') {
281
+ value = evaluateExpression(attr.value.expression);
282
+ }
283
+ props[key] = value;
284
+ }
285
+
286
+ // Children
287
+ const children = node.children
288
+ .map(child => {
289
+ if (child.type === 'JSXText') {
290
+ const text = child.value.replace(/\s+/g, ' ');
291
+ return text.trim() ? text : null;
292
+ }
293
+ if (child.type === 'JSXExpressionContainer') {
294
+ return child.expression.type === 'JSXElement' || child.expression.type === 'JSXFragment'
295
+ ? buildElement(child.expression)
296
+ : evaluateExpression(child.expression);
297
+ }
298
+ if (child.type === 'JSXElement' || child.type === 'JSXFragment') {
299
+ return buildElement(child);
300
+ }
301
+ return null;
302
+ })
303
+ .filter(c => c !== null);
304
+
305
+ // Create React element
306
+ return React.createElement(type, props, ...children);
307
+ }
308
+
309
+ case 'JSXFragment': {
310
+ const children = node.children
311
+ .map(child => (child.type === 'JSXElement' || child.type === 'JSXFragment')
312
+ ? buildElement(child)
313
+ : (child.type === 'JSXText' ? child.value.trim() || null : null)
314
+ )
315
+ .filter(Boolean);
316
+ return React.createElement(React.Fragment, null, ...children);
317
+ }
318
+
319
+ default:
320
+ return null;
321
+ }
322
+ }
323
+
324
+ // Simplistic evaluator for static expressions: identifiers -> undefined, literals -> value, objects -> {}
325
+ function evaluateExpression(expr) {
326
+ switch (expr.type) {
327
+ case 'StringLiteral': return expr.value;
328
+ case 'NumericLiteral': return expr.value;
329
+ case 'BooleanLiteral': return expr.value;
330
+ case 'ObjectExpression': {
331
+ const obj = {};
332
+ for (const prop of expr.properties) {
333
+ if (prop.type === 'ObjectProperty' && prop.key.type === 'Identifier') {
334
+ obj[prop.key.name] = evaluateExpression(prop.value);
335
+ }
336
+ }
337
+ return obj;
338
+ }
339
+ // Add more cases (Identifier, CallExpression, etc.) as needed
340
+ default:
341
+ return undefined;
342
+ }
343
+ }
344
+
345
+ // 4) Locate first JSX node
346
+ function findJSX(node) {
347
+ if (!node || typeof node !== 'object') return null;
348
+ if (node.type === 'JSXElement' || node.type === 'JSXFragment') return node;
349
+ for (const key of Object.keys(node)) {
350
+ const val = node[key];
351
+ if (Array.isArray(val)) {
352
+ for (const child of val) {
353
+ const found = findJSX(child);
354
+ if (found) return found;
355
+ }
356
+ } else {
357
+ const found = findJSX(val);
358
+ if (found) return found;
359
+ }
360
+ }
361
+ return null;
362
+ }
363
+
364
+ function jsxStringToReactTree(jsxString: string = "") {
365
+ const ast = parse(jsxString, { sourceType: 'module', plugins: ['jsx'] });
366
+ const rootJSX = findJSX(ast);
367
+ if (!rootJSX) {
368
+ return null
369
+ }
370
+
371
+ const reactTree = buildElement(rootJSX)
372
+
373
+ return reactTree
374
+ }
375
+
376
+ /**
377
+ * Recursively processes definition properties to convert markdown descriptions to React trees
378
+ * @param definitions The definitions to process
379
+ * @returns The processed definitions with markdown descriptions converted to React trees
380
+ */
381
+ function processDefinitionProperties(definitions: Definition[]): Definition[] {
382
+ if (!definitions || !Array.isArray(definitions)) {
383
+ return definitions;
384
+ }
385
+
386
+ return definitions.map(definition => {
387
+ // Process variants recursively
388
+ if (definition.variants && Array.isArray(definition.variants)) {
389
+ for (const variant of definition.variants) {
390
+ if (variant.properties && Array.isArray(variant.properties)) {
391
+ variant.properties = processDefinitionProperty(variant.properties);
392
+ }
393
+ }
394
+ }
395
+
396
+ // Process the definition's properties recursively
397
+ if (definition.properties && Array.isArray(definition.properties)) {
398
+ definition.properties = processDefinitionProperty(definition.properties);
399
+ }
400
+
401
+ if (definition.description && typeof definition.description === "string") {
402
+ const md = fromMarkdown(definition.description)
403
+ const hast = toHast(md)
404
+ const html = toHtml(hast)
405
+ const jsx = htmlToJsx(html);
406
+ const reactTree = jsxStringToReactTree(jsx);
407
+ if (reactTree) {
408
+ definition.description = reactTree;
409
+ }
410
+ }
411
+ return definition;
412
+ });
413
+ }
414
+
415
+ /**
416
+ * Recursively processes definition properties to convert markdown descriptions to React trees
417
+ * @param properties The properties to process
418
+ * @returns The processed properties with markdown descriptions converted to React trees
419
+ */
420
+ function processDefinitionProperty(properties: DefinitionProperty[]): DefinitionProperty[] {
421
+ if (!properties || !Array.isArray(properties)) {
422
+ return properties;
423
+ }
424
+
425
+ return properties.map(property => {
426
+ const newProperty: DefinitionProperty = {
427
+ ...property,
428
+ };
429
+
430
+ if (typeof newProperty.description === 'string' && isMarkdownText(newProperty.description)) {
431
+ const mdast = fromMarkdown(newProperty.description);
432
+ const hast = toHast(mdast);
433
+ const html = toHtml(hast);
434
+ const jsx = htmlToJsx(html);
435
+ const reactTree = jsxStringToReactTree(jsx);
436
+ if (reactTree) {
437
+ newProperty.description = reactTree;
438
+ }
439
+ }
440
+
441
+ if (property.properties && Array.isArray(property.properties)) {
442
+ newProperty.properties = processDefinitionProperty(property.properties);
443
+ }
444
+
445
+ return newProperty;
446
+ });
447
+ }
448
+
449
+ /**
450
+ * Returns true if the input contains any non-plain-text Markdown tokens.
451
+ */
452
+ function isMarkdownText(text: string) {
453
+ // 1) Lex into a token tree
454
+ const tokens = marked.lexer(text);
455
+ let found = false;
456
+
457
+ // 2) Traverse *every* token (including nested) and flag any non-plain-text kinds
458
+ marked.walkTokens(tokens, token => {
459
+ // ignore pure text/whitespace
460
+ if (!['text', 'paragraph', 'space', 'newline'].includes(token.type)) {
461
+ found = true;
462
+ }
463
+ });
464
+
465
+ return found;
466
+ }
467
+
468
+
469
+
470
+ /**
471
+ * List of standard MDAST node types
472
+ */
473
+ const standardMdastTypes = [
474
+ 'root',
475
+ 'paragraph',
476
+ 'heading',
477
+ 'text',
478
+ 'emphasis',
479
+ 'strong',
480
+ 'delete',
481
+ 'blockquote',
482
+ 'code',
483
+ 'link',
484
+ 'image',
485
+ 'list',
486
+ 'listItem',
487
+ 'table',
488
+ 'tableRow',
489
+ 'tableCell',
490
+ 'html',
491
+ 'break',
492
+ 'thematicBreak',
493
+ 'definition',
494
+ 'footnoteDefinition',
495
+ 'footnoteReference',
496
+ 'inlineCode',
497
+ 'linkReference',
498
+ 'imageReference',
499
+ 'footnote',
500
+ 'tableCaption'
501
+ ];
502
+
503
+
504
+ /**
505
+ * Checks if a given type is a standard MDAST type
506
+ * @param type The node type to check
507
+ * @returns True if the type is a standard MDAST type, false otherwise
508
+ */
509
+ function isStandardMdastType(type: string): boolean {
510
+ return standardMdastTypes.includes(type);
511
+ }
512
+
513
+ function isMdxElement(type: string): boolean {
514
+ return type === 'mdxJsxFlowElement'
515
+ }
@@ -0,0 +1,18 @@
1
+ import { registerMetaComponent } from "@xyd-js/context";
2
+
3
+ export function metaComponent<P, V>(
4
+ name: string,
5
+ componentName?: string
6
+ ) {
7
+ return function (
8
+ target: any,
9
+ context: any
10
+ ) {
11
+ registerMetaComponent(
12
+ name,
13
+ componentName || name,
14
+ target
15
+ );
16
+ };
17
+ }
18
+
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export {
2
+ Composer
3
+ } from "./Composer"
package/tsconfig.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "compilerOptions": {
3
+ "paths": {
4
+ "@xyd-js/framework/react": [
5
+ "../xyd-framework/packages/react/index.ts"
6
+ ],
7
+ "@xyd-js/context": [
8
+ "../xyd-context/src/index.ts"
9
+ ],
10
+ "@xyd-js/core": [
11
+ "../xyd-core/src/index.ts"
12
+ ]
13
+ },
14
+ "module": "esnext",
15
+ "esModuleInterop": true,
16
+ "moduleResolution": "bundler",
17
+ "target": "ES6",
18
+ "lib": [
19
+ "dom",
20
+ "dom.iterable",
21
+ "esnext"
22
+ ],
23
+ "allowJs": true,
24
+ "skipLibCheck": true,
25
+ "strict": false,
26
+ "noEmit": true,
27
+ "incremental": false,
28
+ "resolveJsonModule": true,
29
+ "isolatedModules": true,
30
+ "jsx": "preserve",
31
+ "plugins": [
32
+ {
33
+ "name": "next"
34
+ }
35
+ ],
36
+ "strictNullChecks": true,
37
+ "typeRoots": [
38
+ "./types.d.ts"
39
+ ]
40
+ },
41
+ "include": [
42
+ "src/**/*.ts",
43
+ "src/**/*.tsx",
44
+ "types.d.ts"
45
+ ],
46
+ "exclude": [
47
+ "node_modules"
48
+ ]
49
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,33 @@
1
+ import { defineConfig } from 'tsup';
2
+ import pkg from './package.json' assert { type: 'json' }
3
+
4
+ const deps = [
5
+ ...Object.keys(pkg.devDependencies || {}),
6
+ ...Object.keys(pkg.peerDependencies || {}),
7
+ ]
8
+
9
+ export default defineConfig({
10
+ entry: {
11
+ index: 'src/index.ts'
12
+ },
13
+ format: ['esm'],
14
+ target: 'node16',
15
+ dts: {
16
+ entry: {
17
+ index: 'src/index.ts'
18
+ },
19
+ resolve: true,
20
+ },
21
+ splitting: false,
22
+ sourcemap: true,
23
+ clean: true,
24
+ external: [
25
+ ...deps
26
+ ],
27
+ esbuildOptions: (options) => {
28
+ options.platform = 'node';
29
+ options.external = ['node:fs/promises', 'react-router'];
30
+ options.loader = { '.js': 'jsx' };
31
+ },
32
+ ignoreWatch: ['node_modules', 'dist', '.git', 'build']
33
+ });