@master/css-compiler 0.0.0-site.1793659883.g69c9aebcf628
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/README.md +466 -0
- package/dist/compiler.d.ts +42 -0
- package/dist/compiler.js +248 -0
- package/dist/contracts.d.ts +31 -0
- package/dist/contracts.js +13 -0
- package/dist/diagnostics/contracts.d.ts +119 -0
- package/dist/diagnostics/contracts.js +1 -0
- package/dist/diagnostics/design-system.d.ts +31 -0
- package/dist/diagnostics/design-system.js +75 -0
- package/dist/diagnostics/index.d.ts +28 -0
- package/dist/diagnostics/index.js +304 -0
- package/dist/diagnostics/project-comparison.d.ts +4 -0
- package/dist/diagnostics/project-comparison.js +8 -0
- package/dist/index.d.ts +95 -0
- package/dist/index.js +34 -0
- package/dist/node-compiler.d.ts +133 -0
- package/dist/node-compiler.js +417 -0
- package/dist/node-imports.d.ts +54 -0
- package/dist/node-imports.js +253 -0
- package/dist/node.d.ts +21 -0
- package/dist/node.js +47 -0
- package/dist/notices.d.ts +5 -0
- package/dist/notices.js +29 -0
- package/dist/prepared-graph-cache.d.ts +5 -0
- package/dist/prepared-graph-cache.js +31 -0
- package/dist/project/binding-project.d.ts +29 -0
- package/dist/project/binding-project.js +100 -0
- package/dist/project/entries.d.ts +7 -0
- package/dist/project/entries.js +30 -0
- package/dist/project/manifest-sync.d.ts +5 -0
- package/dist/project/manifest-sync.js +40 -0
- package/dist/project/manifest.d.ts +5 -0
- package/dist/project/manifest.js +49 -0
- package/dist/project/options.d.ts +43 -0
- package/dist/project/options.js +1 -0
- package/dist/pure-css-cache.d.ts +11 -0
- package/dist/pure-css-cache.js +39 -0
- package/dist/session.d.ts +19 -0
- package/dist/session.js +46 -0
- package/dist/stylesheet/browser.d.ts +32 -0
- package/dist/stylesheet/browser.js +71 -0
- package/dist/stylesheet/compiled-source.d.ts +11 -0
- package/dist/stylesheet/compiled-source.js +96 -0
- package/dist/stylesheet/composition-cache.d.ts +18 -0
- package/dist/stylesheet/composition-cache.js +79 -0
- package/dist/stylesheet/delivery.d.ts +103 -0
- package/dist/stylesheet/delivery.js +367 -0
- package/dist/stylesheet/directives.d.ts +31 -0
- package/dist/stylesheet/directives.js +105 -0
- package/dist/stylesheet/index-public.d.ts +3 -0
- package/dist/stylesheet/index-public.js +4 -0
- package/dist/stylesheet/index.d.ts +39 -0
- package/dist/stylesheet/index.js +501 -0
- package/dist/stylesheet/linked-stylesheet.d.ts +10 -0
- package/dist/stylesheet/linked-stylesheet.js +13 -0
- package/dist/stylesheet/output-map.d.ts +20 -0
- package/dist/stylesheet/output-map.js +222 -0
- package/dist/stylesheet/public.d.ts +171 -0
- package/dist/stylesheet/public.js +346 -0
- package/dist/stylesheet/reference-files.d.ts +6 -0
- package/dist/stylesheet/reference-files.js +13 -0
- package/dist/stylesheet/reference-origins.d.ts +4 -0
- package/dist/stylesheet/reference-origins.js +28 -0
- package/dist/stylesheet/render-core.d.ts +35 -0
- package/dist/stylesheet/render-core.js +28 -0
- package/dist/stylesheet/render-delivery.d.ts +4 -0
- package/dist/stylesheet/render-delivery.js +61 -0
- package/dist/stylesheet/render.d.ts +5 -0
- package/dist/stylesheet/render.js +31 -0
- package/dist/stylesheet/source-context.d.ts +8 -0
- package/dist/stylesheet/source-context.js +71 -0
- package/dist/stylesheet/source-map-url.d.ts +4 -0
- package/dist/stylesheet/source-map-url.js +11 -0
- package/dist/stylesheet/source.d.ts +3 -0
- package/dist/stylesheet/source.js +52 -0
- package/dist/stylesheet/types.d.ts +162 -0
- package/dist/stylesheet/types.js +1 -0
- package/dist/value-validation.d.ts +19 -0
- package/dist/value-validation.js +96 -0
- package/package.json +79 -0
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
import { prepareCSSImportGraph } from "../node-imports.js";
|
|
2
|
+
import { analyzeCSSDependencies, createManifestFromCSSResult, filterCSSExtractionCandidates, inspectCSS, isMasterCSSPackageStyleFile as isMasterCSSPackageStyleFile$1, resolveCSSImportGraphSource, resolveMasterCSSPackageImportGraph, stripRequestSuffix } from "../node-compiler.js";
|
|
3
|
+
import { collectStylesheetDirectives, collectStylesheetDirectivesFromCSSGraph, createStylesheetDirectives, findStylesheetDirectiveStatements, hasLocalStyleDirectives, hasStylesheetDirectives, hasStylesheetSourceDirectives, mergeStylesheetDirectives, mergeStylesheetSourceOptions, removeStylesheetDirectiveStatements, resolveStylesheetSourcePaths } from "./directives.js";
|
|
4
|
+
import { hasStylesheetResourceReferences, renderCompiledManifestCSS } from "./render.js";
|
|
5
|
+
import { compileDeliveredSource, compileStylesheetMetadata, composeDeliveredStylesheets, registerDeliveredStylesheet } from "./delivery.js";
|
|
6
|
+
import { mapStylesheetError } from "./source-context.js";
|
|
7
|
+
import { compilePreparedStylesheet } from "./compiled-source.js";
|
|
8
|
+
import { compileRenderedDelivery } from "./render-delivery.js";
|
|
9
|
+
import { prepareSassSource } from "./source.js";
|
|
10
|
+
import { pathToFileURL } from "node:url";
|
|
11
|
+
import { extname, resolve } from "node:path";
|
|
12
|
+
import { readFileSync } from "node:fs";
|
|
13
|
+
import { createToolingSessionSync } from "@master/css-tooling/node";
|
|
14
|
+
// src/stylesheet/index.ts
|
|
15
|
+
const STYLESHEET_REQUEST_RE = /\.(css|scss|sass)(?:[?#].*)?$/;
|
|
16
|
+
const VIRTUAL_CSS_ID = "virtual:master-utilities.css";
|
|
17
|
+
const MASTER_CSS_MODULE_IDS = ["@master/css"];
|
|
18
|
+
function normalizeStylesheetModuleIds() {
|
|
19
|
+
return new Set(MASTER_CSS_MODULE_IDS);
|
|
20
|
+
}
|
|
21
|
+
function cleanStyleRequest(id) {
|
|
22
|
+
if (id.startsWith("\0")) return id;
|
|
23
|
+
return stripRequestSuffix(id);
|
|
24
|
+
}
|
|
25
|
+
function getStyleRequestSearchParams(id) {
|
|
26
|
+
const queryStart = id.indexOf("?");
|
|
27
|
+
return queryStart === -1 ? new URLSearchParams() : new URLSearchParams(id.slice(queryStart + 1));
|
|
28
|
+
}
|
|
29
|
+
function getStyleRequestExtension(id) {
|
|
30
|
+
const cleanExtension = extname(cleanStyleRequest(id));
|
|
31
|
+
if (cleanExtension === ".css" || cleanExtension === ".scss" || cleanExtension === ".sass") return cleanExtension;
|
|
32
|
+
const lang = getStyleRequestSearchParams(id).get("lang");
|
|
33
|
+
if (lang === "css" || lang === "scss" || lang === "sass") return "." + lang;
|
|
34
|
+
return cleanExtension;
|
|
35
|
+
}
|
|
36
|
+
function isStyleModuleRequest(source) {
|
|
37
|
+
return getStyleRequestSearchParams(source).get("type") === "style";
|
|
38
|
+
}
|
|
39
|
+
function isStylesheetRequest(id) {
|
|
40
|
+
return STYLESHEET_REQUEST_RE.test(id) || isStyleModuleRequest(id) && [
|
|
41
|
+
".css",
|
|
42
|
+
".scss",
|
|
43
|
+
".sass"
|
|
44
|
+
].includes(getStyleRequestExtension(id));
|
|
45
|
+
}
|
|
46
|
+
function replaceStylesheetImports(source, replacement) {
|
|
47
|
+
const ids = /* @__PURE__ */ new Set([...normalizeStylesheetModuleIds(), VIRTUAL_CSS_ID]);
|
|
48
|
+
const imports = analyzeCSSDependencies(source).imports;
|
|
49
|
+
let replaced = false;
|
|
50
|
+
let code = source;
|
|
51
|
+
for (const statement of imports.toReversed()) {
|
|
52
|
+
if (!ids.has(statement.source)) continue;
|
|
53
|
+
code = code.slice(0, statement.start) + replacement + code.slice(statement.end);
|
|
54
|
+
replaced = true;
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
code,
|
|
58
|
+
replaced
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function isExpandableStyleImportSource(source) {
|
|
62
|
+
return (source.startsWith("./") || source.startsWith("../")) && extname(source) === ".css";
|
|
63
|
+
}
|
|
64
|
+
function findImportStatements(source) {
|
|
65
|
+
return analyzeCSSDependencies(source).imports;
|
|
66
|
+
}
|
|
67
|
+
function resolveStylesheetImportGraph(file, source, projectDir, options = {}) {
|
|
68
|
+
if (!STYLESHEET_REQUEST_RE.test(cleanStyleRequest(file))) return {
|
|
69
|
+
source,
|
|
70
|
+
dependencies: [cleanStyleRequest(file)]
|
|
71
|
+
};
|
|
72
|
+
return resolveCSSImportGraphSource(cleanStyleRequest(file), source, {
|
|
73
|
+
projectDir,
|
|
74
|
+
expandPackageImports: options.expandMasterCSSPackage !== false
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function collectStylesheetDependencies(file, source, projectDir) {
|
|
78
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
79
|
+
const filename = cleanStyleRequest(file);
|
|
80
|
+
dependencies.add(filename);
|
|
81
|
+
let resolvedSource = source;
|
|
82
|
+
if (resolvedSource === void 0) try {
|
|
83
|
+
resolvedSource = readFileSync(filename, "utf-8");
|
|
84
|
+
} catch {
|
|
85
|
+
return [...dependencies];
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
const graph = prepareCSSImportGraph(filename, resolvedSource, {
|
|
89
|
+
projectDir,
|
|
90
|
+
expandPackageImports: false
|
|
91
|
+
}, analyzeCSSDependencies);
|
|
92
|
+
for (const dependency of Object.keys(graph.files)) dependencies.add(cleanStyleRequest(dependency));
|
|
93
|
+
} catch {}
|
|
94
|
+
return [...dependencies];
|
|
95
|
+
}
|
|
96
|
+
function removeStylesheetImports(source) {
|
|
97
|
+
return replaceStylesheetImports(source, "");
|
|
98
|
+
}
|
|
99
|
+
function hasMasterStyleEntrypoint(source) {
|
|
100
|
+
return inspectCSS(source).hasMasterEntry;
|
|
101
|
+
}
|
|
102
|
+
function resolveMasterStyleSource(file, source, projectDir) {
|
|
103
|
+
if (!isStylesheetRequest(file)) return;
|
|
104
|
+
const sourceHasMasterEntry = hasMasterStyleEntrypoint(source);
|
|
105
|
+
let unresolvedPackageSource;
|
|
106
|
+
try {
|
|
107
|
+
unresolvedPackageSource = resolveStylesheetImportGraph(file, source, projectDir, { expandMasterCSSPackage: false });
|
|
108
|
+
} catch (error) {
|
|
109
|
+
if (!sourceHasMasterEntry) return;
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
if (!isMasterStyleSource(unresolvedPackageSource.source)) return;
|
|
113
|
+
return resolveStylesheetImportGraph(file, source, projectDir);
|
|
114
|
+
}
|
|
115
|
+
function isMasterCSSPackageStyleFile(id, projectDir) {
|
|
116
|
+
return isMasterCSSPackageStyleFile$1(id, projectDir);
|
|
117
|
+
}
|
|
118
|
+
function removeMasterStyleDirectives(source) {
|
|
119
|
+
return removeStylesheetDirectiveStatements(source);
|
|
120
|
+
}
|
|
121
|
+
function isStylesheetHostImport(importSource, masterImport) {
|
|
122
|
+
return importSource === masterImport || masterImport === "@master/css" && normalizeStylesheetModuleIds().has(importSource);
|
|
123
|
+
}
|
|
124
|
+
function createStylesheetHostSource(source, options = {}) {
|
|
125
|
+
const masterImport = options.masterImport || "@master/css";
|
|
126
|
+
const masterSource = options.masterSource;
|
|
127
|
+
const hasMasterSource = Object.prototype.hasOwnProperty.call(options, "masterSource");
|
|
128
|
+
const cleanSource = removeMasterStyleDirectives(source).code;
|
|
129
|
+
const imports = findImportStatements(cleanSource);
|
|
130
|
+
const preservedImports = [];
|
|
131
|
+
for (const importStatement of imports) {
|
|
132
|
+
const importSource = importStatement.source;
|
|
133
|
+
if (!importSource) continue;
|
|
134
|
+
if (importSource === VIRTUAL_CSS_ID || normalizeStylesheetModuleIds().has(importSource)) {
|
|
135
|
+
if (!hasMasterSource && isStylesheetHostImport(importSource, masterImport)) preservedImports.push(importStatement.statement.trim());
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (!isExpandableStyleImportSource(importSource)) preservedImports.push(importStatement.statement.trim());
|
|
139
|
+
}
|
|
140
|
+
if (hasMasterSource) {
|
|
141
|
+
if (masterSource) preservedImports.push(masterSource);
|
|
142
|
+
} else if (!preservedImports.some((statement) => {
|
|
143
|
+
const importSource = findImportStatements(statement)[0]?.source;
|
|
144
|
+
return importSource && isStylesheetHostImport(importSource, masterImport);
|
|
145
|
+
})) preservedImports.unshift(`@import "${masterImport}";`);
|
|
146
|
+
return preservedImports.join("\n");
|
|
147
|
+
}
|
|
148
|
+
function resolveMasterCSSPackageCompileSource(projectDir) {
|
|
149
|
+
const graph = resolveMasterCSSPackageImportGraph(projectDir);
|
|
150
|
+
return {
|
|
151
|
+
source: removeMasterStyleDirectives(removeStylesheetImports(graph.source).code).code,
|
|
152
|
+
dependencies: graph.dependencies
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
function isMasterStyleSource(source) {
|
|
156
|
+
return hasMasterStyleEntrypoint(source);
|
|
157
|
+
}
|
|
158
|
+
function prepareStylesheetSource(id, source, options = {}) {
|
|
159
|
+
return prepareSassSource(cleanStyleRequest(id), source, getStyleRequestExtension(id.startsWith("\0") && options.baseFile ? options.baseFile : id), options);
|
|
160
|
+
}
|
|
161
|
+
async function preprocessStylesheet(source, id, options) {
|
|
162
|
+
const extension = getStyleRequestExtension(id);
|
|
163
|
+
if (extension !== ".scss" && extension !== ".sass") return source;
|
|
164
|
+
return (await prepareStylesheetSource(id, source, options)).source;
|
|
165
|
+
}
|
|
166
|
+
async function compileStylesheet(id, source, options) {
|
|
167
|
+
const { result, finalizedResult, outputMap } = await compileStylesheetResult(id, source, options);
|
|
168
|
+
return {
|
|
169
|
+
...result,
|
|
170
|
+
dependencies: finalizedResult.dependencies,
|
|
171
|
+
warnings: finalizedResult.warnings,
|
|
172
|
+
notices: finalizedResult.notices,
|
|
173
|
+
css: finalizedResult.css,
|
|
174
|
+
generatedCSS: finalizedResult.generatedCSS,
|
|
175
|
+
sourceMap: outputMap(finalizedResult.css)
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
async function compileStylesheetResult(id, source, options, resolveImports = false) {
|
|
179
|
+
const prepared = await prepareStylesheetSource(id, source, options);
|
|
180
|
+
return compilePreparedStylesheet(cleanStyleRequest(id), prepared.source, {
|
|
181
|
+
...options,
|
|
182
|
+
sourceMap: options.sourceMap ?? prepared.sourceMap
|
|
183
|
+
}, resolveImports);
|
|
184
|
+
}
|
|
185
|
+
async function compileRenderedStylesheet(id, source, options) {
|
|
186
|
+
if (options.delivery) {
|
|
187
|
+
const prepared = await prepareStylesheetSource(id, source, options);
|
|
188
|
+
const filename = id.startsWith("\0") ? id : resolve(options.projectDir ?? "", cleanStyleRequest(id));
|
|
189
|
+
const result = await compileRenderedDelivery(filename, prepared.source, {
|
|
190
|
+
...options,
|
|
191
|
+
delivery: {
|
|
192
|
+
...options.delivery,
|
|
193
|
+
onDependency: (file) => {
|
|
194
|
+
options.onDependency?.(file);
|
|
195
|
+
if (options.delivery.onDependency !== options.onDependency) options.delivery.onDependency?.(file);
|
|
196
|
+
},
|
|
197
|
+
baseFile: options.delivery.baseFile ?? options.baseFile,
|
|
198
|
+
sourceMap: options.delivery.sourceMap ?? options.sourceMap ?? prepared.sourceMap
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
return {
|
|
202
|
+
...result,
|
|
203
|
+
dependencies: [.../* @__PURE__ */ new Set([...prepared.dependencies, ...result.dependencies])]
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
const { compileOptions, finalizedResult, result, outputMap } = await compileStylesheetResult(id, source, options, true);
|
|
207
|
+
const renderedCSS = renderCompiledManifestCSS({
|
|
208
|
+
manifest: finalizedResult.resolutionManifest,
|
|
209
|
+
nativeCSS: finalizedResult.css,
|
|
210
|
+
classNames: compileOptions.classes,
|
|
211
|
+
emittedGlobals: options.emittedGlobals
|
|
212
|
+
});
|
|
213
|
+
return {
|
|
214
|
+
...result,
|
|
215
|
+
dependencies: finalizedResult.dependencies,
|
|
216
|
+
warnings: finalizedResult.warnings,
|
|
217
|
+
notices: finalizedResult.notices,
|
|
218
|
+
css: renderedCSS.css,
|
|
219
|
+
sourceMap: outputMap(renderedCSS.css, renderedCSS.outputMappings),
|
|
220
|
+
nativeCSS: renderedCSS.nativeCSS,
|
|
221
|
+
generatedCSS: renderedCSS.generatedCSS,
|
|
222
|
+
emittedGlobals: renderedCSS.emittedGlobals,
|
|
223
|
+
manifest: finalizedResult.manifest,
|
|
224
|
+
renderedCSS
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
function createEmptyStyleEntryEmittedGlobals() {
|
|
228
|
+
return {
|
|
229
|
+
variables: {},
|
|
230
|
+
keyframes: {}
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function hasEmittedGlobals(emittedGlobals) {
|
|
234
|
+
return Boolean(Object.keys(emittedGlobals?.variables || {}).length || Object.keys(emittedGlobals?.keyframes || {}).length);
|
|
235
|
+
}
|
|
236
|
+
async function createStyleEntryEmittedGlobals(entries, options) {
|
|
237
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
238
|
+
let baseManifest = options.baseManifest;
|
|
239
|
+
let emittedGlobals = createEmptyStyleEntryEmittedGlobals();
|
|
240
|
+
for (const entry of [...new Set(entries)].sort()) {
|
|
241
|
+
const filename = cleanStyleRequest(entry);
|
|
242
|
+
const source = await preprocessStylesheet(readFileSync(filename, "utf-8"), filename, options);
|
|
243
|
+
const result = compileStylesheetMetadata(filename, source, {
|
|
244
|
+
...options,
|
|
245
|
+
baseManifest,
|
|
246
|
+
preserveNativeCSS: true
|
|
247
|
+
});
|
|
248
|
+
if (!result) continue;
|
|
249
|
+
for (const dependency of result.directives.dependencies) dependencies.add(cleanStyleRequest(dependency));
|
|
250
|
+
const renderedCSS = renderCompiledManifestCSS({
|
|
251
|
+
manifest: result.manifest,
|
|
252
|
+
nativeCSS: result.stylesheets.map((stylesheet) => stylesheet.css),
|
|
253
|
+
emittedGlobals
|
|
254
|
+
});
|
|
255
|
+
if (hasEmittedGlobals(renderedCSS.emittedGlobals)) emittedGlobals = renderedCSS.emittedGlobals;
|
|
256
|
+
baseManifest = result.manifest;
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
emittedGlobals,
|
|
260
|
+
dependencies: [...dependencies]
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
async function transformLocalStylesheet(id, source, options) {
|
|
264
|
+
let local = false;
|
|
265
|
+
let native = false;
|
|
266
|
+
try {
|
|
267
|
+
if (isStylesheetRequest(id)) {
|
|
268
|
+
native = !hasLocalStyleDirectives(source, cleanStyleRequest(id));
|
|
269
|
+
local = Boolean(options.delivery || options.transformNativeStylesheets || !native);
|
|
270
|
+
}
|
|
271
|
+
} catch (error) {
|
|
272
|
+
throw mapStylesheetError(error, cleanStyleRequest(id), options, source);
|
|
273
|
+
}
|
|
274
|
+
if (!isStylesheetRequest(id) || !local) return {
|
|
275
|
+
code: source,
|
|
276
|
+
dependencies: [],
|
|
277
|
+
transformed: false
|
|
278
|
+
};
|
|
279
|
+
const { emittedGlobals, generatedGlobals = "inline", preserveUnchangedNativeCSS = false, ...compileOptions } = options;
|
|
280
|
+
if (generatedGlobals !== "inline" && generatedGlobals !== "separate") throw new TypeError("generatedGlobals must be inline or separate.");
|
|
281
|
+
if (options.delivery) {
|
|
282
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
283
|
+
const compiled = await compileDeliveredSource(cleanStyleRequest(id), await preprocessStylesheet(source, id, options), {
|
|
284
|
+
...compileOptions,
|
|
285
|
+
preserveUnchangedNativeCSS,
|
|
286
|
+
delivery: {
|
|
287
|
+
...options.delivery,
|
|
288
|
+
onDependency: (file) => {
|
|
289
|
+
dependencies.add(file);
|
|
290
|
+
options.delivery.onDependency?.(file);
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
preserveNativeCSS: true
|
|
294
|
+
});
|
|
295
|
+
if (!compiled) return {
|
|
296
|
+
code: source,
|
|
297
|
+
dependencies: preserveUnchangedNativeCSS ? [...dependencies] : [],
|
|
298
|
+
transformed: false
|
|
299
|
+
};
|
|
300
|
+
const rendered = renderCompiledManifestCSS({
|
|
301
|
+
manifest: compiled.resolutionManifest,
|
|
302
|
+
nativeCSS: compiled.stylesheets.map((asset) => asset.css),
|
|
303
|
+
includeGeneratedCSS: false,
|
|
304
|
+
emittedGlobals
|
|
305
|
+
});
|
|
306
|
+
const code = [compiled.directives.css, generatedGlobals === "inline" && rendered.generatedCSS].filter(Boolean).join("\n\n");
|
|
307
|
+
return {
|
|
308
|
+
code,
|
|
309
|
+
transformed: true,
|
|
310
|
+
dependencies: compiled.directives.dependencies,
|
|
311
|
+
...generatedGlobals === "separate" && rendered.generatedCSS ? { globalStylesheet: { css: rendered.generatedCSS } } : {},
|
|
312
|
+
stylesheets: compiled.stylesheets.filter((asset) => asset.id !== compiled.entry).map(({ id, href, css }) => ({
|
|
313
|
+
id,
|
|
314
|
+
href,
|
|
315
|
+
css
|
|
316
|
+
})),
|
|
317
|
+
resources: compiled.resources,
|
|
318
|
+
result: {
|
|
319
|
+
...compiled.directives,
|
|
320
|
+
css: code,
|
|
321
|
+
generatedCSS: rendered.generatedCSS
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
const { result, finalizedResult, outputMap } = await compileStylesheetResult(id, source, {
|
|
326
|
+
...compileOptions,
|
|
327
|
+
preserveNativeSource: compileOptions.preserveNativeSource ?? native,
|
|
328
|
+
preserveNativeCSS: true
|
|
329
|
+
});
|
|
330
|
+
if (native && !hasStylesheetResourceReferences(finalizedResult.resolutionManifest, finalizedResult.css || result.nativeCSS || "")) return {
|
|
331
|
+
code: source,
|
|
332
|
+
dependencies: finalizedResult.dependencies,
|
|
333
|
+
transformed: false
|
|
334
|
+
};
|
|
335
|
+
const renderedCSS = renderCompiledManifestCSS({
|
|
336
|
+
manifest: finalizedResult.resolutionManifest,
|
|
337
|
+
nativeCSS: finalizedResult.css || result.nativeCSS,
|
|
338
|
+
includeGeneratedCSS: false,
|
|
339
|
+
emittedGlobals
|
|
340
|
+
});
|
|
341
|
+
const transformedResult = {
|
|
342
|
+
...result,
|
|
343
|
+
dependencies: finalizedResult.dependencies,
|
|
344
|
+
warnings: finalizedResult.warnings,
|
|
345
|
+
notices: finalizedResult.notices,
|
|
346
|
+
css: generatedGlobals === "separate" ? renderedCSS.nativeCSS : renderedCSS.css,
|
|
347
|
+
sourceMap: outputMap(generatedGlobals === "separate" ? renderedCSS.nativeCSS : renderedCSS.css, generatedGlobals === "separate" ? [] : renderedCSS.outputMappings),
|
|
348
|
+
generatedCSS: renderedCSS.generatedCSS
|
|
349
|
+
};
|
|
350
|
+
return {
|
|
351
|
+
code: transformedResult.css || transformedResult.nativeCSS || "",
|
|
352
|
+
...generatedGlobals === "separate" && renderedCSS.generatedCSS ? { globalStylesheet: { css: renderedCSS.generatedCSS } } : {},
|
|
353
|
+
dependencies: [.../* @__PURE__ */ new Set([cleanStyleRequest(id), ...transformedResult.dependencies || []])],
|
|
354
|
+
transformed: true,
|
|
355
|
+
result: transformedResult
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
function getNativeCSS(result) {
|
|
359
|
+
if (result.nativeCSS !== void 0) return result.nativeCSS;
|
|
360
|
+
const css = result.css || "";
|
|
361
|
+
const generatedCSS = result.generatedCSS || "";
|
|
362
|
+
if (generatedCSS && css.endsWith(generatedCSS)) return css.slice(0, -generatedCSS.length).trim();
|
|
363
|
+
return css;
|
|
364
|
+
}
|
|
365
|
+
function hasCompiledStyleManifestInput(result) {
|
|
366
|
+
return Boolean(Object.keys(result.manifestInput || {}).length || result.styleDefinitions?.length);
|
|
367
|
+
}
|
|
368
|
+
function getScannerClasses(scanner) {
|
|
369
|
+
return filterCSSExtractionCandidates([.../* @__PURE__ */ new Set([
|
|
370
|
+
...scanner.latentClasses || [],
|
|
371
|
+
...scanner.validClasses || [],
|
|
372
|
+
...scanner.usedNativeClasses || [],
|
|
373
|
+
...scanner.options.safelist || []
|
|
374
|
+
])], scanner.options.blocklist);
|
|
375
|
+
}
|
|
376
|
+
function getStylesheetOptionClasses(options, manifest, projectDir = process.cwd()) {
|
|
377
|
+
const classes = new Set(options.safelist || []);
|
|
378
|
+
const tooling = createToolingSessionSync({ manifest });
|
|
379
|
+
try {
|
|
380
|
+
for (const sourcePath of resolveStylesheetSourcePaths(options, projectDir)) {
|
|
381
|
+
const absolutePath = resolve(projectDir, sourcePath);
|
|
382
|
+
const extracted = tooling.extractSource({ files: [{
|
|
383
|
+
source: absolutePath,
|
|
384
|
+
content: readFileSync(absolutePath, "utf-8")
|
|
385
|
+
}] }).files[0];
|
|
386
|
+
if (extracted.diagnostics.length) throw new Error(`${absolutePath}: ${extracted.diagnostics[0].message}`);
|
|
387
|
+
for (const className of extracted.candidates) classes.add(className);
|
|
388
|
+
}
|
|
389
|
+
} finally {
|
|
390
|
+
tooling.dispose();
|
|
391
|
+
}
|
|
392
|
+
return filterCSSExtractionCandidates([...classes], options.blocklist);
|
|
393
|
+
}
|
|
394
|
+
function getStyleSourceClasses(scanner, styleSource, baseClasses, projectDir) {
|
|
395
|
+
if (!hasStylesheetDirectives(styleSource.directives)) return baseClasses;
|
|
396
|
+
const scopedOptions = mergeStylesheetSourceOptions({
|
|
397
|
+
...scanner.options,
|
|
398
|
+
exclude: scanner.customOptions ? scanner.customOptions.exclude : scanner.options.exclude
|
|
399
|
+
}, styleSource.directives);
|
|
400
|
+
const classes = hasStylesheetSourceDirectives(styleSource.directives) ? getStylesheetOptionClasses(scopedOptions, scanner.css.manifest, projectDir) : [...baseClasses, ...styleSource.directives.safelist || []];
|
|
401
|
+
return filterCSSExtractionCandidates([...new Set(classes)], scopedOptions.blocklist);
|
|
402
|
+
}
|
|
403
|
+
async function registerStylesheetSource(scanner, stylesheetSources, id, source, options) {
|
|
404
|
+
if (options.delivery) return registerDeliveredStylesheet(scanner, stylesheetSources, id, source, options);
|
|
405
|
+
const filename = cleanStyleRequest(id);
|
|
406
|
+
const prepared = await prepareStylesheetSource(filename, source, options);
|
|
407
|
+
const compileOptions = {
|
|
408
|
+
...options,
|
|
409
|
+
delivery: defaultCollectionDelivery(options.projectDir ?? scanner.cwd, {
|
|
410
|
+
...options,
|
|
411
|
+
sourceMap: options.sourceMap ?? prepared.sourceMap
|
|
412
|
+
})
|
|
413
|
+
};
|
|
414
|
+
return registerDeliveredStylesheet(scanner, stylesheetSources, filename, prepared.source, compileOptions, true);
|
|
415
|
+
}
|
|
416
|
+
function defaultCollectionDelivery(projectDir, options) {
|
|
417
|
+
return {
|
|
418
|
+
entryURL: pathToFileURL(resolve(projectDir, "master.css")).href,
|
|
419
|
+
stylesheetURL: (file, variant) => pathToFileURL(variant ?? file).href,
|
|
420
|
+
resourceURL: (file) => pathToFileURL(file).href,
|
|
421
|
+
baseFile: options.baseFile,
|
|
422
|
+
sourceMap: options.sourceMap,
|
|
423
|
+
onDependency: options.onDependency
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
function hasMasterCSSPackageSource(stylesheetSources) {
|
|
427
|
+
return Array.from(stylesheetSources?.values() || []).some((styleSource) => styleSource.masterCSS);
|
|
428
|
+
}
|
|
429
|
+
async function compileMasterCSSPackage(projectDir, options) {
|
|
430
|
+
const graph = resolveMasterCSSPackageCompileSource(projectDir);
|
|
431
|
+
return {
|
|
432
|
+
...await compileStylesheet(graph.dependencies[0] || "@master/css", graph.source, options),
|
|
433
|
+
dependencies: graph.dependencies
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
function createEmptyExtractedCSSResult(css = "") {
|
|
437
|
+
return {
|
|
438
|
+
css,
|
|
439
|
+
emittedGlobals: {
|
|
440
|
+
variables: {},
|
|
441
|
+
keyframes: {}
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
async function createExtractedCSSResult(options) {
|
|
446
|
+
const { scanner, stylesheetSources, manifest: planOption, includeGeneratedCSS = true, includeNativeCSS = true, includeMasterBaseCSS = true, ...compileOptions } = options;
|
|
447
|
+
const classes = compileOptions.classes ?? getScannerClasses(scanner);
|
|
448
|
+
if (compileOptions.delivery || stylesheetSources?.size && [...stylesheetSources.values()].every((source) => source.graph)) {
|
|
449
|
+
const inlineImports = !compileOptions.delivery;
|
|
450
|
+
return composeDeliveredStylesheets(stylesheetSources ?? /* @__PURE__ */ new Map(), {
|
|
451
|
+
...compileOptions,
|
|
452
|
+
delivery: compileOptions.delivery ?? defaultCollectionDelivery(compileOptions.projectDir ?? scanner.cwd, compileOptions),
|
|
453
|
+
manifest: planOption,
|
|
454
|
+
includeGeneratedCSS,
|
|
455
|
+
includeNativeCSS,
|
|
456
|
+
includeMasterBaseCSS
|
|
457
|
+
}, classes, (source) => getStyleSourceClasses(scanner, source, classes, compileOptions.projectDir ?? scanner.cwd), inlineImports);
|
|
458
|
+
}
|
|
459
|
+
if (!planOption && !compileOptions.classes && !stylesheetSources?.size) return createEmptyExtractedCSSResult(includeGeneratedCSS ? scanner.css.text : "");
|
|
460
|
+
const hasMasterCSS = hasMasterCSSPackageSource(stylesheetSources);
|
|
461
|
+
const explicitPlan = planOption;
|
|
462
|
+
const masterCSSResult = hasMasterCSS ? await compileMasterCSSPackage(compileOptions.projectDir, compileOptions) : void 0;
|
|
463
|
+
const entryStyleResults = await Promise.all(Array.from(stylesheetSources || []).map(([id, styleSource]) => compileStylesheet(id, styleSource.source, {
|
|
464
|
+
...compileOptions,
|
|
465
|
+
references: styleSource.references,
|
|
466
|
+
pruneNativeCSS: styleSource.pruneNativeCSS,
|
|
467
|
+
classes: styleSource.pruneNativeCSS ? getStyleSourceClasses(scanner, styleSource, classes, compileOptions.projectDir ?? scanner.cwd) : void 0
|
|
468
|
+
})));
|
|
469
|
+
const styleResults = [...masterCSSResult ? [masterCSSResult] : [], ...entryStyleResults];
|
|
470
|
+
let mergedPlan = explicitPlan ?? compileOptions.baseManifest;
|
|
471
|
+
const finalizedStyleResults = /* @__PURE__ */ new Map();
|
|
472
|
+
for (const result of styleResults) {
|
|
473
|
+
if (!hasCompiledStyleManifestInput(result)) continue;
|
|
474
|
+
const finalizedResult = createManifestFromCSSResult(result, {
|
|
475
|
+
...compileOptions,
|
|
476
|
+
baseManifest: mergedPlan
|
|
477
|
+
});
|
|
478
|
+
mergedPlan = finalizedResult.manifest;
|
|
479
|
+
finalizedStyleResults.set(result, finalizedResult);
|
|
480
|
+
}
|
|
481
|
+
const nativeCSS = [...includeMasterBaseCSS ? [...masterCSSResult ? [getNativeCSS(finalizedStyleResults.get(masterCSSResult) || masterCSSResult)] : []] : [], ...includeNativeCSS ? entryStyleResults.map((result) => finalizedStyleResults.get(result)?.css || result.nativeCSS).filter(Boolean) : []];
|
|
482
|
+
const generatedClasses = new Set(classes);
|
|
483
|
+
if (includeGeneratedCSS) for (const styleSource of stylesheetSources?.values() || []) {
|
|
484
|
+
if (!hasStylesheetDirectives(styleSource.directives)) continue;
|
|
485
|
+
for (const className of getStyleSourceClasses(scanner, styleSource, classes, compileOptions.projectDir ?? scanner.cwd)) generatedClasses.add(className);
|
|
486
|
+
}
|
|
487
|
+
const renderedCSS = renderCompiledManifestCSS({
|
|
488
|
+
manifest: mergedPlan,
|
|
489
|
+
nativeCSS,
|
|
490
|
+
classNames: generatedClasses,
|
|
491
|
+
includeGeneratedCSS
|
|
492
|
+
});
|
|
493
|
+
return {
|
|
494
|
+
css: renderedCSS.css,
|
|
495
|
+
emittedGlobals: renderedCSS.emittedGlobals
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
async function createExtractedCSS(options) {
|
|
499
|
+
return (await createExtractedCSSResult(options)).css;
|
|
500
|
+
}
|
|
501
|
+
export { cleanStyleRequest, collectStylesheetDependencies, collectStylesheetDirectives, collectStylesheetDirectivesFromCSSGraph, compileRenderedStylesheet, compileStylesheet, createExtractedCSS, createExtractedCSSResult, createStyleEntryEmittedGlobals, createStylesheetDirectives, createStylesheetHostSource, findStylesheetDirectiveStatements, getNativeCSS, getScannerClasses, hasLocalStyleDirectives, hasMasterStyleEntrypoint, hasStylesheetDirectives, hasStylesheetSourceDirectives, isMasterCSSPackageStyleFile, isMasterStyleSource, isStylesheetRequest, mergeStylesheetDirectives, mergeStylesheetSourceOptions, prepareStylesheetSource, registerStylesheetSource, removeMasterStyleDirectives, removeStylesheetDirectiveStatements, removeStylesheetImports, replaceStylesheetImports, resolveMasterStyleSource, resolveStylesheetImportGraph, resolveStylesheetSourcePaths, transformLocalStylesheet };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** A final stylesheet a server-rendered page may link, as `@master/css-server` reads it. */
|
|
2
|
+
interface MasterCSSLinkedStylesheet {
|
|
3
|
+
readonly href: string;
|
|
4
|
+
readonly css: string;
|
|
5
|
+
/** Import specifiers of the listed stylesheets it imports, in order, relative to `href`. */
|
|
6
|
+
readonly imports: readonly string[];
|
|
7
|
+
}
|
|
8
|
+
/** Describes final adapter CSS and which of `stylesheetURLs` it imports. */
|
|
9
|
+
declare function describeLinkedStylesheet(css: string, href: string, stylesheetURLs?: readonly string[]): MasterCSSLinkedStylesheet;
|
|
10
|
+
export { MasterCSSLinkedStylesheet, describeLinkedStylesheet };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { analyzeCSSDependencies } from "../node-compiler.js";
|
|
2
|
+
// src/stylesheet/linked-stylesheet.ts
|
|
3
|
+
/** Describes final adapter CSS and which of `stylesheetURLs` it imports. */
|
|
4
|
+
function describeLinkedStylesheet(css, href, stylesheetURLs = []) {
|
|
5
|
+
const base = new URL(href, "https://master-css-delivery.invalid/");
|
|
6
|
+
const listed = new Set(stylesheetURLs.map((url) => new URL(url, base).href));
|
|
7
|
+
return {
|
|
8
|
+
href,
|
|
9
|
+
css,
|
|
10
|
+
imports: analyzeCSSDependencies(css).imports.map((imported) => imported.source).filter((specifier) => listed.has(new URL(specifier, base).href))
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export { describeLinkedStylesheet };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ValidationSource } from "../value-validation.js";
|
|
2
|
+
import { CSSOutputMapping } from "@master/css-schema/css-directives";
|
|
3
|
+
interface StylesheetOutputContext {
|
|
4
|
+
file: string;
|
|
5
|
+
source: string;
|
|
6
|
+
compilationFile: string;
|
|
7
|
+
sourceMap?: string;
|
|
8
|
+
graph?: {
|
|
9
|
+
sourceMappings?: CSSOutputMapping[];
|
|
10
|
+
sources: Record<string, string>;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
declare function stylesheetOutputMap(code: string, mappings: readonly CSSOutputMapping[], context: StylesheetOutputContext, mappedLength?: number): string;
|
|
14
|
+
/** The concatenation order is supplied by the owning compiler result. */
|
|
15
|
+
declare function stylesheetOutputMappings(nativeCSS: string, native?: readonly CSSOutputMapping[], generated?: readonly CSSOutputMapping[]): CSSOutputMapping[];
|
|
16
|
+
/** Exact graph copies also form the input map for structured lowering errors. */
|
|
17
|
+
declare function stylesheetInputMap(code: string, context: StylesheetOutputContext): string;
|
|
18
|
+
/** Map validation to the same authoring segments as browser devtools. */
|
|
19
|
+
declare function stylesheetValidationSource(css: string, source?: string, sourceMap?: string, mappings?: readonly CSSOutputMapping[]): ValidationSource;
|
|
20
|
+
export { StylesheetOutputContext, stylesheetInputMap, stylesheetOutputMap, stylesheetOutputMappings, stylesheetValidationSource };
|