auklet 0.0.10 → 0.0.11

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 CHANGED
@@ -53,6 +53,8 @@ import type { AukletConfig } from 'auklet';
53
53
  export const config: AukletConfig = {
54
54
  source: 'src',
55
55
  output: 'dist',
56
+ modules: true,
57
+ tsconfig: 'tsconfig.json',
56
58
  styles: {
57
59
  themes: {
58
60
  light: './src/themes/light.css',
@@ -72,17 +74,12 @@ export const config: AukletConfig = {
72
74
  },
73
75
  },
74
76
  },
75
- modules: true,
76
77
  build: {
77
- formats: ['esm', 'cjs'],
78
+ alias: { ... },
79
+ globals: { ... },
78
80
  target: 'es2020',
79
- alias: {
80
- '@shared': './src/shared',
81
- },
81
+ formats: ['esm', 'cjs'],
82
82
  mainFields: ['browser', 'module', 'main'],
83
- globals: {
84
- react: 'React',
85
- },
86
83
  configureTsdown(config, context) {
87
84
  if (context.kind !== 'bundle') return config;
88
85
  return {
@@ -90,7 +87,6 @@ export const config: AukletConfig = {
90
87
  sourcemap: true,
91
88
  };
92
89
  },
93
- tsconfig: 'tsconfig.json',
94
90
  },
95
91
  };
96
92
  ```
@@ -112,6 +108,12 @@ Component style inference only scans source `.tsx` files. Component imports or
112
108
  re-exports in `.ts` files are ignored for CSS auto import, so component barrel
113
109
  files that should drive component CSS must be `.tsx`.
114
110
 
111
+ Same-package component style inference resolves relative imports,
112
+ `package.json#imports` mappings, and `tsconfig.json` `compilerOptions.paths`.
113
+ For `package.json#imports`, the `source` condition is preferred when present.
114
+ Only aliases that resolve into the current package source directory are treated
115
+ as same-package CSS dependencies.
116
+
115
117
  Supported value forms include named imports, named re-exports, and local
116
118
  re-exports that can be traced back to an import binding:
117
119
 
@@ -0,0 +1,5 @@
1
+ export declare function resolvePackageImportsSourceImport(
2
+ packageRoot: string,
3
+ sourceRoot: string,
4
+ importPath: string,
5
+ ): string[];
@@ -0,0 +1,53 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { findPathInImports } from 'conditional-export';
4
+ import { POSIX_SEPARATOR, toPosixPath } from '#auklet/utils';
5
+ const conditions = ['source', 'import', 'default'];
6
+ const sourceExtensions = /\.(?:[cm]?[jt]s|[jt]sx)$/;
7
+ const readPackageImports = (packageRoot) => {
8
+ const packageJsonPath = path.join(packageRoot, 'package.json');
9
+ if (!fs.existsSync(packageJsonPath)) return {};
10
+ try {
11
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
12
+ return packageJson.imports ?? {};
13
+ } catch {
14
+ return {};
15
+ }
16
+ };
17
+ const trimSourceExtension = (value) => {
18
+ return value.replace(sourceExtensions, '');
19
+ };
20
+ const toSourceRelativePath = (packageRoot, sourceRoot, target) => {
21
+ if (!target.startsWith('.')) return null;
22
+ const file = path.resolve(packageRoot, target);
23
+ const relative = path.relative(sourceRoot, file);
24
+ if (relative.startsWith('..') || path.isAbsolute(relative)) return null;
25
+ return trimSourceExtension(toPosixPath(relative));
26
+ };
27
+ export function resolvePackageImportsSourceImport(
28
+ packageRoot,
29
+ sourceRoot,
30
+ importPath,
31
+ ) {
32
+ if (!importPath.startsWith('#')) return [];
33
+ const resolved = (() => {
34
+ try {
35
+ return findPathInImports(
36
+ importPath,
37
+ readPackageImports(packageRoot),
38
+ conditions,
39
+ );
40
+ } catch {
41
+ return null;
42
+ }
43
+ })();
44
+ if (!resolved) return [];
45
+ const sourceRelativePath = toSourceRelativePath(
46
+ packageRoot,
47
+ sourceRoot,
48
+ resolved,
49
+ );
50
+ return sourceRelativePath
51
+ ? [sourceRelativePath.split(POSIX_SEPARATOR).join(path.sep)]
52
+ : [];
53
+ }
@@ -0,0 +1,4 @@
1
+ export declare function resolveRelativeSourceImport(
2
+ sourceDir: string,
3
+ importPath: string,
4
+ ): string[];
@@ -0,0 +1,5 @@
1
+ import path from 'node:path';
2
+ export function resolveRelativeSourceImport(sourceDir, importPath) {
3
+ if (!importPath.startsWith('.')) return [];
4
+ return [path.normalize(path.join(sourceDir, importPath))];
5
+ }
@@ -0,0 +1,5 @@
1
+ export declare function resolveTsconfigPathsSourceImport(
2
+ packageRoot: string,
3
+ sourceRoot: string,
4
+ importPath: string,
5
+ ): string[];
@@ -0,0 +1,85 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import ts from 'typescript';
4
+ import { POSIX_SEPARATOR, toPosixPath } from '#auklet/utils';
5
+ const sourceExtensions = /\.(?:[cm]?[jt]s|[jt]sx)$/;
6
+ const findTsconfig = (packageRoot) => {
7
+ let current = packageRoot;
8
+ while (true) {
9
+ const tsconfig = path.join(current, 'tsconfig.json');
10
+ if (fs.existsSync(tsconfig)) return tsconfig;
11
+ const parent = path.dirname(current);
12
+ if (parent === current) return null;
13
+ current = parent;
14
+ }
15
+ };
16
+ const readTsconfigPaths = (packageRoot) => {
17
+ const tsconfig = findTsconfig(packageRoot);
18
+ if (!tsconfig) return null;
19
+ const loaded = ts.readConfigFile(tsconfig, ts.sys.readFile);
20
+ if (loaded.error) return null;
21
+ const parsed = ts.parseJsonConfigFileContent(
22
+ loaded.config,
23
+ ts.sys,
24
+ path.dirname(tsconfig),
25
+ {},
26
+ tsconfig,
27
+ );
28
+ return {
29
+ baseUrl: parsed.options.baseUrl ?? path.dirname(tsconfig),
30
+ paths: parsed.options.paths ?? {},
31
+ };
32
+ };
33
+ const resolvePattern = (pattern, target, importPath) => {
34
+ const wildcardIndex = pattern.indexOf('*');
35
+ if (wildcardIndex < 0) return pattern === importPath ? target : null;
36
+ const prefix = pattern.slice(0, wildcardIndex);
37
+ const suffix = pattern.slice(wildcardIndex + 1);
38
+ if (!importPath.startsWith(prefix) || !importPath.endsWith(suffix)) {
39
+ return null;
40
+ }
41
+ const value = importPath.slice(
42
+ prefix.length,
43
+ importPath.length - suffix.length,
44
+ );
45
+ return target.replace(/\*/g, value);
46
+ };
47
+ const getPatternScore = (pattern) => {
48
+ const wildcardIndex = pattern.indexOf('*');
49
+ if (wildcardIndex < 0) return Number.MAX_SAFE_INTEGER;
50
+ return pattern.slice(0, wildcardIndex).length;
51
+ };
52
+ const trimSourceExtension = (value) => {
53
+ return value.replace(sourceExtensions, '');
54
+ };
55
+ const toSourceRelativePath = (sourceRoot, file) => {
56
+ const relative = path.relative(sourceRoot, file);
57
+ if (relative.startsWith('..') || path.isAbsolute(relative)) return null;
58
+ return trimSourceExtension(toPosixPath(relative));
59
+ };
60
+ export function resolveTsconfigPathsSourceImport(
61
+ packageRoot,
62
+ sourceRoot,
63
+ importPath,
64
+ ) {
65
+ const config = readTsconfigPaths(packageRoot);
66
+ if (!config) return [];
67
+ const matches = [];
68
+ for (const [pattern, targets] of Object.entries(config.paths)) {
69
+ for (const target of targets) {
70
+ const resolved = resolvePattern(pattern, target, importPath);
71
+ if (!resolved) continue;
72
+ const sourceRelativePath = toSourceRelativePath(
73
+ sourceRoot,
74
+ path.resolve(config.baseUrl, resolved),
75
+ );
76
+ if (sourceRelativePath) {
77
+ matches.push({
78
+ path: sourceRelativePath.split(POSIX_SEPARATOR).join(path.sep),
79
+ score: getPatternScore(pattern),
80
+ });
81
+ }
82
+ }
83
+ }
84
+ return matches.sort((a, b) => b.score - a.score).map((match) => match.path);
85
+ }
@@ -5,7 +5,6 @@ export declare class ModuleStyleImportCollector {
5
5
  private readonly packageRoot;
6
6
  private readonly resolver;
7
7
  private readonly styleExtensions;
8
- private readonly sourceImportAliasRules;
9
8
  constructor(
10
9
  srcRoot: string,
11
10
  packageRoot: string,
@@ -18,8 +17,9 @@ export declare class ModuleStyleImportCollector {
18
17
  ): Map<string, string[]>;
19
18
  private collectSourceImportStyle;
20
19
  private resolveSourceImportStyleEntry;
21
- private resolveSourceImportPath;
22
- private createSourceImportAliasRules;
20
+ private isInsideSourceRoot;
21
+ private resolveSourceImportPaths;
22
+ private toSourceBase;
23
23
  private toRelativeSpecifier;
24
24
  private createAutoImportRules;
25
25
  private matchAutoImportRules;
@@ -13,19 +13,22 @@ import {
13
13
  getSourceReferenceImportedNames,
14
14
  isTypeOnlySourceReference,
15
15
  } from '#auklet/css/core/styleImports/sourceReference';
16
+ import { resolveRelativeSourceImport } from '#auklet/css/core/resolvers/relative';
17
+ import { resolvePackageImportsSourceImport } from '#auklet/css/core/resolvers/packageImports';
18
+ import { resolveTsconfigPathsSourceImport } from '#auklet/css/core/resolvers/tsconfigPaths';
16
19
  const GLOBSTAR_TOKEN = '**';
20
+ const SOURCE_EXTENSION_RE = /\.(?:[cm]?[jt]s|[jt]sx)$/;
21
+ const SOURCE_INDEX_RE = new RegExp(`[/\\\\]index${SOURCE_EXTENSION_RE.source}`);
17
22
  export class ModuleStyleImportCollector {
18
23
  srcRoot;
19
24
  packageRoot;
20
25
  resolver;
21
26
  styleExtensions;
22
- sourceImportAliasRules;
23
27
  constructor(srcRoot, packageRoot, resolver, styleExtensions = ['.css']) {
24
28
  this.srcRoot = srcRoot;
25
29
  this.packageRoot = packageRoot;
26
30
  this.resolver = resolver;
27
31
  this.styleExtensions = styleExtensions;
28
- this.sourceImportAliasRules = this.createSourceImportAliasRules();
29
32
  }
30
33
  collect(files, config) {
31
34
  const entries = new Map();
@@ -100,51 +103,51 @@ export class ModuleStyleImportCollector {
100
103
  );
101
104
  }
102
105
  resolveSourceImportStyleEntry(sourceDir, importPath) {
103
- const sourceRelativePath = this.resolveSourceImportPath(
106
+ const sourceRelativePaths = this.resolveSourceImportPaths(
104
107
  sourceDir,
105
108
  importPath,
106
109
  );
107
- if (!sourceRelativePath) return null;
108
- const sourceBase = path.join(this.srcRoot, sourceRelativePath);
109
- const directoryStyleEntry = path.join(sourceBase, 'style', 'index.css');
110
- for (const extension of this.styleExtensions) {
111
- const directorySourceStyle = path.join(sourceBase, `index${extension}`);
112
- if (fs.existsSync(directorySourceStyle)) return directoryStyleEntry;
113
- }
114
- const hasFileSourceStyle = this.styleExtensions.some((extension) =>
115
- fs.existsSync(`${sourceBase}${extension}`),
116
- );
117
- if (!hasFileSourceStyle) return null;
118
- return path.join(sourceBase, 'style', 'index.css');
119
- }
120
- resolveSourceImportPath(sourceDir, importPath) {
121
- if (importPath.startsWith('.')) {
122
- return path.normalize(path.join(sourceDir, importPath));
123
- }
124
- for (const rule of this.sourceImportAliasRules) {
125
- if (!importPath.startsWith(rule.prefix)) continue;
126
- return importPath.slice(rule.prefix.length);
110
+ for (const sourceRelativePath of sourceRelativePaths) {
111
+ const sourceBase = this.toSourceBase(sourceRelativePath);
112
+ if (!this.isInsideSourceRoot(sourceBase)) continue;
113
+ const directoryStyleEntry = path.join(sourceBase, 'style', 'index.css');
114
+ for (const extension of this.styleExtensions) {
115
+ const directorySourceStyle = path.join(sourceBase, `index${extension}`);
116
+ if (fs.existsSync(directorySourceStyle)) return directoryStyleEntry;
117
+ }
118
+ const hasFileSourceStyle = this.styleExtensions.some((extension) =>
119
+ fs.existsSync(`${sourceBase}${extension}`),
120
+ );
121
+ if (hasFileSourceStyle)
122
+ return path.join(sourceBase, 'style', 'index.css');
127
123
  }
128
124
  return null;
129
125
  }
130
- createSourceImportAliasRules() {
131
- const packageJsonPath = path.join(this.packageRoot, 'package.json');
132
- if (!fs.existsSync(packageJsonPath)) return [];
133
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
134
- const rules = [];
135
- for (const [name, target] of Object.entries(packageJson.imports ?? {})) {
136
- if (
137
- !name.endsWith(`${POSIX_SEPARATOR}*`) ||
138
- typeof target !== 'string' ||
139
- !target.includes('*')
140
- ) {
141
- continue;
142
- }
143
- rules.push({
144
- prefix: name.slice(0, -1),
145
- });
126
+ isInsideSourceRoot(file) {
127
+ const relative = path.relative(this.srcRoot, file);
128
+ return !relative.startsWith('..') && !path.isAbsolute(relative);
129
+ }
130
+ resolveSourceImportPaths(sourceDir, importPath) {
131
+ return [
132
+ ...resolveRelativeSourceImport(sourceDir, importPath),
133
+ ...resolvePackageImportsSourceImport(
134
+ this.packageRoot,
135
+ this.srcRoot,
136
+ importPath,
137
+ ),
138
+ ...resolveTsconfigPathsSourceImport(
139
+ this.packageRoot,
140
+ this.srcRoot,
141
+ importPath,
142
+ ),
143
+ ];
144
+ }
145
+ toSourceBase(sourceRelativePath) {
146
+ const sourceBase = path.join(this.srcRoot, sourceRelativePath);
147
+ if (SOURCE_INDEX_RE.test(sourceBase)) {
148
+ return path.dirname(sourceBase);
146
149
  }
147
- return rules;
150
+ return sourceBase.replace(SOURCE_EXTENSION_RE, '');
148
151
  }
149
152
  toRelativeSpecifier(fromDir, file) {
150
153
  const relative = path.relative(fromDir, file).split(path.sep).join('/');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auklet",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "type": "module",
5
5
  "author": "chentao.arthur",
6
6
  "packageManager": "pnpm@10.27.0",
@@ -72,7 +72,7 @@
72
72
  "chokidar": "^5.0.0",
73
73
  "minimist": "^1.2.8",
74
74
  "typescript": "^6.0.3",
75
- "tailwindcss": "^4.2.4"
75
+ "conditional-export": "^1.1.0"
76
76
  },
77
77
  "devDependencies": {
78
78
  "@types/node": "^22.17.0",