@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
package/dist/git.js ADDED
@@ -0,0 +1,200 @@
1
+ import { spawn, spawn_out } from '@ryanatkn/belt/process.js';
2
+ import { z } from 'zod';
3
+ import { exists } from './fs.js';
4
+ import { to_file_path } from './path.js';
5
+ // TODO maybe extract to `util-git`
6
+ export const Git_Origin = z.string();
7
+ export const Git_Branch = z.string();
8
+ /**
9
+ * Returns the current git branch name or throws if something goes wrong.
10
+ */
11
+ export const git_current_branch_name = async (options) => {
12
+ const { stdout } = await spawn_out('git', ['rev-parse', '--abbrev-ref', 'HEAD'], options);
13
+ if (!stdout)
14
+ throw Error('git_current_branch_name failed');
15
+ const branch_name = stdout.toString().trim();
16
+ return branch_name;
17
+ };
18
+ /**
19
+ * @returns a boolean indicating if the remote git branch exists
20
+ */
21
+ export const git_remote_branch_exists = async (origin = 'origin', branch, options) => {
22
+ const final_branch = branch ?? (await git_current_branch_name(options));
23
+ if (options?.cwd && !(await exists(to_file_path(options.cwd)))) {
24
+ return false;
25
+ }
26
+ const result = await spawn('git', ['ls-remote', '--exit-code', '--heads', origin, 'refs/heads/' + final_branch], options);
27
+ if (result.ok) {
28
+ return true;
29
+ }
30
+ else if (result.code === 2) {
31
+ return false;
32
+ }
33
+ else {
34
+ throw Error(`git_remote_branch_exists failed for origin '${origin}' and branch '${final_branch}' with code ${result.code}`);
35
+ }
36
+ };
37
+ /**
38
+ * @returns a boolean indicating if the local git branch exists
39
+ */
40
+ export const git_local_branch_exists = async (branch, options) => {
41
+ if (options?.cwd && !(await exists(to_file_path(options.cwd)))) {
42
+ return false;
43
+ }
44
+ const result = await spawn('git', ['show-ref', '--quiet', 'refs/heads/' + branch], options);
45
+ return result.ok;
46
+ };
47
+ /**
48
+ * TODO make this return an enum and separate the text into a different function
49
+ * @returns an error message if the git workspace has any unstaged or uncommitted changes, or `null` if it's clean
50
+ */
51
+ export const git_check_clean_workspace = async (options) => {
52
+ const unstaged_result = await spawn('git', ['diff', '--exit-code', '--quiet'], options);
53
+ if (!unstaged_result.ok) {
54
+ return 'git has unstaged changes';
55
+ }
56
+ const staged_result = await spawn('git', ['diff', '--exit-code', '--cached', '--quiet'], options);
57
+ if (!staged_result.ok) {
58
+ return 'git has staged but uncommitted changes';
59
+ }
60
+ const status_result = await spawn_out('git', ['status', '--porcelain'], options);
61
+ if (status_result.stdout?.length) {
62
+ return 'git has untracked files';
63
+ }
64
+ return null;
65
+ };
66
+ /**
67
+ * Calls `git fetch` and throws if anything goes wrong.
68
+ */
69
+ export const git_fetch = async (origin = 'origin', branch, options) => {
70
+ const args = ['fetch', origin];
71
+ if (branch)
72
+ args.push(branch);
73
+ const result = await spawn('git', args, options);
74
+ if (!result.ok) {
75
+ throw Error(`git_fetch failed for origin '${origin}' and branch '${branch}' with code ${result.code}`);
76
+ }
77
+ };
78
+ /**
79
+ * Calls `git checkout` and throws if anything goes wrong.
80
+ * @returns the previous branch name, if it changed
81
+ */
82
+ export const git_checkout = async (branch, options) => {
83
+ const current_branch = await git_current_branch_name(options);
84
+ if (branch === current_branch) {
85
+ return null;
86
+ }
87
+ const result = await spawn('git', ['checkout', branch], options);
88
+ if (!result.ok) {
89
+ throw Error(`git_checkout failed for branch '${branch}' with code ${result.code}`);
90
+ }
91
+ return current_branch;
92
+ };
93
+ /**
94
+ * Calls `git pull` and throws if anything goes wrong.
95
+ */
96
+ export const git_pull = async (origin = 'origin', branch, options) => {
97
+ const args = ['pull', origin];
98
+ if (branch)
99
+ args.push(branch);
100
+ const result = await spawn('git', args, options);
101
+ if (!result.ok) {
102
+ throw Error(`git_pull failed for branch '${branch}' with code ${result.code}`);
103
+ }
104
+ };
105
+ /**
106
+ * Calls `git push` and throws if anything goes wrong.
107
+ */
108
+ export const git_push = async (origin, branch, options) => {
109
+ const final_branch = branch ?? (await git_current_branch_name(options));
110
+ const result = await spawn('git', ['push', origin, final_branch], options);
111
+ if (!result.ok) {
112
+ throw Error(`git_push failed for branch '${final_branch}' with code ${result.code}`);
113
+ }
114
+ };
115
+ /**
116
+ * Calls `git push` and throws if anything goes wrong.
117
+ */
118
+ export const git_push_to_create = async (origin = 'origin', branch, options) => {
119
+ const final_branch = branch ?? (await git_current_branch_name(options));
120
+ const push_args = ['push'];
121
+ if (await git_remote_branch_exists(origin, final_branch, options)) {
122
+ push_args.push(origin);
123
+ }
124
+ else {
125
+ push_args.push('-u', origin);
126
+ }
127
+ push_args.push(final_branch);
128
+ const result = await spawn('git', push_args, options);
129
+ if (!result.ok) {
130
+ throw Error(`git_push failed for branch '${final_branch}' with code ${result.code}`);
131
+ }
132
+ };
133
+ /**
134
+ * Deletes a branch locally and throws if anything goes wrong.
135
+ */
136
+ export const git_delete_local_branch = async (branch, options) => {
137
+ const result = await spawn('git', ['branch', '-D', branch], options);
138
+ if (!result.ok) {
139
+ throw Error(`git_delete_local_branch failed for branch '${branch}' with code ${result.code}`);
140
+ }
141
+ };
142
+ /**
143
+ * Deletes a branch remotely and throws if anything goes wrong.
144
+ */
145
+ export const git_delete_remote_branch = async (origin, branch, options) => {
146
+ const result = await spawn('git', ['push', origin, ':' + branch], options);
147
+ if (!result.ok) {
148
+ throw Error(`git_delete_remote_branch failed for branch '${branch}' with code ${result.code}`);
149
+ }
150
+ };
151
+ /**
152
+ * Resets the `target` branch back to its first commit both locally and remotely.
153
+ */
154
+ export const git_reset_branch_to_first_commit = async (origin, branch, options) => {
155
+ const previous_branch = await git_checkout(branch, options);
156
+ const first_commit_hash = await git_current_branch_first_commit_hash(options);
157
+ await spawn('git', ['reset', '--hard', first_commit_hash], options);
158
+ await spawn('git', ['push', origin, branch, '--force'], options);
159
+ if (previous_branch) {
160
+ await git_checkout(previous_branch, options);
161
+ }
162
+ };
163
+ /**
164
+ * Returns the branch's latest commit hash or throws if something goes wrong.
165
+ */
166
+ export const git_current_commit_hash = async (branch, options) => {
167
+ const final_branch = branch ?? (await git_current_branch_name(options));
168
+ const { stdout } = await spawn_out('git', ['show-ref', '-s', final_branch], options);
169
+ if (!stdout)
170
+ return null; // TODO hack for CI
171
+ return stdout.toString().split('\n')[0].trim();
172
+ };
173
+ /**
174
+ * Returns the hash of the current branch's first commit or throws if something goes wrong.
175
+ */
176
+ export const git_current_branch_first_commit_hash = async (options) => {
177
+ const { stdout } = await spawn_out('git', ['rev-list', '--max-parents=0', '--abbrev-commit', 'HEAD'], options);
178
+ if (!stdout)
179
+ throw Error('git_current_branch_first_commit_hash failed');
180
+ return stdout.toString().trim();
181
+ };
182
+ /**
183
+ * Returns the global git config setting for `pull.rebase`.
184
+ * Gro is currently written to expect `true`,
185
+ * but the restriction could be loosened with additional work.
186
+ */
187
+ export const git_check_setting_pull_rebase = async (options) => {
188
+ const value = await spawn_out('git', ['config', '--global', 'pull.rebase'], options);
189
+ return value.stdout?.trim() === 'true';
190
+ };
191
+ /**
192
+ * Clones a branch locally to another directory and updates the origin to match the source.
193
+ */
194
+ export const git_clone_locally = async (origin, branch, source_dir, target_dir, options) => {
195
+ await spawn('git', ['clone', '-b', branch, '--single-branch', source_dir, target_dir], options);
196
+ const origin_url = (await spawn_out('git', ['remote', 'get-url', origin], { ...options, cwd: source_dir })).stdout?.trim();
197
+ if (!origin_url)
198
+ throw Error('Failed to get the origin url with git in ' + source_dir);
199
+ await spawn('git', ['remote', 'set-url', origin, origin_url], { ...options, cwd: target_dir });
200
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,18 @@
1
+ import { test } from 'uvu';
2
+ import * as assert from 'uvu/assert';
3
+ import { git_check_clean_workspace, git_current_branch_first_commit_hash, git_current_branch_name, git_current_commit_hash, } from './git.js';
4
+ test('git_current_branch_name', async () => {
5
+ const branch_name = await git_current_branch_name();
6
+ assert.ok(branch_name);
7
+ });
8
+ test('git_check_clean_workspace', async () => {
9
+ await git_check_clean_workspace();
10
+ });
11
+ test('git_current_commit_hash', async () => {
12
+ await git_current_commit_hash();
13
+ });
14
+ test('git_current_branch_first_commit_hash', async () => {
15
+ const first_commit_hash = await git_current_branch_first_commit_hash();
16
+ assert.ok(first_commit_hash);
17
+ });
18
+ test.run();
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+ export declare const Github_Pull_Request: z.ZodObject<{
3
+ url: z.ZodString;
4
+ id: z.ZodNumber;
5
+ html_url: z.ZodString;
6
+ number: z.ZodNumber;
7
+ user: z.ZodObject<{
8
+ login: z.ZodString;
9
+ }, "strip", z.ZodTypeAny, {
10
+ login: string;
11
+ }, {
12
+ login: string;
13
+ }>;
14
+ }, "strip", z.ZodTypeAny, {
15
+ number: number;
16
+ url: string;
17
+ id: number;
18
+ html_url: string;
19
+ user: {
20
+ login: string;
21
+ };
22
+ }, {
23
+ number: number;
24
+ url: string;
25
+ id: number;
26
+ html_url: string;
27
+ user: {
28
+ login: string;
29
+ };
30
+ }>;
31
+ export type Github_Pull_Request = z.infer<typeof Github_Pull_Request>;
32
+ /**
33
+ * @see https://docs.github.com/en/rest/commits/commits?apiVersion=2022-11-28#list-pull-requests-associated-with-a-commit
34
+ */
35
+ export declare const github_fetch_commit_prs: (owner: string, repo: string, commit_sha: string, token?: string, log?: any, cache?: any, api_version?: string) => Promise<Github_Pull_Request[] | null>;
package/dist/github.js ADDED
@@ -0,0 +1,32 @@
1
+ // TODO if this grows at all, use `@octokit/request`,
2
+ // for now it's just calling a single endpoint so we do it manually
3
+ // and we specify just the types we need
4
+ import { Fetch_Value_Cache, fetch_value } from '@ryanatkn/belt/fetch.js';
5
+ import { z } from 'zod';
6
+ export const Github_Pull_Request = z.object({
7
+ url: z.string(),
8
+ id: z.number(),
9
+ html_url: z.string(),
10
+ number: z.number(),
11
+ user: z.object({
12
+ login: z.string(),
13
+ }),
14
+ });
15
+ /**
16
+ * @see https://docs.github.com/en/rest/commits/commits?apiVersion=2022-11-28#list-pull-requests-associated-with-a-commit
17
+ */
18
+ export const github_fetch_commit_prs = async (owner, repo, commit_sha, token, log, cache, api_version) => {
19
+ const headers = api_version ? new Headers({ 'x-github-api-version': api_version }) : undefined;
20
+ const url = `https://api.github.com/repos/${owner}/${repo}/commits/${commit_sha}/pulls`;
21
+ const fetched = await fetch_value(url, {
22
+ request: { headers },
23
+ parse: (v) => v.map((p) => Github_Pull_Request.parse(p)),
24
+ token,
25
+ cache,
26
+ return_early_from_cache: true,
27
+ log,
28
+ });
29
+ if (!fetched.ok)
30
+ return null;
31
+ return fetched.value;
32
+ };
@@ -0,0 +1,12 @@
1
+ import type { Create_Gro_Config } from './config.js';
2
+ /**
3
+ * This is the default config that's passed to `gro.config.ts`
4
+ * if it exists in the current project, and if not, this is the final config.
5
+ * It looks at the project and tries to do the right thing:
6
+ *
7
+ * - if `src/routes`, assumes a SvelteKit frontend
8
+ * - if `src/lib`, assumes a Node library
9
+ * - if `src/lib/server/server.ts`, assumes a Node server
10
+ */
11
+ declare const config: Create_Gro_Config;
12
+ export default config;
@@ -0,0 +1,31 @@
1
+ import { has_sveltekit_library, gro_plugin_sveltekit_library, } from './gro_plugin_sveltekit_library.js';
2
+ import { has_server, gro_plugin_server } from './gro_plugin_server.js';
3
+ import { has_sveltekit_app, gro_plugin_sveltekit_app } from './gro_plugin_sveltekit_app.js';
4
+ /**
5
+ * This is the default config that's passed to `gro.config.ts`
6
+ * if it exists in the current project, and if not, this is the final config.
7
+ * It looks at the project and tries to do the right thing:
8
+ *
9
+ * - if `src/routes`, assumes a SvelteKit frontend
10
+ * - if `src/lib`, assumes a Node library
11
+ * - if `src/lib/server/server.ts`, assumes a Node server
12
+ */
13
+ const config = async (cfg) => {
14
+ const [enable_sveltekit_library, enable_server, enable_sveltekit_app] = await Promise.all([
15
+ has_sveltekit_library(),
16
+ has_server(),
17
+ has_sveltekit_app(),
18
+ ]);
19
+ cfg.plugins = async () => [
20
+ enable_sveltekit_library ? gro_plugin_sveltekit_library() : null,
21
+ enable_server ? gro_plugin_server() : null,
22
+ enable_sveltekit_app
23
+ ? gro_plugin_sveltekit_app({ host_target: enable_server ? 'node' : 'github_pages' })
24
+ : null,
25
+ // TODO replace with an esbuild plugin, see the module for more
26
+ // import {gro_plugin_gen} from './gro_plugin_gen.js';
27
+ // gro_plugin_gen(),
28
+ ];
29
+ return cfg;
30
+ };
31
+ export default config;
package/dist/gro.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/gro.js ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ import { join } from 'node:path';
3
+ import { resolve_gro_module_path, spawn_with_loader } from './gro_helpers.js';
4
+ /*
5
+
6
+ This file is a loader for the Gro CLI.
7
+ Its only purpose is to import the `invoke.js` script in the correct directory.
8
+ By using `resolve_gro_module_path` it lets the global Gro CLI defer
9
+ to a local installation of Gro if one is available,
10
+ and it also provides special handling for the case
11
+ where we're running Gro inside Gro's own repo for development.
12
+
13
+ */
14
+ const invoke_path = await resolve_gro_module_path('invoke.js');
15
+ const loader_path = join(invoke_path, '../loader.js');
16
+ const spawned = await spawn_with_loader(loader_path, invoke_path, process.argv.slice(2));
17
+ if (!spawned.ok) {
18
+ process.exit(spawned.code || 1);
19
+ }
@@ -0,0 +1,43 @@
1
+ import { type Spawn_Result } from '@ryanatkn/belt/process.js';
2
+ /**
3
+ * Resolves a path to an internal Gro file.
4
+ * Prefers any local installation of Gro and falls back to the current CLI context.
5
+ *
6
+ * Uses heuristics to find `path`, so may fail in some rare corner cases.
7
+ * Currently looks for `gro.js` as a sibling to the `path` arg for detection.
8
+ * If this fails for your usecases, rename `gro.js` or open an issue/PR!
9
+ *
10
+ * Used by the CLI and `gro run`.
11
+ *
12
+ * case 1:
13
+ *
14
+ * We're in a directory that has a local installation of Gro at `node_modules/.bin/gro`.
15
+ * Use this local version instead of the global.
16
+ *
17
+ * case 2:
18
+ *
19
+ * We're running Gro inside the Gro repo itself.
20
+ *
21
+ * In this case, we use the build directory instead of dist.
22
+ * There's a paradox here for using Gro inside itself -
23
+ * ideally we use the dist directory because that's what's shipped,
24
+ * but the build directory has all of the tests,
25
+ * and loading two instances of its modules causes problems
26
+ * like `instanceof` checks failing.
27
+ * For now we'll just run from build and see if it causes any problems.
28
+ * There's probably a better design in here somewhere.
29
+ *
30
+ * case 3:
31
+ *
32
+ * Fall back to invoking Gro from wherever the CLI is being executed.
33
+ * When using the global CLI, this uses the global Gro installation.
34
+ *
35
+ */
36
+ export declare const resolve_gro_module_path: (path?: string) => Promise<string>;
37
+ /**
38
+ * Runs a file using the Gro loader.
39
+ *
40
+ * @param loader_path path to loader
41
+ * @param invoke_path path to file to spawn with `node`
42
+ */
43
+ export declare const spawn_with_loader: (loader_path: string, invoke_path: string, argv: string[]) => Promise<Spawn_Result>;
@@ -0,0 +1,79 @@
1
+ import { realpath } from 'node:fs/promises';
2
+ import { join, resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { spawn } from '@ryanatkn/belt/process.js';
5
+ import { exists } from './fs.js';
6
+ import { NODE_MODULES_DIRNAME } from './paths.js';
7
+ /**
8
+ * Resolves a path to an internal Gro file.
9
+ * Prefers any local installation of Gro and falls back to the current CLI context.
10
+ *
11
+ * Uses heuristics to find `path`, so may fail in some rare corner cases.
12
+ * Currently looks for `gro.js` as a sibling to the `path` arg for detection.
13
+ * If this fails for your usecases, rename `gro.js` or open an issue/PR!
14
+ *
15
+ * Used by the CLI and `gro run`.
16
+ *
17
+ * case 1:
18
+ *
19
+ * We're in a directory that has a local installation of Gro at `node_modules/.bin/gro`.
20
+ * Use this local version instead of the global.
21
+ *
22
+ * case 2:
23
+ *
24
+ * We're running Gro inside the Gro repo itself.
25
+ *
26
+ * In this case, we use the build directory instead of dist.
27
+ * There's a paradox here for using Gro inside itself -
28
+ * ideally we use the dist directory because that's what's shipped,
29
+ * but the build directory has all of the tests,
30
+ * and loading two instances of its modules causes problems
31
+ * like `instanceof` checks failing.
32
+ * For now we'll just run from build and see if it causes any problems.
33
+ * There's probably a better design in here somewhere.
34
+ *
35
+ * case 3:
36
+ *
37
+ * Fall back to invoking Gro from wherever the CLI is being executed.
38
+ * When using the global CLI, this uses the global Gro installation.
39
+ *
40
+ */
41
+ export const resolve_gro_module_path = async (path = '') => {
42
+ const gro_bin_path = resolve(NODE_MODULES_DIRNAME, '.bin/gro');
43
+ if (await exists(gro_bin_path)) {
44
+ // case 1
45
+ // Prefer any locally installed version of Gro.
46
+ return join(await realpath(gro_bin_path), '..', path);
47
+ }
48
+ else {
49
+ // case 2
50
+ // If running Gro inside its own repo, require the local dist.
51
+ // If the local dist is not yet built it will fall back to the global.
52
+ const file_path = fileURLToPath(import.meta.url);
53
+ const base_path = 'dist';
54
+ if ((await exists(join(base_path, 'gro.js'))) && (await exists(join(base_path, path)))) {
55
+ return join(file_path, '../..', base_path, path);
56
+ }
57
+ else {
58
+ // case 3
59
+ // Fall back to the version associated with the running CLI.
60
+ return join(file_path, '..', path);
61
+ }
62
+ }
63
+ };
64
+ /**
65
+ * Runs a file using the Gro loader.
66
+ *
67
+ * @param loader_path path to loader
68
+ * @param invoke_path path to file to spawn with `node`
69
+ */
70
+ export const spawn_with_loader = async (loader_path, invoke_path, argv) => spawn('node', [
71
+ '--import',
72
+ `data:text/javascript,
73
+ import {register} from "node:module";
74
+ import {pathToFileURL} from "node:url";
75
+ register("${loader_path}", pathToFileURL("./"));`,
76
+ '--enable-source-maps',
77
+ invoke_path,
78
+ ...argv,
79
+ ]);
@@ -0,0 +1,6 @@
1
+ import type { Plugin, Plugin_Context } from './plugin.js';
2
+ import type { Args } from './args.js';
3
+ export interface Task_Args extends Args {
4
+ watch?: boolean;
5
+ }
6
+ export declare const plugin: () => Plugin<Plugin_Context<Task_Args>>;
@@ -0,0 +1,80 @@
1
+ // TODO this became unused with https://github.com/ryanatkn/gro/pull/382
2
+ // because we no longer have a normal system build - replace with an esbuild plugin
3
+ // @ts-nocheck
4
+ import { spawn } from '@ryanatkn/belt/process.js';
5
+ import { source_id_to_base_path } from './paths.js';
6
+ import { find_gen_modules, is_gen_path } from './gen_module.js';
7
+ import { filter_dependents } from './build/source_file.js';
8
+ import { throttle } from './throttle.js';
9
+ const FLUSH_DEBOUNCE_DELAY = 500;
10
+ export const plugin = () => {
11
+ let generating = false;
12
+ let regen = false;
13
+ let on_filer_build;
14
+ const queued_files = new Set();
15
+ const queue_gen = (gen_file_name) => {
16
+ queued_files.add(gen_file_name);
17
+ void flush_gen_queue();
18
+ };
19
+ const flush_gen_queue = throttle(async () => {
20
+ // hacky way to avoid concurrent `gro gen` calls
21
+ if (generating) {
22
+ regen = true;
23
+ return;
24
+ }
25
+ generating = true;
26
+ const files = Array.from(queued_files);
27
+ queued_files.clear();
28
+ await gen(files);
29
+ generating = false;
30
+ if (regen) {
31
+ regen = false;
32
+ void flush_gen_queue();
33
+ }
34
+ }, FLUSH_DEBOUNCE_DELAY);
35
+ const gen = (files = []) => spawn('npx', ['gro', 'gen', ...files]);
36
+ return {
37
+ name: 'gro_plugin_gen',
38
+ setup: async ({ args: { watch }, dev, log }) => {
39
+ // For production builds, we assume `gen` is already fresh,
40
+ // which should be checked by CI via `gro check` which calls `gro gen --check`.
41
+ if (!dev)
42
+ return;
43
+ // Run `gen`, first checking if there are any modules to avoid a console error.
44
+ // Some parts of the build may have already happened,
45
+ // making us miss `build` events for gen dependencies,
46
+ // so we run `gen` here even if it's usually wasteful.
47
+ const found = await find_gen_modules();
48
+ if (found.ok && found.source_ids_by_input_path.size > 0) {
49
+ await gen();
50
+ }
51
+ // Do we need to just generate everything once and exit?
52
+ // TODO could we have an esbuild context here? problem is watching the right files, maybe a plugin that tracks deps
53
+ if (!filer || !watch) {
54
+ log.info('generating and exiting early');
55
+ return;
56
+ }
57
+ // When a file builds, check it and its tree of dependents
58
+ // for any `.gen.` files that need to run.
59
+ on_filer_build = async ({ source_file, build_config }) => {
60
+ // TODO how to handle this now? the loader traces deps for us with `parentPath`,
61
+ // but we probably want to make this an esbuild plugin instead
62
+ // if (build_config.name !== 'system') return;
63
+ if (is_gen_path(source_file.id)) {
64
+ queue_gen(source_id_to_base_path(source_file.id));
65
+ }
66
+ const dependent_gen_file_ids = filter_dependents(source_file, build_config, filer.find_by_id, // cast because we can assume they're all `SourceFile`s
67
+ is_gen_path);
68
+ for (const dependent_gen_file_id of dependent_gen_file_ids) {
69
+ queue_gen(source_id_to_base_path(dependent_gen_file_id));
70
+ }
71
+ };
72
+ filer.on('build', on_filer_build);
73
+ },
74
+ teardown: async ({ filer }) => {
75
+ if (on_filer_build && filer) {
76
+ filer.off('build', on_filer_build);
77
+ }
78
+ },
79
+ };
80
+ };
@@ -0,0 +1,77 @@
1
+ import * as esbuild from 'esbuild';
2
+ import type { Config as SvelteKitConfig } from '@sveltejs/kit';
3
+ import type { Plugin, Plugin_Context } from './plugin.js';
4
+ export declare const SERVER_SOURCE_ID: Flavored<string, "Source_Id">;
5
+ export declare const has_server: (path?: Flavored<string, "Source_Id">) => Promise<boolean>;
6
+ export interface Options {
7
+ /**
8
+ * same as esbuild's `entryPoints`
9
+ */
10
+ entry_points?: string[];
11
+ /**
12
+ * @default cwd
13
+ */
14
+ dir?: string;
15
+ /**
16
+ * Returns the `Outpaths` given a `dev` param.
17
+ * Decoupling this from plugin creation allows it to be created generically,
18
+ * so the build and dev tasks can be the source of truth for `dev`.
19
+ */
20
+ outpaths?: Create_Outpaths;
21
+ /**
22
+ * @default SvelteKit's `.env`, `.env.development`, and `.env.production`
23
+ */
24
+ env_files?: string[];
25
+ /**
26
+ * @default process.env
27
+ */
28
+ ambient_env?: Record<string, string>;
29
+ /**
30
+ * @default loaded from `${cwd}/${SVELTEKIT_CONFIG_FILENAME}`
31
+ */
32
+ sveltekit_config?: SvelteKitConfig;
33
+ /**
34
+ * @default 'esnext'
35
+ */
36
+ target?: string;
37
+ /**
38
+ * Optionally map the esbuild options.
39
+ * @default identity
40
+ */
41
+ esbuild_build_options?: (base_options: esbuild.BuildOptions) => esbuild.BuildOptions;
42
+ /**
43
+ * Milliseconds to throttle rebuilds.
44
+ * Should be longer than it takes to build to avoid backpressure.
45
+ * @default 1000
46
+ */
47
+ rebuild_throttle_delay?: number;
48
+ /**
49
+ * The CLI command to run the server, like `'node'` or `'bun'` or `'deno'`.
50
+ * Receives the path to the server js file as its argument.
51
+ * @default 'node'
52
+ */
53
+ cli_command?: string;
54
+ /**
55
+ * Whether to run the server or not after building.
56
+ * @default dev
57
+ */
58
+ run?: boolean;
59
+ }
60
+ export interface Outpaths {
61
+ /**
62
+ * @default '.gro/dev' or 'dist_server'
63
+ */
64
+ outdir: string;
65
+ /**
66
+ * @default 'src/lib'
67
+ */
68
+ outbase: string;
69
+ /**
70
+ * @default 'server.js'
71
+ */
72
+ outname: string;
73
+ }
74
+ export interface Create_Outpaths {
75
+ (dev: boolean): Outpaths;
76
+ }
77
+ export declare const gro_plugin_server: ({ entry_points, dir, outpaths, env_files, ambient_env, sveltekit_config, target, esbuild_build_options, rebuild_throttle_delay, cli_command, run, }?: Options) => Plugin<Plugin_Context>;