@ryanatkn/gro 0.119.1 → 0.120.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/changelog.d.ts +1 -0
- package/dist/changeset.task.js +4 -5
- package/dist/clean_fs.d.ts +1 -2
- package/dist/clean_fs.js +3 -2
- package/dist/cli.d.ts +1 -2
- package/dist/cli.js +2 -2
- package/dist/config.d.ts +14 -1
- package/dist/config.js +17 -5
- package/dist/config.test.js +50 -1
- package/dist/deploy.task.js +8 -7
- package/dist/docs/README.gen.md.js +3 -3
- package/dist/docs/config.md +22 -6
- package/dist/docs/gen.md +2 -1
- package/dist/docs/task.md +4 -3
- package/dist/docs/tasks.gen.md.js +17 -10
- package/dist/docs/tasks.md +1 -0
- package/dist/env.d.ts +2 -3
- package/dist/env.js +2 -2
- package/dist/esbuild_helpers.d.ts +2 -1
- package/dist/esbuild_plugin_external_worker.d.ts +0 -1
- package/dist/esbuild_plugin_external_worker.js +7 -7
- package/dist/esbuild_plugin_svelte.d.ts +0 -1
- package/dist/esbuild_plugin_sveltekit_local_imports.js +2 -2
- package/dist/format_directory.d.ts +1 -0
- package/dist/fs.d.ts +1 -3
- package/dist/fs.js +3 -13
- package/dist/fs.test.js +5 -5
- package/dist/gen.d.ts +66 -13
- package/dist/gen.js +78 -9
- package/dist/gen.task.d.ts +3 -0
- package/dist/gen.task.js +24 -19
- package/dist/gen.test.js +48 -35
- package/dist/git.d.ts +0 -1
- package/dist/git.js +3 -3
- package/dist/gro_helpers.js +4 -4
- package/dist/gro_plugin_gen.js +7 -7
- package/dist/gro_plugin_server.d.ts +2 -2
- package/dist/gro_plugin_server.js +5 -5
- package/dist/gro_plugin_sveltekit_app.js +8 -8
- package/dist/hash.d.ts +1 -2
- package/dist/input_path.d.ts +34 -16
- package/dist/input_path.js +119 -67
- package/dist/input_path.test.js +150 -46
- package/dist/invoke_task.d.ts +2 -1
- package/dist/invoke_task.js +33 -79
- package/dist/loader.d.ts +0 -1
- package/dist/loader.js +4 -4
- package/dist/modules.d.ts +17 -36
- package/dist/modules.js +29 -68
- package/dist/modules.test.js +19 -143
- package/dist/package.d.ts +11 -20
- package/dist/package.js +61 -64
- package/dist/package_json.d.ts +1 -0
- package/dist/package_json.js +1 -1
- package/dist/package_meta.d.ts +1 -1
- package/dist/path.d.ts +12 -8
- package/dist/path.js +0 -6
- package/dist/paths.d.ts +7 -12
- package/dist/paths.js +11 -34
- package/dist/paths.test.js +17 -15
- package/dist/plugin.d.ts +1 -1
- package/dist/publish.task.js +3 -3
- package/dist/resolve.task.d.ts +11 -0
- package/dist/resolve.task.js +24 -0
- package/dist/resolve_node_specifier.d.ts +2 -2
- package/dist/resolve_node_specifier.js +3 -3
- package/dist/resolve_specifier.d.ts +2 -1
- package/dist/resolve_specifier.js +16 -16
- package/dist/resolve_specifier.test.js +9 -9
- package/dist/run.task.js +2 -2
- package/dist/run_gen.d.ts +4 -4
- package/dist/run_gen.js +9 -16
- package/dist/run_gen.test.js +10 -15
- package/dist/run_task.d.ts +2 -1
- package/dist/run_task.js +2 -0
- package/dist/search_fs.d.ts +20 -7
- package/dist/search_fs.js +40 -18
- package/dist/search_fs.test.js +9 -11
- package/dist/src_json.js +2 -2
- package/dist/sveltekit_config.d.ts +0 -1
- package/dist/sveltekit_helpers.js +4 -4
- package/dist/sveltekit_shim_app.d.ts +1 -1
- package/dist/sveltekit_shim_app_forms.d.ts +0 -1
- package/dist/sveltekit_shim_app_navigation.d.ts +0 -1
- package/dist/sveltekit_shim_app_paths.d.ts +0 -1
- package/dist/sveltekit_shim_app_stores.d.ts +0 -1
- package/dist/sveltekit_shim_env.d.ts +1 -1
- package/dist/task.d.ts +65 -1
- package/dist/task.js +86 -13
- package/dist/task.test.js +25 -11
- package/dist/task_logging.d.ts +3 -6
- package/dist/task_logging.js +18 -36
- package/dist/watch_dir.d.ts +2 -2
- package/dist/watch_dir.js +14 -16
- package/package.json +18 -23
- package/dist/gen_module.d.ts +0 -34
- package/dist/gen_module.js +0 -32
- package/dist/gen_module.test.d.ts +0 -1
- package/dist/gen_module.test.js +0 -30
- package/dist/task_module.d.ts +0 -15
- package/dist/task_module.js +0 -18
- package/dist/task_module.test.d.ts +0 -1
- package/dist/task_module.test.js +0 -67
package/dist/git.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn, spawn_out } from '@ryanatkn/belt/process.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import {
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
4
|
import { to_file_path } from './path.js';
|
|
5
5
|
// TODO maybe extract to `util-git`
|
|
6
6
|
export const Git_Origin = z.string().brand('Git_Origin');
|
|
@@ -20,7 +20,7 @@ export const git_current_branch_name = async (options) => {
|
|
|
20
20
|
*/
|
|
21
21
|
export const git_remote_branch_exists = async (origin = 'origin', branch, options) => {
|
|
22
22
|
const final_branch = branch ?? (await git_current_branch_name(options));
|
|
23
|
-
if (options?.cwd && !(
|
|
23
|
+
if (options?.cwd && !existsSync(to_file_path(options.cwd))) {
|
|
24
24
|
return false;
|
|
25
25
|
}
|
|
26
26
|
const result = await spawn('git', ['ls-remote', '--exit-code', '--heads', origin, 'refs/heads/' + final_branch], options);
|
|
@@ -38,7 +38,7 @@ export const git_remote_branch_exists = async (origin = 'origin', branch, option
|
|
|
38
38
|
* @returns a boolean indicating if the local git branch exists
|
|
39
39
|
*/
|
|
40
40
|
export const git_local_branch_exists = async (branch, options) => {
|
|
41
|
-
if (options?.cwd && !(
|
|
41
|
+
if (options?.cwd && !existsSync(to_file_path(options.cwd))) {
|
|
42
42
|
return false;
|
|
43
43
|
}
|
|
44
44
|
const result = await spawn('git', ['show-ref', '--quiet', 'refs/heads/' + branch], options);
|
package/dist/gro_helpers.js
CHANGED
|
@@ -2,7 +2,7 @@ import { realpath } from 'node:fs/promises';
|
|
|
2
2
|
import { join, resolve } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { spawn } from '@ryanatkn/belt/process.js';
|
|
5
|
-
import {
|
|
5
|
+
import { existsSync } from 'node:fs';
|
|
6
6
|
import { NODE_MODULES_DIRNAME, SVELTEKIT_DIST_DIRNAME } from './path_constants.js';
|
|
7
7
|
/*
|
|
8
8
|
|
|
@@ -47,14 +47,14 @@ export const resolve_gro_module_path = async (path = '') => {
|
|
|
47
47
|
const gro_bin_path = resolve(NODE_MODULES_DIRNAME, '.bin/gro');
|
|
48
48
|
// case 1
|
|
49
49
|
// Prefer any locally installed version of Gro.
|
|
50
|
-
if (
|
|
50
|
+
if (existsSync(gro_bin_path)) {
|
|
51
51
|
return join(await realpath(gro_bin_path), '..', path);
|
|
52
52
|
}
|
|
53
53
|
// case 2
|
|
54
54
|
// If running Gro inside its own repo, require the local dist.
|
|
55
55
|
// If the local dist is not yet built it will fall back to the global.
|
|
56
|
-
if ((
|
|
57
|
-
(
|
|
56
|
+
if (existsSync(join(SVELTEKIT_DIST_DIRNAME, 'gro.js')) &&
|
|
57
|
+
existsSync(join(SVELTEKIT_DIST_DIRNAME, path))) {
|
|
58
58
|
return resolve(SVELTEKIT_DIST_DIRNAME, path);
|
|
59
59
|
}
|
|
60
60
|
// case 3
|
package/dist/gro_plugin_gen.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// because we no longer have a normal system build - replace with an esbuild plugin
|
|
3
3
|
// @ts-nocheck
|
|
4
4
|
import { spawn } from '@ryanatkn/belt/process.js';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { path_id_to_base_path } from './paths.js';
|
|
6
|
+
import { find_genfiles, is_gen_path } from './gen.js';
|
|
7
7
|
import { filter_dependents } from './build/source_file.js';
|
|
8
8
|
import { throttle } from './throttle.js';
|
|
9
9
|
const FLUSH_DEBOUNCE_DELAY = 500;
|
|
@@ -35,7 +35,7 @@ export const plugin = () => {
|
|
|
35
35
|
const gen = (files = []) => spawn_cli('gro', ['gen', ...files]);
|
|
36
36
|
return {
|
|
37
37
|
name: 'gro_plugin_gen',
|
|
38
|
-
setup: async ({ args: { watch }, dev, log }) => {
|
|
38
|
+
setup: async ({ args: { watch }, dev, log, config }) => {
|
|
39
39
|
// For production builds, we assume `gen` is already fresh,
|
|
40
40
|
// which should be checked by CI via `gro check` which calls `gro gen --check`.
|
|
41
41
|
if (!dev)
|
|
@@ -44,8 +44,8 @@ export const plugin = () => {
|
|
|
44
44
|
// Some parts of the build may have already happened,
|
|
45
45
|
// making us miss `build` events for gen dependencies,
|
|
46
46
|
// so we run `gen` here even if it's usually wasteful.
|
|
47
|
-
const found = await
|
|
48
|
-
if (found.ok && found.
|
|
47
|
+
const found = await find_genfiles([paths.source], root_dirs, config);
|
|
48
|
+
if (found.ok && found.resolved_input_files_by_input_path.size > 0) {
|
|
49
49
|
await gen();
|
|
50
50
|
}
|
|
51
51
|
// Do we need to just generate everything once and exit?
|
|
@@ -61,12 +61,12 @@ export const plugin = () => {
|
|
|
61
61
|
// but we probably want to make this an esbuild plugin instead
|
|
62
62
|
// if (build_config.name !== 'system') return;
|
|
63
63
|
if (is_gen_path(source_file.id)) {
|
|
64
|
-
queue_gen(
|
|
64
|
+
queue_gen(path_id_to_base_path(source_file.id));
|
|
65
65
|
}
|
|
66
66
|
const dependent_gen_file_ids = filter_dependents(source_file, build_config, filer.find_by_id, // cast because we can assume they're all `SourceFile`s
|
|
67
67
|
is_gen_path);
|
|
68
68
|
for (const dependent_gen_file_id of dependent_gen_file_ids) {
|
|
69
|
-
queue_gen(
|
|
69
|
+
queue_gen(path_id_to_base_path(dependent_gen_file_id));
|
|
70
70
|
}
|
|
71
71
|
};
|
|
72
72
|
filer.on('build', on_filer_build);
|
|
@@ -2,8 +2,8 @@ import * as esbuild from 'esbuild';
|
|
|
2
2
|
import type { Config as SvelteKitConfig } from '@sveltejs/kit';
|
|
3
3
|
import type { Result } from '@ryanatkn/belt/result.js';
|
|
4
4
|
import type { Plugin, Plugin_Context } from './plugin.js';
|
|
5
|
-
export declare const SERVER_SOURCE_ID: Flavored<string, "
|
|
6
|
-
export declare const has_server: (path?: Flavored<string, "
|
|
5
|
+
export declare const SERVER_SOURCE_ID: Flavored<string, "Path_Id">;
|
|
6
|
+
export declare const has_server: (path?: Flavored<string, "Path_Id">) => Promise<Result<object, {
|
|
7
7
|
message: string;
|
|
8
8
|
}>>;
|
|
9
9
|
export interface Options {
|
|
@@ -3,7 +3,8 @@ import * as esbuild from 'esbuild';
|
|
|
3
3
|
import { join, resolve } from 'node:path';
|
|
4
4
|
import { identity } from '@ryanatkn/belt/function.js';
|
|
5
5
|
import { strip_before, strip_end } from '@ryanatkn/belt/string.js';
|
|
6
|
-
import {
|
|
6
|
+
import { existsSync } from 'node:fs';
|
|
7
|
+
import { base_path_to_path_id, LIB_DIRNAME, paths } from './paths.js';
|
|
7
8
|
import { GRO_DEV_DIRNAME, SERVER_DIST_PATH } from './path_constants.js';
|
|
8
9
|
import { watch_dir } from './watch_dir.js';
|
|
9
10
|
import { init_sveltekit_config } from './sveltekit_config.js';
|
|
@@ -13,14 +14,13 @@ import { print_build_result, to_define_import_meta_env } from './esbuild_helpers
|
|
|
13
14
|
import { esbuild_plugin_sveltekit_shim_alias } from './esbuild_plugin_sveltekit_shim_alias.js';
|
|
14
15
|
import { esbuild_plugin_external_worker } from './esbuild_plugin_external_worker.js';
|
|
15
16
|
import { esbuild_plugin_sveltekit_local_imports } from './esbuild_plugin_sveltekit_local_imports.js';
|
|
16
|
-
import { exists } from './fs.js';
|
|
17
17
|
import { esbuild_plugin_svelte } from './esbuild_plugin_svelte.js';
|
|
18
18
|
import { throttle } from './throttle.js';
|
|
19
19
|
import { sveltekit_config_global } from './sveltekit_config_global.js';
|
|
20
20
|
// TODO sourcemap as a hoisted option? disable for production by default - or like `outpaths`, passed a `dev` param
|
|
21
|
-
export const SERVER_SOURCE_ID =
|
|
21
|
+
export const SERVER_SOURCE_ID = base_path_to_path_id(LIB_DIRNAME + '/server/server.ts');
|
|
22
22
|
export const has_server = async (path = SERVER_SOURCE_ID) => {
|
|
23
|
-
if (!(
|
|
23
|
+
if (!existsSync(path)) {
|
|
24
24
|
return { ok: false, message: `no server file found at ${path}` };
|
|
25
25
|
}
|
|
26
26
|
return { ok: true };
|
|
@@ -138,7 +138,7 @@ export const gro_plugin_server = ({ entry_points = [SERVER_SOURCE_ID], dir = pro
|
|
|
138
138
|
await watcher.init();
|
|
139
139
|
watcher_ready = true;
|
|
140
140
|
}
|
|
141
|
-
if (!(
|
|
141
|
+
if (!existsSync(server_outpath)) {
|
|
142
142
|
throw Error(`Node server failed to start due to missing file: ${server_outpath}`);
|
|
143
143
|
}
|
|
144
144
|
if (run ?? dev) {
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { spawn_process } from '@ryanatkn/belt/process.js';
|
|
2
2
|
import { cp, mkdir, rm, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
|
+
import { existsSync } from 'node:fs';
|
|
4
5
|
import { print_command_args, serialize_args, to_forwarded_args } from './args.js';
|
|
5
|
-
import { exists } from './fs.js';
|
|
6
6
|
import { serialize_package_json, load_package_json } from './package_json.js';
|
|
7
7
|
import { Task_Error } from './task.js';
|
|
8
8
|
import { spawn_cli } from './cli.js';
|
|
9
9
|
import { serialize_src_json, create_src_json } from './src_json.js';
|
|
10
10
|
import { DEFAULT_EXPORTS_EXCLUDER } from './config.js';
|
|
11
11
|
import { sveltekit_config_global } from './sveltekit_config_global.js';
|
|
12
|
+
import { SOURCE_DIRNAME } from './path_constants.js';
|
|
12
13
|
export const gro_plugin_sveltekit_app = ({ host_target = 'github_pages', well_known_package_json, well_known_src_json, well_known_src_files, } = {}) => {
|
|
13
14
|
let sveltekit_process = null;
|
|
14
15
|
return {
|
|
@@ -64,7 +65,7 @@ export const gro_plugin_sveltekit_app = ({ host_target = 'github_pages', well_kn
|
|
|
64
65
|
? await create_temporarily(join(assets_path, '.well-known/src.json'), serialized_src_json)
|
|
65
66
|
: null,
|
|
66
67
|
serialized_src_json && well_known_src_files
|
|
67
|
-
? await copy_temporarily(
|
|
68
|
+
? await copy_temporarily(SOURCE_DIRNAME, assets_path, '.well-known', well_known_src_files === true
|
|
68
69
|
? (file_path) => !DEFAULT_EXPORTS_EXCLUDER.test(file_path)
|
|
69
70
|
: well_known_src_files)
|
|
70
71
|
: null,
|
|
@@ -106,7 +107,7 @@ export const gro_plugin_sveltekit_app = ({ host_target = 'github_pages', well_kn
|
|
|
106
107
|
const copy_temporarily = async (source_path, dest_dir, dest_base_dir = '', filter) => {
|
|
107
108
|
const path = join(dest_dir, dest_base_dir, source_path);
|
|
108
109
|
const dir = dirname(path);
|
|
109
|
-
const dir_already_exists =
|
|
110
|
+
const dir_already_exists = existsSync(dir);
|
|
110
111
|
let root_created_dir;
|
|
111
112
|
if (!dir_already_exists) {
|
|
112
113
|
root_created_dir = await to_root_dir_that_doesnt_exist(dir);
|
|
@@ -114,7 +115,7 @@ const copy_temporarily = async (source_path, dest_dir, dest_base_dir = '', filte
|
|
|
114
115
|
throw Error();
|
|
115
116
|
await mkdir(dir, { recursive: true });
|
|
116
117
|
}
|
|
117
|
-
const path_already_exists =
|
|
118
|
+
const path_already_exists = existsSync(path);
|
|
118
119
|
if (!path_already_exists) {
|
|
119
120
|
await cp(source_path, path, { recursive: true, filter });
|
|
120
121
|
}
|
|
@@ -138,7 +139,7 @@ const copy_temporarily = async (source_path, dest_dir, dest_base_dir = '', filte
|
|
|
138
139
|
*/
|
|
139
140
|
const create_temporarily = async (path, contents) => {
|
|
140
141
|
const dir = dirname(path);
|
|
141
|
-
const dir_already_exists =
|
|
142
|
+
const dir_already_exists = existsSync(dir);
|
|
142
143
|
let root_created_dir;
|
|
143
144
|
if (!dir_already_exists) {
|
|
144
145
|
root_created_dir = await to_root_dir_that_doesnt_exist(dir);
|
|
@@ -146,7 +147,7 @@ const create_temporarily = async (path, contents) => {
|
|
|
146
147
|
throw Error();
|
|
147
148
|
await mkdir(dir, { recursive: true });
|
|
148
149
|
}
|
|
149
|
-
const path_already_exists =
|
|
150
|
+
const path_already_exists = existsSync(path);
|
|
150
151
|
if (!path_already_exists) {
|
|
151
152
|
await writeFile(path, contents, 'utf8');
|
|
152
153
|
}
|
|
@@ -170,8 +171,7 @@ const to_root_dir_that_doesnt_exist = async (dir) => {
|
|
|
170
171
|
let prev;
|
|
171
172
|
let d = dir;
|
|
172
173
|
do {
|
|
173
|
-
|
|
174
|
-
if (await exists(d)) {
|
|
174
|
+
if (existsSync(d)) {
|
|
175
175
|
return prev;
|
|
176
176
|
}
|
|
177
177
|
prev = d;
|
package/dist/hash.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
/**
|
|
3
2
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
|
|
4
3
|
*/
|
|
5
|
-
export declare const to_hash: (data: Buffer, algorithm?:
|
|
4
|
+
export declare const to_hash: (data: Buffer, algorithm?: "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512") => Promise<string>;
|
package/dist/input_path.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { Flavored } from '@ryanatkn/belt/types.js';
|
|
3
|
-
import {
|
|
4
|
-
import { type Path_Data } from './path.js';
|
|
3
|
+
import type { Path_Id } from './path.js';
|
|
5
4
|
export declare const Input_Path: z.ZodString;
|
|
6
5
|
export type Input_Path = Flavored<z.infer<typeof Input_Path>, 'Input_Path'>;
|
|
7
6
|
export declare const Raw_Input_Path: z.ZodString;
|
|
@@ -18,30 +17,49 @@ export type Raw_Input_Path = Flavored<z.infer<typeof Raw_Input_Path>, 'Raw_Input
|
|
|
18
17
|
*
|
|
19
18
|
* Thus, input paths are either absolute or implicitly relative.
|
|
20
19
|
*/
|
|
21
|
-
export declare const to_input_path: (raw_input_path:
|
|
20
|
+
export declare const to_input_path: (raw_input_path: Raw_Input_Path, root_path?: string) => Input_Path;
|
|
22
21
|
export declare const to_input_paths: (raw_input_paths: Raw_Input_Path[], root_path?: string) => Input_Path[];
|
|
22
|
+
export interface Possible_Path {
|
|
23
|
+
id: Path_Id;
|
|
24
|
+
input_path: Input_Path;
|
|
25
|
+
root_dir: Path_Id;
|
|
26
|
+
}
|
|
23
27
|
/**
|
|
24
28
|
* Gets a list of possible source ids for each input path with `extensions`,
|
|
25
|
-
* duplicating each under `root_dirs
|
|
26
|
-
* This is first used to fall back to the Gro dir to search for tasks.
|
|
27
|
-
* It's the helper used in implementations of `get_possible_source_ids_for_input_path` below.
|
|
29
|
+
* duplicating each under `root_dirs`, without checking the filesystem.
|
|
28
30
|
*/
|
|
29
|
-
export declare const
|
|
31
|
+
export declare const get_possible_paths: (input_path: Input_Path, root_dirs: Path_Id[], extensions: string[]) => Possible_Path[];
|
|
32
|
+
export interface Resolved_Input_Path {
|
|
33
|
+
input_path: Input_Path;
|
|
34
|
+
id: Path_Id;
|
|
35
|
+
is_directory: boolean;
|
|
36
|
+
root_dir: Path_Id;
|
|
37
|
+
}
|
|
38
|
+
export interface Resolved_Input_File {
|
|
39
|
+
id: Path_Id;
|
|
40
|
+
input_path: Input_Path;
|
|
41
|
+
resolved_input_path: Resolved_Input_Path;
|
|
42
|
+
}
|
|
43
|
+
export interface Resolved_Input_Paths {
|
|
44
|
+
resolved_input_paths: Resolved_Input_Path[];
|
|
45
|
+
resolved_input_paths_by_input_path: Map<Input_Path, Resolved_Input_Path[]>;
|
|
46
|
+
possible_paths_by_input_path: Map<Input_Path, Possible_Path[]>;
|
|
47
|
+
unmapped_input_paths: Input_Path[];
|
|
48
|
+
}
|
|
30
49
|
/**
|
|
31
50
|
* Gets the path data for each input path, checking the filesystem for the possibilities
|
|
32
51
|
* and stopping at the first existing file or falling back to the first existing directory.
|
|
33
52
|
* If none is found for an input path, it's added to `unmapped_input_paths`.
|
|
34
53
|
*/
|
|
35
|
-
export declare const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
54
|
+
export declare const resolve_input_paths: (input_paths: Input_Path[], root_dirs: Path_Id[], extensions: string[]) => Promise<Resolved_Input_Paths>;
|
|
55
|
+
export interface Resolved_Input_Files {
|
|
56
|
+
resolved_input_files: Resolved_Input_File[];
|
|
57
|
+
resolved_input_files_by_input_path: Map<Input_Path, Resolved_Input_File[]>;
|
|
58
|
+
resolved_input_files_by_root_dir: Map<Path_Id, Resolved_Input_File[]>;
|
|
59
|
+
input_directories_with_no_files: Resolved_Input_Path[];
|
|
60
|
+
}
|
|
39
61
|
/**
|
|
40
62
|
* Finds all of the matching files for the given input paths.
|
|
41
63
|
* De-dupes source ids.
|
|
42
64
|
*/
|
|
43
|
-
export declare const
|
|
44
|
-
source_ids_by_input_path: Map<Input_Path, Source_Id[]>;
|
|
45
|
-
input_directories_with_no_files: Input_Path[];
|
|
46
|
-
}>;
|
|
47
|
-
export declare const to_gro_input_path: (input_path: Flavored<string, "Input_Path">) => Flavored<string, "Input_Path">;
|
|
65
|
+
export declare const resolve_input_files: (resolved_input_paths: Resolved_Input_Path[], custom_search_fs?: (dir: string, options?: import("./search_fs.js").Search_Fs_Options) => Promise<import("./path.js").Resolved_Path[]>) => Promise<Resolved_Input_Files>;
|
package/dist/input_path.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { isAbsolute, join, resolve } from 'node:path';
|
|
1
|
+
import { dirname, isAbsolute, join, resolve } from 'node:path';
|
|
2
|
+
import { existsSync, statSync } from 'node:fs';
|
|
2
3
|
import { strip_start } from '@ryanatkn/belt/string.js';
|
|
3
|
-
import { stat } from 'node:fs/promises';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
-
import { GRO_PACKAGE_DIR, GRO_DIST_DIR
|
|
6
|
-
import { to_path_data } from './path.js';
|
|
7
|
-
import { exists } from './fs.js';
|
|
5
|
+
import { GRO_PACKAGE_DIR, GRO_DIST_DIR } from './paths.js';
|
|
8
6
|
import { search_fs } from './search_fs.js';
|
|
9
7
|
import { TASK_FILE_SUFFIX_JS } from './task.js';
|
|
10
8
|
// TODO Flavored doesn't work when used in schemas, use Zod brand instead? problem is ergonomics
|
|
@@ -34,124 +32,178 @@ export const to_input_path = (raw_input_path, root_path = process.cwd()) => {
|
|
|
34
32
|
export const to_input_paths = (raw_input_paths, root_path) => raw_input_paths.map((p) => to_input_path(p, root_path));
|
|
35
33
|
/**
|
|
36
34
|
* Gets a list of possible source ids for each input path with `extensions`,
|
|
37
|
-
* duplicating each under `root_dirs
|
|
38
|
-
* This is first used to fall back to the Gro dir to search for tasks.
|
|
39
|
-
* It's the helper used in implementations of `get_possible_source_ids_for_input_path` below.
|
|
35
|
+
* duplicating each under `root_dirs`, without checking the filesystem.
|
|
40
36
|
*/
|
|
41
|
-
export const
|
|
42
|
-
const
|
|
43
|
-
const
|
|
37
|
+
export const get_possible_paths = (input_path, root_dirs, extensions) => {
|
|
38
|
+
const possible_paths = new Set();
|
|
39
|
+
const add_possible_paths = (path, root_dir) => {
|
|
44
40
|
// Specifically for paths to the Gro package dist, optimize by only looking for `.task.js`.
|
|
45
41
|
if (path.startsWith(GRO_DIST_DIR)) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
possible_paths.add({
|
|
43
|
+
id: (path.endsWith('/') || path.endsWith(TASK_FILE_SUFFIX_JS)
|
|
44
|
+
? path
|
|
45
|
+
: path + TASK_FILE_SUFFIX_JS),
|
|
46
|
+
input_path,
|
|
47
|
+
root_dir,
|
|
48
|
+
});
|
|
49
49
|
}
|
|
50
50
|
else {
|
|
51
|
-
|
|
51
|
+
possible_paths.add({ id: path, input_path, root_dir });
|
|
52
52
|
if (!path.endsWith('/') && !extensions.some((e) => path.endsWith(e))) {
|
|
53
53
|
for (const extension of extensions) {
|
|
54
|
-
|
|
54
|
+
possible_paths.add({ id: path + extension, input_path, root_dir });
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
59
|
if (isAbsolute(input_path)) {
|
|
60
|
-
|
|
60
|
+
// TODO this is hacky because it's the only place we're using sync fs calls (even if they're faster, it's oddly inconsistent),
|
|
61
|
+
// we probably should just change this function to check the filesystem and not return non-existing paths
|
|
62
|
+
add_possible_paths(input_path, existsSync(input_path) && statSync(input_path).isDirectory()
|
|
63
|
+
? input_path
|
|
64
|
+
: dirname(input_path));
|
|
61
65
|
}
|
|
62
66
|
else {
|
|
63
67
|
for (const root_dir of root_dirs) {
|
|
64
|
-
|
|
68
|
+
add_possible_paths(join(root_dir, input_path), root_dir);
|
|
65
69
|
}
|
|
66
70
|
}
|
|
67
|
-
return
|
|
71
|
+
return Array.from(possible_paths);
|
|
68
72
|
};
|
|
69
73
|
/**
|
|
70
74
|
* Gets the path data for each input path, checking the filesystem for the possibilities
|
|
71
75
|
* and stopping at the first existing file or falling back to the first existing directory.
|
|
72
76
|
* If none is found for an input path, it's added to `unmapped_input_paths`.
|
|
73
77
|
*/
|
|
74
|
-
export const
|
|
75
|
-
const
|
|
78
|
+
export const resolve_input_paths = async (input_paths, root_dirs, extensions) => {
|
|
79
|
+
const resolved_input_paths = [];
|
|
80
|
+
const possible_paths_by_input_path = new Map();
|
|
76
81
|
const unmapped_input_paths = [];
|
|
77
82
|
for (const input_path of input_paths) {
|
|
78
|
-
let
|
|
79
|
-
let
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
: [input_path];
|
|
83
|
+
let found_file = null;
|
|
84
|
+
let found_dirs = null;
|
|
85
|
+
const possible_paths = get_possible_paths(input_path, root_dirs, extensions);
|
|
86
|
+
possible_paths_by_input_path.set(input_path, possible_paths);
|
|
83
87
|
// Find the first existing file path or fallback to the first directory path.
|
|
84
|
-
for (const
|
|
85
|
-
if (!(
|
|
86
|
-
continue;
|
|
87
|
-
const stats =
|
|
88
|
+
for (const possible_path of possible_paths) {
|
|
89
|
+
if (!existsSync(possible_path.id))
|
|
90
|
+
continue;
|
|
91
|
+
const stats = statSync(possible_path.id);
|
|
88
92
|
if (stats.isDirectory()) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
dir_path_data = to_path_data(possible_source_id, stats);
|
|
93
|
+
found_dirs ??= [];
|
|
94
|
+
found_dirs.push([{ id: possible_path.id, is_directory: stats.isDirectory() }, possible_path]);
|
|
92
95
|
}
|
|
93
96
|
else {
|
|
94
|
-
|
|
97
|
+
found_file = [{ id: possible_path.id, is_directory: stats.isDirectory() }, possible_path];
|
|
95
98
|
break;
|
|
96
99
|
}
|
|
97
100
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
+
if (found_file) {
|
|
102
|
+
resolved_input_paths.push({
|
|
103
|
+
input_path,
|
|
104
|
+
id: found_file[0].id,
|
|
105
|
+
is_directory: found_file[0].is_directory,
|
|
106
|
+
root_dir: found_file[1].root_dir,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
else if (found_dirs) {
|
|
110
|
+
for (const found_dir of found_dirs) {
|
|
111
|
+
resolved_input_paths.push({
|
|
112
|
+
input_path,
|
|
113
|
+
id: found_dir[0].id,
|
|
114
|
+
is_directory: found_dir[0].is_directory,
|
|
115
|
+
root_dir: found_dir[1].root_dir,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
101
118
|
}
|
|
102
119
|
else {
|
|
103
120
|
unmapped_input_paths.push(input_path);
|
|
104
121
|
}
|
|
105
122
|
}
|
|
106
|
-
return {
|
|
123
|
+
return {
|
|
124
|
+
resolved_input_paths,
|
|
125
|
+
resolved_input_paths_by_input_path: resolved_input_paths.reduce((map, resolved_input_path) => {
|
|
126
|
+
if (map.has(resolved_input_path.input_path)) {
|
|
127
|
+
map.get(resolved_input_path.input_path).push(resolved_input_path);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
map.set(resolved_input_path.input_path, [resolved_input_path]);
|
|
131
|
+
}
|
|
132
|
+
return map;
|
|
133
|
+
}, new Map()),
|
|
134
|
+
possible_paths_by_input_path,
|
|
135
|
+
unmapped_input_paths,
|
|
136
|
+
};
|
|
107
137
|
};
|
|
108
138
|
/**
|
|
109
139
|
* Finds all of the matching files for the given input paths.
|
|
110
140
|
* De-dupes source ids.
|
|
111
141
|
*/
|
|
112
|
-
export const
|
|
113
|
-
const
|
|
142
|
+
export const resolve_input_files = async (resolved_input_paths, custom_search_fs = search_fs) => {
|
|
143
|
+
const resolved_input_files = [];
|
|
144
|
+
const resolved_input_files_by_input_path = new Map();
|
|
114
145
|
const input_directories_with_no_files = [];
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
146
|
+
const existing_path_ids = new Set();
|
|
147
|
+
// TODO parallelize but would need to de-dupe and retain order
|
|
148
|
+
for (const resolved_input_path of resolved_input_paths) {
|
|
149
|
+
const { input_path, id, is_directory } = resolved_input_path;
|
|
150
|
+
if (is_directory) {
|
|
151
|
+
const files = await custom_search_fs(id, { include_directories: true }); // eslint-disable-line no-await-in-loop
|
|
152
|
+
if (files.length) {
|
|
153
|
+
const path_ids = [];
|
|
122
154
|
let has_files = false;
|
|
123
|
-
for (const
|
|
124
|
-
if (
|
|
155
|
+
for (const { path, is_directory } of files) {
|
|
156
|
+
if (is_directory)
|
|
125
157
|
continue;
|
|
126
158
|
has_files = true;
|
|
127
|
-
const
|
|
128
|
-
if (!
|
|
129
|
-
|
|
130
|
-
|
|
159
|
+
const path_id = join(id, path);
|
|
160
|
+
if (!existing_path_ids.has(path_id)) {
|
|
161
|
+
existing_path_ids.add(path_id);
|
|
162
|
+
path_ids.push(path_id);
|
|
131
163
|
}
|
|
132
164
|
}
|
|
133
|
-
if (
|
|
134
|
-
|
|
165
|
+
if (path_ids.length) {
|
|
166
|
+
const resolved_input_files_for_input_path = [];
|
|
167
|
+
for (const path_id of path_ids) {
|
|
168
|
+
const resolved_input_file = {
|
|
169
|
+
id: path_id,
|
|
170
|
+
input_path,
|
|
171
|
+
resolved_input_path,
|
|
172
|
+
};
|
|
173
|
+
resolved_input_files.push(resolved_input_file);
|
|
174
|
+
resolved_input_files_for_input_path.push(resolved_input_file);
|
|
175
|
+
}
|
|
176
|
+
resolved_input_files_by_input_path.set(input_path, resolved_input_files_for_input_path);
|
|
135
177
|
}
|
|
136
178
|
if (!has_files) {
|
|
137
|
-
input_directories_with_no_files.push(
|
|
179
|
+
input_directories_with_no_files.push(resolved_input_path);
|
|
138
180
|
}
|
|
139
181
|
// do callers ever need `input_directories_with_duplicate_files`?
|
|
140
182
|
}
|
|
141
183
|
else {
|
|
142
|
-
input_directories_with_no_files.push(
|
|
184
|
+
input_directories_with_no_files.push(resolved_input_path);
|
|
143
185
|
}
|
|
144
186
|
}
|
|
145
|
-
else if (!
|
|
146
|
-
|
|
147
|
-
|
|
187
|
+
else if (!existing_path_ids.has(id)) {
|
|
188
|
+
existing_path_ids.add(id);
|
|
189
|
+
const resolved_input_file = { id, input_path, resolved_input_path };
|
|
190
|
+
resolved_input_files.push(resolved_input_file);
|
|
191
|
+
resolved_input_files_by_input_path.set(input_path, [resolved_input_file]);
|
|
148
192
|
}
|
|
149
193
|
}
|
|
150
|
-
return {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
194
|
+
return {
|
|
195
|
+
resolved_input_files,
|
|
196
|
+
resolved_input_files_by_input_path,
|
|
197
|
+
resolved_input_files_by_root_dir: resolved_input_files.reduce((map, resolved_input_file) => {
|
|
198
|
+
const { root_dir } = resolved_input_file.resolved_input_path;
|
|
199
|
+
if (map.has(root_dir)) {
|
|
200
|
+
map.get(root_dir).push(resolved_input_file);
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
map.set(root_dir, [resolved_input_file]);
|
|
204
|
+
}
|
|
205
|
+
return map;
|
|
206
|
+
}, new Map()),
|
|
207
|
+
input_directories_with_no_files,
|
|
208
|
+
};
|
|
157
209
|
};
|