@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,40 @@
1
+ # dev
2
+
3
+ Gro is designed to extend [SvelteKit](https://github.com/sveltejs/kit)
4
+ with helpful tools. It supports:
5
+
6
+ - frontends with SvelteKit and [Vite](https://github.com/vitejs/vite)
7
+ - Node libraries
8
+ - Node servers
9
+
10
+ ## usage
11
+
12
+ ```bash
13
+ gro dev
14
+ gro dev --no-watch # outputs dev artifacts and exits without watch mode
15
+ ```
16
+
17
+ To configure a project, see [the config docs](config.md).
18
+
19
+ ## plugin
20
+
21
+ `Plugin`s are objects that customize the behavior of `gro build` and `gro dev`.
22
+ See [plugin.md](plugin.md) to learn more.
23
+
24
+ ## todo
25
+
26
+ - [x] basics
27
+ - [ ] add API using esbuild to optionally bundle specific pieces to speed up development
28
+ - [ ] livereload CSS (and fix pop-in during dev)
29
+ - [ ] HMR
30
+ - [ ] probably support Rollup plugins in development, but how?
31
+ - [ ] improve loading speed with `cache-control: immutable` and
32
+ [import maps](https://github.com/WICG/import-maps/)
33
+ (on my machine Firefox is much slower than Chrome
34
+ handling a module import waterfall, locally, and http2 didn't help)
35
+
36
+ <p align="center">
37
+ <a href="https://github.com/ryanatkn/gro">
38
+ <img src="static/favicon.png" width="192" height="192">
39
+ </a>
40
+ </p>
@@ -0,0 +1,241 @@
1
+ # gen
2
+
3
+ > automated codegen by convention for
4
+ > [Gro](https://github.com/ryanatkn/gro)
5
+
6
+ ## motivation
7
+
8
+ The [`gro gen` task](/src/lib/gen.task.ts) helps us enhance our projects
9
+ with convention-based code/data/file generation (codegen) techniques.
10
+
11
+ Why? Codegen can produce cool results and unhalting pain.
12
+ Used well, codegen can improve performance, flexibility, consistency, and development speed.
13
+ As developers, automating our work is a natural thing to do,
14
+ and whether or not it's a wise thing to do,
15
+ `gro gen` can bring automation deeper into our code authoring workflows.
16
+
17
+ By convention, `gro gen` looks through `src/`
18
+ for any TypeScript files with `.gen.` in the file name,
19
+ and it outputs a file stripped of `.gen.` to the same directory.
20
+ The `*.gen.*` origin files export a `gen` function
21
+ More flexibility is available when needed
22
+ including multiple custom output files.
23
+
24
+ `gen` is implemented as [a task](/src/lib/gen.task.ts)
25
+ and [a plugin](/src/lib/gro_plugin_gen.ts),
26
+ and runs only during development, not for production builds.
27
+
28
+ Normally you'll want to commit generated files to git,
29
+ but you can always gitignore a specific pattern like `*.ignore.*`
30
+ and name the output files accordingly.
31
+
32
+ Integrating codegen into our development process
33
+ is a simple idea with vast potential.
34
+ It lets us have a single source of truth for data
35
+ without compromising any of our code's runtime characteristics.
36
+ We can generate documentation, types,
37
+ `index.ts` files exporting directories,
38
+ data for a UI,
39
+ validators, tests, fakes,
40
+ and more by introspecting our data at buildtime,
41
+ which speeds up development
42
+ The goal is to leverage automation to increase the power we wield over our code
43
+ with a straightforward developer experience.
44
+ Ergonomics are key to unlocking codegen's full potential.
45
+
46
+ **Be aware** — this is a sharp tool! It should be used sparingly, only when it's a clear win.
47
+ It adds a layer of indirection between the code you write and run,
48
+ and it's possible to tie yourself into knots with dependencies.
49
+ Also, you could introduce security vulnerabilities
50
+ if you fail to escape certain inputs,
51
+ There's no support for sourcemaps yet, and I have no plans for them.
52
+ (I would accept contributions, but I think it's a hard problem to do well,
53
+ and I don't know what the payoffs would be)
54
+
55
+ Inspirations include Lisp macros, the
56
+ [Svelte](https://github.com/sveltejs/svelte) compiler,
57
+ and [Zig](https://github.com/ziglang/zig)'s comptime.
58
+ (but `gro gen` is far more primitive)
59
+
60
+ ## usage
61
+
62
+ The `gro gen` task looks for any files with `.gen.`
63
+ in the file name and tries to call an exported `gen`
64
+ function to generate one or more output files,
65
+ and then it writes the results to the filesystem.
66
+
67
+ ```bash
68
+ gro gen # runs codegen for all *.gen.* files in src/
69
+ gro gen --check # exits with error code 1 if anything is new or different; no-op to the fs
70
+ ```
71
+
72
+ > in the following examples,
73
+ > but it makes for a better DX
74
+
75
+ ### generate arbitrary TypeScript
76
+
77
+ Given `src/script.gen.ts`:
78
+
79
+ ```ts
80
+ import type {Gen} from '@ryanatkn/gro';
81
+
82
+ export const gen: Gen = () => {
83
+ const message = 'generated';
84
+ return `console.log('${message} a ${typeof message}')`;
85
+ };
86
+ ```
87
+
88
+ Outputs `src/script.ts`:
89
+
90
+ ```ts
91
+ console.log('generated a string');
92
+ ```
93
+
94
+ ### generate other filetypes
95
+
96
+ Files with any extension can be generated without configuration.
97
+ If the origin file name ends with the pattern `.gen.*.ts`,
98
+ the default output file name is stripped of its trailing `.ts`.
99
+
100
+ Given `src/markup.gen.html.ts`:
101
+
102
+ ```ts
103
+ import type {Gen} from '@ryanatkn/gro';
104
+
105
+ export const gen: Gen = () => {
106
+ const body = 'hi';
107
+ return `
108
+ <!DOCTYPE html>
109
+ <html>
110
+ <body>
111
+ ${body}
112
+ </body>
113
+ </html>
114
+ `;
115
+ };
116
+ ```
117
+
118
+ Outputs `src/markup.html`:
119
+
120
+ ```html
121
+ <!doctype html>
122
+ <html>
123
+ <body>
124
+ hi
125
+ </body>
126
+ </html>
127
+ ```
128
+
129
+ ### generate a custom file name or write to a different directory
130
+
131
+ The `gen` function can return an object with custom configuration.
132
+
133
+ Given `src/somewhere/originalName.gen.ts`:
134
+
135
+ ```ts
136
+ import type {Gen} from '@ryanatkn/gro';
137
+
138
+ export const gen: Gen = () => {
139
+ const message = 'output path can be relative and name can be anything';
140
+ return {
141
+ content: `console.log('${message}')`,
142
+ filename: '../elsewhere/otherName.ts',
143
+ format: optional_boolean_that_defaults_to_true,
144
+ };
145
+ };
146
+ ```
147
+
148
+ Outputs `src/elsewhere/otherName.ts`:
149
+
150
+ ```ts
151
+ console.log('output path can be relative and name can be anything');
152
+ ```
153
+
154
+ ### generate multiple custom files
155
+
156
+ The `gen` function can also return an array of files.
157
+
158
+ Given `src/thing.gen.ts`:
159
+
160
+ ```ts
161
+ import type {Gen} from '@ryanatkn/gro';
162
+
163
+ export const gen: Gen = () => {
164
+ const fieldValue = 1;
165
+ return [
166
+ {
167
+ content: `
168
+ import {Thing} from './index';
169
+ export const isThing = (t: any): t is Thing => t?.field === ${fieldValue};
170
+ `,
171
+ },
172
+ {
173
+ content: `export interface Thing { field: ${typeof fieldValue} }`,
174
+ filename: 'types.ts',
175
+ },
176
+ {
177
+ content: `{"field": ${fieldValue}}`,
178
+ filename: 'data/thing.json',
179
+ },
180
+ ];
181
+ };
182
+ ```
183
+
184
+ Outputs `src/thing.ts`:
185
+
186
+ ```ts
187
+ import type {Thing} from './index.js';
188
+ export const isThing = (t: any): t is Thing => t?.field === 1;
189
+ ```
190
+
191
+ and `src/types.ts`:
192
+
193
+ ```ts
194
+ export interface Thing {
195
+ field: number;
196
+ }
197
+ ```
198
+
199
+ and `src/data/thing.json`:
200
+
201
+ ```json
202
+ {
203
+ "field": 1
204
+ }
205
+ ```
206
+
207
+ It's often helpful to check if any generated files are new or have changed.
208
+ We don't want to forget to regenerate files before committing or publishing!
209
+ The `check` CLI argument can be passed to perform this check
210
+ instead of writing the generated files to disk.
211
+
212
+ ```bash
213
+ gro gen --check # exits with error code 1 if anything is new or different; no-op to the fs
214
+ ```
215
+
216
+ or in code:
217
+
218
+ ```ts
219
+ import type {Task} from '@ryanatkn/gro';
220
+
221
+ export const task: Task = {
222
+ run: async ({args, invoke_task}) => {
223
+ // this throws a `Task_Error` if anything is new or different
224
+ await invoke_task('gen', {...args, check: true});
225
+ },
226
+ };
227
+ ```
228
+
229
+ Gro uses this in [`check.task.ts`](/src/lib/check.task.ts)
230
+ which is called during `gro publish`, and it's recommended in CI.
231
+ (see [Gro's example `check.yml`](/.github/workflows/check.yml))
232
+
233
+ ## todo
234
+
235
+ - [x] basic functionality
236
+ - [x] format output with Prettier
237
+ - [x] [watch mode and build integration](https://github.com/ryanatkn/gro/pull/283),
238
+ opt out with `watch: false` for expensive gen use cases
239
+ - [ ] change the exported `gen` function to an object with a `summary` and other properties like `watch`
240
+ - [ ] support generating non-text files
241
+ - [ ] think about how to handle gen file dependency graphs (generated files as inputs to gen files)
@@ -0,0 +1,97 @@
1
+ # SvelteKit frontend plugin
2
+
3
+ Gro's [SvelteKit frontend plugin](/src/lib/gro_plugin_sveltekit_app.ts)
4
+ calls `vite dev` and `vite build` with some additional behaviors.
5
+
6
+ ```ts
7
+ // gro.config.ts
8
+ import type {Gro_ConfigCreator} from '@ryanatkn/gro';
9
+ import {gro_plugin_sveltekit_app} from '@ryanatkn/gro/gro_plugin_sveltekit_app.js';
10
+
11
+ const config: Gro_ConfigCreator = async (cfg) => {
12
+ cfg.plugins = async () => [
13
+ // this is included in the default config for SvelteKit projects:
14
+ gro_plugin_sveltekit_app({
15
+ // host_target?: Host_Target;
16
+ // well_known_package_json?: boolean | Map_Package_Json;
17
+ // well_known_src_json?: boolean | Map_Src_Json;
18
+ // filter_well_known_src?: (source: string, destination: string) => boolean | Promise<boolean>;
19
+ }),
20
+ ];
21
+ return cfg;
22
+ };
23
+
24
+ export default config;
25
+
26
+ // src/lib/gro_plugin_sveltekit_app.ts
27
+ export type Host_Target = 'github_pages' | 'static' | 'node';
28
+
29
+ export interface Map_Package_Json {
30
+ (package_json: Package_Json): Package_Json | null | Promise<Package_Json | null>;
31
+ }
32
+ ```
33
+
34
+ ## `host_target`
35
+
36
+ When `host_target` is the default value `'github_pages'`,
37
+ a `.nojekyll` file is included in the build to tell GitHub Pages not to process it with Jekyll.
38
+
39
+ ## `well_known_package_json`
40
+
41
+ If your root `package.json` has `"public": true`
42
+ (telling Gro it's a [public package](./package_json.md#public-packages)),
43
+ by default Gro copies `.well-known/package.json` to `static/` during `vite build`,
44
+ so it's included in the SvelteKit build output.
45
+ The motivation is to provide conventional package metadata to web users and tools.
46
+ (more details below)
47
+
48
+ > ⚠️ Outputting `.well-known/package.json` will surprise some users
49
+ > and could result in information leaks that compromise privacy or security.
50
+ > The feature is enabled only when your root `package.json` has `"public": true`.
51
+ > Templates that default to public should prominently warn their users.
52
+
53
+ By default the root `package.json` is copied without modifications,
54
+ and you can provide your own `well_known_package_json` option to
55
+ mutate the `package_json`, return new data, or return `null` to be a no-op.
56
+
57
+ > Writing to `.well-known/package.json` is unstandardized behavior that
58
+ > extends [Well-known URIs](https://wikipedia.org/wiki/Well-known_URIs) for Node packages
59
+ > to provide conventional metadata for deployed websites.
60
+ > [Mastodon](<https://en.wikipedia.org/wiki/Mastodon_(social_network)>) uses
61
+ > [WebFinger](https://en.wikipedia.org/wiki/WebFinger) which uses `.well-known` for discovery.
62
+ > One difference is that SvelteKit outputs static files relative to the configured `base` path,
63
+ > so the `.well-known` directory may not be in the root `/`.
64
+ > This is useful because it enables websites to provide metadata even when hosted in a namespaced
65
+ > path like `username.github.io/projectname/.well-known`.
66
+
67
+ Why publish this metadata to the web instead of relying on the git repo as the only source of truth?
68
+
69
+ - we want to give all web users and tools access to discoverable package metadata
70
+ - metadata is a much lighter dependency than an entire repo
71
+ - some repos are deployed to multiple websites with metadata differences
72
+ - some repos like monorepos have multiple `package.json` files
73
+ - we don't want to force a dependency on git, the bespoke URLs of forge hosts like GitHub,
74
+ or any particular toolchains
75
+ - the git repo is still the source of truth, but Gro adds a build step for project metadata,
76
+ giving devs full control over the published artifacts
77
+ instead of coupling metadata directly to a source repo's `package.json`
78
+
79
+ ## `well_known_src_json`
80
+
81
+ If your root `package.json` has `"public": true`,
82
+ by default Gro creates `.well-known/src.json` and `.well-known/src/`
83
+ in `static/` during `vite build`,
84
+ so they're included in the SvelteKit build output.
85
+ More [about public packages](./package_json.md#public-packages).
86
+
87
+ This can be customized with `well_known_src_json`.
88
+ Setting it to `false` disables the feature, and `true` enables it.
89
+ Setting it to a function maps the final `src.json` value - returning `null` disables it.
90
+
91
+ The `.well-known/src.json` file contains more details about
92
+ the `package.json`'s `exports`, like exported identifier names and types.
93
+ It maps each export to a source file in `.well-known/src/`.
94
+
95
+ The contents of your `src/` directory are copied to `.well-known/src/`
96
+ using the same filter as `exports` in `package.json` by default,
97
+ and this can be customized with `filter_well_known_src`.
@@ -0,0 +1,29 @@
1
+ # `package.json`
2
+
3
+ Gro extends [`package.json`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json)
4
+ with additional functionality.
5
+
6
+ ## `public` packages
7
+
8
+ Setting `"public": true` in `package.json` opts into
9
+ behavior designed for public open source projects:
10
+
11
+ - [`gro_plugin_sveltekit_app`](./gro_plugin_sveltekit_app.md)
12
+ copies `package.json` from your project root to your
13
+ SvelteKit static directory at `.well-known/package.json` during `vite build`,
14
+ mapping it with the optional
15
+ [`well_known_package_json` option](./gro_plugin_sveltekit_app.md#well_known_package_json)
16
+ - `gro_plugin_sveltekit_app` outputs `.well-known/src.json`
17
+ using the `exports` property of `package.json` during `vite build`,
18
+ containing additional information about the source modules,
19
+ mapping it with the optional
20
+ [`well_known_src_json` option](./gro_plugin_sveltekit_app.md#well_known_src_json)
21
+ - `gro_plugin_sveltekit_app` outputs `.well-known/src/` by
22
+ copying over `src/` filtered by `filter_well_known_src` during `vite build` -
23
+ this is costly (usually more than doubling the final output size
24
+ of the code files in bytes, not counting images and such),
25
+ and it slows the build because it copies your entire source tree (sorry to hard drives),
26
+ but the UX is not affected
27
+
28
+ > ⚠️ Setting `"public": true` in `package.json` exposes your source code at your deployed endpoint!
29
+ > If that's the public web, that means your source code is public.
@@ -0,0 +1,50 @@
1
+ # plugin
2
+
3
+ During the [`gro dev`](dev.md) and [`gro build`](build.md) tasks,
4
+ Gro uses `Plugin`s to support custom usecases outside of the normal build pipeline.
5
+
6
+ In this early implementation of plugins in Gro,
7
+ plugins run serially, in the order they are returned from `plugins` in the `gro.config.ts`.
8
+ Each step of Gro's build processes - `gro dev` for development and `gro build` for production -
9
+ runs a method of each plugin, batched together as `setup -> adapt -> teardown`,
10
+ with some behavioral inconsistencies:
11
+
12
+ - `adapt` only runs during production aka `gro build`
13
+ - `teardown` does not run for `gro dev` in the default `watch` mode,
14
+ but it does run with `gro dev --no-watch`
15
+ - there should probably be a finalization step that runs `teardown` on uncaught exceptions
16
+
17
+ The API needs to be improved for more advanced usecases,
18
+ currently it offers little flexibility -
19
+ we'll follow the Vite/SvelteKit APIs probably. (`pre` etc)
20
+ Maybe let you map the array of each method batch. (is that possible with those?)
21
+
22
+ Gro's builtin plugins:
23
+
24
+ - [`@ryanatkn/gro_plugin_server`](../gro_plugin_server.ts)
25
+ - [`@ryanatkn/gro_plugin_sveltekit_library`](../gro_plugin_sveltekit_library.ts)
26
+ - [`@ryanatkn/gro_plugin_sveltekit_app`](../gro_plugin_sveltekit_app.ts)
27
+ - [`@ryanatkn/gro_plugin_gen`](../gro_plugin_gen.ts)
28
+ (currently disabled, will be replaced with an esbuild plugin)
29
+
30
+ Also see [`config.plugin` in the config docs](config.md#plugin)
31
+ and usage in [the default config](../gro.config.default.ts).
32
+ The default config detects which plugins are included by inspecting the current project.
33
+
34
+ The implementation is at [`src/lib/plugin.ts`](../plugin.ts) with more details.
35
+
36
+ ```ts
37
+ export interface Plugin<T_Plugin_Context extends Plugin_Context = Plugin_Context> {
38
+ name: string;
39
+ setup?: (ctx: T_Plugin_Context) => void | Promise<void>;
40
+ adapt?: (ctx: T_Plugin_Context) => void | Promise<void>;
41
+ teardown?: (ctx: T_Plugin_Context) => void | Promise<void>;
42
+ }
43
+
44
+ export interface Plugin_Context<T_Args = object> extends Task_Context<T_Args> {
45
+ dev: boolean;
46
+ watch: boolean;
47
+ }
48
+ ```
49
+
50
+ The `adapt` step only runs for production during `gro build`, taking after SvelteKit adapters.
@@ -0,0 +1,144 @@
1
+ # publish
2
+
3
+ Here's how to publish a new version of a repo with Gro, including for Gro itself.
4
+
5
+ ## svelte-package
6
+
7
+ Gro uses SvelteKit's [`@sveltejs/package`](https://kit.svelte.dev/docs/packaging)
8
+ with the task `gro publish` to publish packages to npm.
9
+ Gro's default config enables [`@ryanatkn/gro/gro_plugin_sveltekit_library.js`](../gro_plugin_sveltekit_library.ts)
10
+ if it detects `@sveltejs/package` installed as a dependency in the package.json.
11
+
12
+ ```bash
13
+ # enable `gro publish` to publish to npm:
14
+ npm i -D @sveltejs/package # enables `@ryanatkn/gro/gro_plugin_sveltekit_library.js`
15
+ gro sync # updates package.json "exports"
16
+ git commit -am "..."
17
+ # `gro publish` calls `svelte-package`
18
+ ```
19
+
20
+ ## login to npm
21
+
22
+ ```bash
23
+ npm whoami # check if you're logged in
24
+
25
+ # not logged in?
26
+ npm login # and follow the instructions
27
+ ```
28
+
29
+ > more about [`npm login`](https://docs.npmjs.com/v6/commands/npm-adduser)
30
+
31
+ ## using changesets
32
+
33
+ The [`gro publish` task](https://github.com/ryanatkn/gro/blob/main/src/lib/publish.task.ts)
34
+ integrates with [Changesets](https://github.com/changesets/changesets)
35
+ to publish packages to [npm](https://npmjs.com/). Internally the task calls both
36
+ [`changeset version`](https://github.com/changesets/changesets/blob/main/packages/README.md#version)
37
+ and
38
+ [`changeset publish`](https://github.com/changesets/changesets/blob/main/packages/README.md#publish).
39
+
40
+ Gro does not include Changesets as a dependency.
41
+ Install it globally or local to your repo
42
+ (I prefer global, it's not a light dependency):
43
+
44
+ ```bash
45
+ npm i -g @changesets/cli # install globally
46
+ npm i -D @changesets/cli # or install local to your repo
47
+ ```
48
+
49
+ To [init Changesets](https://github.com/changesets/changesets/blob/main/packages/README.md#init)
50
+ in a repo or [add](https://github.com/changesets/changesets/blob/main/packages/README.md#add)
51
+ a changeset to an already-inited repo, use `gro changeset`:
52
+
53
+ ```bash
54
+ gro changeset # inits or adds a changeset
55
+ gro changeset --help # prints:
56
+ gro changeset: call changeset with gro patterns
57
+
58
+ [...args] string[] [] the commands to pass to changeset
59
+ path string './.changeset/config.json' changeset config file path
60
+ access 'restricted' | 'public' undefined changeset 'access' config value, the default depends on package.json#private
61
+ changelog string '@changesets/changelog-git' changeset "changelog" config value
62
+ no-install boolean false opt out of npm installing the changelog package
63
+
64
+ # `gro changeset` is equivalent to:
65
+ changeset init # if needed -- prefix with `npx ` if installed only locally
66
+ changeset
67
+ git add .changeset/$FILE
68
+ # TODO include a `git commit` flag or default behavior, maybe `gro changeset "message"`
69
+ ```
70
+
71
+ After initing, optionally configure and install a custom changelog package
72
+ in the `"changelog"` property of the newly created `.changeset/config.json`:
73
+
74
+ ```diff
75
+ # .changeset/config.json
76
+ - "changelog": "@changesets/changelog",
77
+ + "changelog": "@changesets/changelog-git",
78
+ ```
79
+
80
+ ```bash
81
+ npm i -D @changesets/changelog-git # a minimal package that requires no GitHub auth
82
+ ```
83
+
84
+ Gro inits `"access"` based on the package.json `"private": true` value.
85
+ To manually configure the `access` property:
86
+
87
+ ```diff
88
+ # .changeset/config.json
89
+ - "access": "public",
90
+ + "access": "restricted",
91
+ ```
92
+
93
+ See [the Changesets docs](https://github.com/changesets/changesets) for more.
94
+
95
+ ## GitHub API setup
96
+
97
+ Gro currently expects repos to be on GitHub to generate changelogs with Changesets.
98
+ (sorry, maybe in the future we'll support other forges)
99
+
100
+ Gro modifies the barebones changelog generated by `@changesets/changelog-git`,
101
+ doing things like linkifying commit hashes or linking to PRs if they exist.
102
+ The difference between Gro's version and `@changesets/changelog-github` is that Gro
103
+ doesn't require a token for authorization for public repos,
104
+ and Gro makes some different choices for usability.
105
+
106
+ Gro calls the GitHub API using the environment variable `GITHUB_TOKEN_SECRET` for authorization,
107
+ which is a [GitHub token](https://github.com/settings/tokens)
108
+ (with "public access" for public repos, no options selected)
109
+ in either `process.env`, a project-local `.env`, or the parent directory at `../.env`
110
+ (currently optional to read public repos, but it's recommended regardless,
111
+ and you'll need to select options to support private repos).
112
+
113
+ You'll get a warning if the token is unavailable, but for light usage you won't hit rate limts.
114
+
115
+ ## `gro publish`
116
+
117
+ The publish task builds the project, bumps the version, publishes to npm,
118
+ commits the changes, and then pushes the commit and tag.
119
+
120
+ Ensure `"dist"` is in the `"files"` property of `package.json`:
121
+
122
+ ```json
123
+ "files": [
124
+ "dist"
125
+ ],
126
+ ```
127
+
128
+ Then publish:
129
+
130
+ ```bash
131
+ gro publish
132
+ gro publish --help # view the options
133
+ gro publish -- svelte-package -w # forward options
134
+ ```
135
+
136
+ See [the SvelteKit packaging docs](https://kit.svelte.dev/docs/packaging) for more.
137
+
138
+ If `changeset publish` fails during `gro publish`,
139
+ the task exits without pushing anything to the remote origin.
140
+ It does however create the version commit and tag.
141
+ A common failure is not being logged into npm. (see the instructions above)
142
+ If the builds are correct but `changeset publish` failed,
143
+ and you don't want to undo the version commit and tag,
144
+ you can continue manually with `changeset publish` or `npm publish`.