@ryanatkn/gro 0.161.2 → 0.162.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +8 -7
  2. package/dist/build.task.d.ts.map +1 -1
  3. package/dist/build.task.js +4 -2
  4. package/dist/check.task.d.ts +0 -1
  5. package/dist/check.task.d.ts.map +1 -1
  6. package/dist/check.task.js +8 -8
  7. package/dist/child_process_logging.js +1 -1
  8. package/dist/constants.d.ts +10 -1
  9. package/dist/constants.d.ts.map +1 -1
  10. package/dist/constants.js +12 -3
  11. package/dist/deploy.task.d.ts +2 -0
  12. package/dist/deploy.task.d.ts.map +1 -1
  13. package/dist/deploy.task.js +6 -2
  14. package/dist/dev.task.d.ts +0 -1
  15. package/dist/dev.task.d.ts.map +1 -1
  16. package/dist/dev.task.js +5 -7
  17. package/dist/disknode.d.ts +18 -0
  18. package/dist/disknode.d.ts.map +1 -0
  19. package/dist/disknode.js +1 -0
  20. package/dist/esbuild_plugin_sveltekit_shim_env.d.ts.map +1 -1
  21. package/dist/esbuild_plugin_sveltekit_shim_env.js +1 -2
  22. package/dist/filer.d.ts +6 -21
  23. package/dist/filer.d.ts.map +1 -1
  24. package/dist/filer.js +11 -6
  25. package/dist/format_directory.js +2 -2
  26. package/dist/gen.task.d.ts.map +1 -1
  27. package/dist/gen.task.js +56 -12
  28. package/dist/git.js +3 -3
  29. package/dist/gro.config.default.d.ts.map +1 -1
  30. package/dist/gro.config.default.js +2 -1
  31. package/dist/gro_config.d.ts +1 -1
  32. package/dist/gro_config.d.ts.map +1 -1
  33. package/dist/gro_config.js +5 -5
  34. package/dist/gro_plugin_gen.d.ts.map +1 -1
  35. package/dist/gro_plugin_gen.js +7 -6
  36. package/dist/gro_plugin_server.d.ts.map +1 -1
  37. package/dist/gro_plugin_server.js +16 -25
  38. package/dist/gro_plugin_sveltekit_app.d.ts.map +1 -1
  39. package/dist/gro_plugin_sveltekit_app.js +1 -2
  40. package/dist/gro_plugin_sveltekit_library.d.ts.map +1 -1
  41. package/dist/gro_plugin_sveltekit_library.js +2 -1
  42. package/dist/invoke.js +6 -4
  43. package/dist/package.d.ts.map +1 -1
  44. package/dist/package.gen.d.ts.map +1 -1
  45. package/dist/package.gen.js +4 -0
  46. package/dist/package.js +41 -30
  47. package/dist/package_json.d.ts +4 -3
  48. package/dist/package_json.d.ts.map +1 -1
  49. package/dist/package_json.js +12 -10
  50. package/dist/parse_imports.js +2 -2
  51. package/dist/paths.js +2 -2
  52. package/dist/reinstall.task.js +1 -1
  53. package/dist/resolve_specifier.d.ts.map +1 -1
  54. package/dist/src_json.d.ts.map +1 -1
  55. package/dist/src_json.js +3 -1
  56. package/dist/svelte_config.d.ts.map +1 -1
  57. package/dist/svelte_config.js +2 -0
  58. package/dist/sveltekit_helpers.d.ts +0 -7
  59. package/dist/sveltekit_helpers.d.ts.map +1 -1
  60. package/dist/sveltekit_helpers.js +1 -8
  61. package/dist/sync.task.d.ts +0 -1
  62. package/dist/sync.task.d.ts.map +1 -1
  63. package/dist/sync.task.js +1 -2
  64. package/dist/task.d.ts.map +1 -1
  65. package/dist/test.task.d.ts +2 -3
  66. package/dist/test.task.d.ts.map +1 -1
  67. package/dist/test.task.js +31 -30
  68. package/dist/test_helpers.d.ts +1 -0
  69. package/dist/test_helpers.d.ts.map +1 -1
  70. package/dist/test_helpers.js +1 -0
  71. package/dist/typecheck.task.d.ts.map +1 -1
  72. package/dist/typecheck.task.js +2 -1
  73. package/dist/upgrade.task.d.ts.map +1 -1
  74. package/dist/upgrade.task.js +2 -1
  75. package/package.json +34 -19
  76. package/src/lib/build.task.ts +3 -2
  77. package/src/lib/check.task.ts +7 -8
  78. package/src/lib/child_process_logging.ts +1 -1
  79. package/src/lib/constants.ts +12 -3
  80. package/src/lib/deploy.task.ts +18 -3
  81. package/src/lib/dev.task.ts +4 -7
  82. package/src/lib/disknode.ts +21 -0
  83. package/src/lib/esbuild_plugin_sveltekit_shim_env.ts +1 -2
  84. package/src/lib/filer.ts +23 -35
  85. package/src/lib/format_directory.ts +2 -2
  86. package/src/lib/gen.task.ts +83 -23
  87. package/src/lib/git.ts +3 -3
  88. package/src/lib/gro.config.default.ts +2 -1
  89. package/src/lib/gro_config.ts +11 -7
  90. package/src/lib/gro_plugin_gen.ts +8 -6
  91. package/src/lib/gro_plugin_server.ts +18 -24
  92. package/src/lib/gro_plugin_sveltekit_app.ts +1 -2
  93. package/src/lib/gro_plugin_sveltekit_library.ts +2 -5
  94. package/src/lib/invoke.ts +6 -4
  95. package/src/lib/package.gen.ts +4 -0
  96. package/src/lib/package.ts +41 -30
  97. package/src/lib/package_json.ts +11 -9
  98. package/src/lib/parse_imports.ts +2 -2
  99. package/src/lib/paths.ts +2 -2
  100. package/src/lib/reinstall.task.ts +1 -1
  101. package/src/lib/resolve_specifier.ts +2 -0
  102. package/src/lib/src_json.ts +3 -1
  103. package/src/lib/svelte_config.ts +3 -0
  104. package/src/lib/sveltekit_helpers.ts +7 -13
  105. package/src/lib/sync.task.ts +1 -2
  106. package/src/lib/task.ts +0 -2
  107. package/src/lib/test.task.ts +31 -32
  108. package/src/lib/test_helpers.ts +2 -0
  109. package/src/lib/typecheck.task.ts +2 -1
  110. package/src/lib/upgrade.task.ts +2 -1
@@ -5,7 +5,7 @@ import type {Src_Json} from '@ryanatkn/belt/src_json.js';
5
5
 
6
6
  export const package_json: Package_Json = {
7
7
  name: '@ryanatkn/gro',
8
- version: '0.161.2',
8
+ version: '0.162.1',
9
9
  description: 'task runner and toolkit extending SvelteKit',
10
10
  motto: 'generate, run, optimize',
11
11
  glyph: '🌰',
@@ -44,39 +44,46 @@ export const package_json: Package_Json = {
44
44
  'typescript',
45
45
  ],
46
46
  dependencies: {
47
- '@ryanatkn/belt': '^0.33.0',
47
+ '@ryanatkn/belt': '^0.34.1',
48
48
  chokidar: '^4.0.3',
49
49
  dotenv: '^17.2.1',
50
50
  'esm-env': '^1.2.2',
51
51
  mri: '^1.2.0',
52
- 'oxc-parser': '^0.79.1',
52
+ 'oxc-parser': '^0.82.3',
53
53
  prettier: '^3.6.2',
54
54
  'prettier-plugin-svelte': '^3.4.0',
55
- 'ts-blank-space': '^0.6.1',
55
+ 'ts-blank-space': '^0.6.2',
56
56
  tslib: '^2.8.1',
57
- zod: '^4.0.14',
57
+ zod: '^4.1.4',
58
58
  },
59
- peerDependencies: {esbuild: '^0.25', svelte: '^5', typescript: '^5'},
60
- optionalDependencies: {'@ryanatkn/moss': '>=0.31.0'},
59
+ peerDependencies: {
60
+ '@sveltejs/kit': '^2',
61
+ esbuild: '^0.25',
62
+ svelte: '^5',
63
+ typescript: '^5',
64
+ vitest: '^3',
65
+ },
66
+ peerDependenciesMeta: {'@sveltejs/kit': {optional: true}, vitest: {optional: true}},
67
+ optionalDependencies: {'@ryanatkn/moss': '>=0.31.0', vitest: '^3'},
61
68
  devDependencies: {
62
69
  '@changesets/changelog-git': '^0.2.1',
63
70
  '@changesets/types': '^6.1.0',
64
71
  '@ryanatkn/eslint-config': '^0.8.0',
65
72
  '@ryanatkn/fuz': '^0.145.0',
66
73
  '@ryanatkn/moss': '^0.32.0',
67
- '@sveltejs/adapter-static': '^3.0.8',
68
- '@sveltejs/kit': '^2.27.0',
69
- '@sveltejs/package': '^2.4.0',
70
- '@sveltejs/vite-plugin-svelte': '^6.1.0',
71
- '@types/node': '^24.1.0',
72
- esbuild: '^0.25.5',
73
- eslint: '^9.32.0',
74
+ '@sveltejs/adapter-static': '^3.0.9',
75
+ '@sveltejs/kit': '^2.36.3',
76
+ '@sveltejs/package': '^2.5.0',
77
+ '@sveltejs/vite-plugin-svelte': '^6.1.3',
78
+ '@types/node': '^24.3.0',
79
+ esbuild: '^0.25.9',
80
+ eslint: '^9.34.0',
74
81
  'eslint-plugin-svelte': '^3.11.0',
75
- svelte: '^5.37.2',
76
- 'svelte-check': '^4.3.0',
77
- typescript: '^5.8.3',
78
- 'typescript-eslint': '^8.38.0',
79
- uvu: '^0.5.6',
82
+ svelte: '^5.38.6',
83
+ 'svelte-check': '^4.3.1',
84
+ typescript: '^5.9.2',
85
+ 'typescript-eslint': '^8.41.0',
86
+ vitest: '^3.2.4',
80
87
  },
81
88
  prettier: {
82
89
  plugins: ['prettier-plugin-svelte'],
@@ -114,6 +121,7 @@ export const package_json: Package_Json = {
114
121
  './constants.js': {types: './dist/constants.d.ts', default: './dist/constants.js'},
115
122
  './deploy.task.js': {types: './dist/deploy.task.d.ts', default: './dist/deploy.task.js'},
116
123
  './dev.task.js': {types: './dist/dev.task.d.ts', default: './dist/dev.task.js'},
124
+ './disknode.js': {types: './dist/disknode.d.ts', default: './dist/disknode.js'},
117
125
  './env.js': {types: './dist/env.d.ts', default: './dist/env.js'},
118
126
  './esbuild_helpers.js': {
119
127
  types: './dist/esbuild_helpers.d.ts',
@@ -264,7 +272,7 @@ export const package_json: Package_Json = {
264
272
 
265
273
  export const src_json: Src_Json = {
266
274
  name: '@ryanatkn/gro',
267
- version: '0.161.2',
275
+ version: '0.162.1',
268
276
  modules: {
269
277
  '.': {
270
278
  path: 'index.ts',
@@ -377,11 +385,12 @@ export const src_json: Src_Json = {
377
385
  {name: 'SOURCE_DIR', kind: 'variable'},
378
386
  {name: 'GRO_DIR', kind: 'variable'},
379
387
  {name: 'GRO_DEV_DIR', kind: 'variable'},
380
- {name: 'GRO_CONFIG_PATH', kind: 'variable'},
388
+ {name: 'GRO_CONFIG_FILENAME', kind: 'variable'},
381
389
  {name: 'README_FILENAME', kind: 'variable'},
382
390
  {name: 'SVELTE_CONFIG_FILENAME', kind: 'variable'},
383
391
  {name: 'VITE_CONFIG_FILENAME', kind: 'variable'},
384
392
  {name: 'NODE_MODULES_DIRNAME', kind: 'variable'},
393
+ {name: 'PACKAGE_JSON_FILENAME', kind: 'variable'},
385
394
  {name: 'LOCKFILE_FILENAME', kind: 'variable'},
386
395
  {name: 'SVELTEKIT_DEV_DIRNAME', kind: 'variable'},
387
396
  {name: 'SVELTEKIT_BUILD_DIRNAME', kind: 'variable'},
@@ -396,10 +405,18 @@ export const src_json: Src_Json = {
396
405
  {name: 'SVELTE_MATCHER', kind: 'variable'},
397
406
  {name: 'SVELTE_RUNES_MATCHER', kind: 'variable'},
398
407
  {name: 'SVELTE_SCRIPT_MATCHER', kind: 'variable'},
408
+ {name: 'SVELTEKIT_ENV_MATCHER', kind: 'variable'},
409
+ {name: 'SVELTEKIT_GLOBAL_SPECIFIER', kind: 'variable'},
399
410
  {name: 'EVERYTHING_MATCHER', kind: 'variable'},
400
411
  {name: 'JS_CLI_DEFAULT', kind: 'variable'},
401
412
  {name: 'PM_CLI_DEFAULT', kind: 'variable'},
402
413
  {name: 'PRETTIER_CLI_DEFAULT', kind: 'variable'},
414
+ {name: 'SVELTEKIT_CLI', kind: 'variable'},
415
+ {name: 'SVELTE_CHECK_CLI', kind: 'variable'},
416
+ {name: 'SVELTE_PACKAGE_CLI', kind: 'variable'},
417
+ {name: 'SVELTE_PACKAGE_DEP_NAME', kind: 'variable'},
418
+ {name: 'VITE_CLI', kind: 'variable'},
419
+ {name: 'VITEST_CLI', kind: 'variable'},
403
420
  ],
404
421
  },
405
422
  './deploy.task.js': {
@@ -417,6 +434,7 @@ export const src_json: Src_Json = {
417
434
  {name: 'task', kind: 'variable'},
418
435
  ],
419
436
  },
437
+ './disknode.js': {path: 'disknode.ts', declarations: [{name: 'Disknode', kind: 'type'}]},
420
438
  './env.js': {
421
439
  path: 'env.ts',
422
440
  declarations: [
@@ -477,7 +495,6 @@ export const src_json: Src_Json = {
477
495
  './filer.js': {
478
496
  path: 'filer.ts',
479
497
  declarations: [
480
- {name: 'Source_File', kind: 'type'},
481
498
  {name: 'Cleanup_Watch', kind: 'type'},
482
499
  {name: 'On_Filer_Change', kind: 'type'},
483
500
  {name: 'Filer_Options', kind: 'type'},
@@ -584,7 +601,7 @@ export const src_json: Src_Json = {
584
601
  {name: 'create_empty_gro_config', kind: 'function'},
585
602
  {name: 'SEARCH_EXCLUDER_DEFAULT', kind: 'variable'},
586
603
  {name: 'EXPORTS_EXCLUDER_DEFAULT', kind: 'variable'},
587
- {name: 'normalize_gro_config', kind: 'function'},
604
+ {name: 'cook_gro_config', kind: 'function'},
588
605
  {name: 'Gro_Config_Module', kind: 'type'},
589
606
  {name: 'load_gro_config', kind: 'function'},
590
607
  {name: 'validate_gro_config_module', kind: 'function'},
@@ -872,13 +889,6 @@ export const src_json: Src_Json = {
872
889
  './sveltekit_helpers.js': {
873
890
  path: 'sveltekit_helpers.ts',
874
891
  declarations: [
875
- {name: 'SVELTEKIT_CLI', kind: 'variable'},
876
- {name: 'SVELTE_CHECK_CLI', kind: 'variable'},
877
- {name: 'SVELTE_PACKAGE_CLI', kind: 'variable'},
878
- {name: 'SVELTE_PACKAGE_DEP_NAME', kind: 'variable'},
879
- {name: 'VITE_CLI', kind: 'variable'},
880
- {name: 'SVELTEKIT_ENV_MATCHER', kind: 'variable'},
881
- {name: 'SVELTEKIT_GLOBAL_SPECIFIER', kind: 'variable'},
882
892
  {name: 'has_sveltekit_app', kind: 'function'},
883
893
  {name: 'has_sveltekit_library', kind: 'function'},
884
894
  {name: 'sveltekit_sync', kind: 'function'},
@@ -994,6 +1004,7 @@ export const src_json: Src_Json = {
994
1004
  './test_helpers.js': {
995
1005
  path: 'test_helpers.ts',
996
1006
  declarations: [
1007
+ {name: 'TEST_TIMEOUT_MD', kind: 'variable'},
997
1008
  {name: 'SOME_PUBLIC_ENV_VAR_NAME', kind: 'variable'},
998
1009
  {name: 'SOME_PUBLIC_ENV_VAR_VALUE', kind: 'variable'},
999
1010
  {name: 'init_test_env', kind: 'function'},
@@ -7,7 +7,7 @@ import {styleText as st} from 'node:util';
7
7
  import {Package_Json, Package_Json_Exports} from '@ryanatkn/belt/package_json.js';
8
8
 
9
9
  import {paths, gro_paths, IS_THIS_GRO, replace_extension} from './paths.ts';
10
- import {SVELTEKIT_DIST_DIRNAME} from './constants.ts';
10
+ import {PACKAGE_JSON_FILENAME, SVELTEKIT_DIST_DIRNAME} from './constants.ts';
11
11
  import {search_fs} from './search_fs.ts';
12
12
  import {has_sveltekit_library} from './sveltekit_helpers.ts';
13
13
  import {GITHUB_REPO_MATCHER} from './github.ts';
@@ -22,6 +22,7 @@ export const load_package_json = (
22
22
  dir = IS_THIS_GRO ? gro_paths.root : paths.root,
23
23
  cache?: Record<string, Package_Json>,
24
24
  parse = true, // TODO pass `false` here in more places, especially anything perf-sensitive like work on startup
25
+ log?: Logger,
25
26
  ): Package_Json => {
26
27
  let package_json: Package_Json;
27
28
  if (cache && dir in cache) {
@@ -29,7 +30,8 @@ export const load_package_json = (
29
30
  }
30
31
  try {
31
32
  package_json = JSON.parse(load_package_json_contents(dir));
32
- } catch (_err) {
33
+ } catch (err) {
34
+ log?.error(st('yellow', `Failed to load package.json in ${dir}`), err);
33
35
  return EMPTY_PACKAGE_JSON;
34
36
  }
35
37
  if (parse) {
@@ -44,14 +46,13 @@ export const load_package_json = (
44
46
  export const sync_package_json = async (
45
47
  map_package_json: Map_Package_Json,
46
48
  log: Logger,
47
- check = false,
49
+ write = true,
48
50
  dir = paths.root,
49
51
  exports_dir = paths.lib,
50
52
  ): Promise<{package_json: Package_Json | null; changed: boolean}> => {
51
53
  const exported_files = search_fs(exports_dir);
52
54
  const exported_paths = exported_files.map((f) => f.path);
53
55
  const updated = await update_package_json(
54
- dir,
55
56
  async (package_json) => {
56
57
  if (has_sveltekit_library(package_json).ok) {
57
58
  const exports = to_package_exports(exported_paths);
@@ -60,7 +61,8 @@ export const sync_package_json = async (
60
61
  const mapped = await map_package_json(package_json);
61
62
  return mapped ? parse_package_json(Package_Json, mapped) : mapped;
62
63
  },
63
- !check,
64
+ dir,
65
+ write,
64
66
  );
65
67
 
66
68
  const exports_count =
@@ -80,10 +82,10 @@ export const load_gro_package_json = (): Package_Json => load_package_json(gro_p
80
82
 
81
83
  // TODO probably make this nullable and make callers handle failures
82
84
  const load_package_json_contents = (dir: string): string =>
83
- readFileSync(join(dir, 'package.json'), 'utf8');
85
+ readFileSync(join(dir, PACKAGE_JSON_FILENAME), 'utf8');
84
86
 
85
87
  export const write_package_json = (serialized_package_json: string): void => {
86
- writeFileSync(join(paths.root, 'package.json'), serialized_package_json);
88
+ writeFileSync(join(paths.root, PACKAGE_JSON_FILENAME), serialized_package_json);
87
89
  };
88
90
 
89
91
  export const serialize_package_json = (package_json: Package_Json): string =>
@@ -93,8 +95,8 @@ export const serialize_package_json = (package_json: Package_Json): string =>
93
95
  * Updates package.json. Writes to the filesystem only when contents change.
94
96
  */
95
97
  export const update_package_json = async (
96
- dir = paths.root,
97
98
  update: (package_json: Package_Json) => Package_Json | null | Promise<Package_Json | null>,
99
+ dir = paths.root,
98
100
  write = true,
99
101
  ): Promise<{package_json: Package_Json | null; changed: boolean}> => {
100
102
  const original_contents = load_package_json_contents(dir);
@@ -186,7 +188,7 @@ export const parse_repo_url = (
186
188
  * Parses a `Package_Json` object but preserves the order of the original keys.
187
189
  */
188
190
  const parse_package_json = (schema: typeof Package_Json, value: any): Package_Json => {
189
- const parsed = parse_or_throw_formatted_error('package.json', schema, value);
191
+ const parsed = parse_or_throw_formatted_error(PACKAGE_JSON_FILENAME, schema, value);
190
192
  const keys = Object.keys(value);
191
193
  return Object.fromEntries(
192
194
  Object.entries(parsed).sort(([a], [b]) => keys.indexOf(a) - keys.indexOf(b)),
@@ -124,7 +124,7 @@ export const parse_imports = (
124
124
 
125
125
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
126
126
  if (node.source.type === 'Literal') {
127
- const value = String(node.source.value);
127
+ const value = node.source.value;
128
128
  if (value) {
129
129
  specifiers.push(value);
130
130
  }
@@ -136,7 +136,7 @@ export const parse_imports = (
136
136
  };
137
137
 
138
138
  if (is_svelte) {
139
- // Reset the regex state between calls
139
+ // Reset the regexp state between calls
140
140
  SVELTE_SCRIPT_MATCHER.lastIndex = 0;
141
141
 
142
142
  // Capture script tags at the top level (not nested in HTML)
package/src/lib/paths.ts CHANGED
@@ -4,7 +4,7 @@ import {ensure_end, strip_end} from '@ryanatkn/belt/string.js';
4
4
  import {styleText as st} from 'node:util';
5
5
 
6
6
  import {
7
- GRO_CONFIG_PATH,
7
+ GRO_CONFIG_FILENAME,
8
8
  GRO_DEV_DIR,
9
9
  GRO_DIR,
10
10
  SOURCE_DIR,
@@ -49,7 +49,7 @@ export const create_paths = (root_dir: string): Paths => {
49
49
  lib: root + LIB_DIR,
50
50
  build: root + GRO_DIR,
51
51
  build_dev: root + GRO_DEV_DIR,
52
- config: root + GRO_CONFIG_PATH,
52
+ config: root + GRO_CONFIG_FILENAME,
53
53
  };
54
54
  };
55
55
 
@@ -30,7 +30,7 @@ export const task: Task<Args> = {
30
30
  );
31
31
  }
32
32
 
33
- // TODO this relies on npm behavior that changed in v11
33
+ // TODO @many this relies on npm behavior that changed in v11
34
34
  // Deleting the lockfile and reinstalling cleans the lockfile of unnecessary dep noise,
35
35
  // like esbuild's many packages for each platform.
36
36
  await rm(LOCKFILE_FILENAME);
@@ -4,6 +4,8 @@ import {existsSync} from 'node:fs';
4
4
  import {replace_extension} from './paths.ts';
5
5
  import type {Path_Id} from './path.ts';
6
6
 
7
+ // TODO ideally this module doesnt exist, but import.meta.resolve doesn't work in loaders last I tried
8
+
7
9
  export interface Resolved_Specifier {
8
10
  /**
9
11
  * The resolved filesystem path for the specifier.
@@ -7,6 +7,7 @@ import {Src_Json, Src_Modules} from '@ryanatkn/belt/src_json.js';
7
7
 
8
8
  import {paths, replace_extension} from './paths.ts';
9
9
  import {parse_exports} from './parse_exports.ts';
10
+ import {TS_MATCHER} from './constants.ts';
10
11
 
11
12
  export type Map_Src_Json = (src_json: Src_Json) => Src_Json | null | Promise<Src_Json | null>;
12
13
 
@@ -48,6 +49,7 @@ export const to_src_modules = (
48
49
  continue;
49
50
  }
50
51
 
52
+ // TODO still an error for unknown files running `gro gen`, can it use the filer to invalidate correctly?
51
53
  throw Error(
52
54
  `Failed to infer source file from package.json export path ${k} - the inferred file ${source_file_id} does not exist`,
53
55
  );
@@ -58,7 +60,7 @@ export const to_src_modules = (
58
60
 
59
61
  // Create a TypeScript program for all TypeScript files
60
62
  const ts_files = file_paths
61
- .filter(({file_path}) => file_path.endsWith('.ts') || file_path.endsWith('.tsx'))
63
+ .filter(({file_path}) => TS_MATCHER.test(file_path))
62
64
  .map(({file_path}) => file_path);
63
65
 
64
66
  let program: ts.Program | undefined;
@@ -5,6 +5,9 @@ import {EMPTY_OBJECT} from '@ryanatkn/belt/object.js';
5
5
 
6
6
  import {SVELTE_CONFIG_FILENAME} from './constants.ts';
7
7
 
8
+ /* eslint-disable @typescript-eslint/no-deprecated */
9
+ // see https://github.com/sveltejs/kit/discussions/14240
10
+
8
11
  /*
9
12
 
10
13
  This module is intended to have minimal dependencies to avoid over-imports in the CLI.
@@ -6,23 +6,17 @@ import type {Package_Json} from '@ryanatkn/belt/package_json.js';
6
6
 
7
7
  import {has_dep} from './package_json.ts';
8
8
  import {default_svelte_config, type Parsed_Svelte_Config} from './svelte_config.ts';
9
- import {SVELTE_CONFIG_FILENAME, SVELTEKIT_DEV_DIRNAME, PM_CLI_DEFAULT} from './constants.ts';
9
+ import {
10
+ SVELTE_CONFIG_FILENAME,
11
+ SVELTEKIT_DEV_DIRNAME,
12
+ PM_CLI_DEFAULT,
13
+ SVELTE_PACKAGE_DEP_NAME,
14
+ SVELTEKIT_CLI,
15
+ } from './constants.ts';
10
16
  import {find_cli, spawn_cli, to_cli_name, type Cli} from './cli.ts';
11
17
  import {Task_Error} from './task.ts';
12
18
  import {serialize_args, to_forwarded_args} from './args.ts';
13
19
 
14
- export const SVELTEKIT_CLI = 'svelte-kit';
15
-
16
- export const SVELTE_CHECK_CLI = 'svelte-check';
17
-
18
- export const SVELTE_PACKAGE_CLI = 'svelte-package';
19
- export const SVELTE_PACKAGE_DEP_NAME = '@sveltejs/package';
20
-
21
- export const VITE_CLI = 'vite';
22
-
23
- export const SVELTEKIT_ENV_MATCHER = /^\$env\/(static|dynamic)\/(public|private)$/;
24
- export const SVELTEKIT_GLOBAL_SPECIFIER = /^\$(env|app)\//;
25
-
26
20
  export const has_sveltekit_app = (
27
21
  svelte_config_path: string = SVELTE_CONFIG_FILENAME,
28
22
  ): Result<object, {message: string}> => {
@@ -12,8 +12,7 @@ export const Args = z.strictObject({
12
12
  'no-package_json': z.boolean().meta({description: 'opt out of package.json sync'}).default(false),
13
13
  gen: z.boolean().meta({description: 'dual of no-gen'}).default(true),
14
14
  'no-gen': z.boolean().meta({description: 'opt out of running gen'}).default(false),
15
- install: z.boolean().meta({description: 'dual of no-install'}).default(true),
16
- 'no-install': z.boolean().meta({description: 'opt out of installing packages'}).default(false),
15
+ install: z.boolean().meta({description: 'opt into installing packages'}).default(false),
17
16
  });
18
17
  export type Args = z.infer<typeof Args>;
19
18
 
package/src/lib/task.ts CHANGED
@@ -37,8 +37,6 @@ export interface Task_Context<T_Args = object> {
37
37
  config: Gro_Config;
38
38
  svelte_config: Parsed_Svelte_Config;
39
39
  filer: Filer;
40
- // TODO should this go here or on `config` for convenience?
41
- // svelte_config: Parsed_Svelte_Config;
42
40
  log: Logger;
43
41
  timings: Timings;
44
42
  invoke_task: (task_name: string, args?: Args, config?: Gro_Config) => Promise<void>;
@@ -1,50 +1,49 @@
1
- import {styleText as st} from 'node:util';
2
1
  import {z} from 'zod';
2
+ import {spawn_cli} from '@ryanatkn/gro/cli.js';
3
3
 
4
4
  import {Task_Error, type Task} from './task.ts';
5
- import {paths} from './paths.ts';
6
5
  import {find_cli} from './cli.ts';
6
+ import {has_dep} from './package_json.ts';
7
+ import {serialize_args, to_forwarded_args} from './args.ts';
8
+ import {VITEST_CLI} from './constants.ts';
9
+ import {paths} from './paths.ts';
7
10
 
8
11
  export const Args = z.strictObject({
9
- _: z.array(z.string()).meta({description: 'file patterns to test'}).default([`\\.test\\.ts$`]), // TODO maybe use uvu's default instead of being restrictive?
10
- bail: z
11
- .boolean()
12
- .meta({description: 'the bail option to uvu run, exit immediately on failure'})
13
- .default(false),
14
- cwd: z.string().meta({description: 'the cwd option to uvu parse'}).optional(),
15
- ignore: z
16
- .union([z.string(), z.array(z.string())])
17
- .meta({description: 'the ignore option to uvu parse'})
12
+ _: z.array(z.string()).meta({description: 'file patterns to test'}).default(['.test.']),
13
+ dir: z.string().meta({description: 'working directory for tests'}).default(paths.source),
14
+ t: z
15
+ .string()
16
+ .meta({description: 'search pattern for test names, same as vitest -t and --testNamePattern'})
18
17
  .optional(),
19
18
  });
20
19
  export type Args = z.infer<typeof Args>;
21
20
 
22
21
  export const task: Task<Args> = {
23
- summary: 'run tests with uvu',
22
+ summary: 'run tests with vitest',
24
23
  Args,
25
- run: async ({args, log}): Promise<void> => {
26
- const {_: patterns, bail, cwd, ignore} = args;
24
+ run: async ({args}): Promise<void> => {
25
+ const {_: patterns, dir, t} = args;
27
26
 
28
- if (!find_cli('uvu')) {
29
- log.warn(st('yellow', 'uvu is not installed, skipping tests'));
30
- return;
31
- }
27
+ if (has_dep(VITEST_CLI)) {
28
+ if (!find_cli(VITEST_CLI)) {
29
+ throw new Task_Error('vitest is a dependency but not installed; run `npm i`?');
30
+ }
32
31
 
33
- const [{run}, {parse}] = await Promise.all([import('uvu/run'), import('uvu/parse')]);
34
-
35
- // uvu doesn't work with esm loaders and TypeScript files,
36
- // so we use its `parse` and `run` APIs directly instead of its CLI.
37
- // To avoid surprises, we allow any number of patterns in the rest args,
38
- // so we call `parse` multiple times because it supports only one.
39
- const suites = [];
40
- for (const pattern of patterns) {
41
- const parsed = await parse(paths.source, pattern, {cwd, ignore}); // eslint-disable-line no-await-in-loop
42
- suites.push(...parsed.suites);
43
- }
44
- await run(suites, {bail});
32
+ const vitest_args = ['run', ...patterns];
33
+ if (dir) {
34
+ vitest_args.push('--dir', dir);
35
+ }
36
+ if (t) {
37
+ vitest_args.push('-t', t);
38
+ }
39
+ vitest_args.push(...serialize_args(to_forwarded_args(VITEST_CLI)));
45
40
 
46
- if (process.exitCode) {
47
- throw new Task_Error('Tests failed.');
41
+ const spawned = await spawn_cli(VITEST_CLI, vitest_args); // TODO proper forwarding
42
+ if (!spawned?.ok) {
43
+ throw new Task_Error(`vitest failed with exit code ${spawned?.code}`);
44
+ }
45
+ } else {
46
+ throw new Task_Error('no test runner found, install vitest');
48
47
  }
49
48
  },
50
49
  };
@@ -2,6 +2,8 @@ import {existsSync, readFileSync, writeFileSync} from 'node:fs';
2
2
  import {join} from 'node:path';
3
3
  import ts from 'typescript';
4
4
 
5
+ export const TEST_TIMEOUT_MD = 20_000;
6
+
5
7
  export const SOME_PUBLIC_ENV_VAR_NAME = 'PUBLIC_SOME_PUBLIC_ENV_VAR';
6
8
  export const SOME_PUBLIC_ENV_VAR_VALUE = 'SOME_PUBLIC_ENV_VAR';
7
9
  const name_equals = SOME_PUBLIC_ENV_VAR_NAME + '=';
@@ -4,9 +4,10 @@ import {z} from 'zod';
4
4
  import {Task_Error, type Task} from './task.ts';
5
5
  import {serialize_args, to_forwarded_args} from './args.ts';
6
6
  import {find_cli, spawn_cli, spawn_cli_process} from './cli.ts';
7
- import {SVELTE_CHECK_CLI, sveltekit_sync_if_available} from './sveltekit_helpers.ts';
7
+ import {sveltekit_sync_if_available} from './sveltekit_helpers.ts';
8
8
  import {configure_colored_output_with_path_replacement} from './child_process_logging.ts';
9
9
  import {paths} from './paths.ts';
10
+ import {SVELTE_CHECK_CLI} from './constants.ts';
10
11
 
11
12
  export const Args = z.strictObject({
12
13
  svelte_check_cli: z
@@ -110,6 +110,7 @@ export const task: Task<Args> = {
110
110
  install_args.push(...serialize_args(to_forwarded_args(config.pm_cli)));
111
111
  await spawn(config.pm_cli, install_args);
112
112
 
113
+ // TODO @many this relies on npm behavior that changed in v11
113
114
  // If we deleted the lockfile or node modules, `npm install` again
114
115
  // to fix a recurring npm bug getting the lockfile to its final state.
115
116
  if (!dry && (delete_node_modules || delete_lockfile)) {
@@ -118,7 +119,7 @@ export const task: Task<Args> = {
118
119
  }
119
120
 
120
121
  // Sync in a new process to pick up any changes after installing, avoiding some errors.
121
- await spawn_cli('gro', ['sync', '--no-install']); // don't install because we do above
122
+ await spawn_cli('gro', ['sync']); // don't install because we do above
122
123
  },
123
124
  };
124
125