@hkdigital/lib-core 0.5.71 → 0.5.73

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
@@ -303,17 +303,27 @@ pnpm run lint:imports
303
303
  node node_modules/@hkdigital/lib-core/scripts/validate-imports.mjs
304
304
  ```
305
305
 
306
+ **Alias support:**
307
+
308
+ The validator automatically reads path aliases from your
309
+ `svelte.config.js` and applies the same barrel export validation rules
310
+ to alias imports. This ensures consistent import patterns across:
311
+ - Internal `$lib/` imports
312
+ - Project aliases like `$hklib-core`, `$hklib-pro`, etc.
313
+ - External `@hkdigital/*` package imports
314
+
306
315
  **Validation rules (enforced for `src/lib/` files only):**
307
316
 
308
- 1. **Cross-domain imports** - Use `$lib/` instead of `../../../`
309
- 2. **Prefer barrel exports** - Use higher-level export files when available
310
- 3. **Parent index.js imports** - Use `$lib/` or import specific files
311
- 4. **Non-standard extensions** - Include full extension (e.g.,
317
+ 1. **Alias optimization** - Use `$lib` instead of `$src/lib` (built-in
318
+ SvelteKit alias)
319
+ 2. **Cross-domain imports** - Use `$lib/` instead of `../../../`
320
+ 3. **Prefer barrel exports** - Use higher-level export files when
321
+ available (applies to `$lib/`, aliases, and `@hkdigital/*` packages)
322
+ 4. **Parent index.js imports** - Use `$lib/` or import specific files
323
+ 5. **Non-standard extensions** - Include full extension (e.g.,
312
324
  `.svelte.js`)
313
- 5. **Directory imports** - Write explicitly or create barrel export file
314
- 6. **File existence** - All import paths must resolve to existing files
315
- 7. **External package optimization** - Suggests barrel exports for
316
- `@hkdigital/*` packages
325
+ 6. **Directory imports** - Write explicitly or create barrel export file
326
+ 7. **File existence** - All import paths must resolve to existing files
317
327
 
318
328
  **Barrel export preference:**
319
329
 
@@ -322,6 +332,10 @@ exports your target. This encourages shorter imports that can be
322
332
  combined:
323
333
 
324
334
  ```js
335
+ // Optimize built-in aliases:
336
+ import { MyComponent } from '$src/lib/ui/components.js';
337
+ // → Use: import { MyComponent } from '$lib/ui/components.js';
338
+
325
339
  // Internal imports - instead of deep imports:
326
340
  import ProfileBlocks from '$lib/ui/components/profile-blocks/ProfileBlocks.svelte';
327
341
  import Button from '$lib/ui/primitives/buttons/Button.svelte';
@@ -330,6 +344,14 @@ import Button from '$lib/ui/primitives/buttons/Button.svelte';
330
344
  import { ProfileBlocks } from '$lib/ui/components.js';
331
345
  import { Button } from '$lib/ui/primitives.js';
332
346
 
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
+
333
355
  // External imports - instead of deep imports:
334
356
  import { TextButton } from '@hkdigital/lib-core/ui/primitives/buttons/index.js';
335
357
  import { TextInput } from '@hkdigital/lib-core/ui/primitives/inputs/index.js';
@@ -341,7 +363,7 @@ import { TextButton, TextInput } from '@hkdigital/lib-core/ui/primitives.js';
341
363
  The validator checks from highest to lowest level (`$lib/ui.js` →
342
364
  `$lib/ui/components.js` → `$lib/ui/components/profile-blocks.js`) and
343
365
  suggests the highest-level file that exports your target. The same
344
- logic applies to external `@hkdigital/*` packages.
366
+ logic applies to project aliases and external `@hkdigital/*` packages.
345
367
 
346
368
  **Routes are exempt from strict rules:**
347
369
 
@@ -353,6 +375,17 @@ files.
353
375
  **Example output:**
354
376
 
355
377
  ```
378
+ Validating import paths...
379
+
380
+ Found project aliases:
381
+ $src → src
382
+ $examples → src/routes/examples
383
+ $hklib-core → src/lib
384
+
385
+ src/lib/ui/panels/Panel.svelte:3
386
+ from '$src/lib/ui/components.js'
387
+ => from '$lib/ui/components.js' (use built-in $lib alias)
388
+
356
389
  src/lib/ui/panels/Panel.svelte:6
357
390
  from '../../../components/profile-blocks/ProfileBlocks.svelte'
358
391
  => from '$lib/ui/components.js' (use barrel export)
@@ -362,6 +395,10 @@ src/lib/ui/pages/Profile.svelte:8
362
395
  => from '$lib/ui/components.js' (use barrel export for shorter imports)
363
396
 
364
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
+ src/lib/forms/LoginForm.svelte:6
365
402
  from '@hkdigital/lib-core/ui/primitives/buttons/index.js'
366
403
  => from '@hkdigital/lib-core/ui/primitives.js' (use barrel export)
367
404
 
@@ -370,9 +407,10 @@ src/routes/explorer/[...path]/+page.svelte:4
370
407
  ✅ Allowed in routes
371
408
  ```
372
409
 
373
- **What gets checked for external packages:**
410
+ **What gets checked for barrel export suggestions:**
374
411
 
375
- The validator only suggests barrel exports for:
412
+ The validator only suggests barrel exports (for `$lib/`, project aliases,
413
+ and external `@hkdigital/*` packages) for:
376
414
  - Explicit `index.js` imports
377
415
  - Component files (`.svelte`)
378
416
  - Class files (capitalized `.js` files)
@@ -380,6 +418,20 @@ The validator only suggests barrel exports for:
380
418
  Intentional imports like `helpers.js`, `config.js`, or other lowercase
381
419
  utility files are assumed to be the public API and won't be flagged.
382
420
 
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
+
383
435
  ### Import Patterns and Export Structure
384
436
 
385
437
  **Public exports use domain-specific files matching folder names:**
@@ -16,6 +16,7 @@
16
16
 
17
17
  // Create the state context at this level to ensure all children
18
18
  // have access to the same state instance
19
+ // svelte-ignore state_referenced_locally
19
20
  const dragState = createOrGetDragState(contextKey);
20
21
 
21
22
  /**
@@ -83,6 +83,7 @@
83
83
  ...attrs
84
84
  } = $props();
85
85
 
86
+ // svelte-ignore state_referenced_locally
86
87
  const dragState = createOrGetDragState(contextKey);
87
88
 
88
89
  const draggableId = dragState.newDraggableId();
@@ -84,6 +84,7 @@
84
84
  ...attrs
85
85
  } = $props();
86
86
 
87
+ // svelte-ignore state_referenced_locally
87
88
  const dragState = createOrGetDragState(contextKey);
88
89
  const dropZoneId = generateLocalId();
89
90
 
@@ -26,6 +26,7 @@
26
26
 
27
27
  let show = $state(false);
28
28
 
29
+ // svelte-ignore state_referenced_locally
29
30
  let controller = getLoadingController();
30
31
 
31
32
  async function progressListener(progress, id) {
@@ -54,6 +54,7 @@
54
54
  ...attrs
55
55
  } = $props();
56
56
 
57
+ // svelte-ignore state_referenced_locally
57
58
  createOrGetState(contextKey);
58
59
 
59
60
  //grid-cols-[repeat({cols},minmax(0,auto))]
@@ -33,6 +33,7 @@
33
33
  contextKey
34
34
  } = $props();
35
35
 
36
+ // svelte-ignore state_referenced_locally
36
37
  const selectorState = createOrGetState(contextKey);
37
38
  </script>
38
39
 
@@ -45,23 +45,24 @@
45
45
  icon = src?.[theme] ?? src?.['default'] ?? Object.values(src)?.[0];
46
46
  });
47
47
 
48
- if (size !== '100%') {
49
- if (size.slice(-1) !== '%') {
48
+ let normalizedSize = $derived.by(() => {
49
+ if (size !== '100%' && size.slice(-1) !== '%') {
50
50
  try {
51
- size = parseInt(size, 10) + 'px';
51
+ return parseInt(size, 10) + 'px';
52
52
  } catch (error) {
53
- size = '100%';
53
+ return '100%';
54
54
  }
55
55
  }
56
- }
56
+ return size;
57
+ });
57
58
  </script>
58
59
 
59
60
  <svg
60
61
  data-hk-icon
61
62
  {...icon?.a}
62
63
  xmlns="http://www.w3.org/2000/svg"
63
- width={size}
64
- height={size}
64
+ width={normalizedSize}
65
+ height={normalizedSize}
65
66
  class="{base} {classes}"
66
67
  {...attrs}
67
68
  >
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hkdigital/lib-core",
3
- "version": "0.5.71",
3
+ "version": "0.5.73",
4
4
  "author": {
5
5
  "name": "HKdigital",
6
6
  "url": "https://hkdigital.nl"
@@ -78,7 +78,7 @@
78
78
  "./*": "./dist/*"
79
79
  },
80
80
  "dependencies": {
81
- "@tailwindcss/postcss": "^4.1.11",
81
+ "@tailwindcss/postcss": "^4.1.18",
82
82
  "postcss": "^8.5.6"
83
83
  },
84
84
  "peerDependencies": {
@@ -99,45 +99,45 @@
99
99
  "vite-imagetools": "^8.0.0"
100
100
  },
101
101
  "devDependencies": {
102
- "@eslint/js": "^9.37.0",
103
- "@playwright/test": "^1.56.0",
102
+ "@eslint/js": "^9.39.2",
103
+ "@playwright/test": "^1.57.0",
104
104
  "@skeletonlabs/skeleton": "3.1.7",
105
105
  "@skeletonlabs/skeleton-svelte": "1.3.1",
106
106
  "@steeze-ui/heroicons": "^2.4.2",
107
107
  "@sveltejs/adapter-auto": "^6.1.1",
108
- "@sveltejs/adapter-node": "^5.4.0",
109
- "@sveltejs/kit": "^2.47.0",
110
- "@sveltejs/package": "^2.5.4",
111
- "@sveltejs/vite-plugin-svelte": "^6.2.1",
108
+ "@sveltejs/adapter-node": "^5.5.0",
109
+ "@sveltejs/kit": "^2.49.4",
110
+ "@sveltejs/package": "^2.5.7",
111
+ "@sveltejs/vite-plugin-svelte": "^6.2.4",
112
112
  "@tailwindcss/typography": "^0.5.19",
113
- "@testing-library/svelte": "^5.2.8",
113
+ "@testing-library/svelte": "^5.3.1",
114
114
  "@testing-library/user-event": "^14.6.1",
115
115
  "@types/eslint": "^9.6.1",
116
- "@types/node": "^24.8.0",
117
- "autoprefixer": "^10.4.21",
118
- "eslint": "^9.37.0",
116
+ "@types/node": "^24.10.8",
117
+ "autoprefixer": "^10.4.23",
118
+ "eslint": "^9.39.2",
119
119
  "eslint-config-prettier": "^10.1.8",
120
120
  "eslint-plugin-import": "^2.32.0",
121
- "eslint-plugin-svelte": "^3.12.4",
122
- "fake-indexeddb": "^6.2.3",
123
- "globals": "^16.4.0",
121
+ "eslint-plugin-svelte": "^3.14.0",
122
+ "fake-indexeddb": "^6.2.5",
123
+ "globals": "^16.5.0",
124
124
  "jsdom": "^26.1.0",
125
- "jsonwebtoken": "^9.0.2",
125
+ "jsonwebtoken": "^9.0.3",
126
126
  "npm-check-updates": "^18.3.1",
127
127
  "npm-run-all": "^4.1.5",
128
- "pino": "^9.13.1",
129
- "pino-pretty": "^13.1.2",
130
- "prettier": "^3.6.2",
131
- "prettier-plugin-svelte": "^3.4.0",
128
+ "pino": "^9.14.0",
129
+ "pino-pretty": "^13.1.3",
130
+ "prettier": "^3.7.4",
131
+ "prettier-plugin-svelte": "^3.4.1",
132
132
  "prettier-plugin-tailwindcss": "^0.6.14",
133
- "publint": "^0.3.14",
133
+ "publint": "^0.3.16",
134
134
  "standardized-audio-context-mock": "^9.7.24",
135
- "svelte": "^5.40.1",
136
- "svelte-check": "^4.3.3",
135
+ "svelte": "^5.46.3",
136
+ "svelte-check": "^4.3.5",
137
137
  "svelte-preprocess": "^6.0.3",
138
- "tailwindcss": "^4.1.14",
138
+ "tailwindcss": "^4.1.18",
139
139
  "typescript": "^5.9.3",
140
- "vite": "^7.1.10",
140
+ "vite": "^7.3.1",
141
141
  "vite-imagetools": "^8.0.0",
142
142
  "vitest": "^3.2.4"
143
143
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { readdir, readFile, stat } from 'node:fs/promises';
4
- import { join, relative, resolve, dirname } from 'node:path';
4
+ import { join, relative, resolve, dirname, isAbsolute } from 'node:path';
5
5
 
6
6
  const PROJECT_ROOT = process.cwd();
7
7
  const SRC_DIR = join(PROJECT_ROOT, 'src');
@@ -55,6 +55,12 @@ function resolveAliasPath(aliasPath) {
55
55
  for (const [alias, target] of Object.entries(PROJECT_ALIASES)) {
56
56
  if (aliasPath === alias || aliasPath.startsWith(alias + '/')) {
57
57
  const pathAfterAlias = aliasPath.slice(alias.length);
58
+
59
+ // If target is already absolute, use it directly
60
+ if (isAbsolute(target)) {
61
+ return join(target, pathAfterAlias);
62
+ }
63
+
58
64
  return join(PROJECT_ROOT, target, pathAfterAlias);
59
65
  }
60
66
  }
@@ -498,7 +504,22 @@ async function validateFile(filePath) {
498
504
  const importPathRaw = importMatch[1];
499
505
 
500
506
  // Strip query parameters (Vite asset imports like ?preset=render)
501
- const importPath = importPathRaw.split('?')[0];
507
+ let importPath = importPathRaw.split('?')[0];
508
+
509
+ // Check if using $src/lib when $lib is available (built-in SvelteKit)
510
+ // Report the issue and normalize the path for further validation
511
+ let hasSrcLibIssue = false;
512
+ if (importPath.startsWith('$src/lib/') || importPath === '$src/lib') {
513
+ hasSrcLibIssue = true;
514
+ const optimizedPath = importPath.replace('$src/lib', '$lib');
515
+ errors.push(
516
+ `${relativePath}:${lineNum}\n` +
517
+ ` from '${importPath}'\n` +
518
+ ` => from '${optimizedPath}' (use built-in $lib alias)`
519
+ );
520
+ // Normalize for further validation
521
+ importPath = optimizedPath;
522
+ }
502
523
 
503
524
  // Check if import uses a project alias
504
525
  const isAliasImport = Object.keys(PROJECT_ALIASES).some(
@@ -874,7 +895,14 @@ async function validateFile(filePath) {
874
895
  * Main validation function
875
896
  */
876
897
  async function main() {
877
- console.log('Validating import paths...\n');
898
+ // Load package version
899
+ const pkgJsonPath = join(PROJECT_ROOT, 'package.json');
900
+ const pkgJsonContent = await readFile(pkgJsonPath, 'utf-8');
901
+ const pkgJson = JSON.parse(pkgJsonContent);
902
+ console.log(
903
+ `@hkdigital/lib-core v${pkgJson.version} - ` +
904
+ `Validating import paths...\n`
905
+ );
878
906
 
879
907
  // Load project aliases from svelte.config.js
880
908
  PROJECT_ALIASES = await loadAliases();
@@ -902,7 +930,7 @@ async function main() {
902
930
  process.exit(1);
903
931
  }
904
932
 
905
- console.log(' All import paths are valid!');
933
+ console.log('\x1b[32m✔ All import paths are valid!\x1b[0m');
906
934
  }
907
935
 
908
936
  main().catch(error => {