@hkdigital/lib-core 0.5.80 → 0.5.83

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.
@@ -213,7 +213,7 @@ All loaders implement consistent loading state management:
213
213
 
214
214
  ```svelte
215
215
  <script>
216
- import { ImageBox } from '$lib/ui/components/index.js';
216
+ import { ImageBox } from '$lib/ui/typedef.js';
217
217
 
218
218
  // ImageBox uses ImageVariantsLoader internally
219
219
  const imageSource = [
@@ -259,4 +259,4 @@ try {
259
259
  - `toSingleImageMeta()` - Extract single image from variants
260
260
  - `calculateEffectiveWidth()` - Calculate optimal image dimensions
261
261
 
262
- All loaders provide built-in loading states, error handling, and memory management with automatic cleanup of object URLs.
262
+ All loaders provide built-in loading states, error handling, and memory management with automatic cleanup of object URLs.
@@ -8,8 +8,8 @@
8
8
  * // When using ServiceManager
9
9
  * import { ServiceManager } from './ServiceManager.js';
10
10
  *
11
- * // @ typedef {import('./typedef-service-manager.js').ServiceManagerConfig} ServiceManagerConfig
12
- * // @ typedef {import('./typedef-service-manager.js').ServiceRegistrationOptions} ServiceRegistrationOptions
11
+ * // @ typedef {import('../typedef.js').ServiceManagerConfig} ServiceManagerConfig
12
+ * // @ typedef {import('../typedef.js').ServiceRegistrationOptions} ServiceRegistrationOptions
13
13
  *
14
14
  * const config = {
15
15
  * environment: 'development',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hkdigital/lib-core",
3
- "version": "0.5.80",
3
+ "version": "0.5.83",
4
4
  "author": {
5
5
  "name": "HKdigital",
6
6
  "url": "https://hkdigital.nl"
@@ -15,6 +15,17 @@ const LIB_ROOT = dirname(SCRIPT_DIR);
15
15
  */
16
16
  const EXTERNAL_SCOPES_TO_VALIDATE = ['@hkdigital'];
17
17
 
18
+ /**
19
+ * Built-in SvelteKit aliases
20
+ * These are provided by SvelteKit and don't need to be in svelte.config.js
21
+ */
22
+ const SVELTEKIT_BUILT_IN_ALIASES = [
23
+ '$lib',
24
+ '$app',
25
+ '$env',
26
+ '$service-worker'
27
+ ];
28
+
18
29
  /**
19
30
  * Project aliases from svelte.config.js
20
31
  * Loaded dynamically at startup
@@ -559,28 +570,176 @@ async function validateFile(filePath) {
559
570
  const isInLib = filePath.includes('/src/lib/');
560
571
  const isInRoutes = filePath.includes('/src/routes/');
561
572
 
562
- // Check each line for import statements
573
+ // Check each line for import statements and JSDoc type imports
563
574
  const lines = content.split('\n');
564
575
  for (let index = 0; index < lines.length; index++) {
565
576
  const line = lines[index];
566
577
  const lineNum = index + 1;
567
578
 
568
- // Skip if not an import line
569
- if (!line.trim().startsWith('import ')) {
570
- continue;
579
+ let importPathRaw = null;
580
+ let isJSDocImport = false;
581
+
582
+ // Check for regular import statements
583
+ if (line.trim().startsWith('import ')) {
584
+ const importMatch = line.match(/from ['"]([^'"]+)['"]/);
585
+ if (importMatch) {
586
+ importPathRaw = importMatch[1];
587
+ }
588
+ }
589
+ // Check for JSDoc type imports: import('path')
590
+ else if (line.includes('import(')) {
591
+ // Match import('...') or import("...")
592
+ const jsdocMatch = line.match(/import\(['"]([^'"]+)['"]\)/);
593
+ if (jsdocMatch) {
594
+ importPathRaw = jsdocMatch[1];
595
+ isJSDocImport = true;
596
+ }
571
597
  }
572
598
 
573
- // Extract import path from line
574
- const importMatch = line.match(/from ['"]([^'"]+)['"]/);
575
- if (!importMatch) {
599
+ // Skip if no import found
600
+ if (!importPathRaw) {
576
601
  continue;
577
602
  }
578
603
 
579
- const importPathRaw = importMatch[1];
580
-
581
604
  // Strip query parameters (Vite asset imports like ?preset=render)
582
605
  let importPath = importPathRaw.split('?')[0];
583
606
 
607
+ // For JSDoc imports: only check unsafe aliases and file existence
608
+ if (isJSDocImport) {
609
+ // Check if using an unsafe alias
610
+ const isAliasImport = Object.keys(PROJECT_ALIASES).some(
611
+ alias => importPath === alias || importPath.startsWith(alias + '/')
612
+ );
613
+
614
+ if (isAliasImport && isInLib) {
615
+ let matchedAlias = null;
616
+ for (const alias of Object.keys(PROJECT_ALIASES)) {
617
+ if (importPath === alias || importPath.startsWith(alias + '/')) {
618
+ matchedAlias = alias;
619
+ break;
620
+ }
621
+ }
622
+
623
+ if (matchedAlias && UNSAFE_ALIASES.has(matchedAlias)) {
624
+ const suggestion = UNSAFE_ALIASES.get(matchedAlias);
625
+ const pathAfterAlias = importPath.slice(matchedAlias.length);
626
+
627
+ let errorMsg;
628
+ if (suggestion.startsWith('(')) {
629
+ errorMsg = `${relativePath}:${lineNum}\n` +
630
+ ` JSDoc import('${importPath}')\n` +
631
+ ` => ${suggestion}`;
632
+ } else {
633
+ const suggestedImport = suggestion + pathAfterAlias;
634
+ errorMsg = `${relativePath}:${lineNum}\n` +
635
+ ` JSDoc import('${importPath}')\n` +
636
+ ` => import('${suggestedImport}') ` +
637
+ `(alias resolves outside project)`;
638
+ }
639
+
640
+ errors.push(errorMsg);
641
+ // Skip file existence check if unsafe alias (already error)
642
+ continue;
643
+ }
644
+ }
645
+
646
+ // Check for unknown aliases in JSDoc imports
647
+ if (importPath.startsWith('$')) {
648
+ const aliasName = importPath.split('/')[0];
649
+ const isBuiltInAlias = SVELTEKIT_BUILT_IN_ALIASES.some(
650
+ builtIn => importPath === builtIn || importPath.startsWith(builtIn + '/')
651
+ );
652
+ const isConfiguredAlias = Object.keys(PROJECT_ALIASES).some(
653
+ alias => importPath === alias || importPath.startsWith(alias + '/')
654
+ );
655
+
656
+ if (!isBuiltInAlias && !isConfiguredAlias) {
657
+ errors.push(
658
+ `${relativePath}:${lineNum}\n` +
659
+ ` JSDoc import('${importPath}')\n` +
660
+ ` => Unknown alias '${aliasName}' (not configured in svelte.config.js)`
661
+ );
662
+ continue;
663
+ }
664
+ }
665
+
666
+ // Check file existence for JSDoc imports (skip external packages)
667
+ const isExternalPackage = !importPath.startsWith('./') &&
668
+ !importPath.startsWith('../') &&
669
+ !importPath.startsWith('$lib/') &&
670
+ !importPath.startsWith('$');
671
+
672
+ if (!isExternalPackage) {
673
+ // Resolve to filesystem path
674
+ let jsdocFsPath;
675
+ if (importPath.startsWith('$lib/')) {
676
+ jsdocFsPath = join(
677
+ PROJECT_ROOT,
678
+ importPath.replace('$lib/', 'src/lib/')
679
+ );
680
+ } else {
681
+ jsdocFsPath = resolve(dirname(filePath), importPath);
682
+ }
683
+
684
+ // Check if file exists
685
+ const possiblePaths = [];
686
+ if (importPath.match(/\.(js|svelte|svelte\.js|test\.js|spec\.js)$/)) {
687
+ possiblePaths.push(jsdocFsPath);
688
+ } else {
689
+ possiblePaths.push(jsdocFsPath);
690
+ possiblePaths.push(jsdocFsPath + '.js');
691
+ possiblePaths.push(jsdocFsPath + '.svelte');
692
+ possiblePaths.push(jsdocFsPath + '.svelte.js');
693
+ possiblePaths.push(jsdocFsPath + '/index.js');
694
+ possiblePaths.push(jsdocFsPath + '/index.svelte');
695
+ }
696
+
697
+ let fileExists = false;
698
+ for (const testPath of possiblePaths) {
699
+ try {
700
+ const stats = await stat(testPath);
701
+ if (stats.isFile()) {
702
+ fileExists = true;
703
+ break;
704
+ }
705
+ } catch {
706
+ // File doesn't exist, continue checking
707
+ }
708
+ }
709
+
710
+ if (!fileExists) {
711
+ errors.push(
712
+ `${relativePath}:${lineNum}\n` +
713
+ ` JSDoc import('${importPath}')\n` +
714
+ ` => Import path does not exist`
715
+ );
716
+ }
717
+ }
718
+
719
+ // Skip all other validations for JSDoc imports
720
+ continue;
721
+ }
722
+
723
+ // Check for unknown aliases (starts with $ but not configured)
724
+ if (importPath.startsWith('$')) {
725
+ const aliasName = importPath.split('/')[0];
726
+ const isBuiltInAlias = SVELTEKIT_BUILT_IN_ALIASES.some(
727
+ builtIn => importPath === builtIn || importPath.startsWith(builtIn + '/')
728
+ );
729
+ const isConfiguredAlias = Object.keys(PROJECT_ALIASES).some(
730
+ alias => importPath === alias || importPath.startsWith(alias + '/')
731
+ );
732
+
733
+ if (!isBuiltInAlias && !isConfiguredAlias) {
734
+ errors.push(
735
+ `${relativePath}:${lineNum}\n` +
736
+ ` from '${importPath}'\n` +
737
+ ` => Unknown alias '${aliasName}' (not configured in svelte.config.js)`
738
+ );
739
+ continue;
740
+ }
741
+ }
742
+
584
743
  // Check if using $src/lib when $lib is available (built-in SvelteKit)
585
744
  // Report the issue and normalize the path for further validation
586
745
  let hasSrcLibIssue = false;