@ryanatkn/gro 0.129.6 → 0.129.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -30
- package/dist/config.d.ts +3 -3
- package/dist/gen.test.js +1 -1
- package/dist/invoke.js +1 -1
- package/dist/package.js +2 -2
- package/dist/src_json.d.ts +1 -1
- package/dist/src_json.js +1 -1
- package/package.json +1 -1
- package/src/lib/config.ts +3 -3
- package/src/lib/gen.test.ts +1 -1
- package/src/lib/invoke.ts +1 -1
- package/src/lib/package.ts +2 -2
- package/src/lib/src_json.ts +1 -1
- package/dist/docs/README.gen.md.d.ts +0 -6
- package/dist/docs/README.gen.md.d.ts.map +0 -1
- package/dist/docs/README.gen.md.js +0 -53
- package/dist/docs/README.md +0 -20
- package/dist/docs/build.md +0 -41
- package/dist/docs/config.md +0 -213
- package/dist/docs/deploy.md +0 -32
- package/dist/docs/dev.md +0 -40
- package/dist/docs/gen.md +0 -269
- package/dist/docs/gro_plugin_sveltekit_app.md +0 -113
- package/dist/docs/package_json.md +0 -33
- package/dist/docs/plugin.md +0 -50
- package/dist/docs/publish.md +0 -137
- package/dist/docs/task.md +0 -391
- package/dist/docs/tasks.gen.md.d.ts +0 -3
- package/dist/docs/tasks.gen.md.d.ts.map +0 -1
- package/dist/docs/tasks.gen.md.js +0 -66
- package/dist/docs/tasks.md +0 -37
- package/dist/docs/test.md +0 -52
- package/src/lib/docs/README.gen.md.ts +0 -63
- package/src/lib/docs/README.md +0 -20
- package/src/lib/docs/build.md +0 -41
- package/src/lib/docs/config.md +0 -213
- package/src/lib/docs/deploy.md +0 -32
- package/src/lib/docs/dev.md +0 -40
- package/src/lib/docs/gen.md +0 -269
- package/src/lib/docs/gro_plugin_sveltekit_app.md +0 -113
- package/src/lib/docs/package_json.md +0 -33
- package/src/lib/docs/plugin.md +0 -50
- package/src/lib/docs/publish.md +0 -137
- package/src/lib/docs/task.md +0 -391
- package/src/lib/docs/tasks.gen.md.ts +0 -90
- package/src/lib/docs/tasks.md +0 -37
- package/src/lib/docs/test.md +0 -52
package/src/lib/docs/config.md
DELETED
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
# config
|
|
2
|
-
|
|
3
|
-
Gro supports SvelteKit apps, Node libraries, and Node servers with minimal abstraction
|
|
4
|
-
with the help of an optional config file that lives at the root `gro.config.ts`.
|
|
5
|
-
If a project does not define a config, Gro imports a default config from
|
|
6
|
-
[`src/lib/gro.config.default.ts`](/src/lib/gro.config.default.ts),
|
|
7
|
-
which looks at your project for the familiar patterns and tries to do the right thing.
|
|
8
|
-
|
|
9
|
-
> The [default config](/src/lib/gro.config.default.ts)
|
|
10
|
-
> detects three types of projects that can coexist in one repo:
|
|
11
|
-
> SvelteKit frontends,
|
|
12
|
-
> Node libraries with [`@sveltejs/package`](https://kit.svelte.dev/docs/packaging),
|
|
13
|
-
> and Node servers.
|
|
14
|
-
|
|
15
|
-
See [`src/lib/config.ts`](/src/lib/config.ts) for the config types and implementation.
|
|
16
|
-
|
|
17
|
-
## examples
|
|
18
|
-
|
|
19
|
-
[The default config](/src/lib/gro.config.default.ts)
|
|
20
|
-
is used for projects that do not define `gro.config.ts`.
|
|
21
|
-
It's also passed as the first argument to `Create_Gro_Config`.
|
|
22
|
-
|
|
23
|
-
A simple config that does nothing:
|
|
24
|
-
|
|
25
|
-
```ts
|
|
26
|
-
// gro.config.ts
|
|
27
|
-
import type {Create_Gro_Config} from '@ryanatkn/gro';
|
|
28
|
-
|
|
29
|
-
const config: Create_Gro_Config = async (cfg) => {
|
|
30
|
-
// mutate `cfg` or return a new object
|
|
31
|
-
return cfg;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export default config;
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
The default export of a Gro config is `Gro_Config | Create_Gro_Config`:
|
|
38
|
-
|
|
39
|
-
```ts
|
|
40
|
-
export interface Create_Gro_Config {
|
|
41
|
-
(base_config: Gro_Config): Raw_Gro_Config | Promise<Raw_Gro_Config>;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// The strict variant that's used internally and exposed to users in tasks and elsewhere.
|
|
45
|
-
export interface Gro_Config {
|
|
46
|
-
plugins: Create_Config_Plugins;
|
|
47
|
-
map_package_json: Map_Package_Json | null;
|
|
48
|
-
task_root_dirs: Path_Id[];
|
|
49
|
-
search_filters: Path_Filter[];
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// The relaxed variant that users can provide. Superset of `Gro_Config`.
|
|
53
|
-
export interface Raw_Gro_Config {
|
|
54
|
-
plugins?: Create_Config_Plugins;
|
|
55
|
-
map_package_json?: Map_Package_Json | null;
|
|
56
|
-
task_root_dirs?: string[];
|
|
57
|
-
search_filters?: Path_Filter | Path_Filter[] | null;
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
To define a user config that overrides the default plugins:
|
|
62
|
-
|
|
63
|
-
```ts
|
|
64
|
-
import type {Create_Gro_Config} from '@ryanatkn/gro';
|
|
65
|
-
import {gro_plugin_sveltekit_app} from '@ryanatkn/gro/gro_plugin_sveltekit_app.js';
|
|
66
|
-
|
|
67
|
-
const config: Create_Gro_Config = async (cfg) => {
|
|
68
|
-
// `cfg`, which has type `Gro_Config` and is equal to `create_empty_config()`,
|
|
69
|
-
// can be mutated or you can return your own.
|
|
70
|
-
// A return value is required to avoid potential errors and reduce ambiguity.
|
|
71
|
-
|
|
72
|
-
// example setting your own plugins):
|
|
73
|
-
cfg.plugins = async () => [
|
|
74
|
-
gro_plugin_sveltekit_app(),
|
|
75
|
-
(await import('./src/custom_plugin.js')).plugin(),
|
|
76
|
-
];
|
|
77
|
-
|
|
78
|
-
// example extending the default plugins:
|
|
79
|
-
const get_base_plugins = cfg.plugins;
|
|
80
|
-
cfg.plugins = async (ctx) => {
|
|
81
|
-
// replace a base plugin with `import {replace_plugin} from '@ryanatkn/gro';`:
|
|
82
|
-
const updated_plugins = replace_plugin(
|
|
83
|
-
await get_base_plugins(ctx),
|
|
84
|
-
gro_plugin_sveltekit_app({
|
|
85
|
-
// host_target?: Host_Target;
|
|
86
|
-
// well_known_package_json?: boolean | Map_Package_Json;
|
|
87
|
-
}),
|
|
88
|
-
// 'gro_plugin_sveltekit_app', // optional name if they don't match
|
|
89
|
-
);
|
|
90
|
-
return updated_plugins.concat(create_some_custom_plugin());
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
return cfg; // return type is `Raw_Gro_Config`, which is a relaxed superset of `Gro_Config`
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
export default config;
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
You can also export a config object and use `create_empty_config` to get the defaults:
|
|
100
|
-
|
|
101
|
-
```ts
|
|
102
|
-
import {create_empty_config} from '@ryanatkn/gro/config.js';
|
|
103
|
-
|
|
104
|
-
const config = create_empty_config();
|
|
105
|
-
|
|
106
|
-
// config.plugins = ...;
|
|
107
|
-
// config.map_package_json = ...;
|
|
108
|
-
// config.task_root_dirs = ...;
|
|
109
|
-
// config.search_filters = ...;
|
|
110
|
-
|
|
111
|
-
export default config;
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
See also [Gro's own internal config](/gro.config.ts).
|
|
115
|
-
|
|
116
|
-
## `plugins`
|
|
117
|
-
|
|
118
|
-
The `plugins` property is a function that returns an array of `Plugin` instances.
|
|
119
|
-
Read more about plugins and the `Plugin` in
|
|
120
|
-
[plugin.md](plugin.md), [dev.md](dev.md#plugin), and [build.md](build.md#plugin).
|
|
121
|
-
|
|
122
|
-
```ts
|
|
123
|
-
export interface Create_Config_Plugins<T_Plugin_Context extends Plugin_Context = Plugin_Context> {
|
|
124
|
-
(
|
|
125
|
-
ctx: T_Plugin_Context,
|
|
126
|
-
):
|
|
127
|
-
| (Plugin<T_Plugin_Context> | null | Array<Plugin<T_Plugin_Context> | null>)
|
|
128
|
-
| Promise<Plugin<T_Plugin_Context> | null | Array<Plugin<T_Plugin_Context> | null>>;
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## `map_package_json`
|
|
133
|
-
|
|
134
|
-
The Gro config option `map_package_json` hooks into Gro's `package.json` automations.
|
|
135
|
-
The `gro sync` task, which is called during the dev and build tasks among others,
|
|
136
|
-
performs several steps to get a project's state ready,
|
|
137
|
-
including `svelte-kit sync` and `package.json` automations.
|
|
138
|
-
When the `map_package_json` config value is truthy,
|
|
139
|
-
Gro outputs a mapped version of the root `package.json`.
|
|
140
|
-
|
|
141
|
-
> The `gro check` task integrates with `map_package_json` to ensure everything is synced.
|
|
142
|
-
|
|
143
|
-
The main purpose of `map_package_json` is to automate
|
|
144
|
-
the `"exports"` property of your root `package.json`.
|
|
145
|
-
The motivation is to streamline package publishing by supplementing
|
|
146
|
-
[`@sveltejs/package`](https://kit.svelte.dev/docs/packaging).
|
|
147
|
-
|
|
148
|
-
By default `package_json.exports` includes everything from `$lib/`
|
|
149
|
-
except for some ignored files like tests and markdown,
|
|
150
|
-
and you can provide your own `map_package_json` hook to
|
|
151
|
-
mutate the `package_json`, return new data, or return `null` to be a no-op.
|
|
152
|
-
|
|
153
|
-
Typical usage modifies `package_json.exports` during this step to define the public API.
|
|
154
|
-
|
|
155
|
-
### using `map_package_json`
|
|
156
|
-
|
|
157
|
-
```ts
|
|
158
|
-
// gro.config.ts
|
|
159
|
-
const config: Gro_Config = {
|
|
160
|
-
// ...other config
|
|
161
|
-
|
|
162
|
-
// disable mapping `package.json` with automated `exports`:
|
|
163
|
-
map_package_json: null,
|
|
164
|
-
|
|
165
|
-
// mutate anything and return the final config (can be async):
|
|
166
|
-
map_package_json: (package_json) => {
|
|
167
|
-
// example setting `exports`:
|
|
168
|
-
package_json.exports = {
|
|
169
|
-
'.': {
|
|
170
|
-
default: './dist/index.js',
|
|
171
|
-
types: './dist/index.d.ts',
|
|
172
|
-
},
|
|
173
|
-
'./example.js': {
|
|
174
|
-
default: './dist/example.js',
|
|
175
|
-
types: './dist/example.d.ts',
|
|
176
|
-
},
|
|
177
|
-
'./Example.svelte': {
|
|
178
|
-
svelte: './dist/Example.svelte',
|
|
179
|
-
types: './dist/Example.svelte.d.ts',
|
|
180
|
-
},
|
|
181
|
-
};
|
|
182
|
-
// example filtering `exports`:
|
|
183
|
-
package_json.exports = Object.fromEntries(
|
|
184
|
-
Object.entries(package_json.exports).filter(/* ... */),
|
|
185
|
-
);
|
|
186
|
-
return package_json; // returning `null` is a no-op
|
|
187
|
-
},
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
export interface Map_Package_Json {
|
|
191
|
-
(package_json: Package_Json): Package_Json | null | Promise<Package_Json | null>;
|
|
192
|
-
}
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
## `task_root_dirs`
|
|
196
|
-
|
|
197
|
-
The Gro config option `task_root_dirs` allows customizing Gro's task resolution.
|
|
198
|
-
When calling `gro [input_path]`, absolute and explicitly relative paths starting with `.`
|
|
199
|
-
are resolved according to normal filesystem rules,
|
|
200
|
-
but non-explicit input paths, like `foo`, are resolved by searching
|
|
201
|
-
through `task_root_dirs` in order until a matching file or directory is found on the filesystem.
|
|
202
|
-
|
|
203
|
-
The default task paths are `./src/lib`, then `.`, and then Gro's dist directory.
|
|
204
|
-
|
|
205
|
-
## `search_filters`
|
|
206
|
-
|
|
207
|
-
The Gro config option `search_filters` allows customizing
|
|
208
|
-
how Gro searches for tasks and genfiles on the filesystem.
|
|
209
|
-
Directories and files are included if they pass all of these filters.
|
|
210
|
-
|
|
211
|
-
By default, it uses the `DEFAULT_SEARCH_EXCLUDER` to exclude
|
|
212
|
-
dot-prefixed directories, node_modules,
|
|
213
|
-
and the build and dist directories for SvelteKit and Gro.
|
package/src/lib/docs/deploy.md
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# deploy
|
|
2
|
-
|
|
3
|
-
The [`gro deploy`](/src/lib/deploy.task.ts)
|
|
4
|
-
task was originally designed to support static deployments to
|
|
5
|
-
[GitHub pages](https://pages.github.com/),
|
|
6
|
-
but what it actually does is just [build](./build.md) and push to a branch.
|
|
7
|
-
|
|
8
|
-
Importantly, Gro **destructively force pushes** to the `--target` branch, `deploy` by default.
|
|
9
|
-
This is because Gro treats your deployment
|
|
10
|
-
branch as disposable, able to be deleted or squashed or whatever whenever.
|
|
11
|
-
Internally, `gro deploy` uses [git worktree](https://git-scm.com/docs/git-worktree)
|
|
12
|
-
for tidiness.
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
gro deploy # prepare build/ and commit it to the `deploy` branch, then push to go live
|
|
16
|
-
gro deploy --source my-branch # deploy from `my-branch` instead of the default `main`
|
|
17
|
-
|
|
18
|
-
# deploy to `custom-deploy-branch` instead of the default `deploy`
|
|
19
|
-
# WARNING! this force pushes to the target branch!
|
|
20
|
-
gro deploy --target custom-deploy-branch
|
|
21
|
-
# the above actually fails because force pushing is destructive, so add `--force` to be extra clear:
|
|
22
|
-
gro deploy --target custom-deploy-branch --force
|
|
23
|
-
# TODO maybe it should be `--dangerous-target-branch` instead of `--target` and `--force`?
|
|
24
|
-
|
|
25
|
-
gro deploy --dry # prepare build/ but don't commit or push
|
|
26
|
-
gro deploy --clean # if something goes wrong, use this to reset git and gro state
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Run `gro deploy --help` or see [`src/lib/deploy.task.ts`](/src/lib/deploy.task.ts) for the details.
|
|
30
|
-
|
|
31
|
-
For needs more advanced than pushing to a remote branch,
|
|
32
|
-
projects can implement a custom `src/lib/deploy.task.ts`.
|
package/src/lib/docs/dev.md
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
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/logo.svg" alt="a pixelated green oak acorn with a glint of sun" width="192" height="192">
|
|
39
|
-
</a>
|
|
40
|
-
</p>
|
package/src/lib/docs/gen.md
DELETED
|
@@ -1,269 +0,0 @@
|
|
|
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
|
-
> ⚠️ Generated files should never be edited directly,
|
|
56
|
-
> because the next time `gro gen` or `gro sync` runs,
|
|
57
|
-
> any uncommitted changes will be lost!
|
|
58
|
-
> I considered making `gen` only write to files that have no uncommitted changes,
|
|
59
|
-
> but that would impede many workflows,
|
|
60
|
-
> and I don't want to nudge users towards a habit of always adding an override flag.
|
|
61
|
-
> I can see one possible improvement that lets the user
|
|
62
|
-
> opt into making gen write only to unchanged files for those workflows that don't mind it,
|
|
63
|
-
> so if you would like to see that or something similar,
|
|
64
|
-
> please open an issue or [share your thoughts on Discord](https://discord.gg/YU5tyeK72X).
|
|
65
|
-
|
|
66
|
-
Inspirations include Lisp macros, the
|
|
67
|
-
[Svelte](https://github.com/sveltejs/svelte) compiler,
|
|
68
|
-
and [Zig](https://github.com/ziglang/zig)'s comptime.
|
|
69
|
-
(but `gro gen` is far more primitive)
|
|
70
|
-
|
|
71
|
-
## usage
|
|
72
|
-
|
|
73
|
-
The `gro gen` task looks for any files with `.gen.`
|
|
74
|
-
in the file name and tries to call an exported `gen`
|
|
75
|
-
function to generate one or more output files,
|
|
76
|
-
and then it writes the results to the filesystem.
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
gro gen # runs codegen for all *.gen.* files in src/
|
|
80
|
-
gro gen --check # exits with error code 1 if anything is new or different; no-op to the fs
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
> in the following examples,
|
|
84
|
-
> but it makes for a better DX
|
|
85
|
-
|
|
86
|
-
### generate arbitrary TypeScript
|
|
87
|
-
|
|
88
|
-
Given `src/script.gen.ts`:
|
|
89
|
-
|
|
90
|
-
```ts
|
|
91
|
-
import type {Gen} from '@ryanatkn/gro';
|
|
92
|
-
|
|
93
|
-
export const gen: Gen = () => {
|
|
94
|
-
const message = 'generated';
|
|
95
|
-
return `console.log('${message} a ${typeof message}')`;
|
|
96
|
-
};
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
Outputs `src/script.ts`:
|
|
100
|
-
|
|
101
|
-
```ts
|
|
102
|
-
console.log('generated a string');
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### gen context
|
|
106
|
-
|
|
107
|
-
The `Gen` function receives one argument, the `Gen_Context` object:
|
|
108
|
-
|
|
109
|
-
```ts
|
|
110
|
-
export interface Gen_Context {
|
|
111
|
-
config: Gro_Config;
|
|
112
|
-
sveltekit_config: Parsed_Sveltekit_Config;
|
|
113
|
-
/**
|
|
114
|
-
* Same as `import.meta.url` but in path form.
|
|
115
|
-
*/
|
|
116
|
-
origin_id: Path_Id;
|
|
117
|
-
log: Logger;
|
|
118
|
-
}
|
|
119
|
-
// export const gen: Gen = ({config, origin_id, log}) => {
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### generate other filetypes
|
|
123
|
-
|
|
124
|
-
Files with any extension can be generated without configuration.
|
|
125
|
-
If the origin file name ends with the pattern `.gen.*.ts`,
|
|
126
|
-
the default output file name is stripped of its trailing `.ts`.
|
|
127
|
-
|
|
128
|
-
Given `src/markup.gen.html.ts`:
|
|
129
|
-
|
|
130
|
-
```ts
|
|
131
|
-
import type {Gen} from '@ryanatkn/gro';
|
|
132
|
-
|
|
133
|
-
export const gen: Gen = () => {
|
|
134
|
-
const body = 'hi';
|
|
135
|
-
return `
|
|
136
|
-
<!DOCTYPE html>
|
|
137
|
-
<html>
|
|
138
|
-
<body>
|
|
139
|
-
${body}
|
|
140
|
-
</body>
|
|
141
|
-
</html>
|
|
142
|
-
`;
|
|
143
|
-
};
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
Outputs `src/markup.html`:
|
|
147
|
-
|
|
148
|
-
```html
|
|
149
|
-
<!doctype html>
|
|
150
|
-
<html>
|
|
151
|
-
<body>
|
|
152
|
-
hi
|
|
153
|
-
</body>
|
|
154
|
-
</html>
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### generate a custom file name or write to a different directory
|
|
158
|
-
|
|
159
|
-
The `gen` function can return an object with custom configuration.
|
|
160
|
-
|
|
161
|
-
Given `src/somewhere/originalName.gen.ts`:
|
|
162
|
-
|
|
163
|
-
```ts
|
|
164
|
-
import type {Gen} from '@ryanatkn/gro';
|
|
165
|
-
|
|
166
|
-
export const gen: Gen = () => {
|
|
167
|
-
const message = 'output path can be relative and name can be anything';
|
|
168
|
-
return {
|
|
169
|
-
content: `console.log('${message}')`,
|
|
170
|
-
filename: '../elsewhere/otherName.ts',
|
|
171
|
-
format: optional_boolean_that_defaults_to_true,
|
|
172
|
-
};
|
|
173
|
-
};
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
Outputs `src/elsewhere/otherName.ts`:
|
|
177
|
-
|
|
178
|
-
```ts
|
|
179
|
-
console.log('output path can be relative and name can be anything');
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### generate multiple custom files
|
|
183
|
-
|
|
184
|
-
The `gen` function can also return an array of files.
|
|
185
|
-
|
|
186
|
-
Given `src/thing.gen.ts`:
|
|
187
|
-
|
|
188
|
-
```ts
|
|
189
|
-
import type {Gen} from '@ryanatkn/gro';
|
|
190
|
-
|
|
191
|
-
export const gen: Gen = () => {
|
|
192
|
-
const fieldValue = 1;
|
|
193
|
-
return [
|
|
194
|
-
{
|
|
195
|
-
content: `
|
|
196
|
-
import {Thing} from './index';
|
|
197
|
-
export const isThing = (t: any): t is Thing => t?.field === ${fieldValue};
|
|
198
|
-
`,
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
content: `export interface Thing { field: ${typeof fieldValue} }`,
|
|
202
|
-
filename: 'types.ts',
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
content: `{"field": ${fieldValue}}`,
|
|
206
|
-
filename: 'data/thing.json',
|
|
207
|
-
},
|
|
208
|
-
];
|
|
209
|
-
};
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
Outputs `src/thing.ts`:
|
|
213
|
-
|
|
214
|
-
```ts
|
|
215
|
-
import type {Thing} from './index.js';
|
|
216
|
-
export const isThing = (t: any): t is Thing => t?.field === 1;
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
and `src/types.ts`:
|
|
220
|
-
|
|
221
|
-
```ts
|
|
222
|
-
export interface Thing {
|
|
223
|
-
field: number;
|
|
224
|
-
}
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
and `src/data/thing.json`:
|
|
228
|
-
|
|
229
|
-
```json
|
|
230
|
-
{
|
|
231
|
-
"field": 1
|
|
232
|
-
}
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
It's often helpful to check if any generated files are new or have changed.
|
|
236
|
-
We don't want to forget to regenerate files before committing or publishing!
|
|
237
|
-
The `check` CLI argument can be passed to perform this check
|
|
238
|
-
instead of writing the generated files to disk.
|
|
239
|
-
|
|
240
|
-
```bash
|
|
241
|
-
gro gen --check # exits with error code 1 if anything is new or different; no-op to the fs
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
or in code:
|
|
245
|
-
|
|
246
|
-
```ts
|
|
247
|
-
import type {Task} from '@ryanatkn/gro';
|
|
248
|
-
|
|
249
|
-
export const task: Task = {
|
|
250
|
-
run: async ({args, invoke_task}) => {
|
|
251
|
-
// this throws a `Task_Error` if anything is new or different
|
|
252
|
-
await invoke_task('gen', {...args, check: true});
|
|
253
|
-
},
|
|
254
|
-
};
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
Gro uses this in [`check.task.ts`](/src/lib/check.task.ts)
|
|
258
|
-
which is called during `gro publish`, and it's recommended in CI.
|
|
259
|
-
(see [Gro's example `check.yml`](/.github/workflows/check.yml))
|
|
260
|
-
|
|
261
|
-
## todo
|
|
262
|
-
|
|
263
|
-
- [x] basic functionality
|
|
264
|
-
- [x] format output with Prettier
|
|
265
|
-
- [x] [watch mode and build integration](https://github.com/ryanatkn/gro/pull/283),
|
|
266
|
-
opt out with `watch: false` for expensive gen use cases
|
|
267
|
-
- [ ] change the exported `gen` function to an object with a `summary` and other properties like `watch`
|
|
268
|
-
- [ ] support generating non-text files
|
|
269
|
-
- [ ] think about how to handle gen file dependency graphs (generated files as inputs to gen files)
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
# SvelteKit app plugin
|
|
2
|
-
|
|
3
|
-
Gro's [SvelteKit app 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
|
-
// well_known_src_files?: boolean | Copy_File_Filter;
|
|
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 Copy_File_Filter {
|
|
30
|
-
(file_path: string): boolean | Promise<boolean>;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// src/lib/package_json.ts
|
|
34
|
-
export interface Map_Package_Json {
|
|
35
|
-
(package_json: Package_Json): Package_Json | null | Promise<Package_Json | null>;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// src/lib/src_json.ts
|
|
39
|
-
export interface Map_Src_Json {
|
|
40
|
-
(src_json: Src_Json): Src_Json | null | Promise<Src_Json | null>;
|
|
41
|
-
}
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## `host_target`
|
|
45
|
-
|
|
46
|
-
When `host_target` is the default value `'github_pages'`,
|
|
47
|
-
a `.nojekyll` file is included in the build to tell GitHub Pages not to process it with Jekyll.
|
|
48
|
-
|
|
49
|
-
## `well_known_package_json`
|
|
50
|
-
|
|
51
|
-
If your root `package.json` has `"public": true`
|
|
52
|
-
(telling Gro it's a [public package](./package_json.md#public-packages)),
|
|
53
|
-
by default Gro copies `.well-known/package.json` to `static/` during `vite build`,
|
|
54
|
-
so it's included in the SvelteKit build output.
|
|
55
|
-
The motivation is to provide conventional package metadata to web users and tools.
|
|
56
|
-
(more details below)
|
|
57
|
-
|
|
58
|
-
> ⚠️ Outputting `.well-known/package.json` will surprise some users
|
|
59
|
-
> and could result in information leaks that compromise privacy or security.
|
|
60
|
-
> The feature is enabled only when your root `package.json` has `"public": true`.
|
|
61
|
-
> Templates that default to public should prominently warn their users.
|
|
62
|
-
|
|
63
|
-
By default the root `package.json` is copied without modifications,
|
|
64
|
-
and you can provide your own `well_known_package_json` option to
|
|
65
|
-
mutate the `package_json`, return new data, or return `null` to be a no-op.
|
|
66
|
-
|
|
67
|
-
> Writing to `.well-known/package.json` is unstandardized behavior that
|
|
68
|
-
> extends [Well-known URIs](https://wikipedia.org/wiki/Well-known_URIs) for Node packages
|
|
69
|
-
> to provide conventional metadata for deployed websites.
|
|
70
|
-
> [Mastodon](<https://en.wikipedia.org/wiki/Mastodon_(social_network)>) uses
|
|
71
|
-
> [WebFinger](https://en.wikipedia.org/wiki/WebFinger) which uses `.well-known` for discovery.
|
|
72
|
-
> One difference is that SvelteKit outputs static files relative to the configured `base` path,
|
|
73
|
-
> so the `.well-known` directory may not be in the root `/`.
|
|
74
|
-
> This is useful because it enables websites to provide metadata even when hosted in a namespaced
|
|
75
|
-
> path like `username.github.io/projectname/.well-known`.
|
|
76
|
-
|
|
77
|
-
Why publish this metadata to the web instead of relying on the git repo as the only source of truth?
|
|
78
|
-
|
|
79
|
-
- we want to give all web users and tools access to discoverable package metadata
|
|
80
|
-
- metadata is a much lighter dependency than an entire repo
|
|
81
|
-
- some repos are deployed to multiple websites with metadata differences
|
|
82
|
-
- some repos like monorepos have multiple `package.json` files
|
|
83
|
-
- we don't want to force a dependency on git, the bespoke URLs of forge hosts like GitHub,
|
|
84
|
-
or any particular toolchains
|
|
85
|
-
- the git repo is still the source of truth, but Gro adds a build step for project metadata,
|
|
86
|
-
giving devs full control over the published artifacts
|
|
87
|
-
instead of coupling metadata directly to a source repo's `package.json`
|
|
88
|
-
|
|
89
|
-
## `well_known_src_json`
|
|
90
|
-
|
|
91
|
-
If your root `package.json` has `"public": true`,
|
|
92
|
-
by default Gro creates `.well-known/src.json` and `.well-known/src/`
|
|
93
|
-
in `static/` during `vite build`,
|
|
94
|
-
so they're included in the SvelteKit build output.
|
|
95
|
-
More [about public packages](./package_json.md#public-packages).
|
|
96
|
-
|
|
97
|
-
This can be customized with `well_known_src_json`.
|
|
98
|
-
Setting it to `false` disables the feature, and `true` enables it.
|
|
99
|
-
Setting it to a function maps the final `src.json` value - returning `null` disables it.
|
|
100
|
-
|
|
101
|
-
The `.well-known/src.json` file contains more details about
|
|
102
|
-
the `package.json`'s `exports`, like exported identifier names and types.
|
|
103
|
-
It maps each export to a source file in `.well-known/src/`.
|
|
104
|
-
|
|
105
|
-
## `well_known_src_files`
|
|
106
|
-
|
|
107
|
-
The contents of your `src/` directory can be included in the output
|
|
108
|
-
if you want your app's source code to be available the same as the built files.
|
|
109
|
-
This is disabled by default.
|
|
110
|
-
If `well_known_src_files` is truthy,
|
|
111
|
-
the plugin copies `src/` to `static/.well-known/src/` during `vite build`.
|
|
112
|
-
Passing `true` uses the same filter as `exports` in `package.json` by default,
|
|
113
|
-
and it also accepts a custom filter function.
|