@ryanatkn/gro 0.112.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/LICENSE +21 -0
- package/README.md +257 -0
- package/dist/args.d.ts +59 -0
- package/dist/args.js +132 -0
- package/dist/args.test.d.ts +1 -0
- package/dist/args.test.js +43 -0
- package/dist/build.task.d.ts +11 -0
- package/dist/build.task.js +24 -0
- package/dist/changelog.d.ts +8 -0
- package/dist/changelog.js +47 -0
- package/dist/changelog.test.d.ts +1 -0
- package/dist/changelog.test.js +118 -0
- package/dist/changeset.task.d.ts +49 -0
- package/dist/changeset.task.js +141 -0
- package/dist/check.task.d.ts +47 -0
- package/dist/check.task.js +77 -0
- package/dist/clean.task.d.ts +26 -0
- package/dist/clean.task.js +41 -0
- package/dist/clean_fs.d.ts +9 -0
- package/dist/clean_fs.js +27 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.js +25 -0
- package/dist/commit.task.d.ts +11 -0
- package/dist/commit.task.js +22 -0
- package/dist/config.d.ts +21 -0
- package/dist/config.js +42 -0
- package/dist/config.test.d.ts +1 -0
- package/dist/config.test.js +8 -0
- package/dist/deploy.task.d.ts +47 -0
- package/dist/deploy.task.js +198 -0
- package/dist/dev.task.d.ts +22 -0
- package/dist/dev.task.js +32 -0
- package/dist/docs/README.gen.md.d.ts +5 -0
- package/dist/docs/README.gen.md.js +53 -0
- package/dist/docs/README.md +20 -0
- package/dist/docs/build.md +41 -0
- package/dist/docs/config.md +162 -0
- package/dist/docs/deploy.md +32 -0
- package/dist/docs/dev.md +40 -0
- package/dist/docs/gen.md +241 -0
- package/dist/docs/gro_plugin_sveltekit_frontend.md +97 -0
- package/dist/docs/package_json.md +29 -0
- package/dist/docs/plugin.md +50 -0
- package/dist/docs/publish.md +144 -0
- package/dist/docs/task.md +377 -0
- package/dist/docs/tasks.gen.md.d.ts +2 -0
- package/dist/docs/tasks.gen.md.js +60 -0
- package/dist/docs/tasks.md +35 -0
- package/dist/docs/test.md +52 -0
- package/dist/env.d.ts +10 -0
- package/dist/env.js +47 -0
- package/dist/esbuild_helpers.d.ts +14 -0
- package/dist/esbuild_helpers.js +36 -0
- package/dist/esbuild_plugin_external_worker.d.ts +22 -0
- package/dist/esbuild_plugin_external_worker.js +49 -0
- package/dist/esbuild_plugin_svelte.d.ts +9 -0
- package/dist/esbuild_plugin_svelte.js +49 -0
- package/dist/esbuild_plugin_sveltekit_local_imports.d.ts +7 -0
- package/dist/esbuild_plugin_sveltekit_local_imports.js +30 -0
- package/dist/esbuild_plugin_sveltekit_shim_alias.d.ts +6 -0
- package/dist/esbuild_plugin_sveltekit_shim_alias.js +16 -0
- package/dist/esbuild_plugin_sveltekit_shim_app.d.ts +8 -0
- package/dist/esbuild_plugin_sveltekit_shim_app.js +23 -0
- package/dist/esbuild_plugin_sveltekit_shim_env.d.ts +10 -0
- package/dist/esbuild_plugin_sveltekit_shim_env.js +18 -0
- package/dist/format.task.d.ts +11 -0
- package/dist/format.task.js +24 -0
- package/dist/format_directory.d.ts +2 -0
- package/dist/format_directory.js +27 -0
- package/dist/format_file.d.ts +8 -0
- package/dist/format_file.js +42 -0
- package/dist/format_file.test.d.ts +1 -0
- package/dist/format_file.test.js +16 -0
- package/dist/fs.d.ts +7 -0
- package/dist/fs.js +19 -0
- package/dist/fs.test.d.ts +1 -0
- package/dist/fs.test.js +16 -0
- package/dist/gen.d.ts +57 -0
- package/dist/gen.js +81 -0
- package/dist/gen.task.d.ts +14 -0
- package/dist/gen.task.js +103 -0
- package/dist/gen.test.d.ts +1 -0
- package/dist/gen.test.js +239 -0
- package/dist/gen_module.d.ts +46 -0
- package/dist/gen_module.js +54 -0
- package/dist/gen_module.test.d.ts +1 -0
- package/dist/gen_module.test.js +30 -0
- package/dist/git.d.ts +76 -0
- package/dist/git.js +200 -0
- package/dist/git.test.d.ts +1 -0
- package/dist/git.test.js +18 -0
- package/dist/github.d.ts +35 -0
- package/dist/github.js +32 -0
- package/dist/gro.config.default.d.ts +12 -0
- package/dist/gro.config.default.js +31 -0
- package/dist/gro.d.ts +2 -0
- package/dist/gro.js +19 -0
- package/dist/gro_helpers.d.ts +43 -0
- package/dist/gro_helpers.js +79 -0
- package/dist/gro_plugin_gen.d.ts +6 -0
- package/dist/gro_plugin_gen.js +80 -0
- package/dist/gro_plugin_server.d.ts +77 -0
- package/dist/gro_plugin_server.js +152 -0
- package/dist/gro_plugin_sveltekit_app.d.ts +27 -0
- package/dist/gro_plugin_sveltekit_app.js +180 -0
- package/dist/gro_plugin_sveltekit_library.d.ts +4 -0
- package/dist/gro_plugin_sveltekit_library.js +42 -0
- package/dist/hash.d.ts +5 -0
- package/dist/hash.js +14 -0
- package/dist/hash.test.d.ts +1 -0
- package/dist/hash.test.js +25 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/input_path.d.ts +48 -0
- package/dist/input_path.js +161 -0
- package/dist/input_path.test.d.ts +1 -0
- package/dist/input_path.test.js +106 -0
- package/dist/invoke.d.ts +1 -0
- package/dist/invoke.js +18 -0
- package/dist/invoke_task.d.ts +20 -0
- package/dist/invoke_task.js +140 -0
- package/dist/lint.task.d.ts +11 -0
- package/dist/lint.task.js +29 -0
- package/dist/loader.d.ts +4 -0
- package/dist/loader.js +153 -0
- package/dist/module.d.ts +3 -0
- package/dist/module.js +6 -0
- package/dist/module.test.d.ts +1 -0
- package/dist/module.test.js +41 -0
- package/dist/modules.d.ts +60 -0
- package/dist/modules.js +103 -0
- package/dist/modules.test.d.ts +1 -0
- package/dist/modules.test.js +182 -0
- package/dist/package.d.ts +939 -0
- package/dist/package.gen.d.ts +7 -0
- package/dist/package.gen.js +26 -0
- package/dist/package.js +887 -0
- package/dist/package_json.d.ts +342 -0
- package/dist/package_json.js +212 -0
- package/dist/package_json.test.d.ts +1 -0
- package/dist/package_json.test.js +77 -0
- package/dist/path.d.ts +12 -0
- package/dist/path.js +8 -0
- package/dist/paths.d.ts +60 -0
- package/dist/paths.js +128 -0
- package/dist/paths.test.d.ts +1 -0
- package/dist/paths.test.js +49 -0
- package/dist/plugin.d.ts +36 -0
- package/dist/plugin.js +80 -0
- package/dist/plugin.test.d.ts +1 -0
- package/dist/plugin.test.js +54 -0
- package/dist/print_task.d.ts +4 -0
- package/dist/print_task.js +124 -0
- package/dist/publish.task.d.ts +32 -0
- package/dist/publish.task.js +125 -0
- package/dist/release.task.d.ts +5 -0
- package/dist/release.task.js +18 -0
- package/dist/resolve_node_specifier.d.ts +8 -0
- package/dist/resolve_node_specifier.js +39 -0
- package/dist/resolve_node_specifier.test.d.ts +1 -0
- package/dist/resolve_node_specifier.test.js +21 -0
- package/dist/resolve_specifier.d.ts +15 -0
- package/dist/resolve_specifier.js +51 -0
- package/dist/resolve_specifier.test.d.ts +1 -0
- package/dist/resolve_specifier.test.js +66 -0
- package/dist/run.task.d.ts +11 -0
- package/dist/run.task.js +31 -0
- package/dist/run_gen.d.ts +6 -0
- package/dist/run_gen.js +74 -0
- package/dist/run_gen.test.d.ts +1 -0
- package/dist/run_gen.test.js +182 -0
- package/dist/run_task.d.ts +13 -0
- package/dist/run_task.js +44 -0
- package/dist/run_task.test.d.ts +1 -0
- package/dist/run_task.test.js +63 -0
- package/dist/search_fs.d.ts +11 -0
- package/dist/search_fs.js +22 -0
- package/dist/search_fs.test.d.ts +1 -0
- package/dist/search_fs.test.js +46 -0
- package/dist/src_json.d.ts +256 -0
- package/dist/src_json.js +110 -0
- package/dist/src_json.test.d.ts +1 -0
- package/dist/src_json.test.js +52 -0
- package/dist/sveltekit_config.d.ts +36 -0
- package/dist/sveltekit_config.js +51 -0
- package/dist/sveltekit_shim_app.d.ts +10 -0
- package/dist/sveltekit_shim_app.js +31 -0
- package/dist/sveltekit_shim_app_environment.d.ts +10 -0
- package/dist/sveltekit_shim_app_environment.js +12 -0
- package/dist/sveltekit_shim_app_forms.d.ts +5 -0
- package/dist/sveltekit_shim_app_forms.js +13 -0
- package/dist/sveltekit_shim_app_navigation.d.ts +10 -0
- package/dist/sveltekit_shim_app_navigation.js +11 -0
- package/dist/sveltekit_shim_app_paths.d.ts +11 -0
- package/dist/sveltekit_shim_app_paths.js +6 -0
- package/dist/sveltekit_shim_app_stores.d.ts +6 -0
- package/dist/sveltekit_shim_app_stores.js +17 -0
- package/dist/sveltekit_shim_env.d.ts +4 -0
- package/dist/sveltekit_shim_env.js +23 -0
- package/dist/sync.task.d.ts +30 -0
- package/dist/sync.task.js +45 -0
- package/dist/task.d.ts +29 -0
- package/dist/task.js +17 -0
- package/dist/task.test.d.ts +1 -0
- package/dist/task.test.js +22 -0
- package/dist/task_module.d.ts +14 -0
- package/dist/task_module.js +19 -0
- package/dist/task_module.test.d.ts +1 -0
- package/dist/task_module.test.js +70 -0
- package/dist/test.task.d.ts +20 -0
- package/dist/test.task.js +43 -0
- package/dist/throttle.d.ts +16 -0
- package/dist/throttle.js +59 -0
- package/dist/throttle.test.d.ts +1 -0
- package/dist/throttle.test.js +49 -0
- package/dist/typecheck.task.d.ts +5 -0
- package/dist/typecheck.task.js +38 -0
- package/dist/upgrade.task.d.ts +14 -0
- package/dist/upgrade.task.js +37 -0
- package/dist/watch_dir.d.ts +30 -0
- package/dist/watch_dir.js +59 -0
- package/package.json +422 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { join, isAbsolute, basename } from 'node:path';
|
|
2
|
+
import { strip_end, strip_start } from '@ryanatkn/belt/string.js';
|
|
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';
|
|
5
|
+
import { to_path_data } from './path.js';
|
|
6
|
+
import { exists } from './fs.js';
|
|
7
|
+
import { search_fs } from './search_fs.js';
|
|
8
|
+
/**
|
|
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.`.
|
|
11
|
+
*
|
|
12
|
+
* A raw input path can be:
|
|
13
|
+
*
|
|
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
|
|
20
|
+
*
|
|
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.
|
|
26
|
+
*/
|
|
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), '/');
|
|
37
|
+
}
|
|
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);
|
|
44
|
+
};
|
|
45
|
+
export const resolve_input_paths = (raw_input_paths) => raw_input_paths?.length ? raw_input_paths.map((p) => resolve_input_path(p)) : [paths.source];
|
|
46
|
+
/**
|
|
47
|
+
* Gets a list of possible source ids for each input path with `extensions`,
|
|
48
|
+
* duplicating each under `root_dirs`.
|
|
49
|
+
* This is first used to fall back to the Gro dir to search for tasks.
|
|
50
|
+
* It's the helper used in implementations of `get_possible_source_ids_for_input_path` below.
|
|
51
|
+
*/
|
|
52
|
+
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));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (root_dirs?.length) {
|
|
64
|
+
const ids = possible_source_ids.slice(); // make a copy or infinitely loop!
|
|
65
|
+
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
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return possible_source_ids;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
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.
|
|
86
|
+
*/
|
|
87
|
+
export const load_source_path_data_by_input_path = async (input_paths, get_possible_source_ids_for_input_path) => {
|
|
88
|
+
const source_id_path_data_by_input_path = new Map();
|
|
89
|
+
const unmapped_input_paths = [];
|
|
90
|
+
for (const input_path of input_paths) {
|
|
91
|
+
let file_path_data = null;
|
|
92
|
+
let dir_path_data = null;
|
|
93
|
+
const possible_source_ids = get_possible_source_ids_for_input_path
|
|
94
|
+
? get_possible_source_ids_for_input_path(input_path)
|
|
95
|
+
: [input_path];
|
|
96
|
+
for (const possible_source_id of possible_source_ids) {
|
|
97
|
+
if (!(await exists(possible_source_id)))
|
|
98
|
+
continue; // eslint-disable-line no-await-in-loop
|
|
99
|
+
const stats = await stat(possible_source_id); // eslint-disable-line no-await-in-loop
|
|
100
|
+
if (stats.isDirectory()) {
|
|
101
|
+
if (!dir_path_data) {
|
|
102
|
+
dir_path_data = to_path_data(possible_source_id, stats);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
file_path_data = to_path_data(possible_source_id, stats);
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
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
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
unmapped_input_paths.push(input_path);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return { source_id_path_data_by_input_path, unmapped_input_paths };
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Finds all of the matching files for the given input paths.
|
|
121
|
+
* Parameterized by `find_files` so it's fs-agnostic.
|
|
122
|
+
* De-dupes source ids.
|
|
123
|
+
*/
|
|
124
|
+
export const load_source_ids_by_input_path = async (source_id_path_data_by_input_path, custom_search_fs = search_fs) => {
|
|
125
|
+
const source_ids_by_input_path = new Map();
|
|
126
|
+
const input_directories_with_no_files = [];
|
|
127
|
+
const existing_source_ids = new Set();
|
|
128
|
+
for (const [input_path, path_data] of source_id_path_data_by_input_path) {
|
|
129
|
+
const { id } = path_data;
|
|
130
|
+
if (path_data.isDirectory) {
|
|
131
|
+
const files = await custom_search_fs(id, { files_only: false }); // eslint-disable-line no-await-in-loop
|
|
132
|
+
if (files.size) {
|
|
133
|
+
const source_ids = [];
|
|
134
|
+
let has_files = false;
|
|
135
|
+
for (const path of files.keys()) {
|
|
136
|
+
has_files = true;
|
|
137
|
+
const source_id = join(id, path);
|
|
138
|
+
if (!existing_source_ids.has(source_id)) {
|
|
139
|
+
existing_source_ids.add(source_id);
|
|
140
|
+
source_ids.push(source_id);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (source_ids.length) {
|
|
144
|
+
source_ids_by_input_path.set(input_path, source_ids);
|
|
145
|
+
}
|
|
146
|
+
if (!has_files) {
|
|
147
|
+
input_directories_with_no_files.push(input_path);
|
|
148
|
+
}
|
|
149
|
+
// do callers ever need `inputDirectoriesWithDuplicateFiles`?
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
input_directories_with_no_files.push(input_path);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else if (!existing_source_ids.has(id)) {
|
|
156
|
+
existing_source_ids.add(id);
|
|
157
|
+
source_ids_by_input_path.set(input_path, [id]);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return { source_ids_by_input_path, input_directories_with_no_files };
|
|
161
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { suite } from 'uvu';
|
|
2
|
+
import * as assert from 'uvu/assert';
|
|
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);
|
|
16
|
+
});
|
|
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') + '/',
|
|
34
|
+
]);
|
|
35
|
+
});
|
|
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', () => {
|
|
41
|
+
const input_path = resolve('src/foo/bar');
|
|
42
|
+
assert.equal(get_possible_source_ids(input_path, ['.baz.ts']), [
|
|
43
|
+
input_path,
|
|
44
|
+
input_path + '.baz.ts',
|
|
45
|
+
input_path + '/bar.baz.ts',
|
|
46
|
+
]);
|
|
47
|
+
});
|
|
48
|
+
test__get_possible_source_ids('does not repeat the extension', () => {
|
|
49
|
+
const input_path = resolve('src/foo/bar.baz.ts');
|
|
50
|
+
assert.equal(get_possible_source_ids(input_path, ['.baz.ts']), [input_path]);
|
|
51
|
+
});
|
|
52
|
+
test__get_possible_source_ids('does not repeat with the same root directory', () => {
|
|
53
|
+
const input_path = resolve('src/foo/bar.baz.ts');
|
|
54
|
+
assert.equal(get_possible_source_ids(input_path, ['.baz.ts'], [paths.root, paths.root]), [
|
|
55
|
+
input_path,
|
|
56
|
+
]);
|
|
57
|
+
});
|
|
58
|
+
test__get_possible_source_ids('implied to be a directory by trailing slash', () => {
|
|
59
|
+
const input_path = resolve('src/foo/bar') + '/';
|
|
60
|
+
assert.equal(get_possible_source_ids(input_path, ['.baz.ts']), [input_path]);
|
|
61
|
+
});
|
|
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 () => {
|
|
66
|
+
const test_files = {
|
|
67
|
+
'fake/test1.bar.ts': new Map([['fake/test1.bar.ts', { isDirectory: () => false }]]),
|
|
68
|
+
'fake/test2.bar.ts': new Map([['fake/test2.bar.ts', { isDirectory: () => false }]]),
|
|
69
|
+
'fake/test3': new Map([
|
|
70
|
+
['fake/test3', { isDirectory: () => true }],
|
|
71
|
+
['a.ts', { isDirectory: () => false }],
|
|
72
|
+
['b.ts', { isDirectory: () => false }],
|
|
73
|
+
]),
|
|
74
|
+
// duplicate
|
|
75
|
+
'fake/': new Map([
|
|
76
|
+
['fake/test3', { isDirectory: () => true }],
|
|
77
|
+
['test3/a.ts', { isDirectory: () => false }],
|
|
78
|
+
]),
|
|
79
|
+
// duplicate and not
|
|
80
|
+
fake: new Map([
|
|
81
|
+
['fake/test3', { isDirectory: () => true }],
|
|
82
|
+
['test3/a.ts', { isDirectory: () => false }],
|
|
83
|
+
['test3/c.ts', { isDirectory: () => false }],
|
|
84
|
+
]),
|
|
85
|
+
'fake/nomatches': new Map([['fake/nomatches', { isDirectory: () => true }]]),
|
|
86
|
+
};
|
|
87
|
+
const result = await load_source_ids_by_input_path(new Map([
|
|
88
|
+
['fake/test1.bar.ts', { id: 'fake/test1.bar.ts', isDirectory: false }],
|
|
89
|
+
['fake/test2', { id: 'fake/test2.bar.ts', isDirectory: false }],
|
|
90
|
+
['fake/test3', { id: 'fake/test3', isDirectory: true }],
|
|
91
|
+
['fake/', { id: 'fake/', isDirectory: true }],
|
|
92
|
+
['fake', { id: 'fake', isDirectory: true }],
|
|
93
|
+
['fake/nomatches', { id: 'fake/nomatches', isDirectory: true }],
|
|
94
|
+
]), async (id) => test_files[id]);
|
|
95
|
+
assert.equal(result, {
|
|
96
|
+
source_ids_by_input_path: new Map([
|
|
97
|
+
['fake/test1.bar.ts', ['fake/test1.bar.ts']],
|
|
98
|
+
['fake/test2', ['fake/test2.bar.ts']],
|
|
99
|
+
['fake/test3', ['fake/test3/a.ts', 'fake/test3/b.ts']],
|
|
100
|
+
['fake', ['fake/test3/c.ts']],
|
|
101
|
+
]),
|
|
102
|
+
input_directories_with_no_files: ['fake/nomatches'],
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
test__load_source_ids_by_input_path.run();
|
|
106
|
+
/* test__load_source_ids_by_input_path */
|
package/dist/invoke.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/invoke.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { attach_process_error_handlers } from '@ryanatkn/belt/process.js';
|
|
2
|
+
import { invoke_task } from './invoke_task.js';
|
|
3
|
+
import { to_task_args } from './args.js';
|
|
4
|
+
import { load_config } from './config.js';
|
|
5
|
+
/*
|
|
6
|
+
|
|
7
|
+
This module invokes the Gro CLI which in turn invokes tasks.
|
|
8
|
+
Tasks are the CLI's primary concept.
|
|
9
|
+
To learn more about them, see `src/lib/docs/task.md`.
|
|
10
|
+
|
|
11
|
+
When the CLI is invoked it passes the first CLI arg as `task_name` to `invoke_task`,
|
|
12
|
+
and the rest of the args are forwarded to the task's `run` function.
|
|
13
|
+
|
|
14
|
+
*/
|
|
15
|
+
// handle uncaught errors
|
|
16
|
+
attach_process_error_handlers((err) => err?.constructor?.name === 'Task_Error' ? 'Task_Error' : null);
|
|
17
|
+
const { task_name, args } = to_task_args();
|
|
18
|
+
await invoke_task(task_name, args, await load_config());
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Args } from './args.js';
|
|
2
|
+
import type { Gro_Config } from './config.js';
|
|
3
|
+
/**
|
|
4
|
+
* Invokes Gro tasks by name using the filesystem as the source.
|
|
5
|
+
*
|
|
6
|
+
* When a task is invoked,
|
|
7
|
+
* Gro first searches for tasks in the current working directory.
|
|
8
|
+
* and falls back to searching Gro's directory, if the two are different.
|
|
9
|
+
* See `src/lib/input_path.ts` for info about what "task_name" can refer to.
|
|
10
|
+
* If it matches a directory, all of the tasks within it are logged,
|
|
11
|
+
* both in the current working directory and Gro.
|
|
12
|
+
*
|
|
13
|
+
* This code is particularly hairy because
|
|
14
|
+
* we're accepting a wide range of user input
|
|
15
|
+
* and trying to do the right thing.
|
|
16
|
+
* Precise error messages are especially difficult and
|
|
17
|
+
* there are some subtle differences in the complex logical branches.
|
|
18
|
+
* The comments describe each condition.
|
|
19
|
+
*/
|
|
20
|
+
export declare const invoke_task: (task_name: string, args: Args, config: Gro_Config, timings?: any) => Promise<void>;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { cyan, red, gray } from 'kleur/colors';
|
|
2
|
+
import { Logger, System_Logger, print_log_label } from '@ryanatkn/belt/log.js';
|
|
3
|
+
import { create_stopwatch, Timings } from '@ryanatkn/belt/timings.js';
|
|
4
|
+
import { print_ms, print_timings } from '@ryanatkn/belt/print.js';
|
|
5
|
+
import { to_forwarded_args } from './args.js';
|
|
6
|
+
import { run_task } from './run_task.js';
|
|
7
|
+
import { resolve_input_path } from './input_path.js';
|
|
8
|
+
import { is_task_path } from './task.js';
|
|
9
|
+
import { is_gro_id, is_this_project_gro, print_path, print_path_or_gro_path, gro_sveltekit_dist_dir, to_gro_input_path, } from './paths.js';
|
|
10
|
+
import { find_modules, load_modules } from './modules.js';
|
|
11
|
+
import { find_task_modules, load_task_module } from './task_module.js';
|
|
12
|
+
import { load_gro_package_json } from './package_json.js';
|
|
13
|
+
import { log_available_tasks, log_error_reasons } from './print_task.js';
|
|
14
|
+
import { search_fs } from './search_fs.js';
|
|
15
|
+
/**
|
|
16
|
+
* Invokes Gro tasks by name using the filesystem as the source.
|
|
17
|
+
*
|
|
18
|
+
* When a task is invoked,
|
|
19
|
+
* Gro first searches for tasks in the current working directory.
|
|
20
|
+
* and falls back to searching Gro's directory, if the two are different.
|
|
21
|
+
* See `src/lib/input_path.ts` for info about what "task_name" can refer to.
|
|
22
|
+
* If it matches a directory, all of the tasks within it are logged,
|
|
23
|
+
* both in the current working directory and Gro.
|
|
24
|
+
*
|
|
25
|
+
* This code is particularly hairy because
|
|
26
|
+
* we're accepting a wide range of user input
|
|
27
|
+
* and trying to do the right thing.
|
|
28
|
+
* Precise error messages are especially difficult and
|
|
29
|
+
* there are some subtle differences in the complex logical branches.
|
|
30
|
+
* The comments describe each condition.
|
|
31
|
+
*/
|
|
32
|
+
export const invoke_task = async (task_name, args, config, timings = new Timings()) => {
|
|
33
|
+
const log = new System_Logger(print_log_label(task_name || 'gro'));
|
|
34
|
+
log.info('invoking', task_name ? cyan(task_name) : 'gro');
|
|
35
|
+
const total_timing = create_stopwatch();
|
|
36
|
+
// Check if the caller just wants to see the version.
|
|
37
|
+
if (!task_name && (args.version || args.v)) {
|
|
38
|
+
const gro_package_json = await load_gro_package_json();
|
|
39
|
+
log.info(`${gray('v')}${cyan(gro_package_json.version)}`);
|
|
40
|
+
log.info(`🕒 ${print_ms(total_timing())}`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// Resolve the input path for the provided task name.
|
|
44
|
+
const input_path = resolve_input_path(task_name);
|
|
45
|
+
// Find the task or directory specified by the `input_path`.
|
|
46
|
+
// Fall back to searching the Gro directory as well.
|
|
47
|
+
const find_modules_result = await find_task_modules([input_path], undefined, [
|
|
48
|
+
gro_sveltekit_dist_dir,
|
|
49
|
+
]);
|
|
50
|
+
if (find_modules_result.ok) {
|
|
51
|
+
// Found a match either in the current working directory or Gro's directory.
|
|
52
|
+
const path_data = find_modules_result.source_id_path_data_by_input_path.get(input_path); // this is null safe because result is ok
|
|
53
|
+
if (!path_data.isDirectory) {
|
|
54
|
+
// The input path matches a file, so load and run it.
|
|
55
|
+
// Try to load the task module.
|
|
56
|
+
const load_modules_result = await load_modules(find_modules_result.source_ids_by_input_path, load_task_module);
|
|
57
|
+
if (load_modules_result.ok) {
|
|
58
|
+
// We found a task module. Run it!
|
|
59
|
+
// `path_data` is not a directory, so there's a single task module here.
|
|
60
|
+
const task = load_modules_result.modules[0];
|
|
61
|
+
log.info(`→ ${cyan(task.name)} ${(task.mod.task.summary && gray(task.mod.task.summary)) || ''}`);
|
|
62
|
+
const timing_to_run_task = timings.start('run task ' + task_name);
|
|
63
|
+
const result = await run_task(task, { ...args, ...to_forwarded_args(`gro ${task.name}`) }, invoke_task, config, timings);
|
|
64
|
+
timing_to_run_task();
|
|
65
|
+
if (result.ok) {
|
|
66
|
+
log.info(`✓ ${cyan(task.name)}`);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
log.info(`${red('🞩')} ${cyan(task.name)}`);
|
|
70
|
+
log_error_reasons(log, [result.reason]);
|
|
71
|
+
throw result.error;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
log_error_reasons(log, load_modules_result.reasons);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// The input path matches a directory. Log the tasks but don't run them.
|
|
81
|
+
if (is_this_project_gro) {
|
|
82
|
+
// Is the Gro directory the same as the cwd? Log the matching files.
|
|
83
|
+
await log_available_tasks(log, print_path(path_data.id), find_modules_result.source_ids_by_input_path);
|
|
84
|
+
}
|
|
85
|
+
else if (is_gro_id(path_data.id)) {
|
|
86
|
+
// TODO delete this?
|
|
87
|
+
// Does the Gro directory contain the matching files? Log them.
|
|
88
|
+
await log_available_tasks(log, print_path_or_gro_path(path_data.id), find_modules_result.source_ids_by_input_path);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// The Gro directory is not the same as the cwd
|
|
92
|
+
// and it doesn't contain the matching files.
|
|
93
|
+
// Find all of the possible matches in the Gro directory as well,
|
|
94
|
+
// and log everything out.
|
|
95
|
+
// Ignore any errors - the directory may not exist or have any files!
|
|
96
|
+
const gro_dir_find_modules_result = await to_gro_dir_find_modules_result(input_path, log);
|
|
97
|
+
// Then log the current working directory matches.
|
|
98
|
+
await log_available_tasks(log, print_path(path_data.id), find_modules_result.source_ids_by_input_path, !gro_dir_find_modules_result.ok);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else if (find_modules_result.type === 'input_directories_with_no_files') {
|
|
103
|
+
// The input path matched a directory, but it contains no matching files.
|
|
104
|
+
if (is_this_project_gro ||
|
|
105
|
+
// this is null safe because of the failure type
|
|
106
|
+
is_gro_id(find_modules_result.source_id_path_data_by_input_path.get(input_path).id)) {
|
|
107
|
+
// If the directory is inside Gro, just log the errors.
|
|
108
|
+
log_error_reasons(log, find_modules_result.reasons);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
// If there's a matching directory in the current working directory,
|
|
113
|
+
// but it has no matching files, we still want to search Gro's directory.
|
|
114
|
+
const gro_dir_find_modules_result = await to_gro_dir_find_modules_result(input_path, log);
|
|
115
|
+
if (!gro_dir_find_modules_result.ok) {
|
|
116
|
+
// Log the original errors, not the Gro-specific ones.
|
|
117
|
+
log_error_reasons(log, find_modules_result.reasons);
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
// Some other find modules result failure happened, so log it out.
|
|
124
|
+
// (currently, just "unmapped_input_paths")
|
|
125
|
+
log_error_reasons(log, find_modules_result.reasons);
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
print_timings(timings, log);
|
|
129
|
+
log.info(`🕒 ${print_ms(total_timing())}`);
|
|
130
|
+
};
|
|
131
|
+
const to_gro_dir_find_modules_result = async (input_path, log) => {
|
|
132
|
+
const gro_dir_input_path = to_gro_input_path(input_path);
|
|
133
|
+
const gro_dir_find_modules_result = await find_modules([gro_dir_input_path], (id) => search_fs(id, { filter: (path) => is_task_path(path) }));
|
|
134
|
+
if (gro_dir_find_modules_result.ok) {
|
|
135
|
+
const gro_path_data = gro_dir_find_modules_result.source_id_path_data_by_input_path.get(gro_dir_input_path);
|
|
136
|
+
// Log the Gro matches.
|
|
137
|
+
await log_available_tasks(log, print_path_or_gro_path(gro_path_data.id), gro_dir_find_modules_result.source_ids_by_input_path);
|
|
138
|
+
}
|
|
139
|
+
return gro_dir_find_modules_result;
|
|
140
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type Task } from './task.js';
|
|
3
|
+
export declare const Args: z.ZodObject<{
|
|
4
|
+
_: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
5
|
+
}, "strict", z.ZodTypeAny, {
|
|
6
|
+
_: string[];
|
|
7
|
+
}, {
|
|
8
|
+
_?: string[] | undefined;
|
|
9
|
+
}>;
|
|
10
|
+
export type Args = z.infer<typeof Args>;
|
|
11
|
+
export declare const task: Task<Args>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { print_spawn_result } from '@ryanatkn/belt/process.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { Task_Error } from './task.js';
|
|
4
|
+
import { print_command_args, serialize_args, to_forwarded_args } from './args.js';
|
|
5
|
+
import { SOURCE_DIRNAME } from './paths.js';
|
|
6
|
+
import { find_cli, spawn_cli } from './cli.js';
|
|
7
|
+
export const Args = z
|
|
8
|
+
.object({
|
|
9
|
+
_: z.array(z.string(), { description: 'paths to serve' }).default([SOURCE_DIRNAME]),
|
|
10
|
+
})
|
|
11
|
+
.strict();
|
|
12
|
+
export const task = {
|
|
13
|
+
summary: 'run eslint',
|
|
14
|
+
Args,
|
|
15
|
+
run: async ({ log, args }) => {
|
|
16
|
+
if (!(await find_cli('eslint'))) {
|
|
17
|
+
log.info('ESLint is not installed; skipping linting');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const { _ } = args;
|
|
21
|
+
const forwarded_args = { _, 'max-warnings': 0, ...to_forwarded_args('eslint') };
|
|
22
|
+
const serialized_args = serialize_args(forwarded_args);
|
|
23
|
+
log.info(print_command_args(['eslint'].concat(serialized_args)));
|
|
24
|
+
const eslintResult = await spawn_cli('eslint', serialized_args);
|
|
25
|
+
if (!eslintResult?.ok) {
|
|
26
|
+
throw new Task_Error(`ESLint found some problems. ${print_spawn_result(eslintResult)}`);
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
};
|
package/dist/loader.d.ts
ADDED
package/dist/loader.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import * as esbuild from 'esbuild';
|
|
2
|
+
import { compile, preprocess } from 'svelte/compiler';
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
4
|
+
import { dirname, join, relative } from 'node:path';
|
|
5
|
+
import { escape_regexp } from '@ryanatkn/belt/regexp.js';
|
|
6
|
+
import { render_env_shim_module } from './sveltekit_shim_env.js';
|
|
7
|
+
import { render_sveltekit_shim_app_environment, render_sveltekit_shim_app_paths, sveltekit_shim_app_environment_matcher, sveltekit_shim_app_paths_matcher, sveltekit_shim_app_specifiers, } from './sveltekit_shim_app.js';
|
|
8
|
+
import { init_sveltekit_config } from './sveltekit_config.js';
|
|
9
|
+
import { paths, NODE_MODULES_DIRNAME } from './paths.js';
|
|
10
|
+
import { to_define_import_meta_env, ts_transform_options } from './esbuild_helpers.js';
|
|
11
|
+
import { resolve_specifier } from './resolve_specifier.js';
|
|
12
|
+
import { resolve_node_specifier } from './resolve_node_specifier.js';
|
|
13
|
+
/*
|
|
14
|
+
|
|
15
|
+
Usage via `$lib/run.task.ts`:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
gro run foo.ts
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Direct usage (see also `$lib/gro.ts`):
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
node --import 'data:text/javascript,import {register} from "node:module"; import {pathToFileURL} from "node:url"; register("@ryanatkn/gro/loader.js", pathToFileURL("./"));' --enable-source-maps' foo.ts
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
TODO how to improve that gnarly import line? was originally designed for the now-deprecated `--loader`
|
|
28
|
+
|
|
29
|
+
*/
|
|
30
|
+
// TODO sourcemaps for svelte and the svelte preprocessors
|
|
31
|
+
// TODO `import.meta.resolve` wasn't available in loaders when this was first implemented, but might be now
|
|
32
|
+
// dev is always true in the loader
|
|
33
|
+
const dev = true;
|
|
34
|
+
const dir = paths.root;
|
|
35
|
+
const { alias, base_url, assets_url, env_dir, private_prefix, public_prefix, svelte_compile_options, svelte_preprocessors, } = await init_sveltekit_config(dir); // always load it to keep things simple ahead
|
|
36
|
+
const final_ts_transform_options = {
|
|
37
|
+
...ts_transform_options,
|
|
38
|
+
define: to_define_import_meta_env(dev, base_url),
|
|
39
|
+
sourcemap: 'inline',
|
|
40
|
+
};
|
|
41
|
+
const aliases = Object.entries({ $lib: 'src/lib', ...alias });
|
|
42
|
+
const ts_matcher = /\.(ts|tsx|mts|cts)$/u;
|
|
43
|
+
const svelte_matcher = /\.(svelte)$/u;
|
|
44
|
+
const json_matcher = /\.(json)$/u;
|
|
45
|
+
const env_matcher = /src\/lib\/\$env\/(static|dynamic)\/(public|private)$/u;
|
|
46
|
+
const node_modules_matcher = new RegExp(escape_regexp('/' + NODE_MODULES_DIRNAME + '/'), 'u');
|
|
47
|
+
const package_json_cache = {};
|
|
48
|
+
export const load = async (url, context, nextLoad) => {
|
|
49
|
+
if (sveltekit_shim_app_paths_matcher.test(url)) {
|
|
50
|
+
// $app/paths shim
|
|
51
|
+
return {
|
|
52
|
+
format: 'module',
|
|
53
|
+
shortCircuit: true,
|
|
54
|
+
source: render_sveltekit_shim_app_paths(base_url, assets_url),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
else if (sveltekit_shim_app_environment_matcher.test(url)) {
|
|
58
|
+
// $app/environment shim
|
|
59
|
+
return {
|
|
60
|
+
format: 'module',
|
|
61
|
+
shortCircuit: true,
|
|
62
|
+
source: render_sveltekit_shim_app_environment(dev),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
else if (ts_matcher.test(url)) {
|
|
66
|
+
// ts
|
|
67
|
+
const loaded = await nextLoad(url, context.format === 'module' ? context : { ...context, format: 'module' });
|
|
68
|
+
const transformed = await esbuild.transform(loaded.source.toString(), // eslint-disable-line @typescript-eslint/no-base-to-string
|
|
69
|
+
{ ...final_ts_transform_options, sourcefile: url });
|
|
70
|
+
return { format: 'module', shortCircuit: true, source: transformed.code };
|
|
71
|
+
}
|
|
72
|
+
else if (svelte_matcher.test(url)) {
|
|
73
|
+
// svelte
|
|
74
|
+
// TODO support sourcemaps
|
|
75
|
+
const loaded = await nextLoad(url, context.format === 'module' ? context : { ...context, format: 'module' });
|
|
76
|
+
const raw_source = loaded.source.toString(); // eslint-disable-line @typescript-eslint/no-base-to-string
|
|
77
|
+
const preprocessed = svelte_preprocessors
|
|
78
|
+
? await preprocess(raw_source, svelte_preprocessors, {
|
|
79
|
+
filename: relative(dir, fileURLToPath(url)),
|
|
80
|
+
})
|
|
81
|
+
: null;
|
|
82
|
+
const source = preprocessed?.code ?? raw_source;
|
|
83
|
+
const transformed = compile(source, svelte_compile_options);
|
|
84
|
+
return { format: 'module', shortCircuit: true, source: transformed.js.code };
|
|
85
|
+
}
|
|
86
|
+
else if (json_matcher.test(url)) {
|
|
87
|
+
// json
|
|
88
|
+
// TODO probably follow esbuild and also export every top-level property for objects from the module - https://esbuild.github.io/content-types/#json (type generation?)
|
|
89
|
+
const loaded = await nextLoad(url);
|
|
90
|
+
const raw_source = loaded.source.toString(); // eslint-disable-line @typescript-eslint/no-base-to-string
|
|
91
|
+
const source = `export default ` + raw_source;
|
|
92
|
+
return { format: 'module', shortCircuit: true, source };
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
// neither ts nor svelte
|
|
96
|
+
const matched_env = env_matcher.exec(url);
|
|
97
|
+
if (matched_env) {
|
|
98
|
+
const mode = matched_env[1];
|
|
99
|
+
const visibility = matched_env[2];
|
|
100
|
+
return {
|
|
101
|
+
format: 'module',
|
|
102
|
+
shortCircuit: true,
|
|
103
|
+
source: await render_env_shim_module(dev, mode, visibility, public_prefix, private_prefix, env_dir),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return nextLoad(url, context);
|
|
108
|
+
};
|
|
109
|
+
export const resolve = async (specifier, context, nextResolve) => {
|
|
110
|
+
if (specifier === '$env/static/public' ||
|
|
111
|
+
specifier === '$env/static/private' ||
|
|
112
|
+
specifier === '$env/dynamic/public' ||
|
|
113
|
+
specifier === '$env/dynamic/private') {
|
|
114
|
+
// The returned `url` is validated before `load` is called,
|
|
115
|
+
// so we need a slightly roundabout strategy to pass through the specifier for virtual files.
|
|
116
|
+
return {
|
|
117
|
+
url: pathToFileURL(join(dir, 'src/lib', specifier)).href,
|
|
118
|
+
format: 'module',
|
|
119
|
+
shortCircuit: true,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
const parent_url = context.parentURL;
|
|
123
|
+
if (!parent_url || node_modules_matcher.test(parent_url)) {
|
|
124
|
+
return nextResolve(specifier, context);
|
|
125
|
+
}
|
|
126
|
+
const shimmed = sveltekit_shim_app_specifiers.get(specifier);
|
|
127
|
+
if (shimmed !== undefined) {
|
|
128
|
+
return nextResolve(shimmed, context);
|
|
129
|
+
}
|
|
130
|
+
let path = specifier;
|
|
131
|
+
// Map the path with the SvelteKit aliases.
|
|
132
|
+
for (const [from, to] of aliases) {
|
|
133
|
+
if (path.startsWith(from)) {
|
|
134
|
+
path = join(dir, to, path.substring(from.length));
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// The specifier `path` has now been mapped to its final form, so we can inspect it.
|
|
139
|
+
if (path[0] !== '.' && path[0] !== '/') {
|
|
140
|
+
// Resolve to `node_modules`.
|
|
141
|
+
if (svelte_matcher.test(path) || json_matcher.test(path)) {
|
|
142
|
+
// Match the behavior of Vite and esbuild for Svelte and JSON imports.
|
|
143
|
+
// TODO maybe `.ts` too
|
|
144
|
+
const source_id = await resolve_node_specifier(path, dir, parent_url, package_json_cache);
|
|
145
|
+
return { url: pathToFileURL(source_id).href, format: 'module', shortCircuit: true };
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
return nextResolve(path, context);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const { source_id } = await resolve_specifier(path, dirname(fileURLToPath(parent_url)));
|
|
152
|
+
return { url: pathToFileURL(source_id).href, format: 'module', shortCircuit: true };
|
|
153
|
+
};
|
package/dist/module.d.ts
ADDED