@ryanatkn/gro 0.148.0 → 0.149.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/args.d.ts.map +1 -1
- package/dist/build.task.d.ts.map +1 -1
- package/dist/changelog.d.ts.map +1 -1
- package/dist/changeset.task.d.ts.map +1 -1
- package/dist/changeset_helpers.d.ts.map +1 -1
- package/dist/check.task.d.ts.map +1 -1
- package/dist/child_process_logging.d.ts +10 -0
- package/dist/child_process_logging.d.ts.map +1 -0
- package/dist/child_process_logging.js +26 -0
- package/dist/clean.task.d.ts.map +1 -1
- package/dist/clean_fs.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/commit.task.d.ts.map +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -0
- package/dist/deploy.task.d.ts +2 -2
- package/dist/deploy.task.d.ts.map +1 -1
- package/dist/dev.task.d.ts.map +1 -1
- package/dist/env.d.ts.map +1 -1
- package/dist/esbuild_helpers.d.ts.map +1 -1
- package/dist/esbuild_helpers.js +1 -1
- package/dist/esbuild_plugin_external_worker.d.ts.map +1 -1
- package/dist/esbuild_plugin_svelte.d.ts.map +1 -1
- package/dist/esbuild_plugin_sveltekit_local_imports.d.ts.map +1 -1
- package/dist/esbuild_plugin_sveltekit_shim_alias.d.ts.map +1 -1
- package/dist/esbuild_plugin_sveltekit_shim_app.d.ts.map +1 -1
- package/dist/esbuild_plugin_sveltekit_shim_env.d.ts.map +1 -1
- package/dist/filer.d.ts.map +1 -1
- package/dist/format.task.d.ts.map +1 -1
- package/dist/format_directory.d.ts.map +1 -1
- package/dist/format_file.d.ts.map +1 -1
- package/dist/fs.d.ts.map +1 -1
- package/dist/gen.d.ts.map +1 -1
- package/dist/gen.task.d.ts.map +1 -1
- package/dist/git.d.ts.map +1 -1
- package/dist/github.d.ts.map +1 -1
- package/dist/gro.config.default.d.ts.map +1 -1
- package/dist/gro.d.ts.map +1 -1
- package/dist/gro.js +1 -1
- package/dist/gro_config.d.ts.map +1 -1
- package/dist/gro_helpers.d.ts.map +1 -1
- package/dist/gro_plugin_gen.d.ts.map +1 -1
- package/dist/gro_plugin_moss.d.ts.map +1 -1
- package/dist/gro_plugin_moss.js +1 -1
- package/dist/gro_plugin_server.d.ts.map +1 -1
- package/dist/gro_plugin_sveltekit_app.d.ts.map +1 -1
- package/dist/gro_plugin_sveltekit_library.d.ts.map +1 -1
- package/dist/hash.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/input_path.d.ts.map +1 -1
- package/dist/invoke.d.ts.map +1 -1
- package/dist/invoke_task.d.ts.map +1 -1
- package/dist/lint.task.d.ts.map +1 -1
- package/dist/loader.d.ts.map +1 -1
- package/dist/module.d.ts.map +1 -1
- package/dist/modules.d.ts.map +1 -1
- package/dist/package.d.ts +11 -0
- package/dist/package.d.ts.map +1 -1
- package/dist/package.gen.d.ts.map +1 -1
- package/dist/package.js +42 -30
- package/dist/package_json.d.ts.map +1 -1
- package/dist/package_meta.d.ts.map +1 -1
- package/dist/parse_imports.d.ts.map +1 -1
- package/dist/parse_imports.js +122 -12
- package/dist/path.d.ts.map +1 -1
- package/dist/paths.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/publish.task.d.ts.map +1 -1
- package/dist/register.d.ts.map +1 -1
- package/dist/reinstall.task.d.ts.map +1 -1
- package/dist/release.task.d.ts.map +1 -1
- package/dist/resolve.task.d.ts.map +1 -1
- package/dist/resolve_specifier.d.ts.map +1 -1
- package/dist/run.task.d.ts.map +1 -1
- package/dist/run_gen.d.ts.map +1 -1
- package/dist/run_task.d.ts.map +1 -1
- package/dist/search_fs.d.ts.map +1 -1
- package/dist/src_json.d.ts.map +1 -1
- package/dist/svelte_helpers.d.ts.map +1 -1
- package/dist/sveltekit_config.d.ts.map +1 -1
- package/dist/sveltekit_helpers.d.ts.map +1 -1
- package/dist/sveltekit_shim_app.d.ts.map +1 -1
- package/dist/sveltekit_shim_app_environment.d.ts.map +1 -1
- package/dist/sveltekit_shim_app_forms.d.ts.map +1 -1
- package/dist/sveltekit_shim_app_navigation.d.ts.map +1 -1
- package/dist/sveltekit_shim_app_paths.d.ts.map +1 -1
- package/dist/sveltekit_shim_app_stores.d.ts.map +1 -1
- package/dist/sveltekit_shim_env.d.ts.map +1 -1
- package/dist/sync.task.d.ts.map +1 -1
- package/dist/task.d.ts.map +1 -1
- package/dist/task_logging.d.ts.map +1 -1
- package/dist/task_logging.js +2 -2
- package/dist/test.task.d.ts.map +1 -1
- package/dist/typecheck.task.d.ts +6 -0
- package/dist/typecheck.task.d.ts.map +1 -1
- package/dist/typecheck.task.js +20 -5
- package/dist/upgrade.task.d.ts.map +1 -1
- package/dist/watch_dir.d.ts.map +1 -1
- package/package.json +33 -29
- package/src/lib/child_process_logging.ts +38 -0
- package/src/lib/constants.ts +2 -0
- package/src/lib/esbuild_helpers.ts +1 -1
- package/src/lib/gro.ts +1 -1
- package/src/lib/gro_plugin_moss.ts +1 -1
- package/src/lib/package.ts +42 -30
- package/src/lib/parse_imports.ts +149 -12
- package/src/lib/sveltekit_shim_app_stores.ts +3 -0
- package/src/lib/task_logging.ts +2 -2
- package/src/lib/typecheck.task.ts +24 -5
package/dist/typecheck.task.js
CHANGED
|
@@ -2,8 +2,10 @@ import { print_spawn_result } from '@ryanatkn/belt/process.js';
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { Task_Error } from './task.js';
|
|
4
4
|
import { serialize_args, to_forwarded_args } from './args.js';
|
|
5
|
-
import { find_cli, spawn_cli } from './cli.js';
|
|
5
|
+
import { find_cli, spawn_cli, spawn_cli_process } from './cli.js';
|
|
6
6
|
import { SVELTE_CHECK_CLI, sveltekit_sync_if_available } from './sveltekit_helpers.js';
|
|
7
|
+
import { configure_colored_output_with_path_replacement } from './child_process_logging.js';
|
|
8
|
+
import { paths } from './paths.js';
|
|
7
9
|
export const Args = z
|
|
8
10
|
.object({
|
|
9
11
|
svelte_check_cli: z
|
|
@@ -12,21 +14,34 @@ export const Args = z
|
|
|
12
14
|
typescript_cli: z
|
|
13
15
|
.string({ description: 'the TypeScript CLI to use as a fallback to svelte-check' })
|
|
14
16
|
.default('tsc'),
|
|
17
|
+
path_replacement: z
|
|
18
|
+
.string({ description: 'replacement string for current working directory in output' })
|
|
19
|
+
.default('.'),
|
|
20
|
+
cwd: z.string({ description: 'current working directory' }).default(paths.root),
|
|
15
21
|
})
|
|
16
22
|
.strict();
|
|
17
23
|
export const task = {
|
|
18
24
|
summary: 'run tsc on the project without emitting any files',
|
|
19
25
|
Args,
|
|
20
26
|
run: async ({ args, log }) => {
|
|
21
|
-
const { svelte_check_cli, typescript_cli } = args;
|
|
27
|
+
const { svelte_check_cli, typescript_cli, path_replacement, cwd } = args;
|
|
22
28
|
await sveltekit_sync_if_available();
|
|
23
29
|
// Prefer svelte-check if available.
|
|
24
30
|
const found_svelte_check_cli = find_cli(svelte_check_cli);
|
|
25
31
|
if (found_svelte_check_cli) {
|
|
26
32
|
const serialized = serialize_args(to_forwarded_args(svelte_check_cli));
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
const spawned = spawn_cli_process(found_svelte_check_cli, serialized, undefined, {
|
|
34
|
+
stdio: ['inherit', 'pipe', 'pipe'],
|
|
35
|
+
env: { ...process.env, FORCE_COLOR: '1' }, // Needed for colors (maybe make an option)
|
|
36
|
+
});
|
|
37
|
+
const svelte_check_process = spawned?.child;
|
|
38
|
+
if (svelte_check_process) {
|
|
39
|
+
// Configure process output with path replacement while preserving colors
|
|
40
|
+
configure_colored_output_with_path_replacement(svelte_check_process, path_replacement, cwd);
|
|
41
|
+
const svelte_check_result = await spawned.closed;
|
|
42
|
+
if (!svelte_check_result.ok) {
|
|
43
|
+
throw new Task_Error(`Failed to typecheck. ${print_spawn_result(svelte_check_result)}`);
|
|
44
|
+
}
|
|
30
45
|
}
|
|
31
46
|
return;
|
|
32
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.task.d.ts","sourceRoot":"../src/lib/","sources":["upgrade.task.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAa,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AAMhD,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;EAeP,CAAC;AACX,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;AAExC,eAAO,MAAM,IAAI,EAAE,IAAI,CAAC,IAAI,CA+C3B,CAAC"}
|
|
1
|
+
{"version":3,"file":"upgrade.task.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/upgrade.task.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAa,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AAMhD,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;EAeP,CAAC;AACX,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;AAExC,eAAO,MAAM,IAAI,EAAE,IAAI,CAAC,IAAI,CA+C3B,CAAC"}
|
package/dist/watch_dir.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch_dir.d.ts","sourceRoot":"../src/lib/","sources":["watch_dir.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,eAAe,EAAiB,MAAM,UAAU,CAAC;AAKrE,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,WAAW,CAAC;AAI3C,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;CACtB;AACD,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC9D,MAAM,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;AAEvE,MAAM,WAAW,iBAAiB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,uBAAuB,CAAC;IACnC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"watch_dir.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/watch_dir.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,eAAe,EAAiB,MAAM,UAAU,CAAC;AAKrE,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,WAAW,CAAC;AAI3C,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;CACtB;AACD,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC9D,MAAM,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;AAEvE,MAAM,WAAW,iBAAiB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,uBAAuB,CAAC;IACnC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,GAAI,iDAMvB,iBAAiB,KAAG,aA6CtB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ryanatkn/gro",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.149.0",
|
|
4
4
|
"description": "task runner and toolkit extending SvelteKit",
|
|
5
5
|
"motto": "generate, run, optimize",
|
|
6
6
|
"glyph": "🌰",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"type": "module",
|
|
34
34
|
"engines": {
|
|
35
|
-
"node": ">=
|
|
35
|
+
"node": ">=22.11"
|
|
36
36
|
},
|
|
37
37
|
"bin": {
|
|
38
38
|
"gro": "dist/gro.js"
|
|
@@ -49,40 +49,40 @@
|
|
|
49
49
|
"typescript"
|
|
50
50
|
],
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@ryanatkn/belt": "^0.
|
|
53
|
-
"chokidar": "^4.0.
|
|
54
|
-
"dotenv": "^16.4.
|
|
55
|
-
"esm-env": "^1.
|
|
52
|
+
"@ryanatkn/belt": "^0.30.0",
|
|
53
|
+
"chokidar": "^4.0.3",
|
|
54
|
+
"dotenv": "^16.4.7",
|
|
55
|
+
"esm-env": "^1.2.2",
|
|
56
56
|
"mri": "^1.2.0",
|
|
57
|
-
"oxc-parser": "^0.
|
|
58
|
-
"prettier": "^3.
|
|
59
|
-
"prettier-plugin-svelte": "^3.
|
|
60
|
-
"ts-morph": "^
|
|
57
|
+
"oxc-parser": "^0.62.0",
|
|
58
|
+
"prettier": "^3.5.3",
|
|
59
|
+
"prettier-plugin-svelte": "^3.3.3",
|
|
60
|
+
"ts-morph": "^25.0.1",
|
|
61
61
|
"tslib": "^2.8.1",
|
|
62
|
-
"zod": "^3.
|
|
62
|
+
"zod": "^3.24.2"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
|
-
"esbuild": "^0.
|
|
65
|
+
"esbuild": "^0.25",
|
|
66
66
|
"svelte": "^5"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
|
-
"@changesets/changelog-git": "^0.2.
|
|
70
|
-
"@changesets/types": "^6.
|
|
71
|
-
"@ryanatkn/eslint-config": "^0.
|
|
72
|
-
"@ryanatkn/fuz": "^0.
|
|
73
|
-
"@ryanatkn/moss": "^0.
|
|
74
|
-
"@sveltejs/adapter-static": "^3.0.
|
|
75
|
-
"@sveltejs/kit": "^2.
|
|
76
|
-
"@sveltejs/package": "^2.3.
|
|
77
|
-
"@sveltejs/vite-plugin-svelte": "^
|
|
78
|
-
"@types/node": "^22.
|
|
79
|
-
"esbuild": "^0.
|
|
80
|
-
"eslint": "^9.
|
|
81
|
-
"eslint-plugin-svelte": "^
|
|
82
|
-
"svelte": "^5.
|
|
83
|
-
"svelte-check": "^4.1.
|
|
84
|
-
"typescript": "^5.
|
|
85
|
-
"typescript-eslint": "^8.
|
|
69
|
+
"@changesets/changelog-git": "^0.2.1",
|
|
70
|
+
"@changesets/types": "^6.1.0",
|
|
71
|
+
"@ryanatkn/eslint-config": "^0.8.0",
|
|
72
|
+
"@ryanatkn/fuz": "^0.135.0",
|
|
73
|
+
"@ryanatkn/moss": "^0.24.2",
|
|
74
|
+
"@sveltejs/adapter-static": "^3.0.8",
|
|
75
|
+
"@sveltejs/kit": "^2.20.4",
|
|
76
|
+
"@sveltejs/package": "^2.3.10",
|
|
77
|
+
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
|
78
|
+
"@types/node": "^22.14.0",
|
|
79
|
+
"esbuild": "^0.25.2",
|
|
80
|
+
"eslint": "^9.24.0",
|
|
81
|
+
"eslint-plugin-svelte": "^3.5.1",
|
|
82
|
+
"svelte": "^5.25.6",
|
|
83
|
+
"svelte-check": "^4.1.5",
|
|
84
|
+
"typescript": "^5.8.2",
|
|
85
|
+
"typescript-eslint": "^8.29.0",
|
|
86
86
|
"uvu": "^0.5.6"
|
|
87
87
|
},
|
|
88
88
|
"prettier": {
|
|
@@ -141,6 +141,10 @@
|
|
|
141
141
|
"types": "./dist/check.task.d.ts",
|
|
142
142
|
"default": "./dist/check.task.js"
|
|
143
143
|
},
|
|
144
|
+
"./child_process_logging.js": {
|
|
145
|
+
"types": "./dist/child_process_logging.d.ts",
|
|
146
|
+
"default": "./dist/child_process_logging.js"
|
|
147
|
+
},
|
|
144
148
|
"./clean_fs.js": {
|
|
145
149
|
"types": "./dist/clean_fs.d.ts",
|
|
146
150
|
"default": "./dist/clean_fs.js"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type {ChildProcess} from 'node:child_process';
|
|
2
|
+
import {strip_end} from '@ryanatkn/belt/string.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Maps child process output through a transform function.
|
|
6
|
+
*/
|
|
7
|
+
export const map_child_process_output = (
|
|
8
|
+
child_process: ChildProcess,
|
|
9
|
+
transform: (data: string) => string,
|
|
10
|
+
): void => {
|
|
11
|
+
if (child_process.stdout) {
|
|
12
|
+
child_process.stdout.on('data', (data) => {
|
|
13
|
+
process.stdout.write(transform(data.toString()));
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (child_process.stderr) {
|
|
18
|
+
child_process.stderr.on('data', (data) => {
|
|
19
|
+
process.stderr.write(transform(data.toString()));
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Configures process output handling with path replacements while preserving ANSI colors.
|
|
26
|
+
*/
|
|
27
|
+
export const configure_colored_output_with_path_replacement = (
|
|
28
|
+
child_process: ChildProcess,
|
|
29
|
+
replacement: string = '.',
|
|
30
|
+
cwd: string = process.cwd(),
|
|
31
|
+
): void => {
|
|
32
|
+
// Escape special characters in the cwd for regex safety
|
|
33
|
+
const cwd_escaped = strip_end(cwd, '/').replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
34
|
+
const cwd_reg_exp = new RegExp(cwd_escaped, 'g');
|
|
35
|
+
|
|
36
|
+
// Use the generic mapper with a path replacement transform
|
|
37
|
+
map_child_process_output(child_process, (data) => data.replace(cwd_reg_exp, replacement));
|
|
38
|
+
};
|
package/src/lib/constants.ts
CHANGED
|
@@ -32,6 +32,8 @@ export const TSCONFIG_FILENAME = 'tsconfig.json';
|
|
|
32
32
|
export const TS_MATCHER = /\.(ts|tsx|mts|cts)$/;
|
|
33
33
|
export const JS_MATCHER = /\.(js|jsx|mjs|cjs)$/;
|
|
34
34
|
export const JSON_MATCHER = /\.json$/;
|
|
35
|
+
/** Extracts the script content from Svelte files. */
|
|
36
|
+
export const SVELTE_SCRIPT_MATCHER = /<script(?:\s+[^>]*)?>([\s\S]*?)<\/script>/gim; // TODO maybe this shouldnt be global? or make a getter?
|
|
35
37
|
export const EVERYTHING_MATCHER = /.*/;
|
|
36
38
|
|
|
37
39
|
export const JS_CLI_DEFAULT = 'node';
|
|
@@ -38,7 +38,7 @@ export const to_define_import_meta_env = (
|
|
|
38
38
|
[import_meta_env + 'SSR']: JSON.stringify(ssr),
|
|
39
39
|
[import_meta_env + 'MODE']: JSON.stringify(mode),
|
|
40
40
|
// it appears SvelteKit's `''` translates to Vite's `'/'`, so this intentionally falls back for falsy values, not just undefined
|
|
41
|
-
[import_meta_env + 'BASE_URL']: JSON.stringify(base_url || '/'),
|
|
41
|
+
[import_meta_env + 'BASE_URL']: JSON.stringify(base_url || '/'),
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
export const default_ts_transform_options: esbuild.TransformOptions = {
|
package/src/lib/gro.ts
CHANGED
|
@@ -21,5 +21,5 @@ const loader_path = join(invoke_path, '../loader.js');
|
|
|
21
21
|
|
|
22
22
|
const spawned = await spawn_with_loader(loader_path, invoke_path, process.argv.slice(2));
|
|
23
23
|
if (!spawned.ok) {
|
|
24
|
-
process.exitCode = spawned.code || 1;
|
|
24
|
+
process.exitCode = spawned.code || 1;
|
|
25
25
|
}
|
|
@@ -53,7 +53,7 @@ export const gro_plugin_moss = ({
|
|
|
53
53
|
};
|
|
54
54
|
const flush_gen_queue = throttle(
|
|
55
55
|
async () => {
|
|
56
|
-
const css = generate_classes_css(css_classes.
|
|
56
|
+
const css = generate_classes_css(css_classes.get(), css_classes_by_name);
|
|
57
57
|
const contents = `/* ${banner} */\n\n${css}\n\n/* ${banner} */`;
|
|
58
58
|
const output = await format_file(contents, {filepath: outfile});
|
|
59
59
|
// TODO think about using gen to implement this, would have some nice benefits like automatic change detection
|
package/src/lib/package.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type {Src_Json} from './src_json.js';
|
|
|
5
5
|
|
|
6
6
|
export const package_json = {
|
|
7
7
|
name: '@ryanatkn/gro',
|
|
8
|
-
version: '0.
|
|
8
|
+
version: '0.149.0',
|
|
9
9
|
description: 'task runner and toolkit extending SvelteKit',
|
|
10
10
|
motto: 'generate, run, optimize',
|
|
11
11
|
glyph: '🌰',
|
|
@@ -30,7 +30,7 @@ export const package_json = {
|
|
|
30
30
|
deploy: 'gro deploy',
|
|
31
31
|
},
|
|
32
32
|
type: 'module',
|
|
33
|
-
engines: {node: '>=
|
|
33
|
+
engines: {node: '>=22.11'},
|
|
34
34
|
bin: {gro: 'dist/gro.js'},
|
|
35
35
|
keywords: [
|
|
36
36
|
'web',
|
|
@@ -44,37 +44,37 @@ export const package_json = {
|
|
|
44
44
|
'typescript',
|
|
45
45
|
],
|
|
46
46
|
dependencies: {
|
|
47
|
-
'@ryanatkn/belt': '^0.
|
|
48
|
-
chokidar: '^4.0.
|
|
49
|
-
dotenv: '^16.4.
|
|
50
|
-
'esm-env': '^1.
|
|
47
|
+
'@ryanatkn/belt': '^0.30.0',
|
|
48
|
+
chokidar: '^4.0.3',
|
|
49
|
+
dotenv: '^16.4.7',
|
|
50
|
+
'esm-env': '^1.2.2',
|
|
51
51
|
mri: '^1.2.0',
|
|
52
|
-
'oxc-parser': '^0.
|
|
53
|
-
prettier: '^3.
|
|
54
|
-
'prettier-plugin-svelte': '^3.
|
|
55
|
-
'ts-morph': '^
|
|
52
|
+
'oxc-parser': '^0.62.0',
|
|
53
|
+
prettier: '^3.5.3',
|
|
54
|
+
'prettier-plugin-svelte': '^3.3.3',
|
|
55
|
+
'ts-morph': '^25.0.1',
|
|
56
56
|
tslib: '^2.8.1',
|
|
57
|
-
zod: '^3.
|
|
57
|
+
zod: '^3.24.2',
|
|
58
58
|
},
|
|
59
|
-
peerDependencies: {esbuild: '^0.
|
|
59
|
+
peerDependencies: {esbuild: '^0.25', svelte: '^5'},
|
|
60
60
|
devDependencies: {
|
|
61
|
-
'@changesets/changelog-git': '^0.2.
|
|
62
|
-
'@changesets/types': '^6.
|
|
63
|
-
'@ryanatkn/eslint-config': '^0.
|
|
64
|
-
'@ryanatkn/fuz': '^0.
|
|
65
|
-
'@ryanatkn/moss': '^0.
|
|
66
|
-
'@sveltejs/adapter-static': '^3.0.
|
|
67
|
-
'@sveltejs/kit': '^2.
|
|
68
|
-
'@sveltejs/package': '^2.3.
|
|
69
|
-
'@sveltejs/vite-plugin-svelte': '^
|
|
70
|
-
'@types/node': '^22.
|
|
71
|
-
esbuild: '^0.
|
|
72
|
-
eslint: '^9.
|
|
73
|
-
'eslint-plugin-svelte': '^
|
|
74
|
-
svelte: '^5.
|
|
75
|
-
'svelte-check': '^4.1.
|
|
76
|
-
typescript: '^5.
|
|
77
|
-
'typescript-eslint': '^8.
|
|
61
|
+
'@changesets/changelog-git': '^0.2.1',
|
|
62
|
+
'@changesets/types': '^6.1.0',
|
|
63
|
+
'@ryanatkn/eslint-config': '^0.8.0',
|
|
64
|
+
'@ryanatkn/fuz': '^0.135.0',
|
|
65
|
+
'@ryanatkn/moss': '^0.24.2',
|
|
66
|
+
'@sveltejs/adapter-static': '^3.0.8',
|
|
67
|
+
'@sveltejs/kit': '^2.20.4',
|
|
68
|
+
'@sveltejs/package': '^2.3.10',
|
|
69
|
+
'@sveltejs/vite-plugin-svelte': '^5.0.3',
|
|
70
|
+
'@types/node': '^22.14.0',
|
|
71
|
+
esbuild: '^0.25.2',
|
|
72
|
+
eslint: '^9.24.0',
|
|
73
|
+
'eslint-plugin-svelte': '^3.5.1',
|
|
74
|
+
svelte: '^5.25.6',
|
|
75
|
+
'svelte-check': '^4.1.5',
|
|
76
|
+
typescript: '^5.8.2',
|
|
77
|
+
'typescript-eslint': '^8.29.0',
|
|
78
78
|
uvu: '^0.5.6',
|
|
79
79
|
},
|
|
80
80
|
prettier: {
|
|
@@ -102,6 +102,10 @@ export const package_json = {
|
|
|
102
102
|
default: './dist/changeset.task.js',
|
|
103
103
|
},
|
|
104
104
|
'./check.task.js': {types: './dist/check.task.d.ts', default: './dist/check.task.js'},
|
|
105
|
+
'./child_process_logging.js': {
|
|
106
|
+
types: './dist/child_process_logging.d.ts',
|
|
107
|
+
default: './dist/child_process_logging.js',
|
|
108
|
+
},
|
|
105
109
|
'./clean_fs.js': {types: './dist/clean_fs.d.ts', default: './dist/clean_fs.js'},
|
|
106
110
|
'./clean.task.js': {types: './dist/clean.task.d.ts', default: './dist/clean.task.js'},
|
|
107
111
|
'./cli.js': {types: './dist/cli.d.ts', default: './dist/cli.js'},
|
|
@@ -265,7 +269,7 @@ export const package_json = {
|
|
|
265
269
|
|
|
266
270
|
export const src_json = {
|
|
267
271
|
name: '@ryanatkn/gro',
|
|
268
|
-
version: '0.
|
|
272
|
+
version: '0.149.0',
|
|
269
273
|
modules: {
|
|
270
274
|
'.': {
|
|
271
275
|
path: 'index.ts',
|
|
@@ -334,6 +338,13 @@ export const src_json = {
|
|
|
334
338
|
{name: 'task', kind: 'variable'},
|
|
335
339
|
],
|
|
336
340
|
},
|
|
341
|
+
'./child_process_logging.js': {
|
|
342
|
+
path: 'child_process_logging.ts',
|
|
343
|
+
declarations: [
|
|
344
|
+
{name: 'map_child_process_output', kind: 'function'},
|
|
345
|
+
{name: 'configure_colored_output_with_path_replacement', kind: 'function'},
|
|
346
|
+
],
|
|
347
|
+
},
|
|
337
348
|
'./clean_fs.js': {path: 'clean_fs.ts', declarations: [{name: 'clean_fs', kind: 'function'}]},
|
|
338
349
|
'./clean.task.js': {
|
|
339
350
|
path: 'clean.task.ts',
|
|
@@ -387,6 +398,7 @@ export const src_json = {
|
|
|
387
398
|
{name: 'TS_MATCHER', kind: 'variable'},
|
|
388
399
|
{name: 'JS_MATCHER', kind: 'variable'},
|
|
389
400
|
{name: 'JSON_MATCHER', kind: 'variable'},
|
|
401
|
+
{name: 'SVELTE_SCRIPT_MATCHER', kind: 'variable'},
|
|
390
402
|
{name: 'EVERYTHING_MATCHER', kind: 'variable'},
|
|
391
403
|
{name: 'JS_CLI_DEFAULT', kind: 'variable'},
|
|
392
404
|
{name: 'PM_CLI_DEFAULT', kind: 'variable'},
|
package/src/lib/parse_imports.ts
CHANGED
|
@@ -1,13 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {parseSync, type ImportDeclaration} from 'oxc-parser';
|
|
2
2
|
import type {Flavored} from '@ryanatkn/belt/types.js';
|
|
3
|
+
import {Unreachable_Error} from '@ryanatkn/belt/error.js';
|
|
3
4
|
|
|
4
5
|
import type {Path_Id} from './path.js';
|
|
5
6
|
import {SVELTE_MATCHER} from './svelte_helpers.js';
|
|
6
|
-
import {JS_MATCHER, TS_MATCHER} from './constants.js';
|
|
7
|
+
import {JS_MATCHER, TS_MATCHER, SVELTE_SCRIPT_MATCHER} from './constants.js';
|
|
7
8
|
|
|
8
9
|
export type Import_Specifier = Flavored<string, 'Import_Specifier'>;
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
// TODO this is probably way more complicated that it should be, maybe report the issues upstream unless I made a mistake here
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Extracts the string value from a module request, handling different quote styles.
|
|
15
|
+
* Returns null if the value is not a valid string literal.
|
|
16
|
+
*/
|
|
17
|
+
const extract_string_literal = (content: string, start: number, end: number): string | null => {
|
|
18
|
+
const value = content.substring(start, end);
|
|
19
|
+
|
|
20
|
+
// Check if it's a string literal (starts and ends with quotes)
|
|
21
|
+
if (
|
|
22
|
+
(value.startsWith("'") && value.endsWith("'")) ||
|
|
23
|
+
(value.startsWith('"') && value.endsWith('"')) ||
|
|
24
|
+
(value.startsWith('`') && value.endsWith('`'))
|
|
25
|
+
) {
|
|
26
|
+
// Remove the quotes
|
|
27
|
+
return value.slice(1, -1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Not a valid string literal
|
|
31
|
+
return null;
|
|
32
|
+
};
|
|
11
33
|
|
|
12
34
|
export const parse_imports = (
|
|
13
35
|
id: Path_Id,
|
|
@@ -15,26 +37,141 @@ export const parse_imports = (
|
|
|
15
37
|
ignore_types = true,
|
|
16
38
|
): Array<Import_Specifier> => {
|
|
17
39
|
const specifiers: Array<string> = [];
|
|
18
|
-
|
|
19
40
|
const is_svelte = SVELTE_MATCHER.test(id);
|
|
20
41
|
|
|
21
42
|
const parse_from = (s: string): void => {
|
|
22
|
-
const parsed =
|
|
23
|
-
|
|
43
|
+
const parsed = parseSync(is_svelte ? id + '.ts' : id, s, {});
|
|
44
|
+
|
|
45
|
+
// Process static imports
|
|
46
|
+
for (const static_import of parsed.module.staticImports) {
|
|
47
|
+
// Get the module source node
|
|
48
|
+
const import_decl = parsed.program.body.find(
|
|
49
|
+
(node) => node.type === 'ImportDeclaration' && node.start === static_import.start,
|
|
50
|
+
) as ImportDeclaration | undefined;
|
|
51
|
+
|
|
52
|
+
if (!import_decl?.source) continue;
|
|
53
|
+
|
|
54
|
+
// Extract the module request string value
|
|
55
|
+
const value = extract_string_literal(s, import_decl.source.start, import_decl.source.end);
|
|
56
|
+
|
|
57
|
+
if (!value) continue;
|
|
58
|
+
|
|
59
|
+
// Skip type-only imports if ignore_types is true
|
|
24
60
|
if (ignore_types) {
|
|
25
|
-
|
|
26
|
-
if (
|
|
61
|
+
// Handle import type {...} (type-only imports)
|
|
62
|
+
if (import_decl.importKind === 'type') {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Handle inline type imports ({type foo})
|
|
67
|
+
if (static_import.entries.length > 0) {
|
|
68
|
+
// If all imports are type imports, skip this import
|
|
69
|
+
const has_non_type_specifier = static_import.entries.some((entry) => !entry.isType);
|
|
70
|
+
if (!has_non_type_specifier) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
specifiers.push(value);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Process dynamic imports
|
|
80
|
+
for (const dynamic_import of parsed.module.dynamicImports) {
|
|
81
|
+
// Find the corresponding AST node
|
|
82
|
+
let found = false;
|
|
83
|
+
for (const node of parsed.program.body) {
|
|
84
|
+
if (
|
|
85
|
+
node.type === 'ExpressionStatement' &&
|
|
86
|
+
node.expression.type === 'AwaitExpression' &&
|
|
87
|
+
node.expression.argument.type === 'ImportExpression'
|
|
88
|
+
) {
|
|
89
|
+
const import_expr = node.expression.argument;
|
|
90
|
+
if (import_expr.start === dynamic_import.start) {
|
|
91
|
+
// Only process string literals (not expressions or variables)
|
|
92
|
+
if (import_expr.source.type === 'Literal') {
|
|
93
|
+
const value = String(import_expr.source.value);
|
|
94
|
+
if (value) {
|
|
95
|
+
specifiers.push(value);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
found = true;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// If we didn't find a match through AST, fall back to the original approach
|
|
105
|
+
// but only for simple string literals
|
|
106
|
+
if (!found) {
|
|
107
|
+
const value = extract_string_literal(
|
|
108
|
+
s,
|
|
109
|
+
dynamic_import.moduleRequest.start,
|
|
110
|
+
dynamic_import.moduleRequest.end,
|
|
111
|
+
);
|
|
112
|
+
if (value) {
|
|
113
|
+
specifiers.push(value);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Process re-exports
|
|
119
|
+
for (const node of parsed.program.body) {
|
|
120
|
+
if (node.type === 'ExportNamedDeclaration' && node.source) {
|
|
121
|
+
// Skip type-only exports if ignore_types is true
|
|
122
|
+
if (ignore_types && node.exportKind === 'type') {
|
|
27
123
|
continue;
|
|
28
124
|
}
|
|
125
|
+
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
127
|
+
if (node.source.type === 'Literal') {
|
|
128
|
+
const value = String(node.source.value);
|
|
129
|
+
if (value) {
|
|
130
|
+
specifiers.push(value);
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
throw new Unreachable_Error(node.source.type);
|
|
134
|
+
}
|
|
29
135
|
}
|
|
30
|
-
if (p.n) specifiers.push(p.n);
|
|
31
136
|
}
|
|
32
137
|
};
|
|
33
138
|
|
|
34
139
|
if (is_svelte) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
140
|
+
// Reset the regex state between calls
|
|
141
|
+
SVELTE_SCRIPT_MATCHER.lastIndex = 0;
|
|
142
|
+
|
|
143
|
+
// Capture script tags at the top level (not nested in HTML)
|
|
144
|
+
let last_index = 0;
|
|
145
|
+
const script_blocks: Array<{content: string; start: number; end: number}> = [];
|
|
146
|
+
|
|
147
|
+
// First collect all script blocks
|
|
148
|
+
let match;
|
|
149
|
+
while ((match = SVELTE_SCRIPT_MATCHER.exec(contents)) !== null) {
|
|
150
|
+
// Save position of the script tag
|
|
151
|
+
const start = match.index;
|
|
152
|
+
const end = SVELTE_SCRIPT_MATCHER.lastIndex;
|
|
153
|
+
|
|
154
|
+
// Only process top-level script tags (skip nested ones)
|
|
155
|
+
// A nested script would be inside another HTML tag between lastIndex and start
|
|
156
|
+
const text_between = contents.substring(last_index, start);
|
|
157
|
+
const contains_opening_tag = /<[a-z][^>]*>/i.test(text_between);
|
|
158
|
+
const contains_closing_tag = /<\/[a-z][^>]*>/i.test(text_between);
|
|
159
|
+
|
|
160
|
+
// If we're not nested (no HTML tag nesting), process this script
|
|
161
|
+
if (!(contains_opening_tag && !contains_closing_tag)) {
|
|
162
|
+
script_blocks.push({
|
|
163
|
+
content: match[1],
|
|
164
|
+
start,
|
|
165
|
+
end,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
last_index = end;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Process all the collected script blocks
|
|
173
|
+
for (const block of script_blocks) {
|
|
174
|
+
parse_from(block.content);
|
|
38
175
|
}
|
|
39
176
|
} else if (TS_MATCHER.test(id) || JS_MATCHER.test(id)) {
|
|
40
177
|
parse_from(contents);
|
package/src/lib/task_logging.ts
CHANGED
|
@@ -131,11 +131,11 @@ const to_args_schema_type = ({_def}: ZodTypeAny): Arg_Schema['type'] => {
|
|
|
131
131
|
case ZodFirstPartyTypeKind.ZodNumber:
|
|
132
132
|
return 'number';
|
|
133
133
|
case ZodFirstPartyTypeKind.ZodArray:
|
|
134
|
-
return 'string
|
|
134
|
+
return 'Array<string>'; // TODO support arrays of arbitrary types, or more hardcoded ones as needed
|
|
135
135
|
case ZodFirstPartyTypeKind.ZodEnum:
|
|
136
136
|
return _def.values.map((v: string) => `'${v}'`).join(' | ');
|
|
137
137
|
case ZodFirstPartyTypeKind.ZodUnion:
|
|
138
|
-
return 'string | string
|
|
138
|
+
return 'string | Array<string>'; // TODO support unions of arbitrary types, or more hardcoded ones as needed
|
|
139
139
|
default: {
|
|
140
140
|
const subschema = to_subschema(_def);
|
|
141
141
|
if (subschema) {
|
|
@@ -3,8 +3,10 @@ import {z} from 'zod';
|
|
|
3
3
|
|
|
4
4
|
import {Task_Error, type Task} from './task.js';
|
|
5
5
|
import {serialize_args, to_forwarded_args} from './args.js';
|
|
6
|
-
import {find_cli, spawn_cli} from './cli.js';
|
|
6
|
+
import {find_cli, spawn_cli, spawn_cli_process} from './cli.js';
|
|
7
7
|
import {SVELTE_CHECK_CLI, sveltekit_sync_if_available} from './sveltekit_helpers.js';
|
|
8
|
+
import {configure_colored_output_with_path_replacement} from './child_process_logging.js';
|
|
9
|
+
import {paths} from './paths.js';
|
|
8
10
|
|
|
9
11
|
export const Args = z
|
|
10
12
|
.object({
|
|
@@ -14,6 +16,10 @@ export const Args = z
|
|
|
14
16
|
typescript_cli: z
|
|
15
17
|
.string({description: 'the TypeScript CLI to use as a fallback to svelte-check'})
|
|
16
18
|
.default('tsc'),
|
|
19
|
+
path_replacement: z
|
|
20
|
+
.string({description: 'replacement string for current working directory in output'})
|
|
21
|
+
.default('.'),
|
|
22
|
+
cwd: z.string({description: 'current working directory'}).default(paths.root),
|
|
17
23
|
})
|
|
18
24
|
.strict();
|
|
19
25
|
export type Args = z.infer<typeof Args>;
|
|
@@ -22,7 +28,7 @@ export const task: Task<Args> = {
|
|
|
22
28
|
summary: 'run tsc on the project without emitting any files',
|
|
23
29
|
Args,
|
|
24
30
|
run: async ({args, log}): Promise<void> => {
|
|
25
|
-
const {svelte_check_cli, typescript_cli} = args;
|
|
31
|
+
const {svelte_check_cli, typescript_cli, path_replacement, cwd} = args;
|
|
26
32
|
|
|
27
33
|
await sveltekit_sync_if_available();
|
|
28
34
|
|
|
@@ -30,10 +36,23 @@ export const task: Task<Args> = {
|
|
|
30
36
|
const found_svelte_check_cli = find_cli(svelte_check_cli);
|
|
31
37
|
if (found_svelte_check_cli) {
|
|
32
38
|
const serialized = serialize_args(to_forwarded_args(svelte_check_cli));
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
39
|
+
const spawned = spawn_cli_process(found_svelte_check_cli, serialized, undefined, {
|
|
40
|
+
stdio: ['inherit', 'pipe', 'pipe'],
|
|
41
|
+
env: {...process.env, FORCE_COLOR: '1'}, // Needed for colors (maybe make an option)
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const svelte_check_process = spawned?.child;
|
|
45
|
+
if (svelte_check_process) {
|
|
46
|
+
// Configure process output with path replacement while preserving colors
|
|
47
|
+
configure_colored_output_with_path_replacement(svelte_check_process, path_replacement, cwd);
|
|
48
|
+
|
|
49
|
+
const svelte_check_result = await spawned.closed;
|
|
50
|
+
|
|
51
|
+
if (!svelte_check_result.ok) {
|
|
52
|
+
throw new Task_Error(`Failed to typecheck. ${print_spawn_result(svelte_check_result)}`);
|
|
53
|
+
}
|
|
36
54
|
}
|
|
55
|
+
|
|
37
56
|
return;
|
|
38
57
|
}
|
|
39
58
|
|