@ryanatkn/gro 0.178.0 → 0.180.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.d.ts +2 -0
- package/dist/build.task.d.ts.map +1 -1
- package/dist/build.task.js +14 -10
- package/dist/build_cache.d.ts +3 -3
- package/dist/build_cache.d.ts.map +1 -1
- package/dist/build_cache.js +53 -43
- package/dist/changeset.task.js +9 -9
- package/dist/clean_fs.d.ts +1 -1
- package/dist/clean_fs.d.ts.map +1 -1
- package/dist/clean_fs.js +3 -4
- package/dist/cli.d.ts +4 -4
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +11 -12
- package/dist/deploy.task.d.ts +7 -0
- package/dist/deploy.task.d.ts.map +1 -1
- package/dist/deploy.task.js +27 -14
- package/dist/esbuild_plugin_external_worker.js +1 -1
- package/dist/esbuild_plugin_svelte.js +4 -4
- package/dist/esbuild_plugin_sveltekit_local_imports.js +2 -2
- package/dist/filer.d.ts.map +1 -1
- package/dist/filer.js +103 -52
- package/dist/format_file.js +1 -1
- package/dist/gen.d.ts +1 -1
- package/dist/gen.d.ts.map +1 -1
- package/dist/gen.js +28 -22
- package/dist/gen.task.js +1 -1
- package/dist/gro.config.default.js +1 -1
- package/dist/gro_config.js +2 -2
- package/dist/gro_plugin_gen.js +1 -1
- package/dist/gro_plugin_server.js +2 -2
- package/dist/gro_plugin_sveltekit_app.d.ts.map +1 -1
- package/dist/gro_plugin_sveltekit_app.js +40 -36
- package/dist/gro_plugin_sveltekit_library.js +2 -1
- package/dist/input_path.d.ts +3 -3
- package/dist/input_path.d.ts.map +1 -1
- package/dist/input_path.js +16 -14
- package/dist/invoke_task.js +2 -2
- package/dist/lint.task.js +1 -1
- package/dist/loader.js +1 -1
- package/dist/modules.js +2 -2
- package/dist/package_json.d.ts +4 -4
- package/dist/package_json.d.ts.map +1 -1
- package/dist/package_json.js +12 -14
- package/dist/publish.task.js +6 -6
- package/dist/release.task.js +1 -1
- package/dist/resolve.task.js +2 -2
- package/dist/resolve_specifier.d.ts +1 -1
- package/dist/resolve_specifier.d.ts.map +1 -1
- package/dist/resolve_specifier.js +5 -4
- package/dist/run.task.js +2 -2
- package/dist/run_gen.d.ts.map +1 -1
- package/dist/run_gen.js +9 -8
- package/dist/run_task.js +4 -4
- package/dist/source_json.d.ts +2 -2
- package/dist/source_json.d.ts.map +1 -1
- package/dist/source_json.js +16 -15
- package/dist/sveltekit_helpers.js +3 -3
- package/dist/sveltekit_shim_env.js +1 -1
- package/dist/task.d.ts +1 -1
- package/dist/task.d.ts.map +1 -1
- package/dist/task.js +4 -4
- package/dist/test.task.d.ts.map +1 -1
- package/dist/test.task.js +5 -4
- package/dist/typecheck.task.js +3 -3
- package/dist/upgrade.task.js +4 -4
- package/package.json +7 -7
- package/src/lib/build.task.ts +15 -10
- package/src/lib/build_cache.ts +79 -63
- package/src/lib/changeset.task.ts +10 -10
- package/src/lib/clean_fs.ts +4 -4
- package/src/lib/cli.ts +15 -14
- package/src/lib/deploy.task.ts +30 -13
- package/src/lib/esbuild_plugin_external_worker.ts +1 -1
- package/src/lib/esbuild_plugin_svelte.ts +4 -4
- package/src/lib/esbuild_plugin_sveltekit_local_imports.ts +2 -2
- package/src/lib/filer.ts +111 -52
- package/src/lib/format_file.ts +1 -1
- package/src/lib/gen.task.ts +1 -1
- package/src/lib/gen.ts +52 -46
- package/src/lib/gro.config.default.ts +1 -1
- package/src/lib/gro_config.ts +2 -2
- package/src/lib/gro_plugin_gen.ts +1 -1
- package/src/lib/gro_plugin_server.ts +2 -2
- package/src/lib/gro_plugin_sveltekit_app.ts +49 -41
- package/src/lib/gro_plugin_sveltekit_library.ts +2 -2
- package/src/lib/input_path.ts +20 -21
- package/src/lib/invoke_task.ts +2 -2
- package/src/lib/lint.task.ts +1 -1
- package/src/lib/loader.ts +1 -1
- package/src/lib/modules.ts +2 -2
- package/src/lib/package_json.ts +16 -20
- package/src/lib/publish.task.ts +6 -6
- package/src/lib/release.task.ts +1 -1
- package/src/lib/resolve.task.ts +2 -2
- package/src/lib/resolve_specifier.ts +8 -4
- package/src/lib/run.task.ts +2 -2
- package/src/lib/run_gen.ts +15 -10
- package/src/lib/run_task.ts +4 -4
- package/src/lib/source_json.ts +25 -19
- package/src/lib/sveltekit_helpers.ts +3 -3
- package/src/lib/task.ts +11 -9
- package/src/lib/test.task.ts +4 -3
- package/src/lib/typecheck.task.ts +3 -3
- package/src/lib/upgrade.task.ts +4 -4
- package/dist/search_fs.d.ts +0 -26
- package/dist/search_fs.d.ts.map +0 -1
- package/dist/search_fs.js +0 -52
- package/src/lib/search_fs.ts +0 -100
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {SpawnedProcess} from '@ryanatkn/belt/process.js';
|
|
2
|
-
import {
|
|
2
|
+
import {cp, mkdir, rm, writeFile} from 'node:fs/promises';
|
|
3
3
|
import {dirname, join} from 'node:path';
|
|
4
|
+
import {fs_exists} from '@ryanatkn/belt/fs.js';
|
|
4
5
|
|
|
5
6
|
import type {Plugin} from './plugin.ts';
|
|
6
7
|
import {serialize_args, to_forwarded_args} from './args.ts';
|
|
@@ -57,7 +58,7 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
57
58
|
return {
|
|
58
59
|
name: 'gro_plugin_sveltekit_app',
|
|
59
60
|
setup: async ({dev, watch, log, config}) => {
|
|
60
|
-
const found_vite_cli = find_cli(vite_cli);
|
|
61
|
+
const found_vite_cli = await find_cli(vite_cli);
|
|
61
62
|
if (!found_vite_cli)
|
|
62
63
|
throw Error(
|
|
63
64
|
`Failed to find Vite CLI \`${vite_cli}\`, do you need to run \`${config.pm_cli} i\`?`,
|
|
@@ -66,7 +67,7 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
66
67
|
// `vite dev` in development mode
|
|
67
68
|
if (watch) {
|
|
68
69
|
const serialized_args = ['dev', ...serialize_args(to_forwarded_args(vite_cli))];
|
|
69
|
-
sveltekit_process = spawn_cli_process(found_vite_cli, serialized_args, log);
|
|
70
|
+
sveltekit_process = await spawn_cli_process(found_vite_cli, serialized_args, log);
|
|
70
71
|
} else {
|
|
71
72
|
log.debug(
|
|
72
73
|
`the SvelteKit app plugin is loaded but will not output anything` +
|
|
@@ -77,7 +78,7 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
77
78
|
// `vite build` in production mode
|
|
78
79
|
|
|
79
80
|
// `.well-known/package.json`
|
|
80
|
-
const package_json = load_package_json(); // TODO put in plugin context? same with sveltekit config?
|
|
81
|
+
const package_json = await load_package_json(); // TODO put in plugin context? same with sveltekit config?
|
|
81
82
|
if (well_known_package_json === undefined) {
|
|
82
83
|
well_known_package_json = package_json.public; // eslint-disable-line no-param-reassign
|
|
83
84
|
}
|
|
@@ -91,7 +92,7 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
91
92
|
|
|
92
93
|
// `.well-known/source.json` and `.well-known/src/`
|
|
93
94
|
const final_package_json = mapped_package_json ?? package_json;
|
|
94
|
-
const source_json = source_json_create(final_package_json, undefined, log);
|
|
95
|
+
const source_json = await source_json_create(final_package_json, undefined, log);
|
|
95
96
|
if (well_known_source_json === undefined) {
|
|
96
97
|
well_known_source_json = final_package_json.public; // eslint-disable-line no-param-reassign
|
|
97
98
|
}
|
|
@@ -100,7 +101,8 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
100
101
|
: well_known_source_json === true
|
|
101
102
|
? source_json
|
|
102
103
|
: await well_known_source_json(source_json);
|
|
103
|
-
const serialized_source_json =
|
|
104
|
+
const serialized_source_json =
|
|
105
|
+
mapped_source_json && source_json_serialize(mapped_source_json);
|
|
104
106
|
|
|
105
107
|
// TODO this strategy means the files aren't available during development --
|
|
106
108
|
// maybe a Vite middleware is best? what if this plugin added its plugin to your `vite.config.ts`?
|
|
@@ -108,7 +110,7 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
108
110
|
// copy files to `static` before building, in such a way
|
|
109
111
|
// that's non-destructive to existing files and dirs and easy to clean up
|
|
110
112
|
const {assets_path} = default_svelte_config;
|
|
111
|
-
const
|
|
113
|
+
const cleanup_promises = [
|
|
112
114
|
serialized_package_json
|
|
113
115
|
? create_temporarily(
|
|
114
116
|
join(assets_path, '.well-known/package.json'),
|
|
@@ -116,7 +118,10 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
116
118
|
)
|
|
117
119
|
: null,
|
|
118
120
|
serialized_source_json
|
|
119
|
-
? create_temporarily(
|
|
121
|
+
? create_temporarily(
|
|
122
|
+
join(assets_path, '.well-known/source.json'),
|
|
123
|
+
serialized_source_json,
|
|
124
|
+
)
|
|
120
125
|
: null,
|
|
121
126
|
serialized_source_json && well_known_src_files
|
|
122
127
|
? copy_temporarily(
|
|
@@ -137,9 +142,11 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
137
142
|
host_target === 'github_pages'
|
|
138
143
|
? create_temporarily(join(assets_path, '.nojekyll'), '')
|
|
139
144
|
: null,
|
|
140
|
-
].filter((v) => v != null);
|
|
141
|
-
const
|
|
142
|
-
|
|
145
|
+
].filter((v): v is Promise<AsyncCleanup> => v != null);
|
|
146
|
+
const cleanups = await Promise.all(cleanup_promises);
|
|
147
|
+
const cleanup = async () => {
|
|
148
|
+
// eslint-disable-next-line no-await-in-loop
|
|
149
|
+
for (const c of cleanups) await c();
|
|
143
150
|
};
|
|
144
151
|
try {
|
|
145
152
|
const serialized_args = ['build', ...serialize_args(to_forwarded_args(vite_cli))];
|
|
@@ -147,11 +154,11 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
147
154
|
if (!spawned?.ok) {
|
|
148
155
|
throw new TaskError(`${vite_cli} build failed with exit code ${spawned?.code}`);
|
|
149
156
|
}
|
|
150
|
-
} catch (
|
|
151
|
-
cleanup();
|
|
152
|
-
throw
|
|
157
|
+
} catch (error) {
|
|
158
|
+
await cleanup();
|
|
159
|
+
throw error;
|
|
153
160
|
}
|
|
154
|
-
cleanup();
|
|
161
|
+
await cleanup();
|
|
155
162
|
}
|
|
156
163
|
},
|
|
157
164
|
teardown: async () => {
|
|
@@ -163,41 +170,41 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
163
170
|
};
|
|
164
171
|
};
|
|
165
172
|
|
|
166
|
-
type
|
|
173
|
+
type AsyncCleanup = () => Promise<void>;
|
|
167
174
|
|
|
168
175
|
// TODO probably extract these, and create a common helper or merge them
|
|
169
176
|
|
|
170
|
-
const copy_temporarily = (
|
|
177
|
+
const copy_temporarily = async (
|
|
171
178
|
source_path: string,
|
|
172
179
|
dest_dir: string,
|
|
173
180
|
dest_base_dir = '',
|
|
174
181
|
filter?: CopyFileFilter,
|
|
175
|
-
):
|
|
182
|
+
): Promise<AsyncCleanup> => {
|
|
176
183
|
const path = join(dest_dir, dest_base_dir, source_path);
|
|
177
184
|
const dir = dirname(path);
|
|
178
185
|
|
|
179
|
-
const dir_already_exists =
|
|
186
|
+
const dir_already_exists = await fs_exists(dir);
|
|
180
187
|
let root_created_dir: string | undefined;
|
|
181
188
|
if (!dir_already_exists) {
|
|
182
|
-
root_created_dir = to_root_dir_that_doesnt_exist(dir);
|
|
189
|
+
root_created_dir = await to_root_dir_that_doesnt_exist(dir);
|
|
183
190
|
if (!root_created_dir) throw Error();
|
|
184
|
-
|
|
191
|
+
await mkdir(dir, {recursive: true});
|
|
185
192
|
}
|
|
186
193
|
|
|
187
|
-
const path_already_exists =
|
|
194
|
+
const path_already_exists = await fs_exists(path);
|
|
188
195
|
if (!path_already_exists) {
|
|
189
|
-
|
|
196
|
+
await cp(source_path, path, {recursive: true, filter});
|
|
190
197
|
}
|
|
191
198
|
|
|
192
|
-
return () => {
|
|
199
|
+
return async () => {
|
|
193
200
|
if (!dir_already_exists) {
|
|
194
201
|
if (!root_created_dir) throw Error();
|
|
195
|
-
if (
|
|
196
|
-
|
|
202
|
+
if (await fs_exists(root_created_dir)) {
|
|
203
|
+
await rm(root_created_dir, {recursive: true});
|
|
197
204
|
}
|
|
198
205
|
} else if (!path_already_exists) {
|
|
199
|
-
if (
|
|
200
|
-
|
|
206
|
+
if (await fs_exists(path)) {
|
|
207
|
+
await rm(path, {recursive: true});
|
|
201
208
|
}
|
|
202
209
|
}
|
|
203
210
|
};
|
|
@@ -210,31 +217,31 @@ const copy_temporarily = (
|
|
|
210
217
|
* @param contents
|
|
211
218
|
* @returns cleanup function that deletes the file and any created dirs
|
|
212
219
|
*/
|
|
213
|
-
const create_temporarily = (path: string, contents: string):
|
|
220
|
+
const create_temporarily = async (path: string, contents: string): Promise<AsyncCleanup> => {
|
|
214
221
|
const dir = dirname(path);
|
|
215
222
|
|
|
216
|
-
const dir_already_exists =
|
|
223
|
+
const dir_already_exists = await fs_exists(dir);
|
|
217
224
|
let root_created_dir: string | undefined;
|
|
218
225
|
if (!dir_already_exists) {
|
|
219
|
-
root_created_dir = to_root_dir_that_doesnt_exist(dir);
|
|
226
|
+
root_created_dir = await to_root_dir_that_doesnt_exist(dir);
|
|
220
227
|
if (!root_created_dir) throw Error();
|
|
221
|
-
|
|
228
|
+
await mkdir(dir, {recursive: true});
|
|
222
229
|
}
|
|
223
230
|
|
|
224
|
-
const path_already_exists =
|
|
231
|
+
const path_already_exists = await fs_exists(path);
|
|
225
232
|
if (!path_already_exists) {
|
|
226
|
-
|
|
233
|
+
await writeFile(path, contents, 'utf8');
|
|
227
234
|
}
|
|
228
235
|
|
|
229
|
-
return () => {
|
|
236
|
+
return async () => {
|
|
230
237
|
if (!dir_already_exists) {
|
|
231
238
|
if (!root_created_dir) throw Error();
|
|
232
|
-
if (
|
|
233
|
-
|
|
239
|
+
if (await fs_exists(root_created_dir)) {
|
|
240
|
+
await rm(root_created_dir, {recursive: true});
|
|
234
241
|
}
|
|
235
242
|
} else if (!path_already_exists) {
|
|
236
|
-
if (
|
|
237
|
-
|
|
243
|
+
if (await fs_exists(path)) {
|
|
244
|
+
await rm(path);
|
|
238
245
|
}
|
|
239
246
|
}
|
|
240
247
|
};
|
|
@@ -245,11 +252,12 @@ const create_temporarily = (path: string, contents: string): Cleanup => {
|
|
|
245
252
|
* for `/a/b/DOESNT_EXIST/NOR_THIS/ETC` returns `/a/b/DOESNT_EXIST`
|
|
246
253
|
* where `/a/b` does exist on the filesystem and `DOESNT_EXIST` is not one of its subdirectories.
|
|
247
254
|
*/
|
|
248
|
-
const to_root_dir_that_doesnt_exist = (dir: string): string | undefined => {
|
|
255
|
+
const to_root_dir_that_doesnt_exist = async (dir: string): Promise<string | undefined> => {
|
|
249
256
|
let prev: string | undefined;
|
|
250
257
|
let d = dir;
|
|
251
258
|
do {
|
|
252
|
-
|
|
259
|
+
// eslint-disable-next-line no-await-in-loop
|
|
260
|
+
if (await fs_exists(d)) {
|
|
253
261
|
return prev;
|
|
254
262
|
}
|
|
255
263
|
prev = d;
|
|
@@ -23,12 +23,11 @@ export const gro_plugin_sveltekit_library = ({
|
|
|
23
23
|
svelte_package_options,
|
|
24
24
|
svelte_package_cli = SVELTE_PACKAGE_CLI,
|
|
25
25
|
}: GroPluginSveltekitLibraryOptions = {}): Plugin => {
|
|
26
|
-
const package_json = load_package_json();
|
|
27
|
-
|
|
28
26
|
return {
|
|
29
27
|
name: 'gro_plugin_sveltekit_library',
|
|
30
28
|
setup: async ({dev, log, config}) => {
|
|
31
29
|
if (!dev) {
|
|
30
|
+
const package_json = await load_package_json();
|
|
32
31
|
await run_svelte_package(
|
|
33
32
|
package_json,
|
|
34
33
|
svelte_package_options,
|
|
@@ -39,6 +38,7 @@ export const gro_plugin_sveltekit_library = ({
|
|
|
39
38
|
}
|
|
40
39
|
},
|
|
41
40
|
adapt: async ({log, timings, config}) => {
|
|
41
|
+
const package_json = await load_package_json();
|
|
42
42
|
// link the CLI binaries if they exist
|
|
43
43
|
if (package_json.bin) {
|
|
44
44
|
const timing_to_link = timings.start(`${config.pm_cli} link`);
|
package/src/lib/input_path.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {dirname, isAbsolute, join, resolve} from 'node:path';
|
|
2
|
-
import {
|
|
2
|
+
import {stat} from 'node:fs/promises';
|
|
3
|
+
import {fs_exists, fs_search} from '@ryanatkn/belt/fs.js';
|
|
3
4
|
import {strip_start} from '@ryanatkn/belt/string.js';
|
|
4
5
|
import {z} from 'zod';
|
|
5
6
|
import type {Flavored} from '@ryanatkn/belt/types.js';
|
|
6
7
|
import type {PathInfo, PathId, ResolvedPath} from '@ryanatkn/belt/path.js';
|
|
7
8
|
|
|
8
9
|
import {GRO_PACKAGE_DIR, GRO_DIST_DIR} from './paths.ts';
|
|
9
|
-
import {search_fs} from './search_fs.ts';
|
|
10
10
|
import {TASK_FILE_SUFFIX_JS} from './task.ts';
|
|
11
11
|
|
|
12
12
|
// TODO Flavored doesn't work when used in schemas, use Zod brand instead? problem is ergonomics
|
|
@@ -55,11 +55,11 @@ export interface PossiblePath {
|
|
|
55
55
|
* Gets a list of possible source ids for each input path with `extensions`,
|
|
56
56
|
* duplicating each under `root_dirs`, without checking the filesystem.
|
|
57
57
|
*/
|
|
58
|
-
export const get_possible_paths = (
|
|
58
|
+
export const get_possible_paths = async (
|
|
59
59
|
input_path: InputPath,
|
|
60
60
|
root_dirs: Array<PathId>,
|
|
61
61
|
extensions: Array<string>,
|
|
62
|
-
): Array<PossiblePath
|
|
62
|
+
): Promise<Array<PossiblePath>> => {
|
|
63
63
|
const possible_paths: Set<PossiblePath> = new Set();
|
|
64
64
|
|
|
65
65
|
const add_possible_paths = (path: string, root_dir: PathId) => {
|
|
@@ -83,14 +83,9 @@ export const get_possible_paths = (
|
|
|
83
83
|
};
|
|
84
84
|
|
|
85
85
|
if (isAbsolute(input_path)) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
add_possible_paths(
|
|
89
|
-
input_path,
|
|
90
|
-
existsSync(input_path) && statSync(input_path).isDirectory()
|
|
91
|
-
? input_path
|
|
92
|
-
: dirname(input_path),
|
|
93
|
-
);
|
|
86
|
+
const exists = await fs_exists(input_path);
|
|
87
|
+
const is_directory = exists && (await stat(input_path)).isDirectory();
|
|
88
|
+
add_possible_paths(input_path, is_directory ? input_path : dirname(input_path));
|
|
94
89
|
} else {
|
|
95
90
|
for (const root_dir of root_dirs) {
|
|
96
91
|
add_possible_paths(join(root_dir, input_path), root_dir);
|
|
@@ -123,24 +118,27 @@ export interface ResolvedInputPaths {
|
|
|
123
118
|
* and stopping at the first existing file or falling back to the first existing directory.
|
|
124
119
|
* If none is found for an input path, it's added to `unmapped_input_paths`.
|
|
125
120
|
*/
|
|
126
|
-
export const resolve_input_paths = (
|
|
121
|
+
export const resolve_input_paths = async (
|
|
127
122
|
input_paths: Array<InputPath>,
|
|
128
123
|
root_dirs: Array<PathId>,
|
|
129
124
|
extensions: Array<string>,
|
|
130
|
-
): ResolvedInputPaths => {
|
|
125
|
+
): Promise<ResolvedInputPaths> => {
|
|
131
126
|
const resolved_input_paths: Array<ResolvedInputPath> = [];
|
|
132
127
|
const possible_paths_by_input_path: Map<InputPath, Array<PossiblePath>> = new Map();
|
|
133
128
|
const unmapped_input_paths: Array<InputPath> = [];
|
|
134
129
|
for (const input_path of input_paths) {
|
|
135
130
|
let found_file: [PathInfo, PossiblePath] | null = null;
|
|
136
131
|
let found_dirs: Array<[PathInfo, PossiblePath]> | null = null;
|
|
137
|
-
|
|
132
|
+
// eslint-disable-next-line no-await-in-loop
|
|
133
|
+
const possible_paths = await get_possible_paths(input_path, root_dirs, extensions);
|
|
138
134
|
possible_paths_by_input_path.set(input_path, possible_paths);
|
|
139
135
|
|
|
140
136
|
// Find the first existing file path or fallback to the first directory path.
|
|
141
137
|
for (const possible_path of possible_paths) {
|
|
142
|
-
|
|
143
|
-
|
|
138
|
+
// eslint-disable-next-line no-await-in-loop
|
|
139
|
+
if (!(await fs_exists(possible_path.id))) continue;
|
|
140
|
+
// eslint-disable-next-line no-await-in-loop
|
|
141
|
+
const stats = await stat(possible_path.id);
|
|
144
142
|
if (stats.isDirectory()) {
|
|
145
143
|
found_dirs ??= [];
|
|
146
144
|
found_dirs.push([{id: possible_path.id, is_directory: stats.isDirectory()}, possible_path]);
|
|
@@ -186,10 +184,10 @@ export interface ResolvedInputFiles {
|
|
|
186
184
|
* Finds all of the matching files for the given input paths.
|
|
187
185
|
* De-dupes source ids.
|
|
188
186
|
*/
|
|
189
|
-
export const resolve_input_files = (
|
|
187
|
+
export const resolve_input_files = async (
|
|
190
188
|
resolved_input_paths: Array<ResolvedInputPath>,
|
|
191
|
-
search: (dir: string) => Array<ResolvedPath
|
|
192
|
-
): ResolvedInputFiles => {
|
|
189
|
+
search: (dir: string) => Promise<Array<ResolvedPath>> = fs_search,
|
|
190
|
+
): Promise<ResolvedInputFiles> => {
|
|
193
191
|
const resolved_input_files: Array<ResolvedInputFile> = [];
|
|
194
192
|
// Add all input paths initially, and remove each when resolved to a file.
|
|
195
193
|
const existing_path_ids: Set<PathId> = new Set();
|
|
@@ -206,7 +204,8 @@ export const resolve_input_files = (
|
|
|
206
204
|
const {input_path, id, is_directory} = resolved_input_path;
|
|
207
205
|
if (is_directory) {
|
|
208
206
|
// Handle input paths that resolve to directories.
|
|
209
|
-
|
|
207
|
+
// eslint-disable-next-line no-await-in-loop
|
|
208
|
+
const files = await search(id);
|
|
210
209
|
if (!files.length) continue;
|
|
211
210
|
const path_ids: Array<PathId> = [];
|
|
212
211
|
for (const {path, is_directory} of files) {
|
package/src/lib/invoke_task.ts
CHANGED
|
@@ -68,7 +68,7 @@ export const invoke_task = async (
|
|
|
68
68
|
|
|
69
69
|
// Check if the caller just wants to see the version.
|
|
70
70
|
if (!task_name && (args?.version || args?.v)) {
|
|
71
|
-
const gro_package_json = load_gro_package_json();
|
|
71
|
+
const gro_package_json = await load_gro_package_json();
|
|
72
72
|
log.info(`${st('gray', 'v')}${st('cyan', gro_package_json.version)}`);
|
|
73
73
|
await finish();
|
|
74
74
|
return;
|
|
@@ -81,7 +81,7 @@ export const invoke_task = async (
|
|
|
81
81
|
|
|
82
82
|
// Find the task or directory specified by the `input_path`.
|
|
83
83
|
// Fall back to searching the Gro directory as well.
|
|
84
|
-
const found = find_tasks([input_path], task_root_dirs, config);
|
|
84
|
+
const found = await find_tasks([input_path], task_root_dirs, config);
|
|
85
85
|
if (!found.ok) {
|
|
86
86
|
log_error_reasons(log, found.reasons);
|
|
87
87
|
throw new SilentError();
|
package/src/lib/lint.task.ts
CHANGED
|
@@ -21,7 +21,7 @@ export const task: Task<Args> = {
|
|
|
21
21
|
run: async ({log, args}): Promise<void> => {
|
|
22
22
|
const {_, eslint_cli} = args;
|
|
23
23
|
|
|
24
|
-
const found_eslint_cli = find_cli(eslint_cli);
|
|
24
|
+
const found_eslint_cli = await find_cli(eslint_cli);
|
|
25
25
|
if (!found_eslint_cli) {
|
|
26
26
|
// TODO maybe make this an option?
|
|
27
27
|
log.info('ESLint is not installed; skipping linting');
|
package/src/lib/loader.ts
CHANGED
|
@@ -233,7 +233,7 @@ export const resolve: ResolveHook = async (specifier, context, nextResolve) => {
|
|
|
233
233
|
return nextResolve(s, context);
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
const resolved = resolve_specifier(s, dirname(fileURLToPath(parent_url)));
|
|
236
|
+
const resolved = await resolve_specifier(s, dirname(fileURLToPath(parent_url)));
|
|
237
237
|
|
|
238
238
|
return {
|
|
239
239
|
url: pathToFileURL(resolved.path_id_with_querystring).href,
|
package/src/lib/modules.ts
CHANGED
|
@@ -38,8 +38,8 @@ export const load_module = async <TModule extends Record<string, any>>(
|
|
|
38
38
|
import_path = url.href;
|
|
39
39
|
}
|
|
40
40
|
mod = await import(import_path);
|
|
41
|
-
} catch (
|
|
42
|
-
return {ok: false, type: 'failed_import', id, error
|
|
41
|
+
} catch (error) {
|
|
42
|
+
return {ok: false, type: 'failed_import', id, error};
|
|
43
43
|
}
|
|
44
44
|
if (validate && !validate(mod)) {
|
|
45
45
|
return {ok: false, type: 'failed_validation', id, mod, validation: validate.name};
|
package/src/lib/package_json.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import {z} from 'zod';
|
|
2
2
|
import {join} from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import {readFile, writeFile} from 'node:fs/promises';
|
|
4
4
|
import {plural, strip_end} from '@ryanatkn/belt/string.js';
|
|
5
5
|
import type {Logger} from '@ryanatkn/belt/log.js';
|
|
6
6
|
import {styleText as st} from 'node:util';
|
|
7
7
|
import {PackageJson, PackageJsonExports} from '@ryanatkn/belt/package_json.js';
|
|
8
|
+
import {fs_search} from '@ryanatkn/belt/fs.js';
|
|
8
9
|
|
|
9
10
|
import {paths, gro_paths, IS_THIS_GRO} from './paths.ts';
|
|
10
11
|
import {
|
|
@@ -16,7 +17,6 @@ import {
|
|
|
16
17
|
JSON_MATCHER,
|
|
17
18
|
CSS_MATCHER,
|
|
18
19
|
} from './constants.ts';
|
|
19
|
-
import {search_fs} from './search_fs.ts';
|
|
20
20
|
import {has_sveltekit_library} from './sveltekit_helpers.ts';
|
|
21
21
|
import {GITHUB_REPO_MATCHER} from './github.ts';
|
|
22
22
|
|
|
@@ -26,20 +26,20 @@ export type PackageJsonMapper = (
|
|
|
26
26
|
|
|
27
27
|
export const EMPTY_PACKAGE_JSON: PackageJson = {name: '', version: ''};
|
|
28
28
|
|
|
29
|
-
export const load_package_json = (
|
|
29
|
+
export const load_package_json = async (
|
|
30
30
|
dir = IS_THIS_GRO ? gro_paths.root : paths.root,
|
|
31
31
|
cache?: Record<string, PackageJson>,
|
|
32
32
|
parse = true, // TODO pass `false` here in more places, especially anything perf-sensitive like work on startup
|
|
33
33
|
log?: Logger,
|
|
34
|
-
): PackageJson => {
|
|
34
|
+
): Promise<PackageJson> => {
|
|
35
35
|
let package_json: PackageJson;
|
|
36
36
|
if (cache && dir in cache) {
|
|
37
37
|
return cache[dir]!;
|
|
38
38
|
}
|
|
39
39
|
try {
|
|
40
|
-
package_json = JSON.parse(load_package_json_contents(dir));
|
|
41
|
-
} catch (
|
|
42
|
-
log?.error(st('yellow', `Failed to load package.json in ${dir}`),
|
|
40
|
+
package_json = JSON.parse(await load_package_json_contents(dir));
|
|
41
|
+
} catch (error) {
|
|
42
|
+
log?.error(st('yellow', `Failed to load package.json in ${dir}`), error);
|
|
43
43
|
return EMPTY_PACKAGE_JSON;
|
|
44
44
|
}
|
|
45
45
|
if (parse) {
|
|
@@ -58,7 +58,7 @@ export const sync_package_json = async (
|
|
|
58
58
|
dir = paths.root,
|
|
59
59
|
exports_dir = paths.lib,
|
|
60
60
|
): Promise<{package_json: PackageJson | null; changed: boolean}> => {
|
|
61
|
-
const exported_files =
|
|
61
|
+
const exported_files = await fs_search(exports_dir);
|
|
62
62
|
const exported_paths = exported_files.map((f) => f.path);
|
|
63
63
|
const updated = await update_package_json(
|
|
64
64
|
async (package_json) => {
|
|
@@ -85,15 +85,14 @@ export const sync_package_json = async (
|
|
|
85
85
|
return updated;
|
|
86
86
|
};
|
|
87
87
|
|
|
88
|
-
export const load_gro_package_json = (): PackageJson => load_package_json(gro_paths.root);
|
|
88
|
+
export const load_gro_package_json = (): Promise<PackageJson> => load_package_json(gro_paths.root);
|
|
89
89
|
|
|
90
90
|
// TODO probably make this nullable and make callers handle failures
|
|
91
|
-
const load_package_json_contents = (dir: string): string =>
|
|
92
|
-
|
|
91
|
+
const load_package_json_contents = (dir: string): Promise<string> =>
|
|
92
|
+
readFile(join(dir, PACKAGE_JSON_FILENAME), 'utf8');
|
|
93
93
|
|
|
94
|
-
export const write_package_json = (serialized_package_json: string): void =>
|
|
95
|
-
|
|
96
|
-
};
|
|
94
|
+
export const write_package_json = (serialized_package_json: string): Promise<void> =>
|
|
95
|
+
writeFile(join(paths.root, PACKAGE_JSON_FILENAME), serialized_package_json);
|
|
97
96
|
|
|
98
97
|
export const serialize_package_json = (package_json: PackageJson): string =>
|
|
99
98
|
JSON.stringify(parse_package_json(PackageJson, package_json), null, 2) + '\n';
|
|
@@ -106,7 +105,7 @@ export const update_package_json = async (
|
|
|
106
105
|
dir = paths.root,
|
|
107
106
|
write = true,
|
|
108
107
|
): Promise<{package_json: PackageJson | null; changed: boolean}> => {
|
|
109
|
-
const original_contents = load_package_json_contents(dir);
|
|
108
|
+
const original_contents = await load_package_json_contents(dir);
|
|
110
109
|
const original = JSON.parse(original_contents);
|
|
111
110
|
const updated = await update(original);
|
|
112
111
|
if (updated === null) {
|
|
@@ -116,7 +115,7 @@ export const update_package_json = async (
|
|
|
116
115
|
if (updated_contents === original_contents) {
|
|
117
116
|
return {package_json: original, changed: false};
|
|
118
117
|
}
|
|
119
|
-
if (write) write_package_json(updated_contents);
|
|
118
|
+
if (write) await write_package_json(updated_contents);
|
|
120
119
|
return {package_json: updated, changed: true};
|
|
121
120
|
};
|
|
122
121
|
|
|
@@ -225,10 +224,7 @@ const parse_or_throw_formatted_error = <T extends z.ZodType>(
|
|
|
225
224
|
return parsed.data;
|
|
226
225
|
};
|
|
227
226
|
|
|
228
|
-
export const has_dep = (
|
|
229
|
-
dep_name: string,
|
|
230
|
-
package_json: PackageJson = load_package_json(),
|
|
231
|
-
): boolean =>
|
|
227
|
+
export const has_dep = (dep_name: string, package_json: PackageJson): boolean =>
|
|
232
228
|
!!package_json.devDependencies?.[dep_name] ||
|
|
233
229
|
!!package_json.dependencies?.[dep_name] ||
|
|
234
230
|
!!package_json.peerDependencies?.[dep_name];
|
package/src/lib/publish.task.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {spawn} from '@ryanatkn/belt/process.js';
|
|
2
2
|
import {z} from 'zod';
|
|
3
3
|
import {styleText as st} from 'node:util';
|
|
4
|
-
import {
|
|
4
|
+
import {fs_exists} from '@ryanatkn/belt/fs.js';
|
|
5
5
|
import {
|
|
6
6
|
GitBranch,
|
|
7
7
|
GitOrigin,
|
|
@@ -85,7 +85,7 @@ export const task: Task<Args> = {
|
|
|
85
85
|
log.info(st('green', 'dry run!'));
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
const package_json = load_package_json();
|
|
88
|
+
const package_json = await load_package_json();
|
|
89
89
|
|
|
90
90
|
const has_sveltekit_library_result = await has_sveltekit_library(package_json);
|
|
91
91
|
if (!has_sveltekit_library_result.ok) {
|
|
@@ -94,9 +94,9 @@ export const task: Task<Args> = {
|
|
|
94
94
|
);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
const changelog_exists =
|
|
97
|
+
const changelog_exists = await fs_exists(changelog);
|
|
98
98
|
|
|
99
|
-
const found_changeset_cli = find_cli(changeset_cli);
|
|
99
|
+
const found_changeset_cli = await find_cli(changeset_cli);
|
|
100
100
|
if (!found_changeset_cli) {
|
|
101
101
|
throw new TaskError(
|
|
102
102
|
'changeset command not found, install @changesets/cli locally or globally',
|
|
@@ -178,7 +178,7 @@ export const task: Task<Args> = {
|
|
|
178
178
|
// The check above ensures gen is updated.
|
|
179
179
|
await invoke_task('gen');
|
|
180
180
|
|
|
181
|
-
const package_json_after_versioning = load_package_json();
|
|
181
|
+
const package_json_after_versioning = await load_package_json();
|
|
182
182
|
version = package_json_after_versioning.version!;
|
|
183
183
|
if (package_json.version === version) {
|
|
184
184
|
// The version didn't change.
|
|
@@ -217,7 +217,7 @@ export const task: Task<Args> = {
|
|
|
217
217
|
);
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
-
if (!changelog_exists &&
|
|
220
|
+
if (!changelog_exists && (await fs_exists(changelog))) {
|
|
221
221
|
await spawn('git', ['add', changelog]);
|
|
222
222
|
}
|
|
223
223
|
await spawn('git', ['commit', '-a', '-m', `publish v${version}`]);
|
package/src/lib/release.task.ts
CHANGED
|
@@ -13,7 +13,7 @@ export const task: Task<Args> = {
|
|
|
13
13
|
summary: 'publish and deploy',
|
|
14
14
|
Args,
|
|
15
15
|
run: async ({invoke_task}) => {
|
|
16
|
-
const package_json = load_package_json();
|
|
16
|
+
const package_json = await load_package_json();
|
|
17
17
|
|
|
18
18
|
const publish = (await has_sveltekit_library(package_json)).ok;
|
|
19
19
|
if (publish) {
|
package/src/lib/resolve.task.ts
CHANGED
|
@@ -15,7 +15,7 @@ export type Args = z.infer<typeof Args>;
|
|
|
15
15
|
export const task: Task<Args> = {
|
|
16
16
|
summary: 'diagnostic that logs resolved filesystem info for the given input paths',
|
|
17
17
|
Args,
|
|
18
|
-
run: ({args, config, log}): void => {
|
|
18
|
+
run: async ({args, config, log}): Promise<void> => {
|
|
19
19
|
const {_, verbose} = args;
|
|
20
20
|
|
|
21
21
|
if (verbose) log.info('raw input paths:', _);
|
|
@@ -27,7 +27,7 @@ export const task: Task<Args> = {
|
|
|
27
27
|
if (verbose) log.info('task root paths:', task_root_dirs);
|
|
28
28
|
|
|
29
29
|
const {resolved_input_paths, possible_paths_by_input_path, unmapped_input_paths} =
|
|
30
|
-
resolve_input_paths(input_paths, task_root_dirs, TASK_FILE_SUFFIXES);
|
|
30
|
+
await resolve_input_paths(input_paths, task_root_dirs, TASK_FILE_SUFFIXES);
|
|
31
31
|
if (verbose) log.info('resolved_input_paths:', resolved_input_paths);
|
|
32
32
|
if (verbose) log.info('possible_paths_by_input_path:', possible_paths_by_input_path);
|
|
33
33
|
if (verbose) log.info('unmapped_input_paths:', unmapped_input_paths);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {extname, isAbsolute, join, relative} from 'node:path';
|
|
2
|
-
import {
|
|
2
|
+
import {fs_exists} from '@ryanatkn/belt/fs.js';
|
|
3
3
|
import type {PathId} from '@ryanatkn/belt/path.js';
|
|
4
4
|
|
|
5
5
|
import {replace_extension} from './paths.ts';
|
|
@@ -26,7 +26,10 @@ export interface ResolvedSpecifier {
|
|
|
26
26
|
* and infer the correct extension following Vite conventions.
|
|
27
27
|
* If no `.js` file is found for the specifier on the filesystem, it assumes `.ts`.
|
|
28
28
|
*/
|
|
29
|
-
export const resolve_specifier = (
|
|
29
|
+
export const resolve_specifier = async (
|
|
30
|
+
specifier: string,
|
|
31
|
+
dir: string,
|
|
32
|
+
): Promise<ResolvedSpecifier> => {
|
|
30
33
|
const raw = specifier.endsWith('?raw'); // TODO more robust detection? other values?
|
|
31
34
|
const final_specifier = raw ? specifier.substring(0, specifier.length - 4) : specifier;
|
|
32
35
|
const absolute_path = isAbsolute(final_specifier) ? final_specifier : join(dir, final_specifier);
|
|
@@ -39,7 +42,7 @@ export const resolve_specifier = (specifier: string, dir: string): ResolvedSpeci
|
|
|
39
42
|
const is_js = ext === '.js';
|
|
40
43
|
const is_ts = ext === '.ts';
|
|
41
44
|
|
|
42
|
-
if (!is_js && !is_ts &&
|
|
45
|
+
if (!is_js && !is_ts && (await fs_exists(absolute_path))) {
|
|
43
46
|
// unrecognized extension and the file exists
|
|
44
47
|
mapped_path = absolute_path;
|
|
45
48
|
path_id = absolute_path;
|
|
@@ -52,7 +55,8 @@ export const resolve_specifier = (specifier: string, dir: string): ResolvedSpeci
|
|
|
52
55
|
// extensionless, or js that points to ts, or just js
|
|
53
56
|
const js_id = is_js ? absolute_path : absolute_path + '.js';
|
|
54
57
|
const ts_id = is_js ? replace_extension(absolute_path, '.ts') : absolute_path + '.ts';
|
|
55
|
-
|
|
58
|
+
const [ts_exists, js_exists] = await Promise.all([fs_exists(ts_id), fs_exists(js_id)]);
|
|
59
|
+
if (!ts_exists && js_exists) {
|
|
56
60
|
mapped_path = js_id;
|
|
57
61
|
path_id = js_id;
|
|
58
62
|
namespace = 'sveltekit_local_imports_js';
|
package/src/lib/run.task.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {z} from 'zod';
|
|
2
2
|
import {styleText as st} from 'node:util';
|
|
3
|
-
import {
|
|
3
|
+
import {fs_exists} from '@ryanatkn/belt/fs.js';
|
|
4
4
|
|
|
5
5
|
import {TaskError, type Task} from './task.ts';
|
|
6
6
|
import {resolve_gro_module_path, spawn_with_loader} from './gro_helpers.ts';
|
|
@@ -39,7 +39,7 @@ export const task: Task<Args> = {
|
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
if (!
|
|
42
|
+
if (!(await fs_exists(path))) {
|
|
43
43
|
throw new TaskError('Cannot find file to run at path: ' + path);
|
|
44
44
|
}
|
|
45
45
|
|