@constela/start 1.2.3 → 1.2.5

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.
@@ -1492,7 +1492,7 @@ function normalizeDataSourcePatterns(projectRoot, pageDir, dataSources) {
1492
1492
  }
1493
1493
  return result;
1494
1494
  }
1495
- async function loadJsonPage(baseDir, pagePath) {
1495
+ async function loadJsonPage(baseDir, pagePath, options) {
1496
1496
  const filePath = join6(baseDir, pagePath);
1497
1497
  const resolvedBase = resolve3(baseDir);
1498
1498
  const resolvedPath = resolve3(filePath);
@@ -1523,7 +1523,8 @@ async function loadJsonPage(baseDir, pagePath) {
1523
1523
  validateVersion(page.version);
1524
1524
  const pageDir = dirname2(filePath);
1525
1525
  const resolvedImports = await resolveImports(pageDir, page.imports, baseDir);
1526
- const normalizedData = normalizeDataSourcePatterns(baseDir, pageDir, page.data);
1526
+ const patternBaseDir = options?.routesDir ?? pageDir;
1527
+ const normalizedData = normalizeDataSourcePatterns(baseDir, patternBaseDir, page.data);
1527
1528
  const loadedData = await loadPageData(baseDir, normalizedData, { imports: resolvedImports });
1528
1529
  const widgets = await loadWidgets(pageDir, page.widgets, baseDir);
1529
1530
  return {
@@ -1831,9 +1832,11 @@ async function convertToCompiledProgram(pageInfo) {
1831
1832
  }
1832
1833
  var JsonPageLoader = class {
1833
1834
  projectRoot;
1835
+ routesDir;
1834
1836
  cache = /* @__PURE__ */ new Map();
1835
- constructor(projectRoot) {
1837
+ constructor(projectRoot, options) {
1836
1838
  this.projectRoot = projectRoot;
1839
+ this.routesDir = options?.routesDir;
1837
1840
  }
1838
1841
  /**
1839
1842
  * Load a JSON page with full resolution
@@ -1842,7 +1845,9 @@ var JsonPageLoader = class {
1842
1845
  if (this.cache.has(pagePath)) {
1843
1846
  return this.cache.get(pagePath);
1844
1847
  }
1845
- const pageInfo = await loadJsonPage(this.projectRoot, pagePath);
1848
+ const pageInfo = await loadJsonPage(this.projectRoot, pagePath, {
1849
+ routesDir: this.routesDir
1850
+ });
1846
1851
  this.cache.set(pagePath, pageInfo);
1847
1852
  return pageInfo;
1848
1853
  }
@@ -2168,14 +2173,15 @@ h1 { color: #666; }
2168
2173
  }
2169
2174
 
2170
2175
  // src/build/index.ts
2171
- import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
2176
+ import { existsSync as existsSync8, readFileSync as readFileSync5 } from "fs";
2172
2177
  import { mkdir as mkdir2, writeFile, cp, readdir } from "fs/promises";
2173
- import { join as join9, dirname as dirname5, relative as relative2, basename as basename4, isAbsolute as isAbsolute2, resolve as resolve4 } from "path";
2178
+ import { join as join9, dirname as dirname5, relative as relative2, basename as basename4, isAbsolute as isAbsolute3, resolve as resolve4 } from "path";
2174
2179
 
2175
2180
  // src/build/bundler.ts
2176
2181
  import * as esbuild from "esbuild";
2182
+ import { existsSync as existsSync7 } from "fs";
2177
2183
  import { mkdir } from "fs/promises";
2178
- import { join as join8, dirname as dirname4 } from "path";
2184
+ import { join as join8, dirname as dirname4, isAbsolute as isAbsolute2 } from "path";
2179
2185
  import { fileURLToPath } from "url";
2180
2186
  var __dirname = dirname4(fileURLToPath(import.meta.url));
2181
2187
  async function bundleRuntime(options) {
@@ -2205,6 +2211,46 @@ async function bundleRuntime(options) {
2205
2211
  }
2206
2212
  return "/_constela/runtime.js";
2207
2213
  }
2214
+ async function bundleCSS(options) {
2215
+ const cssFiles = Array.isArray(options.css) ? options.css : [options.css];
2216
+ const outFile = join8(options.outDir, "_constela", "styles.css");
2217
+ await mkdir(dirname4(outFile), { recursive: true });
2218
+ const resolvedCssFiles = cssFiles.map((f) => isAbsolute2(f) ? f : join8(process.cwd(), f));
2219
+ for (const fullPath of resolvedCssFiles) {
2220
+ if (!existsSync7(fullPath)) {
2221
+ throw new Error(`CSS file not found: ${fullPath}`);
2222
+ }
2223
+ }
2224
+ try {
2225
+ if (resolvedCssFiles.length === 1) {
2226
+ await esbuild.build({
2227
+ entryPoints: resolvedCssFiles,
2228
+ bundle: true,
2229
+ outfile: outFile,
2230
+ minify: options.minify ?? true,
2231
+ loader: { ".css": "css" },
2232
+ conditions: ["style"]
2233
+ });
2234
+ } else {
2235
+ const virtualEntry = resolvedCssFiles.map((f) => `@import "${f}";`).join("\n");
2236
+ await esbuild.build({
2237
+ stdin: {
2238
+ contents: virtualEntry,
2239
+ loader: "css",
2240
+ resolveDir: process.cwd()
2241
+ },
2242
+ bundle: true,
2243
+ outfile: outFile,
2244
+ minify: options.minify ?? true,
2245
+ conditions: ["style"]
2246
+ });
2247
+ }
2248
+ } catch (error) {
2249
+ const message = error instanceof Error ? error.message : String(error);
2250
+ throw new Error(`Failed to bundle CSS to ${outFile}: ${message}`);
2251
+ }
2252
+ return "/_constela/styles.css";
2253
+ }
2208
2254
 
2209
2255
  // src/build/index.ts
2210
2256
  var DEFAULT_PUBLIC_DIR2 = "public";
@@ -2234,7 +2280,7 @@ async function loadGetStaticPaths(pageFile) {
2234
2280
  const dir = dirname5(pageFile);
2235
2281
  const baseName = basename4(pageFile, ".json");
2236
2282
  const pathsFile = join9(dir, `${baseName}.paths.ts`);
2237
- if (!existsSync7(pathsFile)) {
2283
+ if (!existsSync8(pathsFile)) {
2238
2284
  return null;
2239
2285
  }
2240
2286
  try {
@@ -2275,7 +2321,7 @@ async function loadGetStaticPaths(pageFile) {
2275
2321
  }
2276
2322
  async function loadLayout2(layoutName, layoutsDir) {
2277
2323
  const layoutPath = join9(layoutsDir, `${layoutName}.json`);
2278
- if (!existsSync7(layoutPath)) {
2324
+ if (!existsSync8(layoutPath)) {
2279
2325
  throw new Error(`Layout "${layoutName}" not found at ${layoutPath}`);
2280
2326
  }
2281
2327
  try {
@@ -2383,7 +2429,7 @@ async function processLayouts(pageInfo, layoutsDir) {
2383
2429
  }
2384
2430
  return updatedPageInfo;
2385
2431
  }
2386
- async function renderPageToHtml(program, params, runtimePath) {
2432
+ async function renderPageToHtml(program, params, runtimePath, cssPath) {
2387
2433
  const normalizedProgram = {
2388
2434
  ...program,
2389
2435
  view: normalizeViewNode(structuredClone(program.view))
@@ -2399,11 +2445,12 @@ async function renderPageToHtml(program, params, runtimePath) {
2399
2445
  query: {},
2400
2446
  path: "/"
2401
2447
  };
2448
+ const cssLinkTag = cssPath ? `<link rel="stylesheet" href="${cssPath}">` : void 0;
2402
2449
  const hydrationScript = generateHydrationScript(normalizedProgram, void 0, routeContext);
2403
- return wrapHtml(content, hydrationScript, void 0, runtimePath ? { runtimePath } : void 0);
2450
+ return wrapHtml(content, hydrationScript, cssLinkTag, runtimePath ? { runtimePath } : void 0);
2404
2451
  }
2405
2452
  async function copyPublicDir(publicDir, outDir, generatedFiles) {
2406
- if (!existsSync7(publicDir)) {
2453
+ if (!existsSync8(publicDir)) {
2407
2454
  return;
2408
2455
  }
2409
2456
  await copyDirRecursive(publicDir, outDir, generatedFiles);
@@ -2471,7 +2518,14 @@ async function build2(options) {
2471
2518
  };
2472
2519
  }
2473
2520
  const runtimePath = await bundleRuntime({ outDir });
2474
- const absoluteRoutesDir = isAbsolute2(routesDir) ? routesDir : resolve4(routesDir);
2521
+ let cssPath;
2522
+ if (options?.css) {
2523
+ cssPath = await bundleCSS({
2524
+ outDir,
2525
+ css: options.css
2526
+ });
2527
+ }
2528
+ const absoluteRoutesDir = isAbsolute3(routesDir) ? routesDir : resolve4(routesDir);
2475
2529
  const projectRoot = dirname5(dirname5(absoluteRoutesDir));
2476
2530
  for (const route of jsonPages) {
2477
2531
  const relPathFromRoutesDir = relative2(absoluteRoutesDir, route.file);
@@ -2479,23 +2533,31 @@ async function build2(options) {
2479
2533
  const content = readFileSync5(route.file, "utf-8");
2480
2534
  const page = validateJsonPage(content, route.file);
2481
2535
  if (isDynamicRoute(route.pattern)) {
2482
- const staticPaths = await loadGetStaticPaths(route.file);
2483
- if (!staticPaths) {
2536
+ const loader = new JsonPageLoader(projectRoot, { routesDir: absoluteRoutesDir });
2537
+ let pageInfo = await loader.loadPage(relPathFromProjectRoot);
2538
+ let staticPathsResult = null;
2539
+ if (pageInfo.page.getStaticPaths) {
2540
+ staticPathsResult = await generateStaticPathsFromPage(
2541
+ pageInfo.page,
2542
+ pageInfo.loadedData
2543
+ );
2544
+ } else {
2545
+ const externalPaths = await loadGetStaticPaths(route.file);
2546
+ if (externalPaths) {
2547
+ staticPathsResult = externalPaths.paths.map((p) => ({ params: p.params }));
2548
+ }
2549
+ }
2550
+ if (!staticPathsResult || staticPathsResult.length === 0) {
2484
2551
  continue;
2485
2552
  }
2486
- if (!staticPaths.paths || !Array.isArray(staticPaths.paths)) {
2487
- throw new Error(`Invalid getStaticPaths format in ${route.file}`);
2553
+ if (layoutsDir) {
2554
+ pageInfo = await processLayouts(pageInfo, layoutsDir);
2488
2555
  }
2489
- for (const pathEntry of staticPaths.paths) {
2556
+ for (const pathEntry of staticPathsResult) {
2490
2557
  const params = pathEntry.params;
2491
2558
  const outputPath = paramsToOutputPath(route.pattern, params, outDir);
2492
- const loader = new JsonPageLoader(projectRoot);
2493
- let pageInfo = await loader.loadPage(relPathFromProjectRoot);
2494
- if (layoutsDir) {
2495
- pageInfo = await processLayouts(pageInfo, layoutsDir);
2496
- }
2497
2559
  const program = await convertToCompiledProgram(pageInfo);
2498
- const html = await renderPageToHtml(program, params, runtimePath);
2560
+ const html = await renderPageToHtml(program, params, runtimePath, cssPath);
2499
2561
  await mkdir2(dirname5(outputPath), { recursive: true });
2500
2562
  await writeFile(outputPath, html, "utf-8");
2501
2563
  generatedFiles.push(outputPath);
@@ -2508,13 +2570,13 @@ async function build2(options) {
2508
2570
  }
2509
2571
  } else {
2510
2572
  const outputPath = getOutputPath(relPathFromRoutesDir, outDir);
2511
- const loader = new JsonPageLoader(projectRoot);
2573
+ const loader = new JsonPageLoader(projectRoot, { routesDir: absoluteRoutesDir });
2512
2574
  let pageInfo = await loader.loadPage(relPathFromProjectRoot);
2513
2575
  if (layoutsDir) {
2514
2576
  pageInfo = await processLayouts(pageInfo, layoutsDir);
2515
2577
  }
2516
2578
  const program = await convertToCompiledProgram(pageInfo);
2517
- const html = await renderPageToHtml(program, {}, runtimePath);
2579
+ const html = await renderPageToHtml(program, {}, runtimePath, cssPath);
2518
2580
  await mkdir2(dirname5(outputPath), { recursive: true });
2519
2581
  await writeFile(outputPath, html, "utf-8");
2520
2582
  generatedFiles.push(outputPath);
@@ -2532,12 +2594,12 @@ async function build2(options) {
2532
2594
  }
2533
2595
 
2534
2596
  // src/config/config-loader.ts
2535
- import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
2597
+ import { existsSync as existsSync9, readFileSync as readFileSync6 } from "fs";
2536
2598
  import { join as join10 } from "path";
2537
2599
  var CONFIG_FILENAME = "constela.config.json";
2538
2600
  async function loadConfig(projectRoot) {
2539
2601
  const configPath = join10(projectRoot, CONFIG_FILENAME);
2540
- if (!existsSync8(configPath)) {
2602
+ if (!existsSync9(configPath)) {
2541
2603
  return {};
2542
2604
  }
2543
2605
  let content;
package/dist/cli/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  createDevServer,
4
4
  loadConfig,
5
5
  resolveConfig
6
- } from "../chunk-U6CTMEFX.js";
6
+ } from "../chunk-C4DIT5X5.js";
7
7
  import "../chunk-PUTC5BCP.js";
8
8
 
9
9
  // src/cli/index.ts
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  transformCsv,
24
24
  transformMdx,
25
25
  transformYaml
26
- } from "./chunk-U6CTMEFX.js";
26
+ } from "./chunk-C4DIT5X5.js";
27
27
  import {
28
28
  generateHydrationScript,
29
29
  renderPage,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constela/start",
3
- "version": "1.2.3",
3
+ "version": "1.2.5",
4
4
  "description": "Meta-framework for Constela applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -41,10 +41,10 @@
41
41
  "unified": "^11.0.0",
42
42
  "vite": "^6.0.0",
43
43
  "@constela/compiler": "0.7.0",
44
- "@constela/core": "0.7.0",
45
- "@constela/server": "3.0.0",
46
44
  "@constela/router": "8.0.0",
47
- "@constela/runtime": "0.10.1"
45
+ "@constela/core": "0.7.0",
46
+ "@constela/runtime": "0.10.1",
47
+ "@constela/server": "3.0.0"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/mdast": "^4.0.4",