@ryanatkn/gro 0.135.2 → 0.136.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/check.task.d.ts +2 -2
- package/dist/filer.d.ts +29 -0
- package/dist/filer.d.ts.map +1 -0
- package/dist/filer.js +165 -0
- package/dist/gen.task.d.ts +2 -2
- package/dist/gro.config.default.d.ts.map +1 -1
- package/dist/gro.config.default.js +2 -3
- package/dist/gro_plugin_gen.d.ts +9 -2
- package/dist/gro_plugin_gen.d.ts.map +1 -1
- package/dist/gro_plugin_gen.js +67 -37
- package/dist/gro_plugin_sveltekit_library.d.ts.map +1 -1
- package/dist/gro_plugin_sveltekit_library.js +4 -16
- package/dist/invoke_task.d.ts +2 -1
- package/dist/invoke_task.d.ts.map +1 -1
- package/dist/invoke_task.js +4 -2
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +3 -9
- package/dist/package.d.ts +22 -0
- package/dist/package.d.ts.map +1 -1
- package/dist/package.js +39 -13
- package/dist/parse_imports.d.ts +6 -0
- package/dist/parse_imports.d.ts.map +1 -0
- package/dist/parse_imports.js +29 -0
- package/dist/path_constants.d.ts +1 -0
- package/dist/path_constants.d.ts.map +1 -1
- package/dist/path_constants.js +1 -0
- package/dist/paths.d.ts +2 -1
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +3 -1
- package/dist/run_task.d.ts +2 -1
- package/dist/run_task.d.ts.map +1 -1
- package/dist/run_task.js +4 -3
- package/dist/sveltekit_config.d.ts +1 -1
- package/dist/sveltekit_config.d.ts.map +1 -1
- package/dist/sveltekit_config.js +1 -1
- package/dist/sveltekit_helpers.d.ts +6 -0
- package/dist/sveltekit_helpers.d.ts.map +1 -1
- package/dist/sveltekit_helpers.js +32 -0
- package/dist/sync.task.d.ts +2 -2
- package/dist/task.d.ts +2 -0
- package/dist/task.d.ts.map +1 -1
- package/dist/watch_dir.d.ts +1 -1
- package/dist/watch_dir.d.ts.map +1 -1
- package/dist/watch_dir.js +14 -12
- package/package.json +19 -11
- package/src/lib/filer.ts +212 -0
- package/src/lib/gro.config.default.ts +2 -3
- package/src/lib/gro_plugin_gen.ts +90 -43
- package/src/lib/gro_plugin_sveltekit_library.ts +4 -20
- package/src/lib/invoke_task.ts +6 -1
- package/src/lib/loader.ts +3 -10
- package/src/lib/package.ts +39 -13
- package/src/lib/parse_imports.ts +42 -0
- package/src/lib/path_constants.ts +1 -0
- package/src/lib/paths.ts +8 -1
- package/src/lib/run_task.ts +5 -2
- package/src/lib/sveltekit_config.ts +2 -2
- package/src/lib/sveltekit_helpers.ts +46 -0
- package/src/lib/task.ts +2 -0
- package/src/lib/watch_dir.ts +15 -14
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {init, parse} from 'es-module-lexer';
|
|
2
|
+
import type {Flavored} from '@ryanatkn/belt/types.js';
|
|
3
|
+
|
|
4
|
+
import type {Path_Id} from './path.js';
|
|
5
|
+
|
|
6
|
+
export const init_lexer = (): Promise<void> => init;
|
|
7
|
+
|
|
8
|
+
export type Import_Specifier = Flavored<string, 'Import_Specifier'>;
|
|
9
|
+
|
|
10
|
+
const script_matcher = /<script.*?>(.*?)<\/script>/gimsu;
|
|
11
|
+
|
|
12
|
+
export const parse_imports = (
|
|
13
|
+
id: Path_Id,
|
|
14
|
+
contents: string,
|
|
15
|
+
ignore_types = true,
|
|
16
|
+
): Import_Specifier[] => {
|
|
17
|
+
const specifiers: string[] = [];
|
|
18
|
+
|
|
19
|
+
const parse_from = (s: string): void => {
|
|
20
|
+
const parsed = parse(s);
|
|
21
|
+
for (const p of parsed[0]) {
|
|
22
|
+
if (ignore_types) {
|
|
23
|
+
const import_statement = s.slice(p.ss, p.se);
|
|
24
|
+
if (import_statement.startsWith('import type')) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (p.n) specifiers.push(p.n);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
if (id.endsWith('.svelte')) {
|
|
33
|
+
const matches = contents.matchAll(script_matcher);
|
|
34
|
+
for (const m of matches) {
|
|
35
|
+
parse_from(m[1]);
|
|
36
|
+
}
|
|
37
|
+
} else {
|
|
38
|
+
parse_from(contents);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return specifiers;
|
|
42
|
+
};
|
|
@@ -30,5 +30,6 @@ export const GIT_DIRNAME = '.git';
|
|
|
30
30
|
export const TSCONFIG_FILENAME = 'tsconfig.json';
|
|
31
31
|
|
|
32
32
|
export const TS_MATCHER = /\.(ts|tsx|mts|cts)$/;
|
|
33
|
+
export const JS_MATCHER = /\.(js|jsx|mjs|cjs)$/;
|
|
33
34
|
export const JSON_MATCHER = /\.(json)$/;
|
|
34
35
|
export const EVERYTHING_MATCHER = /.*/;
|
package/src/lib/paths.ts
CHANGED
|
@@ -7,11 +7,15 @@ import {
|
|
|
7
7
|
GRO_CONFIG_PATH,
|
|
8
8
|
GRO_DEV_DIR,
|
|
9
9
|
GRO_DIR,
|
|
10
|
+
JS_MATCHER,
|
|
11
|
+
JSON_MATCHER,
|
|
10
12
|
SOURCE_DIR,
|
|
11
13
|
SVELTEKIT_DIST_DIRNAME,
|
|
14
|
+
TS_MATCHER,
|
|
12
15
|
} from './path_constants.js';
|
|
13
16
|
import {default_sveltekit_config} from './sveltekit_config.js';
|
|
14
|
-
import type {Path_Id} from './path.js';
|
|
17
|
+
import type {File_Filter, Path_Id} from './path.js';
|
|
18
|
+
import {SVELTE_MATCHER} from './svelte_helpers.js';
|
|
15
19
|
|
|
16
20
|
/*
|
|
17
21
|
|
|
@@ -99,3 +103,6 @@ export const IS_THIS_GRO = gro_package_dir_path === paths.root;
|
|
|
99
103
|
*/
|
|
100
104
|
export const gro_paths = IS_THIS_GRO ? paths : create_paths(gro_package_dir_path);
|
|
101
105
|
export const GRO_DIST_DIR = gro_paths.root + SVELTEKIT_DIST_DIRNAME + '/';
|
|
106
|
+
|
|
107
|
+
export const default_file_filter: File_Filter = (p) =>
|
|
108
|
+
SVELTE_MATCHER.test(p) || JS_MATCHER.test(p) || TS_MATCHER.test(p) || JSON_MATCHER.test(p);
|
package/src/lib/run_task.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {log_task_help} from './task_logging.js';
|
|
|
9
9
|
import type {Gro_Config} from './gro_config.js';
|
|
10
10
|
import {Task_Error, type Task_Module_Meta} from './task.js';
|
|
11
11
|
import {default_sveltekit_config} from './sveltekit_config.js';
|
|
12
|
+
import type {Filer} from './filer.js';
|
|
12
13
|
|
|
13
14
|
export type Run_Task_Result =
|
|
14
15
|
| {
|
|
@@ -26,6 +27,7 @@ export const run_task = async (
|
|
|
26
27
|
unparsed_args: Args,
|
|
27
28
|
invoke_task: typeof base_invoke_task,
|
|
28
29
|
config: Gro_Config,
|
|
30
|
+
filer: Filer,
|
|
29
31
|
timings: Timings,
|
|
30
32
|
): Promise<Run_Task_Result> => {
|
|
31
33
|
const {task} = task_meta.mod;
|
|
@@ -48,16 +50,17 @@ export const run_task = async (
|
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
// Run the task.
|
|
51
|
-
let output: unknown;
|
|
53
|
+
let output: unknown; // TODO generic
|
|
52
54
|
try {
|
|
53
55
|
output = await task.run({
|
|
54
56
|
args,
|
|
55
57
|
config,
|
|
56
58
|
sveltekit_config: default_sveltekit_config,
|
|
59
|
+
filer,
|
|
57
60
|
log,
|
|
58
61
|
timings,
|
|
59
62
|
invoke_task: (invoked_task_name, invoked_args, invoked_config) =>
|
|
60
|
-
invoke_task(invoked_task_name, invoked_args, invoked_config ?? config, timings),
|
|
63
|
+
invoke_task(invoked_task_name, invoked_args, invoked_config ?? config, filer, timings),
|
|
61
64
|
});
|
|
62
65
|
} catch (err) {
|
|
63
66
|
return {
|
|
@@ -35,7 +35,7 @@ export const load_sveltekit_config = async (
|
|
|
35
35
|
export interface Parsed_Sveltekit_Config {
|
|
36
36
|
// TODO probably fill these out with defaults
|
|
37
37
|
sveltekit_config: SveltekitConfig | null;
|
|
38
|
-
alias: Record<string, string
|
|
38
|
+
alias: Record<string, string>;
|
|
39
39
|
base_url: '' | `/${string}` | undefined;
|
|
40
40
|
assets_url: '' | `http://${string}` | `https://${string}` | undefined;
|
|
41
41
|
|
|
@@ -74,7 +74,7 @@ export const init_sveltekit_config = async (
|
|
|
74
74
|
typeof dir_or_config === 'string' ? await load_sveltekit_config(dir_or_config) : dir_or_config;
|
|
75
75
|
const kit = sveltekit_config?.kit;
|
|
76
76
|
|
|
77
|
-
const alias = kit?.alias;
|
|
77
|
+
const alias = {$lib: 'src/lib', ...kit?.alias};
|
|
78
78
|
|
|
79
79
|
const base_url = kit?.paths?.base;
|
|
80
80
|
const assets_url = kit?.paths?.assets;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type {Result} from '@ryanatkn/belt/result.js';
|
|
2
2
|
import {existsSync} from 'node:fs';
|
|
3
|
+
import type {Logger} from '@ryanatkn/belt/log.js';
|
|
4
|
+
import {join} from 'node:path';
|
|
3
5
|
|
|
4
6
|
import {Package_Json, load_package_json} from './package_json.js';
|
|
5
7
|
import {default_sveltekit_config, type Parsed_Sveltekit_Config} from './sveltekit_config.js';
|
|
6
8
|
import {SVELTEKIT_CONFIG_FILENAME, SVELTEKIT_DEV_DIRNAME} from './path_constants.js';
|
|
7
9
|
import {find_cli, spawn_cli, to_cli_name, type Cli} from './cli.js';
|
|
8
10
|
import {Task_Error} from './task.js';
|
|
11
|
+
import {serialize_args, to_forwarded_args} from './args.js';
|
|
9
12
|
|
|
10
13
|
export const SVELTEKIT_CLI = 'svelte-kit';
|
|
11
14
|
|
|
@@ -145,3 +148,46 @@ export interface Svelte_Package_Options {
|
|
|
145
148
|
*/
|
|
146
149
|
tsconfig?: string;
|
|
147
150
|
}
|
|
151
|
+
|
|
152
|
+
export const run_svelte_package = async (
|
|
153
|
+
options: Svelte_Package_Options | undefined,
|
|
154
|
+
cli: string | Cli,
|
|
155
|
+
log: Logger,
|
|
156
|
+
): Promise<void> => {
|
|
157
|
+
const has_sveltekit_library_result = has_sveltekit_library();
|
|
158
|
+
if (!has_sveltekit_library_result.ok) {
|
|
159
|
+
throw new Task_Error(
|
|
160
|
+
'Failed to find SvelteKit library: ' + has_sveltekit_library_result.message,
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
const cli_name = typeof cli === 'string' ? cli : cli.name;
|
|
164
|
+
const found_svelte_package_cli = cli === cli_name ? find_cli(cli) : (cli as Cli);
|
|
165
|
+
if (found_svelte_package_cli?.kind !== 'local') {
|
|
166
|
+
throw new Task_Error(
|
|
167
|
+
`Failed to find SvelteKit packaging CLI \`${cli_name}\`, do you need to run \`npm i\`?`,
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
const serialized_args = serialize_args({
|
|
171
|
+
...options,
|
|
172
|
+
...to_forwarded_args(cli_name),
|
|
173
|
+
});
|
|
174
|
+
await spawn_cli(found_svelte_package_cli, serialized_args, log);
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
//
|
|
178
|
+
/**
|
|
179
|
+
* Map an import specifier with the SvelteKit aliases.
|
|
180
|
+
*/
|
|
181
|
+
export const map_sveltekit_aliases = (
|
|
182
|
+
specifier: string,
|
|
183
|
+
aliases: Array<[string, string]>,
|
|
184
|
+
): string => {
|
|
185
|
+
let path = specifier;
|
|
186
|
+
for (const [from, to] of aliases) {
|
|
187
|
+
if (path.startsWith(from)) {
|
|
188
|
+
path = join(process.cwd(), to, path.substring(from.length));
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return path;
|
|
193
|
+
};
|
package/src/lib/task.ts
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
import {GRO_DIST_DIR, print_path} from './paths.js';
|
|
21
21
|
import {search_fs} from './search_fs.js';
|
|
22
22
|
import {load_modules, type Load_Modules_Failure, type Module_Meta} from './modules.js';
|
|
23
|
+
import type {Filer} from './filer.js';
|
|
23
24
|
|
|
24
25
|
export interface Task<
|
|
25
26
|
T_Args = Args, // same as `z.infer<typeof Args>`
|
|
@@ -35,6 +36,7 @@ export interface Task_Context<T_Args = object> {
|
|
|
35
36
|
args: T_Args;
|
|
36
37
|
config: Gro_Config;
|
|
37
38
|
sveltekit_config: Parsed_Sveltekit_Config;
|
|
39
|
+
filer: Filer;
|
|
38
40
|
// TODO should this go here or on `config` for convenience?
|
|
39
41
|
// sveltekit_config: Parsed_Sveltekit_Config;
|
|
40
42
|
log: Logger;
|
package/src/lib/watch_dir.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {watch, type ChokidarOptions, type FSWatcher} from 'chokidar';
|
|
2
2
|
import {relative} from 'node:path';
|
|
3
|
+
import {statSync} from 'node:fs';
|
|
3
4
|
|
|
4
5
|
import type {Path_Filter} from './path.js';
|
|
5
|
-
import {statSync} from 'node:fs';
|
|
6
6
|
|
|
7
7
|
// TODO pretty hacky
|
|
8
8
|
|
|
@@ -16,7 +16,7 @@ export interface Watcher_Change {
|
|
|
16
16
|
path: string;
|
|
17
17
|
is_directory: boolean;
|
|
18
18
|
}
|
|
19
|
-
export type Watcher_Change_Type = '
|
|
19
|
+
export type Watcher_Change_Type = 'add' | 'update' | 'delete';
|
|
20
20
|
export type Watcher_Change_Callback = (change: Watcher_Change) => void;
|
|
21
21
|
|
|
22
22
|
export interface Options {
|
|
@@ -42,21 +42,23 @@ export const watch_dir = ({
|
|
|
42
42
|
chokidar,
|
|
43
43
|
}: Options): Watch_Node_Fs => {
|
|
44
44
|
let watcher: FSWatcher | undefined;
|
|
45
|
+
let initing: Promise<void> | undefined;
|
|
45
46
|
|
|
46
47
|
return {
|
|
47
48
|
init: async () => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
if (initing) return initing;
|
|
50
|
+
let resolve: any;
|
|
51
|
+
initing = new Promise((r) => (resolve = r)); // TODO `create_deferred`?// cwd: chokidar?.cwd ?? process.cwd()
|
|
52
|
+
watcher = watch(dir, {...chokidar});
|
|
53
|
+
watcher.on('add', (path) => {
|
|
51
54
|
const final_path = absolute ? path : relative(dir, path);
|
|
52
|
-
if (filter && !filter(final_path,
|
|
53
|
-
on_change({type: '
|
|
55
|
+
if (filter && !filter(final_path, false)) return;
|
|
56
|
+
on_change({type: 'add', path: final_path, is_directory: false});
|
|
54
57
|
});
|
|
55
|
-
watcher.on('addDir', (path
|
|
56
|
-
const stats = s ?? statSync(path);
|
|
58
|
+
watcher.on('addDir', (path) => {
|
|
57
59
|
const final_path = absolute ? path : relative(dir, path);
|
|
58
|
-
if (filter && !filter(final_path,
|
|
59
|
-
on_change({type: '
|
|
60
|
+
if (filter && !filter(final_path, true)) return;
|
|
61
|
+
on_change({type: 'add', path: final_path, is_directory: true});
|
|
60
62
|
});
|
|
61
63
|
watcher.on('change', (path, s) => {
|
|
62
64
|
const stats = s ?? statSync(path);
|
|
@@ -75,12 +77,11 @@ export const watch_dir = ({
|
|
|
75
77
|
on_change({type: 'delete', path: final_path, is_directory: true});
|
|
76
78
|
});
|
|
77
79
|
// wait until ready
|
|
78
|
-
let resolve: any;
|
|
79
|
-
const promise = new Promise((r) => (resolve = r));
|
|
80
80
|
watcher.once('ready', () => resolve());
|
|
81
|
-
await
|
|
81
|
+
await initing;
|
|
82
82
|
},
|
|
83
83
|
close: async () => {
|
|
84
|
+
initing = undefined;
|
|
84
85
|
if (!watcher) return;
|
|
85
86
|
await watcher.close();
|
|
86
87
|
},
|