@ryanatkn/gro 0.141.1 → 0.142.0
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/changeset.task.d.ts.map +1 -1
- package/dist/changeset.task.js +2 -2
- package/dist/filer.d.ts +7 -0
- package/dist/filer.d.ts.map +1 -1
- package/dist/filer.js +28 -29
- package/dist/gro_config.d.ts +5 -0
- package/dist/gro_config.d.ts.map +1 -1
- package/dist/gro_config.js +3 -1
- package/dist/gro_plugin_sveltekit_library.js +4 -4
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +22 -16
- package/dist/moss_helpers.d.ts.map +1 -1
- package/dist/moss_helpers.js +2 -1
- package/dist/package.d.ts +326 -164
- package/dist/package.d.ts.map +1 -1
- package/dist/package.js +15 -15
- package/dist/package_json.d.ts +9 -6
- package/dist/package_json.d.ts.map +1 -1
- package/dist/package_json.js +19 -4
- package/dist/publish.task.d.ts.map +1 -1
- package/dist/publish.task.js +3 -8
- package/dist/reinstall.task.js +4 -4
- package/dist/resolve_node_specifier.d.ts +7 -1
- package/dist/resolve_node_specifier.d.ts.map +1 -1
- package/dist/resolve_node_specifier.js +77 -13
- package/dist/resolve_specifier.d.ts +2 -6
- package/dist/resolve_specifier.d.ts.map +1 -1
- package/dist/resolve_specifier.js +2 -6
- package/dist/src_json.d.ts +39 -3
- package/dist/src_json.d.ts.map +1 -1
- package/dist/sveltekit_config.d.ts +1 -1
- package/dist/sveltekit_config.d.ts.map +1 -1
- package/dist/sync.task.js +1 -1
- package/dist/upgrade.task.d.ts.map +1 -1
- package/dist/upgrade.task.js +4 -2
- package/dist/watch_dir.d.ts.map +1 -1
- package/dist/watch_dir.js +5 -5
- package/package.json +14 -14
- package/src/lib/changeset.task.ts +2 -1
- package/src/lib/filer.ts +37 -27
- package/src/lib/gro_config.ts +8 -0
- package/src/lib/gro_plugin_sveltekit_library.ts +4 -4
- package/src/lib/loader.ts +24 -16
- package/src/lib/moss_helpers.ts +2 -1
- package/src/lib/package.ts +15 -15
- package/src/lib/package_json.ts +21 -4
- package/src/lib/publish.task.ts +3 -9
- package/src/lib/reinstall.task.ts +4 -4
- package/src/lib/resolve_node_specifier.ts +99 -17
- package/src/lib/resolve_specifier.ts +2 -6
- package/src/lib/sveltekit_config.ts +1 -1
- package/src/lib/sync.task.ts +1 -1
- package/src/lib/upgrade.task.ts +4 -2
- package/src/lib/watch_dir.ts +6 -6
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
import {join} from 'node:path';
|
|
2
|
+
import {existsSync} from 'node:fs';
|
|
3
|
+
import {DEV} from 'esm-env';
|
|
2
4
|
|
|
3
|
-
import {Package_Json, load_package_json} from './package_json.js';
|
|
5
|
+
import {Package_Json, Package_Json_Exports, load_package_json} from './package_json.js';
|
|
4
6
|
import {paths} from './paths.js';
|
|
5
7
|
import {NODE_MODULES_DIRNAME} from './path_constants.js';
|
|
6
8
|
import type {Resolved_Specifier} from './resolve_specifier.js';
|
|
7
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Like `resolve_specifier` but for Node specifiers,
|
|
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`.
|
|
15
|
+
*/
|
|
8
16
|
export const resolve_node_specifier = (
|
|
9
17
|
specifier: string,
|
|
10
18
|
dir = paths.root,
|
|
11
|
-
|
|
19
|
+
parent_path?: string,
|
|
12
20
|
cache?: Record<string, Package_Json>,
|
|
13
|
-
|
|
14
|
-
|
|
21
|
+
throw_on_missing_package = true,
|
|
22
|
+
// TODO this needs to use `--conditions`/`-C` to determine the correct key
|
|
23
|
+
exports_condition = DEV ? 'development' : 'default',
|
|
24
|
+
): Resolved_Specifier | null => {
|
|
15
25
|
const raw = specifier.endsWith('?raw');
|
|
16
26
|
const mapped_specifier = raw ? specifier.substring(0, specifier.length - 4) : specifier;
|
|
17
27
|
|
|
18
|
-
|
|
28
|
+
// Parse the specifier
|
|
29
|
+
let idx: number = -1;
|
|
19
30
|
if (mapped_specifier[0] === '@') {
|
|
20
31
|
// get the index of the second `/`
|
|
21
32
|
let count = 0;
|
|
@@ -29,21 +40,47 @@ export const resolve_node_specifier = (
|
|
|
29
40
|
} else {
|
|
30
41
|
idx = mapped_specifier.indexOf('/');
|
|
31
42
|
}
|
|
32
|
-
const
|
|
33
|
-
const
|
|
43
|
+
const pkg_name = idx === -1 ? mapped_specifier : mapped_specifier.substring(0, idx);
|
|
44
|
+
const module_path = idx === -1 ? '' : mapped_specifier.substring(idx + 1);
|
|
45
|
+
const subpath = module_path ? './' + module_path : '.';
|
|
46
|
+
const package_dir = join(dir, NODE_MODULES_DIRNAME, pkg_name);
|
|
34
47
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
48
|
+
if (!existsSync(package_dir)) {
|
|
49
|
+
if (throw_on_missing_package) {
|
|
50
|
+
throw Error(
|
|
51
|
+
`Package not found at ${package_dir} for specifier ${specifier}, you may need to npm install or fix the path` +
|
|
52
|
+
(parent_path ? ` imported from ${parent_path}` : ''),
|
|
53
|
+
);
|
|
54
|
+
} else {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const package_json = load_package_json(package_dir, cache, false);
|
|
60
|
+
const {exported, exports_key} = resolve_subpath(package_json, specifier, subpath);
|
|
39
61
|
if (!exported) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
62
|
+
if (throw_on_missing_package) {
|
|
63
|
+
// same error message as Node
|
|
64
|
+
throw Error(
|
|
65
|
+
`[ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath '${subpath}' is not defined by 'exports' in ${package_dir}/package.json` +
|
|
66
|
+
(parent_path ? ` imported from ${parent_path}` : ''),
|
|
67
|
+
);
|
|
68
|
+
} else {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
45
71
|
}
|
|
46
|
-
const
|
|
72
|
+
const exported_value = resolve_exported_value(exported, exports_key, exports_condition);
|
|
73
|
+
if (exported_value === undefined) {
|
|
74
|
+
if (throw_on_missing_package) {
|
|
75
|
+
throw Error(
|
|
76
|
+
`Package subpath '${subpath}' does not define the key '${exports_key}' in 'exports' in ${package_dir}/package.json` +
|
|
77
|
+
(parent_path ? ` imported from ${parent_path}` : ''),
|
|
78
|
+
);
|
|
79
|
+
} else {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const path_id = join(package_dir, exported_value);
|
|
47
84
|
|
|
48
85
|
return {
|
|
49
86
|
path_id,
|
|
@@ -54,3 +91,48 @@ export const resolve_node_specifier = (
|
|
|
54
91
|
namespace: undefined,
|
|
55
92
|
};
|
|
56
93
|
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Resolves the subpath of a package.json `exports` field based on the `specifier`.
|
|
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';
|
|
104
|
+
|
|
105
|
+
const exported =
|
|
106
|
+
subpath === '.' && !package_json.exports
|
|
107
|
+
? {[exports_key]: package_json.main}
|
|
108
|
+
: package_json.exports?.[subpath];
|
|
109
|
+
|
|
110
|
+
return {exported, exports_key};
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Resolves the exported value based on the exports key and condition.
|
|
115
|
+
*/
|
|
116
|
+
const resolve_exported_value = (
|
|
117
|
+
exported: Exclude<Package_Json_Exports[string], undefined>,
|
|
118
|
+
exports_key: string,
|
|
119
|
+
exports_condition: string,
|
|
120
|
+
): string | undefined => {
|
|
121
|
+
let exported_value = typeof exported === 'string' ? exported : exported[exports_key];
|
|
122
|
+
|
|
123
|
+
// TODO best effort fallback, support `default` but fall back to `import` or `node` as the exports key.
|
|
124
|
+
if (exported_value === undefined && typeof exported !== 'string' && exports_key === 'default') {
|
|
125
|
+
exported_value = exported.import ?? exported.node;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Possibly resolve to conditional exports.
|
|
129
|
+
exported_value =
|
|
130
|
+
exported_value === undefined || typeof exported_value === 'string'
|
|
131
|
+
? exported_value
|
|
132
|
+
: (exported_value[exports_condition] ??
|
|
133
|
+
exported_value.default ??
|
|
134
|
+
exported_value.import ??
|
|
135
|
+
exported_value.node); // TODO this fallback has corner case bugs for off-spec exports
|
|
136
|
+
|
|
137
|
+
return exported_value;
|
|
138
|
+
};
|
|
@@ -20,13 +20,9 @@ export interface Resolved_Specifier {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* Maps
|
|
23
|
+
* Maps an import `specifier` relative to `dir`,
|
|
24
24
|
* and infer the correct extension following Vite conventions.
|
|
25
|
-
* If no `.js` file is found for the
|
|
26
|
-
* @param specifier
|
|
27
|
-
* @param dir - if defined, enables relative importers like from esbuild plugins
|
|
28
|
-
* @param passthrough_extensions - used to support specifiers that have no file extention, which Vite supports, so we do our best effort
|
|
29
|
-
* @returns
|
|
25
|
+
* If no `.js` file is found for the specifier on the filesystem, it assumes `.ts`.
|
|
30
26
|
*/
|
|
31
27
|
export const resolve_specifier = (specifier: string, dir: string): Resolved_Specifier => {
|
|
32
28
|
const raw = specifier.endsWith('?raw');
|
|
@@ -57,7 +57,7 @@ export interface Parsed_Sveltekit_Config {
|
|
|
57
57
|
private_prefix: string | undefined;
|
|
58
58
|
public_prefix: string | undefined;
|
|
59
59
|
svelte_compile_options: CompileOptions;
|
|
60
|
-
svelte_compile_module_options:
|
|
60
|
+
svelte_compile_module_options: ModuleCompileOptions;
|
|
61
61
|
svelte_preprocessors: PreprocessorGroup | PreprocessorGroup[] | undefined;
|
|
62
62
|
}
|
|
63
63
|
|
package/src/lib/sync.task.ts
CHANGED
|
@@ -26,7 +26,7 @@ export const task: Task<Args> = {
|
|
|
26
26
|
const {sveltekit, package_json, gen, install} = args;
|
|
27
27
|
|
|
28
28
|
if (install) {
|
|
29
|
-
const result = await spawn(
|
|
29
|
+
const result = await spawn(config.pm_cli, ['i']);
|
|
30
30
|
if (!result.ok) {
|
|
31
31
|
throw new Task_Error('Failed npm install');
|
|
32
32
|
}
|
package/src/lib/upgrade.task.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {Task_Error, type Task} from './task.js';
|
|
|
5
5
|
import {extract_deps, load_package_json, type Package_Json_Dep} from './package_json.js';
|
|
6
6
|
import {Git_Origin, git_pull} from './git.js';
|
|
7
7
|
import {spawn_cli} from './cli.js';
|
|
8
|
+
import {serialize_args, to_forwarded_args} from './args.js';
|
|
8
9
|
|
|
9
10
|
export const Args = z
|
|
10
11
|
.object({
|
|
@@ -27,7 +28,7 @@ export type Args = z.infer<typeof Args>;
|
|
|
27
28
|
export const task: Task<Args> = {
|
|
28
29
|
summary: 'upgrade deps',
|
|
29
30
|
Args,
|
|
30
|
-
run: async ({args, log}): Promise<void> => {
|
|
31
|
+
run: async ({args, log, config}): Promise<void> => {
|
|
31
32
|
const {_, only, origin, force, pull, dry} = args;
|
|
32
33
|
|
|
33
34
|
if (_.length && only.length) {
|
|
@@ -65,7 +66,8 @@ export const task: Task<Args> = {
|
|
|
65
66
|
if (force) {
|
|
66
67
|
install_args.push('--force');
|
|
67
68
|
}
|
|
68
|
-
|
|
69
|
+
install_args.push(...serialize_args(to_forwarded_args(config.pm_cli)));
|
|
70
|
+
await spawn(config.pm_cli, install_args);
|
|
69
71
|
|
|
70
72
|
// Sync in a new process to pick up any changes after installing, avoiding some errors.
|
|
71
73
|
await spawn_cli('gro', ['sync', '--no-install']); // don't install because we do above
|
package/src/lib/watch_dir.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {watch, type ChokidarOptions, type FSWatcher} from 'chokidar';
|
|
2
2
|
import {relative} from 'node:path';
|
|
3
3
|
import {statSync} from 'node:fs';
|
|
4
|
+
import {create_deferred, type Deferred} from '@ryanatkn/belt/async.js';
|
|
4
5
|
|
|
5
6
|
import type {Path_Filter} from './path.js';
|
|
6
7
|
|
|
@@ -42,13 +43,12 @@ export const watch_dir = ({
|
|
|
42
43
|
chokidar,
|
|
43
44
|
}: Options): Watch_Node_Fs => {
|
|
44
45
|
let watcher: FSWatcher | undefined;
|
|
45
|
-
let initing:
|
|
46
|
+
let initing: Deferred<void> | undefined;
|
|
46
47
|
|
|
47
48
|
return {
|
|
48
49
|
init: async () => {
|
|
49
|
-
if (initing) return initing;
|
|
50
|
-
|
|
51
|
-
initing = new Promise((r) => (resolve = r)); // TODO `create_deferred`?// cwd: chokidar?.cwd ?? process.cwd()
|
|
50
|
+
if (initing) return initing.promise;
|
|
51
|
+
initing = create_deferred();
|
|
52
52
|
watcher = watch(dir, {...chokidar});
|
|
53
53
|
watcher.on('add', (path) => {
|
|
54
54
|
const final_path = absolute ? path : relative(dir, path);
|
|
@@ -77,8 +77,8 @@ export const watch_dir = ({
|
|
|
77
77
|
on_change({type: 'delete', path: final_path, is_directory: true});
|
|
78
78
|
});
|
|
79
79
|
// wait until ready
|
|
80
|
-
watcher.once('ready', () => resolve());
|
|
81
|
-
await initing;
|
|
80
|
+
watcher.once('ready', () => initing?.resolve());
|
|
81
|
+
await initing.promise;
|
|
82
82
|
},
|
|
83
83
|
close: async () => {
|
|
84
84
|
initing = undefined;
|