@hkdigital/lib-core 0.5.77 → 0.5.79
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 +2 -30
- package/claude.md +45 -0
- package/dist/design/config/design-tokens.js +2 -2
- package/dist/design/generators/index.d.ts +2 -2
- package/dist/design/generators/index.js +2 -2
- package/dist/design/index.js +2 -2
- package/dist/design/utils/root-vars.d.ts +1 -1
- package/dist/design/utils/root-vars.js +1 -1
- package/dist/logging/README.md +1 -1
- package/dist/logging/internal/logger/Logger.js +1 -1
- package/dist/services/README.md +3 -3
- package/dist/ui/components/game-box/_previous/GameBox.svelte +1 -1
- package/package.json +1 -1
- package/scripts/README.md +65 -0
- package/scripts/validate-imports.mjs +121 -4
package/README.md
CHANGED
|
@@ -309,7 +309,6 @@ The validator automatically reads path aliases from your
|
|
|
309
309
|
`svelte.config.js` and applies the same barrel export validation rules
|
|
310
310
|
to alias imports. This ensures consistent import patterns across:
|
|
311
311
|
- Internal `$lib/` imports
|
|
312
|
-
- Project aliases like `$hklib-core`, `$hklib-pro`, etc.
|
|
313
312
|
- External `@hkdigital/*` package imports
|
|
314
313
|
|
|
315
314
|
**Validation rules (enforced for `src/lib/` files only):**
|
|
@@ -344,14 +343,6 @@ import Button from '$lib/ui/primitives/buttons/Button.svelte';
|
|
|
344
343
|
import { ProfileBlocks } from '$lib/ui/components.js';
|
|
345
344
|
import { Button } from '$lib/ui/primitives.js';
|
|
346
345
|
|
|
347
|
-
// Project aliases - instead of deep imports:
|
|
348
|
-
import { Logger } from '$hklib-core/logging/logger/Logger.js';
|
|
349
|
-
import { HttpClient } from '$hklib-core/network/http/HttpClient.js';
|
|
350
|
-
|
|
351
|
-
// Use barrel exports:
|
|
352
|
-
import { Logger } from '$hklib-core/logging.js';
|
|
353
|
-
import { HttpClient } from '$hklib-core/network/http.js';
|
|
354
|
-
|
|
355
346
|
// External imports - instead of deep imports:
|
|
356
347
|
import { TextButton } from '@hkdigital/lib-core/ui/primitives/buttons/index.js';
|
|
357
348
|
import { TextInput } from '@hkdigital/lib-core/ui/primitives/inputs/index.js';
|
|
@@ -380,7 +371,6 @@ Validating import paths...
|
|
|
380
371
|
Found project aliases:
|
|
381
372
|
$src → src
|
|
382
373
|
$examples → src/routes/examples
|
|
383
|
-
$hklib-core → src/lib
|
|
384
374
|
|
|
385
375
|
src/lib/ui/panels/Panel.svelte:3
|
|
386
376
|
from '$src/lib/ui/components.js'
|
|
@@ -394,10 +384,6 @@ src/lib/ui/pages/Profile.svelte:8
|
|
|
394
384
|
from '$lib/ui/components/profile-blocks/ProfileBlocks.svelte'
|
|
395
385
|
=> from '$lib/ui/components.js' (use barrel export for shorter imports)
|
|
396
386
|
|
|
397
|
-
src/lib/forms/LoginForm.svelte:4
|
|
398
|
-
from '$hklib-core/logging/logger/Logger.js'
|
|
399
|
-
=> from '$hklib-core/logging.js' (use barrel export)
|
|
400
|
-
|
|
401
387
|
src/lib/forms/LoginForm.svelte:6
|
|
402
388
|
from '@hkdigital/lib-core/ui/primitives/buttons/index.js'
|
|
403
389
|
=> from '@hkdigital/lib-core/ui/primitives.js' (use barrel export)
|
|
@@ -409,8 +395,8 @@ src/routes/explorer/[...path]/+page.svelte:4
|
|
|
409
395
|
|
|
410
396
|
**What gets checked for barrel export suggestions:**
|
|
411
397
|
|
|
412
|
-
The validator only suggests barrel exports (for `$lib
|
|
413
|
-
|
|
398
|
+
The validator only suggests barrel exports (for `$lib/` and external
|
|
399
|
+
`@hkdigital/*` packages) for:
|
|
414
400
|
- Explicit `index.js` imports
|
|
415
401
|
- Component files (`.svelte`)
|
|
416
402
|
- Class files (capitalized `.js` files)
|
|
@@ -418,20 +404,6 @@ and external `@hkdigital/*` packages) for:
|
|
|
418
404
|
Intentional imports like `helpers.js`, `config.js`, or other lowercase
|
|
419
405
|
utility files are assumed to be the public API and won't be flagged.
|
|
420
406
|
|
|
421
|
-
**Alias configuration:**
|
|
422
|
-
|
|
423
|
-
The validator automatically detects aliases in your `svelte.config.js`.
|
|
424
|
-
For example, if your config has:
|
|
425
|
-
```js
|
|
426
|
-
alias: {
|
|
427
|
-
$src: 'src',
|
|
428
|
-
$hklib-core: 'node_modules/@hkdigital/lib-core/dist'
|
|
429
|
-
}
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
The validator will apply the same barrel export rules to these aliases
|
|
433
|
-
as it does to `$lib/` and `@hkdigital/*` imports.
|
|
434
|
-
|
|
435
407
|
### Import Patterns and Export Structure
|
|
436
408
|
|
|
437
409
|
**Public exports use domain-specific files matching folder names:**
|
package/claude.md
CHANGED
|
@@ -130,6 +130,51 @@ This is a modern SvelteKit library built with Svelte 5 and Skeleton.dev v3 compo
|
|
|
130
130
|
|
|
131
131
|
**Import validation:** Run `node scripts/validate-imports.mjs` to validate import patterns. The validator checks for barrel export files at each level and suggests the highest-level file that exports your target. These rules are enforced for `src/lib/` files only. Files in `src/routes/` can use relative imports freely. See README.md "Import Validation" section for usage in other projects.
|
|
132
132
|
|
|
133
|
+
### Critical: Aliases in Libraries vs Apps
|
|
134
|
+
|
|
135
|
+
**IMPORTANT**: Due to Vite/SvelteKit limitations, aliases in library
|
|
136
|
+
code (`src/lib/**`) must resolve to paths **inside the project folder**.
|
|
137
|
+
Aliases to external packages or paths outside the project break when
|
|
138
|
+
building libraries.
|
|
139
|
+
|
|
140
|
+
**The problem:**
|
|
141
|
+
```javascript
|
|
142
|
+
// ❌ These aliases don't work in src/lib/** files:
|
|
143
|
+
// svelte.config.js
|
|
144
|
+
alias: {
|
|
145
|
+
'$ext': 'node_modules/@hkdigital/lib-core/dist', // Outside project
|
|
146
|
+
'$pkg': '@hkdigital/lib-core' // Package name (doesn't resolve)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// In src/lib/** - BREAKS during build!
|
|
150
|
+
import { Button } from '$ext/ui/primitives.js';
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**The solution:**
|
|
154
|
+
- **In library code (`src/lib/**`)**: Use direct package imports
|
|
155
|
+
- **In app code (`src/routes/**`)**: Aliases work fine
|
|
156
|
+
|
|
157
|
+
```javascript
|
|
158
|
+
// ✅ Library code - use direct imports
|
|
159
|
+
import { Button } from '@hkdigital/lib-core/ui/primitives.js';
|
|
160
|
+
|
|
161
|
+
// ✅ App code - aliases OK (not built/published)
|
|
162
|
+
import { Button } from '$ext/ui/primitives.js';
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Local aliases work everywhere:**
|
|
166
|
+
```javascript
|
|
167
|
+
// svelte.config.js
|
|
168
|
+
alias: {
|
|
169
|
+
'$lib': 'src/lib', // ✅ Inside project - works everywhere
|
|
170
|
+
'$examples': 'src/routes/examples' // ✅ Inside project
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Why**: Vite/SvelteKit aliases are designed for internal project
|
|
175
|
+
structure. Build tools cannot properly handle aliases pointing outside
|
|
176
|
+
the project or to package names.
|
|
177
|
+
|
|
133
178
|
## Class Export Conventions
|
|
134
179
|
- **All classes should be default exports**: `export default class ClassName`
|
|
135
180
|
- **Import classes without destructuring**: `import ClassName from './ClassName.js'`
|
|
@@ -87,8 +87,8 @@ const STROKE_WIDTH_SIZES = {
|
|
|
87
87
|
*
|
|
88
88
|
* @example Usage with generateTailwindThemeExtensions
|
|
89
89
|
* ```javascript
|
|
90
|
-
* import { generateTailwindThemeExtensions } from '
|
|
91
|
-
* import { designTokens } from '
|
|
90
|
+
* import { generateTailwindThemeExtensions } from '../index.js';
|
|
91
|
+
* import { designTokens } from './design-tokens.js';
|
|
92
92
|
*
|
|
93
93
|
* const themeExtensions = generateTailwindThemeExtensions(designTokens);
|
|
94
94
|
* ```
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
* // ... other exports
|
|
28
28
|
*
|
|
29
29
|
* // your-project/tailwind.config.js
|
|
30
|
-
* import { generateTailwindThemeExtensions } from '
|
|
31
|
-
* import { customUtilitiesPlugin } from '
|
|
30
|
+
* import { generateTailwindThemeExtensions } from '../index.js';
|
|
31
|
+
* import { customUtilitiesPlugin } from '../index.js';
|
|
32
32
|
* import * as designConfig from './src/lib/design/design-config.js';
|
|
33
33
|
*
|
|
34
34
|
* export default {
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
* // ... other exports
|
|
28
28
|
*
|
|
29
29
|
* // your-project/tailwind.config.js
|
|
30
|
-
* import { generateTailwindThemeExtensions } from '
|
|
31
|
-
* import { customUtilitiesPlugin } from '
|
|
30
|
+
* import { generateTailwindThemeExtensions } from '../index.js';
|
|
31
|
+
* import { customUtilitiesPlugin } from '../index.js';
|
|
32
32
|
* import * as designConfig from './src/lib/design/design-config.js';
|
|
33
33
|
*
|
|
34
34
|
* export default {
|
package/dist/design/index.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @example Basic usage with default tokens
|
|
9
9
|
* ```javascript
|
|
10
|
-
* import { generateTailwindThemeExtensions, designTokens, customUtilitiesPlugin } from '
|
|
10
|
+
* import { generateTailwindThemeExtensions, designTokens, customUtilitiesPlugin } from './index.js';
|
|
11
11
|
*
|
|
12
12
|
* const themeExtensions = generateTailwindThemeExtensions(designTokens);
|
|
13
13
|
*
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
*
|
|
22
22
|
* @example Custom design tokens
|
|
23
23
|
* ```javascript
|
|
24
|
-
* import { generateTailwindThemeExtensions } from '
|
|
24
|
+
* import { generateTailwindThemeExtensions } from './index.js';
|
|
25
25
|
*
|
|
26
26
|
* const myTokens = {
|
|
27
27
|
* TEXT_POINT_SIZES: [4, 8, 12, 16, 24],
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* @example
|
|
26
26
|
* // +layout.svelte
|
|
27
27
|
* <script>
|
|
28
|
-
* import { designTokens, designTokensToRootCssVars } from '
|
|
28
|
+
* import { designTokens, designTokensToRootCssVars } from '../index.js';
|
|
29
29
|
* </script>
|
|
30
30
|
*
|
|
31
31
|
* <svelte:head>
|
|
@@ -114,7 +114,7 @@ function setRootCssVar(varName, value) {
|
|
|
114
114
|
* @example
|
|
115
115
|
* // +layout.svelte
|
|
116
116
|
* <script>
|
|
117
|
-
* import { designTokens, designTokensToRootCssVars } from '
|
|
117
|
+
* import { designTokens, designTokensToRootCssVars } from '../index.js';
|
|
118
118
|
* </script>
|
|
119
119
|
*
|
|
120
120
|
* <svelte:head>
|
package/dist/logging/README.md
CHANGED
|
@@ -188,7 +188,7 @@ When integrating with a service management system, you can set up global
|
|
|
188
188
|
error handling and forward service logs to the main logger:
|
|
189
189
|
|
|
190
190
|
```javascript
|
|
191
|
-
import { ServiceManager } from '
|
|
191
|
+
import { ServiceManager } from '@hkdigital/lib-core/services/index.js';
|
|
192
192
|
import { initClientLogger } from '$lib/logging/client.js';
|
|
193
193
|
|
|
194
194
|
/** @type {ServiceManager} */
|
package/dist/services/README.md
CHANGED
|
@@ -163,7 +163,7 @@ Manages multiple services with dependency resolution and coordinated lifecycle o
|
|
|
163
163
|
### Usage
|
|
164
164
|
|
|
165
165
|
```javascript
|
|
166
|
-
import { ServiceManager } from '
|
|
166
|
+
import { ServiceManager } from '@hkdigital/lib-core/services/index.js';
|
|
167
167
|
|
|
168
168
|
import DatabaseService from './services/DatabaseService.js';
|
|
169
169
|
import AuthService from './services/AuthService.js';
|
|
@@ -211,7 +211,7 @@ class AuthService extends ServiceBase {
|
|
|
211
211
|
/** @type {(<T>(serviceName: string) => T)} */
|
|
212
212
|
#getService;
|
|
213
213
|
|
|
214
|
-
/** @type {() => import('
|
|
214
|
+
/** @type {() => import('@hkdigital/lib-core/services/index.js').ServiceManager} */
|
|
215
215
|
#getManager;
|
|
216
216
|
|
|
217
217
|
constructor(serviceName, options) {
|
|
@@ -257,7 +257,7 @@ export default class PlayerService extends ServiceBase {
|
|
|
257
257
|
|
|
258
258
|
/**
|
|
259
259
|
* @param {string} serviceName
|
|
260
|
-
* @param {import('
|
|
260
|
+
* @param {import('@hkdigital/lib-core/services/typedef.js').ServiceOptions} [options]
|
|
261
261
|
*/
|
|
262
262
|
constructor(serviceName, options) {
|
|
263
263
|
super(serviceName, options);
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
} from './gamebox.util.js';
|
|
8
8
|
|
|
9
9
|
import { enableContainerScaling } from '../../../../design/index.js';
|
|
10
|
-
// import { enableContainerScaling } from '
|
|
10
|
+
// import { enableContainerScaling } from '../../../../design/index.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* @typedef {{
|
package/package.json
CHANGED
package/scripts/README.md
CHANGED
|
@@ -35,6 +35,8 @@ node scripts/validate-imports.mjs
|
|
|
35
35
|
etc. must be explicit
|
|
36
36
|
5. **Import paths must exist** - All imports must resolve to actual
|
|
37
37
|
files
|
|
38
|
+
6. **Aliases must resolve inside project** - Library code (`src/lib/`)
|
|
39
|
+
can only use aliases that resolve to paths inside the project folder
|
|
38
40
|
|
|
39
41
|
## Import Rules
|
|
40
42
|
|
|
@@ -180,6 +182,69 @@ import { current } from './existing-file.js';
|
|
|
180
182
|
them at build time or runtime. Helps prevent errors when refactoring
|
|
181
183
|
or moving files.
|
|
182
184
|
|
|
185
|
+
### Rule 6: Aliases must resolve inside the project
|
|
186
|
+
|
|
187
|
+
**Library code must only use aliases that resolve to paths inside the
|
|
188
|
+
project folder**
|
|
189
|
+
|
|
190
|
+
Aliases are designed for internal project structure, not external
|
|
191
|
+
packages. Due to Vite/SvelteKit limitations, aliases that point
|
|
192
|
+
outside the project folder or to package names cannot work correctly in
|
|
193
|
+
library code.
|
|
194
|
+
|
|
195
|
+
❌ Bad (aliases that don't work in `src/lib/`):
|
|
196
|
+
```javascript
|
|
197
|
+
// svelte.config.js
|
|
198
|
+
alias: {
|
|
199
|
+
// Points to node_modules (outside project)
|
|
200
|
+
'$ext-lib': 'node_modules/@some/library/dist',
|
|
201
|
+
|
|
202
|
+
// Package name (Vite treats as relative path, doesn't resolve)
|
|
203
|
+
'$pkg': '@some/library',
|
|
204
|
+
|
|
205
|
+
// Absolute path outside project
|
|
206
|
+
'$external': '/usr/local/lib/something'
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// In src/lib/ui/MyComponent.svelte
|
|
210
|
+
import { Button } from '$ext-lib/ui/primitives.js';
|
|
211
|
+
// ^ Breaks when building library!
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
✅ Good (use direct package imports):
|
|
215
|
+
```javascript
|
|
216
|
+
// In src/lib/ui/MyComponent.svelte
|
|
217
|
+
import { Button } from '@some/library/ui/primitives.js';
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
✅ Good (local aliases work everywhere):
|
|
221
|
+
```javascript
|
|
222
|
+
// svelte.config.js
|
|
223
|
+
alias: {
|
|
224
|
+
'$lib': 'src/lib', // ✅ Inside project
|
|
225
|
+
'$examples': 'src/routes/examples' // ✅ Inside project
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// In src/lib/ui/MyComponent.svelte
|
|
229
|
+
import { helper } from '$lib/util/helpers.js'; // ✅ Works!
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
✅ Also good (aliases work fine in app code):
|
|
233
|
+
```javascript
|
|
234
|
+
// In src/routes/+page.svelte (not built/published)
|
|
235
|
+
import { Button } from '$ext-lib/ui/primitives.js';
|
|
236
|
+
// ✅ OK - app code isn't published
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Scope:**
|
|
240
|
+
- **Enforced in**: `src/lib/**` (library code that gets built)
|
|
241
|
+
- **Allowed in**: `src/routes/**` (app code, not published)
|
|
242
|
+
|
|
243
|
+
**Why:** Vite/SvelteKit aliases are designed for internal project
|
|
244
|
+
structure. Build tools (`@sveltejs/package`, Vite) cannot properly
|
|
245
|
+
handle aliases pointing outside the project folder or to package names.
|
|
246
|
+
For external dependencies, use direct imports.
|
|
247
|
+
|
|
183
248
|
## How Module Resolution Works
|
|
184
249
|
|
|
185
250
|
Understanding how Node.js and Vite resolve imports helps explain
|
|
@@ -23,6 +23,15 @@ const EXTERNAL_SCOPES_TO_VALIDATE = ['@hkdigital'];
|
|
|
23
23
|
*/
|
|
24
24
|
let PROJECT_ALIASES = {};
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Unsafe aliases that don't resolve inside the project folder
|
|
28
|
+
* These break when building libraries with @sveltejs/package
|
|
29
|
+
*
|
|
30
|
+
* Maps alias name to suggested fix (package name or explanation)
|
|
31
|
+
* @type {Map<string, string>}
|
|
32
|
+
*/
|
|
33
|
+
const UNSAFE_ALIASES = new Map();
|
|
34
|
+
|
|
26
35
|
/**
|
|
27
36
|
* Load aliases from svelte.config.js
|
|
28
37
|
*
|
|
@@ -47,10 +56,66 @@ async function loadAliases() {
|
|
|
47
56
|
return {};
|
|
48
57
|
}
|
|
49
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Extract package name from node_modules path
|
|
61
|
+
*
|
|
62
|
+
* @param {string} path - Path containing node_modules
|
|
63
|
+
*
|
|
64
|
+
* @returns {string|null} Package name or null
|
|
65
|
+
*/
|
|
66
|
+
function extractPackageNameFromPath(path) {
|
|
67
|
+
// Find node_modules in the path
|
|
68
|
+
const match = path.match(/node_modules\/(@[^/]+\/[^/]+|[^/]+)/);
|
|
69
|
+
if (match) {
|
|
70
|
+
return match[1]; // Returns @scope/package or package
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Detect unsafe aliases that don't resolve inside the project
|
|
77
|
+
* Populates the UNSAFE_ALIASES map
|
|
78
|
+
*/
|
|
79
|
+
function detectUnsafeAliases() {
|
|
80
|
+
UNSAFE_ALIASES.clear();
|
|
81
|
+
|
|
82
|
+
for (const [alias, target] of Object.entries(PROJECT_ALIASES)) {
|
|
83
|
+
let suggestion = null;
|
|
84
|
+
|
|
85
|
+
// Resolve to absolute path
|
|
86
|
+
const resolvedPath = isAbsolute(target) ?
|
|
87
|
+
target : join(PROJECT_ROOT, target);
|
|
88
|
+
|
|
89
|
+
// Normalize both paths for comparison (resolve symlinks, etc.)
|
|
90
|
+
const normalizedResolved = resolve(resolvedPath);
|
|
91
|
+
const normalizedRoot = resolve(PROJECT_ROOT);
|
|
92
|
+
|
|
93
|
+
// Check if resolved path is inside the project folder
|
|
94
|
+
const isInsideProject = normalizedResolved.startsWith(normalizedRoot);
|
|
95
|
+
|
|
96
|
+
if (!isInsideProject) {
|
|
97
|
+
// Path is outside project - check if it's in node_modules
|
|
98
|
+
if (resolvedPath.includes('/node_modules/')) {
|
|
99
|
+
const packageName = extractPackageNameFromPath(resolvedPath);
|
|
100
|
+
if (packageName) {
|
|
101
|
+
suggestion = packageName;
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
// Outside project but not node_modules
|
|
105
|
+
suggestion = '(path outside project - use direct imports)';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (suggestion) {
|
|
109
|
+
UNSAFE_ALIASES.set(alias, suggestion);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
50
115
|
/**
|
|
51
116
|
* Resolve an alias path to its filesystem location
|
|
52
117
|
*
|
|
53
|
-
* @param {string} aliasPath - Import path using alias (e.g., $
|
|
118
|
+
* @param {string} aliasPath - Import path using alias (e.g., $examples/...)
|
|
54
119
|
*
|
|
55
120
|
* @returns {string|null} Resolved filesystem path or null
|
|
56
121
|
*/
|
|
@@ -379,9 +444,9 @@ async function findExternalBarrelExport(importPath, targetName) {
|
|
|
379
444
|
/**
|
|
380
445
|
* Find highest-level barrel export in alias path
|
|
381
446
|
*
|
|
382
|
-
* For $
|
|
383
|
-
* - Check $
|
|
384
|
-
* - Check $
|
|
447
|
+
* For $components/ui/primitives/buttons/index.js:
|
|
448
|
+
* - Check $components/ui/primitives.js
|
|
449
|
+
* - Check $components/ui.js
|
|
385
450
|
*
|
|
386
451
|
* @param {string} importPath - Alias import path
|
|
387
452
|
* @param {string} targetName - Name of export to find
|
|
@@ -538,6 +603,42 @@ async function validateFile(filePath) {
|
|
|
538
603
|
);
|
|
539
604
|
|
|
540
605
|
if (isAliasImport) {
|
|
606
|
+
// Find which alias is being used
|
|
607
|
+
let matchedAlias = null;
|
|
608
|
+
for (const alias of Object.keys(PROJECT_ALIASES)) {
|
|
609
|
+
if (importPath === alias || importPath.startsWith(alias + '/')) {
|
|
610
|
+
matchedAlias = alias;
|
|
611
|
+
break;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// Check for unsafe alias usage in library code
|
|
616
|
+
if (isInLib && matchedAlias && UNSAFE_ALIASES.has(matchedAlias)) {
|
|
617
|
+
const suggestion = UNSAFE_ALIASES.get(matchedAlias);
|
|
618
|
+
const pathAfterAlias = importPath.slice(matchedAlias.length);
|
|
619
|
+
|
|
620
|
+
// Construct suggested import if it's a package name
|
|
621
|
+
let errorMsg;
|
|
622
|
+
if (suggestion.startsWith('(')) {
|
|
623
|
+
// Generic message (not a package name)
|
|
624
|
+
errorMsg = `${relativePath}:${lineNum}\n` +
|
|
625
|
+
` from '${importPath}'\n` +
|
|
626
|
+
` => ${suggestion}`;
|
|
627
|
+
} else {
|
|
628
|
+
// Package name - construct full import path
|
|
629
|
+
const suggestedImport = suggestion + pathAfterAlias;
|
|
630
|
+
errorMsg = `${relativePath}:${lineNum}\n` +
|
|
631
|
+
` from '${importPath}'\n` +
|
|
632
|
+
` => from '${suggestedImport}' ` +
|
|
633
|
+
`(alias resolves outside project)`;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
errors.push(errorMsg);
|
|
637
|
+
|
|
638
|
+
// Skip further validation for this import
|
|
639
|
+
continue;
|
|
640
|
+
}
|
|
641
|
+
|
|
541
642
|
// Extract imported names from the import statement
|
|
542
643
|
const importedNames = extractImportNames(line);
|
|
543
644
|
|
|
@@ -981,6 +1082,22 @@ async function main() {
|
|
|
981
1082
|
console.log();
|
|
982
1083
|
}
|
|
983
1084
|
|
|
1085
|
+
// Detect unsafe aliases (outside project folder)
|
|
1086
|
+
detectUnsafeAliases();
|
|
1087
|
+
|
|
1088
|
+
if (UNSAFE_ALIASES.size > 0) {
|
|
1089
|
+
console.log(
|
|
1090
|
+
'⚠️ Unsafe aliases detected (resolve outside project folder):'
|
|
1091
|
+
);
|
|
1092
|
+
for (const [alias, suggestion] of UNSAFE_ALIASES.entries()) {
|
|
1093
|
+
console.log(
|
|
1094
|
+
` ${alias} → ${suggestion} ` +
|
|
1095
|
+
`(breaks in src/lib/, OK in src/routes/)`
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1098
|
+
console.log();
|
|
1099
|
+
}
|
|
1100
|
+
|
|
984
1101
|
const files = await findFiles(SRC_DIR);
|
|
985
1102
|
const allErrors = [];
|
|
986
1103
|
|