@xaendar/build-tools 0.3.19 → 0.3.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/index.js +37 -26
  2. package/index.js.map +1 -1
  3. package/package.json +2 -2
package/index.js CHANGED
@@ -1,9 +1,8 @@
1
1
  // ../packages/build-tools/src/lib/plugin.ts
2
2
  import { compile } from "@xaendar/compiler";
3
- import { basename, dirname as dirname2, extname, resolve as resolve2 } from "path";
3
+ import { dirname as dirname2, resolve as resolve2 } from "path";
4
4
 
5
5
  // ../packages/build-tools/src/lib/costants.ts
6
- var TEMPLATE_EXTENSION = ".xd.component.html";
7
6
  var COMPONENT_FILE_RE = /\.xd\.component\.ts$/;
8
7
 
9
8
  // ../packages/build-tools/src/lib/node-compiler-host.model.ts
@@ -174,33 +173,33 @@ function xaendarPlugin() {
174
173
  if (!COMPONENT_FILE_RE.test(id)) {
175
174
  return null;
176
175
  }
177
- const templatePath = resolveTemplatePath(id);
178
- this.addWatchFile(templatePath);
179
- if (!host.fileExists(templatePath)) {
176
+ const { templatePath, stylePath } = extractDecoratorPaths(code, dirname2(id));
177
+ if (!templatePath || !host.fileExists(templatePath)) {
180
178
  this.warn(`Xaendar: could not find template at ${templatePath}`);
181
179
  return null;
182
180
  }
181
+ this.addWatchFile(templatePath);
183
182
  const templateSource = host.readFile(templatePath);
184
183
  if (templateSource === void 0) {
185
184
  this.warn(`Xaendar: could not read template at ${templatePath}`);
186
185
  return null;
187
186
  }
188
- const stylePath = resolveStylePath(id);
189
187
  let cssContent = "";
190
- if (host.fileExists(stylePath)) {
188
+ if (stylePath && host.fileExists(stylePath)) {
191
189
  this.addWatchFile(stylePath);
192
190
  cssContent = host.readFile(stylePath) ?? "";
193
191
  }
194
192
  let compiledMethods;
193
+ const varName = `__${extractClassName(id)}_sheet`;
195
194
  try {
196
- compiledMethods = compile(templateSource, cssContent);
195
+ compiledMethods = compile(templateSource, varName);
197
196
  } catch (err) {
198
197
  this.error(`Xaendar: failed to compile template ${templatePath}:
199
198
  ${String(err)}`);
200
199
  }
201
200
  let transformed;
202
201
  try {
203
- transformed = fixDecoratorExport(injectRenderMethods(code, compiledMethods));
202
+ transformed = fixDecoratorExport(injectRenderMethods(code, compiledMethods, varName, cssContent));
204
203
  } catch (err) {
205
204
  this.error(String(err));
206
205
  }
@@ -210,29 +209,41 @@ ${String(err)}`);
210
209
  }
211
210
  };
212
211
  }
213
- function extractComponentName(componentPath) {
214
- const base = basename(componentPath, extname(componentPath));
215
- return base.split(".")[0];
216
- }
217
- function resolveTemplatePath(componentPath) {
218
- const dir = dirname2(componentPath);
219
- const base = extractComponentName(componentPath);
220
- return resolve2(dir, `${base}${TEMPLATE_EXTENSION}`);
221
- }
222
- function resolveStylePath(componentPath, ext = "css") {
223
- const dir = dirname2(componentPath);
224
- const base = extractComponentName(componentPath);
225
- return resolve2(dir, `${base}.${ext}`);
212
+ function extractDecoratorPaths(jsSource, componentDir) {
213
+ const templateUrl = jsSource.match(/templateUrl\s*:\s*["'](.+?)["']/)?.[1];
214
+ const styleUrl = jsSource.match(/styleUrl\s*:\s*["'](.+?)["']/)?.[1];
215
+ return {
216
+ templatePath: templateUrl ? resolve2(componentDir, templateUrl) : void 0,
217
+ stylePath: styleUrl ? resolve2(componentDir, styleUrl) : void 0
218
+ };
226
219
  }
227
- function injectRenderMethods(jsSource, compiledMethods) {
220
+ function injectRenderMethods(jsSource, compiledMethods, varName, cssContent) {
221
+ const styleSnippet = cssContent.trim().length ? buildStyleSnippet(varName, cssContent) : "";
222
+ let result = jsSource;
223
+ if (styleSnippet) {
224
+ result = result.replace(/^(class\s+\w+\s+extends)/m, `${styleSnippet}$1`);
225
+ }
228
226
  const lastStaticBlock = /static\s*\{\s*\n(\s*)(\w+)\(\);\s*\n\s*\}/;
229
- if (!lastStaticBlock.test(jsSource)) {
230
- throw new Error("Xaendar: could not find static initializer block.");
227
+ if (!lastStaticBlock.test(result)) {
228
+ throw new Error("Xaendar: could not find the static initializer block in the transpiled output. Make sure @rolldown/plugin-babel with @babel/plugin-proposal-decorators runs before xaendarPlugin() in your Vite config.");
231
229
  }
232
- return jsSource.replace(lastStaticBlock, (_, indent, initFn) => `${compiledMethods}
230
+ return result.replace(lastStaticBlock, (_, indent, initFn) => `${compiledMethods}
233
231
  static {
234
232
  ${indent}${initFn}();
235
233
  }`);
234
+ ;
235
+ }
236
+ function extractClassName(jsSource) {
237
+ const match = jsSource.match(/class\s+(\w+)\s+extends/);
238
+ return match?.[1] ?? "__Component";
239
+ }
240
+ function buildStyleSnippet(varName, css) {
241
+ const escaped = css.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
242
+ return [
243
+ `const ${varName} = new CSSStyleSheet();`,
244
+ `${varName}.replaceSync(\`${escaped}\`);`,
245
+ ""
246
+ ].join("\n");
236
247
  }
237
248
  function fixDecoratorExport(code) {
238
249
  return code.replace(/^export\s+(@\w+[\s\S]*?)\s+(class\s)/gm, "$1\nexport $2");
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../packages/build-tools/src/lib/plugin.ts","../../../packages/build-tools/src/lib/costants.ts","../../../packages/build-tools/src/lib/node-compiler-host.model.ts"],"sourcesContent":["import { compile } from '@xaendar/compiler';\r\nimport { basename, dirname, extname, resolve } from 'node:path';\r\nimport type { Plugin } from 'vite';\r\nimport { COMPONENT_FILE_RE, TEMPLATE_EXTENSION } from './costants.js';\r\nimport { NodeCompilerHost } from './node-compiler-host.model.js';\r\n\r\n/**\r\n * Vite plugin that compiles Xaendar DSL template files (`.xd.component.html`)\r\n * and injects the generated render methods into the associated component class.\r\n *\r\n * ## Dev mode\r\n *\r\n * Files are transformed on demand when the browser requests them. The plugin\r\n * registers the template as a watch file via `this.addWatchFile` so that\r\n * modifying the template invalidates the component module and triggers HMR.\r\n *\r\n * ## Production build\r\n *\r\n * The same `transform` hook runs for every component file during the esbuild\r\n * bundling phase. The output is handed to esbuild as TypeScript, which strips\r\n * the types and produces the final JavaScript bundle.\r\n *\r\n * @returns A Vite {@link Plugin} instance.\r\n *\r\n * @example\r\n * // vite.config.ts\r\n * import { defineConfig } from 'vite';\r\n * import { xaendarPlugin } from '@xaendar/build-tools';\r\n *\r\n * export default defineConfig({\r\n * plugins: [xaendarPlugin()],\r\n * });\r\n */\r\nexport function xaendarPlugin(): Plugin {\r\n const host = new NodeCompilerHost;\r\n\r\n return {\r\n name: 'xaendar',\r\n transform(code, id) {\r\n if (!COMPONENT_FILE_RE.test(id)) {\r\n return null;\r\n }\r\n\r\n const templatePath = resolveTemplatePath(id);\r\n this.addWatchFile(templatePath);\r\n\r\n if (!host.fileExists(templatePath)) {\r\n this.warn(`Xaendar: could not find template at ${templatePath}`);\r\n return null;\r\n }\r\n\r\n const templateSource = host.readFile(templatePath);\r\n if (templateSource === undefined) {\r\n this.warn(`Xaendar: could not read template at ${templatePath}`);\r\n return null;\r\n }\r\n\r\n\r\n const stylePath = resolveStylePath(id);\r\n let cssContent = '';\r\n\r\n if (host.fileExists(stylePath)) {\r\n this.addWatchFile(stylePath);\r\n cssContent = host.readFile(stylePath) ?? '';\r\n }\r\n\r\n let compiledMethods!: string;\r\n try {\r\n compiledMethods = compile(templateSource, cssContent);\r\n } catch (err) {\r\n this.error(`Xaendar: failed to compile template ${templatePath}:\\n${String(err)}`);\r\n }\r\n\r\n let transformed!: string;\r\n try {\r\n transformed = fixDecoratorExport(injectRenderMethods(code, compiledMethods));\r\n } catch (err) {\r\n this.error(String(err));\r\n }\r\n\r\n return {\r\n code: transformed\r\n };\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Extracts the component name from the given file path by removing the directory\r\n * and file extension, and taking the first segment of the remaining base name.\r\n *\r\n * For example, given `src/components/app.xd.component.ts`, it will return `app`.\r\n * @param componentPath - The absolute path of the component file.\r\n * @returns The extracted component name.\r\n */\r\nfunction extractComponentName(componentPath: string): string {\r\n const base = basename(componentPath, extname(componentPath));\r\n return base.split('.')[0]!;\r\n}\r\n\r\n/**\r\n * Resolves the absolute path of the template file associated with a given\r\n * component `.ts` file, following the convention:\r\n *\r\n * ```\r\n * app.xd.component.ts → app.xd.component.html\r\n * ```\r\n *\r\n * @param componentPath - Absolute path of the component TypeScript file.\r\n * @returns Absolute path of the associated template file.\r\n */\r\nfunction resolveTemplatePath(componentPath: string): string {\r\n const dir = dirname(componentPath);\r\n const base = extractComponentName(componentPath);\r\n return resolve(dir, `${base}${TEMPLATE_EXTENSION}`);\r\n}\r\n\r\n/**\r\n * Resolves the absolute path of the style file associated with a given\r\n * component `.css` file, following the convention:\r\n *\r\n * ```\r\n * app.xd.component.ts → app.xd.component.css\r\n * ```\r\n *\r\n * @param componentPath - Absolute path of the component TypeScript file.\r\n * @returns Absolute path of the associated style file.\r\n */\r\nfunction resolveStylePath(componentPath: string, ext = 'css'): string {\r\n const dir = dirname(componentPath);\r\n const base = extractComponentName(componentPath);\r\n return resolve(dir, `${base}.${ext}`);\r\n}\r\n\r\n/**\r\n * Injects the compiled render methods into the original component component code\r\n * by replacing the placeholder static block scaffolded by the CLI. The block\r\n * is guaranteed to be present added by the Babel plugin, so if it's not found\r\n * the function throws an error indicating a misconfiguration in the component\r\n * file. \r\n * \r\n * The compiled methods are inserted before the static block, which is\r\n * preserved to maintain the correct execution order: the methods must be\r\n * defined before the initializer function runs, as the latter may reference them\r\n * to register the component with the framework.\r\n *\r\n * @param compiledCode - The original TypeScript source of the component file.\r\n * @param compiledMethods - The raw output of the compiler, already\r\n * formatted as class method bodies (no `function` keyword, no standalone\r\n * context parameter).\r\n * @returns The transformed TypeScript source with the placeholder replaced\r\n * by the compiled methods.\r\n * @throws {Error} When the placeholder is not found in the source — this\r\n * means the component file was not scaffolded correctly by the CLI.\r\n */\r\nfunction injectRenderMethods(jsSource: string, compiledMethods: string): string {\r\n // Search for the last static block in the class, which is guaranteed by the babel plugin\r\n const lastStaticBlock = /static\\s*\\{\\s*\\n(\\s*)(\\w+)\\(\\);\\s*\\n\\s*\\}/;\r\n \r\n if (!lastStaticBlock.test(jsSource)) {\r\n throw new Error('Xaendar: could not find static initializer block.');\r\n }\r\n\r\n return jsSource.replace(lastStaticBlock, (_, indent, initFn) => `${compiledMethods}\\n static {\\n${indent}${initFn}();\\n }`);\r\n}\r\n\r\n/**\r\n * esbuild bug workaround — quando transpila decorator stage 3 con export,\r\n * produce `export @Decorator class Foo {}` invece di\r\n * `@Decorator\\nexport class Foo {}`.\r\n * Riordina i token per produrre sintassi valida.\r\n */\r\nfunction fixDecoratorExport(code: string): string {\r\n return code.replace(/^export\\s+(@\\w+[\\s\\S]*?)\\s+(class\\s)/gm, '$1\\nexport $2');\r\n}","/** \r\n * Extension of the Xaendar DSL template files. \r\n */\r\nexport const TEMPLATE_EXTENSION = '.xd.component.html';\r\n\r\n/** \r\n * Matches any TypeScript file that follows the Xaendar component convention. \r\n */\r\nexport const COMPONENT_FILE_RE = /\\.xd\\.component\\.ts$/;","import type { CompilerHost } from '@xaendar/compiler';\r\nimport { existsSync, readdirSync, readFileSync, realpathSync, statSync } from 'node:fs';\r\nimport { dirname, resolve } from 'node:path';\r\n\r\n/**\r\n * Node.js implementation of {@link CompilerHost}.\r\n *\r\n * Reads files synchronously from the real filesystem using the Node.js\r\n * `fs` and `path` modules. Intended for use in `build-tools` (Vite and\r\n * esbuild plugins) and `cli` (project and component generation).\r\n *\r\n * All methods are synchronous to match the expectations of the TypeScript\r\n * compiler host API and to keep the compiler pipeline free of async\r\n * complexity at the I/O level.\r\n *\r\n * Every method that interacts with the filesystem swallows OS-level errors\r\n * (e.g. `ENOENT`, `EACCES`) and returns a safe fallback value instead of\r\n * throwing. The compiler is responsible for turning missing or unreadable\r\n * files into structured diagnostics.\r\n *\r\n * @example\r\n * import { NodeCompilerHost } from '@xaendar/build-tools';\r\n * import { Compiler } from '@xaendar/compiler';\r\n *\r\n * const host = new NodeCompilerHost();\r\n * const compiler = new Compiler(host);\r\n * const result = compiler.compile('/absolute/path/to/template.xd.component.html');\r\n */\r\nexport class NodeCompilerHost implements CompilerHost {\r\n /**\r\n * Reads the content of a file from disk as a UTF-8 string.\r\n *\r\n * Returns `undefined` instead of throwing when the file does not exist,\r\n * is a directory, or cannot be read due to permission restrictions.\r\n * The compiler treats `undefined` as a missing-file condition and emits\r\n * an appropriate diagnostic.\r\n *\r\n * @param filePath - Absolute path of the file to read.\r\n * @returns The file content as a UTF-8 string, or `undefined` on any\r\n * filesystem error.\r\n */\r\n public readFile(filePath: string): string | undefined {\r\n try {\r\n return readFileSync(filePath, 'utf-8');\r\n } catch {\r\n return undefined;\r\n }\r\n }\r\n\r\n /**\r\n * Checks whether a file exists and is accessible on disk.\r\n *\r\n * Uses `existsSync` rather than `accessSync` to avoid throwing —\r\n * a missing file is an expected condition during path resolution,\r\n * not an exceptional one.\r\n *\r\n * Returns `true` for both regular files and directories. Callers that\r\n * need to distinguish between the two should combine this method with\r\n * {@link isDirectory}.\r\n *\r\n * @param filePath - Absolute path of the file to check.\r\n * @returns `true` if the path exists and is accessible, `false` otherwise.\r\n */\r\n public fileExists(filePath: string): boolean {\r\n return existsSync(filePath);\r\n }\r\n\r\n /**\r\n * Resolves a path relative to the **directory** containing the source file.\r\n *\r\n * Delegates to `path.resolve(path.dirname(from), to)` so that relative\r\n * paths like `./button.xd.component.html` are resolved against the\r\n * directory of the referencing file, not the current working directory.\r\n *\r\n * Absolute paths passed as `to` are returned unchanged by `path.resolve`\r\n * and therefore work correctly without any special handling.\r\n *\r\n * Does not resolve path aliases (e.g. `@components/button.html`).\r\n * Alias resolution must be performed by the caller before invoking\r\n * this method, or by providing a subclass that overrides it.\r\n *\r\n * @param from - Absolute path of the source file that contains the\r\n * reference (e.g. the `.ts` file of the component).\r\n * @param to - Relative or absolute path to resolve.\r\n * @returns The resolved absolute path of the target file.\r\n *\r\n * @example\r\n * host.resolvePath(\r\n * '/src/features/user/user.xd.component.ts',\r\n * './user.xd.component.html',\r\n * );\r\n * // → '/src/features/user/user.xd.component.html'\r\n */\r\n public resolvePath(from: string, to: string): string {\r\n return resolve(dirname(from), to);\r\n }\r\n\r\n /**\r\n * Returns the names of all entries (files and subdirectories) inside\r\n * a directory.\r\n *\r\n * Returns an empty array instead of throwing when the directory does\r\n * not exist, is not readable, or `dirPath` points to a regular file.\r\n * This matches the behaviour expected by the compiler during the\r\n * discovery phase, where missing directories are not errors.\r\n *\r\n * The returned names are entry names only — not absolute paths. Callers\r\n * must combine them with `dirPath` via {@link resolvePath} to obtain\r\n * usable absolute paths.\r\n *\r\n * @param dirPath - Absolute path of the directory to read.\r\n * @returns An array of entry names inside `dirPath`, or an empty array\r\n * if the directory does not exist or cannot be read.\r\n *\r\n * @example\r\n * host.getDirectoryEntries('/src/components');\r\n * // → ['button', 'input', 'modal']\r\n */\r\n public getDirectoryEntries(dirPath: string): string[] {\r\n try {\r\n return readdirSync(dirPath);\r\n } catch {\r\n return [];\r\n }\r\n }\r\n\r\n /**\r\n * Checks whether the given path refers to a directory.\r\n *\r\n * Uses `statSync` rather than `lstatSync` so that symlinks to directories\r\n * are correctly reported as directories. Returns `false` for non-existent\r\n * paths, regular files, symlinks to files, and any path that causes\r\n * `statSync` to throw (e.g. permission denied).\r\n *\r\n * @param filePath - Absolute path to check.\r\n * @returns `true` if the path exists and is a directory (or a symlink\r\n * to one), `false` in all other cases.\r\n */\r\n public isDirectory(filePath: string): boolean {\r\n try {\r\n return statSync(filePath).isDirectory();\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Resolves all symlinks in a path and returns the real physical path.\r\n *\r\n * Critical in npm monorepos where workspace packages are symlinked inside\r\n * `node_modules`. Without real-path resolution the compiler may process\r\n * the same physical file twice under different apparent paths, producing\r\n * duplicate entries in the module graph and the output bundle.\r\n *\r\n * Falls back to returning `filePath` unchanged when `realpathSync` throws\r\n * (e.g. the path does not exist or a symlink is dangling). This keeps the\r\n * compiler operational even when the path cannot be fully resolved.\r\n *\r\n * @param filePath - Absolute path, potentially containing symlinks.\r\n * @returns The real absolute path with all symlinks resolved, or\r\n * `filePath` unchanged if resolution fails.\r\n *\r\n * @example\r\n * // In an npm monorepo:\r\n * // /app/node_modules/@xaendar/core → /packages/core/src\r\n * host.getRealPath('/app/node_modules/@xaendar/core/index.ts');\r\n * // → '/packages/core/src/index.ts'\r\n */\r\n public getRealPath(filePath: string): string {\r\n try {\r\n return realpathSync(filePath);\r\n } catch {\r\n return filePath;\r\n }\r\n }\r\n\r\n /**\r\n * Returns the current working directory of the Node.js process.\r\n *\r\n * Used by the compiler as the base for resolving relative paths that\r\n * have no associated source file — for example paths passed as CLI\r\n * arguments or specified in the project configuration file.\r\n *\r\n * @returns The absolute path of the current working directory.\r\n */\r\n public getCurrentDirectory(): string {\r\n return process.cwd();\r\n }\r\n}"],"mappings":"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","names":["dirname","resolve","dirname","resolve"]}
1
+ {"version":3,"sources":["../../../packages/build-tools/src/lib/plugin.ts","../../../packages/build-tools/src/lib/costants.ts","../../../packages/build-tools/src/lib/node-compiler-host.model.ts"],"sourcesContent":["import { compile } from '@xaendar/compiler';\r\nimport { dirname, resolve } from 'node:path';\r\nimport type { Plugin } from 'vite';\r\nimport { COMPONENT_FILE_RE } from './costants.js';\r\nimport { NodeCompilerHost } from './node-compiler-host.model.js';\r\n\r\n/**\r\n * Vite plugin that compiles Xaendar DSL template files (`.xd.component.html`)\r\n * and injects the generated render methods into the associated component class.\r\n *\r\n * ## Dev mode\r\n *\r\n * Files are transformed on demand when the browser requests them. The plugin\r\n * registers the template as a watch file via `this.addWatchFile` so that\r\n * modifying the template invalidates the component module and triggers HMR.\r\n *\r\n * ## Production build\r\n *\r\n * The same `transform` hook runs for every component file during the esbuild\r\n * bundling phase. The output is handed to esbuild as TypeScript, which strips\r\n * the types and produces the final JavaScript bundle.\r\n *\r\n * @returns A Vite {@link Plugin} instance.\r\n *\r\n * @example\r\n * // vite.config.ts\r\n * import { defineConfig } from 'vite';\r\n * import { xaendarPlugin } from '@xaendar/build-tools';\r\n *\r\n * export default defineConfig({\r\n * plugins: [xaendarPlugin()],\r\n * });\r\n */\r\nexport function xaendarPlugin(): Plugin {\r\n const host = new NodeCompilerHost;\r\n\r\n return {\r\n name: 'xaendar',\r\n transform(code, id) {\r\n if (!COMPONENT_FILE_RE.test(id)) {\r\n return null;\r\n }\r\n\r\n const { templatePath, stylePath } = extractDecoratorPaths(code, dirname(id));\r\n\r\n if (!templatePath || !host.fileExists(templatePath)) {\r\n this.warn(`Xaendar: could not find template at ${templatePath}`);\r\n return null;\r\n }\r\n\r\n this.addWatchFile(templatePath);\r\n\r\n const templateSource = host.readFile(templatePath);\r\n if (templateSource === undefined) {\r\n this.warn(`Xaendar: could not read template at ${templatePath}`);\r\n return null;\r\n }\r\n\r\n let cssContent = '';\r\n\r\n if (stylePath && host.fileExists(stylePath)) {\r\n this.addWatchFile(stylePath);\r\n cssContent = host.readFile(stylePath) ?? '';\r\n }\r\n\r\n let compiledMethods!: string;\r\n const varName = `__${extractClassName(id)}_sheet`\r\n ;\r\n try {\r\n compiledMethods = compile(templateSource, varName);\r\n } catch (err) {\r\n this.error(`Xaendar: failed to compile template ${templatePath}:\\n${String(err)}`);\r\n }\r\n\r\n let transformed!: string;\r\n try {\r\n transformed = fixDecoratorExport(injectRenderMethods(code, compiledMethods, varName, cssContent));\r\n } catch (err) {\r\n this.error(String(err));\r\n }\r\n\r\n return {\r\n code: transformed\r\n };\r\n },\r\n };\r\n}\r\n\r\nfunction extractDecoratorPaths(jsSource: string, componentDir: string): { templatePath: string | undefined; stylePath: string | undefined } {\r\n const templateUrl = jsSource.match(/templateUrl\\s*:\\s*[\"'](.+?)[\"']/)?.[1];\r\n const styleUrl = jsSource.match(/styleUrl\\s*:\\s*[\"'](.+?)[\"']/)?.[1];\r\n\r\n return {\r\n templatePath: templateUrl ? resolve(componentDir, templateUrl) : undefined,\r\n stylePath: styleUrl ? resolve(componentDir, styleUrl) : undefined,\r\n };\r\n}\r\n\r\n/**\r\n * Injects the compiled render methods into the original component component code\r\n * by replacing the placeholder static block scaffolded by the CLI. The block\r\n * is guaranteed to be present added by the Babel plugin, so if it's not found\r\n * the function throws an error indicating a misconfiguration in the component\r\n * file. \r\n * \r\n * The compiled methods are inserted before the static block, which is\r\n * preserved to maintain the correct execution order: the methods must be\r\n * defined before the initializer function runs, as the latter may reference them\r\n * to register the component with the framework.\r\n *\r\n * @param compiledCode - The original TypeScript source of the component file.\r\n * @param compiledMethods - The raw output of the compiler, already\r\n * formatted as class method bodies (no `function` keyword, no standalone\r\n * context parameter).\r\n * @param varName - The variable name to use for the shared `CSSStyleSheet`\r\n * declaration, if any CSS content is provided.\r\n * @param cssContent - The raw CSS content read from disk, to be injected as a\r\n * shared `CSSStyleSheet` if not empty.\r\n * @returns The transformed TypeScript source with the placeholder replaced\r\n * by the compiled methods.\r\n * @throws {Error} When the placeholder is not found in the source — this\r\n * means the component file was not scaffolded correctly by the CLI.\r\n */\r\nfunction injectRenderMethods(jsSource: string, compiledMethods: string, varName: string, cssContent: string): string {\r\n const styleSnippet = cssContent.trim().length ? buildStyleSnippet(varName, cssContent) : '';\r\n \r\n let result = jsSource;\r\n \r\n if (styleSnippet) {\r\n result = result.replace(/^(class\\s+\\w+\\s+extends)/m, `${styleSnippet}$1`);\r\n }\r\n \r\n const lastStaticBlock = /static\\s*\\{\\s*\\n(\\s*)(\\w+)\\(\\);\\s*\\n\\s*\\}/;\r\n \r\n if (!lastStaticBlock.test(result)) {\r\n throw new Error('Xaendar: could not find the static initializer block in the transpiled output. Make sure @rolldown/plugin-babel with @babel/plugin-proposal-decorators runs before xaendarPlugin() in your Vite config.');\r\n }\r\n \r\n return result.replace(lastStaticBlock, (_, indent, initFn) => `${compiledMethods}\\n static {\\n${indent}${initFn}();\\n }`);;\r\n}\r\n\r\n/**\r\n * Extracts the class name from the Babel-transpiled JS source.\r\n *\r\n * Babel always emits `class ClassName extends ...` so this is safe to match.\r\n * Used to generate a unique name for the per-class CSSStyleSheet variable\r\n * that must be declared outside the class body to guarantee it exists before\r\n * `connectedCallback` fires.\r\n *\r\n * @param jsSource - The Babel-transpiled JS source of the component.\r\n * @returns The class name, or `__Component` as a safe fallback.\r\n */\r\nfunction extractClassName(jsSource: string): string {\r\n const match = jsSource.match(/class\\s+(\\w+)\\s+extends/);\r\n return match?.[1] ?? '__Component';\r\n}\r\n \r\n/**\r\n * Builds the JS snippet that declares and populates the shared\r\n * `CSSStyleSheet` for the component class.\r\n *\r\n * The variable is declared outside the class body so it is fully\r\n * initialised before Babel's first `static {}` block runs — which is\r\n * where `customElements.define()` is called and may immediately trigger\r\n * `connectedCallback` if the element is already in the DOM.\r\n *\r\n * @param varName - The variable name for the shared `CSSStyleSheet`.\r\n * @param css - Raw CSS content to embed.\r\n * @returns A JS snippet string ending with a newline.\r\n */\r\nfunction buildStyleSnippet(varName: string, css: string): string {\r\n const escaped = css.replace(/\\\\/g, '\\\\\\\\').replace(/`/g, '\\\\`').replace(/\\$\\{/g, '\\\\${');\r\n return [\r\n `const ${varName} = new CSSStyleSheet();`,\r\n `${varName}.replaceSync(\\`${escaped}\\`);`,\r\n '',\r\n ].join('\\n');\r\n}\r\n\r\n/**\r\n * esbuild bug workaround — quando transpila decorator stage 3 con export,\r\n * produce `export @Decorator class Foo {}` invece di\r\n * `@Decorator\\nexport class Foo {}`.\r\n * Riordina i token per produrre sintassi valida.\r\n */\r\nfunction fixDecoratorExport(code: string): string {\r\n return code.replace(/^export\\s+(@\\w+[\\s\\S]*?)\\s+(class\\s)/gm, '$1\\nexport $2');\r\n}","/** \r\n * Extension of the Xaendar DSL template files. \r\n */\r\nexport const TEMPLATE_EXTENSION = '.xd.component.html';\r\n\r\n/** \r\n * Extension of the Xaendar DSL style files. \r\n */\r\nexport const STYLE_EXTENSION = (extension = 'css') => `.xd.component.${extension}`;\r\n\r\n/** \r\n * Matches any TypeScript file that follows the Xaendar component convention. \r\n */\r\nexport const COMPONENT_FILE_RE = /\\.xd\\.component\\.ts$/;","import type { CompilerHost } from '@xaendar/compiler';\r\nimport { existsSync, readdirSync, readFileSync, realpathSync, statSync } from 'node:fs';\r\nimport { dirname, resolve } from 'node:path';\r\n\r\n/**\r\n * Node.js implementation of {@link CompilerHost}.\r\n *\r\n * Reads files synchronously from the real filesystem using the Node.js\r\n * `fs` and `path` modules. Intended for use in `build-tools` (Vite and\r\n * esbuild plugins) and `cli` (project and component generation).\r\n *\r\n * All methods are synchronous to match the expectations of the TypeScript\r\n * compiler host API and to keep the compiler pipeline free of async\r\n * complexity at the I/O level.\r\n *\r\n * Every method that interacts with the filesystem swallows OS-level errors\r\n * (e.g. `ENOENT`, `EACCES`) and returns a safe fallback value instead of\r\n * throwing. The compiler is responsible for turning missing or unreadable\r\n * files into structured diagnostics.\r\n *\r\n * @example\r\n * import { NodeCompilerHost } from '@xaendar/build-tools';\r\n * import { Compiler } from '@xaendar/compiler';\r\n *\r\n * const host = new NodeCompilerHost();\r\n * const compiler = new Compiler(host);\r\n * const result = compiler.compile('/absolute/path/to/template.xd.component.html');\r\n */\r\nexport class NodeCompilerHost implements CompilerHost {\r\n /**\r\n * Reads the content of a file from disk as a UTF-8 string.\r\n *\r\n * Returns `undefined` instead of throwing when the file does not exist,\r\n * is a directory, or cannot be read due to permission restrictions.\r\n * The compiler treats `undefined` as a missing-file condition and emits\r\n * an appropriate diagnostic.\r\n *\r\n * @param filePath - Absolute path of the file to read.\r\n * @returns The file content as a UTF-8 string, or `undefined` on any\r\n * filesystem error.\r\n */\r\n public readFile(filePath: string): string | undefined {\r\n try {\r\n return readFileSync(filePath, 'utf-8');\r\n } catch {\r\n return undefined;\r\n }\r\n }\r\n\r\n /**\r\n * Checks whether a file exists and is accessible on disk.\r\n *\r\n * Uses `existsSync` rather than `accessSync` to avoid throwing —\r\n * a missing file is an expected condition during path resolution,\r\n * not an exceptional one.\r\n *\r\n * Returns `true` for both regular files and directories. Callers that\r\n * need to distinguish between the two should combine this method with\r\n * {@link isDirectory}.\r\n *\r\n * @param filePath - Absolute path of the file to check.\r\n * @returns `true` if the path exists and is accessible, `false` otherwise.\r\n */\r\n public fileExists(filePath: string): boolean {\r\n return existsSync(filePath);\r\n }\r\n\r\n /**\r\n * Resolves a path relative to the **directory** containing the source file.\r\n *\r\n * Delegates to `path.resolve(path.dirname(from), to)` so that relative\r\n * paths like `./button.xd.component.html` are resolved against the\r\n * directory of the referencing file, not the current working directory.\r\n *\r\n * Absolute paths passed as `to` are returned unchanged by `path.resolve`\r\n * and therefore work correctly without any special handling.\r\n *\r\n * Does not resolve path aliases (e.g. `@components/button.html`).\r\n * Alias resolution must be performed by the caller before invoking\r\n * this method, or by providing a subclass that overrides it.\r\n *\r\n * @param from - Absolute path of the source file that contains the\r\n * reference (e.g. the `.ts` file of the component).\r\n * @param to - Relative or absolute path to resolve.\r\n * @returns The resolved absolute path of the target file.\r\n *\r\n * @example\r\n * host.resolvePath(\r\n * '/src/features/user/user.xd.component.ts',\r\n * './user.xd.component.html',\r\n * );\r\n * // → '/src/features/user/user.xd.component.html'\r\n */\r\n public resolvePath(from: string, to: string): string {\r\n return resolve(dirname(from), to);\r\n }\r\n\r\n /**\r\n * Returns the names of all entries (files and subdirectories) inside\r\n * a directory.\r\n *\r\n * Returns an empty array instead of throwing when the directory does\r\n * not exist, is not readable, or `dirPath` points to a regular file.\r\n * This matches the behaviour expected by the compiler during the\r\n * discovery phase, where missing directories are not errors.\r\n *\r\n * The returned names are entry names only — not absolute paths. Callers\r\n * must combine them with `dirPath` via {@link resolvePath} to obtain\r\n * usable absolute paths.\r\n *\r\n * @param dirPath - Absolute path of the directory to read.\r\n * @returns An array of entry names inside `dirPath`, or an empty array\r\n * if the directory does not exist or cannot be read.\r\n *\r\n * @example\r\n * host.getDirectoryEntries('/src/components');\r\n * // → ['button', 'input', 'modal']\r\n */\r\n public getDirectoryEntries(dirPath: string): string[] {\r\n try {\r\n return readdirSync(dirPath);\r\n } catch {\r\n return [];\r\n }\r\n }\r\n\r\n /**\r\n * Checks whether the given path refers to a directory.\r\n *\r\n * Uses `statSync` rather than `lstatSync` so that symlinks to directories\r\n * are correctly reported as directories. Returns `false` for non-existent\r\n * paths, regular files, symlinks to files, and any path that causes\r\n * `statSync` to throw (e.g. permission denied).\r\n *\r\n * @param filePath - Absolute path to check.\r\n * @returns `true` if the path exists and is a directory (or a symlink\r\n * to one), `false` in all other cases.\r\n */\r\n public isDirectory(filePath: string): boolean {\r\n try {\r\n return statSync(filePath).isDirectory();\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Resolves all symlinks in a path and returns the real physical path.\r\n *\r\n * Critical in npm monorepos where workspace packages are symlinked inside\r\n * `node_modules`. Without real-path resolution the compiler may process\r\n * the same physical file twice under different apparent paths, producing\r\n * duplicate entries in the module graph and the output bundle.\r\n *\r\n * Falls back to returning `filePath` unchanged when `realpathSync` throws\r\n * (e.g. the path does not exist or a symlink is dangling). This keeps the\r\n * compiler operational even when the path cannot be fully resolved.\r\n *\r\n * @param filePath - Absolute path, potentially containing symlinks.\r\n * @returns The real absolute path with all symlinks resolved, or\r\n * `filePath` unchanged if resolution fails.\r\n *\r\n * @example\r\n * // In an npm monorepo:\r\n * // /app/node_modules/@xaendar/core → /packages/core/src\r\n * host.getRealPath('/app/node_modules/@xaendar/core/index.ts');\r\n * // → '/packages/core/src/index.ts'\r\n */\r\n public getRealPath(filePath: string): string {\r\n try {\r\n return realpathSync(filePath);\r\n } catch {\r\n return filePath;\r\n }\r\n }\r\n\r\n /**\r\n * Returns the current working directory of the Node.js process.\r\n *\r\n * Used by the compiler as the base for resolving relative paths that\r\n * have no associated source file — for example paths passed as CLI\r\n * arguments or specified in the project configuration file.\r\n *\r\n * @returns The absolute path of the current working directory.\r\n */\r\n public getCurrentDirectory(): string {\r\n return process.cwd();\r\n }\r\n}"],"mappings":"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","names":["dirname","resolve","dirname","resolve"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xaendar/build-tools",
3
- "version": "0.3.19",
3
+ "version": "0.3.21",
4
4
  "description": "A library containing build tools for Xaendar framework",
5
5
  "author": "Kaitenjo",
6
6
  "license": "MIT",
@@ -9,7 +9,7 @@
9
9
  ".": "./index.js"
10
10
  },
11
11
  "dependencies": {
12
- "@xaendar/compiler": "0.3.19",
12
+ "@xaendar/compiler": "0.3.21",
13
13
  "vite": "^8.0.14"
14
14
  }
15
15
  }