@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.
- package/LICENSE +21 -0
- package/README.md +257 -0
- package/dist/args.d.ts +59 -0
- package/dist/args.js +132 -0
- package/dist/args.test.d.ts +1 -0
- package/dist/args.test.js +43 -0
- package/dist/build.task.d.ts +11 -0
- package/dist/build.task.js +24 -0
- package/dist/changelog.d.ts +8 -0
- package/dist/changelog.js +47 -0
- package/dist/changelog.test.d.ts +1 -0
- package/dist/changelog.test.js +118 -0
- package/dist/changeset.task.d.ts +49 -0
- package/dist/changeset.task.js +141 -0
- package/dist/check.task.d.ts +47 -0
- package/dist/check.task.js +77 -0
- package/dist/clean.task.d.ts +26 -0
- package/dist/clean.task.js +41 -0
- package/dist/clean_fs.d.ts +9 -0
- package/dist/clean_fs.js +27 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.js +25 -0
- package/dist/commit.task.d.ts +11 -0
- package/dist/commit.task.js +22 -0
- package/dist/config.d.ts +21 -0
- package/dist/config.js +42 -0
- package/dist/config.test.d.ts +1 -0
- package/dist/config.test.js +8 -0
- package/dist/deploy.task.d.ts +47 -0
- package/dist/deploy.task.js +198 -0
- package/dist/dev.task.d.ts +22 -0
- package/dist/dev.task.js +32 -0
- package/dist/docs/README.gen.md.d.ts +5 -0
- package/dist/docs/README.gen.md.js +53 -0
- package/dist/docs/README.md +20 -0
- package/dist/docs/build.md +41 -0
- package/dist/docs/config.md +162 -0
- package/dist/docs/deploy.md +32 -0
- package/dist/docs/dev.md +40 -0
- package/dist/docs/gen.md +241 -0
- package/dist/docs/gro_plugin_sveltekit_frontend.md +97 -0
- package/dist/docs/package_json.md +29 -0
- package/dist/docs/plugin.md +50 -0
- package/dist/docs/publish.md +144 -0
- package/dist/docs/task.md +377 -0
- package/dist/docs/tasks.gen.md.d.ts +2 -0
- package/dist/docs/tasks.gen.md.js +60 -0
- package/dist/docs/tasks.md +35 -0
- package/dist/docs/test.md +52 -0
- package/dist/env.d.ts +10 -0
- package/dist/env.js +47 -0
- package/dist/esbuild_helpers.d.ts +14 -0
- package/dist/esbuild_helpers.js +36 -0
- package/dist/esbuild_plugin_external_worker.d.ts +22 -0
- package/dist/esbuild_plugin_external_worker.js +49 -0
- package/dist/esbuild_plugin_svelte.d.ts +9 -0
- package/dist/esbuild_plugin_svelte.js +49 -0
- package/dist/esbuild_plugin_sveltekit_local_imports.d.ts +7 -0
- package/dist/esbuild_plugin_sveltekit_local_imports.js +30 -0
- package/dist/esbuild_plugin_sveltekit_shim_alias.d.ts +6 -0
- package/dist/esbuild_plugin_sveltekit_shim_alias.js +16 -0
- package/dist/esbuild_plugin_sveltekit_shim_app.d.ts +8 -0
- package/dist/esbuild_plugin_sveltekit_shim_app.js +23 -0
- package/dist/esbuild_plugin_sveltekit_shim_env.d.ts +10 -0
- package/dist/esbuild_plugin_sveltekit_shim_env.js +18 -0
- package/dist/format.task.d.ts +11 -0
- package/dist/format.task.js +24 -0
- package/dist/format_directory.d.ts +2 -0
- package/dist/format_directory.js +27 -0
- package/dist/format_file.d.ts +8 -0
- package/dist/format_file.js +42 -0
- package/dist/format_file.test.d.ts +1 -0
- package/dist/format_file.test.js +16 -0
- package/dist/fs.d.ts +7 -0
- package/dist/fs.js +19 -0
- package/dist/fs.test.d.ts +1 -0
- package/dist/fs.test.js +16 -0
- package/dist/gen.d.ts +57 -0
- package/dist/gen.js +81 -0
- package/dist/gen.task.d.ts +14 -0
- package/dist/gen.task.js +103 -0
- package/dist/gen.test.d.ts +1 -0
- package/dist/gen.test.js +239 -0
- package/dist/gen_module.d.ts +46 -0
- package/dist/gen_module.js +54 -0
- package/dist/gen_module.test.d.ts +1 -0
- package/dist/gen_module.test.js +30 -0
- package/dist/git.d.ts +76 -0
- package/dist/git.js +200 -0
- package/dist/git.test.d.ts +1 -0
- package/dist/git.test.js +18 -0
- package/dist/github.d.ts +35 -0
- package/dist/github.js +32 -0
- package/dist/gro.config.default.d.ts +12 -0
- package/dist/gro.config.default.js +31 -0
- package/dist/gro.d.ts +2 -0
- package/dist/gro.js +19 -0
- package/dist/gro_helpers.d.ts +43 -0
- package/dist/gro_helpers.js +79 -0
- package/dist/gro_plugin_gen.d.ts +6 -0
- package/dist/gro_plugin_gen.js +80 -0
- package/dist/gro_plugin_server.d.ts +77 -0
- package/dist/gro_plugin_server.js +152 -0
- package/dist/gro_plugin_sveltekit_app.d.ts +27 -0
- package/dist/gro_plugin_sveltekit_app.js +180 -0
- package/dist/gro_plugin_sveltekit_library.d.ts +4 -0
- package/dist/gro_plugin_sveltekit_library.js +42 -0
- package/dist/hash.d.ts +5 -0
- package/dist/hash.js +14 -0
- package/dist/hash.test.d.ts +1 -0
- package/dist/hash.test.js +25 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/input_path.d.ts +48 -0
- package/dist/input_path.js +161 -0
- package/dist/input_path.test.d.ts +1 -0
- package/dist/input_path.test.js +106 -0
- package/dist/invoke.d.ts +1 -0
- package/dist/invoke.js +18 -0
- package/dist/invoke_task.d.ts +20 -0
- package/dist/invoke_task.js +140 -0
- package/dist/lint.task.d.ts +11 -0
- package/dist/lint.task.js +29 -0
- package/dist/loader.d.ts +4 -0
- package/dist/loader.js +153 -0
- package/dist/module.d.ts +3 -0
- package/dist/module.js +6 -0
- package/dist/module.test.d.ts +1 -0
- package/dist/module.test.js +41 -0
- package/dist/modules.d.ts +60 -0
- package/dist/modules.js +103 -0
- package/dist/modules.test.d.ts +1 -0
- package/dist/modules.test.js +182 -0
- package/dist/package.d.ts +939 -0
- package/dist/package.gen.d.ts +7 -0
- package/dist/package.gen.js +26 -0
- package/dist/package.js +887 -0
- package/dist/package_json.d.ts +342 -0
- package/dist/package_json.js +212 -0
- package/dist/package_json.test.d.ts +1 -0
- package/dist/package_json.test.js +77 -0
- package/dist/path.d.ts +12 -0
- package/dist/path.js +8 -0
- package/dist/paths.d.ts +60 -0
- package/dist/paths.js +128 -0
- package/dist/paths.test.d.ts +1 -0
- package/dist/paths.test.js +49 -0
- package/dist/plugin.d.ts +36 -0
- package/dist/plugin.js +80 -0
- package/dist/plugin.test.d.ts +1 -0
- package/dist/plugin.test.js +54 -0
- package/dist/print_task.d.ts +4 -0
- package/dist/print_task.js +124 -0
- package/dist/publish.task.d.ts +32 -0
- package/dist/publish.task.js +125 -0
- package/dist/release.task.d.ts +5 -0
- package/dist/release.task.js +18 -0
- package/dist/resolve_node_specifier.d.ts +8 -0
- package/dist/resolve_node_specifier.js +39 -0
- package/dist/resolve_node_specifier.test.d.ts +1 -0
- package/dist/resolve_node_specifier.test.js +21 -0
- package/dist/resolve_specifier.d.ts +15 -0
- package/dist/resolve_specifier.js +51 -0
- package/dist/resolve_specifier.test.d.ts +1 -0
- package/dist/resolve_specifier.test.js +66 -0
- package/dist/run.task.d.ts +11 -0
- package/dist/run.task.js +31 -0
- package/dist/run_gen.d.ts +6 -0
- package/dist/run_gen.js +74 -0
- package/dist/run_gen.test.d.ts +1 -0
- package/dist/run_gen.test.js +182 -0
- package/dist/run_task.d.ts +13 -0
- package/dist/run_task.js +44 -0
- package/dist/run_task.test.d.ts +1 -0
- package/dist/run_task.test.js +63 -0
- package/dist/search_fs.d.ts +11 -0
- package/dist/search_fs.js +22 -0
- package/dist/search_fs.test.d.ts +1 -0
- package/dist/search_fs.test.js +46 -0
- package/dist/src_json.d.ts +256 -0
- package/dist/src_json.js +110 -0
- package/dist/src_json.test.d.ts +1 -0
- package/dist/src_json.test.js +52 -0
- package/dist/sveltekit_config.d.ts +36 -0
- package/dist/sveltekit_config.js +51 -0
- package/dist/sveltekit_shim_app.d.ts +10 -0
- package/dist/sveltekit_shim_app.js +31 -0
- package/dist/sveltekit_shim_app_environment.d.ts +10 -0
- package/dist/sveltekit_shim_app_environment.js +12 -0
- package/dist/sveltekit_shim_app_forms.d.ts +5 -0
- package/dist/sveltekit_shim_app_forms.js +13 -0
- package/dist/sveltekit_shim_app_navigation.d.ts +10 -0
- package/dist/sveltekit_shim_app_navigation.js +11 -0
- package/dist/sveltekit_shim_app_paths.d.ts +11 -0
- package/dist/sveltekit_shim_app_paths.js +6 -0
- package/dist/sveltekit_shim_app_stores.d.ts +6 -0
- package/dist/sveltekit_shim_app_stores.js +17 -0
- package/dist/sveltekit_shim_env.d.ts +4 -0
- package/dist/sveltekit_shim_env.js +23 -0
- package/dist/sync.task.d.ts +30 -0
- package/dist/sync.task.js +45 -0
- package/dist/task.d.ts +29 -0
- package/dist/task.js +17 -0
- package/dist/task.test.d.ts +1 -0
- package/dist/task.test.js +22 -0
- package/dist/task_module.d.ts +14 -0
- package/dist/task_module.js +19 -0
- package/dist/task_module.test.d.ts +1 -0
- package/dist/task_module.test.js +70 -0
- package/dist/test.task.d.ts +20 -0
- package/dist/test.task.js +43 -0
- package/dist/throttle.d.ts +16 -0
- package/dist/throttle.js +59 -0
- package/dist/throttle.test.d.ts +1 -0
- package/dist/throttle.test.js +49 -0
- package/dist/typecheck.task.d.ts +5 -0
- package/dist/typecheck.task.js +38 -0
- package/dist/upgrade.task.d.ts +14 -0
- package/dist/upgrade.task.js +37 -0
- package/dist/watch_dir.d.ts +30 -0
- package/dist/watch_dir.js +59 -0
- package/package.json +422 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { spawn_restartable_process } from '@ryanatkn/belt/process.js';
|
|
2
|
+
import * as esbuild from 'esbuild';
|
|
3
|
+
import { cwd } from 'node:process';
|
|
4
|
+
import { join, resolve } from 'node:path';
|
|
5
|
+
import { identity } from '@ryanatkn/belt/function.js';
|
|
6
|
+
import { strip_before } from '@ryanatkn/belt/string.js';
|
|
7
|
+
import { base_path_to_source_id, GRO_DEV_DIRNAME, SERVER_DIST_PATH, LIB_DIRNAME, paths, } from './paths.js';
|
|
8
|
+
import { watch_dir } from './watch_dir.js';
|
|
9
|
+
import { init_sveltekit_config } from './sveltekit_config.js';
|
|
10
|
+
import { esbuild_plugin_sveltekit_shim_app } from './esbuild_plugin_sveltekit_shim_app.js';
|
|
11
|
+
import { esbuild_plugin_sveltekit_shim_env } from './esbuild_plugin_sveltekit_shim_env.js';
|
|
12
|
+
import { print_build_result, to_define_import_meta_env } from './esbuild_helpers.js';
|
|
13
|
+
import { esbuild_plugin_sveltekit_shim_alias } from './esbuild_plugin_sveltekit_shim_alias.js';
|
|
14
|
+
import { esbuild_plugin_external_worker } from './esbuild_plugin_external_worker.js';
|
|
15
|
+
import { esbuild_plugin_sveltekit_local_imports } from './esbuild_plugin_sveltekit_local_imports.js';
|
|
16
|
+
import { exists } from './fs.js';
|
|
17
|
+
import { esbuild_plugin_svelte } from './esbuild_plugin_svelte.js';
|
|
18
|
+
import { throttle } from './throttle.js';
|
|
19
|
+
// TODO sourcemap as a hoisted option? disable for production by default - or like `outpaths`, passed a `dev` param
|
|
20
|
+
export const SERVER_SOURCE_ID = base_path_to_source_id(LIB_DIRNAME + '/server/server.ts');
|
|
21
|
+
export const has_server = (path = SERVER_SOURCE_ID) => exists(path);
|
|
22
|
+
export const gro_plugin_server = ({ entry_points = [SERVER_SOURCE_ID], dir = cwd(), outpaths = (dev) => ({
|
|
23
|
+
outdir: join(dir, dev ? GRO_DEV_DIRNAME : SERVER_DIST_PATH),
|
|
24
|
+
outbase: paths.lib,
|
|
25
|
+
outname: 'server/server.js',
|
|
26
|
+
}), env_files, ambient_env, sveltekit_config, target = 'esnext', esbuild_build_options = identity, rebuild_throttle_delay = 1000, cli_command = 'node', run, // `dev` default is not available in this scope
|
|
27
|
+
} = {}) => {
|
|
28
|
+
let build_ctx;
|
|
29
|
+
let watcher;
|
|
30
|
+
let server_process = null;
|
|
31
|
+
let deps = null;
|
|
32
|
+
return {
|
|
33
|
+
name: 'gro_plugin_server',
|
|
34
|
+
setup: async ({ dev, watch, timings, log }) => {
|
|
35
|
+
const { alias, base_url, assets_url, env_dir, private_prefix, public_prefix, svelte_compile_options, svelte_preprocessors, } = await init_sveltekit_config(sveltekit_config ?? dir);
|
|
36
|
+
const { outbase, outdir, outname } = outpaths(dev);
|
|
37
|
+
const server_outpath = join(outdir, outname);
|
|
38
|
+
const timing_to_esbuild_create_context = timings.start('create build context');
|
|
39
|
+
const build_options = esbuild_build_options({
|
|
40
|
+
outdir,
|
|
41
|
+
outbase,
|
|
42
|
+
format: 'esm',
|
|
43
|
+
platform: 'node',
|
|
44
|
+
packages: 'external',
|
|
45
|
+
bundle: true,
|
|
46
|
+
target,
|
|
47
|
+
metafile: watch,
|
|
48
|
+
});
|
|
49
|
+
build_ctx = await esbuild.context({
|
|
50
|
+
entryPoints: entry_points.map((path) => resolve(dir, path)),
|
|
51
|
+
plugins: [
|
|
52
|
+
esbuild_plugin_sveltekit_shim_app({ dev, base_url, assets_url }),
|
|
53
|
+
esbuild_plugin_sveltekit_shim_env({
|
|
54
|
+
dev,
|
|
55
|
+
public_prefix,
|
|
56
|
+
private_prefix,
|
|
57
|
+
env_dir,
|
|
58
|
+
env_files,
|
|
59
|
+
ambient_env,
|
|
60
|
+
}),
|
|
61
|
+
esbuild_plugin_sveltekit_shim_alias({ dir, alias }),
|
|
62
|
+
esbuild_plugin_external_worker({
|
|
63
|
+
dev,
|
|
64
|
+
build_options,
|
|
65
|
+
dir,
|
|
66
|
+
svelte_compile_options,
|
|
67
|
+
svelte_preprocessors,
|
|
68
|
+
alias,
|
|
69
|
+
base_url,
|
|
70
|
+
public_prefix,
|
|
71
|
+
private_prefix,
|
|
72
|
+
env_dir,
|
|
73
|
+
env_files,
|
|
74
|
+
ambient_env,
|
|
75
|
+
log,
|
|
76
|
+
}),
|
|
77
|
+
esbuild_plugin_svelte({ dir, svelte_compile_options, svelte_preprocessors }),
|
|
78
|
+
esbuild_plugin_sveltekit_local_imports(),
|
|
79
|
+
],
|
|
80
|
+
define: to_define_import_meta_env(dev, base_url),
|
|
81
|
+
...build_options,
|
|
82
|
+
});
|
|
83
|
+
timing_to_esbuild_create_context();
|
|
84
|
+
const rebuild = throttle(async () => {
|
|
85
|
+
let build_result;
|
|
86
|
+
try {
|
|
87
|
+
build_result = await build_ctx.rebuild();
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
log.error('[gro_plugin_server] build failed', err);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const { metafile } = build_result;
|
|
94
|
+
if (!metafile)
|
|
95
|
+
return;
|
|
96
|
+
print_build_result(log, build_result);
|
|
97
|
+
deps = parse_deps(metafile.inputs, dir);
|
|
98
|
+
server_process?.restart();
|
|
99
|
+
}, rebuild_throttle_delay);
|
|
100
|
+
await rebuild();
|
|
101
|
+
// uses chokidar instead of esbuild's watcher for efficiency
|
|
102
|
+
if (watch) {
|
|
103
|
+
let watcher_ready = false;
|
|
104
|
+
// TODO maybe reuse this watcher globally via an option,
|
|
105
|
+
// because it watches all of `$lib`, and that means it excludes `$routes`
|
|
106
|
+
// while also including a lot of client files we don't care about,
|
|
107
|
+
// but we can't discern which of `$lib` to watch ahead of time
|
|
108
|
+
watcher = watch_dir({
|
|
109
|
+
dir: paths.lib,
|
|
110
|
+
on_change: (change) => {
|
|
111
|
+
if (!watcher_ready || !deps?.has(change.path))
|
|
112
|
+
return;
|
|
113
|
+
void rebuild();
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
await watcher.init();
|
|
117
|
+
watcher_ready = true;
|
|
118
|
+
}
|
|
119
|
+
if (!(await exists(server_outpath))) {
|
|
120
|
+
throw Error(`Node server failed to start due to missing file: ${server_outpath}`);
|
|
121
|
+
}
|
|
122
|
+
if (run ?? dev) {
|
|
123
|
+
server_process = spawn_restartable_process(cli_command, [server_outpath]);
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
teardown: async () => {
|
|
127
|
+
if (server_process) {
|
|
128
|
+
const s = server_process; // avoid possible issue where a build is in progress, don't want to issue a restart, could be fixed upstream in `spawn_restartable_process`
|
|
129
|
+
server_process = null;
|
|
130
|
+
await s.kill();
|
|
131
|
+
}
|
|
132
|
+
if (watcher) {
|
|
133
|
+
await watcher.close();
|
|
134
|
+
}
|
|
135
|
+
if (build_ctx) {
|
|
136
|
+
await build_ctx.dispose();
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* The esbuild metafile contains the paths in `entryPoints` relative to the `dir`
|
|
143
|
+
* even though we're resolving them to absolute paths before passing them to esbuild,
|
|
144
|
+
* so we resolve them here relative to the `dir`.
|
|
145
|
+
*/
|
|
146
|
+
const parse_deps = (metafile_inputs, dir) => {
|
|
147
|
+
const deps = new Set();
|
|
148
|
+
for (const key in metafile_inputs) {
|
|
149
|
+
deps.add(resolve(dir, strip_before(key, ':')));
|
|
150
|
+
}
|
|
151
|
+
return deps;
|
|
152
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Plugin, Plugin_Context } from './plugin.js';
|
|
2
|
+
import { type Map_Package_Json } from './package_json.js';
|
|
3
|
+
import { type Map_Src_Json } from './src_json.js';
|
|
4
|
+
export declare const has_sveltekit_app: () => Promise<boolean>;
|
|
5
|
+
export interface Options {
|
|
6
|
+
/**
|
|
7
|
+
* Used for finalizing a SvelteKit build like adding a `.nojekyll` file for GitHub Pages.
|
|
8
|
+
* @default 'github_pages'
|
|
9
|
+
*/
|
|
10
|
+
host_target?: Host_Target;
|
|
11
|
+
/**
|
|
12
|
+
* If truthy, adds `/.well-known/package.json` to the static output.
|
|
13
|
+
* If a function, maps the value.
|
|
14
|
+
*/
|
|
15
|
+
well_known_package_json?: boolean | Map_Package_Json;
|
|
16
|
+
/**
|
|
17
|
+
* If truthy, adds `/.well-known/src.json` and `/.well-known/src/` to the static output.
|
|
18
|
+
* If a function, maps the value.
|
|
19
|
+
*/
|
|
20
|
+
well_known_src_json?: boolean | Map_Src_Json;
|
|
21
|
+
/**
|
|
22
|
+
* Filter what's copied from `src/` to `.well-known/src/`.
|
|
23
|
+
*/
|
|
24
|
+
filter_well_known_src?: (source: string, destination: string) => boolean | Promise<boolean>;
|
|
25
|
+
}
|
|
26
|
+
export type Host_Target = 'github_pages' | 'static' | 'node';
|
|
27
|
+
export declare const gro_plugin_sveltekit_app: ({ host_target, well_known_package_json, well_known_src_json, filter_well_known_src, }?: Options) => Plugin<Plugin_Context>;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { spawn_process } from '@ryanatkn/belt/process.js';
|
|
2
|
+
import { cp, mkdir, rm, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { print_command_args, serialize_args, to_forwarded_args } from './args.js';
|
|
5
|
+
import { exists } from './fs.js';
|
|
6
|
+
import { serialize_package_json, load_package_json } from './package_json.js';
|
|
7
|
+
import { init_sveltekit_config } from './sveltekit_config.js';
|
|
8
|
+
import { Task_Error } from './task.js';
|
|
9
|
+
import { spawn_cli } from './cli.js';
|
|
10
|
+
import { serialize_src_json, create_src_json } from './src_json.js';
|
|
11
|
+
import { DEFAULT_EXPORTS_EXCLUDER } from './config.js';
|
|
12
|
+
import { SVELTEKIT_CONFIG_FILENAME } from './paths.js';
|
|
13
|
+
export const has_sveltekit_app = () => exists(SVELTEKIT_CONFIG_FILENAME);
|
|
14
|
+
export const gro_plugin_sveltekit_app = ({ host_target = 'github_pages', well_known_package_json, well_known_src_json, filter_well_known_src = (source) => !DEFAULT_EXPORTS_EXCLUDER.test(source), } = {}) => {
|
|
15
|
+
let sveltekit_process = null;
|
|
16
|
+
return {
|
|
17
|
+
name: 'gro_plugin_sveltekit_app',
|
|
18
|
+
setup: async ({ dev, watch, log }) => {
|
|
19
|
+
if (dev) {
|
|
20
|
+
// `vite dev` in development mode
|
|
21
|
+
if (watch) {
|
|
22
|
+
const serialized_args = ['vite', 'dev', ...serialize_args(to_forwarded_args('vite'))];
|
|
23
|
+
log.info(print_command_args(serialized_args));
|
|
24
|
+
sveltekit_process = spawn_process('npx', serialized_args);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
log.debug(`the SvelteKit frontend plugin is loaded but will not output anything` +
|
|
28
|
+
' because `dev` is true and `watch` is false');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
// `vite build` in production mode
|
|
33
|
+
// `.well-known/package.json`
|
|
34
|
+
const package_json = await load_package_json(); // TODO put in plugin context? same with sveltekit config?
|
|
35
|
+
if (well_known_package_json === undefined) {
|
|
36
|
+
well_known_package_json = package_json.public; // eslint-disable-line no-param-reassign
|
|
37
|
+
}
|
|
38
|
+
const mapped_package_json = !well_known_package_json
|
|
39
|
+
? null
|
|
40
|
+
: well_known_package_json === true
|
|
41
|
+
? package_json
|
|
42
|
+
: await well_known_package_json(package_json);
|
|
43
|
+
const serialized_package_json = mapped_package_json && serialize_package_json(mapped_package_json);
|
|
44
|
+
// `.well-known/src.json` and `.well-known/src/`
|
|
45
|
+
const final_package_json = mapped_package_json || package_json;
|
|
46
|
+
const src_json = await create_src_json(final_package_json);
|
|
47
|
+
if (well_known_src_json === undefined) {
|
|
48
|
+
well_known_src_json = final_package_json.public; // eslint-disable-line no-param-reassign
|
|
49
|
+
}
|
|
50
|
+
const mapped_src_json = !well_known_src_json
|
|
51
|
+
? null
|
|
52
|
+
: well_known_src_json === true
|
|
53
|
+
? src_json
|
|
54
|
+
: await well_known_src_json(src_json);
|
|
55
|
+
const serialized_src_json = mapped_src_json && serialize_src_json(mapped_src_json);
|
|
56
|
+
// TODO this strategy means the files aren't available during development --
|
|
57
|
+
// maybe a Vite middleware is best? what if this plugin added its plugin to your `vite.config.ts`?
|
|
58
|
+
// copy files to `static` before building, in such a way
|
|
59
|
+
// that's non-destructive to existing files and dirs and easy to clean up
|
|
60
|
+
const { assets_path } = await init_sveltekit_config(); // TODO probably put in plugin context
|
|
61
|
+
const cleanups = [
|
|
62
|
+
serialized_package_json
|
|
63
|
+
? await create_temporarily(join(assets_path, '.well-known/package.json'), serialized_package_json)
|
|
64
|
+
: null,
|
|
65
|
+
serialized_src_json
|
|
66
|
+
? await create_temporarily(join(assets_path, '.well-known/src.json'), serialized_src_json)
|
|
67
|
+
: null,
|
|
68
|
+
serialized_src_json
|
|
69
|
+
? await copy_temporarily('src', assets_path, '.well-known', filter_well_known_src)
|
|
70
|
+
: null,
|
|
71
|
+
/**
|
|
72
|
+
* GitHub pages processes everything with Jekyll by default,
|
|
73
|
+
* breaking things like files and dirs prefixed with an underscore.
|
|
74
|
+
* This adds a `.nojekyll` file to the root of the output
|
|
75
|
+
* to tell GitHub Pages to treat the outputs as plain static files.
|
|
76
|
+
*/
|
|
77
|
+
host_target === 'github_pages'
|
|
78
|
+
? await create_temporarily(join(assets_path, '.nojekyll'), '')
|
|
79
|
+
: null,
|
|
80
|
+
].filter(Boolean);
|
|
81
|
+
const cleanup = () => Promise.all(cleanups.map((c) => c()));
|
|
82
|
+
try {
|
|
83
|
+
const serialized_args = ['build', ...serialize_args(to_forwarded_args('vite'))];
|
|
84
|
+
log.info(print_command_args(['vite'].concat(serialized_args)));
|
|
85
|
+
const spawned = await spawn_cli('vite', serialized_args); // TODO call with the gro helper instead of npx?
|
|
86
|
+
if (!spawned?.ok) {
|
|
87
|
+
throw new Task_Error('vite build failed with exit code ' + spawned?.code);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
await cleanup();
|
|
92
|
+
throw err;
|
|
93
|
+
}
|
|
94
|
+
await cleanup();
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
teardown: async () => {
|
|
98
|
+
if (sveltekit_process) {
|
|
99
|
+
sveltekit_process.child.kill();
|
|
100
|
+
await sveltekit_process.closed;
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
// TODO probably extract these, and create a common helper or merge them
|
|
106
|
+
const copy_temporarily = async (source_path, dest_dir, dest_base_dir = '', filter) => {
|
|
107
|
+
const path = join(dest_dir, dest_base_dir, source_path);
|
|
108
|
+
const dir = dirname(path);
|
|
109
|
+
const dir_already_exists = await exists(dir);
|
|
110
|
+
let root_created_dir;
|
|
111
|
+
if (!dir_already_exists) {
|
|
112
|
+
root_created_dir = await to_root_dir_that_doesnt_exist(dir);
|
|
113
|
+
if (!root_created_dir)
|
|
114
|
+
throw Error();
|
|
115
|
+
await mkdir(dir, { recursive: true });
|
|
116
|
+
}
|
|
117
|
+
const path_already_exists = await exists(path);
|
|
118
|
+
if (!path_already_exists) {
|
|
119
|
+
await cp(source_path, path, { recursive: true, filter });
|
|
120
|
+
}
|
|
121
|
+
return async () => {
|
|
122
|
+
if (!dir_already_exists) {
|
|
123
|
+
if (!root_created_dir)
|
|
124
|
+
throw Error();
|
|
125
|
+
await rm(root_created_dir, { recursive: true });
|
|
126
|
+
}
|
|
127
|
+
else if (!path_already_exists) {
|
|
128
|
+
await rm(path, { recursive: true });
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Creates a file at `path` with `contents` if it doesn't already exist,
|
|
134
|
+
* and returns a function that deletes the file and any created directories.
|
|
135
|
+
* @param path
|
|
136
|
+
* @param contents
|
|
137
|
+
* @returns cleanup function that deletes the file and any created dirs
|
|
138
|
+
*/
|
|
139
|
+
const create_temporarily = async (path, contents) => {
|
|
140
|
+
const dir = dirname(path);
|
|
141
|
+
const dir_already_exists = await exists(dir);
|
|
142
|
+
let root_created_dir;
|
|
143
|
+
if (!dir_already_exists) {
|
|
144
|
+
root_created_dir = await to_root_dir_that_doesnt_exist(dir);
|
|
145
|
+
if (!root_created_dir)
|
|
146
|
+
throw Error();
|
|
147
|
+
await mkdir(dir, { recursive: true });
|
|
148
|
+
}
|
|
149
|
+
const path_already_exists = await exists(path);
|
|
150
|
+
if (!path_already_exists) {
|
|
151
|
+
await writeFile(path, contents, 'utf8');
|
|
152
|
+
}
|
|
153
|
+
return async () => {
|
|
154
|
+
if (!dir_already_exists) {
|
|
155
|
+
if (!root_created_dir)
|
|
156
|
+
throw Error();
|
|
157
|
+
await rm(root_created_dir, { recursive: true });
|
|
158
|
+
}
|
|
159
|
+
else if (!path_already_exists) {
|
|
160
|
+
await rm(path);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Niche and probably needs refactoring,
|
|
166
|
+
* for `/a/b/DOESNT_EXIST/NOR_THIS/ETC` returns `/a/b/DOESNT_EXIST`
|
|
167
|
+
* where `/a/b` does exist on the filesystem and `DOESNT_EXIST` is not one of its subdirectories.
|
|
168
|
+
*/
|
|
169
|
+
const to_root_dir_that_doesnt_exist = async (dir) => {
|
|
170
|
+
let prev;
|
|
171
|
+
let d = dir;
|
|
172
|
+
do {
|
|
173
|
+
// eslint-disable-next-line no-await-in-loop
|
|
174
|
+
if (await exists(d)) {
|
|
175
|
+
return prev;
|
|
176
|
+
}
|
|
177
|
+
prev = d;
|
|
178
|
+
} while ((d = dirname(d)));
|
|
179
|
+
throw Error('no dirs exist for ' + dir);
|
|
180
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Plugin, Plugin_Context } from './plugin.js';
|
|
2
|
+
import { Package_Json } from './package_json.js';
|
|
3
|
+
export declare const has_sveltekit_library: (package_json?: Package_Json) => Promise<boolean>;
|
|
4
|
+
export declare const gro_plugin_sveltekit_library: () => Plugin<Plugin_Context>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { print_spawn_result, spawn } from '@ryanatkn/belt/process.js';
|
|
2
|
+
import { Task_Error } from './task.js';
|
|
3
|
+
import { Package_Json, load_package_json } from './package_json.js';
|
|
4
|
+
import { print_command_args, serialize_args, to_forwarded_args } from './args.js';
|
|
5
|
+
import { find_cli, spawn_cli } from './cli.js';
|
|
6
|
+
export const has_sveltekit_library = async (package_json) => {
|
|
7
|
+
const p = package_json ?? (await load_package_json()); // TODO from param, on config?
|
|
8
|
+
return !!p.devDependencies?.['@sveltejs/package'] || !!p.dependencies?.['@sveltejs/package'];
|
|
9
|
+
// TODO @multiple get from the sveltekit config
|
|
10
|
+
// && exists(sveltekit_config.lib_path);
|
|
11
|
+
};
|
|
12
|
+
export const gro_plugin_sveltekit_library = () => {
|
|
13
|
+
return {
|
|
14
|
+
name: 'gro_plugin_sveltekit_library',
|
|
15
|
+
setup: async ({ log }) => {
|
|
16
|
+
if ((await find_cli('svelte-package')) !== 'local') {
|
|
17
|
+
throw new Task_Error('Failed to find svelte-package, run `npm i -D @sveltejs/package`');
|
|
18
|
+
}
|
|
19
|
+
const serialized_args = serialize_args(to_forwarded_args('svelte-package'));
|
|
20
|
+
log.info(print_command_args(serialized_args));
|
|
21
|
+
await spawn_cli('svelte-package', serialized_args);
|
|
22
|
+
},
|
|
23
|
+
adapt: async ({ log, timings }) => {
|
|
24
|
+
const package_json = await load_package_json();
|
|
25
|
+
// `npm link`
|
|
26
|
+
if (package_json.bin) {
|
|
27
|
+
const timing_to_npm_link = timings.start('npm link');
|
|
28
|
+
await Promise.all(Object.values(package_json.bin).map(async (bin_path) => {
|
|
29
|
+
const chmod_result = await spawn('chmod', ['+x', bin_path]);
|
|
30
|
+
if (!chmod_result.ok)
|
|
31
|
+
log.error(`chmod on bin path ${bin_path} failed with code ${chmod_result.code}`);
|
|
32
|
+
}));
|
|
33
|
+
log.info(`linking`);
|
|
34
|
+
const link_result = await spawn('npm', ['link', '-f']); // TODO don't use `-f` unless necessary or at all?
|
|
35
|
+
if (!link_result.ok) {
|
|
36
|
+
throw new Task_Error(`Failed to link. ${print_spawn_result(link_result)}`);
|
|
37
|
+
}
|
|
38
|
+
timing_to_npm_link();
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
};
|
package/dist/hash.d.ts
ADDED
package/dist/hash.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { webcrypto } from 'node:crypto';
|
|
2
|
+
const { subtle } = webcrypto;
|
|
3
|
+
/**
|
|
4
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
|
|
5
|
+
*/
|
|
6
|
+
export const to_hash = async (data, algorithm = 'SHA-256') => {
|
|
7
|
+
const digested = await subtle.digest(algorithm, data);
|
|
8
|
+
const bytes = Array.from(new Uint8Array(digested));
|
|
9
|
+
let hex = '';
|
|
10
|
+
for (const h of bytes) {
|
|
11
|
+
hex += h.toString(16).padStart(2, '0');
|
|
12
|
+
}
|
|
13
|
+
return hex;
|
|
14
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { suite } from 'uvu';
|
|
2
|
+
import * as assert from 'uvu/assert';
|
|
3
|
+
import { webcrypto } from 'node:crypto';
|
|
4
|
+
import { to_hash } from './hash.js';
|
|
5
|
+
/* test__to_hash */
|
|
6
|
+
const test__to_hash = suite('to_hash');
|
|
7
|
+
test__to_hash('turns a buffer into a string', async () => {
|
|
8
|
+
assert.type(await to_hash(Buffer.from('hey')), 'string');
|
|
9
|
+
});
|
|
10
|
+
test__to_hash('returns the same value given the same input', async () => {
|
|
11
|
+
assert.is(await to_hash(Buffer.from('hey')), await to_hash(Buffer.from('hey')));
|
|
12
|
+
});
|
|
13
|
+
test__to_hash('checks against an implementation copied from MDN', async () => {
|
|
14
|
+
const data = Buffer.from('some_test_string');
|
|
15
|
+
assert.is(await to_hash_from_mdn_example(data), await to_hash(data));
|
|
16
|
+
});
|
|
17
|
+
test__to_hash.run();
|
|
18
|
+
/* test__to_hash */
|
|
19
|
+
/**
|
|
20
|
+
* Copied from https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest
|
|
21
|
+
* and compared against our implementation for extra assurances, because cryptography.
|
|
22
|
+
*/
|
|
23
|
+
const to_hash_from_mdn_example = async (data) => Array.from(new Uint8Array(await webcrypto.subtle.digest('SHA-256', data)))
|
|
24
|
+
.map((h) => h.toString(16).padStart(2, '0'))
|
|
25
|
+
.join('');
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type Path_Data } from './path.js';
|
|
2
|
+
/**
|
|
3
|
+
* Raw input paths are paths that users provide to Gro to reference files
|
|
4
|
+
* enhanced with Gro's conventions like `.test.`, `.task.`, and `.gen.`.
|
|
5
|
+
*
|
|
6
|
+
* A raw input path can be:
|
|
7
|
+
*
|
|
8
|
+
* - a relative path to a file, e.g. `src/foo/bar.test.ts`
|
|
9
|
+
* - a file without an extension, e.g. `src/foo/bar` if `extensions` is `.test.ts`
|
|
10
|
+
* - a directory containing any number of files, e.g. `src/foo`
|
|
11
|
+
* - any of the above without the leading `src/` or with a leading `./`
|
|
12
|
+
* - any of the above but leading with `gro/` to ignore the local directory
|
|
13
|
+
* - an absolute path to a file or directory in the current directory or Gro's
|
|
14
|
+
*
|
|
15
|
+
* The input path API lets the caller customize the allowable extensions.
|
|
16
|
+
* That means that the caller can look for `.test.` files but not `.gen.`,
|
|
17
|
+
* or both, or neither, depending on its needs.
|
|
18
|
+
*
|
|
19
|
+
* In the future we may want to support globbing or regexps.
|
|
20
|
+
*/
|
|
21
|
+
export declare const resolve_input_path: (raw_input_path: string) => string;
|
|
22
|
+
export declare const resolve_input_paths: (raw_input_paths?: string[]) => string[];
|
|
23
|
+
/**
|
|
24
|
+
* Gets a list of possible source ids for each input path with `extensions`,
|
|
25
|
+
* duplicating each under `root_dirs`.
|
|
26
|
+
* This is first used to fall back to the Gro dir to search for tasks.
|
|
27
|
+
* It's the helper used in implementations of `get_possible_source_ids_for_input_path` below.
|
|
28
|
+
*/
|
|
29
|
+
export declare const get_possible_source_ids: (input_path: string, extensions: string[], root_dirs?: string[]) => string[];
|
|
30
|
+
/**
|
|
31
|
+
* Gets the path data for each input path,
|
|
32
|
+
* searching for the possibilities based on `extensions`
|
|
33
|
+
* and stopping at the first match.
|
|
34
|
+
* Parameterized by `exists` and `stat` so it's fs-agnostic.
|
|
35
|
+
*/
|
|
36
|
+
export declare const load_source_path_data_by_input_path: (input_paths: string[], get_possible_source_ids_for_input_path?: ((input_path: string) => string[]) | undefined) => Promise<{
|
|
37
|
+
source_id_path_data_by_input_path: Map<string, Path_Data>;
|
|
38
|
+
unmapped_input_paths: string[];
|
|
39
|
+
}>;
|
|
40
|
+
/**
|
|
41
|
+
* Finds all of the matching files for the given input paths.
|
|
42
|
+
* Parameterized by `find_files` so it's fs-agnostic.
|
|
43
|
+
* De-dupes source ids.
|
|
44
|
+
*/
|
|
45
|
+
export declare const load_source_ids_by_input_path: (source_id_path_data_by_input_path: Map<string, Path_Data>, custom_search_fs?: (dir: string, options?: import("./search_fs.js").Search_Fs_Options) => Promise<Map<string, import("./path.js").Path_Stats>>) => Promise<{
|
|
46
|
+
source_ids_by_input_path: Map<string, string[]>;
|
|
47
|
+
input_directories_with_no_files: string[];
|
|
48
|
+
}>;
|