@knighted/css 1.0.0-rc.6 → 1.0.0-rc.8
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/bin/generate-types.js +31 -0
- package/dist/cjs/css.cjs +54 -6
- package/dist/cjs/generateTypes.cjs +529 -0
- package/dist/cjs/generateTypes.d.cts +54 -0
- package/dist/cjs/loader.cjs +51 -27
- package/dist/cjs/loader.d.cts +1 -0
- package/dist/cjs/loaderInternals.cjs +38 -1
- package/dist/cjs/loaderInternals.d.cts +7 -0
- package/dist/cjs/stableNamespace.cjs +12 -0
- package/dist/cjs/stableNamespace.d.cts +3 -0
- package/dist/cjs/stableSelectorsLiteral.cjs +104 -0
- package/dist/cjs/stableSelectorsLiteral.d.cts +19 -0
- package/dist/css.js +54 -6
- package/dist/generateTypes.d.ts +54 -0
- package/dist/generateTypes.js +521 -0
- package/dist/loader.d.ts +1 -0
- package/dist/loader.js +50 -26
- package/dist/loaderInternals.d.ts +7 -0
- package/dist/loaderInternals.js +33 -0
- package/dist/stableNamespace.d.ts +3 -0
- package/dist/stableNamespace.js +8 -0
- package/dist/stableSelectorsLiteral.d.ts +19 -0
- package/dist/stableSelectorsLiteral.js +98 -0
- package/loader-queries.d.ts +34 -2
- package/package.json +19 -5
- package/types-stub/index.d.ts +5 -0
- package/types.d.ts +1 -0
package/dist/cjs/loader.cjs
CHANGED
|
@@ -4,11 +4,25 @@ exports.pitch = void 0;
|
|
|
4
4
|
const css_js_1 = require("./css.cjs");
|
|
5
5
|
const moduleInfo_js_1 = require("./moduleInfo.cjs");
|
|
6
6
|
const loaderInternals_js_1 = require("./loaderInternals.cjs");
|
|
7
|
+
const stableSelectorsLiteral_js_1 = require("./stableSelectorsLiteral.cjs");
|
|
8
|
+
const stableNamespace_js_1 = require("./stableNamespace.cjs");
|
|
7
9
|
const DEFAULT_EXPORT_NAME = 'knightedCss';
|
|
8
10
|
const loader = async function loader(source) {
|
|
9
|
-
const { cssOptions, vanillaOptions } = resolveLoaderOptions(this);
|
|
11
|
+
const { cssOptions, vanillaOptions, stableNamespace: optionNamespace, } = resolveLoaderOptions(this);
|
|
12
|
+
const resolvedNamespace = (0, stableNamespace_js_1.resolveStableNamespace)(optionNamespace);
|
|
13
|
+
const typesRequested = (0, loaderInternals_js_1.hasQueryFlag)(this.resourceQuery, loaderInternals_js_1.TYPES_QUERY_FLAG);
|
|
10
14
|
const css = await extractCss(this, cssOptions);
|
|
11
|
-
const
|
|
15
|
+
const stableSelectorsLiteral = typesRequested
|
|
16
|
+
? (0, stableSelectorsLiteral_js_1.buildStableSelectorsLiteral)({
|
|
17
|
+
css,
|
|
18
|
+
namespace: resolvedNamespace,
|
|
19
|
+
resourcePath: this.resourcePath,
|
|
20
|
+
emitWarning: message => emitKnightedWarning(this, message),
|
|
21
|
+
})
|
|
22
|
+
: undefined;
|
|
23
|
+
const injection = buildInjection(css, {
|
|
24
|
+
stableSelectorsLiteral: stableSelectorsLiteral?.literal,
|
|
25
|
+
});
|
|
12
26
|
const isStyleModule = this.resourcePath.endsWith('.css.ts');
|
|
13
27
|
if (isStyleModule) {
|
|
14
28
|
const { source: compiledSource } = await (0, css_js_1.compileVanillaModule)(this.resourcePath, cssOptions.cwd ?? this.rootContext ?? process.cwd(), cssOptions.peerResolver);
|
|
@@ -43,12 +57,14 @@ function maybeTransformVanillaModule(source, options) {
|
|
|
43
57
|
return transformVanillaModuleToEsm(source);
|
|
44
58
|
}
|
|
45
59
|
const pitch = function pitch() {
|
|
46
|
-
if (!hasCombinedQuery(this.resourceQuery)) {
|
|
60
|
+
if (!(0, loaderInternals_js_1.hasCombinedQuery)(this.resourceQuery)) {
|
|
47
61
|
return;
|
|
48
62
|
}
|
|
49
63
|
const request = buildProxyRequest(this);
|
|
50
|
-
const { cssOptions } = resolveLoaderOptions(this);
|
|
51
|
-
const
|
|
64
|
+
const { cssOptions, stableNamespace: optionNamespace } = resolveLoaderOptions(this);
|
|
65
|
+
const typesRequested = (0, loaderInternals_js_1.hasQueryFlag)(this.resourceQuery, loaderInternals_js_1.TYPES_QUERY_FLAG);
|
|
66
|
+
const resolvedNamespace = (0, stableNamespace_js_1.resolveStableNamespace)(optionNamespace);
|
|
67
|
+
const skipSyntheticDefault = (0, loaderInternals_js_1.hasNamedOnlyQueryFlag)(this.resourceQuery);
|
|
52
68
|
const defaultSignalPromise = skipSyntheticDefault
|
|
53
69
|
? Promise.resolve('unknown')
|
|
54
70
|
: (0, moduleInfo_js_1.detectModuleDefaultExport)(this.resourcePath);
|
|
@@ -58,7 +74,18 @@ const pitch = function pitch() {
|
|
|
58
74
|
skipSyntheticDefault,
|
|
59
75
|
detection: defaultSignal,
|
|
60
76
|
});
|
|
61
|
-
|
|
77
|
+
const stableSelectorsLiteral = typesRequested
|
|
78
|
+
? (0, stableSelectorsLiteral_js_1.buildStableSelectorsLiteral)({
|
|
79
|
+
css,
|
|
80
|
+
namespace: resolvedNamespace,
|
|
81
|
+
resourcePath: this.resourcePath,
|
|
82
|
+
emitWarning: message => emitKnightedWarning(this, message),
|
|
83
|
+
})
|
|
84
|
+
: undefined;
|
|
85
|
+
return createCombinedModule(request, css, {
|
|
86
|
+
emitDefault,
|
|
87
|
+
stableSelectorsLiteral: stableSelectorsLiteral?.literal,
|
|
88
|
+
});
|
|
62
89
|
});
|
|
63
90
|
};
|
|
64
91
|
exports.pitch = pitch;
|
|
@@ -66,7 +93,7 @@ loader.pitch = exports.pitch;
|
|
|
66
93
|
exports.default = loader;
|
|
67
94
|
function resolveLoaderOptions(ctx) {
|
|
68
95
|
const rawOptions = (typeof ctx.getOptions === 'function' ? ctx.getOptions() : {});
|
|
69
|
-
const { vanilla, ...rest } = rawOptions;
|
|
96
|
+
const { vanilla, stableNamespace, ...rest } = rawOptions;
|
|
70
97
|
const cssOptions = {
|
|
71
98
|
...rest,
|
|
72
99
|
cwd: rest.cwd ?? ctx.rootContext ?? process.cwd(),
|
|
@@ -74,6 +101,7 @@ function resolveLoaderOptions(ctx) {
|
|
|
74
101
|
return {
|
|
75
102
|
cssOptions,
|
|
76
103
|
vanillaOptions: vanilla,
|
|
104
|
+
stableNamespace,
|
|
77
105
|
};
|
|
78
106
|
}
|
|
79
107
|
async function extractCss(ctx, options) {
|
|
@@ -87,25 +115,12 @@ async function extractCss(ctx, options) {
|
|
|
87
115
|
function toSourceString(source) {
|
|
88
116
|
return typeof source === 'string' ? source : source.toString('utf8');
|
|
89
117
|
}
|
|
90
|
-
function buildInjection(css) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const trimmed = query.startsWith('?') ? query.slice(1) : query;
|
|
97
|
-
if (!trimmed)
|
|
98
|
-
return false;
|
|
99
|
-
return trimmed
|
|
100
|
-
.split('&')
|
|
101
|
-
.filter(Boolean)
|
|
102
|
-
.some(part => (0, loaderInternals_js_1.isQueryFlag)(part, loaderInternals_js_1.COMBINED_QUERY_FLAG));
|
|
103
|
-
}
|
|
104
|
-
function hasNamedOnlyQueryFlag(query) {
|
|
105
|
-
if (!query)
|
|
106
|
-
return false;
|
|
107
|
-
const entries = (0, loaderInternals_js_1.splitQuery)(query);
|
|
108
|
-
return entries.some(part => loaderInternals_js_1.NAMED_ONLY_QUERY_FLAGS.some(flag => (0, loaderInternals_js_1.isQueryFlag)(part, flag)));
|
|
118
|
+
function buildInjection(css, extras) {
|
|
119
|
+
const lines = [`\n\nexport const ${DEFAULT_EXPORT_NAME} = ${JSON.stringify(css)};\n`];
|
|
120
|
+
if (extras?.stableSelectorsLiteral) {
|
|
121
|
+
lines.push(extras.stableSelectorsLiteral);
|
|
122
|
+
}
|
|
123
|
+
return lines.join('');
|
|
109
124
|
}
|
|
110
125
|
function buildProxyRequest(ctx) {
|
|
111
126
|
const sanitizedQuery = (0, loaderInternals_js_1.buildSanitizedQuery)(ctx.resourceQuery);
|
|
@@ -146,6 +161,15 @@ typeof __knightedModule.default !== 'undefined'
|
|
|
146
161
|
? __knightedModule.default
|
|
147
162
|
: __knightedModule;`, 'export default __knightedDefault;');
|
|
148
163
|
}
|
|
149
|
-
lines.push(buildInjection(css));
|
|
164
|
+
lines.push(buildInjection(css, { stableSelectorsLiteral: options?.stableSelectorsLiteral }));
|
|
150
165
|
return lines.join('\n');
|
|
151
166
|
}
|
|
167
|
+
function emitKnightedWarning(ctx, message) {
|
|
168
|
+
const formatted = `\x1b[33m@knighted/css warning\x1b[0m ${message}`;
|
|
169
|
+
if (typeof ctx.emitWarning === 'function') {
|
|
170
|
+
ctx.emitWarning(new Error(formatted));
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
// eslint-disable-next-line no-console
|
|
174
|
+
console.warn(formatted);
|
|
175
|
+
}
|
package/dist/cjs/loader.d.cts
CHANGED
|
@@ -8,6 +8,7 @@ export interface KnightedCssVanillaOptions {
|
|
|
8
8
|
}
|
|
9
9
|
export interface KnightedCssLoaderOptions extends CssOptions {
|
|
10
10
|
vanilla?: KnightedCssVanillaOptions;
|
|
11
|
+
stableNamespace?: string;
|
|
11
12
|
}
|
|
12
13
|
declare const loader: LoaderDefinitionFunction<KnightedCssLoaderOptions>;
|
|
13
14
|
export declare const pitch: PitchLoaderDefinitionFunction<KnightedCssLoaderOptions>;
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.__loaderInternals = exports.NAMED_ONLY_QUERY_FLAGS = exports.COMBINED_QUERY_FLAG = void 0;
|
|
3
|
+
exports.__loaderInternals = exports.NAMED_ONLY_QUERY_FLAGS = exports.TYPES_QUERY_FLAG = exports.COMBINED_QUERY_FLAG = void 0;
|
|
4
4
|
exports.splitQuery = splitQuery;
|
|
5
5
|
exports.isQueryFlag = isQueryFlag;
|
|
6
6
|
exports.buildSanitizedQuery = buildSanitizedQuery;
|
|
7
|
+
exports.hasQueryFlag = hasQueryFlag;
|
|
7
8
|
exports.shouldForwardDefaultExport = shouldForwardDefaultExport;
|
|
9
|
+
exports.hasCombinedQuery = hasCombinedQuery;
|
|
10
|
+
exports.hasNamedOnlyQueryFlag = hasNamedOnlyQueryFlag;
|
|
11
|
+
exports.determineSelectorVariant = determineSelectorVariant;
|
|
8
12
|
exports.shouldEmitCombinedDefault = shouldEmitCombinedDefault;
|
|
9
13
|
exports.COMBINED_QUERY_FLAG = 'combined';
|
|
14
|
+
exports.TYPES_QUERY_FLAG = 'types';
|
|
10
15
|
exports.NAMED_ONLY_QUERY_FLAGS = ['named-only', 'no-default'];
|
|
11
16
|
function splitQuery(query) {
|
|
12
17
|
const trimmed = query.startsWith('?') ? query.slice(1) : query;
|
|
@@ -33,6 +38,9 @@ function buildSanitizedQuery(query) {
|
|
|
33
38
|
if (isQueryFlag(part, 'knighted-css')) {
|
|
34
39
|
return false;
|
|
35
40
|
}
|
|
41
|
+
if (isQueryFlag(part, exports.TYPES_QUERY_FLAG)) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
36
44
|
if (exports.NAMED_ONLY_QUERY_FLAGS.some(flag => isQueryFlag(part, flag))) {
|
|
37
45
|
return false;
|
|
38
46
|
}
|
|
@@ -40,6 +48,22 @@ function buildSanitizedQuery(query) {
|
|
|
40
48
|
});
|
|
41
49
|
return entries.length > 0 ? `?${entries.join('&')}` : '';
|
|
42
50
|
}
|
|
51
|
+
function hasQueryFlag(query, flag) {
|
|
52
|
+
if (!query)
|
|
53
|
+
return false;
|
|
54
|
+
const entries = splitQuery(query);
|
|
55
|
+
if (entries.length === 0)
|
|
56
|
+
return false;
|
|
57
|
+
return entries.some(part => isQueryFlag(part, flag));
|
|
58
|
+
}
|
|
59
|
+
function safeDecode(value) {
|
|
60
|
+
try {
|
|
61
|
+
return decodeURIComponent(value);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return value;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
43
67
|
function shouldForwardDefaultExport(request) {
|
|
44
68
|
const [pathPart] = request.split('?');
|
|
45
69
|
if (!pathPart)
|
|
@@ -50,6 +74,18 @@ function shouldForwardDefaultExport(request) {
|
|
|
50
74
|
}
|
|
51
75
|
return true;
|
|
52
76
|
}
|
|
77
|
+
function hasCombinedQuery(query) {
|
|
78
|
+
return hasQueryFlag(query, exports.COMBINED_QUERY_FLAG);
|
|
79
|
+
}
|
|
80
|
+
function hasNamedOnlyQueryFlag(query) {
|
|
81
|
+
return exports.NAMED_ONLY_QUERY_FLAGS.some(flag => hasQueryFlag(query, flag));
|
|
82
|
+
}
|
|
83
|
+
function determineSelectorVariant(query) {
|
|
84
|
+
if (hasCombinedQuery(query)) {
|
|
85
|
+
return hasNamedOnlyQueryFlag(query) ? 'combinedWithoutDefault' : 'combined';
|
|
86
|
+
}
|
|
87
|
+
return 'types';
|
|
88
|
+
}
|
|
53
89
|
function shouldEmitCombinedDefault(options) {
|
|
54
90
|
if (options.skipSyntheticDefault) {
|
|
55
91
|
return false;
|
|
@@ -68,4 +104,5 @@ function shouldEmitCombinedDefault(options) {
|
|
|
68
104
|
exports.__loaderInternals = {
|
|
69
105
|
buildSanitizedQuery,
|
|
70
106
|
shouldEmitCombinedDefault,
|
|
107
|
+
determineSelectorVariant,
|
|
71
108
|
};
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import type { ModuleDefaultSignal } from './moduleInfo.cjs';
|
|
2
2
|
export declare const COMBINED_QUERY_FLAG = "combined";
|
|
3
|
+
export declare const TYPES_QUERY_FLAG = "types";
|
|
3
4
|
export declare const NAMED_ONLY_QUERY_FLAGS: readonly ["named-only", "no-default"];
|
|
5
|
+
export type SelectorTypeVariant = 'types' | 'combined' | 'combinedWithoutDefault';
|
|
4
6
|
export declare function splitQuery(query: string): string[];
|
|
5
7
|
export declare function isQueryFlag(entry: string, flag: string): boolean;
|
|
6
8
|
export declare function buildSanitizedQuery(query?: string | null): string;
|
|
9
|
+
export declare function hasQueryFlag(query: string | null | undefined, flag: string): boolean;
|
|
7
10
|
export declare function shouldForwardDefaultExport(request: string): boolean;
|
|
11
|
+
export declare function hasCombinedQuery(query?: string | null): boolean;
|
|
12
|
+
export declare function hasNamedOnlyQueryFlag(query?: string | null): boolean;
|
|
13
|
+
export declare function determineSelectorVariant(query?: string | null): SelectorTypeVariant;
|
|
8
14
|
export declare function shouldEmitCombinedDefault(options: {
|
|
9
15
|
detection: ModuleDefaultSignal;
|
|
10
16
|
request: string;
|
|
@@ -13,4 +19,5 @@ export declare function shouldEmitCombinedDefault(options: {
|
|
|
13
19
|
export declare const __loaderInternals: {
|
|
14
20
|
buildSanitizedQuery: typeof buildSanitizedQuery;
|
|
15
21
|
shouldEmitCombinedDefault: typeof shouldEmitCombinedDefault;
|
|
22
|
+
determineSelectorVariant: typeof determineSelectorVariant;
|
|
16
23
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_STABLE_NAMESPACE = void 0;
|
|
4
|
+
exports.resolveStableNamespace = resolveStableNamespace;
|
|
5
|
+
const DEFAULT_STABLE_NAMESPACE = 'knighted';
|
|
6
|
+
exports.DEFAULT_STABLE_NAMESPACE = DEFAULT_STABLE_NAMESPACE;
|
|
7
|
+
function resolveStableNamespace(optionNamespace) {
|
|
8
|
+
if (typeof optionNamespace === 'string') {
|
|
9
|
+
return optionNamespace;
|
|
10
|
+
}
|
|
11
|
+
return DEFAULT_STABLE_NAMESPACE;
|
|
12
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.__stableSelectorsLiteralInternals = void 0;
|
|
4
|
+
exports.buildStableSelectorsLiteral = buildStableSelectorsLiteral;
|
|
5
|
+
exports.collectStableSelectors = collectStableSelectors;
|
|
6
|
+
exports.formatStableSelectorMap = formatStableSelectorMap;
|
|
7
|
+
const lightningcss_1 = require("lightningcss");
|
|
8
|
+
const helpers_js_1 = require("./helpers.cjs");
|
|
9
|
+
function buildStableSelectorsLiteral(options) {
|
|
10
|
+
const trimmedNamespace = options.namespace.trim();
|
|
11
|
+
if (!trimmedNamespace) {
|
|
12
|
+
options.emitWarning(`stableSelectors requested for ${options.resourcePath} but "stableNamespace" resolved to an empty value.`);
|
|
13
|
+
return {
|
|
14
|
+
literal: 'export const stableSelectors = {} as const;\n',
|
|
15
|
+
selectorMap: new Map(),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
const selectorMap = collectStableSelectors(options.css, trimmedNamespace, options.resourcePath);
|
|
19
|
+
if (selectorMap.size === 0) {
|
|
20
|
+
options.emitWarning(`stableSelectors requested for ${options.resourcePath} but no selectors matched namespace "${trimmedNamespace}".`);
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
literal: `export const stableSelectors = ${formatStableSelectorMap(selectorMap)} as const;\n`,
|
|
24
|
+
selectorMap,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function collectStableSelectors(css, namespace, filename) {
|
|
28
|
+
if (!namespace)
|
|
29
|
+
return new Map();
|
|
30
|
+
const astResult = collectStableSelectorsFromAst(css, namespace, filename);
|
|
31
|
+
if (astResult) {
|
|
32
|
+
return astResult;
|
|
33
|
+
}
|
|
34
|
+
return collectStableSelectorsByRegex(css, namespace);
|
|
35
|
+
}
|
|
36
|
+
function collectStableSelectorsFromAst(css, namespace, filename) {
|
|
37
|
+
try {
|
|
38
|
+
const tokens = new Map();
|
|
39
|
+
const escaped = (0, helpers_js_1.escapeRegex)(namespace);
|
|
40
|
+
const pattern = new RegExp(`\\.${escaped}-([A-Za-z0-9_-]+)`, 'g');
|
|
41
|
+
(0, lightningcss_1.transform)({
|
|
42
|
+
filename: filename ?? 'knighted-types-probe.css',
|
|
43
|
+
code: Buffer.from(css),
|
|
44
|
+
minify: false,
|
|
45
|
+
visitor: {
|
|
46
|
+
Rule: {
|
|
47
|
+
style(rule) {
|
|
48
|
+
const target = Array.isArray(rule?.selectors)
|
|
49
|
+
? rule
|
|
50
|
+
: rule?.value && Array.isArray(rule.value.selectors)
|
|
51
|
+
? rule.value
|
|
52
|
+
: undefined;
|
|
53
|
+
if (!target)
|
|
54
|
+
return rule;
|
|
55
|
+
for (const selector of target.selectors) {
|
|
56
|
+
const selectorStr = (0, helpers_js_1.serializeSelector)(selector);
|
|
57
|
+
pattern.lastIndex = 0;
|
|
58
|
+
let match;
|
|
59
|
+
while ((match = pattern.exec(selectorStr)) !== null) {
|
|
60
|
+
const token = match[1];
|
|
61
|
+
if (!token)
|
|
62
|
+
continue;
|
|
63
|
+
tokens.set(token, `${namespace}-${token}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return rule;
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
return tokens;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function collectStableSelectorsByRegex(css, namespace) {
|
|
78
|
+
const escaped = (0, helpers_js_1.escapeRegex)(namespace);
|
|
79
|
+
const pattern = new RegExp(`\\.${escaped}-([A-Za-z0-9_-]+)`, 'g');
|
|
80
|
+
const tokens = new Map();
|
|
81
|
+
let match;
|
|
82
|
+
while ((match = pattern.exec(css)) !== null) {
|
|
83
|
+
const token = match[1];
|
|
84
|
+
if (!token)
|
|
85
|
+
continue;
|
|
86
|
+
tokens.set(token, `${namespace}-${token}`);
|
|
87
|
+
}
|
|
88
|
+
return tokens;
|
|
89
|
+
}
|
|
90
|
+
function formatStableSelectorMap(map) {
|
|
91
|
+
if (map.size === 0) {
|
|
92
|
+
return 'Object.freeze({})';
|
|
93
|
+
}
|
|
94
|
+
const entries = Array.from(map.entries()).sort(([a], [b]) => a.localeCompare(b));
|
|
95
|
+
const lines = entries.map(([token, selector]) => {
|
|
96
|
+
return ` ${JSON.stringify(token)}: ${JSON.stringify(selector)}`;
|
|
97
|
+
});
|
|
98
|
+
return `Object.freeze({\n${lines.join(',\n')}\n})`;
|
|
99
|
+
}
|
|
100
|
+
exports.__stableSelectorsLiteralInternals = {
|
|
101
|
+
collectStableSelectors,
|
|
102
|
+
collectStableSelectorsByRegex,
|
|
103
|
+
formatStableSelectorMap,
|
|
104
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface StableSelectorsLiteralResult {
|
|
2
|
+
literal: string;
|
|
3
|
+
selectorMap: Map<string, string>;
|
|
4
|
+
}
|
|
5
|
+
export declare function buildStableSelectorsLiteral(options: {
|
|
6
|
+
css: string;
|
|
7
|
+
namespace: string;
|
|
8
|
+
resourcePath: string;
|
|
9
|
+
emitWarning: (message: string) => void;
|
|
10
|
+
}): StableSelectorsLiteralResult;
|
|
11
|
+
export declare function collectStableSelectors(css: string, namespace: string, filename?: string): Map<string, string>;
|
|
12
|
+
declare function collectStableSelectorsByRegex(css: string, namespace: string): Map<string, string>;
|
|
13
|
+
export declare function formatStableSelectorMap(map: Map<string, string>): string;
|
|
14
|
+
export declare const __stableSelectorsLiteralInternals: {
|
|
15
|
+
collectStableSelectors: typeof collectStableSelectors;
|
|
16
|
+
collectStableSelectorsByRegex: typeof collectStableSelectorsByRegex;
|
|
17
|
+
formatStableSelectorMap: typeof formatStableSelectorMap;
|
|
18
|
+
};
|
|
19
|
+
export {};
|
package/dist/css.js
CHANGED
|
@@ -119,14 +119,41 @@ async function compileStyleModule(file, { cwd, peerResolver, resolver, }) {
|
|
|
119
119
|
}
|
|
120
120
|
async function compileSass(filePath, indented, { cwd, peerResolver, resolver, }) {
|
|
121
121
|
const sassModule = await optionalPeer('sass', 'Sass', peerResolver);
|
|
122
|
-
const sass = sassModule;
|
|
122
|
+
const sass = resolveSassNamespace(sassModule);
|
|
123
123
|
const importer = createSassImporter({ cwd, resolver });
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
const loadPaths = buildSassLoadPaths(filePath);
|
|
125
|
+
if (typeof sass.compileAsync === 'function') {
|
|
126
|
+
const result = await sass.compileAsync(filePath, {
|
|
127
|
+
style: 'expanded',
|
|
128
|
+
loadPaths,
|
|
129
|
+
importers: importer ? [importer] : undefined,
|
|
130
|
+
});
|
|
131
|
+
return result.css;
|
|
132
|
+
}
|
|
133
|
+
if (typeof sass.render === 'function') {
|
|
134
|
+
return renderLegacySass(sass, filePath, indented, loadPaths);
|
|
135
|
+
}
|
|
136
|
+
throw new Error('@knighted/css: Installed "sass" package does not expose compileAsync or render APIs. Please update "sass" to a supported version.');
|
|
137
|
+
}
|
|
138
|
+
function renderLegacySass(sass, filePath, indented, loadPaths) {
|
|
139
|
+
return new Promise((resolve, reject) => {
|
|
140
|
+
sass.render({
|
|
141
|
+
file: filePath,
|
|
142
|
+
indentedSyntax: indented,
|
|
143
|
+
outputStyle: 'expanded',
|
|
144
|
+
includePaths: loadPaths,
|
|
145
|
+
}, (error, result) => {
|
|
146
|
+
if (error) {
|
|
147
|
+
reject(error);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (!result || typeof result.css === 'undefined') {
|
|
151
|
+
resolve('');
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
resolve(result.css.toString());
|
|
155
|
+
});
|
|
128
156
|
});
|
|
129
|
-
return result.css;
|
|
130
157
|
}
|
|
131
158
|
// Ensure Sass can resolve bare module specifiers by walking node_modules folders.
|
|
132
159
|
function buildSassLoadPaths(filePath) {
|
|
@@ -214,6 +241,27 @@ async function optionalPeer(name, label, loader) {
|
|
|
214
241
|
throw error;
|
|
215
242
|
}
|
|
216
243
|
}
|
|
244
|
+
function resolveSassNamespace(mod) {
|
|
245
|
+
if (isSassNamespace(mod)) {
|
|
246
|
+
return mod;
|
|
247
|
+
}
|
|
248
|
+
if (typeof mod === 'object' &&
|
|
249
|
+
mod !== null &&
|
|
250
|
+
'default' in mod) {
|
|
251
|
+
const candidate = mod.default;
|
|
252
|
+
if (isSassNamespace(candidate)) {
|
|
253
|
+
return candidate;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return mod;
|
|
257
|
+
}
|
|
258
|
+
function isSassNamespace(candidate) {
|
|
259
|
+
if (typeof candidate !== 'object' || !candidate) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
const namespace = candidate;
|
|
263
|
+
return typeof namespace.compile === 'function' || typeof namespace.render === 'function';
|
|
264
|
+
}
|
|
217
265
|
function unwrapModuleNamespace(mod) {
|
|
218
266
|
if (typeof mod === 'object' &&
|
|
219
267
|
mod !== null &&
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type SelectorTypeVariant } from './loaderInternals.js';
|
|
2
|
+
interface DeclarationRecord {
|
|
3
|
+
specifier: string;
|
|
4
|
+
filePath: string;
|
|
5
|
+
}
|
|
6
|
+
export interface GenerateTypesResult {
|
|
7
|
+
written: number;
|
|
8
|
+
removed: number;
|
|
9
|
+
declarations: DeclarationRecord[];
|
|
10
|
+
warnings: string[];
|
|
11
|
+
outDir: string;
|
|
12
|
+
typesIndexPath: string;
|
|
13
|
+
}
|
|
14
|
+
export interface GenerateTypesOptions {
|
|
15
|
+
rootDir?: string;
|
|
16
|
+
include?: string[];
|
|
17
|
+
outDir?: string;
|
|
18
|
+
typesRoot?: string;
|
|
19
|
+
stableNamespace?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function generateTypes(options?: GenerateTypesOptions): Promise<GenerateTypesResult>;
|
|
22
|
+
declare function normalizeIncludeOptions(include: string[] | undefined, rootDir: string): string[];
|
|
23
|
+
declare function stripInlineLoader(specifier: string): string;
|
|
24
|
+
declare function splitResourceAndQuery(specifier: string): {
|
|
25
|
+
resource: string;
|
|
26
|
+
query: string;
|
|
27
|
+
};
|
|
28
|
+
declare function buildDeclarationFileName(specifier: string): string;
|
|
29
|
+
declare function formatModuleDeclaration(specifier: string, variant: SelectorTypeVariant, selectors: Map<string, string>): string;
|
|
30
|
+
declare function formatSelectorType(selectors: Map<string, string>): string;
|
|
31
|
+
export declare function runGenerateTypesCli(argv?: string[]): Promise<void>;
|
|
32
|
+
export interface ParsedCliArgs {
|
|
33
|
+
rootDir: string;
|
|
34
|
+
include?: string[];
|
|
35
|
+
outDir?: string;
|
|
36
|
+
typesRoot?: string;
|
|
37
|
+
stableNamespace?: string;
|
|
38
|
+
help?: boolean;
|
|
39
|
+
}
|
|
40
|
+
declare function parseCliArgs(argv: string[]): ParsedCliArgs;
|
|
41
|
+
declare function printHelp(): void;
|
|
42
|
+
declare function reportCliResult(result: GenerateTypesResult): void;
|
|
43
|
+
export declare const __generateTypesInternals: {
|
|
44
|
+
stripInlineLoader: typeof stripInlineLoader;
|
|
45
|
+
splitResourceAndQuery: typeof splitResourceAndQuery;
|
|
46
|
+
buildDeclarationFileName: typeof buildDeclarationFileName;
|
|
47
|
+
formatModuleDeclaration: typeof formatModuleDeclaration;
|
|
48
|
+
formatSelectorType: typeof formatSelectorType;
|
|
49
|
+
normalizeIncludeOptions: typeof normalizeIncludeOptions;
|
|
50
|
+
parseCliArgs: typeof parseCliArgs;
|
|
51
|
+
printHelp: typeof printHelp;
|
|
52
|
+
reportCliResult: typeof reportCliResult;
|
|
53
|
+
};
|
|
54
|
+
export {};
|