veryfront 0.1.173 → 0.1.175
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/esm/deno.js +1 -1
- package/esm/src/platform/adapters/fs/veryfront/stat-operations.d.ts +1 -0
- package/esm/src/platform/adapters/fs/veryfront/stat-operations.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/stat-operations.js +48 -41
- package/esm/src/rendering/orchestrator/html-imported-css.d.ts +17 -0
- package/esm/src/rendering/orchestrator/html-imported-css.d.ts.map +1 -0
- package/esm/src/rendering/orchestrator/html-imported-css.js +49 -0
- package/esm/src/rendering/orchestrator/html.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/html.js +8 -48
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
- package/src/deno.js +1 -1
- package/src/src/platform/adapters/fs/veryfront/stat-operations.ts +70 -49
- package/src/src/rendering/orchestrator/html-imported-css.ts +81 -0
- package/src/src/rendering/orchestrator/html.ts +8 -55
- package/src/src/utils/version-constant.ts +1 -1
package/esm/deno.js
CHANGED
|
@@ -18,6 +18,7 @@ export declare class StatOperations extends VeryfrontOperationsBase {
|
|
|
18
18
|
private normalizeMatchedPaths;
|
|
19
19
|
private tryResolveViaApiSearch;
|
|
20
20
|
private hasCachedFileList;
|
|
21
|
+
private resolveFromIndex;
|
|
21
22
|
exists(path: string): Promise<boolean>;
|
|
22
23
|
resolveFile(basePath: string, options?: ResolveFileOptions): Promise<string | null>;
|
|
23
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stat-operations.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/stat-operations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAElE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAuB/D,qBAAa,cAAe,SAAQ,uBAAuB;IACzD,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,aAAa,CAA8B;IAEnD,OAAO,CAAC,sBAAsB,CAA6B;IAC3D,OAAO,CAAC,qBAAqB,CAA8B;IAE3D,OAAO,CAAC,WAAW,CAAkC;IAErD,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAGrC;IAEH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;YAiHvB,gBAAgB;YAwChB,UAAU;IAkDxB,UAAU,IAAI,IAAI;IAMlB,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM;YAIpC,cAAc;IAU5B,OAAO,CAAC,0BAA0B;IAgClC,OAAO,CAAC,qBAAqB;YAQf,sBAAsB;YA8EtB,iBAAiB;
|
|
1
|
+
{"version":3,"file":"stat-operations.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/stat-operations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAElE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAuB/D,qBAAa,cAAe,SAAQ,uBAAuB;IACzD,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,aAAa,CAA8B;IAEnD,OAAO,CAAC,sBAAsB,CAA6B;IAC3D,OAAO,CAAC,qBAAqB,CAA8B;IAE3D,OAAO,CAAC,WAAW,CAAkC;IAErD,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAGrC;IAEH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;YAiHvB,gBAAgB;YAwChB,UAAU;IAkDxB,UAAU,IAAI,IAAI;IAMlB,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM;YAIpC,cAAc;IAU5B,OAAO,CAAC,0BAA0B;IAgClC,OAAO,CAAC,qBAAqB;YAQf,sBAAsB;YA8EtB,iBAAiB;IAS/B,OAAO,CAAC,gBAAgB;IA6DlB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWtC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CA0F1F"}
|
|
@@ -310,6 +310,51 @@ export class StatOperations extends VeryfrontOperationsBase {
|
|
|
310
310
|
const files = await this.contextProvider?.getFileList?.();
|
|
311
311
|
return Array.isArray(files) && files.length > 0;
|
|
312
312
|
}
|
|
313
|
+
resolveFromIndex(fileIdx, normalizedPath, options, indexMs, resolveStart) {
|
|
314
|
+
if (fileIdx.has(normalizedPath)) {
|
|
315
|
+
const totalMs = Math.round(performance.now() - resolveStart);
|
|
316
|
+
logger.debug("resolveFile exact match found", {
|
|
317
|
+
normalizedPath,
|
|
318
|
+
indexMs,
|
|
319
|
+
totalMs,
|
|
320
|
+
});
|
|
321
|
+
return normalizedPath;
|
|
322
|
+
}
|
|
323
|
+
const pathWithoutExt = stripKnownExtension(normalizedPath, EXTENSION_PRIORITY);
|
|
324
|
+
const resolvedDirect = resolveByExtensionPriority(fileIdx, pathWithoutExt, EXTENSION_PRIORITY);
|
|
325
|
+
if (resolvedDirect) {
|
|
326
|
+
const totalMs = Math.round(performance.now() - resolveStart);
|
|
327
|
+
logger.debug("resolveFile found with extension", {
|
|
328
|
+
pathWithExt: resolvedDirect,
|
|
329
|
+
indexMs,
|
|
330
|
+
totalMs,
|
|
331
|
+
});
|
|
332
|
+
return resolvedDirect;
|
|
333
|
+
}
|
|
334
|
+
if (options?.allowPagesPrefix !== false && !pathWithoutExt.startsWith("pages/")) {
|
|
335
|
+
const resolvedPages = resolveByExtensionPriority(fileIdx, `pages/${pathWithoutExt}`, EXTENSION_PRIORITY);
|
|
336
|
+
if (resolvedPages) {
|
|
337
|
+
const totalMs = Math.round(performance.now() - resolveStart);
|
|
338
|
+
logger.debug("resolveFile found with pages prefix", {
|
|
339
|
+
pathWithExt: resolvedPages,
|
|
340
|
+
indexMs,
|
|
341
|
+
totalMs,
|
|
342
|
+
});
|
|
343
|
+
return resolvedPages;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
const indexPath = resolveIndexByExtensionPriority(fileIdx, pathWithoutExt, EXTENSION_PRIORITY);
|
|
347
|
+
if (indexPath) {
|
|
348
|
+
const totalMs = Math.round(performance.now() - resolveStart);
|
|
349
|
+
logger.debug("resolveFile found index file", {
|
|
350
|
+
indexPath,
|
|
351
|
+
indexMs,
|
|
352
|
+
totalMs,
|
|
353
|
+
});
|
|
354
|
+
return indexPath;
|
|
355
|
+
}
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
313
358
|
async exists(path) {
|
|
314
359
|
const normalizedPath = this.normalizer.normalize(path);
|
|
315
360
|
try {
|
|
@@ -364,47 +409,9 @@ export class StatOperations extends VeryfrontOperationsBase {
|
|
|
364
409
|
logger.debug("resolveFile - no file index", { indexMs });
|
|
365
410
|
return null;
|
|
366
411
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
normalizedPath,
|
|
371
|
-
indexMs,
|
|
372
|
-
totalMs,
|
|
373
|
-
});
|
|
374
|
-
return normalizedPath;
|
|
375
|
-
}
|
|
376
|
-
const pathWithoutExt = stripKnownExtension(normalizedPath, EXTENSION_PRIORITY);
|
|
377
|
-
const resolvedDirect = resolveByExtensionPriority(fileIdx, pathWithoutExt, EXTENSION_PRIORITY);
|
|
378
|
-
if (resolvedDirect) {
|
|
379
|
-
const totalMs = Math.round(performance.now() - resolveStart);
|
|
380
|
-
logger.debug("resolveFile found with extension", {
|
|
381
|
-
pathWithExt: resolvedDirect,
|
|
382
|
-
indexMs,
|
|
383
|
-
totalMs,
|
|
384
|
-
});
|
|
385
|
-
return resolvedDirect;
|
|
386
|
-
}
|
|
387
|
-
if (options?.allowPagesPrefix !== false && !pathWithoutExt.startsWith("pages/")) {
|
|
388
|
-
const resolvedPages = resolveByExtensionPriority(fileIdx, `pages/${pathWithoutExt}`, EXTENSION_PRIORITY);
|
|
389
|
-
if (resolvedPages) {
|
|
390
|
-
const totalMs = Math.round(performance.now() - resolveStart);
|
|
391
|
-
logger.debug("resolveFile found with pages prefix", {
|
|
392
|
-
pathWithExt: resolvedPages,
|
|
393
|
-
indexMs,
|
|
394
|
-
totalMs,
|
|
395
|
-
});
|
|
396
|
-
return resolvedPages;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
const indexPath = resolveIndexByExtensionPriority(fileIdx, pathWithoutExt, EXTENSION_PRIORITY);
|
|
400
|
-
if (indexPath) {
|
|
401
|
-
const totalMs = Math.round(performance.now() - resolveStart);
|
|
402
|
-
logger.debug("resolveFile found index file", {
|
|
403
|
-
indexPath,
|
|
404
|
-
indexMs,
|
|
405
|
-
totalMs,
|
|
406
|
-
});
|
|
407
|
-
return indexPath;
|
|
412
|
+
const indexedResolution = this.resolveFromIndex(fileIdx, normalizedPath, options, indexMs, resolveStart);
|
|
413
|
+
if (indexedResolution) {
|
|
414
|
+
return indexedResolution;
|
|
408
415
|
}
|
|
409
416
|
if (attemptedApiResolve) {
|
|
410
417
|
logger.debug("resolveFile not found after pre-index API search", {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
interface CssFsAdapterLike {
|
|
2
|
+
readFile(path: string): Promise<string>;
|
|
3
|
+
}
|
|
4
|
+
interface CssLoggerLike {
|
|
5
|
+
debug(message: string, context?: Record<string, unknown>): void;
|
|
6
|
+
}
|
|
7
|
+
interface MergeImportedCssOptions {
|
|
8
|
+
fs: CssFsAdapterLike;
|
|
9
|
+
logger: CssLoggerLike;
|
|
10
|
+
projectDir: string;
|
|
11
|
+
globalCSS: string | undefined;
|
|
12
|
+
cssImports: string[] | undefined;
|
|
13
|
+
stylesheetPath: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function mergeImportedCSS({ fs, logger, projectDir, globalCSS, cssImports, stylesheetPath, }: MergeImportedCssOptions): Promise<string | undefined>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=html-imported-css.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-imported-css.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/orchestrator/html-imported-css.ts"],"names":[],"mappings":"AAMA,UAAU,gBAAgB;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACzC;AAED,UAAU,aAAa;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACjE;AAED,UAAU,uBAAuB;IAC/B,EAAE,EAAE,gBAAgB,CAAC;IACrB,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,UAAU,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACjC,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAsB,gBAAgB,CAAC,EACrC,EAAE,EACF,MAAM,EACN,UAAU,EACV,SAAS,EACT,UAAU,EACV,cAAc,GACf,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAkDvD"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { join } from "../../platform/compat/path/index.js";
|
|
2
|
+
import { normalizeCssModuleKey, rewriteCssModuleContent, } from "../../transforms/css-modules/naming.js";
|
|
3
|
+
export async function mergeImportedCSS({ fs, logger, projectDir, globalCSS, cssImports, stylesheetPath, }) {
|
|
4
|
+
if (!cssImports || cssImports.length === 0)
|
|
5
|
+
return globalCSS;
|
|
6
|
+
const normalizedStylesheetPath = stylesheetPath.replace(/^\/+/, "");
|
|
7
|
+
const configuredStylesheetAbsolute = normalizeCssModuleKey(join(projectDir, normalizedStylesheetPath));
|
|
8
|
+
const uniqueImports = new Map();
|
|
9
|
+
for (const cssPath of cssImports) {
|
|
10
|
+
const normalized = normalizeCssModuleKey(cssPath);
|
|
11
|
+
if (!uniqueImports.has(normalized)) {
|
|
12
|
+
uniqueImports.set(normalized, cssPath);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const sortedImports = [...uniqueImports.entries()].sort((a, b) => a[0].localeCompare(b[0]));
|
|
16
|
+
const regularCssSegments = [];
|
|
17
|
+
const moduleCssSegments = [];
|
|
18
|
+
for (const [normalizedCssPath, cssPath] of sortedImports) {
|
|
19
|
+
if (normalizedCssPath === configuredStylesheetAbsolute) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const content = await fs.readFile(cssPath);
|
|
24
|
+
if (!content)
|
|
25
|
+
continue;
|
|
26
|
+
if (normalizedCssPath.endsWith(".module.css")) {
|
|
27
|
+
moduleCssSegments.push(rewriteCssModuleContent(content, normalizedCssPath));
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
regularCssSegments.push(content);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (_) {
|
|
34
|
+
logger.debug("Could not load imported CSS file", { cssPath });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (regularCssSegments.length === 0 && moduleCssSegments.length === 0)
|
|
38
|
+
return globalCSS;
|
|
39
|
+
const combined = [globalCSS, ...regularCssSegments, ...moduleCssSegments]
|
|
40
|
+
.filter(Boolean)
|
|
41
|
+
.join("\n");
|
|
42
|
+
logger.debug("Merged imported CSS with global stylesheet", {
|
|
43
|
+
importedCount: regularCssSegments.length + moduleCssSegments.length,
|
|
44
|
+
regularCount: regularCssSegments.length,
|
|
45
|
+
moduleCount: moduleCssSegments.length,
|
|
46
|
+
totalLength: combined.length,
|
|
47
|
+
});
|
|
48
|
+
return combined;
|
|
49
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/orchestrator/html.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAS7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,SAAS,EAET,UAAU,EACX,MAAM,sBAAsB,CAAC;AAG9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/orchestrator/html.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAS7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,SAAS,EAET,UAAU,EACX,MAAM,sBAAsB,CAAC;AAG9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA6EhD,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,eAAe,CAAC;IACxB,IAAI,EAAE,aAAa,GAAG,YAAY,CAAC;CACpC;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,UAAU,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,YAAY,EAAE,SAAS,GAAG,SAAS,CAAC;IACpC,aAAa,EAAE,UAAU,EAAE,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,2FAA2F;IAC3F,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAsB;gBAExB,MAAM,EAAE,mBAAmB;IAIjC,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC;IA0BjE,kBAAkB,CACtB,WAAW,EAAE,cAAc,EAC3B,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,GAC3C,OAAO,CAAC,cAAc,CAAC;YAqEZ,sBAAsB;YAqDtB,4BAA4B;YAiB5B,wBAAwB;YAmBxB,gBAAgB;YAyBhB,kBAAkB;IAwDhC,OAAO,CAAC,cAAc;YAQR,eAAe;YAaf,gBAAgB;IAgF9B;;;;OAIG;YACW,gBAAgB;CAc/B"}
|
|
@@ -9,9 +9,9 @@ import { extractRelativePath } from "../../utils/route-path-utils.js";
|
|
|
9
9
|
import { resolveAppComponentPath } from "../layouts/utils/app-resolver.js";
|
|
10
10
|
import { StreamTimeoutError, streamToString } from "../utils/stream-utils.js";
|
|
11
11
|
import { profilePhase, profileSyncPhase } from "../../observability/request-profiler.js";
|
|
12
|
-
import { normalizeCssModuleKey, rewriteCssModuleContent, } from "../../transforms/css-modules/naming.js";
|
|
13
12
|
import { extractProjectClassesForRoute, startPreparedCSSWarmup, startProjectCSSPreparation, } from "./html-project-css.js";
|
|
14
13
|
import { buildHeadElements as buildCollectedHeadElements, mergeFrontmatter as mergeCollectedFrontmatter, } from "./html-head.js";
|
|
14
|
+
import { mergeImportedCSS as mergeImportedProjectCss } from "./html-imported-css.js";
|
|
15
15
|
const logger = rendererLogger.component("html-generator");
|
|
16
16
|
function applyExplicitThemeToDocument(html, colorScheme, enabled) {
|
|
17
17
|
if (!enabled || !colorScheme)
|
|
@@ -297,53 +297,13 @@ export class HTMLGenerator {
|
|
|
297
297
|
* double-loading globals.css when it's both auto-discovered and explicitly imported.
|
|
298
298
|
*/
|
|
299
299
|
async mergeImportedCSS(globalCSS, cssImports, stylesheetPath) {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
if (!uniqueImports.has(normalized)) {
|
|
308
|
-
uniqueImports.set(normalized, cssPath);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
const sortedImports = [...uniqueImports.entries()].sort((a, b) => a[0].localeCompare(b[0]));
|
|
312
|
-
const regularCssSegments = [];
|
|
313
|
-
const moduleCssSegments = [];
|
|
314
|
-
for (const [normalizedCssPath, cssPath] of sortedImports) {
|
|
315
|
-
// Deduplicate only exact path matches to avoid skipping unrelated files
|
|
316
|
-
// like /styles/globals.css when the configured stylesheet is /globals.css.
|
|
317
|
-
if (normalizedCssPath === configuredStylesheetAbsolute) {
|
|
318
|
-
continue;
|
|
319
|
-
}
|
|
320
|
-
try {
|
|
321
|
-
const content = await this.config.adapter.fs.readFile(cssPath);
|
|
322
|
-
if (!content)
|
|
323
|
-
continue;
|
|
324
|
-
if (normalizedCssPath.endsWith(".module.css")) {
|
|
325
|
-
moduleCssSegments.push(rewriteCssModuleContent(content, normalizedCssPath));
|
|
326
|
-
}
|
|
327
|
-
else {
|
|
328
|
-
regularCssSegments.push(content);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
catch (_) {
|
|
332
|
-
/* expected: imported CSS file may not exist */
|
|
333
|
-
logger.debug("Could not load imported CSS file", { cssPath });
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
if (regularCssSegments.length === 0 && moduleCssSegments.length === 0)
|
|
337
|
-
return globalCSS;
|
|
338
|
-
const combined = [globalCSS, ...regularCssSegments, ...moduleCssSegments]
|
|
339
|
-
.filter(Boolean)
|
|
340
|
-
.join("\n");
|
|
341
|
-
logger.debug("Merged imported CSS with global stylesheet", {
|
|
342
|
-
importedCount: regularCssSegments.length + moduleCssSegments.length,
|
|
343
|
-
regularCount: regularCssSegments.length,
|
|
344
|
-
moduleCount: moduleCssSegments.length,
|
|
345
|
-
totalLength: combined.length,
|
|
300
|
+
return mergeImportedProjectCss({
|
|
301
|
+
fs: this.config.adapter.fs,
|
|
302
|
+
logger,
|
|
303
|
+
projectDir: this.config.projectDir,
|
|
304
|
+
globalCSS,
|
|
305
|
+
cssImports,
|
|
306
|
+
stylesheetPath,
|
|
346
307
|
});
|
|
347
|
-
return combined;
|
|
348
308
|
}
|
|
349
309
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.1.
|
|
1
|
+
export declare const VERSION = "0.1.175";
|
|
2
2
|
//# sourceMappingURL=version-constant.d.ts.map
|
package/package.json
CHANGED
package/src/deno.js
CHANGED
|
@@ -390,6 +390,67 @@ export class StatOperations extends VeryfrontOperationsBase {
|
|
|
390
390
|
return Array.isArray(files) && files.length > 0;
|
|
391
391
|
}
|
|
392
392
|
|
|
393
|
+
private resolveFromIndex(
|
|
394
|
+
fileIdx: Map<string, ProjectFile>,
|
|
395
|
+
normalizedPath: string,
|
|
396
|
+
options: ResolveFileOptions | undefined,
|
|
397
|
+
indexMs: number,
|
|
398
|
+
resolveStart: number,
|
|
399
|
+
): string | null {
|
|
400
|
+
if (fileIdx.has(normalizedPath)) {
|
|
401
|
+
const totalMs = Math.round(performance.now() - resolveStart);
|
|
402
|
+
logger.debug("resolveFile exact match found", {
|
|
403
|
+
normalizedPath,
|
|
404
|
+
indexMs,
|
|
405
|
+
totalMs,
|
|
406
|
+
});
|
|
407
|
+
return normalizedPath;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const pathWithoutExt = stripKnownExtension(normalizedPath, EXTENSION_PRIORITY);
|
|
411
|
+
|
|
412
|
+
const resolvedDirect = resolveByExtensionPriority(fileIdx, pathWithoutExt, EXTENSION_PRIORITY);
|
|
413
|
+
if (resolvedDirect) {
|
|
414
|
+
const totalMs = Math.round(performance.now() - resolveStart);
|
|
415
|
+
logger.debug("resolveFile found with extension", {
|
|
416
|
+
pathWithExt: resolvedDirect,
|
|
417
|
+
indexMs,
|
|
418
|
+
totalMs,
|
|
419
|
+
});
|
|
420
|
+
return resolvedDirect;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (options?.allowPagesPrefix !== false && !pathWithoutExt.startsWith("pages/")) {
|
|
424
|
+
const resolvedPages = resolveByExtensionPriority(
|
|
425
|
+
fileIdx,
|
|
426
|
+
`pages/${pathWithoutExt}`,
|
|
427
|
+
EXTENSION_PRIORITY,
|
|
428
|
+
);
|
|
429
|
+
if (resolvedPages) {
|
|
430
|
+
const totalMs = Math.round(performance.now() - resolveStart);
|
|
431
|
+
logger.debug("resolveFile found with pages prefix", {
|
|
432
|
+
pathWithExt: resolvedPages,
|
|
433
|
+
indexMs,
|
|
434
|
+
totalMs,
|
|
435
|
+
});
|
|
436
|
+
return resolvedPages;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
const indexPath = resolveIndexByExtensionPriority(fileIdx, pathWithoutExt, EXTENSION_PRIORITY);
|
|
441
|
+
if (indexPath) {
|
|
442
|
+
const totalMs = Math.round(performance.now() - resolveStart);
|
|
443
|
+
logger.debug("resolveFile found index file", {
|
|
444
|
+
indexPath,
|
|
445
|
+
indexMs,
|
|
446
|
+
totalMs,
|
|
447
|
+
});
|
|
448
|
+
return indexPath;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
return null;
|
|
452
|
+
}
|
|
453
|
+
|
|
393
454
|
async exists(path: string): Promise<boolean> {
|
|
394
455
|
const normalizedPath = this.normalizer.normalize(path);
|
|
395
456
|
try {
|
|
@@ -453,55 +514,15 @@ export class StatOperations extends VeryfrontOperationsBase {
|
|
|
453
514
|
return null;
|
|
454
515
|
}
|
|
455
516
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
const pathWithoutExt = stripKnownExtension(normalizedPath, EXTENSION_PRIORITY);
|
|
467
|
-
|
|
468
|
-
const resolvedDirect = resolveByExtensionPriority(fileIdx, pathWithoutExt, EXTENSION_PRIORITY);
|
|
469
|
-
if (resolvedDirect) {
|
|
470
|
-
const totalMs = Math.round(performance.now() - resolveStart);
|
|
471
|
-
logger.debug("resolveFile found with extension", {
|
|
472
|
-
pathWithExt: resolvedDirect,
|
|
473
|
-
indexMs,
|
|
474
|
-
totalMs,
|
|
475
|
-
});
|
|
476
|
-
return resolvedDirect;
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
if (options?.allowPagesPrefix !== false && !pathWithoutExt.startsWith("pages/")) {
|
|
480
|
-
const resolvedPages = resolveByExtensionPriority(
|
|
481
|
-
fileIdx,
|
|
482
|
-
`pages/${pathWithoutExt}`,
|
|
483
|
-
EXTENSION_PRIORITY,
|
|
484
|
-
);
|
|
485
|
-
if (resolvedPages) {
|
|
486
|
-
const totalMs = Math.round(performance.now() - resolveStart);
|
|
487
|
-
logger.debug("resolveFile found with pages prefix", {
|
|
488
|
-
pathWithExt: resolvedPages,
|
|
489
|
-
indexMs,
|
|
490
|
-
totalMs,
|
|
491
|
-
});
|
|
492
|
-
return resolvedPages;
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
const indexPath = resolveIndexByExtensionPriority(fileIdx, pathWithoutExt, EXTENSION_PRIORITY);
|
|
497
|
-
if (indexPath) {
|
|
498
|
-
const totalMs = Math.round(performance.now() - resolveStart);
|
|
499
|
-
logger.debug("resolveFile found index file", {
|
|
500
|
-
indexPath,
|
|
501
|
-
indexMs,
|
|
502
|
-
totalMs,
|
|
503
|
-
});
|
|
504
|
-
return indexPath;
|
|
517
|
+
const indexedResolution = this.resolveFromIndex(
|
|
518
|
+
fileIdx,
|
|
519
|
+
normalizedPath,
|
|
520
|
+
options,
|
|
521
|
+
indexMs,
|
|
522
|
+
resolveStart,
|
|
523
|
+
);
|
|
524
|
+
if (indexedResolution) {
|
|
525
|
+
return indexedResolution;
|
|
505
526
|
}
|
|
506
527
|
|
|
507
528
|
if (attemptedApiResolve) {
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { join } from "../../platform/compat/path/index.js";
|
|
2
|
+
import {
|
|
3
|
+
normalizeCssModuleKey,
|
|
4
|
+
rewriteCssModuleContent,
|
|
5
|
+
} from "../../transforms/css-modules/naming.js";
|
|
6
|
+
|
|
7
|
+
interface CssFsAdapterLike {
|
|
8
|
+
readFile(path: string): Promise<string>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface CssLoggerLike {
|
|
12
|
+
debug(message: string, context?: Record<string, unknown>): void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface MergeImportedCssOptions {
|
|
16
|
+
fs: CssFsAdapterLike;
|
|
17
|
+
logger: CssLoggerLike;
|
|
18
|
+
projectDir: string;
|
|
19
|
+
globalCSS: string | undefined;
|
|
20
|
+
cssImports: string[] | undefined;
|
|
21
|
+
stylesheetPath: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function mergeImportedCSS({
|
|
25
|
+
fs,
|
|
26
|
+
logger,
|
|
27
|
+
projectDir,
|
|
28
|
+
globalCSS,
|
|
29
|
+
cssImports,
|
|
30
|
+
stylesheetPath,
|
|
31
|
+
}: MergeImportedCssOptions): Promise<string | undefined> {
|
|
32
|
+
if (!cssImports || cssImports.length === 0) return globalCSS;
|
|
33
|
+
|
|
34
|
+
const normalizedStylesheetPath = stylesheetPath.replace(/^\/+/, "");
|
|
35
|
+
const configuredStylesheetAbsolute = normalizeCssModuleKey(
|
|
36
|
+
join(projectDir, normalizedStylesheetPath),
|
|
37
|
+
);
|
|
38
|
+
const uniqueImports = new Map<string, string>();
|
|
39
|
+
for (const cssPath of cssImports) {
|
|
40
|
+
const normalized = normalizeCssModuleKey(cssPath);
|
|
41
|
+
if (!uniqueImports.has(normalized)) {
|
|
42
|
+
uniqueImports.set(normalized, cssPath);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const sortedImports = [...uniqueImports.entries()].sort((a, b) => a[0].localeCompare(b[0]));
|
|
47
|
+
const regularCssSegments: string[] = [];
|
|
48
|
+
const moduleCssSegments: string[] = [];
|
|
49
|
+
|
|
50
|
+
for (const [normalizedCssPath, cssPath] of sortedImports) {
|
|
51
|
+
if (normalizedCssPath === configuredStylesheetAbsolute) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
const content = await fs.readFile(cssPath);
|
|
57
|
+
if (!content) continue;
|
|
58
|
+
|
|
59
|
+
if (normalizedCssPath.endsWith(".module.css")) {
|
|
60
|
+
moduleCssSegments.push(rewriteCssModuleContent(content, normalizedCssPath));
|
|
61
|
+
} else {
|
|
62
|
+
regularCssSegments.push(content);
|
|
63
|
+
}
|
|
64
|
+
} catch (_) {
|
|
65
|
+
logger.debug("Could not load imported CSS file", { cssPath });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (regularCssSegments.length === 0 && moduleCssSegments.length === 0) return globalCSS;
|
|
70
|
+
|
|
71
|
+
const combined = [globalCSS, ...regularCssSegments, ...moduleCssSegments]
|
|
72
|
+
.filter(Boolean)
|
|
73
|
+
.join("\n");
|
|
74
|
+
logger.debug("Merged imported CSS with global stylesheet", {
|
|
75
|
+
importedCount: regularCssSegments.length + moduleCssSegments.length,
|
|
76
|
+
regularCount: regularCssSegments.length,
|
|
77
|
+
moduleCount: moduleCssSegments.length,
|
|
78
|
+
totalLength: combined.length,
|
|
79
|
+
});
|
|
80
|
+
return combined;
|
|
81
|
+
}
|
|
@@ -27,10 +27,6 @@ import { extractRelativePath } from "../../utils/route-path-utils.js";
|
|
|
27
27
|
import { resolveAppComponentPath } from "../layouts/utils/app-resolver.js";
|
|
28
28
|
import { StreamTimeoutError, streamToString } from "../utils/stream-utils.js";
|
|
29
29
|
import { profilePhase, profileSyncPhase } from "../../observability/request-profiler.js";
|
|
30
|
-
import {
|
|
31
|
-
normalizeCssModuleKey,
|
|
32
|
-
rewriteCssModuleContent,
|
|
33
|
-
} from "../../transforms/css-modules/naming.js";
|
|
34
30
|
import {
|
|
35
31
|
extractProjectClassesForRoute,
|
|
36
32
|
type ProjectCSSResult,
|
|
@@ -41,6 +37,7 @@ import {
|
|
|
41
37
|
buildHeadElements as buildCollectedHeadElements,
|
|
42
38
|
mergeFrontmatter as mergeCollectedFrontmatter,
|
|
43
39
|
} from "./html-head.js";
|
|
40
|
+
import { mergeImportedCSS as mergeImportedProjectCss } from "./html-imported-css.js";
|
|
44
41
|
|
|
45
42
|
const logger = rendererLogger.component("html-generator");
|
|
46
43
|
|
|
@@ -508,57 +505,13 @@ export class HTMLGenerator {
|
|
|
508
505
|
cssImports: string[] | undefined,
|
|
509
506
|
stylesheetPath: string,
|
|
510
507
|
): Promise<string | undefined> {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
for (const cssPath of cssImports) {
|
|
519
|
-
const normalized = normalizeCssModuleKey(cssPath);
|
|
520
|
-
if (!uniqueImports.has(normalized)) {
|
|
521
|
-
uniqueImports.set(normalized, cssPath);
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
const sortedImports = [...uniqueImports.entries()].sort((a, b) => a[0].localeCompare(b[0]));
|
|
526
|
-
const regularCssSegments: string[] = [];
|
|
527
|
-
const moduleCssSegments: string[] = [];
|
|
528
|
-
|
|
529
|
-
for (const [normalizedCssPath, cssPath] of sortedImports) {
|
|
530
|
-
// Deduplicate only exact path matches to avoid skipping unrelated files
|
|
531
|
-
// like /styles/globals.css when the configured stylesheet is /globals.css.
|
|
532
|
-
if (normalizedCssPath === configuredStylesheetAbsolute) {
|
|
533
|
-
continue;
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
try {
|
|
537
|
-
const content = await this.config.adapter.fs.readFile(cssPath);
|
|
538
|
-
if (!content) continue;
|
|
539
|
-
|
|
540
|
-
if (normalizedCssPath.endsWith(".module.css")) {
|
|
541
|
-
moduleCssSegments.push(rewriteCssModuleContent(content, normalizedCssPath));
|
|
542
|
-
} else {
|
|
543
|
-
regularCssSegments.push(content);
|
|
544
|
-
}
|
|
545
|
-
} catch (_) {
|
|
546
|
-
/* expected: imported CSS file may not exist */
|
|
547
|
-
logger.debug("Could not load imported CSS file", { cssPath });
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
if (regularCssSegments.length === 0 && moduleCssSegments.length === 0) return globalCSS;
|
|
552
|
-
|
|
553
|
-
const combined = [globalCSS, ...regularCssSegments, ...moduleCssSegments]
|
|
554
|
-
.filter(Boolean)
|
|
555
|
-
.join("\n");
|
|
556
|
-
logger.debug("Merged imported CSS with global stylesheet", {
|
|
557
|
-
importedCount: regularCssSegments.length + moduleCssSegments.length,
|
|
558
|
-
regularCount: regularCssSegments.length,
|
|
559
|
-
moduleCount: moduleCssSegments.length,
|
|
560
|
-
totalLength: combined.length,
|
|
508
|
+
return mergeImportedProjectCss({
|
|
509
|
+
fs: this.config.adapter.fs,
|
|
510
|
+
logger,
|
|
511
|
+
projectDir: this.config.projectDir,
|
|
512
|
+
globalCSS,
|
|
513
|
+
cssImports,
|
|
514
|
+
stylesheetPath,
|
|
561
515
|
});
|
|
562
|
-
return combined;
|
|
563
516
|
}
|
|
564
517
|
}
|