auklet 0.0.3 → 0.0.5
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 +99 -42
- package/bin/entry.cjs +33 -11
- package/dist/build/runTsdown.js +2 -3
- package/dist/build/tsdownConfig.d.ts +138 -2
- package/dist/build/tsdownConfig.js +108 -63
- package/dist/config.d.ts +38 -6
- package/dist/config.js +43 -7
- package/dist/configLoader.js +1 -2
- package/dist/css/config.d.ts +2 -0
- package/dist/css/config.js +10 -0
- package/dist/css/constants.d.ts +7 -0
- package/dist/css/constants.js +7 -0
- package/dist/css/core/moduleGraph.d.ts +55 -0
- package/dist/css/core/moduleGraph.js +363 -0
- package/dist/css/core/moduleGraphRequestCache.d.ts +80 -0
- package/dist/css/core/moduleGraphRequestCache.js +92 -0
- package/dist/css/core/style/dependencies.d.ts +20 -0
- package/dist/css/core/style/dependencies.js +55 -0
- package/dist/css/core/style/files.d.ts +8 -0
- package/dist/css/core/style/files.js +19 -0
- package/dist/css/core/style/plan.d.ts +59 -0
- package/dist/css/core/style/plan.js +27 -0
- package/dist/css/core/style/specifier.d.ts +14 -0
- package/dist/css/core/style/specifier.js +27 -0
- package/dist/css/core/{moduleStyleImportCollector.d.ts → styleImports/collector.d.ts} +5 -5
- package/dist/css/core/{moduleStyleImportCollector.js → styleImports/collector.js} +36 -99
- package/dist/css/core/styleImports/sourceReference.d.ts +19 -0
- package/dist/css/core/styleImports/sourceReference.js +193 -0
- package/dist/css/core/styleModuleEntryPlanner.d.ts +29 -0
- package/dist/css/core/styleModuleEntryPlanner.js +67 -0
- package/dist/css/core/stylePackageContext.d.ts +27 -0
- package/dist/css/core/stylePackageContext.js +57 -0
- package/dist/css/core/styleProcessor.d.ts +3 -3
- package/dist/css/core/styleProcessor.js +18 -35
- package/dist/css/core/workspaceStyleResolver.d.ts +4 -5
- package/dist/css/core/workspaceStyleResolver.js +12 -28
- package/dist/css/production/builder.d.ts +18 -0
- package/dist/css/production/builder.js +68 -0
- package/dist/css/production/format/componentWriter.d.ts +12 -0
- package/dist/css/production/format/componentWriter.js +67 -0
- package/dist/css/production/format/entryWriter.d.ts +12 -0
- package/dist/css/production/format/entryWriter.js +54 -0
- package/dist/css/production/format/externalWriter.d.ts +9 -0
- package/dist/css/production/format/externalWriter.js +39 -0
- package/dist/css/production/format/moduleWriter.d.ts +8 -0
- package/dist/css/production/format/moduleWriter.js +31 -0
- package/dist/css/production/format/shared.d.ts +20 -0
- package/dist/css/production/format/shared.js +8 -0
- package/dist/css/production/format/sourceWriter.d.ts +6 -0
- package/dist/css/production/format/sourceWriter.js +16 -0
- package/dist/css/production/format/themeWriter.d.ts +16 -0
- package/dist/css/production/format/themeWriter.js +80 -0
- package/dist/css/production/moduleOutputWriter.d.ts +26 -0
- package/dist/css/production/moduleOutputWriter.js +83 -0
- package/dist/css/production/packageEntryWriter.d.ts +20 -0
- package/dist/css/production/packageEntryWriter.js +55 -0
- package/dist/css/vite/hmr.d.ts +4 -4
- package/dist/css/vite/hmr.js +14 -27
- package/dist/css/vite/vitePlugin.d.ts +5 -5
- package/dist/css/vite/vitePlugin.js +21 -30
- package/dist/css/watch/{moduleCssWatcher.d.ts → watcher.d.ts} +8 -4
- package/dist/css/watch/watcher.js +91 -0
- package/dist/index.d.ts +15 -12
- package/dist/index.js +6 -5
- package/dist/types.d.ts +40 -20
- package/dist/utils.d.ts +5 -1
- package/dist/utils.js +37 -12
- package/package.json +19 -14
- package/dist/css/core/config.d.ts +0 -2
- package/dist/css/core/config.js +0 -11
- package/dist/css/core/constants.d.ts +0 -3
- package/dist/css/core/constants.js +0 -3
- package/dist/css/core/moduleCssGraph.d.ts +0 -51
- package/dist/css/core/moduleCssGraph.js +0 -416
- package/dist/css/core/path.d.ts +0 -4
- package/dist/css/core/path.js +0 -26
- package/dist/css/core/styleEntry.d.ts +0 -45
- package/dist/css/core/styleEntry.js +0 -108
- package/dist/css/production/moduleCssBuilder.d.ts +0 -33
- package/dist/css/production/moduleCssBuilder.js +0 -445
- package/dist/css/watch/moduleCssWatcher.js +0 -106
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getExternalStyleDependencies,
|
|
3
|
+
getGlobalStyleDependencies,
|
|
4
|
+
getThemeNames,
|
|
5
|
+
getThemeStyleDependencies,
|
|
6
|
+
} from '#auklet/css/core/style/dependencies';
|
|
7
|
+
const dependenciesPart = (specifiers) => ({ type: 'dependencies', specifiers });
|
|
8
|
+
export function createStyleEntryParts(config) {
|
|
9
|
+
return [
|
|
10
|
+
dependenciesPart(getGlobalStyleDependencies(config)),
|
|
11
|
+
{ type: 'themes', themeNames: getThemeNames(config) },
|
|
12
|
+
{ type: 'module' },
|
|
13
|
+
];
|
|
14
|
+
}
|
|
15
|
+
export function createThemeEntryParts(config, themeName, options = {}) {
|
|
16
|
+
const themePart = { type: 'theme', themeName };
|
|
17
|
+
if (options.includeDependencies === false) {
|
|
18
|
+
return [themePart];
|
|
19
|
+
}
|
|
20
|
+
return [
|
|
21
|
+
dependenciesPart(getThemeStyleDependencies(config, themeName)),
|
|
22
|
+
themePart,
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
export function createExternalEntryParts(config) {
|
|
26
|
+
return [dependenciesPart(getExternalStyleDependencies(config))];
|
|
27
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type PackageStyleSpecifier = {
|
|
2
|
+
packageName: string;
|
|
3
|
+
stylePath: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function parsePackageStyleSpecifier(specifier: string): {
|
|
6
|
+
packageName: string;
|
|
7
|
+
stylePath: string;
|
|
8
|
+
} | null;
|
|
9
|
+
export declare function joinDependencySpecifier(
|
|
10
|
+
packageName: string,
|
|
11
|
+
dependencyPath: string,
|
|
12
|
+
): string;
|
|
13
|
+
export declare function createImportCode(specifiers: Array<string>): string;
|
|
14
|
+
export declare function removeStyleExtension(stylePath: string): string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
export function parsePackageStyleSpecifier(specifier) {
|
|
3
|
+
if (specifier.startsWith('.')) return null;
|
|
4
|
+
const parts = specifier.split('/');
|
|
5
|
+
const packageName = specifier.startsWith('@')
|
|
6
|
+
? `${parts.shift() ?? ''}/${parts.shift() ?? ''}`
|
|
7
|
+
: parts.shift() ?? '';
|
|
8
|
+
if (!packageName) return null;
|
|
9
|
+
return {
|
|
10
|
+
packageName,
|
|
11
|
+
stylePath: parts.join('/'),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function joinDependencySpecifier(packageName, dependencyPath) {
|
|
15
|
+
if (!dependencyPath) return packageName;
|
|
16
|
+
return dependencyPath.startsWith('/')
|
|
17
|
+
? `${packageName}${dependencyPath}`
|
|
18
|
+
: `${packageName}/${dependencyPath}`;
|
|
19
|
+
}
|
|
20
|
+
export function createImportCode(specifiers) {
|
|
21
|
+
return Array.from(new Set(specifiers))
|
|
22
|
+
.map((specifier) => `@import "${specifier}";`)
|
|
23
|
+
.join('\n');
|
|
24
|
+
}
|
|
25
|
+
export function removeStyleExtension(stylePath) {
|
|
26
|
+
return stylePath.slice(0, -path.extname(stylePath).length);
|
|
27
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { NormalizedAukletConfig } from '#auklet/types';
|
|
2
2
|
import type { WorkspaceStyleResolver } from '#auklet/css/core/workspaceStyleResolver';
|
|
3
3
|
export declare class ModuleStyleImportCollector {
|
|
4
4
|
private readonly srcRoot;
|
|
@@ -12,8 +12,10 @@ export declare class ModuleStyleImportCollector {
|
|
|
12
12
|
resolver: WorkspaceStyleResolver,
|
|
13
13
|
styleExtensions?: Array<string>,
|
|
14
14
|
);
|
|
15
|
-
collect(
|
|
16
|
-
|
|
15
|
+
collect(
|
|
16
|
+
files: Array<string>,
|
|
17
|
+
config: NormalizedAukletConfig,
|
|
18
|
+
): Map<string, string[]>;
|
|
17
19
|
private collectSourceImportStyle;
|
|
18
20
|
private resolveSourceImportStyleEntry;
|
|
19
21
|
private resolveSourceImportPath;
|
|
@@ -24,6 +26,4 @@ export declare class ModuleStyleImportCollector {
|
|
|
24
26
|
private getImportPathValues;
|
|
25
27
|
private createStyleSpecifier;
|
|
26
28
|
private createDirectStyleSpecifier;
|
|
27
|
-
private joinDependencySpecifier;
|
|
28
|
-
private getImportedNames;
|
|
29
29
|
}
|
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import ts from 'typescript';
|
|
4
3
|
import { isArray } from 'aidly';
|
|
4
|
+
import { SOURCE_COMPONENT_MODULE_RE } from '#auklet/css/constants';
|
|
5
|
+
import { joinDependencySpecifier } from '#auklet/css/core/style/specifier';
|
|
5
6
|
import {
|
|
6
7
|
appendUniqueMapValue,
|
|
7
8
|
getSourceModuleDir,
|
|
8
|
-
SOURCE_DECLARATION_RE,
|
|
9
9
|
POSIX_SEPARATOR,
|
|
10
|
-
SOURCE_MODULE_RE,
|
|
11
10
|
} from '#auklet/utils';
|
|
11
|
+
import {
|
|
12
|
+
collectModuleStyleSourceReferences,
|
|
13
|
+
getSourceReferenceImportedNames,
|
|
14
|
+
isTypeOnlySourceReference,
|
|
15
|
+
} from '#auklet/css/core/styleImports/sourceReference';
|
|
12
16
|
const GLOBSTAR_TOKEN = '**';
|
|
13
17
|
export class ModuleStyleImportCollector {
|
|
18
|
+
srcRoot;
|
|
19
|
+
packageRoot;
|
|
20
|
+
resolver;
|
|
21
|
+
styleExtensions;
|
|
22
|
+
sourceImportAliasRules;
|
|
14
23
|
constructor(srcRoot, packageRoot, resolver, styleExtensions = ['.css']) {
|
|
15
24
|
this.srcRoot = srcRoot;
|
|
16
25
|
this.packageRoot = packageRoot;
|
|
@@ -18,18 +27,18 @@ export class ModuleStyleImportCollector {
|
|
|
18
27
|
this.styleExtensions = styleExtensions;
|
|
19
28
|
this.sourceImportAliasRules = this.createSourceImportAliasRules();
|
|
20
29
|
}
|
|
21
|
-
collect(files,
|
|
30
|
+
collect(files, config) {
|
|
22
31
|
const entries = new Map();
|
|
23
|
-
const rules = this.createAutoImportRules(
|
|
32
|
+
const rules = this.createAutoImportRules(config);
|
|
24
33
|
for (const file of files) {
|
|
25
|
-
if (!
|
|
34
|
+
if (!SOURCE_COMPONENT_MODULE_RE.test(file)) {
|
|
26
35
|
continue;
|
|
27
36
|
}
|
|
28
37
|
const sourceRelative = path.relative(this.srcRoot, file);
|
|
29
38
|
const sourceDir = path.dirname(sourceRelative);
|
|
30
39
|
const sourceModuleDir = getSourceModuleDir(sourceRelative);
|
|
31
40
|
const code = fs.readFileSync(file, 'utf8');
|
|
32
|
-
const imports =
|
|
41
|
+
const imports = collectModuleStyleSourceReferences(file, code);
|
|
33
42
|
for (const item of imports) {
|
|
34
43
|
this.collectSourceImportStyle(
|
|
35
44
|
entries,
|
|
@@ -37,14 +46,17 @@ export class ModuleStyleImportCollector {
|
|
|
37
46
|
sourceModuleDir,
|
|
38
47
|
item,
|
|
39
48
|
);
|
|
49
|
+
if (isTypeOnlySourceReference(item)) continue;
|
|
40
50
|
const importPath = item.importPath;
|
|
41
51
|
const ruleMatches = this.matchAutoImportRules(rules, importPath);
|
|
42
52
|
if (!ruleMatches.length) continue;
|
|
43
|
-
const directSpecifiers = ruleMatches
|
|
44
|
-
.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
const directSpecifiers = ruleMatches.flatMap((ruleMatch) => {
|
|
54
|
+
const specifier = this.createDirectStyleSpecifier(
|
|
55
|
+
ruleMatch.rule,
|
|
56
|
+
importPath,
|
|
57
|
+
);
|
|
58
|
+
return specifier ? [specifier] : [];
|
|
59
|
+
});
|
|
48
60
|
if (directSpecifiers.length) {
|
|
49
61
|
for (const specifier of directSpecifiers) {
|
|
50
62
|
const cssFile = this.resolver.resolveStyleDependency(specifier);
|
|
@@ -55,7 +67,7 @@ export class ModuleStyleImportCollector {
|
|
|
55
67
|
continue;
|
|
56
68
|
}
|
|
57
69
|
for (const ruleMatch of ruleMatches) {
|
|
58
|
-
const importedNames =
|
|
70
|
+
const importedNames = getSourceReferenceImportedNames(file, item);
|
|
59
71
|
for (const importedName of importedNames) {
|
|
60
72
|
const specifier = this.createStyleSpecifier(
|
|
61
73
|
ruleMatch.rule,
|
|
@@ -73,37 +85,8 @@ export class ModuleStyleImportCollector {
|
|
|
73
85
|
}
|
|
74
86
|
return entries;
|
|
75
87
|
}
|
|
76
|
-
getImportDeclarations(file, code) {
|
|
77
|
-
const imports = [];
|
|
78
|
-
const sourceFile = ts.createSourceFile(
|
|
79
|
-
file,
|
|
80
|
-
code,
|
|
81
|
-
ts.ScriptTarget.Latest,
|
|
82
|
-
false,
|
|
83
|
-
file.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS,
|
|
84
|
-
);
|
|
85
|
-
sourceFile.forEachChild((node) => {
|
|
86
|
-
if (
|
|
87
|
-
!ts.isImportDeclaration(node) ||
|
|
88
|
-
!ts.isStringLiteral(node.moduleSpecifier)
|
|
89
|
-
) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
imports.push({
|
|
93
|
-
importPath: node.moduleSpecifier.text,
|
|
94
|
-
importClause: node.importClause,
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
return imports;
|
|
98
|
-
}
|
|
99
88
|
collectSourceImportStyle(entries, sourceDir, sourceModuleDir, item) {
|
|
100
|
-
|
|
101
|
-
if (
|
|
102
|
-
(_a = item.importClause) === null || _a === void 0
|
|
103
|
-
? void 0
|
|
104
|
-
: _a.isTypeOnly
|
|
105
|
-
)
|
|
106
|
-
return;
|
|
89
|
+
if (isTypeOnlySourceReference(item)) return;
|
|
107
90
|
const importedStyleEntry = this.resolveSourceImportStyleEntry(
|
|
108
91
|
sourceDir,
|
|
109
92
|
item.importPath,
|
|
@@ -145,14 +128,11 @@ export class ModuleStyleImportCollector {
|
|
|
145
128
|
return null;
|
|
146
129
|
}
|
|
147
130
|
createSourceImportAliasRules() {
|
|
148
|
-
var _a;
|
|
149
131
|
const packageJsonPath = path.join(this.packageRoot, 'package.json');
|
|
150
132
|
if (!fs.existsSync(packageJsonPath)) return [];
|
|
151
133
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
152
134
|
const rules = [];
|
|
153
|
-
for (const [name, target] of Object.entries(
|
|
154
|
-
(_a = packageJson.imports) !== null && _a !== void 0 ? _a : {},
|
|
155
|
-
)) {
|
|
135
|
+
for (const [name, target] of Object.entries(packageJson.imports ?? {})) {
|
|
156
136
|
if (
|
|
157
137
|
!name.endsWith(`${POSIX_SEPARATOR}*`) ||
|
|
158
138
|
typeof target !== 'string' ||
|
|
@@ -170,22 +150,20 @@ export class ModuleStyleImportCollector {
|
|
|
170
150
|
const relative = path.relative(fromDir, file).split(path.sep).join('/');
|
|
171
151
|
return relative.startsWith('.') ? relative : `./${relative}`;
|
|
172
152
|
}
|
|
173
|
-
createAutoImportRules(
|
|
174
|
-
var _a;
|
|
153
|
+
createAutoImportRules(config) {
|
|
175
154
|
const rules = [];
|
|
176
155
|
for (const [packageName, dependency] of Object.entries(
|
|
177
|
-
|
|
156
|
+
config.styles.dependencies,
|
|
178
157
|
)) {
|
|
179
|
-
const dependencyPaths = isArray(dependency.
|
|
180
|
-
? dependency.
|
|
181
|
-
:
|
|
158
|
+
const dependencyPaths = isArray(dependency.components)
|
|
159
|
+
? dependency.components
|
|
160
|
+
: dependency.components
|
|
161
|
+
? [dependency.components]
|
|
162
|
+
: [];
|
|
182
163
|
for (const dependencyPath of dependencyPaths) {
|
|
183
164
|
rules.push({
|
|
184
165
|
packageName,
|
|
185
|
-
outputPattern:
|
|
186
|
-
packageName,
|
|
187
|
-
dependencyPath,
|
|
188
|
-
),
|
|
166
|
+
outputPattern: joinDependencySpecifier(packageName, dependencyPath),
|
|
189
167
|
});
|
|
190
168
|
}
|
|
191
169
|
}
|
|
@@ -220,9 +198,7 @@ export class ModuleStyleImportCollector {
|
|
|
220
198
|
const matchedValue = pathValues.shift();
|
|
221
199
|
if (matchedValue) return matchedValue;
|
|
222
200
|
if (token === GLOBSTAR_TOKEN) return importedName;
|
|
223
|
-
return matchedValue
|
|
224
|
-
? matchedValue
|
|
225
|
-
: importedName;
|
|
201
|
+
return matchedValue ?? importedName;
|
|
226
202
|
});
|
|
227
203
|
}
|
|
228
204
|
createDirectStyleSpecifier(rule, importPath) {
|
|
@@ -243,43 +219,4 @@ export class ModuleStyleImportCollector {
|
|
|
243
219
|
}
|
|
244
220
|
return `${importPath}${suffix}`;
|
|
245
221
|
}
|
|
246
|
-
joinDependencySpecifier(packageName, dependencyPath) {
|
|
247
|
-
if (!dependencyPath) return packageName;
|
|
248
|
-
if (dependencyPath.startsWith(POSIX_SEPARATOR)) {
|
|
249
|
-
return `${packageName}${dependencyPath}`;
|
|
250
|
-
}
|
|
251
|
-
return `${packageName}${POSIX_SEPARATOR}${dependencyPath}`;
|
|
252
|
-
}
|
|
253
|
-
getImportedNames(file, item) {
|
|
254
|
-
var _a;
|
|
255
|
-
const importClause = item.importClause;
|
|
256
|
-
if (!importClause || importClause.isTypeOnly) {
|
|
257
|
-
return [];
|
|
258
|
-
}
|
|
259
|
-
const names = [];
|
|
260
|
-
if (importClause.name) {
|
|
261
|
-
names.push(importClause.name.text);
|
|
262
|
-
}
|
|
263
|
-
const namedBindings = importClause.namedBindings;
|
|
264
|
-
if (!namedBindings) {
|
|
265
|
-
return names;
|
|
266
|
-
}
|
|
267
|
-
if (ts.isNamespaceImport(namedBindings)) {
|
|
268
|
-
throw new Error(
|
|
269
|
-
`Namespace import is not supported for CSS auto import: ${item.importPath}\n` +
|
|
270
|
-
`Use named imports instead, for example: import { Component } from '${item.importPath}'.\n` +
|
|
271
|
-
`File: ${file}`,
|
|
272
|
-
);
|
|
273
|
-
}
|
|
274
|
-
for (const element of namedBindings.elements) {
|
|
275
|
-
if (element.isTypeOnly) continue;
|
|
276
|
-
names.push(
|
|
277
|
-
((_a = element.propertyName) !== null && _a !== void 0
|
|
278
|
-
? _a
|
|
279
|
-
: element.name
|
|
280
|
-
).text,
|
|
281
|
-
);
|
|
282
|
-
}
|
|
283
|
-
return names;
|
|
284
|
-
}
|
|
285
222
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
export type ModuleStyleSourceReference = {
|
|
3
|
+
importPath: string;
|
|
4
|
+
importClause?: ts.ImportClause;
|
|
5
|
+
importedNames?: Array<string>;
|
|
6
|
+
isTypeOnly?: boolean;
|
|
7
|
+
hasNamespaceImport?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare function collectModuleStyleSourceReferences(
|
|
10
|
+
file: string,
|
|
11
|
+
code: string,
|
|
12
|
+
): ModuleStyleSourceReference[];
|
|
13
|
+
export declare function isTypeOnlySourceReference(
|
|
14
|
+
item: ModuleStyleSourceReference,
|
|
15
|
+
): boolean | undefined;
|
|
16
|
+
export declare function getSourceReferenceImportedNames(
|
|
17
|
+
file: string,
|
|
18
|
+
item: ModuleStyleSourceReference,
|
|
19
|
+
): string[];
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
export function collectModuleStyleSourceReferences(file, code) {
|
|
3
|
+
const imports = [];
|
|
4
|
+
const importBindings = new Map();
|
|
5
|
+
const localDeclarations = new Set();
|
|
6
|
+
const sourceFile = ts.createSourceFile(
|
|
7
|
+
file,
|
|
8
|
+
code,
|
|
9
|
+
ts.ScriptTarget.Latest,
|
|
10
|
+
false,
|
|
11
|
+
file.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS,
|
|
12
|
+
);
|
|
13
|
+
sourceFile.forEachChild((node) => {
|
|
14
|
+
collectLocalDeclarationNames(node, localDeclarations);
|
|
15
|
+
if (ts.isImportDeclaration(node)) {
|
|
16
|
+
collectImportBindings(node, importBindings);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
sourceFile.forEachChild((node) => {
|
|
20
|
+
if (ts.isImportDeclaration(node)) {
|
|
21
|
+
if (!ts.isStringLiteral(node.moduleSpecifier)) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
imports.push({
|
|
25
|
+
importPath: node.moduleSpecifier.text,
|
|
26
|
+
importClause: node.importClause,
|
|
27
|
+
});
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (ts.isExportDeclaration(node)) {
|
|
31
|
+
collectExportDeclaration(
|
|
32
|
+
file,
|
|
33
|
+
node,
|
|
34
|
+
imports,
|
|
35
|
+
importBindings,
|
|
36
|
+
localDeclarations,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return imports;
|
|
41
|
+
}
|
|
42
|
+
export function isTypeOnlySourceReference(item) {
|
|
43
|
+
return isTypeOnlyImportClause(item.importClause) || item.isTypeOnly;
|
|
44
|
+
}
|
|
45
|
+
export function getSourceReferenceImportedNames(file, item) {
|
|
46
|
+
if (item.importedNames) {
|
|
47
|
+
if (item.isTypeOnly) return [];
|
|
48
|
+
if (item.hasNamespaceImport) {
|
|
49
|
+
throw createNamespaceImportError(file, item.importPath);
|
|
50
|
+
}
|
|
51
|
+
return item.importedNames;
|
|
52
|
+
}
|
|
53
|
+
const importClause = item.importClause;
|
|
54
|
+
if (!importClause || isTypeOnlyImportClause(importClause)) {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
const names = [];
|
|
58
|
+
if (importClause.name) {
|
|
59
|
+
names.push(importClause.name.text);
|
|
60
|
+
}
|
|
61
|
+
const namedBindings = importClause.namedBindings;
|
|
62
|
+
if (!namedBindings) {
|
|
63
|
+
return names;
|
|
64
|
+
}
|
|
65
|
+
if (ts.isNamespaceImport(namedBindings)) {
|
|
66
|
+
throw createNamespaceImportError(file, item.importPath);
|
|
67
|
+
}
|
|
68
|
+
for (const element of namedBindings.elements) {
|
|
69
|
+
if (element.isTypeOnly) continue;
|
|
70
|
+
names.push((element.propertyName ?? element.name).text);
|
|
71
|
+
}
|
|
72
|
+
return names;
|
|
73
|
+
}
|
|
74
|
+
const collectLocalDeclarationNames = (node, localDeclarations) => {
|
|
75
|
+
if (
|
|
76
|
+
(ts.isFunctionDeclaration(node) ||
|
|
77
|
+
ts.isClassDeclaration(node) ||
|
|
78
|
+
ts.isInterfaceDeclaration(node) ||
|
|
79
|
+
ts.isTypeAliasDeclaration(node) ||
|
|
80
|
+
ts.isEnumDeclaration(node)) &&
|
|
81
|
+
node.name
|
|
82
|
+
) {
|
|
83
|
+
localDeclarations.add(node.name.text);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (!ts.isVariableStatement(node)) return;
|
|
87
|
+
for (const declaration of node.declarationList.declarations) {
|
|
88
|
+
if (ts.isIdentifier(declaration.name)) {
|
|
89
|
+
localDeclarations.add(declaration.name.text);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
const collectImportBindings = (node, importBindings) => {
|
|
94
|
+
if (!ts.isStringLiteral(node.moduleSpecifier) || !node.importClause) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const importPath = node.moduleSpecifier.text;
|
|
98
|
+
const isTypeOnly = isTypeOnlyImportClause(node.importClause);
|
|
99
|
+
if (node.importClause.name) {
|
|
100
|
+
const importedName = node.importClause.name.text;
|
|
101
|
+
importBindings.set(importedName, {
|
|
102
|
+
importPath,
|
|
103
|
+
importedName,
|
|
104
|
+
isTypeOnly,
|
|
105
|
+
hasNamespaceImport: false,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
const namedBindings = node.importClause.namedBindings;
|
|
109
|
+
if (!namedBindings) return;
|
|
110
|
+
if (ts.isNamespaceImport(namedBindings)) {
|
|
111
|
+
importBindings.set(namedBindings.name.text, {
|
|
112
|
+
importPath,
|
|
113
|
+
importedName: namedBindings.name.text,
|
|
114
|
+
isTypeOnly,
|
|
115
|
+
hasNamespaceImport: true,
|
|
116
|
+
});
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
for (const element of namedBindings.elements) {
|
|
120
|
+
const importedName = (element.propertyName ?? element.name).text;
|
|
121
|
+
importBindings.set(element.name.text, {
|
|
122
|
+
importPath,
|
|
123
|
+
importedName,
|
|
124
|
+
isTypeOnly: isTypeOnly || element.isTypeOnly,
|
|
125
|
+
hasNamespaceImport: false,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
const collectExportDeclaration = (
|
|
130
|
+
file,
|
|
131
|
+
node,
|
|
132
|
+
imports,
|
|
133
|
+
importBindings,
|
|
134
|
+
localDeclarations,
|
|
135
|
+
) => {
|
|
136
|
+
if (node.moduleSpecifier) {
|
|
137
|
+
if (!ts.isStringLiteral(node.moduleSpecifier)) return;
|
|
138
|
+
if (!node.exportClause || !ts.isNamedExports(node.exportClause)) {
|
|
139
|
+
throw new Error(
|
|
140
|
+
`[auklet:css] Export-all declarations are not supported for CSS auto import: ${node.moduleSpecifier.text}\n` +
|
|
141
|
+
`Use named exports instead, for example: export { Component } from '${node.moduleSpecifier.text}'.\n` +
|
|
142
|
+
`File: ${file}`,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
imports.push({
|
|
146
|
+
importPath: node.moduleSpecifier.text,
|
|
147
|
+
importedNames: getExportedNames(node),
|
|
148
|
+
isTypeOnly: node.isTypeOnly,
|
|
149
|
+
});
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (!node.exportClause || !ts.isNamedExports(node.exportClause)) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
for (const element of node.exportClause.elements) {
|
|
156
|
+
if (node.isTypeOnly || element.isTypeOnly) continue;
|
|
157
|
+
const localName = (element.propertyName ?? element.name).text;
|
|
158
|
+
const binding = importBindings.get(localName);
|
|
159
|
+
if (binding) {
|
|
160
|
+
imports.push({
|
|
161
|
+
importPath: binding.importPath,
|
|
162
|
+
importedNames: [binding.importedName],
|
|
163
|
+
isTypeOnly: binding.isTypeOnly,
|
|
164
|
+
hasNamespaceImport: binding.hasNamespaceImport,
|
|
165
|
+
});
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
if (!localDeclarations.has(localName)) {
|
|
169
|
+
throw new Error(
|
|
170
|
+
`[auklet:css] Unable to resolve exported symbol "${localName}" for CSS auto import.\n` +
|
|
171
|
+
`File: ${file}`,
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
const getExportedNames = (node) => {
|
|
177
|
+
if (!node.exportClause || !ts.isNamedExports(node.exportClause)) {
|
|
178
|
+
return [];
|
|
179
|
+
}
|
|
180
|
+
return node.exportClause.elements
|
|
181
|
+
.filter((element) => !element.isTypeOnly)
|
|
182
|
+
.map((element) => (element.propertyName ?? element.name).text);
|
|
183
|
+
};
|
|
184
|
+
const isTypeOnlyImportClause = (importClause) => {
|
|
185
|
+
return importClause?.phaseModifier === ts.SyntaxKind.TypeKeyword;
|
|
186
|
+
};
|
|
187
|
+
const createNamespaceImportError = (file, importPath) => {
|
|
188
|
+
return new Error(
|
|
189
|
+
`Namespace import is not supported for CSS auto import: ${importPath}\n` +
|
|
190
|
+
`Use named imports instead, for example: import { Component } from '${importPath}'.\n` +
|
|
191
|
+
`File: ${file}`,
|
|
192
|
+
);
|
|
193
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { StylePackageContext } from '#auklet/css/core/stylePackageContext';
|
|
2
|
+
export type ModuleStyleEntryPlan = {
|
|
3
|
+
sourceDir: string;
|
|
4
|
+
moduleStyleImports: Array<string>;
|
|
5
|
+
ownStyleFiles: Array<string>;
|
|
6
|
+
};
|
|
7
|
+
export declare class StyleModuleEntryPlanner {
|
|
8
|
+
private readonly packageContext;
|
|
9
|
+
private readonly styleFilesByDir;
|
|
10
|
+
private readonly importedStyleFiles;
|
|
11
|
+
constructor(packageContext: StylePackageContext);
|
|
12
|
+
createEntries(moduleStyleImports: Map<string, Array<string>>): {
|
|
13
|
+
sourceDir: string;
|
|
14
|
+
moduleStyleImports: string[];
|
|
15
|
+
ownStyleFiles: string[];
|
|
16
|
+
}[];
|
|
17
|
+
createEntry(
|
|
18
|
+
sourceDir: string,
|
|
19
|
+
moduleStyleImports: Map<string, Array<string>>,
|
|
20
|
+
): {
|
|
21
|
+
sourceDir: string;
|
|
22
|
+
moduleStyleImports: string[];
|
|
23
|
+
ownStyleFiles: string[];
|
|
24
|
+
};
|
|
25
|
+
private getSourceDirs;
|
|
26
|
+
private getSourceModuleDirs;
|
|
27
|
+
private getOwnStyleDirs;
|
|
28
|
+
private getOwnStyleFiles;
|
|
29
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { SOURCE_COMPONENT_MODULE_RE } from '#auklet/css/constants';
|
|
3
|
+
import { groupStyleFilesByDir } from '#auklet/css/core/style/files';
|
|
4
|
+
import { getSourceModuleDir, toPosixPath } from '#auklet/utils';
|
|
5
|
+
export class StyleModuleEntryPlanner {
|
|
6
|
+
packageContext;
|
|
7
|
+
styleFilesByDir;
|
|
8
|
+
importedStyleFiles;
|
|
9
|
+
constructor(packageContext) {
|
|
10
|
+
this.packageContext = packageContext;
|
|
11
|
+
this.styleFilesByDir = groupStyleFilesByDir(
|
|
12
|
+
this.packageContext.sourceRoot,
|
|
13
|
+
this.packageContext.styleFiles,
|
|
14
|
+
);
|
|
15
|
+
this.importedStyleFiles =
|
|
16
|
+
this.packageContext.styleProcessor.collectImportedStyleFiles(
|
|
17
|
+
this.packageContext.styleFiles,
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
createEntries(moduleStyleImports) {
|
|
21
|
+
return this.getSourceDirs(moduleStyleImports).map((sourceDir) =>
|
|
22
|
+
this.createEntry(sourceDir, moduleStyleImports),
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
createEntry(sourceDir, moduleStyleImports) {
|
|
26
|
+
return {
|
|
27
|
+
sourceDir,
|
|
28
|
+
moduleStyleImports: moduleStyleImports.get(sourceDir) ?? [],
|
|
29
|
+
ownStyleFiles: this.getOwnStyleFiles(sourceDir),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
getSourceDirs(moduleStyleImports) {
|
|
33
|
+
return Array.from(
|
|
34
|
+
new Set([
|
|
35
|
+
...this.getSourceModuleDirs(),
|
|
36
|
+
...this.getOwnStyleDirs(),
|
|
37
|
+
...moduleStyleImports.keys(),
|
|
38
|
+
]),
|
|
39
|
+
).filter((sourceDir) => sourceDir !== '.');
|
|
40
|
+
}
|
|
41
|
+
getSourceModuleDirs() {
|
|
42
|
+
return this.packageContext.sourceFiles
|
|
43
|
+
.filter((sourceFile) => SOURCE_COMPONENT_MODULE_RE.test(sourceFile))
|
|
44
|
+
.map((sourceFile) => {
|
|
45
|
+
return getSourceModuleDir(
|
|
46
|
+
path.relative(this.packageContext.sourceRoot, sourceFile),
|
|
47
|
+
);
|
|
48
|
+
})
|
|
49
|
+
.filter((sourceModuleDir) => {
|
|
50
|
+
return toPosixPath(sourceModuleDir).split('/').length === 2;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
getOwnStyleDirs() {
|
|
54
|
+
return Array.from(this.styleFilesByDir.entries())
|
|
55
|
+
.filter(([, dirStyleFiles]) =>
|
|
56
|
+
dirStyleFiles.some(
|
|
57
|
+
(styleFile) => !this.importedStyleFiles.has(path.resolve(styleFile)),
|
|
58
|
+
),
|
|
59
|
+
)
|
|
60
|
+
.map(([sourceDir]) => sourceDir);
|
|
61
|
+
}
|
|
62
|
+
getOwnStyleFiles(sourceDir) {
|
|
63
|
+
return (this.styleFilesByDir.get(sourceDir) ?? []).filter(
|
|
64
|
+
(styleFile) => !this.importedStyleFiles.has(path.resolve(styleFile)),
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ModuleStyleImportCollector } from '#auklet/css/core/styleImports/collector';
|
|
2
|
+
import { StyleProcessor } from '#auklet/css/core/styleProcessor';
|
|
3
|
+
import { WorkspaceStyleResolver } from '#auklet/css/core/workspaceStyleResolver';
|
|
4
|
+
import type {
|
|
5
|
+
ModuleStyleBuildConfig,
|
|
6
|
+
NormalizedAukletConfig,
|
|
7
|
+
ResolvedModuleStyleBuildContext,
|
|
8
|
+
} from '#auklet/types';
|
|
9
|
+
export type StylePackageContextOptions = {
|
|
10
|
+
config: ModuleStyleBuildConfig;
|
|
11
|
+
context: ResolvedModuleStyleBuildContext;
|
|
12
|
+
normalizedConfig: NormalizedAukletConfig;
|
|
13
|
+
};
|
|
14
|
+
export declare class StylePackageContext {
|
|
15
|
+
private readonly options;
|
|
16
|
+
readonly normalizedConfig: NormalizedAukletConfig;
|
|
17
|
+
readonly sourceRoot: string;
|
|
18
|
+
readonly resolver: WorkspaceStyleResolver;
|
|
19
|
+
readonly styleProcessor: StyleProcessor;
|
|
20
|
+
readonly importCollector: ModuleStyleImportCollector;
|
|
21
|
+
readonly sourceFiles: Array<string>;
|
|
22
|
+
readonly themeFiles: Map<string, string>;
|
|
23
|
+
readonly themeNames: Array<string>;
|
|
24
|
+
readonly styleFiles: Array<string>;
|
|
25
|
+
constructor(options: StylePackageContextOptions);
|
|
26
|
+
getStyleFiles(files: Array<string>): string[];
|
|
27
|
+
}
|