@ryanatkn/gro 0.179.0 → 0.181.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/README.md +1 -1
- package/dist/build.task.d.ts +2 -0
- package/dist/build.task.d.ts.map +1 -1
- package/dist/build.task.js +15 -11
- package/dist/build_cache.d.ts +4 -4
- package/dist/build_cache.d.ts.map +1 -1
- package/dist/build_cache.js +54 -44
- package/dist/changelog.d.ts +2 -2
- package/dist/changelog.d.ts.map +1 -1
- package/dist/changeset.task.js +11 -11
- package/dist/check.task.js +2 -2
- package/dist/child_process_logging.js +1 -1
- package/dist/clean.task.js +2 -2
- 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 +7 -7
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +11 -12
- package/dist/commit.task.js +2 -2
- package/dist/deploy.task.d.ts +7 -0
- package/dist/deploy.task.d.ts.map +1 -1
- package/dist/deploy.task.js +30 -17
- package/dist/disknode.d.ts +1 -1
- package/dist/disknode.d.ts.map +1 -1
- package/dist/esbuild_helpers.d.ts +1 -1
- package/dist/esbuild_helpers.d.ts.map +1 -1
- package/dist/esbuild_plugin_external_worker.d.ts +1 -1
- package/dist/esbuild_plugin_external_worker.d.ts.map +1 -1
- 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/esbuild_plugin_sveltekit_shim_alias.js +1 -1
- package/dist/filer.d.ts +4 -4
- package/dist/filer.d.ts.map +1 -1
- package/dist/filer.js +105 -54
- package/dist/format.task.js +1 -1
- package/dist/format_directory.d.ts +2 -2
- package/dist/format_directory.d.ts.map +1 -1
- package/dist/format_file.js +1 -1
- package/dist/gen.d.ts +5 -5
- package/dist/gen.d.ts.map +1 -1
- package/dist/gen.js +28 -22
- package/dist/gen.task.js +3 -3
- package/dist/gen_helpers.d.ts +3 -3
- package/dist/gen_helpers.d.ts.map +1 -1
- package/dist/github.d.ts +2 -2
- package/dist/github.d.ts.map +1 -1
- package/dist/github.js +1 -1
- package/dist/gro.config.default.js +1 -1
- package/dist/gro_config.d.ts +1 -1
- package/dist/gro_config.d.ts.map +1 -1
- package/dist/gro_config.js +4 -4
- package/dist/gro_helpers.d.ts +1 -1
- package/dist/gro_helpers.d.ts.map +1 -1
- package/dist/gro_helpers.js +1 -1
- package/dist/gro_plugin_gen.js +4 -4
- package/dist/gro_plugin_server.d.ts +2 -2
- package/dist/gro_plugin_server.d.ts.map +1 -1
- package/dist/gro_plugin_server.js +7 -7
- 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 +3 -2
- package/dist/input_path.d.ts +5 -5
- package/dist/input_path.d.ts.map +1 -1
- package/dist/input_path.js +17 -15
- package/dist/invoke.js +2 -2
- package/dist/invoke_task.d.ts +2 -2
- package/dist/invoke_task.d.ts.map +1 -1
- package/dist/invoke_task.js +5 -5
- package/dist/lint.task.js +2 -2
- package/dist/loader.js +2 -2
- package/dist/modules.d.ts +3 -3
- package/dist/modules.d.ts.map +1 -1
- package/dist/modules.js +4 -4
- package/dist/package_json.d.ts +6 -6
- package/dist/package_json.d.ts.map +1 -1
- package/dist/package_json.js +14 -16
- package/dist/parse_exports.d.ts +4 -4
- package/dist/parse_exports.d.ts.map +1 -1
- package/dist/parse_exports_context.d.ts +1 -1
- package/dist/parse_exports_context.d.ts.map +1 -1
- package/dist/parse_imports.d.ts +2 -2
- package/dist/parse_imports.d.ts.map +1 -1
- package/dist/parse_imports.js +1 -1
- package/dist/paths.d.ts +1 -1
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +1 -1
- package/dist/publish.task.js +8 -8
- package/dist/reinstall.task.js +1 -1
- package/dist/release.task.js +1 -1
- package/dist/resolve.task.js +2 -2
- package/dist/resolve_specifier.d.ts +2 -2
- 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 +2 -2
- package/dist/run_gen.d.ts.map +1 -1
- package/dist/run_gen.js +10 -9
- package/dist/run_task.d.ts +2 -2
- package/dist/run_task.d.ts.map +1 -1
- package/dist/run_task.js +4 -4
- package/dist/source_json.d.ts +5 -5
- package/dist/source_json.d.ts.map +1 -1
- package/dist/source_json.js +18 -17
- package/dist/svelte_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 +4 -4
- package/dist/sveltekit_shim_app_forms.js +1 -1
- package/dist/sveltekit_shim_app_navigation.js +1 -1
- package/dist/sveltekit_shim_app_paths.js +1 -1
- package/dist/sveltekit_shim_env.js +1 -1
- package/dist/sync.task.js +1 -1
- package/dist/task.d.ts +5 -5
- package/dist/task.d.ts.map +1 -1
- package/dist/task.js +5 -5
- package/dist/task_logging.d.ts +1 -1
- package/dist/task_logging.d.ts.map +1 -1
- package/dist/task_logging.js +2 -2
- package/dist/test.task.d.ts.map +1 -1
- package/dist/test.task.js +5 -4
- package/dist/typecheck.task.js +4 -4
- package/dist/upgrade.task.js +6 -6
- package/dist/watch_dir.d.ts +1 -1
- package/dist/watch_dir.d.ts.map +1 -1
- package/dist/watch_dir.js +2 -2
- package/package.json +8 -8
- package/src/lib/build.task.ts +16 -11
- package/src/lib/build_cache.ts +81 -65
- package/src/lib/changelog.ts +2 -2
- package/src/lib/changeset.task.ts +12 -12
- package/src/lib/check.task.ts +2 -2
- package/src/lib/child_process_logging.ts +1 -1
- package/src/lib/clean.task.ts +2 -2
- package/src/lib/clean_fs.ts +4 -4
- package/src/lib/cli.ts +18 -17
- package/src/lib/commit.task.ts +2 -2
- package/src/lib/deploy.task.ts +33 -16
- package/src/lib/disknode.ts +1 -1
- package/src/lib/esbuild_helpers.ts +1 -1
- package/src/lib/esbuild_plugin_external_worker.ts +3 -3
- package/src/lib/esbuild_plugin_svelte.ts +4 -4
- package/src/lib/esbuild_plugin_sveltekit_local_imports.ts +2 -2
- package/src/lib/esbuild_plugin_sveltekit_shim_alias.ts +1 -1
- package/src/lib/filer.ts +117 -58
- package/src/lib/format.task.ts +1 -1
- package/src/lib/format_directory.ts +2 -2
- package/src/lib/format_file.ts +1 -1
- package/src/lib/gen.task.ts +3 -3
- package/src/lib/gen.ts +56 -50
- package/src/lib/gen_helpers.ts +3 -3
- package/src/lib/github.ts +2 -2
- package/src/lib/gro.config.default.ts +1 -1
- package/src/lib/gro_config.ts +5 -5
- package/src/lib/gro_helpers.ts +1 -1
- package/src/lib/gro_plugin_gen.ts +4 -4
- package/src/lib/gro_plugin_server.ts +9 -9
- package/src/lib/gro_plugin_sveltekit_app.ts +44 -40
- package/src/lib/gro_plugin_sveltekit_library.ts +3 -3
- package/src/lib/input_path.ts +23 -24
- package/src/lib/invoke.ts +2 -2
- package/src/lib/invoke_task.ts +5 -5
- package/src/lib/lint.task.ts +2 -2
- package/src/lib/loader.ts +2 -2
- package/src/lib/modules.ts +7 -7
- package/src/lib/package_json.ts +19 -23
- package/src/lib/parse_exports.ts +4 -4
- package/src/lib/parse_exports_context.ts +2 -2
- package/src/lib/parse_imports.ts +3 -3
- package/src/lib/paths.ts +2 -2
- package/src/lib/publish.task.ts +8 -8
- package/src/lib/reinstall.task.ts +1 -1
- package/src/lib/release.task.ts +1 -1
- package/src/lib/resolve.task.ts +2 -2
- package/src/lib/resolve_specifier.ts +9 -5
- package/src/lib/run.task.ts +2 -2
- package/src/lib/run_gen.ts +18 -13
- package/src/lib/run_task.ts +6 -6
- package/src/lib/source_json.ts +26 -22
- package/src/lib/svelte_config.ts +1 -1
- package/src/lib/sveltekit_helpers.ts +7 -7
- package/src/lib/sveltekit_shim_app_forms.ts +1 -1
- package/src/lib/sveltekit_shim_app_navigation.ts +1 -1
- package/src/lib/sveltekit_shim_app_paths.ts +1 -1
- package/src/lib/sync.task.ts +1 -1
- package/src/lib/task.ts +16 -14
- package/src/lib/task_logging.ts +3 -3
- package/src/lib/test.task.ts +4 -3
- package/src/lib/typecheck.task.ts +4 -4
- package/src/lib/upgrade.task.ts +6 -6
- package/src/lib/watch_dir.ts +3 -3
- 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
package/src/lib/gen.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type {Logger} from '@
|
|
1
|
+
import type {Logger} from '@fuzdev/fuz_util/log.js';
|
|
2
2
|
import {join, basename, dirname, isAbsolute} from 'node:path';
|
|
3
3
|
import {mkdir, readFile, writeFile} from 'node:fs/promises';
|
|
4
|
-
import type {Result} from '@
|
|
5
|
-
import type {Timings} from '@
|
|
4
|
+
import type {Result} from '@fuzdev/fuz_util/result.js';
|
|
5
|
+
import type {Timings} from '@fuzdev/fuz_util/timings.js';
|
|
6
6
|
import {styleText as st} from 'node:util';
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
7
|
+
import type {PathId} from '@fuzdev/fuz_util/path.js';
|
|
8
|
+
import {map_concurrent} from '@fuzdev/fuz_util/async.js';
|
|
9
|
+
import {fs_search} from '@fuzdev/fuz_util/fs.js';
|
|
9
10
|
|
|
10
11
|
import {print_path} from './paths.ts';
|
|
11
12
|
import type {GroConfig} from './gro_config.ts';
|
|
@@ -18,7 +19,6 @@ import {
|
|
|
18
19
|
type ResolvedInputFile,
|
|
19
20
|
type ResolvedInputPath,
|
|
20
21
|
} from './input_path.ts';
|
|
21
|
-
import {search_fs} from './search_fs.ts';
|
|
22
22
|
import type {Filer} from './filer.ts';
|
|
23
23
|
import type {InvokeTask} from './task.ts';
|
|
24
24
|
|
|
@@ -210,23 +210,28 @@ export type AnalyzedGenResult =
|
|
|
210
210
|
has_changed: true;
|
|
211
211
|
};
|
|
212
212
|
|
|
213
|
-
export const analyze_gen_results = (
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
213
|
+
export const analyze_gen_results = async (
|
|
214
|
+
gen_results: GenResults,
|
|
215
|
+
): Promise<Array<AnalyzedGenResult>> => {
|
|
216
|
+
const files = gen_results.successes.flatMap((result) => result.files);
|
|
217
|
+
return map_concurrent(files, (file) => analyze_gen_result(file), 10);
|
|
218
|
+
};
|
|
219
219
|
|
|
220
220
|
export const analyze_gen_result = async (file: GenFile): Promise<AnalyzedGenResult> => {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
221
|
+
let existing_content: string;
|
|
222
|
+
try {
|
|
223
|
+
existing_content = await readFile(file.id, 'utf8');
|
|
224
|
+
} catch (error) {
|
|
225
|
+
if (error.code === 'ENOENT') {
|
|
226
|
+
return {
|
|
227
|
+
file,
|
|
228
|
+
existing_content: null,
|
|
229
|
+
is_new: true,
|
|
230
|
+
has_changed: true,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
throw error;
|
|
228
234
|
}
|
|
229
|
-
const existing_content = await readFile(file.id, 'utf8');
|
|
230
235
|
return {
|
|
231
236
|
file,
|
|
232
237
|
existing_content,
|
|
@@ -240,26 +245,25 @@ export const write_gen_results = async (
|
|
|
240
245
|
analyzed_gen_results: Array<AnalyzedGenResult>,
|
|
241
246
|
log: Logger,
|
|
242
247
|
): Promise<void> => {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
.flat(),
|
|
248
|
+
const files = gen_results.successes.flatMap((result) => result.files);
|
|
249
|
+
await map_concurrent(
|
|
250
|
+
files,
|
|
251
|
+
async (file) => {
|
|
252
|
+
const analyzed = analyzed_gen_results.find((r) => r.file.id === file.id);
|
|
253
|
+
if (!analyzed) throw Error('Expected to find analyzed result: ' + file.id);
|
|
254
|
+
const log_args = [print_path(file.id), 'generated from', print_path(file.origin_id)];
|
|
255
|
+
if (analyzed.is_new) {
|
|
256
|
+
log.info('writing new', ...log_args);
|
|
257
|
+
await mkdir(dirname(file.id), {recursive: true});
|
|
258
|
+
await writeFile(file.id, file.content);
|
|
259
|
+
} else if (analyzed.has_changed) {
|
|
260
|
+
log.info('writing changed', ...log_args);
|
|
261
|
+
await writeFile(file.id, file.content);
|
|
262
|
+
} else {
|
|
263
|
+
log.info('skipping unchanged', ...log_args);
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
10,
|
|
263
267
|
);
|
|
264
268
|
};
|
|
265
269
|
|
|
@@ -289,17 +293,17 @@ export type FindGenfilesFailure =
|
|
|
289
293
|
/**
|
|
290
294
|
* Finds modules from input paths. (see `src/lib/input_path.ts` for more)
|
|
291
295
|
*/
|
|
292
|
-
export const find_genfiles = (
|
|
296
|
+
export const find_genfiles = async (
|
|
293
297
|
input_paths: Array<InputPath>,
|
|
294
298
|
root_dirs: Array<PathId>,
|
|
295
299
|
config: GroConfig,
|
|
296
300
|
timings?: Timings,
|
|
297
|
-
): FindGenfilesResult => {
|
|
301
|
+
): Promise<FindGenfilesResult> => {
|
|
298
302
|
const extensions: Array<string> = [GEN_FILE_PATTERN];
|
|
299
303
|
|
|
300
304
|
// Check which extension variation works - if it's a directory, prefer others first!
|
|
301
305
|
const timing_to_resolve_input_paths = timings?.start('resolve input paths');
|
|
302
|
-
const {resolved_input_paths, unmapped_input_paths} = resolve_input_paths(
|
|
306
|
+
const {resolved_input_paths, unmapped_input_paths} = await resolve_input_paths(
|
|
303
307
|
input_paths,
|
|
304
308
|
root_dirs,
|
|
305
309
|
extensions,
|
|
@@ -320,15 +324,17 @@ export const find_genfiles = (
|
|
|
320
324
|
}
|
|
321
325
|
|
|
322
326
|
// Find all of the files for any directories.
|
|
323
|
-
const
|
|
327
|
+
const timing_to_fs_search = timings?.start('find files');
|
|
324
328
|
const {resolved_input_files, resolved_input_files_by_root_dir, input_directories_with_no_files} =
|
|
325
|
-
resolve_input_files(
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
329
|
+
await resolve_input_files(
|
|
330
|
+
resolved_input_paths,
|
|
331
|
+
async (id) =>
|
|
332
|
+
await fs_search(id, {
|
|
333
|
+
filter: config.search_filters,
|
|
334
|
+
file_filter: (p) => extensions.some((e) => p.includes(e)),
|
|
335
|
+
}),
|
|
330
336
|
);
|
|
331
|
-
|
|
337
|
+
timing_to_fs_search?.();
|
|
332
338
|
|
|
333
339
|
// Error if any input path has no files. (means we have an empty directory)
|
|
334
340
|
if (input_directories_with_no_files.length) {
|
package/src/lib/gen_helpers.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {resolve} from 'node:path';
|
|
2
|
-
import type {Logger} from '@
|
|
3
|
-
import type {Timings} from '@
|
|
4
|
-
import type {PathId} from '@
|
|
2
|
+
import type {Logger} from '@fuzdev/fuz_util/log.js';
|
|
3
|
+
import type {Timings} from '@fuzdev/fuz_util/timings.js';
|
|
4
|
+
import type {PathId} from '@fuzdev/fuz_util/path.js';
|
|
5
5
|
|
|
6
6
|
import type {GroConfig} from './gro_config.ts';
|
|
7
7
|
import {filter_dependents, type Filer} from './filer.ts';
|
package/src/lib/github.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// for now it's just calling a single endpoint so we do it manually
|
|
3
3
|
// and we specify just the types we need
|
|
4
4
|
|
|
5
|
-
import {FetchValueCache, fetch_value} from '@
|
|
6
|
-
import type {Logger} from '@
|
|
5
|
+
import {FetchValueCache, fetch_value} from '@fuzdev/fuz_util/fetch.js';
|
|
6
|
+
import type {Logger} from '@fuzdev/fuz_util/log.js';
|
|
7
7
|
import {z} from 'zod';
|
|
8
8
|
|
|
9
9
|
export const GITHUB_REPO_MATCHER = /.+github.com\/(.+)\/(.+)/;
|
|
@@ -18,7 +18,7 @@ import {load_package_json} from './package_json.ts';
|
|
|
18
18
|
* - if `src/lib/server/server.ts`, assumes a Node server - needs config
|
|
19
19
|
*/
|
|
20
20
|
const config: CreateGroConfig = async (cfg, svelte_config) => {
|
|
21
|
-
const package_json = load_package_json(); // TODO gets wastefully loaded by some plugins, maybe put in plugin/task context? how does that interact with `map_package_json`?
|
|
21
|
+
const package_json = await load_package_json(); // TODO gets wastefully loaded by some plugins, maybe put in plugin/task context? how does that interact with `map_package_json`?
|
|
22
22
|
|
|
23
23
|
const [has_server_result, has_sveltekit_library_result, has_sveltekit_app_result] =
|
|
24
24
|
await Promise.all([
|
package/src/lib/gro_config.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {join, resolve} from 'node:path';
|
|
2
|
-
import {
|
|
3
|
-
import {identity} from '@
|
|
4
|
-
import type {PathFilter, PathId} from '@
|
|
5
|
-
import {json_stringify_deterministic} from '@
|
|
2
|
+
import {fs_exists} from '@fuzdev/fuz_util/fs.js';
|
|
3
|
+
import {identity} from '@fuzdev/fuz_util/function.js';
|
|
4
|
+
import type {PathFilter, PathId} from '@fuzdev/fuz_util/path.js';
|
|
5
|
+
import {json_stringify_deterministic} from '@fuzdev/fuz_util/json.js';
|
|
6
6
|
|
|
7
7
|
import {GRO_DIST_DIR, IS_THIS_GRO, paths} from './paths.ts';
|
|
8
8
|
import {
|
|
@@ -208,7 +208,7 @@ export const load_gro_config = async (dir = paths.root): Promise<GroConfig> => {
|
|
|
208
208
|
);
|
|
209
209
|
|
|
210
210
|
const config_path = join(dir, GRO_CONFIG_FILENAME);
|
|
211
|
-
if (!
|
|
211
|
+
if (!(await fs_exists(config_path))) {
|
|
212
212
|
// No user config file found, so return the default.
|
|
213
213
|
return default_config;
|
|
214
214
|
}
|
package/src/lib/gro_helpers.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {realpathSync, existsSync} from 'node:fs';
|
|
2
2
|
import {join, resolve} from 'node:path';
|
|
3
3
|
import {fileURLToPath} from 'node:url';
|
|
4
|
-
import {spawn, type SpawnResult} from '@
|
|
4
|
+
import {spawn, type SpawnResult} from '@fuzdev/fuz_util/process.js';
|
|
5
5
|
|
|
6
6
|
import {JS_CLI_DEFAULT, NODE_MODULES_DIRNAME, SVELTEKIT_DIST_DIRNAME} from './constants.ts';
|
|
7
7
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {EMPTY_OBJECT} from '@
|
|
2
|
-
import {throttle} from '@
|
|
3
|
-
import {UnreachableError} from '@
|
|
1
|
+
import {EMPTY_OBJECT} from '@fuzdev/fuz_util/object.js';
|
|
2
|
+
import {throttle} from '@fuzdev/fuz_util/throttle.js';
|
|
3
|
+
import {UnreachableError} from '@fuzdev/fuz_util/error.js';
|
|
4
4
|
|
|
5
5
|
import type {Plugin} from './plugin.ts';
|
|
6
6
|
import type {Args} from './args.ts';
|
|
@@ -48,7 +48,7 @@ export const gro_plugin_gen = ({
|
|
|
48
48
|
// Some parts of the build may have already happened,
|
|
49
49
|
// making us miss `build` events for gen dependencies,
|
|
50
50
|
// so we run a full `gen` here even if it's usually wasteful.
|
|
51
|
-
const found = find_genfiles(input_paths, root_dirs, config);
|
|
51
|
+
const found = await find_genfiles(input_paths, root_dirs, config);
|
|
52
52
|
if (found.ok && found.value.resolved_input_files.length > 0) {
|
|
53
53
|
await gen();
|
|
54
54
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {spawn_restartable_process, type RestartableProcess} from '@
|
|
1
|
+
import {spawn_restartable_process, type RestartableProcess} from '@fuzdev/fuz_util/process.js';
|
|
2
2
|
import * as esbuild from 'esbuild';
|
|
3
3
|
import type {Config as SvelteConfig} from '@sveltejs/kit';
|
|
4
4
|
import {join, resolve} from 'node:path';
|
|
5
|
-
import {identity} from '@
|
|
6
|
-
import {strip_before, strip_end} from '@
|
|
7
|
-
import type {Result} from '@
|
|
8
|
-
import {fs_exists} from '@
|
|
9
|
-
import {throttle} from '@
|
|
10
|
-
import type {PathId} from '@
|
|
5
|
+
import {identity} from '@fuzdev/fuz_util/function.js';
|
|
6
|
+
import {strip_before, strip_end} from '@fuzdev/fuz_util/string.js';
|
|
7
|
+
import type {Result} from '@fuzdev/fuz_util/result.js';
|
|
8
|
+
import {fs_exists} from '@fuzdev/fuz_util/fs.js';
|
|
9
|
+
import {throttle} from '@fuzdev/fuz_util/throttle.js';
|
|
10
|
+
import type {PathId} from '@fuzdev/fuz_util/path.js';
|
|
11
11
|
|
|
12
12
|
import type {Plugin} from './plugin.ts';
|
|
13
13
|
import {base_path_to_path_id, LIB_DIRNAME, paths} from './paths.ts';
|
|
@@ -217,8 +217,8 @@ export const gro_plugin_server = ({
|
|
|
217
217
|
let build_result;
|
|
218
218
|
try {
|
|
219
219
|
build_result = await build_ctx!.rebuild();
|
|
220
|
-
} catch (
|
|
221
|
-
log.error('[gro_plugin_server] build failed',
|
|
220
|
+
} catch (error) {
|
|
221
|
+
log.error('[gro_plugin_server] build failed', error);
|
|
222
222
|
return;
|
|
223
223
|
}
|
|
224
224
|
const {metafile} = build_result;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type {SpawnedProcess} from '@
|
|
2
|
-
import {
|
|
1
|
+
import type {SpawnedProcess} from '@fuzdev/fuz_util/process.js';
|
|
2
|
+
import {cp, mkdir, rm, writeFile} from 'node:fs/promises';
|
|
3
3
|
import {dirname, join} from 'node:path';
|
|
4
|
+
import {fs_exists} from '@fuzdev/fuz_util/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
|
}
|
|
@@ -109,7 +110,7 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
109
110
|
// copy files to `static` before building, in such a way
|
|
110
111
|
// that's non-destructive to existing files and dirs and easy to clean up
|
|
111
112
|
const {assets_path} = default_svelte_config;
|
|
112
|
-
const
|
|
113
|
+
const cleanup_promises = [
|
|
113
114
|
serialized_package_json
|
|
114
115
|
? create_temporarily(
|
|
115
116
|
join(assets_path, '.well-known/package.json'),
|
|
@@ -141,9 +142,11 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
141
142
|
host_target === 'github_pages'
|
|
142
143
|
? create_temporarily(join(assets_path, '.nojekyll'), '')
|
|
143
144
|
: null,
|
|
144
|
-
].filter((v) => v != null);
|
|
145
|
-
const
|
|
146
|
-
|
|
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();
|
|
147
150
|
};
|
|
148
151
|
try {
|
|
149
152
|
const serialized_args = ['build', ...serialize_args(to_forwarded_args(vite_cli))];
|
|
@@ -151,11 +154,11 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
151
154
|
if (!spawned?.ok) {
|
|
152
155
|
throw new TaskError(`${vite_cli} build failed with exit code ${spawned?.code}`);
|
|
153
156
|
}
|
|
154
|
-
} catch (
|
|
155
|
-
cleanup();
|
|
156
|
-
throw
|
|
157
|
+
} catch (error) {
|
|
158
|
+
await cleanup();
|
|
159
|
+
throw error;
|
|
157
160
|
}
|
|
158
|
-
cleanup();
|
|
161
|
+
await cleanup();
|
|
159
162
|
}
|
|
160
163
|
},
|
|
161
164
|
teardown: async () => {
|
|
@@ -167,41 +170,41 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
167
170
|
};
|
|
168
171
|
};
|
|
169
172
|
|
|
170
|
-
type
|
|
173
|
+
type AsyncCleanup = () => Promise<void>;
|
|
171
174
|
|
|
172
175
|
// TODO probably extract these, and create a common helper or merge them
|
|
173
176
|
|
|
174
|
-
const copy_temporarily = (
|
|
177
|
+
const copy_temporarily = async (
|
|
175
178
|
source_path: string,
|
|
176
179
|
dest_dir: string,
|
|
177
180
|
dest_base_dir = '',
|
|
178
181
|
filter?: CopyFileFilter,
|
|
179
|
-
):
|
|
182
|
+
): Promise<AsyncCleanup> => {
|
|
180
183
|
const path = join(dest_dir, dest_base_dir, source_path);
|
|
181
184
|
const dir = dirname(path);
|
|
182
185
|
|
|
183
|
-
const dir_already_exists =
|
|
186
|
+
const dir_already_exists = await fs_exists(dir);
|
|
184
187
|
let root_created_dir: string | undefined;
|
|
185
188
|
if (!dir_already_exists) {
|
|
186
|
-
root_created_dir = to_root_dir_that_doesnt_exist(dir);
|
|
189
|
+
root_created_dir = await to_root_dir_that_doesnt_exist(dir);
|
|
187
190
|
if (!root_created_dir) throw Error();
|
|
188
|
-
|
|
191
|
+
await mkdir(dir, {recursive: true});
|
|
189
192
|
}
|
|
190
193
|
|
|
191
|
-
const path_already_exists =
|
|
194
|
+
const path_already_exists = await fs_exists(path);
|
|
192
195
|
if (!path_already_exists) {
|
|
193
|
-
|
|
196
|
+
await cp(source_path, path, {recursive: true, filter});
|
|
194
197
|
}
|
|
195
198
|
|
|
196
|
-
return () => {
|
|
199
|
+
return async () => {
|
|
197
200
|
if (!dir_already_exists) {
|
|
198
201
|
if (!root_created_dir) throw Error();
|
|
199
|
-
if (
|
|
200
|
-
|
|
202
|
+
if (await fs_exists(root_created_dir)) {
|
|
203
|
+
await rm(root_created_dir, {recursive: true});
|
|
201
204
|
}
|
|
202
205
|
} else if (!path_already_exists) {
|
|
203
|
-
if (
|
|
204
|
-
|
|
206
|
+
if (await fs_exists(path)) {
|
|
207
|
+
await rm(path, {recursive: true});
|
|
205
208
|
}
|
|
206
209
|
}
|
|
207
210
|
};
|
|
@@ -214,31 +217,31 @@ const copy_temporarily = (
|
|
|
214
217
|
* @param contents
|
|
215
218
|
* @returns cleanup function that deletes the file and any created dirs
|
|
216
219
|
*/
|
|
217
|
-
const create_temporarily = (path: string, contents: string):
|
|
220
|
+
const create_temporarily = async (path: string, contents: string): Promise<AsyncCleanup> => {
|
|
218
221
|
const dir = dirname(path);
|
|
219
222
|
|
|
220
|
-
const dir_already_exists =
|
|
223
|
+
const dir_already_exists = await fs_exists(dir);
|
|
221
224
|
let root_created_dir: string | undefined;
|
|
222
225
|
if (!dir_already_exists) {
|
|
223
|
-
root_created_dir = to_root_dir_that_doesnt_exist(dir);
|
|
226
|
+
root_created_dir = await to_root_dir_that_doesnt_exist(dir);
|
|
224
227
|
if (!root_created_dir) throw Error();
|
|
225
|
-
|
|
228
|
+
await mkdir(dir, {recursive: true});
|
|
226
229
|
}
|
|
227
230
|
|
|
228
|
-
const path_already_exists =
|
|
231
|
+
const path_already_exists = await fs_exists(path);
|
|
229
232
|
if (!path_already_exists) {
|
|
230
|
-
|
|
233
|
+
await writeFile(path, contents, 'utf8');
|
|
231
234
|
}
|
|
232
235
|
|
|
233
|
-
return () => {
|
|
236
|
+
return async () => {
|
|
234
237
|
if (!dir_already_exists) {
|
|
235
238
|
if (!root_created_dir) throw Error();
|
|
236
|
-
if (
|
|
237
|
-
|
|
239
|
+
if (await fs_exists(root_created_dir)) {
|
|
240
|
+
await rm(root_created_dir, {recursive: true});
|
|
238
241
|
}
|
|
239
242
|
} else if (!path_already_exists) {
|
|
240
|
-
if (
|
|
241
|
-
|
|
243
|
+
if (await fs_exists(path)) {
|
|
244
|
+
await rm(path);
|
|
242
245
|
}
|
|
243
246
|
}
|
|
244
247
|
};
|
|
@@ -249,11 +252,12 @@ const create_temporarily = (path: string, contents: string): Cleanup => {
|
|
|
249
252
|
* for `/a/b/DOESNT_EXIST/NOR_THIS/ETC` returns `/a/b/DOESNT_EXIST`
|
|
250
253
|
* where `/a/b` does exist on the filesystem and `DOESNT_EXIST` is not one of its subdirectories.
|
|
251
254
|
*/
|
|
252
|
-
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> => {
|
|
253
256
|
let prev: string | undefined;
|
|
254
257
|
let d = dir;
|
|
255
258
|
do {
|
|
256
|
-
|
|
259
|
+
// eslint-disable-next-line no-await-in-loop
|
|
260
|
+
if (await fs_exists(d)) {
|
|
257
261
|
return prev;
|
|
258
262
|
}
|
|
259
263
|
prev = d;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {print_spawn_result, spawn} from '@
|
|
1
|
+
import {print_spawn_result, spawn} from '@fuzdev/fuz_util/process.js';
|
|
2
2
|
|
|
3
3
|
import type {Plugin} from './plugin.ts';
|
|
4
4
|
import {TaskError} from './task.ts';
|
|
@@ -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 {
|
|
3
|
-
import {
|
|
2
|
+
import {stat} from 'node:fs/promises';
|
|
3
|
+
import {fs_exists, fs_search} from '@fuzdev/fuz_util/fs.js';
|
|
4
|
+
import {strip_start} from '@fuzdev/fuz_util/string.js';
|
|
4
5
|
import {z} from 'zod';
|
|
5
|
-
import type {Flavored} from '@
|
|
6
|
-
import type {PathInfo, PathId, ResolvedPath} from '@
|
|
6
|
+
import type {Flavored} from '@fuzdev/fuz_util/types.js';
|
|
7
|
+
import type {PathInfo, PathId, ResolvedPath} from '@fuzdev/fuz_util/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.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {attach_process_error_handlers} from '@
|
|
2
|
-
import {configure_print_colors} from '@
|
|
1
|
+
import {attach_process_error_handlers} from '@fuzdev/fuz_util/process.js';
|
|
2
|
+
import {configure_print_colors} from '@fuzdev/fuz_util/print.js';
|
|
3
3
|
|
|
4
4
|
import {invoke_task} from './invoke_task.ts';
|
|
5
5
|
import {to_task_args} from './args.ts';
|
package/src/lib/invoke_task.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {styleText as st} from 'node:util';
|
|
2
|
-
import {create_stopwatch, Timings} from '@
|
|
3
|
-
import {print_ms, print_timings} from '@
|
|
4
|
-
import {Logger} from '@
|
|
2
|
+
import {create_stopwatch, Timings} from '@fuzdev/fuz_util/timings.js';
|
|
3
|
+
import {print_ms, print_timings} from '@fuzdev/fuz_util/print.js';
|
|
4
|
+
import {Logger} from '@fuzdev/fuz_util/log.js';
|
|
5
5
|
|
|
6
6
|
import {to_forwarded_args, type Args} from './args.ts';
|
|
7
7
|
import {run_task} from './run_task.ts';
|
|
@@ -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();
|