@ryanatkn/gro 0.116.2 → 0.118.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.
Files changed (74) hide show
  1. package/README.md +31 -15
  2. package/dist/changeset.task.js +1 -1
  3. package/dist/clean_fs.js +2 -1
  4. package/dist/cli.js +1 -1
  5. package/dist/config.d.ts +5 -0
  6. package/dist/config.js +11 -3
  7. package/dist/deploy.task.js +5 -4
  8. package/dist/docs/config.md +25 -0
  9. package/dist/docs/gen.md +16 -0
  10. package/dist/docs/task.md +38 -32
  11. package/dist/docs/tasks.gen.md.js +3 -4
  12. package/dist/esbuild_plugin_external_worker.js +1 -2
  13. package/dist/esbuild_plugin_svelte.js +1 -2
  14. package/dist/esbuild_plugin_sveltekit_shim_alias.js +1 -2
  15. package/dist/format_directory.js +3 -2
  16. package/dist/gen.d.ts +5 -0
  17. package/dist/gen.task.js +7 -8
  18. package/dist/gen_module.d.ts +2 -1
  19. package/dist/gen_module.js +1 -1
  20. package/dist/gro.config.default.js +3 -2
  21. package/dist/gro_helpers.js +18 -17
  22. package/dist/gro_plugin_server.js +9 -5
  23. package/dist/gro_plugin_sveltekit_app.d.ts +0 -1
  24. package/dist/gro_plugin_sveltekit_app.js +2 -4
  25. package/dist/gro_plugin_sveltekit_library.d.ts +0 -2
  26. package/dist/gro_plugin_sveltekit_library.js +1 -7
  27. package/dist/input_path.d.ts +27 -28
  28. package/dist/input_path.js +62 -66
  29. package/dist/input_path.test.js +26 -48
  30. package/dist/invoke_task.d.ts +1 -1
  31. package/dist/invoke_task.js +78 -88
  32. package/dist/lint.task.js +1 -1
  33. package/dist/loader.js +11 -4
  34. package/dist/module.d.ts +1 -1
  35. package/dist/module.js +2 -2
  36. package/dist/modules.d.ts +13 -9
  37. package/dist/modules.js +5 -13
  38. package/dist/modules.test.js +2 -2
  39. package/dist/package.d.ts +47 -6
  40. package/dist/package.gen.js +3 -3
  41. package/dist/package.js +89 -60
  42. package/dist/package_json.d.ts +5 -0
  43. package/dist/package_json.js +9 -4
  44. package/dist/package_meta.d.ts +1 -2
  45. package/dist/path_constants.d.ts +20 -0
  46. package/dist/path_constants.js +27 -0
  47. package/dist/paths.d.ts +11 -34
  48. package/dist/paths.js +28 -67
  49. package/dist/publish.task.js +3 -3
  50. package/dist/register.d.ts +1 -0
  51. package/dist/register.js +2 -0
  52. package/dist/release.task.js +1 -2
  53. package/dist/resolve_node_specifier.js +2 -1
  54. package/dist/run_gen.d.ts +2 -1
  55. package/dist/run_gen.js +2 -2
  56. package/dist/run_gen.test.js +3 -2
  57. package/dist/run_task.js +2 -2
  58. package/dist/sveltekit_config.d.ts +1 -1
  59. package/dist/sveltekit_config.js +9 -5
  60. package/dist/sveltekit_config_global.d.ts +4 -0
  61. package/dist/sveltekit_config_global.js +5 -0
  62. package/dist/sveltekit_helpers.d.ts +4 -0
  63. package/dist/sveltekit_helpers.js +12 -0
  64. package/dist/sync.task.js +4 -1
  65. package/dist/task.d.ts +1 -1
  66. package/dist/task.js +11 -6
  67. package/dist/task.test.js +9 -13
  68. package/dist/task_logging.d.ts +8 -0
  69. package/dist/{print_task.js → task_logging.js} +30 -16
  70. package/dist/task_module.d.ts +4 -3
  71. package/dist/task_module.js +7 -8
  72. package/dist/task_module.test.js +4 -7
  73. package/package.json +36 -20
  74. package/dist/print_task.d.ts +0 -4
@@ -1,10 +1,10 @@
1
1
  import { spawn_restartable_process } from '@ryanatkn/belt/process.js';
2
2
  import * as esbuild from 'esbuild';
3
- import { cwd } from 'node:process';
4
3
  import { join, resolve } from 'node:path';
5
4
  import { identity } from '@ryanatkn/belt/function.js';
6
- import { strip_before } from '@ryanatkn/belt/string.js';
7
- import { base_path_to_source_id, GRO_DEV_DIRNAME, SERVER_DIST_PATH, LIB_DIRNAME, paths, } from './paths.js';
5
+ import { strip_before, strip_end } from '@ryanatkn/belt/string.js';
6
+ import { base_path_to_source_id, LIB_DIRNAME, paths } from './paths.js';
7
+ import { GRO_DEV_DIRNAME, SERVER_DIST_PATH } from './path_constants.js';
8
8
  import { watch_dir } from './watch_dir.js';
9
9
  import { init_sveltekit_config } from './sveltekit_config.js';
10
10
  import { esbuild_plugin_sveltekit_shim_app } from './esbuild_plugin_sveltekit_shim_app.js';
@@ -16,10 +16,11 @@ import { esbuild_plugin_sveltekit_local_imports } from './esbuild_plugin_sveltek
16
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
+ import { sveltekit_config_global } from './sveltekit_config_global.js';
19
20
  // TODO sourcemap as a hoisted option? disable for production by default - or like `outpaths`, passed a `dev` param
20
21
  export const SERVER_SOURCE_ID = base_path_to_source_id(LIB_DIRNAME + '/server/server.ts');
21
22
  export const has_server = (path = SERVER_SOURCE_ID) => exists(path);
22
- export const gro_plugin_server = ({ entry_points = [SERVER_SOURCE_ID], dir = cwd(), outpaths = (dev) => ({
23
+ export const gro_plugin_server = ({ entry_points = [SERVER_SOURCE_ID], dir = process.cwd(), outpaths = (dev) => ({
23
24
  outdir: join(dir, dev ? GRO_DEV_DIRNAME : SERVER_DIST_PATH),
24
25
  outbase: paths.lib,
25
26
  outname: 'server/server.js',
@@ -32,7 +33,10 @@ export const gro_plugin_server = ({ entry_points = [SERVER_SOURCE_ID], dir = cwd
32
33
  return {
33
34
  name: 'gro_plugin_server',
34
35
  setup: async ({ dev, watch, timings, log }) => {
35
- const { alias, base_url, assets_url, env_dir, private_prefix, public_prefix, svelte_compile_options, svelte_compile_module_options, svelte_preprocessors, } = await init_sveltekit_config(sveltekit_config ?? dir);
36
+ const parsed_sveltekit_config = !sveltekit_config && strip_end(dir, '/') === process.cwd()
37
+ ? sveltekit_config_global
38
+ : await init_sveltekit_config(sveltekit_config ?? dir);
39
+ const { alias, base_url, assets_url, env_dir, private_prefix, public_prefix, svelte_compile_options, svelte_compile_module_options, svelte_preprocessors, } = parsed_sveltekit_config;
36
40
  // TODO hacky
37
41
  if (svelte_compile_options.generate === undefined) {
38
42
  svelte_compile_options.generate = 'server';
@@ -1,7 +1,6 @@
1
1
  import type { Plugin, Plugin_Context } from './plugin.js';
2
2
  import { type Map_Package_Json } from './package_json.js';
3
3
  import { type Map_Src_Json } from './src_json.js';
4
- export declare const has_sveltekit_app: () => Promise<boolean>;
5
4
  export interface Options {
6
5
  /**
7
6
  * Used for finalizing a SvelteKit build like adding a `.nojekyll` file for GitHub Pages.
@@ -4,13 +4,11 @@ import { dirname, join } from 'node:path';
4
4
  import { print_command_args, serialize_args, to_forwarded_args } from './args.js';
5
5
  import { exists } from './fs.js';
6
6
  import { serialize_package_json, load_package_json } from './package_json.js';
7
- import { init_sveltekit_config } from './sveltekit_config.js';
8
7
  import { Task_Error } from './task.js';
9
8
  import { spawn_cli } from './cli.js';
10
9
  import { serialize_src_json, create_src_json } from './src_json.js';
11
10
  import { DEFAULT_EXPORTS_EXCLUDER } from './config.js';
12
- import { SVELTEKIT_CONFIG_FILENAME } from './paths.js';
13
- export const has_sveltekit_app = () => exists(SVELTEKIT_CONFIG_FILENAME);
11
+ import { sveltekit_config_global } from './sveltekit_config_global.js';
14
12
  export const gro_plugin_sveltekit_app = ({ host_target = 'github_pages', well_known_package_json, well_known_src_json, well_known_src_files, } = {}) => {
15
13
  let sveltekit_process = null;
16
14
  return {
@@ -57,7 +55,7 @@ export const gro_plugin_sveltekit_app = ({ host_target = 'github_pages', well_kn
57
55
  // maybe a Vite middleware is best? what if this plugin added its plugin to your `vite.config.ts`?
58
56
  // copy files to `static` before building, in such a way
59
57
  // that's non-destructive to existing files and dirs and easy to clean up
60
- const { assets_path } = await init_sveltekit_config(); // TODO probably put in plugin context
58
+ const { assets_path } = sveltekit_config_global;
61
59
  const cleanups = [
62
60
  serialized_package_json
63
61
  ? await create_temporarily(join(assets_path, '.well-known/package.json'), serialized_package_json)
@@ -1,4 +1,2 @@
1
1
  import type { Plugin, Plugin_Context } from './plugin.js';
2
- import { Package_Json } from './package_json.js';
3
- export declare const has_sveltekit_library: (package_json?: Package_Json) => Promise<boolean>;
4
2
  export declare const gro_plugin_sveltekit_library: () => Plugin<Plugin_Context>;
@@ -1,14 +1,8 @@
1
1
  import { print_spawn_result, spawn } from '@ryanatkn/belt/process.js';
2
2
  import { Task_Error } from './task.js';
3
- import { Package_Json, load_package_json } from './package_json.js';
3
+ import { load_package_json } from './package_json.js';
4
4
  import { print_command_args, serialize_args, to_forwarded_args } from './args.js';
5
5
  import { find_cli, spawn_cli } from './cli.js';
6
- export const has_sveltekit_library = async (package_json) => {
7
- const p = package_json ?? (await load_package_json()); // TODO from param, on config?
8
- return !!p.devDependencies?.['@sveltejs/package'] || !!p.dependencies?.['@sveltejs/package'];
9
- // TODO @multiple get from the sveltekit config
10
- // && exists(sveltekit_config.lib_path);
11
- };
12
6
  export const gro_plugin_sveltekit_library = () => {
13
7
  return {
14
8
  name: 'gro_plugin_sveltekit_library',
@@ -1,48 +1,47 @@
1
+ import { z } from 'zod';
2
+ import type { Flavored } from '@ryanatkn/belt/types.js';
3
+ import { Source_Id } from './paths.js';
1
4
  import { type Path_Data } from './path.js';
5
+ export declare const Input_Path: z.ZodString;
6
+ export type Input_Path = Flavored<z.infer<typeof Input_Path>, 'Input_Path'>;
7
+ export declare const Raw_Input_Path: z.ZodString;
8
+ export type Raw_Input_Path = Flavored<z.infer<typeof Raw_Input_Path>, 'Raw_Input_Path'>;
2
9
  /**
3
- * Raw input paths are paths that users provide to Gro to reference files
4
- * enhanced with Gro's conventions like `.test.`, `.task.`, and `.gen.`.
10
+ * Raw input paths are paths that users provide to Gro to reference files for tasks and gen.
5
11
  *
6
- * A raw input path can be:
12
+ * A raw input path can be to a file or directory in the following forms:
7
13
  *
8
- * - a relative path to a file, e.g. `src/foo/bar.test.ts`
9
- * - a file without an extension, e.g. `src/foo/bar` if `extensions` is `.test.ts`
10
- * - a directory containing any number of files, e.g. `src/foo`
11
- * - any of the above without the leading `src/` or with a leading `./`
12
- * - any of the above but leading with `gro/` to ignore the local directory
13
- * - an absolute path to a file or directory in the current directory or Gro's
14
+ * - an absolute path, preserved
15
+ * - an explicit relative path, e.g. `./src/foo`, resolved to `root_path` which defaults to the cwd
16
+ * - an implicit relative path, e.g. `src/foo`, preserved
17
+ * - an implicit relative path prefixed with `gro/`, transformed to absolute in the Gro directory
14
18
  *
15
- * The input path API lets the caller customize the allowable extensions.
16
- * That means that the caller can look for `.test.` files but not `.gen.`,
17
- * or both, or neither, depending on its needs.
18
- *
19
- * In the future we may want to support globbing or regexps.
19
+ * Thus, input paths are either absolute or implicitly relative.
20
20
  */
21
- export declare const resolve_input_path: (raw_input_path: string) => string;
22
- export declare const resolve_input_paths: (raw_input_paths?: string[]) => string[];
21
+ export declare const to_input_path: (raw_input_path: Flavored<string, "Raw_Input_Path">, root_path?: string) => Flavored<string, "Input_Path">;
22
+ export declare const to_input_paths: (raw_input_paths: Raw_Input_Path[], root_path?: string) => Input_Path[];
23
23
  /**
24
24
  * Gets a list of possible source ids for each input path with `extensions`,
25
25
  * duplicating each under `root_dirs`.
26
26
  * This is first used to fall back to the Gro dir to search for tasks.
27
27
  * It's the helper used in implementations of `get_possible_source_ids_for_input_path` below.
28
28
  */
29
- export declare const get_possible_source_ids: (input_path: string, extensions: string[], root_dirs?: string[]) => string[];
29
+ export declare const get_possible_source_ids: (input_path: Flavored<string, "Input_Path">, extensions: string[], root_dirs: string[]) => Source_Id[];
30
30
  /**
31
- * Gets the path data for each input path,
32
- * searching for the possibilities based on `extensions`
33
- * and stopping at the first match.
34
- * Parameterized by `exists` and `stat` so it's fs-agnostic.
31
+ * Gets the path data for each input path, checking the filesystem for the possibilities
32
+ * and stopping at the first existing file or falling back to the first existing directory.
33
+ * If none is found for an input path, it's added to `unmapped_input_paths`.
35
34
  */
36
- export declare const load_source_path_data_by_input_path: (input_paths: string[], get_possible_source_ids_for_input_path?: (input_path: string) => string[]) => Promise<{
37
- source_id_path_data_by_input_path: Map<string, Path_Data>;
38
- unmapped_input_paths: string[];
35
+ export declare const load_source_path_data_by_input_path: (input_paths: Input_Path[], get_possible_source_ids_for_input_path?: (input_path: Input_Path) => Source_Id[]) => Promise<{
36
+ source_id_path_data_by_input_path: Map<Input_Path, Path_Data>;
37
+ unmapped_input_paths: Input_Path[];
39
38
  }>;
40
39
  /**
41
40
  * Finds all of the matching files for the given input paths.
42
- * Parameterized by `find_files` so it's fs-agnostic.
43
41
  * De-dupes source ids.
44
42
  */
45
- export declare const load_source_ids_by_input_path: (source_id_path_data_by_input_path: Map<string, Path_Data>, custom_search_fs?: (dir: string, options?: import("./search_fs.js").Search_Fs_Options) => Promise<Map<string, import("./path.js").Path_Stats>>) => Promise<{
46
- source_ids_by_input_path: Map<string, string[]>;
47
- input_directories_with_no_files: string[];
43
+ export declare const load_source_ids_by_input_path: (source_id_path_data_by_input_path: Map<Input_Path, Path_Data>, custom_search_fs?: (dir: string, options?: import("./search_fs.js").Search_Fs_Options) => Promise<Map<string, import("./path.js").Path_Stats>>) => Promise<{
44
+ source_ids_by_input_path: Map<Input_Path, Source_Id[]>;
45
+ input_directories_with_no_files: Input_Path[];
48
46
  }>;
47
+ export declare const to_gro_input_path: (input_path: Flavored<string, "Input_Path">) => Flavored<string, "Input_Path">;
@@ -1,48 +1,37 @@
1
- import { join, isAbsolute, basename } from 'node:path';
2
- import { strip_end, strip_start } from '@ryanatkn/belt/string.js';
1
+ import { isAbsolute, join, resolve } from 'node:path';
2
+ import { strip_start } from '@ryanatkn/belt/string.js';
3
3
  import { stat } from 'node:fs/promises';
4
- import { lib_path_to_import_id, replace_root_dir, gro_dir_basename, gro_paths, LIB_DIR, LIB_PATH, is_this_project_gro, gro_sveltekit_dist_dir, paths, } from './paths.js';
4
+ import { z } from 'zod';
5
+ import { GRO_PACKAGE_DIR, GRO_DIST_DIR, paths, Source_Id } from './paths.js';
5
6
  import { to_path_data } from './path.js';
6
7
  import { exists } from './fs.js';
7
8
  import { search_fs } from './search_fs.js';
9
+ import { TASK_FILE_SUFFIX_JS } from './task.js';
10
+ // TODO Flavored doesn't work when used in schemas, use Zod brand instead? problem is ergonomics
11
+ export const Input_Path = z.string();
12
+ export const Raw_Input_Path = z.string();
8
13
  /**
9
- * Raw input paths are paths that users provide to Gro to reference files
10
- * enhanced with Gro's conventions like `.test.`, `.task.`, and `.gen.`.
14
+ * Raw input paths are paths that users provide to Gro to reference files for tasks and gen.
11
15
  *
12
- * A raw input path can be:
16
+ * A raw input path can be to a file or directory in the following forms:
13
17
  *
14
- * - a relative path to a file, e.g. `src/foo/bar.test.ts`
15
- * - a file without an extension, e.g. `src/foo/bar` if `extensions` is `.test.ts`
16
- * - a directory containing any number of files, e.g. `src/foo`
17
- * - any of the above without the leading `src/` or with a leading `./`
18
- * - any of the above but leading with `gro/` to ignore the local directory
19
- * - an absolute path to a file or directory in the current directory or Gro's
18
+ * - an absolute path, preserved
19
+ * - an explicit relative path, e.g. `./src/foo`, resolved to `root_path` which defaults to the cwd
20
+ * - an implicit relative path, e.g. `src/foo`, preserved
21
+ * - an implicit relative path prefixed with `gro/`, transformed to absolute in the Gro directory
20
22
  *
21
- * The input path API lets the caller customize the allowable extensions.
22
- * That means that the caller can look for `.test.` files but not `.gen.`,
23
- * or both, or neither, depending on its needs.
24
- *
25
- * In the future we may want to support globbing or regexps.
23
+ * Thus, input paths are either absolute or implicitly relative.
26
24
  */
27
- export const resolve_input_path = (raw_input_path) => {
28
- if (isAbsolute(raw_input_path))
29
- return strip_end(raw_input_path, '/');
30
- // Allow prefix `./` and just remove it if it's there.
31
- let base_path = strip_end(strip_start(raw_input_path, './'), '/');
32
- let paths;
33
- // If it's prefixed with `gro/` or exactly `gro`, use the Gro paths.
34
- if (is_this_project_gro || (base_path + '/').startsWith(gro_dir_basename)) {
35
- paths = gro_paths;
36
- base_path = strip_end(strip_start(base_path + '/', gro_dir_basename), '/');
25
+ export const to_input_path = (raw_input_path, root_path = process.cwd()) => {
26
+ if (raw_input_path.startsWith(GRO_PACKAGE_DIR)) {
27
+ return GRO_DIST_DIR + strip_start(raw_input_path, GRO_PACKAGE_DIR);
28
+ }
29
+ else if (raw_input_path[0] === '.') {
30
+ return resolve(root_path, raw_input_path);
37
31
  }
38
- // Handle `src/lib` by itself without conflicting with `src/libFoo` names.
39
- if (base_path === LIB_PATH)
40
- base_path = ''; // TODO @multiple get from the sveltekit config
41
- // Allow prefix `src/lib/` and just remove it if it's there.
42
- base_path = strip_start(base_path, LIB_DIR);
43
- return lib_path_to_import_id(base_path, paths);
32
+ return raw_input_path;
44
33
  };
45
- export const resolve_input_paths = (raw_input_paths) => raw_input_paths?.length ? raw_input_paths.map((p) => resolve_input_path(p)) : [paths.source];
34
+ export const to_input_paths = (raw_input_paths, root_path) => raw_input_paths.map((p) => to_input_path(p, root_path));
46
35
  /**
47
36
  * Gets a list of possible source ids for each input path with `extensions`,
48
37
  * duplicating each under `root_dirs`.
@@ -50,39 +39,37 @@ export const resolve_input_paths = (raw_input_paths) => raw_input_paths?.length
50
39
  * It's the helper used in implementations of `get_possible_source_ids_for_input_path` below.
51
40
  */
52
41
  export const get_possible_source_ids = (input_path, extensions, root_dirs) => {
53
- const possible_source_ids = [input_path];
54
- if (!input_path.endsWith('/')) {
55
- for (const extension of extensions) {
56
- if (!input_path.endsWith(extension)) {
57
- possible_source_ids.push(input_path + extension);
58
- // Support task directories, so `src/lib/a/a.task.ts` works like `src/a.task.ts`.
59
- possible_source_ids.push(join(input_path, basename(input_path) + extension));
42
+ const possible_source_ids = [];
43
+ const add_possible_source_ids = (path) => {
44
+ // Specifically for paths to the Gro package dist, optimize by only looking for `.task.js`.
45
+ if (path.startsWith(GRO_DIST_DIR)) {
46
+ possible_source_ids.push((path.endsWith('/') || path.endsWith(TASK_FILE_SUFFIX_JS)
47
+ ? path
48
+ : path + TASK_FILE_SUFFIX_JS));
49
+ }
50
+ else {
51
+ possible_source_ids.push(path);
52
+ if (!path.endsWith('/') && !extensions.some((e) => path.endsWith(e))) {
53
+ for (const extension of extensions) {
54
+ possible_source_ids.push(path + extension);
55
+ }
60
56
  }
61
57
  }
58
+ };
59
+ if (isAbsolute(input_path)) {
60
+ add_possible_source_ids(input_path);
62
61
  }
63
- if (root_dirs?.length) {
64
- const ids = possible_source_ids.slice(); // make a copy or infinitely loop!
62
+ else {
65
63
  for (const root_dir of root_dirs) {
66
- if (input_path.startsWith(root_dir))
67
- continue; // avoid duplicates
68
- const is_gro_dist = root_dir === gro_sveltekit_dist_dir; // TODO hacky to handle Gro importing its JS tasks from dist/
69
- for (const possible_source_id of ids) {
70
- if (is_gro_dist && !possible_source_id.endsWith('.js'))
71
- continue;
72
- // TODO hacky to handle Gro importing its JS tasks from dist/
73
- possible_source_ids.push(is_gro_dist
74
- ? gro_sveltekit_dist_dir + strip_start(possible_source_id, paths.lib)
75
- : replace_root_dir(possible_source_id, root_dir, paths));
76
- }
64
+ add_possible_source_ids(join(root_dir, input_path));
77
65
  }
78
66
  }
79
67
  return possible_source_ids;
80
68
  };
81
69
  /**
82
- * Gets the path data for each input path,
83
- * searching for the possibilities based on `extensions`
84
- * and stopping at the first match.
85
- * Parameterized by `exists` and `stat` so it's fs-agnostic.
70
+ * Gets the path data for each input path, checking the filesystem for the possibilities
71
+ * and stopping at the first existing file or falling back to the first existing directory.
72
+ * If none is found for an input path, it's added to `unmapped_input_paths`.
86
73
  */
87
74
  export const load_source_path_data_by_input_path = async (input_paths, get_possible_source_ids_for_input_path) => {
88
75
  const source_id_path_data_by_input_path = new Map();
@@ -93,22 +80,24 @@ export const load_source_path_data_by_input_path = async (input_paths, get_possi
93
80
  const possible_source_ids = get_possible_source_ids_for_input_path
94
81
  ? get_possible_source_ids_for_input_path(input_path)
95
82
  : [input_path];
83
+ // Find the first existing file path or fallback to the first directory path.
96
84
  for (const possible_source_id of possible_source_ids) {
97
85
  if (!(await exists(possible_source_id)))
98
86
  continue; // eslint-disable-line no-await-in-loop
99
87
  const stats = await stat(possible_source_id); // eslint-disable-line no-await-in-loop
100
88
  if (stats.isDirectory()) {
101
- if (!dir_path_data) {
102
- dir_path_data = to_path_data(possible_source_id, stats);
103
- }
89
+ if (dir_path_data)
90
+ continue;
91
+ dir_path_data = to_path_data(possible_source_id, stats);
104
92
  }
105
93
  else {
106
94
  file_path_data = to_path_data(possible_source_id, stats);
107
95
  break;
108
96
  }
109
97
  }
110
- if (file_path_data || dir_path_data) {
111
- source_id_path_data_by_input_path.set(input_path, file_path_data || dir_path_data); // the ! is needed because TypeScript inference fails
98
+ const path_data = file_path_data || dir_path_data;
99
+ if (path_data) {
100
+ source_id_path_data_by_input_path.set(input_path, path_data);
112
101
  }
113
102
  else {
114
103
  unmapped_input_paths.push(input_path);
@@ -118,7 +107,6 @@ export const load_source_path_data_by_input_path = async (input_paths, get_possi
118
107
  };
119
108
  /**
120
109
  * Finds all of the matching files for the given input paths.
121
- * Parameterized by `find_files` so it's fs-agnostic.
122
110
  * De-dupes source ids.
123
111
  */
124
112
  export const load_source_ids_by_input_path = async (source_id_path_data_by_input_path, custom_search_fs = search_fs) => {
@@ -132,7 +120,9 @@ export const load_source_ids_by_input_path = async (source_id_path_data_by_input
132
120
  if (files.size) {
133
121
  const source_ids = [];
134
122
  let has_files = false;
135
- for (const path of files.keys()) {
123
+ for (const [path, stats] of files) {
124
+ if (stats.isDirectory())
125
+ continue;
136
126
  has_files = true;
137
127
  const source_id = join(id, path);
138
128
  if (!existing_source_ids.has(source_id)) {
@@ -146,7 +136,7 @@ export const load_source_ids_by_input_path = async (source_id_path_data_by_input
146
136
  if (!has_files) {
147
137
  input_directories_with_no_files.push(input_path);
148
138
  }
149
- // do callers ever need `inputDirectoriesWithDuplicateFiles`?
139
+ // do callers ever need `input_directories_with_duplicate_files`?
150
140
  }
151
141
  else {
152
142
  input_directories_with_no_files.push(input_path);
@@ -159,3 +149,9 @@ export const load_source_ids_by_input_path = async (source_id_path_data_by_input
159
149
  }
160
150
  return { source_ids_by_input_path, input_directories_with_no_files };
161
151
  };
152
+ // TODO I don't think this is valid any more, we shouldn't transform absolute paths like this,
153
+ // the searching should happen with the input paths
154
+ export const to_gro_input_path = (input_path) => {
155
+ const base_path = input_path === paths.lib.slice(0, -1) ? '' : strip_start(input_path, paths.lib);
156
+ return GRO_DIST_DIR + base_path;
157
+ };
@@ -1,68 +1,47 @@
1
- import { suite } from 'uvu';
1
+ import { test } from 'uvu';
2
2
  import * as assert from 'uvu/assert';
3
3
  import { resolve } from 'node:path';
4
- import { resolve_input_path, resolve_input_paths, load_source_ids_by_input_path, get_possible_source_ids, } from './input_path.js';
5
- import { paths } from './paths.js';
6
- /* test__resolve_input_path */
7
- const test__resolve_input_path = suite('resolve_input_path');
8
- test__resolve_input_path('basic behavior', () => {
9
- const target = resolve('dist/foo/bar.ts');
10
- assert.is(resolve_input_path('foo/bar.ts'), target);
11
- assert.is(resolve_input_path('src/lib/foo/bar.ts'), target);
12
- assert.is(resolve_input_path('./src/lib/foo/bar.ts'), target);
13
- assert.is(resolve_input_path('./foo/bar.ts'), target); // questionable
14
- assert.is(resolve_input_path(target), target);
15
- assert.is.not(resolve_input_path('bar.ts'), target);
4
+ import { to_input_path, to_input_paths, load_source_ids_by_input_path, get_possible_source_ids, } from './input_path.js';
5
+ import { GRO_DIST_DIR, paths } from './paths.js';
6
+ test('to_input_path', () => {
7
+ assert.is(to_input_path(resolve('foo.ts')), resolve('foo.ts'));
8
+ assert.is(to_input_path('./foo.ts'), resolve('foo.ts'));
9
+ assert.is(to_input_path('foo.ts'), 'foo.ts');
10
+ assert.is(to_input_path('gro/foo'), GRO_DIST_DIR + 'foo');
11
+ // trailing slashes are preserved:
12
+ assert.is(to_input_path(resolve('foo/bar/')), resolve('foo/bar/'));
13
+ assert.is(to_input_path('./foo/bar/'), resolve('foo/bar/'));
14
+ assert.is(to_input_path('foo/bar/'), 'foo/bar/');
16
15
  });
17
- test__resolve_input_path('directories', () => {
18
- const target_dir = resolve('dist/foo/bar');
19
- assert.is(resolve_input_path('foo/bar'), target_dir);
20
- assert.is(resolve_input_path('foo/bar/'), target_dir);
21
- assert.is(resolve_input_path('./foo/bar'), target_dir);
22
- assert.is(resolve_input_path('./foo/bar/'), target_dir);
23
- assert.is.not(resolve_input_path('bar'), target_dir);
24
- });
25
- test__resolve_input_path.run();
26
- /* test__resolve_input_path */
27
- /* test__resolve_input_paths */
28
- const test__resolve_input_paths = suite('resolve_input_paths');
29
- test__resolve_input_paths('resolves multiple input path forms', () => {
30
- assert.equal(resolve_input_paths(['foo/bar.ts', 'baz', './']), [
31
- resolve('dist/foo/bar.ts'),
32
- resolve('dist/baz'),
33
- resolve('dist') + '/',
16
+ test('to_input_paths', () => {
17
+ assert.equal(to_input_paths([resolve('foo/bar.ts'), './baz', 'foo']), [
18
+ resolve('foo/bar.ts'),
19
+ resolve('baz'),
20
+ 'foo',
34
21
  ]);
35
22
  });
36
- test__resolve_input_paths.run();
37
- /* test__resolve_input_paths */
38
- /* test__get_possible_source_ids */
39
- const test__get_possible_source_ids = suite('get_possible_source_ids');
40
- test__get_possible_source_ids('in the gro directory', () => {
23
+ test('get_possible_source_ids in the gro directory', () => {
41
24
  const input_path = resolve('src/foo/bar');
42
- assert.equal(get_possible_source_ids(input_path, ['.baz.ts']), [
25
+ assert.equal(get_possible_source_ids(input_path, ['.baz.ts'], []), [
43
26
  input_path,
44
27
  input_path + '.baz.ts',
45
- input_path + '/bar.baz.ts',
46
28
  ]);
47
29
  });
48
- test__get_possible_source_ids('does not repeat the extension', () => {
30
+ test('get_possible_source_ids does not repeat the extension', () => {
49
31
  const input_path = resolve('src/foo/bar.baz.ts');
50
- assert.equal(get_possible_source_ids(input_path, ['.baz.ts']), [input_path]);
32
+ assert.equal(get_possible_source_ids(input_path, ['.baz.ts'], []), [input_path]);
51
33
  });
52
- test__get_possible_source_ids('does not repeat with the same root directory', () => {
34
+ test('get_possible_source_ids does not repeat with the same root directory', () => {
53
35
  const input_path = resolve('src/foo/bar.baz.ts');
54
36
  assert.equal(get_possible_source_ids(input_path, ['.baz.ts'], [paths.root, paths.root]), [
55
37
  input_path,
56
38
  ]);
57
39
  });
58
- test__get_possible_source_ids('implied to be a directory by trailing slash', () => {
40
+ test('get_possible_source_ids implied to be a directory by trailing slash', () => {
59
41
  const input_path = resolve('src/foo/bar') + '/';
60
- assert.equal(get_possible_source_ids(input_path, ['.baz.ts']), [input_path]);
42
+ assert.equal(get_possible_source_ids(input_path, ['.baz.ts'], []), [input_path]);
61
43
  });
62
- test__get_possible_source_ids.run();
63
- /* test__get_possible_source_ids */
64
- /* test__load_source_ids_by_input_path */
65
- const test__load_source_ids_by_input_path = suite('load_source_ids_by_input_path', async () => {
44
+ test('load_source_ids_by_input_path', async () => {
66
45
  const test_files = {
67
46
  'fake/test1.bar.ts': new Map([['fake/test1.bar.ts', { isDirectory: () => false }]]),
68
47
  'fake/test2.bar.ts': new Map([['fake/test2.bar.ts', { isDirectory: () => false }]]),
@@ -102,5 +81,4 @@ const test__load_source_ids_by_input_path = suite('load_source_ids_by_input_path
102
81
  input_directories_with_no_files: ['fake/nomatches'],
103
82
  });
104
83
  });
105
- test__load_source_ids_by_input_path.run();
106
- /* test__load_source_ids_by_input_path */
84
+ test.run();
@@ -17,4 +17,4 @@ import type { Gro_Config } from './config.js';
17
17
  * there are some subtle differences in the complex logical branches.
18
18
  * The comments describe each condition.
19
19
  */
20
- export declare const invoke_task: (task_name: string, args: Args, config: Gro_Config, timings?: any) => Promise<void>;
20
+ export declare const invoke_task: (task_name: Flavored<string, "Raw_Input_Path">, args: Args, config: Gro_Config, timings?: any) => Promise<void>;