@constela/start 1.2.7 → 1.2.9
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/dist/{chunk-RA772QBZ.js → chunk-APCF5VWN.js} +158 -24
- package/dist/cli/index.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -1
- package/package.json +5 -2
|
@@ -1523,7 +1523,7 @@ async function loadJsonPage(baseDir, pagePath, options) {
|
|
|
1523
1523
|
validateVersion(page.version);
|
|
1524
1524
|
const pageDir = dirname2(filePath);
|
|
1525
1525
|
const resolvedImports = await resolveImports(pageDir, page.imports, baseDir);
|
|
1526
|
-
const patternBaseDir =
|
|
1526
|
+
const patternBaseDir = pageDir;
|
|
1527
1527
|
const normalizedData = normalizeDataSourcePatterns(baseDir, patternBaseDir, page.data);
|
|
1528
1528
|
const loadedData = await loadPageData(baseDir, normalizedData, { imports: resolvedImports });
|
|
1529
1529
|
const widgets = await loadWidgets(pageDir, page.widgets, baseDir);
|
|
@@ -2211,13 +2211,13 @@ h1 { color: #666; }
|
|
|
2211
2211
|
// src/build/index.ts
|
|
2212
2212
|
import { existsSync as existsSync8, readFileSync as readFileSync5 } from "fs";
|
|
2213
2213
|
import { mkdir as mkdir2, writeFile, cp, readdir } from "fs/promises";
|
|
2214
|
-
import { join as join9, dirname as dirname5, relative as
|
|
2214
|
+
import { join as join9, dirname as dirname5, relative as relative3, basename as basename4, isAbsolute as isAbsolute3, resolve as resolve4 } from "path";
|
|
2215
2215
|
|
|
2216
2216
|
// src/build/bundler.ts
|
|
2217
2217
|
import * as esbuild from "esbuild";
|
|
2218
2218
|
import { existsSync as existsSync7 } from "fs";
|
|
2219
|
-
import { mkdir } from "fs/promises";
|
|
2220
|
-
import { join as join8, dirname as dirname4, isAbsolute as isAbsolute2 } from "path";
|
|
2219
|
+
import { mkdir, readFile } from "fs/promises";
|
|
2220
|
+
import { join as join8, dirname as dirname4, isAbsolute as isAbsolute2, relative as relative2 } from "path";
|
|
2221
2221
|
import { fileURLToPath } from "url";
|
|
2222
2222
|
var __dirname = dirname4(fileURLToPath(import.meta.url));
|
|
2223
2223
|
async function bundleRuntime(options) {
|
|
@@ -2257,33 +2257,92 @@ async function bundleCSS(options) {
|
|
|
2257
2257
|
throw new Error(`CSS file not found: ${fullPath}`);
|
|
2258
2258
|
}
|
|
2259
2259
|
}
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2260
|
+
if (options.content !== void 0) {
|
|
2261
|
+
try {
|
|
2262
|
+
const firstCssFile = resolvedCssFiles[0];
|
|
2263
|
+
if (!firstCssFile) {
|
|
2264
|
+
throw new Error("No CSS files provided");
|
|
2265
|
+
}
|
|
2266
|
+
let cssContent;
|
|
2267
|
+
if (resolvedCssFiles.length === 1) {
|
|
2268
|
+
cssContent = await readFile(firstCssFile, "utf-8");
|
|
2269
|
+
} else {
|
|
2270
|
+
cssContent = resolvedCssFiles.map((f) => `@import "${f}";`).join("\n");
|
|
2271
|
+
}
|
|
2272
|
+
if (options.content.length > 0) {
|
|
2273
|
+
const fg4 = (await import("fast-glob")).default;
|
|
2274
|
+
const resolvedContentPaths = options.content.map(
|
|
2275
|
+
(p) => isAbsolute2(p) ? p : join8(process.cwd(), p)
|
|
2276
|
+
);
|
|
2277
|
+
const matchedFiles = await fg4(resolvedContentPaths, { onlyFiles: true });
|
|
2278
|
+
if (matchedFiles.length === 0) {
|
|
2279
|
+
throw new Error(
|
|
2280
|
+
`No content files matched the provided patterns: ${options.content.join(", ")}`
|
|
2281
|
+
);
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
const sourceDir = dirname4(firstCssFile);
|
|
2285
|
+
const sourceDirectives = options.content.map((contentPath) => {
|
|
2286
|
+
const absolutePath = isAbsolute2(contentPath) ? contentPath : join8(process.cwd(), contentPath);
|
|
2287
|
+
const relativePath = relative2(sourceDir, absolutePath);
|
|
2288
|
+
return `@source "${relativePath}";`;
|
|
2289
|
+
}).join("\n");
|
|
2290
|
+
const processedCssInput = sourceDirectives + "\n" + cssContent;
|
|
2291
|
+
const postcss = (await import("postcss")).default;
|
|
2292
|
+
const tailwindPostcss = (await import("@tailwindcss/postcss")).default;
|
|
2293
|
+
const result = await postcss([
|
|
2294
|
+
tailwindPostcss({
|
|
2295
|
+
base: sourceDir,
|
|
2296
|
+
optimize: options.minify ?? true
|
|
2297
|
+
})
|
|
2298
|
+
]).process(processedCssInput, {
|
|
2299
|
+
// Use __dirname for package resolution (tailwindcss is a peer dependency of this package)
|
|
2300
|
+
from: join8(__dirname, "styles.css")
|
|
2269
2301
|
});
|
|
2270
|
-
} else {
|
|
2271
|
-
const virtualEntry = resolvedCssFiles.map((f) => `@import "${f}";`).join("\n");
|
|
2272
2302
|
await esbuild.build({
|
|
2273
2303
|
stdin: {
|
|
2274
|
-
contents:
|
|
2304
|
+
contents: result.css,
|
|
2275
2305
|
loader: "css",
|
|
2276
|
-
resolveDir:
|
|
2306
|
+
resolveDir: sourceDir
|
|
2277
2307
|
},
|
|
2278
2308
|
bundle: true,
|
|
2279
2309
|
outfile: outFile,
|
|
2280
2310
|
minify: options.minify ?? true,
|
|
2281
2311
|
conditions: ["style"]
|
|
2282
2312
|
});
|
|
2313
|
+
} catch (error) {
|
|
2314
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2315
|
+
throw new Error(`Failed to process CSS with PostCSS/Tailwind: ${message}`);
|
|
2316
|
+
}
|
|
2317
|
+
} else {
|
|
2318
|
+
try {
|
|
2319
|
+
if (resolvedCssFiles.length === 1) {
|
|
2320
|
+
await esbuild.build({
|
|
2321
|
+
entryPoints: resolvedCssFiles,
|
|
2322
|
+
bundle: true,
|
|
2323
|
+
outfile: outFile,
|
|
2324
|
+
minify: options.minify ?? true,
|
|
2325
|
+
loader: { ".css": "css" },
|
|
2326
|
+
conditions: ["style"]
|
|
2327
|
+
});
|
|
2328
|
+
} else {
|
|
2329
|
+
const virtualEntry = resolvedCssFiles.map((f) => `@import "${f}";`).join("\n");
|
|
2330
|
+
await esbuild.build({
|
|
2331
|
+
stdin: {
|
|
2332
|
+
contents: virtualEntry,
|
|
2333
|
+
loader: "css",
|
|
2334
|
+
resolveDir: process.cwd()
|
|
2335
|
+
},
|
|
2336
|
+
bundle: true,
|
|
2337
|
+
outfile: outFile,
|
|
2338
|
+
minify: options.minify ?? true,
|
|
2339
|
+
conditions: ["style"]
|
|
2340
|
+
});
|
|
2341
|
+
}
|
|
2342
|
+
} catch (error) {
|
|
2343
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2344
|
+
throw new Error(`Failed to bundle CSS to ${outFile}: ${message}`);
|
|
2283
2345
|
}
|
|
2284
|
-
} catch (error) {
|
|
2285
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2286
|
-
throw new Error(`Failed to bundle CSS to ${outFile}: ${message}`);
|
|
2287
2346
|
}
|
|
2288
2347
|
return "/_constela/styles.css";
|
|
2289
2348
|
}
|
|
@@ -2414,6 +2473,76 @@ function normalizeViewNode(node) {
|
|
|
2414
2473
|
}
|
|
2415
2474
|
return nodeObj;
|
|
2416
2475
|
}
|
|
2476
|
+
function substituteLayoutParamsInExpr(expr, layoutParams) {
|
|
2477
|
+
if (!expr || typeof expr !== "object") {
|
|
2478
|
+
return expr;
|
|
2479
|
+
}
|
|
2480
|
+
const exprObj = expr;
|
|
2481
|
+
if (exprObj["expr"] === "param" && typeof exprObj["name"] === "string") {
|
|
2482
|
+
const paramName = exprObj["name"];
|
|
2483
|
+
const paramValue = layoutParams[paramName];
|
|
2484
|
+
if (paramValue !== void 0) {
|
|
2485
|
+
if (typeof exprObj["path"] === "string") {
|
|
2486
|
+
return {
|
|
2487
|
+
expr: "get",
|
|
2488
|
+
base: paramValue,
|
|
2489
|
+
path: exprObj["path"]
|
|
2490
|
+
};
|
|
2491
|
+
}
|
|
2492
|
+
return paramValue;
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
const result = {};
|
|
2496
|
+
for (const [key, value] of Object.entries(exprObj)) {
|
|
2497
|
+
if (key === "expr") {
|
|
2498
|
+
result[key] = value;
|
|
2499
|
+
} else if (value && typeof value === "object") {
|
|
2500
|
+
if (Array.isArray(value)) {
|
|
2501
|
+
result[key] = value.map((item) => substituteLayoutParamsInExpr(item, layoutParams));
|
|
2502
|
+
} else {
|
|
2503
|
+
result[key] = substituteLayoutParamsInExpr(value, layoutParams);
|
|
2504
|
+
}
|
|
2505
|
+
} else {
|
|
2506
|
+
result[key] = value;
|
|
2507
|
+
}
|
|
2508
|
+
}
|
|
2509
|
+
return result;
|
|
2510
|
+
}
|
|
2511
|
+
function substituteLayoutParamsInNode(node, layoutParams) {
|
|
2512
|
+
if (!node || typeof node !== "object") {
|
|
2513
|
+
return node;
|
|
2514
|
+
}
|
|
2515
|
+
const nodeObj = node;
|
|
2516
|
+
const result = {};
|
|
2517
|
+
for (const [key, value] of Object.entries(nodeObj)) {
|
|
2518
|
+
if (key === "children" && Array.isArray(value)) {
|
|
2519
|
+
result[key] = value.map((child) => substituteLayoutParamsInNode(child, layoutParams));
|
|
2520
|
+
} else if (key === "props" && value && typeof value === "object") {
|
|
2521
|
+
const props = {};
|
|
2522
|
+
for (const [propKey, propValue] of Object.entries(value)) {
|
|
2523
|
+
props[propKey] = substituteLayoutParamsInExpr(propValue, layoutParams);
|
|
2524
|
+
}
|
|
2525
|
+
result[key] = props;
|
|
2526
|
+
} else if (key === "value" && value && typeof value === "object") {
|
|
2527
|
+
result[key] = substituteLayoutParamsInExpr(value, layoutParams);
|
|
2528
|
+
} else if (key === "items" && value && typeof value === "object") {
|
|
2529
|
+
result[key] = substituteLayoutParamsInExpr(value, layoutParams);
|
|
2530
|
+
} else if (key === "condition" && value && typeof value === "object") {
|
|
2531
|
+
result[key] = substituteLayoutParamsInExpr(value, layoutParams);
|
|
2532
|
+
} else if (key === "content" && value && typeof value === "object") {
|
|
2533
|
+
result[key] = substituteLayoutParamsInExpr(value, layoutParams);
|
|
2534
|
+
} else if (key === "then" && value && typeof value === "object") {
|
|
2535
|
+
result[key] = substituteLayoutParamsInNode(value, layoutParams);
|
|
2536
|
+
} else if (key === "else" && value && typeof value === "object") {
|
|
2537
|
+
result[key] = substituteLayoutParamsInNode(value, layoutParams);
|
|
2538
|
+
} else if (key === "body" && value && typeof value === "object") {
|
|
2539
|
+
result[key] = substituteLayoutParamsInNode(value, layoutParams);
|
|
2540
|
+
} else {
|
|
2541
|
+
result[key] = value;
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
return result;
|
|
2545
|
+
}
|
|
2417
2546
|
function replaceSlot(node, content) {
|
|
2418
2547
|
if (!node || typeof node !== "object") {
|
|
2419
2548
|
return node;
|
|
@@ -2437,7 +2566,11 @@ async function processLayouts(pageInfo, layoutsDir) {
|
|
|
2437
2566
|
}
|
|
2438
2567
|
const layout = await loadLayout2(layoutName, layoutsDir);
|
|
2439
2568
|
const normalizedLayoutView = normalizeViewNode(structuredClone(layout.view));
|
|
2440
|
-
|
|
2569
|
+
let wrappedView = applyLayout(pageInfo.page.view, normalizedLayoutView);
|
|
2570
|
+
const layoutParams = pageInfo.page.route?.layoutParams;
|
|
2571
|
+
if (layoutParams && Object.keys(layoutParams).length > 0) {
|
|
2572
|
+
wrappedView = substituteLayoutParamsInNode(wrappedView, layoutParams);
|
|
2573
|
+
}
|
|
2441
2574
|
let updatedRoute;
|
|
2442
2575
|
if (pageInfo.page.route) {
|
|
2443
2576
|
const { layout: _layout, ...routeWithoutLayout } = pageInfo.page.route;
|
|
@@ -2558,14 +2691,15 @@ async function build2(options) {
|
|
|
2558
2691
|
if (options?.css) {
|
|
2559
2692
|
cssPath = await bundleCSS({
|
|
2560
2693
|
outDir,
|
|
2561
|
-
css: options.css
|
|
2694
|
+
css: options.css,
|
|
2695
|
+
...options.cssContent ? { content: options.cssContent } : {}
|
|
2562
2696
|
});
|
|
2563
2697
|
}
|
|
2564
2698
|
const absoluteRoutesDir = isAbsolute3(routesDir) ? routesDir : resolve4(routesDir);
|
|
2565
2699
|
const projectRoot = dirname5(dirname5(absoluteRoutesDir));
|
|
2566
2700
|
for (const route of jsonPages) {
|
|
2567
|
-
const relPathFromRoutesDir =
|
|
2568
|
-
const relPathFromProjectRoot =
|
|
2701
|
+
const relPathFromRoutesDir = relative3(absoluteRoutesDir, route.file);
|
|
2702
|
+
const relPathFromProjectRoot = relative3(projectRoot, route.file);
|
|
2569
2703
|
const content = readFileSync5(route.file, "utf-8");
|
|
2570
2704
|
const page = validateJsonPage(content, route.file);
|
|
2571
2705
|
if (isDynamicRoute(route.pattern)) {
|
package/dist/cli/index.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -101,8 +101,10 @@ interface BuildOptions {
|
|
|
101
101
|
routesDir?: string | undefined;
|
|
102
102
|
publicDir?: string | undefined;
|
|
103
103
|
layoutsDir?: string | undefined;
|
|
104
|
-
/** CSS entry point(s) for
|
|
104
|
+
/** CSS entry point(s) for bundling */
|
|
105
105
|
css?: string | string[] | undefined;
|
|
106
|
+
/** Content paths for Tailwind CSS class scanning (enables PostCSS processing) */
|
|
107
|
+
cssContent?: string[] | undefined;
|
|
106
108
|
target?: 'node' | 'edge' | undefined;
|
|
107
109
|
}
|
|
108
110
|
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constela/start",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.9",
|
|
4
4
|
"description": "Meta-framework for Constela applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -40,9 +40,12 @@
|
|
|
40
40
|
"remark-parse": "^11.0.0",
|
|
41
41
|
"unified": "^11.0.0",
|
|
42
42
|
"vite": "^6.0.0",
|
|
43
|
+
"postcss": "^8.5.0",
|
|
44
|
+
"@tailwindcss/postcss": "^4.0.0",
|
|
45
|
+
"tailwindcss": "^4.0.0",
|
|
43
46
|
"@constela/compiler": "0.7.0",
|
|
44
|
-
"@constela/core": "0.7.0",
|
|
45
47
|
"@constela/server": "3.0.1",
|
|
48
|
+
"@constela/core": "0.7.0",
|
|
46
49
|
"@constela/runtime": "0.10.1",
|
|
47
50
|
"@constela/router": "8.0.0"
|
|
48
51
|
},
|