@knighted/css 1.0.0-rc.0 → 1.0.0-rc.10
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 +107 -25
- package/dist/cjs/css.d.cts +10 -6
- package/dist/cjs/generateTypes.cjs +636 -0
- package/dist/cjs/generateTypes.d.cts +104 -0
- package/dist/cjs/loader.cjs +128 -56
- package/dist/cjs/loader.d.cts +5 -0
- package/dist/cjs/loaderInternals.cjs +108 -0
- package/dist/cjs/loaderInternals.d.cts +23 -0
- package/dist/cjs/moduleGraph.cjs +431 -0
- package/dist/cjs/moduleGraph.d.cts +15 -0
- package/dist/cjs/moduleInfo.cjs +62 -0
- package/dist/cjs/moduleInfo.d.cts +10 -0
- package/dist/cjs/sassInternals.cjs +135 -0
- package/dist/cjs/sassInternals.d.cts +25 -0
- package/dist/cjs/stableNamespace.cjs +12 -0
- package/dist/cjs/stableNamespace.d.cts +3 -0
- package/dist/cjs/stableSelectors.cjs +44 -0
- package/dist/cjs/stableSelectors.d.cts +13 -0
- package/dist/cjs/stableSelectorsLiteral.cjs +104 -0
- package/dist/cjs/stableSelectorsLiteral.d.cts +19 -0
- package/dist/cjs/types.cjs +2 -0
- package/dist/cjs/types.d.cts +4 -0
- package/dist/css.d.ts +10 -6
- package/dist/css.js +107 -26
- package/dist/generateTypes.d.ts +104 -0
- package/dist/generateTypes.js +628 -0
- package/dist/loader.d.ts +5 -0
- package/dist/loader.js +127 -55
- package/dist/loaderInternals.d.ts +23 -0
- package/dist/loaderInternals.js +96 -0
- package/dist/moduleGraph.d.ts +15 -0
- package/dist/moduleGraph.js +425 -0
- package/dist/moduleInfo.d.ts +10 -0
- package/dist/moduleInfo.js +55 -0
- package/dist/sassInternals.d.ts +25 -0
- package/dist/sassInternals.js +124 -0
- package/dist/stableNamespace.d.ts +3 -0
- package/dist/stableNamespace.js +8 -0
- package/dist/stableSelectors.d.ts +13 -0
- package/dist/stableSelectors.js +36 -0
- package/dist/stableSelectorsLiteral.d.ts +19 -0
- package/dist/stableSelectorsLiteral.js +98 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.js +1 -0
- package/loader-queries.d.ts +61 -0
- package/package.json +58 -8
- package/stable/_index.scss +57 -0
- package/stable/stable.css +15 -0
- package/types-stub/index.d.ts +5 -0
- package/types.d.ts +4 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.stableClassFromModule = void 0;
|
|
4
|
+
exports.stableToken = stableToken;
|
|
5
|
+
exports.stableClass = stableClass;
|
|
6
|
+
exports.stableSelector = stableSelector;
|
|
7
|
+
exports.createStableClassFactory = createStableClassFactory;
|
|
8
|
+
exports.stableClassName = stableClassName;
|
|
9
|
+
const DEFAULT_NAMESPACE = 'knighted';
|
|
10
|
+
const defaultJoin = (values) => values.filter(Boolean).join(' ');
|
|
11
|
+
const normalizeToken = (token) => {
|
|
12
|
+
const sanitized = token
|
|
13
|
+
.trim()
|
|
14
|
+
.replace(/\s+/g, '-')
|
|
15
|
+
.replace(/[^A-Za-z0-9_-]/g, '-')
|
|
16
|
+
.replace(/-+/g, '-')
|
|
17
|
+
.replace(/^-|-$/g, '');
|
|
18
|
+
return sanitized.length ? sanitized : 'stable';
|
|
19
|
+
};
|
|
20
|
+
function stableToken(token, options) {
|
|
21
|
+
const normalized = normalizeToken(token);
|
|
22
|
+
const namespace = options?.namespace?.trim() ?? DEFAULT_NAMESPACE;
|
|
23
|
+
if (!namespace) {
|
|
24
|
+
return normalized;
|
|
25
|
+
}
|
|
26
|
+
return `${namespace}-${normalized}`;
|
|
27
|
+
}
|
|
28
|
+
function stableClass(token, options) {
|
|
29
|
+
return stableToken(token, options);
|
|
30
|
+
}
|
|
31
|
+
function stableSelector(token, options) {
|
|
32
|
+
return `.${stableToken(token, options)}`;
|
|
33
|
+
}
|
|
34
|
+
function createStableClassFactory(options) {
|
|
35
|
+
return (token) => stableClass(token, options);
|
|
36
|
+
}
|
|
37
|
+
function stableClassName(styles, key, options) {
|
|
38
|
+
const hashed = styles[key] ?? '';
|
|
39
|
+
const token = options?.token ?? String(key);
|
|
40
|
+
const stable = stableClass(token, options);
|
|
41
|
+
const join = options?.join ?? defaultJoin;
|
|
42
|
+
return join([hashed, stable]);
|
|
43
|
+
}
|
|
44
|
+
exports.stableClassFromModule = stableClassName;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface StableSelectorOptions {
|
|
2
|
+
namespace?: string;
|
|
3
|
+
}
|
|
4
|
+
export interface StableClassNameOptions extends StableSelectorOptions {
|
|
5
|
+
token?: string;
|
|
6
|
+
join?: (values: string[]) => string;
|
|
7
|
+
}
|
|
8
|
+
export declare function stableToken(token: string, options?: StableSelectorOptions): string;
|
|
9
|
+
export declare function stableClass(token: string, options?: StableSelectorOptions): string;
|
|
10
|
+
export declare function stableSelector(token: string, options?: StableSelectorOptions): string;
|
|
11
|
+
export declare function createStableClassFactory(options?: StableSelectorOptions): (token: string) => string;
|
|
12
|
+
export declare function stableClassName<T extends Record<string, string>>(styles: T, key: keyof T | string, options?: StableClassNameOptions): string;
|
|
13
|
+
export declare const stableClassFromModule: typeof stableClassName;
|
|
@@ -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.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { Options as DependencyTreeOpts } from 'dependency-tree';
|
|
2
1
|
import { type TransformOptions as LightningTransformOptions } from 'lightningcss';
|
|
3
2
|
import { type SpecificitySelector, type SpecificityStrategy } from './helpers.js';
|
|
3
|
+
import type { ModuleGraphOptions } from './moduleGraph.js';
|
|
4
|
+
import type { CssResolver } from './types.js';
|
|
5
|
+
export type { CssResolver } from './types.js';
|
|
6
|
+
export type { ModuleGraphOptions } from './moduleGraph.js';
|
|
4
7
|
export declare const DEFAULT_EXTENSIONS: string[];
|
|
5
8
|
type LightningCssConfig = boolean | Partial<Omit<LightningTransformOptions<never>, 'code'>>;
|
|
6
|
-
export type CssResolver = (specifier: string, ctx: {
|
|
7
|
-
cwd: string;
|
|
8
|
-
}) => string | Promise<string | undefined>;
|
|
9
9
|
type PeerLoader = (name: string) => Promise<unknown>;
|
|
10
10
|
export interface CssOptions {
|
|
11
11
|
extensions?: string[];
|
|
@@ -17,10 +17,14 @@ export interface CssOptions {
|
|
|
17
17
|
strategy?: SpecificityStrategy;
|
|
18
18
|
match?: SpecificitySelector[];
|
|
19
19
|
};
|
|
20
|
-
|
|
20
|
+
moduleGraph?: ModuleGraphOptions;
|
|
21
21
|
resolver?: CssResolver;
|
|
22
22
|
peerResolver?: PeerLoader;
|
|
23
23
|
}
|
|
24
|
+
export interface VanillaCompileResult {
|
|
25
|
+
source: string;
|
|
26
|
+
css: string;
|
|
27
|
+
}
|
|
24
28
|
/**
|
|
25
29
|
* Extract and compile all CSS-like dependencies for a given module.
|
|
26
30
|
*/
|
|
@@ -30,4 +34,4 @@ export interface CssResult {
|
|
|
30
34
|
}
|
|
31
35
|
export declare function css(entry: string, options?: CssOptions): Promise<string>;
|
|
32
36
|
export declare function cssWithMeta(entry: string, options?: CssOptions): Promise<CssResult>;
|
|
33
|
-
export
|
|
37
|
+
export declare function compileVanillaModule(filePath: string, cwd: string, peerResolver?: PeerLoader): Promise<VanillaCompileResult>;
|
package/dist/css.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import { promises as fs } from 'node:fs';
|
|
3
|
-
import dependencyTree from 'dependency-tree';
|
|
2
|
+
import { existsSync, promises as fs } from 'node:fs';
|
|
4
3
|
import { composeVisitors, transform as lightningTransform, } from 'lightningcss';
|
|
5
4
|
import { applyStringSpecificityBoost, buildSpecificityVisitor, } from './helpers.js';
|
|
5
|
+
import { collectStyleImports } from './moduleGraph.js';
|
|
6
|
+
import { createSassImporter } from './sassInternals.js';
|
|
6
7
|
export const DEFAULT_EXTENSIONS = ['.css', '.scss', '.sass', '.less', '.css.ts'];
|
|
7
8
|
export async function css(entry, options = {}) {
|
|
8
9
|
const { css: output } = await cssWithMeta(entry, options);
|
|
@@ -12,11 +13,12 @@ export async function cssWithMeta(entry, options = {}) {
|
|
|
12
13
|
const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd();
|
|
13
14
|
const entryPath = await resolveEntry(entry, cwd, options.resolver);
|
|
14
15
|
const extensions = (options.extensions ?? DEFAULT_EXTENSIONS).map(ext => ext.toLowerCase());
|
|
15
|
-
const files = collectStyleDependencies(entryPath, {
|
|
16
|
+
const files = await collectStyleDependencies(entryPath, {
|
|
16
17
|
cwd,
|
|
17
18
|
extensions,
|
|
18
19
|
filter: options.filter,
|
|
19
|
-
|
|
20
|
+
graphOptions: options.moduleGraph,
|
|
21
|
+
resolver: options.resolver,
|
|
20
22
|
});
|
|
21
23
|
if (files.length === 0) {
|
|
22
24
|
return { css: '', files: [] };
|
|
@@ -26,6 +28,7 @@ export async function cssWithMeta(entry, options = {}) {
|
|
|
26
28
|
const chunk = await compileStyleModule(file, {
|
|
27
29
|
cwd,
|
|
28
30
|
peerResolver: options.peerResolver,
|
|
31
|
+
resolver: options.resolver,
|
|
29
32
|
});
|
|
30
33
|
if (chunk) {
|
|
31
34
|
chunks.push(chunk);
|
|
@@ -65,30 +68,33 @@ async function resolveEntry(entry, cwd, resolver) {
|
|
|
65
68
|
}
|
|
66
69
|
return path.resolve(cwd, entry);
|
|
67
70
|
}
|
|
68
|
-
function collectStyleDependencies(entryPath, { cwd, extensions, filter,
|
|
71
|
+
async function collectStyleDependencies(entryPath, { cwd, extensions, filter, graphOptions, resolver, }) {
|
|
69
72
|
const seen = new Set();
|
|
70
73
|
const order = [];
|
|
71
74
|
const shouldInclude = typeof filter === 'function'
|
|
72
75
|
? filter
|
|
73
76
|
: (filePath) => !filePath.includes('node_modules');
|
|
74
77
|
const entryIsStyle = Boolean(matchExtension(entryPath, extensions));
|
|
75
|
-
let
|
|
78
|
+
let discoveredStyles = [];
|
|
76
79
|
if (!entryIsStyle) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
directory: cwd,
|
|
80
|
+
discoveredStyles = await collectStyleImports(entryPath, {
|
|
81
|
+
cwd,
|
|
82
|
+
styleExtensions: extensions,
|
|
81
83
|
filter: shouldInclude,
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
resolver,
|
|
85
|
+
graphOptions,
|
|
86
|
+
});
|
|
84
87
|
}
|
|
85
|
-
const candidates = entryIsStyle ? [entryPath] : [entryPath, ...
|
|
88
|
+
const candidates = entryIsStyle ? [entryPath] : [entryPath, ...discoveredStyles];
|
|
86
89
|
for (const candidate of candidates) {
|
|
87
90
|
const match = matchExtension(candidate, extensions);
|
|
88
|
-
if (!match
|
|
91
|
+
if (!match)
|
|
92
|
+
continue;
|
|
93
|
+
const resolvedCandidate = path.resolve(candidate);
|
|
94
|
+
if (seen.has(resolvedCandidate))
|
|
89
95
|
continue;
|
|
90
|
-
seen.add(
|
|
91
|
-
order.push({ path:
|
|
96
|
+
seen.add(resolvedCandidate);
|
|
97
|
+
order.push({ path: resolvedCandidate, ext: match });
|
|
92
98
|
}
|
|
93
99
|
return order;
|
|
94
100
|
}
|
|
@@ -96,28 +102,79 @@ function matchExtension(filePath, extensions) {
|
|
|
96
102
|
const lower = filePath.toLowerCase();
|
|
97
103
|
return extensions.find(ext => lower.endsWith(ext));
|
|
98
104
|
}
|
|
99
|
-
async function compileStyleModule(file, { cwd, peerResolver }) {
|
|
105
|
+
async function compileStyleModule(file, { cwd, peerResolver, resolver, }) {
|
|
100
106
|
switch (file.ext) {
|
|
101
107
|
case '.css':
|
|
102
108
|
return fs.readFile(file.path, 'utf8');
|
|
103
109
|
case '.scss':
|
|
104
110
|
case '.sass':
|
|
105
|
-
return compileSass(file.path, file.ext === '.sass',
|
|
111
|
+
return compileSass(file.path, file.ext === '.sass', {
|
|
112
|
+
cwd,
|
|
113
|
+
peerResolver,
|
|
114
|
+
resolver,
|
|
115
|
+
});
|
|
106
116
|
case '.less':
|
|
107
117
|
return compileLess(file.path, peerResolver);
|
|
108
118
|
case '.css.ts':
|
|
109
|
-
return
|
|
119
|
+
return (await compileVanillaModule(file.path, cwd, peerResolver)).css;
|
|
110
120
|
default:
|
|
111
121
|
return '';
|
|
112
122
|
}
|
|
113
123
|
}
|
|
114
|
-
async function compileSass(filePath, indented, peerResolver) {
|
|
124
|
+
async function compileSass(filePath, indented, { cwd, peerResolver, resolver, }) {
|
|
115
125
|
const sassModule = await optionalPeer('sass', 'Sass', peerResolver);
|
|
116
|
-
const sass = sassModule;
|
|
117
|
-
const
|
|
118
|
-
|
|
126
|
+
const sass = resolveSassNamespace(sassModule);
|
|
127
|
+
const importer = createSassImporter({ cwd, resolver });
|
|
128
|
+
const loadPaths = buildSassLoadPaths(filePath);
|
|
129
|
+
if (typeof sass.compileAsync === 'function') {
|
|
130
|
+
const result = await sass.compileAsync(filePath, {
|
|
131
|
+
style: 'expanded',
|
|
132
|
+
loadPaths,
|
|
133
|
+
importers: importer ? [importer] : undefined,
|
|
134
|
+
});
|
|
135
|
+
return result.css;
|
|
136
|
+
}
|
|
137
|
+
if (typeof sass.render === 'function') {
|
|
138
|
+
return renderLegacySass(sass, filePath, indented, loadPaths);
|
|
139
|
+
}
|
|
140
|
+
throw new Error('@knighted/css: Installed "sass" package does not expose compileAsync or render APIs. Please update "sass" to a supported version.');
|
|
141
|
+
}
|
|
142
|
+
function renderLegacySass(sass, filePath, indented, loadPaths) {
|
|
143
|
+
return new Promise((resolve, reject) => {
|
|
144
|
+
sass.render({
|
|
145
|
+
file: filePath,
|
|
146
|
+
indentedSyntax: indented,
|
|
147
|
+
outputStyle: 'expanded',
|
|
148
|
+
includePaths: loadPaths,
|
|
149
|
+
}, (error, result) => {
|
|
150
|
+
if (error) {
|
|
151
|
+
reject(error);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (!result || typeof result.css === 'undefined') {
|
|
155
|
+
resolve('');
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
resolve(result.css.toString());
|
|
159
|
+
});
|
|
119
160
|
});
|
|
120
|
-
|
|
161
|
+
}
|
|
162
|
+
// Ensure Sass can resolve bare module specifiers by walking node_modules folders.
|
|
163
|
+
function buildSassLoadPaths(filePath) {
|
|
164
|
+
const loadPaths = new Set();
|
|
165
|
+
let cursor = path.dirname(filePath);
|
|
166
|
+
const root = path.parse(cursor).root;
|
|
167
|
+
while (true) {
|
|
168
|
+
loadPaths.add(cursor);
|
|
169
|
+
loadPaths.add(path.join(cursor, 'node_modules'));
|
|
170
|
+
if (cursor === root)
|
|
171
|
+
break;
|
|
172
|
+
cursor = path.dirname(cursor);
|
|
173
|
+
}
|
|
174
|
+
const cwd = process.cwd();
|
|
175
|
+
loadPaths.add(cwd);
|
|
176
|
+
loadPaths.add(path.join(cwd, 'node_modules'));
|
|
177
|
+
return Array.from(loadPaths).filter(dir => dir && existsSync(dir));
|
|
121
178
|
}
|
|
122
179
|
async function compileLess(filePath, peerResolver) {
|
|
123
180
|
const mod = await optionalPeer('less', 'Less', peerResolver);
|
|
@@ -126,7 +183,7 @@ async function compileLess(filePath, peerResolver) {
|
|
|
126
183
|
const result = await less.render(source, { filename: filePath });
|
|
127
184
|
return result.css;
|
|
128
185
|
}
|
|
129
|
-
async function
|
|
186
|
+
export async function compileVanillaModule(filePath, cwd, peerResolver) {
|
|
130
187
|
const mod = await optionalPeer('@vanilla-extract/integration', 'Vanilla Extract', peerResolver);
|
|
131
188
|
const namespace = unwrapModuleNamespace(mod);
|
|
132
189
|
const compileFn = namespace.compile;
|
|
@@ -166,7 +223,10 @@ async function compileVanillaExtract(filePath, cwd, peerResolver) {
|
|
|
166
223
|
imports.push(virtualFile.source);
|
|
167
224
|
}
|
|
168
225
|
}
|
|
169
|
-
return
|
|
226
|
+
return {
|
|
227
|
+
source,
|
|
228
|
+
css: imports.join('\n'),
|
|
229
|
+
};
|
|
170
230
|
}
|
|
171
231
|
const defaultPeerLoader = name => import(name);
|
|
172
232
|
async function optionalPeer(name, label, loader) {
|
|
@@ -185,6 +245,27 @@ async function optionalPeer(name, label, loader) {
|
|
|
185
245
|
throw error;
|
|
186
246
|
}
|
|
187
247
|
}
|
|
248
|
+
function resolveSassNamespace(mod) {
|
|
249
|
+
if (isSassNamespace(mod)) {
|
|
250
|
+
return mod;
|
|
251
|
+
}
|
|
252
|
+
if (typeof mod === 'object' &&
|
|
253
|
+
mod !== null &&
|
|
254
|
+
'default' in mod) {
|
|
255
|
+
const candidate = mod.default;
|
|
256
|
+
if (isSassNamespace(candidate)) {
|
|
257
|
+
return candidate;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return mod;
|
|
261
|
+
}
|
|
262
|
+
function isSassNamespace(candidate) {
|
|
263
|
+
if (typeof candidate !== 'object' || !candidate) {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
const namespace = candidate;
|
|
267
|
+
return typeof namespace.compile === 'function' || typeof namespace.render === 'function';
|
|
268
|
+
}
|
|
188
269
|
function unwrapModuleNamespace(mod) {
|
|
189
270
|
if (typeof mod === 'object' &&
|
|
190
271
|
mod !== null &&
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { moduleType } from 'node-module-type';
|
|
3
|
+
import { getTsconfig } from 'get-tsconfig';
|
|
4
|
+
import { type MatchPath } from 'tsconfig-paths';
|
|
5
|
+
import { cssWithMeta } from './css.js';
|
|
6
|
+
import { type SelectorTypeVariant } from './loaderInternals.js';
|
|
7
|
+
interface ManifestEntry {
|
|
8
|
+
file: string;
|
|
9
|
+
hash: string;
|
|
10
|
+
}
|
|
11
|
+
type Manifest = Record<string, ManifestEntry>;
|
|
12
|
+
interface ImportMatch {
|
|
13
|
+
specifier: string;
|
|
14
|
+
importer: string;
|
|
15
|
+
}
|
|
16
|
+
interface DeclarationRecord {
|
|
17
|
+
specifier: string;
|
|
18
|
+
filePath: string;
|
|
19
|
+
}
|
|
20
|
+
interface TsconfigResolutionContext {
|
|
21
|
+
absoluteBaseUrl?: string;
|
|
22
|
+
matchPath?: MatchPath;
|
|
23
|
+
}
|
|
24
|
+
type CssWithMetaFn = typeof cssWithMeta;
|
|
25
|
+
export interface GenerateTypesResult {
|
|
26
|
+
written: number;
|
|
27
|
+
removed: number;
|
|
28
|
+
declarations: DeclarationRecord[];
|
|
29
|
+
warnings: string[];
|
|
30
|
+
outDir: string;
|
|
31
|
+
typesIndexPath: string;
|
|
32
|
+
}
|
|
33
|
+
export interface GenerateTypesOptions {
|
|
34
|
+
rootDir?: string;
|
|
35
|
+
include?: string[];
|
|
36
|
+
outDir?: string;
|
|
37
|
+
typesRoot?: string;
|
|
38
|
+
stableNamespace?: string;
|
|
39
|
+
}
|
|
40
|
+
type ModuleTypeDetector = () => ReturnType<typeof moduleType>;
|
|
41
|
+
declare function resolvePackageRoot(): string;
|
|
42
|
+
export declare function generateTypes(options?: GenerateTypesOptions): Promise<GenerateTypesResult>;
|
|
43
|
+
declare function normalizeIncludeOptions(include: string[] | undefined, rootDir: string): string[];
|
|
44
|
+
declare function collectCandidateFiles(entries: string[]): Promise<string[]>;
|
|
45
|
+
declare function findSpecifierImports(filePath: string): Promise<ImportMatch[]>;
|
|
46
|
+
declare function stripInlineLoader(specifier: string): string;
|
|
47
|
+
declare function splitResourceAndQuery(specifier: string): {
|
|
48
|
+
resource: string;
|
|
49
|
+
query: string;
|
|
50
|
+
};
|
|
51
|
+
declare function resolveImportPath(resourceSpecifier: string, importerPath: string, rootDir: string, tsconfig?: TsconfigResolutionContext): Promise<string | undefined>;
|
|
52
|
+
declare function buildDeclarationFileName(specifier: string): string;
|
|
53
|
+
declare function formatModuleDeclaration(specifier: string, variant: SelectorTypeVariant, selectors: Map<string, string>): string;
|
|
54
|
+
declare function formatSelectorType(selectors: Map<string, string>): string;
|
|
55
|
+
declare function writeTypesIndex(indexPath: string, manifest: Manifest, outDir: string): Promise<void>;
|
|
56
|
+
declare function relativeToRoot(filePath: string, rootDir: string): string;
|
|
57
|
+
declare function resolveWithTsconfigPaths(specifier: string, tsconfig?: TsconfigResolutionContext): Promise<string | undefined>;
|
|
58
|
+
declare function loadTsconfigResolutionContext(rootDir: string, loader?: typeof getTsconfig): TsconfigResolutionContext | undefined;
|
|
59
|
+
declare function normalizeTsconfigPaths(paths: Record<string, string[] | string> | undefined): Record<string, string[]> | undefined;
|
|
60
|
+
declare function isNonRelativeSpecifier(specifier: string): boolean;
|
|
61
|
+
declare function createProjectPeerResolver(rootDir: string): (name: string) => Promise<any>;
|
|
62
|
+
declare function getProjectRequire(rootDir: string): ReturnType<typeof createRequire>;
|
|
63
|
+
export declare function runGenerateTypesCli(argv?: string[]): Promise<void>;
|
|
64
|
+
export interface ParsedCliArgs {
|
|
65
|
+
rootDir: string;
|
|
66
|
+
include?: string[];
|
|
67
|
+
outDir?: string;
|
|
68
|
+
typesRoot?: string;
|
|
69
|
+
stableNamespace?: string;
|
|
70
|
+
help?: boolean;
|
|
71
|
+
}
|
|
72
|
+
declare function parseCliArgs(argv: string[]): ParsedCliArgs;
|
|
73
|
+
declare function printHelp(): void;
|
|
74
|
+
declare function reportCliResult(result: GenerateTypesResult): void;
|
|
75
|
+
declare function setCssWithMetaImplementation(impl?: CssWithMetaFn): void;
|
|
76
|
+
declare function setModuleTypeDetector(detector?: ModuleTypeDetector): void;
|
|
77
|
+
declare function setImportMetaUrlProvider(provider?: () => string | undefined): void;
|
|
78
|
+
export declare const __generateTypesInternals: {
|
|
79
|
+
writeTypesIndex: typeof writeTypesIndex;
|
|
80
|
+
stripInlineLoader: typeof stripInlineLoader;
|
|
81
|
+
splitResourceAndQuery: typeof splitResourceAndQuery;
|
|
82
|
+
findSpecifierImports: typeof findSpecifierImports;
|
|
83
|
+
resolveImportPath: typeof resolveImportPath;
|
|
84
|
+
resolvePackageRoot: typeof resolvePackageRoot;
|
|
85
|
+
buildDeclarationFileName: typeof buildDeclarationFileName;
|
|
86
|
+
formatModuleDeclaration: typeof formatModuleDeclaration;
|
|
87
|
+
formatSelectorType: typeof formatSelectorType;
|
|
88
|
+
relativeToRoot: typeof relativeToRoot;
|
|
89
|
+
collectCandidateFiles: typeof collectCandidateFiles;
|
|
90
|
+
normalizeIncludeOptions: typeof normalizeIncludeOptions;
|
|
91
|
+
normalizeTsconfigPaths: typeof normalizeTsconfigPaths;
|
|
92
|
+
setCssWithMetaImplementation: typeof setCssWithMetaImplementation;
|
|
93
|
+
setModuleTypeDetector: typeof setModuleTypeDetector;
|
|
94
|
+
setImportMetaUrlProvider: typeof setImportMetaUrlProvider;
|
|
95
|
+
isNonRelativeSpecifier: typeof isNonRelativeSpecifier;
|
|
96
|
+
createProjectPeerResolver: typeof createProjectPeerResolver;
|
|
97
|
+
getProjectRequire: typeof getProjectRequire;
|
|
98
|
+
loadTsconfigResolutionContext: typeof loadTsconfigResolutionContext;
|
|
99
|
+
resolveWithTsconfigPaths: typeof resolveWithTsconfigPaths;
|
|
100
|
+
parseCliArgs: typeof parseCliArgs;
|
|
101
|
+
printHelp: typeof printHelp;
|
|
102
|
+
reportCliResult: typeof reportCliResult;
|
|
103
|
+
};
|
|
104
|
+
export {};
|