@knighted/css 1.1.0-rc.6 → 1.1.0-rc.7

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.
@@ -6,20 +6,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.__loaderBridgeInternals = exports.pitch = void 0;
7
7
  const node_path_1 = __importDefault(require("node:path"));
8
8
  const loaderInternals_js_1 = require("./loaderInternals.cjs");
9
+ const styleGraph_js_1 = require("./styleGraph.cjs");
9
10
  const DEFAULT_EXPORT_NAME = 'knightedCss';
11
+ const BRIDGE_STYLE_EXTENSIONS = ['.css', '.scss', '.sass', '.less', '.css.ts'];
10
12
  const loader = function loader(source) {
11
13
  return source;
12
14
  };
13
15
  const pitch = function pitch(remainingRequest) {
14
16
  const resolvedRemainingRequest = resolveRemainingRequest(this, remainingRequest);
15
17
  if (isJsLikeResource(this.resourcePath) && (0, loaderInternals_js_1.hasCombinedQuery)(this.resourceQuery)) {
16
- const callback = this.async();
18
+ const callback = getAsyncCallback(this);
17
19
  if (!callback) {
18
20
  return createCombinedJsBridgeModuleSync(resolvedRemainingRequest);
19
21
  }
20
22
  readResourceSource(this)
21
- .then(source => {
22
- const cssRequests = collectCssModuleRequests(source).map(request => buildBridgeCssRequest(request));
23
+ .then(async (source) => {
24
+ const cssRequests = await collectBridgeStyleRequests(this, source);
23
25
  const upstreamRequest = buildUpstreamRequest(resolvedRemainingRequest);
24
26
  callback(null, createCombinedJsBridgeModule({
25
27
  upstreamRequest: upstreamRequest || '',
@@ -30,6 +32,33 @@ const pitch = function pitch(remainingRequest) {
30
32
  .catch(error => callback(error));
31
33
  return;
32
34
  }
35
+ const callback = getAsyncCallback(this);
36
+ if (!callback) {
37
+ const localsRequest = buildProxyRequest(this);
38
+ const upstreamRequest = buildUpstreamRequest(resolvedRemainingRequest);
39
+ const { emitCssModules } = resolveLoaderOptions(this);
40
+ const combined = (0, loaderInternals_js_1.hasCombinedQuery)(this.resourceQuery);
41
+ const skipSyntheticDefault = (0, loaderInternals_js_1.hasNamedOnlyQueryFlag)(this.resourceQuery);
42
+ if ((0, loaderInternals_js_1.hasQueryFlag)(this.resourceQuery, loaderInternals_js_1.TYPES_QUERY_FLAG)) {
43
+ emitKnightedWarning(this, 'The bridge loader does not generate stableSelectors. Remove the "types" query flag.');
44
+ }
45
+ const emitDefault = combined
46
+ ? (0, loaderInternals_js_1.shouldEmitCombinedDefault)({
47
+ detection: 'unknown',
48
+ request: localsRequest,
49
+ skipSyntheticDefault,
50
+ })
51
+ : false;
52
+ const resolvedUpstream = upstreamRequest || localsRequest;
53
+ const resolvedLocals = upstreamRequest || localsRequest;
54
+ return createBridgeModule({
55
+ localsRequest: resolvedLocals,
56
+ upstreamRequest: resolvedUpstream,
57
+ combined,
58
+ emitDefault,
59
+ emitCssModules,
60
+ });
61
+ }
33
62
  const localsRequest = buildProxyRequest(this);
34
63
  const upstreamRequest = buildUpstreamRequest(resolvedRemainingRequest);
35
64
  const { emitCssModules } = resolveLoaderOptions(this);
@@ -47,13 +76,23 @@ const pitch = function pitch(remainingRequest) {
47
76
  : false;
48
77
  const resolvedUpstream = upstreamRequest || localsRequest;
49
78
  const resolvedLocals = upstreamRequest || localsRequest;
50
- return createBridgeModule({
51
- localsRequest: resolvedLocals,
52
- upstreamRequest: resolvedUpstream,
53
- combined,
54
- emitDefault,
55
- emitCssModules,
56
- });
79
+ const collectSource = isJsLikeResource(this.resourcePath)
80
+ ? readResourceSource(this)
81
+ : Promise.resolve(undefined);
82
+ collectSource
83
+ .then(async (source) => {
84
+ const cssRequests = await collectBridgeStyleRequests(this, source);
85
+ callback(null, createBridgeModule({
86
+ localsRequest: resolvedLocals,
87
+ upstreamRequest: resolvedUpstream,
88
+ combined,
89
+ emitDefault,
90
+ emitCssModules,
91
+ cssRequests,
92
+ }));
93
+ })
94
+ .catch(error => callback(error));
95
+ return;
57
96
  };
58
97
  exports.pitch = pitch;
59
98
  loader.pitch = exports.pitch;
@@ -64,6 +103,9 @@ function resolveLoaderOptions(ctx) {
64
103
  emitCssModules: rawOptions.emitCssModules !== false,
65
104
  };
66
105
  }
106
+ function getAsyncCallback(ctx) {
107
+ return typeof ctx.async === 'function' ? ctx.async() : undefined;
108
+ }
67
109
  function readResourceSource(ctx) {
68
110
  return new Promise((resolve, reject) => {
69
111
  ctx.fs.readFile(ctx.resourcePath, (error, data) => {
@@ -79,9 +121,70 @@ function readResourceSource(ctx) {
79
121
  });
80
122
  });
81
123
  }
82
- function collectCssModuleRequests(source) {
124
+ async function collectBridgeStyleRequests(ctx, source) {
125
+ const graphImports = await collectStyleGraphImports(ctx);
126
+ const graphPaths = new Set(graphImports.map(filePath => node_path_1.default.resolve(filePath)));
127
+ const graphRequests = graphImports
128
+ .filter(filePath => node_path_1.default.resolve(filePath) !== node_path_1.default.resolve(ctx.resourcePath))
129
+ .map(filePath => buildBridgeCssRequest(filePath));
130
+ if (!source) {
131
+ return dedupeRequests(graphRequests);
132
+ }
133
+ const directSpecifiers = collectStyleImportSpecifiers(source);
134
+ const directRequests = directSpecifiers
135
+ .map(specifier => {
136
+ const [resource, query] = specifier.split('?');
137
+ if (query) {
138
+ return buildBridgeCssRequest(specifier);
139
+ }
140
+ const resolved = resolveStyleSpecifier(resource, ctx.resourcePath);
141
+ if (resolved && graphPaths.has(resolved)) {
142
+ return undefined;
143
+ }
144
+ return buildBridgeCssRequest(specifier);
145
+ })
146
+ .filter((request) => Boolean(request));
147
+ return dedupeRequests([...graphRequests, ...directRequests]);
148
+ }
149
+ async function collectStyleGraphImports(ctx) {
150
+ const cwd = ctx.rootContext ?? node_path_1.default.dirname(ctx.resourcePath);
151
+ const filter = (filePath) => !filePath.includes('node_modules');
152
+ try {
153
+ return await (0, styleGraph_js_1.collectTransitiveStyleImports)(ctx.resourcePath, {
154
+ cwd,
155
+ styleExtensions: BRIDGE_STYLE_EXTENSIONS,
156
+ filter,
157
+ });
158
+ }
159
+ catch {
160
+ return [];
161
+ }
162
+ }
163
+ function resolveStyleSpecifier(specifier, importer) {
164
+ if (!specifier)
165
+ return undefined;
166
+ if (specifier.startsWith('.')) {
167
+ return node_path_1.default.resolve(node_path_1.default.dirname(importer), specifier);
168
+ }
169
+ if (node_path_1.default.isAbsolute(specifier)) {
170
+ return node_path_1.default.resolve(specifier);
171
+ }
172
+ return undefined;
173
+ }
174
+ function dedupeRequests(requests) {
175
+ const seen = new Set();
176
+ const output = [];
177
+ for (const request of requests) {
178
+ if (seen.has(request))
179
+ continue;
180
+ seen.add(request);
181
+ output.push(request);
182
+ }
183
+ return output;
184
+ }
185
+ function collectStyleImportSpecifiers(source) {
83
186
  const matches = new Set();
84
- const importPattern = /(?:import|export)\s+(?:[^'"\n]+\s+from\s+)?['"]([^'"\n]+?\.module\.(?:css|scss|sass|less)(?:\?[^'"\n]+)?)['"]/g;
187
+ const importPattern = /(?:import|export)\s+(?:[^'"\n]+\s+from\s+)?['"]([^'"\n]+?\.(?:css|scss|sass|less|css\.ts)(?:\?[^'"\n]+)?)['"]/g;
85
188
  let match;
86
189
  while ((match = importPattern.exec(source))) {
87
190
  if (match[1]) {
@@ -112,10 +215,12 @@ function createCombinedJsBridgeModule(options) {
112
215
  const upstreamLiteral = JSON.stringify(options.upstreamRequest);
113
216
  const cssImports = options.cssRequests.map((request, index) => {
114
217
  const literal = JSON.stringify(request);
115
- return `import { knightedCss as __knightedCss${index}, knightedCssModules as __knightedCssModules${index} } from ${literal};`;
218
+ return `import * as __knightedStyle${index} from ${literal};`;
116
219
  });
117
- const cssValues = options.cssRequests.map((_, index) => `__knightedCss${index}`);
118
- const cssModulesValues = options.cssRequests.map((_, index) => `__knightedCssModules${index}`);
220
+ const cssValues = options.cssRequests.map((_, index) => `__knightedStyle${index}.knightedCss`);
221
+ const cssModulesValues = options.cssRequests.map((request, index) => isCssModuleRequest(request)
222
+ ? `__knightedStyle${index}.knightedCssModules`
223
+ : 'undefined');
119
224
  const lines = [
120
225
  `import * as __knightedUpstream from ${upstreamLiteral};`,
121
226
  ...cssImports,
@@ -194,19 +299,30 @@ function resolveCssModules(primary, module) {
194
299
  function createBridgeModule(options) {
195
300
  const localsLiteral = JSON.stringify(options.localsRequest);
196
301
  const upstreamLiteral = JSON.stringify(options.upstreamRequest);
302
+ const cssRequests = options.cssRequests ?? [];
303
+ const cssImports = cssRequests.map((request, index) => {
304
+ const literal = JSON.stringify(request);
305
+ return `import * as __knightedStyle${index} from ${literal};`;
306
+ });
307
+ const cssValues = cssRequests.map((_, index) => `__knightedStyle${index}.knightedCss`);
308
+ const cssModulesValues = cssRequests.map((request, index) => isCssModuleRequest(request)
309
+ ? `__knightedStyle${index}.knightedCssModules`
310
+ : 'undefined');
197
311
  const lines = [
198
312
  `import * as __knightedLocals from ${localsLiteral};`,
199
313
  `import * as __knightedUpstream from ${upstreamLiteral};`,
314
+ ...cssImports,
200
315
  `const __knightedDefault =\ntypeof __knightedUpstream.default !== 'undefined'\n ? __knightedUpstream.default\n : __knightedUpstream;`,
201
316
  `const __knightedResolveCss = ${resolveCssText.toString()};`,
202
317
  `const __knightedResolveCssModules = ${resolveCssModules.toString()};`,
203
318
  `const __knightedUpstreamLocals =\n __knightedResolveCssModules(__knightedUpstream, __knightedUpstream);`,
204
319
  `const __knightedLocalsExport =\n __knightedUpstreamLocals ??\n __knightedResolveCssModules(__knightedLocals, __knightedLocals) ??\n __knightedLocals;`,
205
- `const __knightedCss = __knightedResolveCss(__knightedDefault, __knightedUpstream);`,
320
+ `const __knightedBaseCss = __knightedResolveCss(__knightedDefault, __knightedUpstream);`,
321
+ `const __knightedCss = [__knightedBaseCss, ${cssValues.join(', ')}].filter(Boolean).join('\\n');`,
206
322
  `export const ${DEFAULT_EXPORT_NAME} = __knightedCss;`,
207
323
  ];
208
324
  if (options.emitCssModules) {
209
- lines.push(`const __knightedCssModules = __knightedLocalsExport ?? __knightedResolveCssModules(\n __knightedDefault,\n __knightedUpstream,\n);`, 'export const knightedCssModules = __knightedCssModules;');
325
+ lines.push(`const __knightedCssModules = Object.assign({}, ...[__knightedLocalsExport ?? __knightedResolveCssModules(\n __knightedDefault,\n __knightedUpstream,\n), ${cssModulesValues.join(', ')}].filter(Boolean));`, 'export const knightedCssModules = __knightedCssModules;');
210
326
  }
211
327
  if (options.combined) {
212
328
  lines.push(`export * from ${localsLiteral};`);
@@ -228,6 +344,11 @@ function buildUpstreamRequest(remainingRequest) {
228
344
  : `!!${remainingRequest}`;
229
345
  return request;
230
346
  }
347
+ function isCssModuleRequest(request) {
348
+ const [resource] = request.split('?');
349
+ const lower = resource.toLowerCase();
350
+ return /\.module\.(css|scss|sass|less|css\.ts)$/.test(lower);
351
+ }
231
352
  function buildProxyRequest(ctx) {
232
353
  const sanitizedQuery = (0, loaderInternals_js_1.buildSanitizedQuery)(ctx.resourceQuery);
233
354
  const rawRequest = getRawRequest(ctx);
@@ -337,7 +458,7 @@ function emitKnightedWarning(ctx, message) {
337
458
  console.warn(formatted);
338
459
  }
339
460
  exports.__loaderBridgeInternals = {
340
- collectCssModuleRequests,
461
+ collectStyleImportSpecifiers,
341
462
  buildBridgeCssRequest,
342
463
  createCombinedJsBridgeModule,
343
464
  isJsLikeResource,