xpine 0.0.20 → 0.0.22

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 (40) hide show
  1. package/TODO +0 -2
  2. package/dist/index.js +357 -128
  3. package/dist/src/build/esbuild/addDotJS.d.ts +5 -0
  4. package/dist/src/build/esbuild/addDotJS.d.ts.map +1 -0
  5. package/dist/src/build/esbuild/getDataFiles.d.ts +5 -0
  6. package/dist/src/build/esbuild/getDataFiles.d.ts.map +1 -0
  7. package/dist/src/build/esbuild/transformTSXFiles.d.ts +6 -0
  8. package/dist/src/build/esbuild/transformTSXFiles.d.ts.map +1 -0
  9. package/dist/src/express.d.ts +3 -0
  10. package/dist/src/express.d.ts.map +1 -1
  11. package/dist/src/runDevServer.d.ts.map +1 -1
  12. package/dist/src/scripts/build.d.ts +5 -1
  13. package/dist/src/scripts/build.d.ts.map +1 -1
  14. package/dist/src/scripts/xpine-build.js +249 -104
  15. package/dist/src/scripts/xpine-dev.js +294 -114
  16. package/dist/src/static/spa.js +2 -1
  17. package/dist/src/util/config-file.d.ts +6 -0
  18. package/dist/src/util/config-file.d.ts.map +1 -0
  19. package/dist/src/util/constants.d.ts +3 -0
  20. package/dist/src/util/constants.d.ts.map +1 -0
  21. package/dist/src/util/get-config.d.ts.map +1 -1
  22. package/dist/src/util/postcss/remove-layers.d.ts +1 -1
  23. package/dist/src/util/regex.d.ts +11 -0
  24. package/dist/src/util/regex.d.ts.map +1 -0
  25. package/dist/src/util/require.d.ts.map +1 -1
  26. package/dist/types.d.ts +31 -2
  27. package/dist/types.d.ts.map +1 -1
  28. package/eslint.config.mjs +27 -0
  29. package/package.json +18 -5
  30. package/tests/e2e/alpine.spec.ts +14 -0
  31. package/tests/e2e/app-build.spec.ts +73 -0
  32. package/tests/e2e/spa.spec.ts +23 -0
  33. package/tests/e2e/tests-examples/demo-todo-app.spec.ts +437 -0
  34. package/tests/eslint.config.mjs +27 -0
  35. package/tests/package-lock.json +8941 -0
  36. package/tests/package.json +89 -0
  37. package/tests/playwright.config.ts +81 -0
  38. package/tests/tsconfig.json +46 -0
  39. package/tests/xpine.config.mjs +1 -0
  40. package/types.ts +34 -2
@@ -0,0 +1,5 @@
1
+ export default function addDotJS(allPackages: string[], extensions: string[], isDev: boolean): {
2
+ name: string;
3
+ setup(build: any): void;
4
+ };
5
+ //# sourceMappingURL=addDotJS.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addDotJS.d.ts","sourceRoot":"","sources":["../../../../src/build/esbuild/addDotJS.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO;;;EA0B3F"}
@@ -0,0 +1,5 @@
1
+ export default function getDataFiles(dataFiles: any[]): {
2
+ name: string;
3
+ setup(build: any): void;
4
+ };
5
+ //# sourceMappingURL=getDataFiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getDataFiles.d.ts","sourceRoot":"","sources":["../../../../src/build/esbuild/getDataFiles.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,SAAS,EAAE,GAAG,EAAE;;;EAiBpD"}
@@ -0,0 +1,6 @@
1
+ import { ComponentData } from '../../../types';
2
+ export default function transformTSXFiles(componentData: ComponentData[], pageConfigFiles: string[]): {
3
+ name: string;
4
+ setup(build: any): void;
5
+ };
6
+ //# sourceMappingURL=transformTSXFiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformTSXFiles.d.ts","sourceRoot":"","sources":["../../../../src/build/esbuild/transformTSXFiles.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,aAAa,EAAE,aAAa,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE;;;EA2BlG"}
@@ -4,4 +4,7 @@ export declare function createRouter(): Promise<{
4
4
  routeResults: any[];
5
5
  }>;
6
6
  export declare function createXPineRouter(app: any, beforeErrorRoute?: (app: Express) => void): Promise<void>;
7
+ export declare function routeHasStaticPath(route: string, params: {
8
+ [key: string]: string;
9
+ }): string | false;
7
10
  //# sourceMappingURL=express.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/express.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAgB,OAAO,EAAqB,MAAM,SAAS,CAAC;AAS5E,wBAAsB,YAAY;;;GAgEjC;AAiBD,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,iBA6B1F"}
1
+ {"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/express.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAgB,OAAO,EAAqB,MAAM,SAAS,CAAC;AAY5E,wBAAsB,YAAY;;;GAqGjC;AAiBD,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,iBA6B1F;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,KAAK,CAWnG"}
@@ -1 +1 @@
1
- {"version":3,"file":"runDevServer.d.ts","sourceRoot":"","sources":["../../src/runDevServer.ts"],"names":[],"mappings":"AAYA,wBAAsB,YAAY,kBAiDjC"}
1
+ {"version":3,"file":"runDevServer.d.ts","sourceRoot":"","sources":["../../src/runDevServer.ts"],"names":[],"mappings":"AAYA,wBAAsB,YAAY,kBA6DjC"}
@@ -1,5 +1,9 @@
1
- export declare function buildApp(isDev?: boolean): Promise<void>;
1
+ import { ConfigFile, ComponentData } from '../../types';
2
+ export declare function buildApp(isDev?: boolean, removePreviousBuild?: boolean): Promise<void>;
2
3
  export declare function buildCSS(): Promise<void>;
3
4
  export declare function buildPublicFolderSymlinks(): Promise<void>;
4
5
  export declare function logSize(pathName: string, type: 'app' | 'client' | 'css', validExtensions?: string[]): Promise<void>;
6
+ export declare function buildFilesWithConfigs(componentData: ComponentData[]): Promise<void>;
7
+ export declare function buildStaticFiles(config: ConfigFile, component: ComponentData, componentImport: any, builtComponentPath: string): Promise<void>;
8
+ export declare function getComponentDynamicPaths(componentPath: string): string[];
5
9
  //# sourceMappingURL=build.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/scripts/build.ts"],"names":[],"mappings":"AA2BA,wBAAsB,QAAQ,CAAC,KAAK,UAAQ,iBAa3C;AAmMD,wBAAsB,QAAQ,kBAW7B;AAGD,wBAAsB,yBAAyB,kBAgB9C;AAOD,wBAAsB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,KAAK,EAAE,eAAe,WAAkB,iBAahH"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/scripts/build.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,UAAU,EAA2B,aAAa,EAAE,MAAM,aAAa,CAAC;AASjF,wBAAsB,QAAQ,CAAC,KAAK,UAAQ,EAAE,mBAAmB,UAAQ,iBAgBxE;AA2ID,wBAAsB,QAAQ,kBAW7B;AAGD,wBAAsB,yBAAyB,kBAgB9C;AAED,wBAAsB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,KAAK,EAAE,eAAe,WAAkB,iBAahH;AAED,wBAAsB,qBAAqB,CAAC,aAAa,EAAE,aAAa,EAAE,iBAezE;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,iBA4DpI;AAED,wBAAgB,wBAAwB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,CAQxE"}
@@ -1,11 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/scripts/build.ts
4
- import path3 from "path";
5
- import fs2 from "fs-extra";
4
+ import path5 from "path";
5
+ import fs5 from "fs-extra";
6
6
  import { build } from "esbuild";
7
- import builtinModules from "builtin-modules";
8
- import ts2 from "typescript";
7
+ import ts3 from "typescript";
9
8
 
10
9
  // src/build/typescript-builder.ts
11
10
  import ts from "typescript";
@@ -109,17 +108,6 @@ function removeClientScriptInTSXFile(pathName, source) {
109
108
  clientDataStart
110
109
  };
111
110
  }
112
- function createStaticFile(pathName, source) {
113
- source.forEachChild((child) => {
114
- if (child.kind === ts.SyntaxKind.ExpressionStatement) {
115
- const text = child.getText(source);
116
- const cleanedText = text.replace(/["';]/g, "");
117
- if (cleanedText === "xpine-static") {
118
- console.log("make this file static", pathName);
119
- }
120
- }
121
- });
122
- }
123
111
 
124
112
  // src/scripts/build.ts
125
113
  import { globSync } from "glob";
@@ -135,6 +123,10 @@ var require_default = createRequire(import.meta.url);
135
123
  function getXPineDistDir() {
136
124
  const dir = import.meta.dirname;
137
125
  const splitDir = dir.split("/xpine/dist");
126
+ if (splitDir.length === 1) {
127
+ const splitDirSingle = dir.split("/xpine/");
128
+ return splitDirSingle[0] + "/xpine/dist";
129
+ }
138
130
  return splitDir[0] + "/xpine/dist";
139
131
  }
140
132
 
@@ -176,6 +168,9 @@ var configDefaults = {
176
168
  get pagesDir() {
177
169
  return path2.join(this.srcDir, "./pages");
178
170
  },
171
+ get distPagesDir() {
172
+ return path2.join(this.distDir, "./pages");
173
+ },
179
174
  get publicDir() {
180
175
  return path2.join(this.srcDir, "./public");
181
176
  },
@@ -211,21 +206,152 @@ var plugin = (opts = {}) => {
211
206
  plugin.postcss = true;
212
207
  var remove_layers_default = plugin;
213
208
 
209
+ // src/build/esbuild/transformTSXFiles.ts
210
+ import fs2 from "fs-extra";
211
+ import ts2 from "typescript";
212
+
213
+ // src/util/regex.ts
214
+ var regex_default = {
215
+ dotTsx: /.tsx/,
216
+ hasLetters: /[A-Za-z0-9]/g,
217
+ configFile: /\+config\.[tj]sx?/g,
218
+ dynamicRoutes: /(\[)(.*?)(\])/g,
219
+ isDynamicRoute: /\[(.*)\]/g,
220
+ endsWithTSX: /\.tsx$/,
221
+ endsWithJSX: /\.jsx$/
222
+ };
223
+
224
+ // src/util/config-file.ts
225
+ import path3 from "path";
226
+ function sourcePathToDistPath(sourcePath) {
227
+ return sourcePath?.replace(config.srcDir, config.distDir)?.replace(/\.ts$/, ".js")?.replace(/\.tsx$/, ".js");
228
+ }
229
+ function getConfigFiles(pathName, pageConfigFiles, returnDistPaths = true) {
230
+ const configs = [];
231
+ for (const configFile of pageConfigFiles) {
232
+ const result = path3.relative(pathName, configFile)?.replace(regex_default.configFile, "");
233
+ const hasLetters = result.match(regex_default.hasLetters);
234
+ if (!hasLetters) {
235
+ configs.push(returnDistPaths ? sourcePathToDistPath(configFile) : configFile);
236
+ }
237
+ }
238
+ if (!configs.length) return null;
239
+ return configs.sort((a, b) => b.length - a.length);
240
+ }
241
+ async function getCompleteConfig(configFiles, cacheKey) {
242
+ let config2 = {};
243
+ for (const configFile of configFiles) {
244
+ config2 = {
245
+ ...(await import(configFile + `?cache=${cacheKey}`)).default,
246
+ ...config2
247
+ };
248
+ }
249
+ return config2;
250
+ }
251
+ function isAConfigFile(pathName) {
252
+ return !!pathName.match(regex_default.configFile);
253
+ }
254
+
255
+ // src/build/esbuild/transformTSXFiles.ts
256
+ function transformTSXFiles(componentData, pageConfigFiles) {
257
+ return {
258
+ name: "transform-tsx-files",
259
+ setup(build2) {
260
+ build2.onLoad({ filter: regex_default.dotTsx }, async (args) => {
261
+ const content = fs2.readFileSync(args.path, "utf-8");
262
+ const source = ts2.createSourceFile(
263
+ args.path,
264
+ content,
265
+ ts2.ScriptTarget.Latest
266
+ );
267
+ const cleanedContent = removeClientScriptInTSXFile(args.path, source);
268
+ const htmlImportStart = "import { html } from 'xpine';\n";
269
+ const newContent = `${htmlImportStart}${cleanedContent.content}`;
270
+ componentData.push({
271
+ ...args,
272
+ contents: `${htmlImportStart}${cleanedContent.fullContent}`,
273
+ clientContent: cleanedContent.clientContent,
274
+ configFiles: isAConfigFile(args?.path) ? null : getConfigFiles(args.path, pageConfigFiles)
275
+ });
276
+ return {
277
+ contents: newContent,
278
+ loader: "tsx"
279
+ };
280
+ });
281
+ }
282
+ };
283
+ }
284
+
285
+ // src/build/esbuild/addDotJS.ts
286
+ import fs3 from "fs-extra";
287
+ import path4 from "path";
288
+ import builtinModules from "builtin-modules";
289
+ function addDotJS(allPackages2, extensions2, isDev) {
290
+ const allPackagesIncludingNode = allPackages2.concat(builtinModules);
291
+ return {
292
+ name: "add-dot-js",
293
+ setup(build2) {
294
+ build2.onResolve({ filter: /.*/ }, (args) => {
295
+ const hasAtSign = args.path.startsWith("@");
296
+ const isPackage = hasAtSign ? allPackagesIncludingNode.includes(args.path) : allPackagesIncludingNode.includes(args.path.split("/").shift());
297
+ if (args.importer && !isPackage) {
298
+ const calculatedDir = path4.join(args.resolveDir, args.path);
299
+ let existsAsFile = false;
300
+ for (const extension of extensions2) {
301
+ const asFile = calculatedDir + extension;
302
+ const exists = fs3.existsSync(asFile);
303
+ if (exists) existsAsFile = true;
304
+ }
305
+ let outputPath = args.path + (existsAsFile ? "" : "/index") + ".js";
306
+ outputPath = args.path.endsWith(".js") || args.path.endsWith(".mjs") ? args.path : outputPath;
307
+ return { path: outputPath + (isDev ? `?cache=${Date.now()}` : ""), external: true };
308
+ }
309
+ });
310
+ }
311
+ };
312
+ }
313
+
314
+ // src/build/esbuild/getDataFiles.ts
315
+ import fs4 from "fs-extra";
316
+ function getDataFiles(dataFiles) {
317
+ return {
318
+ name: "get-data-files",
319
+ setup(build2) {
320
+ build2.onLoad({ filter: /\.data\.(js|mjs|ts)$/ }, (args) => {
321
+ const contents = fs4.readFileSync(args.path, "utf-8");
322
+ dataFiles.push({
323
+ ...args,
324
+ contents
325
+ });
326
+ return {
327
+ contents,
328
+ loader: "ts"
329
+ };
330
+ });
331
+ }
332
+ };
333
+ }
334
+
335
+ // src/util/constants.ts
336
+ var doctypeHTML = "<!DOCTYPE html>";
337
+ var staticComment = "<!-- static -->";
338
+
214
339
  // src/scripts/build.ts
215
340
  var extensions = [".ts", ".tsx"];
216
- var packageJson = JSON.parse(fs2.readFileSync(config.packageJsonPath, "utf-8"));
341
+ var packageJson = JSON.parse(fs5.readFileSync(config.packageJsonPath, "utf-8"));
217
342
  var allPackages = Object.keys(packageJson.devDependencies).concat(Object.keys(packageJson.dependencies));
218
- var allPackagesIncludingNode = allPackages.concat(builtinModules);
219
343
  var xpineDistDir = getXPineDistDir();
220
- async function buildApp(isDev = false) {
344
+ async function buildApp(isDev = false, removePreviousBuild = false) {
221
345
  try {
346
+ if (removePreviousBuild) fs5.removeSync(config.distDir);
222
347
  const srcDirFiles = globSync(config.srcDir + "/**/*.{js,ts,tsx,jsx}");
223
348
  const { componentData, dataFiles } = await buildAppFiles(srcDirFiles, isDev);
224
349
  const alpineDataFile = await buildAlpineDataFile(componentData, dataFiles);
225
350
  await buildClientSideFiles([alpineDataFile], isDev);
226
- fs2.removeSync(config.distTempFolder);
351
+ fs5.removeSync(config.distTempFolder);
227
352
  await buildCSS();
228
353
  await buildPublicFolderSymlinks();
354
+ if (!isDev) await buildFilesWithConfigs(componentData);
229
355
  } catch (err) {
230
356
  console.error("Build failed");
231
357
  console.error(err);
@@ -234,8 +360,12 @@ async function buildApp(isDev = false) {
234
360
  async function buildAppFiles(files, isDev) {
235
361
  const componentData = [];
236
362
  const dataFiles = [];
363
+ const pageConfigFiles = files.filter((file) => {
364
+ const fileName = file.split("/").at(-1).split(".").shift();
365
+ return fileName === "+config";
366
+ });
237
367
  const backendFiles = files.filter((file) => extensions.find((ext) => file.endsWith(ext))).filter((file) => !file.startsWith(config.publicDir));
238
- fs2.ensureDirSync(config.distDir);
368
+ fs5.ensureDirSync(config.distDir);
239
369
  await build({
240
370
  entryPoints: backendFiles,
241
371
  format: "esm",
@@ -247,69 +377,9 @@ async function buildAppFiles(files, isDev) {
247
377
  jsx: "transform",
248
378
  minify: !isDev,
249
379
  plugins: [
250
- {
251
- name: "add-dot-js",
252
- setup(build2) {
253
- build2.onResolve({ filter: /.*/ }, (args) => {
254
- const hasAtSign = args.path.startsWith("@");
255
- const isPackage = hasAtSign ? allPackagesIncludingNode.includes(args.path) : allPackagesIncludingNode.includes(args.path.split("/").shift());
256
- if (args.importer && !isPackage) {
257
- const calculatedDir = path3.join(args.resolveDir, args.path);
258
- let existsAsFile = false;
259
- for (const extension of extensions) {
260
- const asFile = calculatedDir + extension;
261
- const exists = fs2.existsSync(asFile);
262
- if (exists) existsAsFile = true;
263
- }
264
- let outputPath = args.path + (existsAsFile ? "" : "/index") + ".js";
265
- outputPath = args.path.endsWith(".js") || args.path.endsWith(".mjs") ? args.path : outputPath;
266
- return { path: outputPath + (isDev ? `?cache=${Date.now()}` : ""), external: true };
267
- }
268
- });
269
- }
270
- },
271
- {
272
- name: "insert-html-banner-and-remove-client-scripts",
273
- setup(build2) {
274
- build2.onLoad({ filter: /.tsx/ }, (args) => {
275
- const content = fs2.readFileSync(args.path, "utf-8");
276
- const source = ts2.createSourceFile(
277
- args.path,
278
- content,
279
- ts2.ScriptTarget.Latest
280
- );
281
- const cleanedContent = removeClientScriptInTSXFile(args.path, source);
282
- createStaticFile(args.path, source);
283
- const htmlImportStart = "import { html } from 'xpine';\n";
284
- const newContent = `${htmlImportStart}${cleanedContent.content}`;
285
- componentData.push({
286
- ...args,
287
- contents: `${htmlImportStart}${cleanedContent.fullContent}`,
288
- clientContent: cleanedContent.clientContent
289
- });
290
- return {
291
- contents: newContent,
292
- loader: "tsx"
293
- };
294
- });
295
- }
296
- },
297
- {
298
- name: "get-data-files",
299
- setup(build2) {
300
- build2.onLoad({ filter: /\.data\.(js|mjs|ts)$/ }, (args) => {
301
- const contents = fs2.readFileSync(args.path, "utf-8");
302
- dataFiles.push({
303
- ...args,
304
- contents
305
- });
306
- return {
307
- contents,
308
- loader: "ts"
309
- };
310
- });
311
- }
312
- }
380
+ addDotJS(allPackages, extensions, isDev),
381
+ transformTSXFiles(componentData, pageConfigFiles),
382
+ getDataFiles(dataFiles)
313
383
  ]
314
384
  });
315
385
  await logSize(config.distDir, "app");
@@ -319,8 +389,8 @@ async function buildAppFiles(files, isDev) {
319
389
  };
320
390
  }
321
391
  async function buildClientSideFiles(alpineDataFiles = [], isDev) {
322
- const tempFilePath = path3.join(config.distTempFolder, "./app.ts");
323
- fs2.ensureFileSync(tempFilePath);
392
+ const tempFilePath = path5.join(config.distTempFolder, "./app.ts");
393
+ fs5.ensureFileSync(tempFilePath);
324
394
  const pagesScriptsGlob = config.publicDir + "/scripts/pages/**/*.{js,ts}";
325
395
  const clientFiles = globSync(
326
396
  config.publicDir + "/**/*.{js,ts}",
@@ -349,16 +419,14 @@ async function buildClientSideFiles(alpineDataFiles = [], isDev) {
349
419
  await logSize(config.distPublicDir, "client");
350
420
  }
351
421
  function writeDevServerClientSideCode(tempFilePath) {
352
- const devServerPath = path3.join(xpineDistDir, "./src/static/dev-server.js");
353
- const content = fs2.readFileSync(devServerPath, "utf-8");
354
- fs2.appendFileSync(tempFilePath, `
355
- ` + content);
422
+ const devServerPath = path5.join(xpineDistDir, "./src/static/dev-server.js");
423
+ const content = fs5.readFileSync(devServerPath, "utf-8");
424
+ fs5.appendFileSync(tempFilePath, "\n" + content);
356
425
  }
357
426
  function writeSpaClientSideCode(tempFilePath) {
358
- const spaPath = path3.join(xpineDistDir, "./src/static/spa.js");
359
- const content = fs2.readFileSync(spaPath, "utf-8");
360
- fs2.appendFileSync(tempFilePath, `
361
- ` + content);
427
+ const spaPath = path5.join(xpineDistDir, "./src/static/spa.js");
428
+ const content = fs5.readFileSync(spaPath, "utf-8");
429
+ fs5.appendFileSync(tempFilePath, "\n" + content);
362
430
  }
363
431
  async function buildAlpineDataFile(componentData, dataFiles) {
364
432
  const output = {
@@ -377,10 +445,10 @@ async function buildAlpineDataFile(componentData, dataFiles) {
377
445
  };
378
446
  const componentsAndDataFiles = componentData.concat(dataFiles);
379
447
  for (const component of componentsAndDataFiles) {
380
- const sourceFile = ts2.createSourceFile(
448
+ const sourceFile = ts3.createSourceFile(
381
449
  component.path,
382
450
  component.contents,
383
- ts2.ScriptTarget.Latest
451
+ ts3.ScriptTarget.Latest
384
452
  );
385
453
  const dataFunctionResult = findDataAttributesAndFunctions(sourceFile, sourceFile);
386
454
  dataFunctionResults.foundDataAttributes.push(...dataFunctionResult.foundDataAttributes);
@@ -402,18 +470,18 @@ async function buildAlpineDataFile(componentData, dataFiles) {
402
470
  output.code.push(`Alpine.data('${dataFunction.name}', ${dataFunction.name});`);
403
471
  }
404
472
  const result = output.imports.join("\n") + "\n" + output.code.join("\n") + "\n" + output.end.join("\n");
405
- fs2.ensureFileSync(config.alpineDataPath);
406
- fs2.writeFileSync(config.alpineDataPath, result);
473
+ fs5.ensureFileSync(config.alpineDataPath);
474
+ fs5.writeFileSync(config.alpineDataPath, result);
407
475
  return config.alpineDataPath;
408
476
  }
409
477
  async function buildCSS() {
410
478
  const cssFiles = globSync(config.srcDir + "/**/*.css");
411
479
  for (const file of cssFiles) {
412
- const fileContents = fs2.readFileSync(file, "utf-8");
480
+ const fileContents = fs5.readFileSync(file, "utf-8");
413
481
  const result = await postcss([tailwindPostcss(), remove_layers_default()]).process(fileContents, { from: file });
414
482
  const newPath = file.replace(config.srcDir, config.distDir);
415
- fs2.ensureFileSync(newPath);
416
- fs2.writeFileSync(newPath, result.css);
483
+ fs5.ensureFileSync(newPath);
484
+ fs5.writeFileSync(newPath, result.css);
417
485
  }
418
486
  logSize(config.distPublicDir, "css");
419
487
  }
@@ -427,8 +495,8 @@ async function buildPublicFolderSymlinks() {
427
495
  const splitNewPath = newPath.split("/");
428
496
  splitNewPath.pop();
429
497
  const newDir = splitNewPath.join("/");
430
- fs2.ensureDirSync(newDir);
431
- fs2.symlinkSync(file, newPath);
498
+ fs5.ensureDirSync(newDir);
499
+ fs5.symlinkSync(file, newPath);
432
500
  } catch {
433
501
  }
434
502
  }
@@ -439,7 +507,7 @@ async function logSize(pathName, type, validExtensions = [".js", ".css"]) {
439
507
  if (!validExtensions.find((ext) => file.endsWith(ext))) return false;
440
508
  return {
441
509
  file,
442
- size: fs2.statSync(file).size / (1024 * 1e3)
510
+ size: fs5.statSync(file).size / (1024 * 1e3)
443
511
  };
444
512
  }).filter(Boolean);
445
513
  const totalSize = fileSizes.reduce((total, current) => {
@@ -447,6 +515,83 @@ async function logSize(pathName, type, validExtensions = [".js", ".css"]) {
447
515
  }, 0);
448
516
  console.info(`[${totalSize.toFixed(3)} MB] Built ${type}`);
449
517
  }
518
+ async function buildFilesWithConfigs(componentData) {
519
+ const now = Date.now();
520
+ const componentsWithConfigs = componentData.filter((item) => item.configFiles);
521
+ for (const component of componentsWithConfigs) {
522
+ let config2 = await getCompleteConfig(component.configFiles, now);
523
+ const builtComponentPath = sourcePathToDistPath(component.path);
524
+ const componentImport = await import(builtComponentPath + `?cache=${Date.now()}`);
525
+ if (componentImport?.config) {
526
+ config2 = {
527
+ ...config2,
528
+ ...componentImport.config
529
+ };
530
+ }
531
+ if (config2?.staticPaths) buildStaticFiles(config2, component, componentImport, builtComponentPath);
532
+ }
533
+ }
534
+ async function buildStaticFiles(config2, component, componentImport, builtComponentPath) {
535
+ if (!config2?.staticPaths) return;
536
+ let componentFileName = component.path.split("/").pop().replace(regex_default.endsWithJSX, "").replace(regex_default.endsWithTSX, "");
537
+ const isDynamicRoute = component.path.match(regex_default.isDynamicRoute);
538
+ if (isDynamicRoute) {
539
+ componentFileName = component.path.split("/").filter((dir) => dir.match(regex_default.isDynamicRoute)).join("/").replace(regex_default.endsWithJSX, "").replace(regex_default.endsWithTSX, "");
540
+ }
541
+ const componentDynamicPaths = getComponentDynamicPaths(componentFileName);
542
+ const componentFn = componentImport.default;
543
+ const outputPath = componentDynamicPaths?.length ? componentDynamicPaths.reduce((total, current) => {
544
+ return total.replace(`/[${current}]`, "");
545
+ }, path5.dirname(builtComponentPath)) : path5.dirname(builtComponentPath);
546
+ if (typeof config2?.staticPaths === "boolean") {
547
+ try {
548
+ const req = { params: {} };
549
+ const data = config2?.data ? await config2.data(req) : null;
550
+ const staticComponentOutput = await componentFn({ data });
551
+ fs5.writeFileSync(
552
+ path5.join(outputPath, "./index.html"),
553
+ doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data }) : staticComponentOutput) + staticComment
554
+ );
555
+ } catch (err) {
556
+ console.error(err);
557
+ console.log("Could not build static component", component.path);
558
+ }
559
+ } else if (typeof config2?.staticPaths === "function") {
560
+ const dynamicPaths = await config2.staticPaths();
561
+ for (const dynamicPath of dynamicPaths) {
562
+ try {
563
+ const req = {
564
+ params: {
565
+ ...componentDynamicPaths?.length ? dynamicPath : {}
566
+ }
567
+ };
568
+ const data = config2?.data ? await config2.data(req) : null;
569
+ const staticComponentOutput = await componentFn({ req, data });
570
+ const updatedOutDir = path5.join(outputPath, `./${componentDynamicPaths.map((key) => dynamicPath[key]).join("/")}`);
571
+ fs5.ensureDirSync(updatedOutDir);
572
+ fs5.writeFileSync(
573
+ path5.join(updatedOutDir, "./index.html"),
574
+ doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data }) : staticComponentOutput) + staticComment
575
+ );
576
+ } catch (err) {
577
+ console.log("Could not build static component", component.path);
578
+ console.error(err);
579
+ }
580
+ }
581
+ }
582
+ }
583
+ function getComponentDynamicPaths(componentPath) {
584
+ const matches = [...componentPath.matchAll(regex_default.dynamicRoutes)];
585
+ if (!matches?.length) return null;
586
+ const output = [];
587
+ for (const match of matches) {
588
+ output.push(match[2]);
589
+ }
590
+ return output;
591
+ }
450
592
 
451
593
  // src/scripts/xpine-build.ts
452
- buildApp();
594
+ import yargs from "yargs";
595
+ import { hideBin } from "yargs/helpers";
596
+ var argv = yargs(hideBin(process.argv)).argv;
597
+ buildApp(argv?.isDev || false, argv?.removePreviousBuild || false);