@ryanatkn/gro 0.141.1 → 0.143.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/build.task.js +1 -1
- package/dist/changeset.task.d.ts.map +1 -1
- package/dist/changeset.task.js +4 -4
- package/dist/check.task.d.ts.map +1 -1
- package/dist/check.task.js +4 -2
- package/dist/clean_fs.js +1 -1
- package/dist/cli.js +1 -1
- package/dist/{path_constants.d.ts → constants.d.ts} +4 -1
- package/dist/constants.d.ts.map +1 -0
- package/dist/{path_constants.js → constants.js} +3 -0
- package/dist/deploy.task.js +1 -1
- package/dist/dev.task.js +1 -1
- package/dist/esbuild_plugin_svelte.js +1 -1
- package/dist/esbuild_plugin_sveltekit_local_imports.js +1 -1
- package/dist/esbuild_plugin_sveltekit_shim_app.js +1 -1
- package/dist/esbuild_plugin_sveltekit_shim_env.js +1 -1
- package/dist/filer.d.ts +7 -0
- package/dist/filer.d.ts.map +1 -1
- package/dist/filer.js +28 -29
- package/dist/format.task.d.ts.map +1 -1
- package/dist/format.task.js +2 -2
- package/dist/format_directory.d.ts +1 -1
- package/dist/format_directory.d.ts.map +1 -1
- package/dist/format_directory.js +5 -6
- package/dist/gen.task.js +1 -1
- package/dist/gro_config.d.ts +12 -2
- package/dist/gro_config.d.ts.map +1 -1
- package/dist/gro_config.js +10 -6
- package/dist/gro_helpers.d.ts +1 -1
- package/dist/gro_helpers.d.ts.map +1 -1
- package/dist/gro_helpers.js +3 -3
- package/dist/gro_plugin_server.js +4 -4
- package/dist/gro_plugin_sveltekit_app.d.ts.map +1 -1
- package/dist/gro_plugin_sveltekit_app.js +5 -5
- package/dist/gro_plugin_sveltekit_library.js +7 -7
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +23 -17
- package/dist/module.js +1 -1
- package/dist/moss_helpers.d.ts +1 -1
- package/dist/moss_helpers.d.ts.map +1 -1
- package/dist/moss_helpers.js +4 -3
- package/dist/package.d.ts +334 -172
- package/dist/package.d.ts.map +1 -1
- package/dist/package.js +51 -51
- package/dist/package_json.d.ts +9 -6
- package/dist/package_json.d.ts.map +1 -1
- package/dist/package_json.js +21 -6
- package/dist/package_meta.d.ts +1 -1
- package/dist/parse_imports.js +1 -1
- package/dist/paths.js +1 -1
- package/dist/publish.task.d.ts.map +1 -1
- package/dist/publish.task.js +7 -20
- package/dist/reinstall.task.js +11 -11
- 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 +78 -14
- 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/run_task.js +1 -1
- 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/sveltekit_config.js +1 -1
- package/dist/sveltekit_helpers.d.ts +3 -3
- package/dist/sveltekit_helpers.d.ts.map +1 -1
- package/dist/sveltekit_helpers.js +7 -7
- package/dist/sync.task.js +5 -5
- 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 +18 -18
- package/src/lib/build.task.ts +1 -1
- package/src/lib/changeset.task.ts +4 -3
- package/src/lib/check.task.ts +4 -2
- package/src/lib/clean_fs.ts +1 -1
- package/src/lib/cli.ts +1 -1
- package/src/lib/{path_constants.ts → constants.ts} +4 -0
- package/src/lib/deploy.task.ts +1 -1
- package/src/lib/dev.task.ts +1 -1
- package/src/lib/esbuild_plugin_svelte.ts +1 -1
- package/src/lib/esbuild_plugin_sveltekit_local_imports.ts +1 -1
- package/src/lib/esbuild_plugin_sveltekit_shim_app.ts +1 -1
- package/src/lib/esbuild_plugin_sveltekit_shim_env.ts +1 -1
- package/src/lib/filer.ts +37 -27
- package/src/lib/format.task.ts +10 -2
- package/src/lib/format_directory.ts +10 -9
- package/src/lib/gen.task.ts +1 -1
- package/src/lib/gro_config.ts +23 -5
- package/src/lib/gro_helpers.ts +3 -2
- package/src/lib/gro_plugin_server.ts +4 -4
- package/src/lib/gro_plugin_sveltekit_app.ts +7 -5
- package/src/lib/gro_plugin_sveltekit_library.ts +7 -7
- package/src/lib/loader.ts +25 -17
- package/src/lib/module.ts +1 -1
- package/src/lib/moss_helpers.ts +4 -2
- package/src/lib/package.ts +51 -51
- package/src/lib/package_json.ts +23 -6
- package/src/lib/package_meta.ts +1 -1
- package/src/lib/parse_imports.ts +1 -1
- package/src/lib/paths.ts +1 -1
- package/src/lib/publish.task.ts +7 -22
- package/src/lib/reinstall.task.ts +11 -11
- package/src/lib/resolve_node_specifier.ts +100 -18
- package/src/lib/resolve_specifier.ts +2 -6
- package/src/lib/run_task.ts +1 -1
- package/src/lib/sveltekit_config.ts +2 -2
- package/src/lib/sveltekit_helpers.ts +7 -4
- package/src/lib/sync.task.ts +5 -5
- package/src/lib/upgrade.task.ts +4 -2
- package/src/lib/watch_dir.ts +6 -6
- package/dist/path_constants.d.ts.map +0 -1
package/src/lib/filer.ts
CHANGED
|
@@ -18,6 +18,8 @@ import {resolve_specifier} from './resolve_specifier.js';
|
|
|
18
18
|
import {default_sveltekit_config} from './sveltekit_config.js';
|
|
19
19
|
import {map_sveltekit_aliases} from './sveltekit_helpers.js';
|
|
20
20
|
import {Unreachable_Error} from '@ryanatkn/belt/error.js';
|
|
21
|
+
import {resolve_node_specifier} from './resolve_node_specifier.js';
|
|
22
|
+
import type {Package_Json} from './package_json.js';
|
|
21
23
|
// TODO see below
|
|
22
24
|
// import {resolve_node_specifier} from './resolve_node_specifier.js';
|
|
23
25
|
|
|
@@ -31,6 +33,11 @@ export interface Source_File {
|
|
|
31
33
|
* We create the file in memory to track its dependents regardless of its existence on disk.
|
|
32
34
|
*/
|
|
33
35
|
contents: string | null;
|
|
36
|
+
/**
|
|
37
|
+
* Is the source file outside of the `root_dir` or excluded by `watch_dir_options.filter`?
|
|
38
|
+
*/
|
|
39
|
+
external: boolean;
|
|
40
|
+
ctime: number | null;
|
|
34
41
|
mtime: number | null;
|
|
35
42
|
dependents: Map<Path_Id, Source_File>;
|
|
36
43
|
dependencies: Map<Path_Id, Source_File>;
|
|
@@ -43,6 +50,7 @@ export type On_Filer_Change = (change: Watcher_Change, source_file: Source_File)
|
|
|
43
50
|
export interface Options {
|
|
44
51
|
watch_dir?: typeof watch_dir;
|
|
45
52
|
watch_dir_options?: Partial<Omit_Strict<Watch_Dir_Options, 'on_change'>>;
|
|
53
|
+
package_json_cache?: Record<string, Package_Json>;
|
|
46
54
|
}
|
|
47
55
|
|
|
48
56
|
export class Filer {
|
|
@@ -53,10 +61,13 @@ export class Filer {
|
|
|
53
61
|
#watch_dir: typeof watch_dir;
|
|
54
62
|
#watch_dir_options: Partial<Watch_Dir_Options>;
|
|
55
63
|
|
|
64
|
+
#package_json_cache: Record<string, Package_Json>;
|
|
65
|
+
|
|
56
66
|
constructor(options: Options = EMPTY_OBJECT) {
|
|
57
67
|
this.#watch_dir = options.watch_dir ?? watch_dir;
|
|
58
68
|
this.#watch_dir_options = options.watch_dir_options ?? EMPTY_OBJECT;
|
|
59
69
|
this.root_dir = resolve(options.watch_dir_options?.dir ?? paths.source);
|
|
70
|
+
this.#package_json_cache = options.package_json_cache ?? {};
|
|
60
71
|
}
|
|
61
72
|
|
|
62
73
|
#watching: Watch_Node_Fs | undefined;
|
|
@@ -74,11 +85,17 @@ export class Filer {
|
|
|
74
85
|
const file: Source_File = {
|
|
75
86
|
id,
|
|
76
87
|
contents: null,
|
|
88
|
+
external: this.#is_external(id), // TODO maybe filter externals by default? the user needs to configure the filer then
|
|
89
|
+
ctime: null,
|
|
77
90
|
mtime: null,
|
|
78
91
|
dependents: new Map(),
|
|
79
92
|
dependencies: new Map(),
|
|
80
93
|
};
|
|
81
94
|
this.files.set(id, file);
|
|
95
|
+
// TODO this may need to be batched/deferred
|
|
96
|
+
if (file.external) {
|
|
97
|
+
this.#on_change({type: 'add', path: file.id, is_directory: false});
|
|
98
|
+
}
|
|
82
99
|
return file;
|
|
83
100
|
};
|
|
84
101
|
|
|
@@ -86,8 +103,7 @@ export class Filer {
|
|
|
86
103
|
const file = this.get_or_create(id);
|
|
87
104
|
|
|
88
105
|
const stats = existsSync(id) ? statSync(id) : null;
|
|
89
|
-
|
|
90
|
-
// const mtime_changed = mtime_prev !== (stats?.mtimeMs ?? null);
|
|
106
|
+
file.ctime = stats?.ctimeMs ?? null;
|
|
91
107
|
file.mtime = stats?.mtimeMs ?? null;
|
|
92
108
|
|
|
93
109
|
const new_contents = stats ? readFileSync(id, 'utf8') : null;
|
|
@@ -109,36 +125,25 @@ export class Filer {
|
|
|
109
125
|
const path = map_sveltekit_aliases(specifier, aliases);
|
|
110
126
|
|
|
111
127
|
// The specifier `path` has now been mapped to its final form, so we can inspect it.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
128
|
+
const resolved =
|
|
129
|
+
path[0] === '.' || path[0] === '/'
|
|
130
|
+
? resolve_specifier(path, dir)
|
|
131
|
+
: resolve_node_specifier(path, undefined, file.id, this.#package_json_cache, false);
|
|
132
|
+
if (!resolved) continue; // ignore any missing imports like Node identifiers
|
|
133
|
+
const {path_id} = resolved;
|
|
134
|
+
dependencies_removed.delete(path_id);
|
|
135
|
+
if (!dependencies_before.has(path_id)) {
|
|
136
|
+
const d = this.get_or_create(path_id);
|
|
137
|
+
file.dependencies.set(d.id, d);
|
|
138
|
+
d.dependents.set(file.id, file);
|
|
120
139
|
}
|
|
121
|
-
// TODO this doesn't work
|
|
122
|
-
// const resolved =
|
|
123
|
-
// path[0] === '.' || path[0] === '/'
|
|
124
|
-
// ? resolve_specifier(path, dir)
|
|
125
|
-
// : resolve_node_specifier(path, dir);
|
|
126
|
-
// const {path_id} = resolved;
|
|
127
|
-
// dependencies_removed.delete(path_id);
|
|
128
|
-
// if (!dependencies_before.has(path_id)) {
|
|
129
|
-
// const d = this.get_or_create(path_id);
|
|
130
|
-
// file.dependencies.set(d.id, d);
|
|
131
|
-
// d.dependents.set(file.id, file);
|
|
132
|
-
// }
|
|
133
140
|
}
|
|
134
141
|
|
|
135
142
|
// update any removed dependencies
|
|
136
143
|
for (const dependency_removed of dependencies_removed) {
|
|
137
|
-
|
|
138
|
-
if (!deleted1) throw Error('expected to delete1 ' + file.id); // TODO @many delete if correct
|
|
144
|
+
file.dependencies.delete(dependency_removed);
|
|
139
145
|
const dependency_removed_file = this.get_or_create(dependency_removed);
|
|
140
|
-
|
|
141
|
-
if (!deleted2) throw Error('expected to delete2 ' + file.id); // TODO @many delete if correct
|
|
146
|
+
dependency_removed_file.dependents.delete(file.id);
|
|
142
147
|
}
|
|
143
148
|
|
|
144
149
|
return file;
|
|
@@ -203,7 +208,7 @@ export class Filer {
|
|
|
203
208
|
}
|
|
204
209
|
|
|
205
210
|
#on_change: Watcher_Change_Callback = (change) => {
|
|
206
|
-
if (change.is_directory) return;
|
|
211
|
+
if (change.is_directory) return; // TODO manage directories?
|
|
207
212
|
let source_file: Source_File | null;
|
|
208
213
|
switch (change.type) {
|
|
209
214
|
case 'add':
|
|
@@ -236,4 +241,9 @@ export class Filer {
|
|
|
236
241
|
this.#watching = undefined;
|
|
237
242
|
}
|
|
238
243
|
}
|
|
244
|
+
|
|
245
|
+
#is_external(id: string): boolean {
|
|
246
|
+
const {filter} = this.#watch_dir_options;
|
|
247
|
+
return !id.startsWith(this.root_dir + '/') || (!!filter && !filter(id, false));
|
|
248
|
+
}
|
|
239
249
|
}
|
package/src/lib/format.task.ts
CHANGED
|
@@ -17,10 +17,18 @@ export type Args = z.infer<typeof Args>;
|
|
|
17
17
|
export const task: Task<Args> = {
|
|
18
18
|
summary: 'format source files',
|
|
19
19
|
Args,
|
|
20
|
-
run: async ({args, log}) => {
|
|
20
|
+
run: async ({args, log, config}) => {
|
|
21
21
|
const {check} = args;
|
|
22
22
|
// TODO forward prettier args
|
|
23
|
-
const format_result = await format_directory(
|
|
23
|
+
const format_result = await format_directory(
|
|
24
|
+
log,
|
|
25
|
+
paths.source,
|
|
26
|
+
check,
|
|
27
|
+
undefined,
|
|
28
|
+
undefined,
|
|
29
|
+
undefined,
|
|
30
|
+
config.pm_cli,
|
|
31
|
+
);
|
|
24
32
|
if (!format_result.ok) {
|
|
25
33
|
throw new Task_Error(
|
|
26
34
|
`Failed ${check ? 'formatting check' : 'to format'}. ${print_spawn_result(format_result)}`,
|
|
@@ -9,14 +9,14 @@ import {
|
|
|
9
9
|
VITE_CONFIG_FILENAME,
|
|
10
10
|
TSCONFIG_FILENAME,
|
|
11
11
|
GRO_CONFIG_PATH,
|
|
12
|
-
|
|
12
|
+
PM_CLI_DEFAULT,
|
|
13
|
+
PRETTIER_CLI_DEFAULT,
|
|
14
|
+
} from './constants.js';
|
|
13
15
|
import {serialize_args, to_forwarded_args} from './args.js';
|
|
14
16
|
import {spawn_cli, to_cli_name, type Cli} from './cli.js';
|
|
15
17
|
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
const DEFAULT_EXTENSIONS = 'ts,js,json,svelte,html,css,md,yml';
|
|
19
|
-
const DEFAULT_ROOT_PATHS = `${[
|
|
18
|
+
const EXTENSIONS_DEFAULT = 'ts,js,json,svelte,html,css,md,yml';
|
|
19
|
+
const ROOT_PATHS_DEFAULT = `${[
|
|
20
20
|
README_FILENAME,
|
|
21
21
|
GRO_CONFIG_PATH,
|
|
22
22
|
SVELTEKIT_CONFIG_FILENAME,
|
|
@@ -35,9 +35,10 @@ export const format_directory = async (
|
|
|
35
35
|
log: Logger,
|
|
36
36
|
dir: string,
|
|
37
37
|
check = false,
|
|
38
|
-
extensions =
|
|
39
|
-
root_paths =
|
|
40
|
-
prettier_cli: string | Cli =
|
|
38
|
+
extensions = EXTENSIONS_DEFAULT,
|
|
39
|
+
root_paths = ROOT_PATHS_DEFAULT,
|
|
40
|
+
prettier_cli: string | Cli = PRETTIER_CLI_DEFAULT,
|
|
41
|
+
pm_cli: string = PM_CLI_DEFAULT,
|
|
41
42
|
): Promise<Spawn_Result> => {
|
|
42
43
|
const forwarded_args = to_forwarded_args(to_cli_name(prettier_cli));
|
|
43
44
|
forwarded_args[check ? 'check' : 'write'] = true;
|
|
@@ -49,7 +50,7 @@ export const format_directory = async (
|
|
|
49
50
|
const spawned = await spawn_cli(prettier_cli, serialized_args, log);
|
|
50
51
|
if (!spawned)
|
|
51
52
|
throw new Error(
|
|
52
|
-
`failed to find \`${to_cli_name(prettier_cli)}\` CLI locally or globally, do you need to run
|
|
53
|
+
`failed to find \`${to_cli_name(prettier_cli)}\` CLI locally or globally, do you need to run \`${pm_cli} install\`?`,
|
|
53
54
|
);
|
|
54
55
|
return spawned;
|
|
55
56
|
};
|
package/src/lib/gen.task.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {format_file} from './format_file.js';
|
|
|
10
10
|
import {print_path} from './paths.js';
|
|
11
11
|
import {log_error_reasons} from './task_logging.js';
|
|
12
12
|
import {write_gen_results, analyze_gen_results, find_genfiles, load_genfiles} from './gen.js';
|
|
13
|
-
import {SOURCE_DIRNAME} from './
|
|
13
|
+
import {SOURCE_DIRNAME} from './constants.js';
|
|
14
14
|
|
|
15
15
|
export const Args = z
|
|
16
16
|
.object({
|
package/src/lib/gro_config.ts
CHANGED
|
@@ -4,11 +4,13 @@ import {existsSync} from 'node:fs';
|
|
|
4
4
|
import {GRO_DIST_DIR, IS_THIS_GRO, paths} from './paths.js';
|
|
5
5
|
import {
|
|
6
6
|
GRO_CONFIG_PATH,
|
|
7
|
+
JS_CLI_DEFAULT,
|
|
7
8
|
NODE_MODULES_DIRNAME,
|
|
9
|
+
PM_CLI_DEFAULT,
|
|
8
10
|
SERVER_DIST_PATH,
|
|
9
11
|
SVELTEKIT_BUILD_DIRNAME,
|
|
10
12
|
SVELTEKIT_DIST_DIRNAME,
|
|
11
|
-
} from './
|
|
13
|
+
} from './constants.js';
|
|
12
14
|
import create_default_config from './gro.config.default.js';
|
|
13
15
|
import type {Create_Config_Plugins} from './plugin.js';
|
|
14
16
|
import type {Map_Package_Json} from './package_json.js';
|
|
@@ -40,6 +42,14 @@ export interface Gro_Config {
|
|
|
40
42
|
* directories and files are included if they pass all of these filters.
|
|
41
43
|
*/
|
|
42
44
|
search_filters: Path_Filter[];
|
|
45
|
+
/**
|
|
46
|
+
* The CLI to use that's compatible with `node`.
|
|
47
|
+
*/
|
|
48
|
+
js_cli: string;
|
|
49
|
+
/**
|
|
50
|
+
* The CLI to use that's compatible with `npm install` and `npm link`. Defaults to `'npm'`.
|
|
51
|
+
*/
|
|
52
|
+
pm_cli: string;
|
|
43
53
|
}
|
|
44
54
|
|
|
45
55
|
/**
|
|
@@ -52,6 +62,8 @@ export interface Raw_Gro_Config {
|
|
|
52
62
|
map_package_json?: Map_Package_Json | null;
|
|
53
63
|
task_root_dirs?: string[];
|
|
54
64
|
search_filters?: Path_Filter | Path_Filter[] | null;
|
|
65
|
+
js_cli?: string;
|
|
66
|
+
pm_cli?: string;
|
|
55
67
|
}
|
|
56
68
|
|
|
57
69
|
export type Create_Gro_Config = (
|
|
@@ -67,7 +79,9 @@ export const create_empty_gro_config = (): Gro_Config => ({
|
|
|
67
79
|
IS_THIS_GRO ? null : paths.root,
|
|
68
80
|
IS_THIS_GRO ? null : GRO_DIST_DIR,
|
|
69
81
|
].filter((v) => v !== null),
|
|
70
|
-
search_filters: [(id) => !
|
|
82
|
+
search_filters: [(id) => !SEARCH_EXCLUDER_DEFAULT.test(id)],
|
|
83
|
+
js_cli: JS_CLI_DEFAULT,
|
|
84
|
+
pm_cli: PM_CLI_DEFAULT,
|
|
71
85
|
});
|
|
72
86
|
|
|
73
87
|
/**
|
|
@@ -76,7 +90,7 @@ export const create_empty_gro_config = (): Gro_Config => ({
|
|
|
76
90
|
* Customize via `search_filters` in the `Gro_Config`.
|
|
77
91
|
* See the test cases for the exact behavior.
|
|
78
92
|
*/
|
|
79
|
-
export const
|
|
93
|
+
export const SEARCH_EXCLUDER_DEFAULT = new RegExp(
|
|
80
94
|
`(${
|
|
81
95
|
'(^|/)\\.[^/]+' + // exclude all `.`-prefixed directories
|
|
82
96
|
// TODO probably change to `pkg.name` instead of this catch-all (also `gro` below)
|
|
@@ -91,13 +105,13 @@ export const DEFAULT_SEARCH_EXCLUDER = new RegExp(
|
|
|
91
105
|
const default_map_package_json: Map_Package_Json = (package_json) => {
|
|
92
106
|
if (package_json.exports) {
|
|
93
107
|
package_json.exports = Object.fromEntries(
|
|
94
|
-
Object.entries(package_json.exports).filter(([k]) => !
|
|
108
|
+
Object.entries(package_json.exports).filter(([k]) => !EXPORTS_EXCLUDER_DEFAULT.test(k)),
|
|
95
109
|
);
|
|
96
110
|
}
|
|
97
111
|
return package_json;
|
|
98
112
|
};
|
|
99
113
|
|
|
100
|
-
export const
|
|
114
|
+
export const EXPORTS_EXCLUDER_DEFAULT = /(\.md|\.(test|ignore)\.|\/(test|fixtures|ignore)\/)/;
|
|
101
115
|
|
|
102
116
|
/**
|
|
103
117
|
* Transforms a `Raw_Gro_Config` to the more strict `Gro_Config`.
|
|
@@ -112,6 +126,8 @@ export const normalize_gro_config = (raw_config: Raw_Gro_Config): Gro_Config =>
|
|
|
112
126
|
map_package_json = empty_config.map_package_json,
|
|
113
127
|
task_root_dirs = empty_config.task_root_dirs,
|
|
114
128
|
search_filters = empty_config.search_filters,
|
|
129
|
+
js_cli = empty_config.js_cli,
|
|
130
|
+
pm_cli = empty_config.pm_cli,
|
|
115
131
|
} = raw_config;
|
|
116
132
|
return {
|
|
117
133
|
plugins,
|
|
@@ -122,6 +138,8 @@ export const normalize_gro_config = (raw_config: Raw_Gro_Config): Gro_Config =>
|
|
|
122
138
|
: search_filters
|
|
123
139
|
? [search_filters]
|
|
124
140
|
: [],
|
|
141
|
+
js_cli,
|
|
142
|
+
pm_cli,
|
|
125
143
|
};
|
|
126
144
|
};
|
|
127
145
|
|
package/src/lib/gro_helpers.ts
CHANGED
|
@@ -3,7 +3,7 @@ import {join, resolve} from 'node:path';
|
|
|
3
3
|
import {fileURLToPath} from 'node:url';
|
|
4
4
|
import {spawn, type Spawn_Result} from '@ryanatkn/belt/process.js';
|
|
5
5
|
|
|
6
|
-
import {NODE_MODULES_DIRNAME, SVELTEKIT_DIST_DIRNAME} from './
|
|
6
|
+
import {JS_CLI_DEFAULT, NODE_MODULES_DIRNAME, SVELTEKIT_DIST_DIRNAME} from './constants.js';
|
|
7
7
|
|
|
8
8
|
/*
|
|
9
9
|
|
|
@@ -84,6 +84,7 @@ export const spawn_with_loader = (
|
|
|
84
84
|
loader_path: string,
|
|
85
85
|
invoke_path: string,
|
|
86
86
|
argv: string[],
|
|
87
|
+
js_cli = JS_CLI_DEFAULT, // TODO source from config when possible
|
|
87
88
|
): Promise<Spawn_Result> => {
|
|
88
89
|
const args = [
|
|
89
90
|
'--import',
|
|
@@ -99,5 +100,5 @@ export const spawn_with_loader = (
|
|
|
99
100
|
args.push('-C', 'development'); // same as `--conditions`
|
|
100
101
|
}
|
|
101
102
|
args.push(invoke_path, ...argv);
|
|
102
|
-
return spawn(
|
|
103
|
+
return spawn(js_cli, args);
|
|
103
104
|
};
|
|
@@ -11,7 +11,7 @@ import {throttle} from '@ryanatkn/belt/throttle.js';
|
|
|
11
11
|
import type {Plugin} from './plugin.js';
|
|
12
12
|
import {base_path_to_path_id, LIB_DIRNAME, paths} from './paths.js';
|
|
13
13
|
import type {Path_Id} from './path.js';
|
|
14
|
-
import {GRO_DEV_DIRNAME, SERVER_DIST_PATH} from './
|
|
14
|
+
import {GRO_DEV_DIRNAME, SERVER_DIST_PATH} from './constants.js';
|
|
15
15
|
import {watch_dir, type Watch_Node_Fs} from './watch_dir.js';
|
|
16
16
|
import {init_sveltekit_config, default_sveltekit_config} from './sveltekit_config.js';
|
|
17
17
|
import {esbuild_plugin_sveltekit_shim_app} from './esbuild_plugin_sveltekit_shim_app.js';
|
|
@@ -119,7 +119,7 @@ export const gro_plugin_server = ({
|
|
|
119
119
|
target = 'esnext',
|
|
120
120
|
esbuild_build_options = identity,
|
|
121
121
|
rebuild_throttle_delay = 1000,
|
|
122
|
-
cli_command
|
|
122
|
+
cli_command,
|
|
123
123
|
run, // `dev` default is not available in this scope
|
|
124
124
|
}: Options = {}): Plugin => {
|
|
125
125
|
let build_ctx: esbuild.BuildContext | null = null;
|
|
@@ -129,7 +129,7 @@ export const gro_plugin_server = ({
|
|
|
129
129
|
|
|
130
130
|
return {
|
|
131
131
|
name: 'gro_plugin_server',
|
|
132
|
-
setup: async ({dev, watch, timings, log}) => {
|
|
132
|
+
setup: async ({dev, watch, timings, log, config}) => {
|
|
133
133
|
const parsed_sveltekit_config =
|
|
134
134
|
!sveltekit_config && strip_end(dir, '/') === process.cwd()
|
|
135
135
|
? default_sveltekit_config
|
|
@@ -256,7 +256,7 @@ export const gro_plugin_server = ({
|
|
|
256
256
|
cli_args.push('-C', 'development'); // same as `--conditions`
|
|
257
257
|
}
|
|
258
258
|
cli_args.push(server_outpath);
|
|
259
|
-
server_process = spawn_restartable_process(cli_command, cli_args);
|
|
259
|
+
server_process = spawn_restartable_process(cli_command ?? config.js_cli, cli_args);
|
|
260
260
|
}
|
|
261
261
|
},
|
|
262
262
|
teardown: async () => {
|
|
@@ -8,9 +8,9 @@ import {serialize_package_json, type Map_Package_Json, load_package_json} from '
|
|
|
8
8
|
import {Task_Error} from './task.js';
|
|
9
9
|
import {find_cli, spawn_cli, spawn_cli_process} from './cli.js';
|
|
10
10
|
import {type Map_Src_Json, serialize_src_json, create_src_json} from './src_json.js';
|
|
11
|
-
import {
|
|
11
|
+
import {EXPORTS_EXCLUDER_DEFAULT} from './gro_config.js';
|
|
12
12
|
import {default_sveltekit_config} from './sveltekit_config.js';
|
|
13
|
-
import {SOURCE_DIRNAME} from './
|
|
13
|
+
import {SOURCE_DIRNAME} from './constants.js';
|
|
14
14
|
import {VITE_CLI} from './sveltekit_helpers.js';
|
|
15
15
|
|
|
16
16
|
export interface Options {
|
|
@@ -57,10 +57,12 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
57
57
|
let sveltekit_process: Spawned_Process | undefined = undefined;
|
|
58
58
|
return {
|
|
59
59
|
name: 'gro_plugin_sveltekit_app',
|
|
60
|
-
setup: async ({dev, watch, log}) => {
|
|
60
|
+
setup: async ({dev, watch, log, config}) => {
|
|
61
61
|
const found_vite_cli = find_cli(vite_cli);
|
|
62
62
|
if (!found_vite_cli)
|
|
63
|
-
throw new Error(
|
|
63
|
+
throw new Error(
|
|
64
|
+
`Failed to find Vite CLI \`${vite_cli}\`, do you need to run \`${config.pm_cli} i\`?`,
|
|
65
|
+
);
|
|
64
66
|
if (dev) {
|
|
65
67
|
// `vite dev` in development mode
|
|
66
68
|
if (watch) {
|
|
@@ -123,7 +125,7 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
123
125
|
assets_path,
|
|
124
126
|
'.well-known',
|
|
125
127
|
well_known_src_files === true
|
|
126
|
-
? (file_path) => !
|
|
128
|
+
? (file_path) => !EXPORTS_EXCLUDER_DEFAULT.test(file_path)
|
|
127
129
|
: well_known_src_files,
|
|
128
130
|
)
|
|
129
131
|
: null,
|
|
@@ -28,17 +28,17 @@ export const gro_plugin_sveltekit_library = ({
|
|
|
28
28
|
}: Options = {}): Plugin => {
|
|
29
29
|
return {
|
|
30
30
|
name: 'gro_plugin_sveltekit_library',
|
|
31
|
-
setup: async ({dev, log}) => {
|
|
31
|
+
setup: async ({dev, log, config}) => {
|
|
32
32
|
if (!dev) {
|
|
33
|
-
await run_svelte_package(svelte_package_options, svelte_package_cli, log);
|
|
33
|
+
await run_svelte_package(svelte_package_options, svelte_package_cli, log, config.pm_cli);
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
|
-
adapt: async ({log, timings}) => {
|
|
36
|
+
adapt: async ({log, timings, config}) => {
|
|
37
37
|
const package_json = load_package_json();
|
|
38
38
|
|
|
39
|
-
//
|
|
39
|
+
// link the CLI binaries if they exist
|
|
40
40
|
if (package_json.bin) {
|
|
41
|
-
const
|
|
41
|
+
const timing_to_link = timings.start(`${config.pm_cli} link`);
|
|
42
42
|
await Promise.all(
|
|
43
43
|
Object.values(package_json.bin).map(async (bin_path) => {
|
|
44
44
|
const chmod_result = await spawn('chmod', ['+x', bin_path]);
|
|
@@ -47,11 +47,11 @@ export const gro_plugin_sveltekit_library = ({
|
|
|
47
47
|
}),
|
|
48
48
|
);
|
|
49
49
|
log.info(`linking`);
|
|
50
|
-
const link_result = await spawn(
|
|
50
|
+
const link_result = await spawn(config.pm_cli, ['link', '-f']); // TODO don't use `-f` unless necessary or at all?
|
|
51
51
|
if (!link_result.ok) {
|
|
52
52
|
throw new Task_Error(`Failed to link. ${print_spawn_result(link_result)}`);
|
|
53
53
|
}
|
|
54
|
-
|
|
54
|
+
timing_to_link();
|
|
55
55
|
}
|
|
56
56
|
},
|
|
57
57
|
};
|
package/src/lib/loader.ts
CHANGED
|
@@ -16,8 +16,8 @@ import {
|
|
|
16
16
|
} from './sveltekit_shim_app.js';
|
|
17
17
|
import {default_sveltekit_config} from './sveltekit_config.js';
|
|
18
18
|
import {SVELTE_MATCHER, SVELTE_RUNES_MATCHER} from './svelte_helpers.js';
|
|
19
|
-
import {paths} from './paths.js';
|
|
20
|
-
import {JSON_MATCHER, NODE_MODULES_DIRNAME, TS_MATCHER} from './
|
|
19
|
+
import {IS_THIS_GRO, paths} from './paths.js';
|
|
20
|
+
import {JSON_MATCHER, NODE_MODULES_DIRNAME, TS_MATCHER} from './constants.js';
|
|
21
21
|
import {to_define_import_meta_env, default_ts_transform_options} from './esbuild_helpers.js';
|
|
22
22
|
import {resolve_specifier} from './resolve_specifier.js';
|
|
23
23
|
import {resolve_node_specifier} from './resolve_node_specifier.js';
|
|
@@ -173,51 +173,59 @@ export const load: LoadHook = async (url, context, nextLoad) => {
|
|
|
173
173
|
};
|
|
174
174
|
|
|
175
175
|
export const resolve: ResolveHook = async (specifier, context, nextResolve) => {
|
|
176
|
+
let s = specifier;
|
|
177
|
+
|
|
178
|
+
// Support SvelteKit `$env` imports
|
|
176
179
|
if (
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
180
|
+
s === '$env/static/public' ||
|
|
181
|
+
s === '$env/static/private' ||
|
|
182
|
+
s === '$env/dynamic/public' ||
|
|
183
|
+
s === '$env/dynamic/private'
|
|
181
184
|
) {
|
|
182
185
|
// The returned `url` is validated before `load` is called,
|
|
183
186
|
// so we need a slightly roundabout strategy to pass through the specifier for virtual files.
|
|
184
187
|
return {
|
|
185
|
-
url: pathToFileURL(join(dir, 'src/lib',
|
|
188
|
+
url: pathToFileURL(join(dir, 'src/lib', s)).href,
|
|
186
189
|
format: 'module',
|
|
187
190
|
shortCircuit: true,
|
|
188
191
|
};
|
|
189
192
|
}
|
|
190
193
|
|
|
194
|
+
// Special case for Gro's dependencies that import into Gro.
|
|
195
|
+
// Without this, we'd need to add a dev dep to Gro for Gro, which causes problems.
|
|
196
|
+
if (IS_THIS_GRO && s.startsWith('@ryanatkn/gro')) {
|
|
197
|
+
s = join(dir, 'dist', s.substring(13));
|
|
198
|
+
}
|
|
199
|
+
|
|
191
200
|
const parent_url = context.parentURL;
|
|
192
201
|
if (!parent_url || NODE_MODULES_MATCHER.test(parent_url)) {
|
|
193
|
-
return nextResolve(
|
|
202
|
+
return nextResolve(s, context);
|
|
194
203
|
}
|
|
195
204
|
|
|
196
|
-
const shimmed = sveltekit_shim_app_specifiers.get(
|
|
205
|
+
const shimmed = sveltekit_shim_app_specifiers.get(s);
|
|
197
206
|
if (shimmed !== undefined) {
|
|
198
207
|
return nextResolve(shimmed, context);
|
|
199
208
|
}
|
|
200
209
|
|
|
201
|
-
|
|
210
|
+
s = map_sveltekit_aliases(s, aliases);
|
|
202
211
|
|
|
203
|
-
// The specifier
|
|
204
|
-
if (
|
|
212
|
+
// The specifier has now been mapped to its final form, so we can inspect it.
|
|
213
|
+
if (s[0] !== '.' && s[0] !== '/') {
|
|
205
214
|
// Resolve to `node_modules`.
|
|
206
|
-
if (SVELTE_MATCHER.test(
|
|
215
|
+
if (SVELTE_MATCHER.test(s) || JSON_MATCHER.test(s)) {
|
|
207
216
|
// Match the behavior of Vite and esbuild for Svelte and JSON imports.
|
|
208
|
-
//
|
|
209
|
-
const resolved = resolve_node_specifier(path, dir, parent_url, package_json_cache);
|
|
217
|
+
const resolved = resolve_node_specifier(s, dir, parent_url, package_json_cache)!; // `node:` specifiers shouldn't reach this point, so the assertion is safe
|
|
210
218
|
return {
|
|
211
219
|
url: pathToFileURL(resolved.path_id_with_querystring).href,
|
|
212
220
|
format: 'module',
|
|
213
221
|
shortCircuit: true,
|
|
214
222
|
};
|
|
215
223
|
} else {
|
|
216
|
-
return nextResolve(
|
|
224
|
+
return nextResolve(s, context);
|
|
217
225
|
}
|
|
218
226
|
}
|
|
219
227
|
|
|
220
|
-
const resolved = resolve_specifier(
|
|
228
|
+
const resolved = resolve_specifier(s, dirname(fileURLToPath(parent_url)));
|
|
221
229
|
|
|
222
230
|
return {
|
|
223
231
|
url: pathToFileURL(resolved.path_id_with_querystring).href,
|
package/src/lib/module.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {LIB_DIRNAME} from './paths.js';
|
|
2
|
-
import {SOURCE_DIR, SOURCE_DIRNAME} from './
|
|
2
|
+
import {SOURCE_DIR, SOURCE_DIRNAME} from './constants.js';
|
|
3
3
|
|
|
4
4
|
export const MODULE_PATH_SRC_PREFIX = SOURCE_DIR;
|
|
5
5
|
export const MODULE_PATH_LIB_PREFIX = `$${LIB_DIRNAME}/`;
|
package/src/lib/moss_helpers.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {existsSync} from 'node:fs';
|
|
|
3
3
|
import {resolve} from 'node:path';
|
|
4
4
|
|
|
5
5
|
import {has_dep, type Package_Json} from './package_json.js';
|
|
6
|
+
import {NODE_MODULES_DIRNAME, PM_CLI_DEFAULT} from './constants.js';
|
|
6
7
|
|
|
7
8
|
export const MOSS_PACKAGE_DEP_NAME = '@ryanatkn/moss';
|
|
8
9
|
|
|
@@ -10,13 +11,14 @@ export const MOSS_PACKAGE_DEP_NAME = '@ryanatkn/moss';
|
|
|
10
11
|
export const load_moss_plugin = async (
|
|
11
12
|
package_json?: Package_Json,
|
|
12
13
|
dep_name = MOSS_PACKAGE_DEP_NAME,
|
|
13
|
-
plugin_path =
|
|
14
|
+
plugin_path = `${NODE_MODULES_DIRNAME}/${dep_name}/dist/gro_plugin_moss.js`, // TODO maybe lookup from its `package_json.exports`? kinda unnecessary
|
|
14
15
|
local_plugin_path = 'src/lib/gro_plugin_moss.ts',
|
|
16
|
+
pm_cli = PM_CLI_DEFAULT, // TODO source from config when possible, is just needed for error messages
|
|
15
17
|
): Promise<Result<{gro_plugin_moss: any}, {message: string}>> => {
|
|
16
18
|
if (!has_dep(dep_name, package_json)) {
|
|
17
19
|
return {
|
|
18
20
|
ok: false,
|
|
19
|
-
message: `no dependency found in package.json for ${dep_name}, install it with
|
|
21
|
+
message: `no dependency found in package.json for ${dep_name}, install it with \`${pm_cli} install -D ${dep_name}\``,
|
|
20
22
|
};
|
|
21
23
|
}
|
|
22
24
|
|