@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.
Files changed (222) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +257 -0
  3. package/dist/args.d.ts +59 -0
  4. package/dist/args.js +132 -0
  5. package/dist/args.test.d.ts +1 -0
  6. package/dist/args.test.js +43 -0
  7. package/dist/build.task.d.ts +11 -0
  8. package/dist/build.task.js +24 -0
  9. package/dist/changelog.d.ts +8 -0
  10. package/dist/changelog.js +47 -0
  11. package/dist/changelog.test.d.ts +1 -0
  12. package/dist/changelog.test.js +118 -0
  13. package/dist/changeset.task.d.ts +49 -0
  14. package/dist/changeset.task.js +141 -0
  15. package/dist/check.task.d.ts +47 -0
  16. package/dist/check.task.js +77 -0
  17. package/dist/clean.task.d.ts +26 -0
  18. package/dist/clean.task.js +41 -0
  19. package/dist/clean_fs.d.ts +9 -0
  20. package/dist/clean_fs.js +27 -0
  21. package/dist/cli.d.ts +11 -0
  22. package/dist/cli.js +25 -0
  23. package/dist/commit.task.d.ts +11 -0
  24. package/dist/commit.task.js +22 -0
  25. package/dist/config.d.ts +21 -0
  26. package/dist/config.js +42 -0
  27. package/dist/config.test.d.ts +1 -0
  28. package/dist/config.test.js +8 -0
  29. package/dist/deploy.task.d.ts +47 -0
  30. package/dist/deploy.task.js +198 -0
  31. package/dist/dev.task.d.ts +22 -0
  32. package/dist/dev.task.js +32 -0
  33. package/dist/docs/README.gen.md.d.ts +5 -0
  34. package/dist/docs/README.gen.md.js +53 -0
  35. package/dist/docs/README.md +20 -0
  36. package/dist/docs/build.md +41 -0
  37. package/dist/docs/config.md +162 -0
  38. package/dist/docs/deploy.md +32 -0
  39. package/dist/docs/dev.md +40 -0
  40. package/dist/docs/gen.md +241 -0
  41. package/dist/docs/gro_plugin_sveltekit_frontend.md +97 -0
  42. package/dist/docs/package_json.md +29 -0
  43. package/dist/docs/plugin.md +50 -0
  44. package/dist/docs/publish.md +144 -0
  45. package/dist/docs/task.md +377 -0
  46. package/dist/docs/tasks.gen.md.d.ts +2 -0
  47. package/dist/docs/tasks.gen.md.js +60 -0
  48. package/dist/docs/tasks.md +35 -0
  49. package/dist/docs/test.md +52 -0
  50. package/dist/env.d.ts +10 -0
  51. package/dist/env.js +47 -0
  52. package/dist/esbuild_helpers.d.ts +14 -0
  53. package/dist/esbuild_helpers.js +36 -0
  54. package/dist/esbuild_plugin_external_worker.d.ts +22 -0
  55. package/dist/esbuild_plugin_external_worker.js +49 -0
  56. package/dist/esbuild_plugin_svelte.d.ts +9 -0
  57. package/dist/esbuild_plugin_svelte.js +49 -0
  58. package/dist/esbuild_plugin_sveltekit_local_imports.d.ts +7 -0
  59. package/dist/esbuild_plugin_sveltekit_local_imports.js +30 -0
  60. package/dist/esbuild_plugin_sveltekit_shim_alias.d.ts +6 -0
  61. package/dist/esbuild_plugin_sveltekit_shim_alias.js +16 -0
  62. package/dist/esbuild_plugin_sveltekit_shim_app.d.ts +8 -0
  63. package/dist/esbuild_plugin_sveltekit_shim_app.js +23 -0
  64. package/dist/esbuild_plugin_sveltekit_shim_env.d.ts +10 -0
  65. package/dist/esbuild_plugin_sveltekit_shim_env.js +18 -0
  66. package/dist/format.task.d.ts +11 -0
  67. package/dist/format.task.js +24 -0
  68. package/dist/format_directory.d.ts +2 -0
  69. package/dist/format_directory.js +27 -0
  70. package/dist/format_file.d.ts +8 -0
  71. package/dist/format_file.js +42 -0
  72. package/dist/format_file.test.d.ts +1 -0
  73. package/dist/format_file.test.js +16 -0
  74. package/dist/fs.d.ts +7 -0
  75. package/dist/fs.js +19 -0
  76. package/dist/fs.test.d.ts +1 -0
  77. package/dist/fs.test.js +16 -0
  78. package/dist/gen.d.ts +57 -0
  79. package/dist/gen.js +81 -0
  80. package/dist/gen.task.d.ts +14 -0
  81. package/dist/gen.task.js +103 -0
  82. package/dist/gen.test.d.ts +1 -0
  83. package/dist/gen.test.js +239 -0
  84. package/dist/gen_module.d.ts +46 -0
  85. package/dist/gen_module.js +54 -0
  86. package/dist/gen_module.test.d.ts +1 -0
  87. package/dist/gen_module.test.js +30 -0
  88. package/dist/git.d.ts +76 -0
  89. package/dist/git.js +200 -0
  90. package/dist/git.test.d.ts +1 -0
  91. package/dist/git.test.js +18 -0
  92. package/dist/github.d.ts +35 -0
  93. package/dist/github.js +32 -0
  94. package/dist/gro.config.default.d.ts +12 -0
  95. package/dist/gro.config.default.js +31 -0
  96. package/dist/gro.d.ts +2 -0
  97. package/dist/gro.js +19 -0
  98. package/dist/gro_helpers.d.ts +43 -0
  99. package/dist/gro_helpers.js +79 -0
  100. package/dist/gro_plugin_gen.d.ts +6 -0
  101. package/dist/gro_plugin_gen.js +80 -0
  102. package/dist/gro_plugin_server.d.ts +77 -0
  103. package/dist/gro_plugin_server.js +152 -0
  104. package/dist/gro_plugin_sveltekit_app.d.ts +27 -0
  105. package/dist/gro_plugin_sveltekit_app.js +180 -0
  106. package/dist/gro_plugin_sveltekit_library.d.ts +4 -0
  107. package/dist/gro_plugin_sveltekit_library.js +42 -0
  108. package/dist/hash.d.ts +5 -0
  109. package/dist/hash.js +14 -0
  110. package/dist/hash.test.d.ts +1 -0
  111. package/dist/hash.test.js +25 -0
  112. package/dist/index.d.ts +4 -0
  113. package/dist/index.js +3 -0
  114. package/dist/input_path.d.ts +48 -0
  115. package/dist/input_path.js +161 -0
  116. package/dist/input_path.test.d.ts +1 -0
  117. package/dist/input_path.test.js +106 -0
  118. package/dist/invoke.d.ts +1 -0
  119. package/dist/invoke.js +18 -0
  120. package/dist/invoke_task.d.ts +20 -0
  121. package/dist/invoke_task.js +140 -0
  122. package/dist/lint.task.d.ts +11 -0
  123. package/dist/lint.task.js +29 -0
  124. package/dist/loader.d.ts +4 -0
  125. package/dist/loader.js +153 -0
  126. package/dist/module.d.ts +3 -0
  127. package/dist/module.js +6 -0
  128. package/dist/module.test.d.ts +1 -0
  129. package/dist/module.test.js +41 -0
  130. package/dist/modules.d.ts +60 -0
  131. package/dist/modules.js +103 -0
  132. package/dist/modules.test.d.ts +1 -0
  133. package/dist/modules.test.js +182 -0
  134. package/dist/package.d.ts +939 -0
  135. package/dist/package.gen.d.ts +7 -0
  136. package/dist/package.gen.js +26 -0
  137. package/dist/package.js +887 -0
  138. package/dist/package_json.d.ts +342 -0
  139. package/dist/package_json.js +212 -0
  140. package/dist/package_json.test.d.ts +1 -0
  141. package/dist/package_json.test.js +77 -0
  142. package/dist/path.d.ts +12 -0
  143. package/dist/path.js +8 -0
  144. package/dist/paths.d.ts +60 -0
  145. package/dist/paths.js +128 -0
  146. package/dist/paths.test.d.ts +1 -0
  147. package/dist/paths.test.js +49 -0
  148. package/dist/plugin.d.ts +36 -0
  149. package/dist/plugin.js +80 -0
  150. package/dist/plugin.test.d.ts +1 -0
  151. package/dist/plugin.test.js +54 -0
  152. package/dist/print_task.d.ts +4 -0
  153. package/dist/print_task.js +124 -0
  154. package/dist/publish.task.d.ts +32 -0
  155. package/dist/publish.task.js +125 -0
  156. package/dist/release.task.d.ts +5 -0
  157. package/dist/release.task.js +18 -0
  158. package/dist/resolve_node_specifier.d.ts +8 -0
  159. package/dist/resolve_node_specifier.js +39 -0
  160. package/dist/resolve_node_specifier.test.d.ts +1 -0
  161. package/dist/resolve_node_specifier.test.js +21 -0
  162. package/dist/resolve_specifier.d.ts +15 -0
  163. package/dist/resolve_specifier.js +51 -0
  164. package/dist/resolve_specifier.test.d.ts +1 -0
  165. package/dist/resolve_specifier.test.js +66 -0
  166. package/dist/run.task.d.ts +11 -0
  167. package/dist/run.task.js +31 -0
  168. package/dist/run_gen.d.ts +6 -0
  169. package/dist/run_gen.js +74 -0
  170. package/dist/run_gen.test.d.ts +1 -0
  171. package/dist/run_gen.test.js +182 -0
  172. package/dist/run_task.d.ts +13 -0
  173. package/dist/run_task.js +44 -0
  174. package/dist/run_task.test.d.ts +1 -0
  175. package/dist/run_task.test.js +63 -0
  176. package/dist/search_fs.d.ts +11 -0
  177. package/dist/search_fs.js +22 -0
  178. package/dist/search_fs.test.d.ts +1 -0
  179. package/dist/search_fs.test.js +46 -0
  180. package/dist/src_json.d.ts +256 -0
  181. package/dist/src_json.js +110 -0
  182. package/dist/src_json.test.d.ts +1 -0
  183. package/dist/src_json.test.js +52 -0
  184. package/dist/sveltekit_config.d.ts +36 -0
  185. package/dist/sveltekit_config.js +51 -0
  186. package/dist/sveltekit_shim_app.d.ts +10 -0
  187. package/dist/sveltekit_shim_app.js +31 -0
  188. package/dist/sveltekit_shim_app_environment.d.ts +10 -0
  189. package/dist/sveltekit_shim_app_environment.js +12 -0
  190. package/dist/sveltekit_shim_app_forms.d.ts +5 -0
  191. package/dist/sveltekit_shim_app_forms.js +13 -0
  192. package/dist/sveltekit_shim_app_navigation.d.ts +10 -0
  193. package/dist/sveltekit_shim_app_navigation.js +11 -0
  194. package/dist/sveltekit_shim_app_paths.d.ts +11 -0
  195. package/dist/sveltekit_shim_app_paths.js +6 -0
  196. package/dist/sveltekit_shim_app_stores.d.ts +6 -0
  197. package/dist/sveltekit_shim_app_stores.js +17 -0
  198. package/dist/sveltekit_shim_env.d.ts +4 -0
  199. package/dist/sveltekit_shim_env.js +23 -0
  200. package/dist/sync.task.d.ts +30 -0
  201. package/dist/sync.task.js +45 -0
  202. package/dist/task.d.ts +29 -0
  203. package/dist/task.js +17 -0
  204. package/dist/task.test.d.ts +1 -0
  205. package/dist/task.test.js +22 -0
  206. package/dist/task_module.d.ts +14 -0
  207. package/dist/task_module.js +19 -0
  208. package/dist/task_module.test.d.ts +1 -0
  209. package/dist/task_module.test.js +70 -0
  210. package/dist/test.task.d.ts +20 -0
  211. package/dist/test.task.js +43 -0
  212. package/dist/throttle.d.ts +16 -0
  213. package/dist/throttle.js +59 -0
  214. package/dist/throttle.test.d.ts +1 -0
  215. package/dist/throttle.test.js +49 -0
  216. package/dist/typecheck.task.d.ts +5 -0
  217. package/dist/typecheck.task.js +38 -0
  218. package/dist/upgrade.task.d.ts +14 -0
  219. package/dist/upgrade.task.js +37 -0
  220. package/dist/watch_dir.d.ts +30 -0
  221. package/dist/watch_dir.js +59 -0
  222. package/package.json +422 -0
@@ -0,0 +1,125 @@
1
+ import { spawn } from '@ryanatkn/belt/process.js';
2
+ import { z } from 'zod';
3
+ import { green, cyan } from 'kleur/colors';
4
+ import { Task_Error } from './task.js';
5
+ import { load_package_json, parse_repo_url } from './package_json.js';
6
+ import { find_cli, spawn_cli } from './cli.js';
7
+ import { exists } from './fs.js';
8
+ import { is_this_project_gro } from './paths.js';
9
+ import { has_sveltekit_library } from './gro_plugin_sveltekit_library.js';
10
+ import { update_changelog } from './changelog.js';
11
+ import { load_from_env } from './env.js';
12
+ // publish.task.ts
13
+ // - usage: `gro publish patch`
14
+ // - forwards args to `npm version`: https://docs.npmjs.com/v6/commands/npm-version
15
+ // - runs the production build
16
+ // - publishes to npm from the `main` branch, configurable with `--branch`
17
+ // - syncs commits and tags to the configured main branch
18
+ export const Args = z
19
+ .object({
20
+ branch: z.string({ description: 'branch to publish from' }).default('main'),
21
+ changelog: z
22
+ .string({ description: 'file name and path of the changelog' })
23
+ .default('CHANGELOG.md'),
24
+ preserve_changelog: z
25
+ .boolean({
26
+ description: 'opt out of linkifying and formatting the changelog from @changesets/changelog-git',
27
+ })
28
+ .default(false),
29
+ dry: z
30
+ .boolean({ description: 'build and prepare to publish without actually publishing' })
31
+ .default(false),
32
+ check: z.boolean({ description: 'dual of no-check' }).default(true),
33
+ 'no-check': z
34
+ .boolean({ description: 'opt out of npm checking before publishing' })
35
+ .default(false),
36
+ install: z.boolean({ description: 'dual of no-install' }).default(true),
37
+ 'no-install': z
38
+ .boolean({ description: 'opt out of npm installing before building' })
39
+ .default(false),
40
+ })
41
+ .strict();
42
+ export const task = {
43
+ summary: 'bump version, publish to npm, and git push',
44
+ Args,
45
+ run: async ({ args, log, invoke_task }) => {
46
+ const { branch, changelog, preserve_changelog, dry, check, install } = args;
47
+ if (dry) {
48
+ log.info(green('dry run!'));
49
+ }
50
+ if (!(await has_sveltekit_library())) {
51
+ throw new Task_Error('gro publish failed to detect a library, run `npm i -D @sveltejs/package` to enable it');
52
+ }
53
+ // TODO hacky, ensures Gro bootstraps itself
54
+ if (is_this_project_gro) {
55
+ await spawn('npm', ['run', 'build']);
56
+ }
57
+ const changelog_exists = await exists(changelog);
58
+ if (!(await find_cli('changeset'))) {
59
+ throw new Task_Error('changeset command not found: install @changesets/cli locally or globally');
60
+ }
61
+ // Make sure we're on the right branch:
62
+ await spawn('git', ['fetch', 'origin', branch]);
63
+ await spawn('git', ['checkout', branch]);
64
+ await spawn('git', ['pull', 'origin', branch]);
65
+ // Check before proceeding.
66
+ if (check) {
67
+ await invoke_task('check', { workspace: true });
68
+ }
69
+ let version;
70
+ // Bump the version so the package.json is updated before building:
71
+ // TODO problem here is build may fail and put us in a bad state,
72
+ // but I don't see how we could do this to robustly
73
+ // have the new version in the build without building twice -
74
+ // maybe the code should catch the error and revert the version and delete the tag?
75
+ if (dry) {
76
+ log.info('dry run, skipping changeset version');
77
+ }
78
+ else {
79
+ const package_json_before = await load_package_json();
80
+ if (typeof package_json_before.version !== 'string') {
81
+ throw new Task_Error('failed to find package.json version');
82
+ }
83
+ const parsed_repo_url = parse_repo_url(package_json_before);
84
+ if (!parsed_repo_url) {
85
+ throw new Task_Error('package.json `repository` must contain a repo url (and GitHub only for now, sorry),' +
86
+ ' like `git+https://github.com/ryanatkn/gro.git` or `https://github.com/ryanatkn/gro`' +
87
+ ' or an object with the `url` key');
88
+ }
89
+ // This is the first line that alters the repo.
90
+ const npmVersionResult = await spawn_cli('changeset', ['version']);
91
+ if (!npmVersionResult?.ok) {
92
+ throw Error('npm version failed: no commits were made: see the error above');
93
+ }
94
+ if (!preserve_changelog) {
95
+ const token = await load_from_env('GITHUB_TOKEN_SECRET');
96
+ if (!token) {
97
+ log.warn('the env var GITHUB_TOKEN_SECRET was not found, so API calls with be unauthorized');
98
+ }
99
+ await update_changelog(parsed_repo_url.owner, parsed_repo_url.repo, changelog, token, log);
100
+ }
101
+ const package_json_after = await load_package_json();
102
+ version = package_json_after.version;
103
+ if (package_json_before.version === version) {
104
+ throw new Task_Error('changeset version failed: are there any changes?');
105
+ }
106
+ }
107
+ // Build to create the final artifacts:
108
+ await invoke_task('build', { install });
109
+ if (dry) {
110
+ log.info('publishing branch ' + branch);
111
+ log.info(green('dry run complete!'));
112
+ return;
113
+ }
114
+ const npm_publish_result = await spawn_cli('changeset', ['publish']);
115
+ if (!npm_publish_result?.ok) {
116
+ throw new Task_Error('changeset publish failed - revert the version tag or run it again manually');
117
+ }
118
+ if (!changelog_exists && (await exists(changelog))) {
119
+ await spawn('git', ['add', changelog]);
120
+ }
121
+ await spawn('git', ['commit', '-a', '-m', `publish v${version}`]);
122
+ await spawn('git', ['push', '--follow-tags']);
123
+ log.info(green(`published to branch ${cyan(branch)}!`));
124
+ },
125
+ };
@@ -0,0 +1,5 @@
1
+ import { z } from 'zod';
2
+ import type { Task } from './task.js';
3
+ export declare const Args: z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>;
4
+ export type Args = z.infer<typeof Args>;
5
+ export declare const task: Task<Args>;
@@ -0,0 +1,18 @@
1
+ import { z } from 'zod';
2
+ import { has_sveltekit_library } from './gro_plugin_sveltekit_library.js';
3
+ import { has_sveltekit_app } from './gro_plugin_sveltekit_app.js';
4
+ export const Args = z.object({}).strict();
5
+ export const task = {
6
+ summary: 'publish and deploy',
7
+ Args,
8
+ run: async ({ invoke_task }) => {
9
+ const publish = await has_sveltekit_library();
10
+ if (publish) {
11
+ await invoke_task('publish'); // TODO use `to_forwarded_args`
12
+ }
13
+ const deploy = await has_sveltekit_app();
14
+ if (deploy) {
15
+ await invoke_task('deploy', { build: !publish }); // TODO use `to_forwarded_args`
16
+ }
17
+ },
18
+ };
@@ -0,0 +1,8 @@
1
+ import { Package_Json } from './package_json.js';
2
+ import { Source_Id } from './paths.js';
3
+ export declare const resolve_node_specifier: (specifier: string, dir?: string, parent_url?: string, cache?: Record<string, Package_Json>, exports_key?: string) => Promise<Source_Id>;
4
+ export interface Parsed_Node_Specifier {
5
+ name: string;
6
+ path: string;
7
+ }
8
+ export declare const parse_node_specifier: (specifier: string) => Parsed_Node_Specifier;
@@ -0,0 +1,39 @@
1
+ import { join } from 'node:path';
2
+ import { Package_Json, load_package_json } from './package_json.js';
3
+ import { NODE_MODULES_DIRNAME, Source_Id, paths } from './paths.js';
4
+ export const resolve_node_specifier = async (specifier, dir = paths.root, parent_url, cache, exports_key = specifier.endsWith('.svelte') ? 'svelte' : 'default') => {
5
+ const parsed = parse_node_specifier(specifier);
6
+ const subpath = './' + parsed.path;
7
+ const package_dir = join(dir, NODE_MODULES_DIRNAME, parsed.name);
8
+ const package_json = await load_package_json(package_dir, cache);
9
+ const exported = package_json.exports?.[subpath];
10
+ if (!exported) {
11
+ // same error message as Node
12
+ throw Error(`[ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath '${subpath}' is not defined by "exports" in ${package_dir}/package.json` +
13
+ (parent_url ? ` imported from ${parent_url}` : ''));
14
+ }
15
+ const source_id = join(package_dir, exported[exports_key]);
16
+ return source_id;
17
+ };
18
+ export const parse_node_specifier = (specifier) => {
19
+ let idx;
20
+ if (specifier[0] === '@') {
21
+ // get the index of the second `/`
22
+ let count = 0;
23
+ for (let i = 0; i < specifier.length; i++) {
24
+ if (specifier[i] === '/')
25
+ count++;
26
+ if (count === 2) {
27
+ idx = i;
28
+ break;
29
+ }
30
+ }
31
+ }
32
+ else {
33
+ idx = specifier.indexOf('/');
34
+ }
35
+ return {
36
+ name: specifier.substring(0, idx),
37
+ path: specifier.substring(idx + 1),
38
+ };
39
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ import { test } from 'uvu';
2
+ import * as assert from 'uvu/assert';
3
+ import { resolve_node_specifier } from './resolve_node_specifier.js';
4
+ import { paths } from './paths.js';
5
+ test('resolves a JS specifier', async () => {
6
+ assert.is(await resolve_node_specifier('@fuz.dev/fuz_library/tome.js'), paths.root + 'node_modules/@fuz.dev/fuz_library/dist/tome.js');
7
+ });
8
+ test('resolves a Svelte specifier', async () => {
9
+ assert.is(await resolve_node_specifier('@fuz.dev/fuz_library/Library.svelte'), paths.root + 'node_modules/@fuz.dev/fuz_library/dist/Library.svelte');
10
+ });
11
+ test('throws for a specifier that does not exist', async () => {
12
+ let err;
13
+ try {
14
+ await resolve_node_specifier('@fuz.dev/fuz_library/this_does_not_exist');
15
+ }
16
+ catch (_err) {
17
+ err = _err;
18
+ }
19
+ assert.ok(err);
20
+ });
21
+ test.run();
@@ -0,0 +1,15 @@
1
+ export interface Resolved_Specifier {
2
+ specifier: string;
3
+ source_id: string;
4
+ namespace: undefined | 'sveltekit_local_imports_ts' | 'sveltekit_local_imports_js';
5
+ }
6
+ /**
7
+ * Maps a `path` import specifier relative to the `importer`,
8
+ * and infer the correct extension following Vite conventions.
9
+ * If no `.js` file is found for the `path` on the filesystem, it assumes `.ts`.
10
+ * @param path
11
+ * @param dir - if defined, enables relative importers like from esbuild plugins
12
+ * @param passthrough_extensions - used to support specifiers that have no file extention, which Vite supports, so we do our best effort
13
+ * @returns
14
+ */
15
+ export declare const resolve_specifier: (path: string, dir: string) => Promise<Resolved_Specifier>;
@@ -0,0 +1,51 @@
1
+ import { extname, join, relative } from 'node:path';
2
+ import { replace_extension } from './paths.js';
3
+ import { exists } from './fs.js';
4
+ /**
5
+ * Maps a `path` import specifier relative to the `importer`,
6
+ * and infer the correct extension following Vite conventions.
7
+ * If no `.js` file is found for the `path` on the filesystem, it assumes `.ts`.
8
+ * @param path
9
+ * @param dir - if defined, enables relative importers like from esbuild plugins
10
+ * @param passthrough_extensions - used to support specifiers that have no file extention, which Vite supports, so we do our best effort
11
+ * @returns
12
+ */
13
+ export const resolve_specifier = async (path, dir) => {
14
+ const path_id = path[0] === '/' ? path : join(dir, path);
15
+ let mapped_path;
16
+ let source_id;
17
+ let namespace;
18
+ const ext = extname(path_id);
19
+ const is_js = ext === '.js';
20
+ const is_ts = ext === '.ts';
21
+ if (!is_js && !is_ts && (await exists(path_id))) {
22
+ // unrecognized extension and the file exists
23
+ mapped_path = path_id;
24
+ source_id = path_id;
25
+ }
26
+ else if (is_ts) {
27
+ // explicitly ts
28
+ mapped_path = replace_extension(path_id, '.js');
29
+ source_id = path_id;
30
+ namespace = 'sveltekit_local_imports_ts';
31
+ }
32
+ else {
33
+ // extensionless, or js that points to ts, or just js
34
+ const js_id = is_js ? path_id : path_id + '.js';
35
+ const ts_id = is_js ? replace_extension(path_id, '.ts') : path_id + '.ts';
36
+ if (!(await exists(ts_id)) && (await exists(js_id))) {
37
+ mapped_path = js_id;
38
+ source_id = js_id;
39
+ namespace = 'sveltekit_local_imports_js';
40
+ }
41
+ else {
42
+ mapped_path = js_id;
43
+ source_id = ts_id;
44
+ namespace = 'sveltekit_local_imports_ts';
45
+ }
46
+ }
47
+ let specifier = relative(dir, mapped_path);
48
+ if (specifier[0] !== '.')
49
+ specifier = './' + specifier;
50
+ return { specifier, source_id, namespace };
51
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,66 @@
1
+ import { test } from 'uvu';
2
+ import * as assert from 'uvu/assert';
3
+ import { join } from 'node:path';
4
+ import { resolve_specifier } from './resolve_specifier.js';
5
+ import { paths } from './paths.js';
6
+ const dir = paths.source + 'fixtures/';
7
+ test('resolves a specifier to a file that exists with an unknown file extension', async () => {
8
+ assert.equal(await resolve_specifier(join(dir, 'test_file.other.ext'), dir), {
9
+ specifier: './test_file.other.ext',
10
+ source_id: join(dir, 'test_file.other.ext'),
11
+ namespace: undefined,
12
+ });
13
+ });
14
+ test('resolves a ts specifier', async () => {
15
+ assert.equal(await resolve_specifier(join(dir, 'test_ts.ts'), dir), {
16
+ specifier: './test_ts.js',
17
+ source_id: join(dir, 'test_ts.ts'),
18
+ namespace: 'sveltekit_local_imports_ts',
19
+ });
20
+ });
21
+ test('resolves relative ts specifiers', async () => {
22
+ assert.equal(await resolve_specifier('./test_ts.ts', dir), {
23
+ specifier: './test_ts.js',
24
+ source_id: join(dir, 'test_ts.ts'),
25
+ namespace: 'sveltekit_local_imports_ts',
26
+ });
27
+ assert.equal(await resolve_specifier('./a/b/test_ts.ts', dir), {
28
+ specifier: './a/b/test_ts.js',
29
+ source_id: join(dir, 'a/b/test_ts.ts'),
30
+ namespace: 'sveltekit_local_imports_ts',
31
+ });
32
+ assert.equal(await resolve_specifier('../../test_ts.ts', dir), {
33
+ specifier: '../../test_ts.js',
34
+ source_id: join(dir, '../../test_ts.ts'),
35
+ namespace: 'sveltekit_local_imports_ts',
36
+ });
37
+ });
38
+ test('resolves an extensionless specifier', async () => {
39
+ assert.equal(await resolve_specifier(join(dir, 'test_ts'), dir), {
40
+ specifier: './test_ts.js',
41
+ source_id: join(dir, 'test_ts.ts'),
42
+ namespace: 'sveltekit_local_imports_ts',
43
+ });
44
+ });
45
+ test('resolves a js specifier', async () => {
46
+ assert.equal(await resolve_specifier(join(dir, 'test_js.js'), dir), {
47
+ specifier: './test_js.js',
48
+ source_id: join(dir, 'test_js.js'),
49
+ namespace: 'sveltekit_local_imports_js',
50
+ });
51
+ });
52
+ test('resolves a js specifier as ts for a file that does not exist', async () => {
53
+ assert.equal(await resolve_specifier(join(dir, 'test_missing.js'), dir), {
54
+ specifier: './test_missing.js',
55
+ source_id: join(dir, 'test_missing.ts'),
56
+ namespace: 'sveltekit_local_imports_ts',
57
+ });
58
+ });
59
+ test('resolves an extensionless specifier for a file that does not exist', async () => {
60
+ assert.equal(await resolve_specifier(join(dir, 'test_missing'), dir), {
61
+ specifier: './test_missing.js',
62
+ source_id: join(dir, 'test_missing.ts'),
63
+ namespace: 'sveltekit_local_imports_ts',
64
+ });
65
+ });
66
+ test.run();
@@ -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,31 @@
1
+ import { z } from 'zod';
2
+ import { green, cyan } from 'kleur/colors';
3
+ import { Task_Error } from './task.js';
4
+ import { exists } from './fs.js';
5
+ import { resolve_gro_module_path, spawn_with_loader } from './gro_helpers.js';
6
+ export const Args = z
7
+ .object({
8
+ _: z
9
+ .array(z.string(), { description: 'the file path to run and other node CLI args' })
10
+ .default([]),
11
+ })
12
+ .strict();
13
+ export const task = {
14
+ summary: 'execute a file with the loader, like `node` but works for TypeScript',
15
+ Args,
16
+ run: async ({ args, log }) => {
17
+ const { _: [path, ...argv], } = args;
18
+ if (!path) {
19
+ log.info(green('\n\nUsage: ') + cyan('gro run path/to/file.ts [...node_args]\n'));
20
+ return;
21
+ }
22
+ if (!(await exists(path))) {
23
+ throw new Task_Error('cannot find file to run at path: ' + path);
24
+ }
25
+ const loader_path = await resolve_gro_module_path('loader.js');
26
+ const spawned = await spawn_with_loader(loader_path, path, argv);
27
+ if (!spawned.ok) {
28
+ throw new Task_Error(`\`gro run ${path}\` failed with exit code ${spawned.code}`);
29
+ }
30
+ },
31
+ };
@@ -0,0 +1,6 @@
1
+ import { type Gen_Module_Meta } from './gen_module.js';
2
+ import { type Gen_Results } from './gen.js';
3
+ import type { format_file as base_format_file } from './format_file.js';
4
+ export declare const GEN_NO_PROD_MESSAGE = "gen runs only during development";
5
+ export declare const run_gen: (gen_modules: Gen_Module_Meta[], log: Logger, timings: Timings, format_file?: typeof base_format_file) => Promise<Gen_Results>;
6
+ export declare const to_gen_import_path: (id: string) => string;
@@ -0,0 +1,74 @@
1
+ import { red } from 'kleur/colors';
2
+ import { print_error } from '@ryanatkn/belt/print.js';
3
+ import { Unreachable_Error } from '@ryanatkn/belt/error.js';
4
+ import { strip_end } from '@ryanatkn/belt/string.js';
5
+ import { GEN_SCHEMA_PATH_SUFFIX } from './gen_module.js';
6
+ import { to_gen_result, } from './gen.js';
7
+ import { print_path, source_id_to_base_path } from './paths.js';
8
+ export const GEN_NO_PROD_MESSAGE = 'gen runs only during development';
9
+ export const run_gen = async (gen_modules, log, timings, format_file) => {
10
+ let input_count = 0;
11
+ let output_count = 0;
12
+ const timing_for_run_gen = timings.start('run_gen');
13
+ const results = await Promise.all(gen_modules.map(async (module_meta) => {
14
+ input_count++;
15
+ const { id } = module_meta;
16
+ const timing_for_module = timings.start(id);
17
+ // Perform code generation by calling `gen` on the module.
18
+ const gen_ctx = { origin_id: id, log };
19
+ let raw_gen_result;
20
+ try {
21
+ switch (module_meta.type) {
22
+ case 'basic': {
23
+ raw_gen_result = await module_meta.mod.gen(gen_ctx);
24
+ break;
25
+ }
26
+ default: {
27
+ throw new Unreachable_Error(module_meta.type);
28
+ }
29
+ }
30
+ }
31
+ catch (err) {
32
+ return {
33
+ ok: false,
34
+ id,
35
+ error: err,
36
+ reason: red(`Error generating ${print_path(id)}`),
37
+ elapsed: timing_for_module(),
38
+ };
39
+ }
40
+ // Convert the module's return value to a normalized form.
41
+ const gen_result = to_gen_result(id, raw_gen_result);
42
+ // Format the files if needed.
43
+ const files = format_file
44
+ ? await Promise.all(gen_result.files.map(async (file) => {
45
+ if (!file.format)
46
+ return file;
47
+ try {
48
+ return { ...file, content: await format_file(file.content, { filepath: file.id }) };
49
+ }
50
+ catch (err) {
51
+ log.error(red(`Error formatting ${print_path(file.id)} via ${print_path(id)}`), print_error(err));
52
+ return file;
53
+ }
54
+ }))
55
+ : gen_result.files;
56
+ output_count += files.length;
57
+ return {
58
+ ok: true,
59
+ id,
60
+ files,
61
+ elapsed: timing_for_module(),
62
+ };
63
+ }));
64
+ return {
65
+ results,
66
+ successes: results.filter((r) => r.ok),
67
+ failures: results.filter((r) => !r.ok),
68
+ input_count,
69
+ output_count,
70
+ elapsed: timing_for_run_gen(),
71
+ };
72
+ };
73
+ // TODO configurable
74
+ export const to_gen_import_path = (id) => '$' + strip_end(source_id_to_base_path(id), GEN_SCHEMA_PATH_SUFFIX);
@@ -0,0 +1 @@
1
+ export {};