@ryanatkn/gro 0.143.3 → 0.144.1
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/dist/esbuild_plugin_external_worker.d.ts +2 -2
- package/dist/esbuild_plugin_external_worker.d.ts.map +1 -1
- package/dist/esbuild_plugin_svelte.d.ts +2 -2
- package/dist/esbuild_plugin_svelte.d.ts.map +1 -1
- package/dist/esbuild_plugin_sveltekit_shim_alias.d.ts +2 -2
- package/dist/esbuild_plugin_sveltekit_shim_alias.d.ts.map +1 -1
- package/dist/esbuild_plugin_sveltekit_shim_app.d.ts +2 -2
- package/dist/esbuild_plugin_sveltekit_shim_app.d.ts.map +1 -1
- package/dist/esbuild_plugin_sveltekit_shim_env.d.ts +2 -2
- package/dist/esbuild_plugin_sveltekit_shim_env.d.ts.map +1 -1
- package/dist/filer.d.ts +3 -3
- package/dist/filer.d.ts.map +1 -1
- package/dist/filer.js +0 -2
- package/dist/gro.config.default.js +5 -5
- package/dist/gro_plugin_gen.d.ts +2 -2
- package/dist/gro_plugin_gen.d.ts.map +1 -1
- package/dist/gro_plugin_moss.d.ts +22 -0
- package/dist/gro_plugin_moss.d.ts.map +1 -0
- package/dist/gro_plugin_moss.js +100 -0
- package/dist/gro_plugin_server.d.ts +2 -2
- package/dist/gro_plugin_server.d.ts.map +1 -1
- package/dist/gro_plugin_sveltekit_app.d.ts +2 -2
- package/dist/gro_plugin_sveltekit_app.d.ts.map +1 -1
- package/dist/gro_plugin_sveltekit_library.d.ts +2 -2
- package/dist/gro_plugin_sveltekit_library.d.ts.map +1 -1
- package/dist/moss_helpers.d.ts +1 -1
- package/dist/moss_helpers.d.ts.map +1 -1
- package/dist/moss_helpers.js +3 -3
- package/dist/package.d.ts +17 -0
- package/dist/package.d.ts.map +1 -1
- package/dist/package.js +36 -20
- package/dist/package_json.d.ts +6 -4
- package/dist/package_json.d.ts.map +1 -1
- package/dist/package_json.js +12 -12
- package/dist/resolve_node_specifier.d.ts +2 -5
- package/dist/resolve_node_specifier.d.ts.map +1 -1
- package/dist/resolve_node_specifier.js +233 -44
- package/dist/sveltekit_helpers.d.ts +1 -1
- package/dist/sveltekit_helpers.d.ts.map +1 -1
- package/dist/sveltekit_helpers.js +2 -2
- package/dist/watch_dir.d.ts +2 -2
- package/dist/watch_dir.d.ts.map +1 -1
- package/package.json +12 -8
- package/src/lib/esbuild_plugin_external_worker.ts +2 -2
- package/src/lib/esbuild_plugin_svelte.ts +2 -2
- package/src/lib/esbuild_plugin_sveltekit_shim_alias.ts +2 -2
- package/src/lib/esbuild_plugin_sveltekit_shim_app.ts +2 -2
- package/src/lib/esbuild_plugin_sveltekit_shim_env.ts +2 -2
- package/src/lib/filer.ts +3 -6
- package/src/lib/gro.config.default.ts +5 -5
- package/src/lib/gro_plugin_gen.ts +2 -2
- package/src/lib/gro_plugin_moss.ts +140 -0
- package/src/lib/gro_plugin_server.ts +2 -2
- package/src/lib/gro_plugin_sveltekit_app.ts +2 -2
- package/src/lib/gro_plugin_sveltekit_library.ts +2 -2
- package/src/lib/moss_helpers.ts +2 -3
- package/src/lib/package.ts +36 -20
- package/src/lib/package_json.ts +15 -14
- package/src/lib/resolve_node_specifier.ts +267 -49
- package/src/lib/sveltekit_helpers.ts +1 -2
- package/src/lib/watch_dir.ts +2 -2
package/src/lib/package.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type {Src_Json} from './src_json.js';
|
|
|
5
5
|
|
|
6
6
|
export const package_json = {
|
|
7
7
|
name: '@ryanatkn/gro',
|
|
8
|
-
version: '0.
|
|
8
|
+
version: '0.144.1',
|
|
9
9
|
description: 'task runner and toolkit extending SvelteKit',
|
|
10
10
|
motto: 'generate, run, optimize',
|
|
11
11
|
glyph: '🌰',
|
|
@@ -44,11 +44,11 @@ export const package_json = {
|
|
|
44
44
|
'typescript',
|
|
45
45
|
],
|
|
46
46
|
dependencies: {
|
|
47
|
-
'@ryanatkn/belt': '^0.
|
|
47
|
+
'@ryanatkn/belt': '^0.26.0',
|
|
48
48
|
chokidar: '^4.0.1',
|
|
49
49
|
dotenv: '^16.4.5',
|
|
50
50
|
'es-module-lexer': '^1.5.4',
|
|
51
|
-
'esm-env': '^1.
|
|
51
|
+
'esm-env': '^1.1.4',
|
|
52
52
|
mri: '^1.2.0',
|
|
53
53
|
prettier: '^3.3.3',
|
|
54
54
|
'prettier-plugin-svelte': '^3.2.7',
|
|
@@ -61,21 +61,21 @@ export const package_json = {
|
|
|
61
61
|
'@changesets/changelog-git': '^0.2.0',
|
|
62
62
|
'@changesets/types': '^6.0.0',
|
|
63
63
|
'@ryanatkn/eslint-config': '^0.5.5',
|
|
64
|
-
'@ryanatkn/fuz': '^0.130.
|
|
65
|
-
'@ryanatkn/moss': '^0.
|
|
64
|
+
'@ryanatkn/fuz': '^0.130.3',
|
|
65
|
+
'@ryanatkn/moss': '^0.19.0',
|
|
66
66
|
'@sveltejs/adapter-static': '^3.0.6',
|
|
67
67
|
'@sveltejs/kit': '^2.7.3',
|
|
68
68
|
'@sveltejs/package': '^2.3.7',
|
|
69
69
|
'@sveltejs/vite-plugin-svelte': '^4.0.0',
|
|
70
70
|
'@types/fs-extra': '^11.0.4',
|
|
71
|
-
'@types/node': '^22.8.
|
|
71
|
+
'@types/node': '^22.8.4',
|
|
72
72
|
esbuild: '^0.21.5',
|
|
73
73
|
eslint: '^9.13.0',
|
|
74
74
|
'eslint-plugin-svelte': '^2.46.0',
|
|
75
|
-
svelte: '^5.1.
|
|
75
|
+
svelte: '^5.1.5',
|
|
76
76
|
'svelte-check': '^4.0.5',
|
|
77
77
|
typescript: '^5.6.3',
|
|
78
|
-
'typescript-eslint': '^8.
|
|
78
|
+
'typescript-eslint': '^8.12.1',
|
|
79
79
|
uvu: '^0.5.6',
|
|
80
80
|
},
|
|
81
81
|
prettier: {
|
|
@@ -157,6 +157,10 @@ export const package_json = {
|
|
|
157
157
|
types: './dist/gro_plugin_gen.d.ts',
|
|
158
158
|
default: './dist/gro_plugin_gen.js',
|
|
159
159
|
},
|
|
160
|
+
'./gro_plugin_moss.js': {
|
|
161
|
+
types: './dist/gro_plugin_moss.d.ts',
|
|
162
|
+
default: './dist/gro_plugin_moss.js',
|
|
163
|
+
},
|
|
160
164
|
'./gro_plugin_server.js': {
|
|
161
165
|
types: './dist/gro_plugin_server.d.ts',
|
|
162
166
|
default: './dist/gro_plugin_server.js',
|
|
@@ -267,7 +271,7 @@ export const package_json = {
|
|
|
267
271
|
|
|
268
272
|
export const src_json = {
|
|
269
273
|
name: '@ryanatkn/gro',
|
|
270
|
-
version: '0.
|
|
274
|
+
version: '0.144.1',
|
|
271
275
|
modules: {
|
|
272
276
|
'.': {
|
|
273
277
|
path: 'index.ts',
|
|
@@ -431,14 +435,14 @@ export const src_json = {
|
|
|
431
435
|
'./esbuild_plugin_external_worker.js': {
|
|
432
436
|
path: 'esbuild_plugin_external_worker.ts',
|
|
433
437
|
declarations: [
|
|
434
|
-
{name: '
|
|
438
|
+
{name: 'Esbuild_Plugin_External_Worker_Options', kind: 'type'},
|
|
435
439
|
{name: 'esbuild_plugin_external_worker', kind: 'function'},
|
|
436
440
|
],
|
|
437
441
|
},
|
|
438
442
|
'./esbuild_plugin_svelte.js': {
|
|
439
443
|
path: 'esbuild_plugin_svelte.ts',
|
|
440
444
|
declarations: [
|
|
441
|
-
{name: '
|
|
445
|
+
{name: 'Esbuild_Plugin_Svelte_Options', kind: 'type'},
|
|
442
446
|
{name: 'esbuild_plugin_svelte', kind: 'function'},
|
|
443
447
|
],
|
|
444
448
|
},
|
|
@@ -449,21 +453,21 @@ export const src_json = {
|
|
|
449
453
|
'./esbuild_plugin_sveltekit_shim_alias.js': {
|
|
450
454
|
path: 'esbuild_plugin_sveltekit_shim_alias.ts',
|
|
451
455
|
declarations: [
|
|
452
|
-
{name: '
|
|
456
|
+
{name: 'Esbuild_Plugin_Sveltekit_Shim_Alias_Options', kind: 'type'},
|
|
453
457
|
{name: 'esbuild_plugin_sveltekit_shim_alias', kind: 'function'},
|
|
454
458
|
],
|
|
455
459
|
},
|
|
456
460
|
'./esbuild_plugin_sveltekit_shim_app.js': {
|
|
457
461
|
path: 'esbuild_plugin_sveltekit_shim_app.ts',
|
|
458
462
|
declarations: [
|
|
459
|
-
{name: '
|
|
463
|
+
{name: 'Esbuild_Plugin_Sveltekit_Shim_App_Options', kind: 'type'},
|
|
460
464
|
{name: 'esbuild_plugin_sveltekit_shim_app', kind: 'function'},
|
|
461
465
|
],
|
|
462
466
|
},
|
|
463
467
|
'./esbuild_plugin_sveltekit_shim_env.js': {
|
|
464
468
|
path: 'esbuild_plugin_sveltekit_shim_env.ts',
|
|
465
469
|
declarations: [
|
|
466
|
-
{name: '
|
|
470
|
+
{name: 'Esbuild_Plugin_Sveltekit_Shim_Env_Options', kind: 'type'},
|
|
467
471
|
{name: 'esbuild_plugin_sveltekit_shim_env', kind: 'function'},
|
|
468
472
|
],
|
|
469
473
|
},
|
|
@@ -473,7 +477,7 @@ export const src_json = {
|
|
|
473
477
|
{name: 'Source_File', kind: 'type'},
|
|
474
478
|
{name: 'Cleanup_Watch', kind: 'type'},
|
|
475
479
|
{name: 'On_Filer_Change', kind: 'type'},
|
|
476
|
-
{name: '
|
|
480
|
+
{name: 'Filer_Options', kind: 'type'},
|
|
477
481
|
{name: 'Filer', kind: 'class'},
|
|
478
482
|
],
|
|
479
483
|
},
|
|
@@ -594,17 +598,28 @@ export const src_json = {
|
|
|
594
598
|
path: 'gro_plugin_gen.ts',
|
|
595
599
|
declarations: [
|
|
596
600
|
{name: 'Task_Args', kind: 'type'},
|
|
597
|
-
{name: '
|
|
601
|
+
{name: 'Gro_Plugin_Gen_Options', kind: 'type'},
|
|
598
602
|
{name: 'gro_plugin_gen', kind: 'function'},
|
|
599
603
|
{name: 'filter_dependents', kind: 'function'},
|
|
600
604
|
],
|
|
601
605
|
},
|
|
606
|
+
'./gro_plugin_moss.js': {
|
|
607
|
+
path: 'gro_plugin_moss.ts',
|
|
608
|
+
declarations: [
|
|
609
|
+
{name: 'MOSS_PACKAGE_DEP_NAME', kind: 'variable'},
|
|
610
|
+
{name: 'has_moss_dep', kind: 'function'},
|
|
611
|
+
{name: 'generate_classes_css', kind: 'function'},
|
|
612
|
+
{name: 'Task_Args', kind: 'type'},
|
|
613
|
+
{name: 'Options', kind: 'type'},
|
|
614
|
+
{name: 'gro_plugin_moss', kind: 'function'},
|
|
615
|
+
],
|
|
616
|
+
},
|
|
602
617
|
'./gro_plugin_server.js': {
|
|
603
618
|
path: 'gro_plugin_server.ts',
|
|
604
619
|
declarations: [
|
|
605
620
|
{name: 'SERVER_SOURCE_ID', kind: 'variable'},
|
|
606
621
|
{name: 'has_server', kind: 'function'},
|
|
607
|
-
{name: '
|
|
622
|
+
{name: 'Gro_Plugin_Server_Options', kind: 'type'},
|
|
608
623
|
{name: 'Outpaths', kind: 'type'},
|
|
609
624
|
{name: 'Create_Outpaths', kind: 'type'},
|
|
610
625
|
{name: 'gro_plugin_server', kind: 'function'},
|
|
@@ -613,7 +628,7 @@ export const src_json = {
|
|
|
613
628
|
'./gro_plugin_sveltekit_app.js': {
|
|
614
629
|
path: 'gro_plugin_sveltekit_app.ts',
|
|
615
630
|
declarations: [
|
|
616
|
-
{name: '
|
|
631
|
+
{name: 'Gro_Plugin_Sveltekit_App_Options', kind: 'type'},
|
|
617
632
|
{name: 'Host_Target', kind: 'type'},
|
|
618
633
|
{name: 'Copy_File_Filter', kind: 'type'},
|
|
619
634
|
{name: 'gro_plugin_sveltekit_app', kind: 'function'},
|
|
@@ -622,7 +637,7 @@ export const src_json = {
|
|
|
622
637
|
'./gro_plugin_sveltekit_library.js': {
|
|
623
638
|
path: 'gro_plugin_sveltekit_library.ts',
|
|
624
639
|
declarations: [
|
|
625
|
-
{name: '
|
|
640
|
+
{name: 'Gro_Plugin_Sveltekit_Library_Options', kind: 'type'},
|
|
626
641
|
{name: 'gro_plugin_sveltekit_library', kind: 'function'},
|
|
627
642
|
],
|
|
628
643
|
},
|
|
@@ -704,6 +719,7 @@ export const src_json = {
|
|
|
704
719
|
{name: 'Package_Json_Repository', kind: 'variable'},
|
|
705
720
|
{name: 'Package_Json_Author', kind: 'variable'},
|
|
706
721
|
{name: 'Package_Json_Funding', kind: 'variable'},
|
|
722
|
+
{name: 'Export_Value', kind: 'variable'},
|
|
707
723
|
{name: 'Package_Json_Exports', kind: 'variable'},
|
|
708
724
|
{name: 'Package_Json', kind: 'variable'},
|
|
709
725
|
{name: 'Map_Package_Json', kind: 'type'},
|
|
@@ -1037,7 +1053,7 @@ export const src_json = {
|
|
|
1037
1053
|
{name: 'Watcher_Change', kind: 'type'},
|
|
1038
1054
|
{name: 'Watcher_Change_Type', kind: 'type'},
|
|
1039
1055
|
{name: 'Watcher_Change_Callback', kind: 'type'},
|
|
1040
|
-
{name: '
|
|
1056
|
+
{name: 'Watch_Dir_Options', kind: 'type'},
|
|
1041
1057
|
{name: 'watch_dir', kind: 'function'},
|
|
1042
1058
|
],
|
|
1043
1059
|
},
|
package/src/lib/package_json.ts
CHANGED
|
@@ -63,20 +63,21 @@ export const Package_Json_Funding = z.union([
|
|
|
63
63
|
]);
|
|
64
64
|
export type Package_Json_Funding = z.infer<typeof Package_Json_Funding>;
|
|
65
65
|
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
export
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
66
|
+
// Helper to create a recursive type that represents export conditions and values
|
|
67
|
+
const create_export_value_schema = (): z.ZodType => {
|
|
68
|
+
return z.lazy(() => z.union([z.string(), z.null(), z.record(z.lazy(() => export_value_schema))]));
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// The base export value schema that can be a string, null, or nested conditions
|
|
72
|
+
const export_value_schema = create_export_value_schema();
|
|
73
|
+
export const Export_Value = export_value_schema;
|
|
74
|
+
export type Export_Value = z.infer<typeof Export_Value>;
|
|
75
|
+
|
|
76
|
+
// Package exports can be:
|
|
77
|
+
// 1. A string (shorthand for main export)
|
|
78
|
+
// 2. null (to block exports)
|
|
79
|
+
// 3. A record of export conditions/paths
|
|
80
|
+
export const Package_Json_Exports = z.union([z.string(), z.null(), z.record(export_value_schema)]);
|
|
80
81
|
export type Package_Json_Exports = z.infer<typeof Package_Json_Exports>;
|
|
81
82
|
|
|
82
83
|
/**
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import {join} from 'node:path';
|
|
1
|
+
import {join, extname} from 'node:path';
|
|
2
2
|
import {existsSync} from 'node:fs';
|
|
3
3
|
import {DEV} from 'esm-env';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {Export_Value, Package_Json, load_package_json} from './package_json.js';
|
|
6
6
|
import {paths} from './paths.js';
|
|
7
7
|
import {NODE_MODULES_DIRNAME} from './constants.js';
|
|
8
8
|
import type {Resolved_Specifier} from './resolve_specifier.js';
|
|
9
|
+
import {escape_regexp} from '@ryanatkn/belt/regexp.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
-
* typically those that aren't relative or absolute.
|
|
13
|
-
* Optionally return `null` instead of throwing by setting
|
|
14
|
-
* `throw_on_missing_package` to `false`.
|
|
12
|
+
* This likely has differences from Node - they should be fixed on a case-by-case basis.
|
|
15
13
|
*/
|
|
16
14
|
export const resolve_node_specifier = (
|
|
17
15
|
specifier: string,
|
|
@@ -19,8 +17,7 @@ export const resolve_node_specifier = (
|
|
|
19
17
|
parent_path?: string,
|
|
20
18
|
cache?: Record<string, Package_Json>,
|
|
21
19
|
throw_on_missing_package = true,
|
|
22
|
-
|
|
23
|
-
exports_condition = DEV ? 'development' : 'default',
|
|
20
|
+
exports_conditions = DEV ? ['development', 'node', 'import'] : ['production', 'node', 'import'],
|
|
24
21
|
): Resolved_Specifier | null => {
|
|
25
22
|
const raw = specifier.endsWith('?raw');
|
|
26
23
|
const mapped_specifier = raw ? specifier.substring(0, specifier.length - 4) : specifier;
|
|
@@ -28,7 +25,6 @@ export const resolve_node_specifier = (
|
|
|
28
25
|
// Parse the specifier
|
|
29
26
|
let idx: number = -1;
|
|
30
27
|
if (mapped_specifier[0] === '@') {
|
|
31
|
-
// get the index of the second `/`
|
|
32
28
|
let count = 0;
|
|
33
29
|
for (let i = 0; i < mapped_specifier.length; i++) {
|
|
34
30
|
if (mapped_specifier[i] === '/') count++;
|
|
@@ -40,12 +36,17 @@ export const resolve_node_specifier = (
|
|
|
40
36
|
} else {
|
|
41
37
|
idx = mapped_specifier.indexOf('/');
|
|
42
38
|
}
|
|
39
|
+
|
|
43
40
|
const pkg_name = idx === -1 ? mapped_specifier : mapped_specifier.substring(0, idx);
|
|
44
41
|
const module_path = idx === -1 ? '' : mapped_specifier.substring(idx + 1);
|
|
45
42
|
const subpath = module_path ? './' + module_path : '.';
|
|
46
43
|
const package_dir = join(dir, NODE_MODULES_DIRNAME, pkg_name);
|
|
47
44
|
|
|
48
|
-
|
|
45
|
+
// Check cache first
|
|
46
|
+
let package_json: Package_Json | undefined;
|
|
47
|
+
if (cache?.[pkg_name]) {
|
|
48
|
+
package_json = cache[pkg_name];
|
|
49
|
+
} else if (!existsSync(package_dir)) {
|
|
49
50
|
if (throw_on_missing_package) {
|
|
50
51
|
throw Error(
|
|
51
52
|
`Package not found at ${package_dir} for specifier ${specifier}, you may need to install packages or fix the path` +
|
|
@@ -54,13 +55,31 @@ export const resolve_node_specifier = (
|
|
|
54
55
|
} else {
|
|
55
56
|
return null;
|
|
56
57
|
}
|
|
58
|
+
} else {
|
|
59
|
+
package_json = load_package_json(package_dir, cache, false);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Handle self-referencing
|
|
63
|
+
if (parent_path?.startsWith(package_dir)) {
|
|
64
|
+
if (!package_json.exports) {
|
|
65
|
+
throw Error(
|
|
66
|
+
`Self-referencing is only available if package.json has "exports" field: ${specifier}` +
|
|
67
|
+
(parent_path ? ` imported from ${parent_path}` : ''),
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const exported = resolve_subpath(package_json, subpath);
|
|
73
|
+
|
|
74
|
+
if (typeof exported === 'string') {
|
|
75
|
+
const validated = validate_export_target(exported, throw_on_missing_package);
|
|
76
|
+
if (validated === null) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
57
79
|
}
|
|
58
80
|
|
|
59
|
-
const package_json = load_package_json(package_dir, cache, false);
|
|
60
|
-
const {exported, exports_key} = resolve_subpath(package_json, specifier, subpath);
|
|
61
81
|
if (!exported) {
|
|
62
82
|
if (throw_on_missing_package) {
|
|
63
|
-
// same error message as Node
|
|
64
83
|
throw Error(
|
|
65
84
|
`[ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath '${subpath}' is not defined by 'exports' in ${package_dir}/package.json` +
|
|
66
85
|
(parent_path ? ` imported from ${parent_path}` : ''),
|
|
@@ -69,18 +88,20 @@ export const resolve_node_specifier = (
|
|
|
69
88
|
return null;
|
|
70
89
|
}
|
|
71
90
|
}
|
|
72
|
-
|
|
91
|
+
|
|
92
|
+
const exported_value = resolve_exported_value(exported, exports_conditions);
|
|
73
93
|
if (exported_value === undefined) {
|
|
74
94
|
if (throw_on_missing_package) {
|
|
75
95
|
throw Error(
|
|
76
|
-
`
|
|
96
|
+
`No valid export found for subpath '${subpath}' in ${package_dir}/package.json with the following conditions: ${exports_conditions.join(', ')}` +
|
|
77
97
|
(parent_path ? ` imported from ${parent_path}` : ''),
|
|
78
98
|
);
|
|
79
99
|
} else {
|
|
80
100
|
return null;
|
|
81
101
|
}
|
|
82
102
|
}
|
|
83
|
-
|
|
103
|
+
|
|
104
|
+
const path_id = normalize_extension(join(package_dir, exported_value));
|
|
84
105
|
|
|
85
106
|
return {
|
|
86
107
|
path_id,
|
|
@@ -92,47 +113,244 @@ export const resolve_node_specifier = (
|
|
|
92
113
|
};
|
|
93
114
|
};
|
|
94
115
|
|
|
95
|
-
|
|
96
|
-
*
|
|
97
|
-
*/
|
|
98
|
-
const resolve_subpath = (
|
|
99
|
-
package_json: Package_Json,
|
|
100
|
-
specifier: string,
|
|
101
|
-
subpath: string,
|
|
102
|
-
): {exported: Package_Json_Exports[string]; exports_key: string} => {
|
|
103
|
-
const exports_key = specifier.endsWith('.svelte') ? 'svelte' : 'default';
|
|
116
|
+
const replace_wildcards = (pattern: string, wildcards: string[]): string => {
|
|
117
|
+
if (!pattern.includes('*')) return pattern;
|
|
104
118
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
119
|
+
let result = pattern;
|
|
120
|
+
let wildcard_index = 0;
|
|
121
|
+
while (result.includes('*') && wildcard_index < wildcards.length) {
|
|
122
|
+
result = result.replace('*', wildcards[wildcard_index++]);
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const resolve_subpath = (package_json: Package_Json, subpath: string): unknown => {
|
|
128
|
+
// If no exports field exists, fallback to main field for the root subpath
|
|
129
|
+
if (!package_json.exports) {
|
|
130
|
+
return subpath === '.' && package_json.main ? package_json.main : null;
|
|
131
|
+
}
|
|
109
132
|
|
|
110
|
-
|
|
133
|
+
const exports = package_json.exports;
|
|
134
|
+
|
|
135
|
+
// Handle exports sugar syntax
|
|
136
|
+
if (typeof exports === 'string') {
|
|
137
|
+
return subpath === '.' ? exports : null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
141
|
+
if (typeof exports === 'object' && exports !== null) {
|
|
142
|
+
// Check for exact match first
|
|
143
|
+
if (subpath in exports) {
|
|
144
|
+
return exports[subpath];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Sort patterns by specificity
|
|
148
|
+
const patterns = Object.entries(exports)
|
|
149
|
+
.filter(([pattern]) => pattern.includes('*'))
|
|
150
|
+
.map(([pattern, target]) => ({
|
|
151
|
+
pattern,
|
|
152
|
+
target,
|
|
153
|
+
static_prefix: pattern.split('*')[0],
|
|
154
|
+
segments: pattern.split('/').length,
|
|
155
|
+
wildcards: (pattern.match(/\*/g) ?? []).length,
|
|
156
|
+
}))
|
|
157
|
+
.sort((a, b) => {
|
|
158
|
+
// Sort by static prefix length first
|
|
159
|
+
const prefix_diff = b.static_prefix.length - a.static_prefix.length;
|
|
160
|
+
if (prefix_diff !== 0) return prefix_diff;
|
|
161
|
+
|
|
162
|
+
// Then by number of segments
|
|
163
|
+
const segment_diff = b.segments - a.segments;
|
|
164
|
+
if (segment_diff !== 0) return segment_diff;
|
|
165
|
+
|
|
166
|
+
// Then by number of wildcards (fewer is more specific)
|
|
167
|
+
const wildcard_diff = a.wildcards - b.wildcards;
|
|
168
|
+
if (wildcard_diff !== 0) return wildcard_diff;
|
|
169
|
+
|
|
170
|
+
// Finally by total pattern length
|
|
171
|
+
return b.pattern.length - a.pattern.length;
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// Track matched wildcards for later use
|
|
175
|
+
let matched_wildcards: string[] = [];
|
|
176
|
+
|
|
177
|
+
// Check patterns in order of specificity
|
|
178
|
+
for (const {pattern, target} of patterns) {
|
|
179
|
+
// Convert pattern to regex, handling path segments properly
|
|
180
|
+
const regex_pattern = pattern.split('*').map(escape_regexp).join('([^/]+)');
|
|
181
|
+
const regex = new RegExp(`^${regex_pattern}$`);
|
|
182
|
+
const match = subpath.match(regex);
|
|
183
|
+
|
|
184
|
+
if (match) {
|
|
185
|
+
// If this is a null pattern and it matches, block access
|
|
186
|
+
if (target === null) return null;
|
|
187
|
+
|
|
188
|
+
// Extract captured wildcards and store them
|
|
189
|
+
matched_wildcards = match.slice(1);
|
|
190
|
+
|
|
191
|
+
if (typeof target === 'string') {
|
|
192
|
+
return replace_wildcards(target, matched_wildcards);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (typeof target === 'object' && target !== null) {
|
|
196
|
+
// For conditional exports, return an object with resolved wildcards
|
|
197
|
+
return Object.fromEntries(
|
|
198
|
+
Object.entries(target).map(([key, value]) => {
|
|
199
|
+
if (typeof value === 'string') {
|
|
200
|
+
return [key, replace_wildcards(value, matched_wildcards)];
|
|
201
|
+
}
|
|
202
|
+
// Handle nested conditions
|
|
203
|
+
if (typeof value === 'object' && value !== null) {
|
|
204
|
+
return [
|
|
205
|
+
key,
|
|
206
|
+
Object.fromEntries(
|
|
207
|
+
Object.entries(value).map(([nested_key, nested_value]) => [
|
|
208
|
+
nested_key,
|
|
209
|
+
typeof nested_value === 'string'
|
|
210
|
+
? replace_wildcards(nested_value, matched_wildcards)
|
|
211
|
+
: nested_value,
|
|
212
|
+
]),
|
|
213
|
+
),
|
|
214
|
+
];
|
|
215
|
+
}
|
|
216
|
+
return [key, value];
|
|
217
|
+
}),
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Handle catch-all patterns for remaining cases
|
|
224
|
+
const catch_all_patterns = patterns.filter(
|
|
225
|
+
({pattern}) => pattern.endsWith('/*') || pattern === './*',
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
for (const {pattern, target} of catch_all_patterns) {
|
|
229
|
+
const base_pattern = pattern.slice(0, -1); // Remove trailing '*'
|
|
230
|
+
if (subpath.startsWith(base_pattern)) {
|
|
231
|
+
if (target === null) return null;
|
|
232
|
+
|
|
233
|
+
const remainder = subpath.slice(base_pattern.length);
|
|
234
|
+
if (typeof target === 'string') {
|
|
235
|
+
return target.slice(0, -1) + remainder;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return null;
|
|
111
242
|
};
|
|
112
243
|
|
|
113
|
-
/**
|
|
114
|
-
* Resolves the exported value based on the exports key and condition.
|
|
115
|
-
*/
|
|
116
244
|
const resolve_exported_value = (
|
|
117
|
-
exported:
|
|
118
|
-
|
|
119
|
-
exports_condition: string,
|
|
245
|
+
exported: Export_Value,
|
|
246
|
+
conditions: string[],
|
|
120
247
|
): string | undefined => {
|
|
121
|
-
|
|
248
|
+
if (typeof exported === 'string') {
|
|
249
|
+
return exported;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (typeof exported !== 'object' || exported === null) {
|
|
253
|
+
return undefined;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const exported_obj = exported as Record<string, unknown>;
|
|
257
|
+
|
|
258
|
+
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
|
259
|
+
let default_value: Export_Value | undefined;
|
|
260
|
+
|
|
261
|
+
// For each key in exported_obj, in order
|
|
262
|
+
for (const [condition, value] of Object.entries(exported_obj)) {
|
|
263
|
+
// Skip invalid conditions
|
|
264
|
+
if (!is_valid_condition(condition)) {
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (condition === 'default') {
|
|
269
|
+
// Store default value to try last
|
|
270
|
+
default_value = value;
|
|
271
|
+
} else if (conditions.includes(condition)) {
|
|
272
|
+
const resolved = resolve_exported_value(value, conditions);
|
|
273
|
+
if (resolved !== undefined) {
|
|
274
|
+
return resolved;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// If no conditions matched, try default
|
|
280
|
+
if (default_value !== undefined) {
|
|
281
|
+
const resolved = resolve_exported_value(default_value, conditions);
|
|
282
|
+
if (resolved !== undefined) {
|
|
283
|
+
return resolved;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return undefined;
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
const is_valid_condition = (condition: string): boolean => {
|
|
291
|
+
if (
|
|
292
|
+
condition.length === 0 ||
|
|
293
|
+
condition.startsWith('.') ||
|
|
294
|
+
condition.includes(',') ||
|
|
295
|
+
/^\d+$/.test(condition)
|
|
296
|
+
) {
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
return /^[a-zA-Z0-9:_\-=]+$/.test(condition);
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
const normalize_extension = (path: string): string => {
|
|
303
|
+
if (path.endsWith('.d.ts')) {
|
|
304
|
+
return path.slice(0, -5) + '.js';
|
|
305
|
+
}
|
|
122
306
|
|
|
123
|
-
//
|
|
124
|
-
if (
|
|
125
|
-
|
|
307
|
+
// No extension handling needed if path already has an extension
|
|
308
|
+
if (extname(path)) {
|
|
309
|
+
return path;
|
|
126
310
|
}
|
|
127
311
|
|
|
128
|
-
//
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
312
|
+
// If no extension at all, add .js
|
|
313
|
+
return path + '.js';
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
const validate_export_target = (target: string, throw_on_missing_package: boolean): void | null => {
|
|
317
|
+
// Must start with './'
|
|
318
|
+
if (!target.startsWith('./') && !target.startsWith('../')) {
|
|
319
|
+
if (throw_on_missing_package) {
|
|
320
|
+
throw new Error('ERR_INVALID_PACKAGE_TARGET: Export target must start with "./" or "../"');
|
|
321
|
+
} else {
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
136
325
|
|
|
137
|
-
|
|
326
|
+
// Can't contain node_modules
|
|
327
|
+
if (target.includes('node_modules')) {
|
|
328
|
+
if (throw_on_missing_package) {
|
|
329
|
+
throw new Error('ERR_INVALID_PACKAGE_TARGET: Export target cannot contain node_modules');
|
|
330
|
+
} else {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Check for package boundary escape
|
|
336
|
+
const parts = target.split('/');
|
|
337
|
+
let depth = 0;
|
|
338
|
+
|
|
339
|
+
for (const part of parts) {
|
|
340
|
+
if (part === '..') {
|
|
341
|
+
depth--;
|
|
342
|
+
// If we go above root, it's escaping the package boundary
|
|
343
|
+
if (depth < 0) {
|
|
344
|
+
if (throw_on_missing_package) {
|
|
345
|
+
throw new Error(
|
|
346
|
+
'ERR_INVALID_PACKAGE_TARGET: Export target cannot escape package boundary',
|
|
347
|
+
);
|
|
348
|
+
} else {
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
} else if (part !== '.' && part !== '') {
|
|
353
|
+
depth++;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
138
356
|
};
|
|
@@ -33,7 +33,6 @@ export const has_sveltekit_library = (
|
|
|
33
33
|
package_json?: Package_Json,
|
|
34
34
|
sveltekit_config: Parsed_Sveltekit_Config = default_sveltekit_config,
|
|
35
35
|
dep_name = SVELTE_PACKAGE_DEP_NAME,
|
|
36
|
-
pm_cli = PM_CLI_DEFAULT, // TODO source from config when possible, is just needed for error messages
|
|
37
36
|
): Result<object, {message: string}> => {
|
|
38
37
|
const has_sveltekit_app_result = has_sveltekit_app();
|
|
39
38
|
if (!has_sveltekit_app_result.ok) {
|
|
@@ -47,7 +46,7 @@ export const has_sveltekit_library = (
|
|
|
47
46
|
if (!has_dep(dep_name, package_json)) {
|
|
48
47
|
return {
|
|
49
48
|
ok: false,
|
|
50
|
-
message: `no dependency found in package.json for ${dep_name}
|
|
49
|
+
message: `no dependency found in package.json for ${dep_name}`,
|
|
51
50
|
};
|
|
52
51
|
}
|
|
53
52
|
|
package/src/lib/watch_dir.ts
CHANGED
|
@@ -20,7 +20,7 @@ export interface Watcher_Change {
|
|
|
20
20
|
export type Watcher_Change_Type = 'add' | 'update' | 'delete';
|
|
21
21
|
export type Watcher_Change_Callback = (change: Watcher_Change) => void;
|
|
22
22
|
|
|
23
|
-
export interface
|
|
23
|
+
export interface Watch_Dir_Options {
|
|
24
24
|
dir: string;
|
|
25
25
|
on_change: Watcher_Change_Callback;
|
|
26
26
|
filter?: Path_Filter | null | undefined;
|
|
@@ -41,7 +41,7 @@ export const watch_dir = ({
|
|
|
41
41
|
filter,
|
|
42
42
|
absolute = true,
|
|
43
43
|
chokidar,
|
|
44
|
-
}:
|
|
44
|
+
}: Watch_Dir_Options): Watch_Node_Fs => {
|
|
45
45
|
let watcher: FSWatcher | undefined;
|
|
46
46
|
let initing: Deferred<void> | undefined;
|
|
47
47
|
|