@fuzdev/gro 0.192.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 +283 -0
- package/dist/args.d.ts +37 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +102 -0
- package/dist/build.task.d.ts +20 -0
- package/dist/build.task.d.ts.map +1 -0
- package/dist/build.task.js +119 -0
- package/dist/build_cache.d.ts +100 -0
- package/dist/build_cache.d.ts.map +1 -0
- package/dist/build_cache.js +299 -0
- package/dist/changelog.d.ts +11 -0
- package/dist/changelog.d.ts.map +1 -0
- package/dist/changelog.js +47 -0
- package/dist/changeset.task.d.ts +35 -0
- package/dist/changeset.task.d.ts.map +1 -0
- package/dist/changeset.task.js +151 -0
- package/dist/changeset_helpers.d.ts +17 -0
- package/dist/changeset_helpers.d.ts.map +1 -0
- package/dist/changeset_helpers.js +7 -0
- package/dist/check.task.d.ts +28 -0
- package/dist/check.task.d.ts.map +1 -0
- package/dist/check.task.js +104 -0
- package/dist/child_process_logging.d.ts +10 -0
- package/dist/child_process_logging.d.ts.map +1 -0
- package/dist/child_process_logging.js +26 -0
- package/dist/clean.task.d.ts +15 -0
- package/dist/clean.task.d.ts.map +1 -0
- package/dist/clean.task.js +40 -0
- package/dist/clean_fs.d.ts +9 -0
- package/dist/clean_fs.d.ts.map +1 -0
- package/dist/clean_fs.js +28 -0
- package/dist/cli.d.ts +34 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +61 -0
- package/dist/commit.task.d.ts +11 -0
- package/dist/commit.task.d.ts.map +1 -0
- package/dist/commit.task.js +24 -0
- package/dist/constants.d.ts +46 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +52 -0
- package/dist/deploy.task.d.ts +29 -0
- package/dist/deploy.task.d.ts.map +1 -0
- package/dist/deploy.task.js +217 -0
- package/dist/dev.task.d.ts +16 -0
- package/dist/dev.task.d.ts.map +1 -0
- package/dist/dev.task.js +44 -0
- package/dist/disknode.d.ts +23 -0
- package/dist/disknode.d.ts.map +1 -0
- package/dist/disknode.js +1 -0
- package/dist/env.d.ts +11 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +49 -0
- package/dist/esbuild_helpers.d.ts +16 -0
- package/dist/esbuild_helpers.d.ts.map +1 -0
- package/dist/esbuild_helpers.js +36 -0
- package/dist/esbuild_plugin_external_worker.d.ts +23 -0
- package/dist/esbuild_plugin_external_worker.d.ts.map +1 -0
- package/dist/esbuild_plugin_external_worker.js +55 -0
- package/dist/esbuild_plugin_svelte.d.ts +15 -0
- package/dist/esbuild_plugin_svelte.d.ts.map +1 -0
- package/dist/esbuild_plugin_svelte.js +83 -0
- package/dist/esbuild_plugin_sveltekit_local_imports.d.ts +8 -0
- package/dist/esbuild_plugin_sveltekit_local_imports.d.ts.map +1 -0
- package/dist/esbuild_plugin_sveltekit_local_imports.js +30 -0
- package/dist/esbuild_plugin_sveltekit_shim_alias.d.ts +7 -0
- package/dist/esbuild_plugin_sveltekit_shim_alias.d.ts.map +1 -0
- package/dist/esbuild_plugin_sveltekit_shim_alias.js +18 -0
- package/dist/esbuild_plugin_sveltekit_shim_app.d.ts +9 -0
- package/dist/esbuild_plugin_sveltekit_shim_app.d.ts.map +1 -0
- package/dist/esbuild_plugin_sveltekit_shim_app.js +22 -0
- package/dist/esbuild_plugin_sveltekit_shim_env.d.ts +11 -0
- package/dist/esbuild_plugin_sveltekit_shim_env.d.ts.map +1 -0
- package/dist/esbuild_plugin_sveltekit_shim_env.js +18 -0
- package/dist/filer.d.ts +33 -0
- package/dist/filer.d.ts.map +1 -0
- package/dist/filer.js +385 -0
- package/dist/format.task.d.ts +11 -0
- package/dist/format.task.d.ts.map +1 -0
- package/dist/format.task.js +27 -0
- package/dist/format_directory.d.ts +13 -0
- package/dist/format_directory.d.ts.map +1 -0
- package/dist/format_directory.js +40 -0
- package/dist/format_file.d.ts +9 -0
- package/dist/format_file.d.ts.map +1 -0
- package/dist/format_file.js +42 -0
- package/dist/gen.d.ts +142 -0
- package/dist/gen.d.ts.map +1 -0
- package/dist/gen.js +199 -0
- package/dist/gen.task.d.ts +12 -0
- package/dist/gen.task.d.ts.map +1 -0
- package/dist/gen.task.js +149 -0
- package/dist/gen_helpers.d.ts +11 -0
- package/dist/gen_helpers.d.ts.map +1 -0
- package/dist/gen_helpers.js +76 -0
- package/dist/github.d.ts +19 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +33 -0
- package/dist/gro.config.default.d.ts +13 -0
- package/dist/gro.config.default.d.ts.map +1 -0
- package/dist/gro.config.default.js +33 -0
- package/dist/gro.d.ts +3 -0
- package/dist/gro.d.ts.map +1 -0
- package/dist/gro.js +21 -0
- package/dist/gro_config.d.ts +115 -0
- package/dist/gro_config.d.ts.map +1 -0
- package/dist/gro_config.js +114 -0
- package/dist/gro_helpers.d.ts +49 -0
- package/dist/gro_helpers.d.ts.map +1 -0
- package/dist/gro_helpers.js +97 -0
- package/dist/gro_plugin_gen.d.ts +12 -0
- package/dist/gro_plugin_gen.d.ts.map +1 -0
- package/dist/gro_plugin_gen.js +101 -0
- package/dist/gro_plugin_server.d.ts +80 -0
- package/dist/gro_plugin_server.d.ts.map +1 -0
- package/dist/gro_plugin_server.js +167 -0
- package/dist/gro_plugin_sveltekit_app.d.ts +9 -0
- package/dist/gro_plugin_sveltekit_app.d.ts.map +1 -0
- package/dist/gro_plugin_sveltekit_app.js +42 -0
- package/dist/gro_plugin_sveltekit_library.d.ts +16 -0
- package/dist/gro_plugin_sveltekit_library.d.ts.map +1 -0
- package/dist/gro_plugin_sveltekit_library.js +34 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/input_path.d.ts +64 -0
- package/dist/input_path.d.ts.map +1 -0
- package/dist/input_path.js +199 -0
- package/dist/invoke.d.ts +2 -0
- package/dist/invoke.d.ts.map +1 -0
- package/dist/invoke.js +28 -0
- package/dist/invoke_task.d.ts +30 -0
- package/dist/invoke_task.d.ts.map +1 -0
- package/dist/invoke_task.js +104 -0
- package/dist/lint.task.d.ts +11 -0
- package/dist/lint.task.d.ts.map +1 -0
- package/dist/lint.task.js +32 -0
- package/dist/loader.d.ts +6 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +192 -0
- package/dist/module.d.ts +4 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +6 -0
- package/dist/modules.d.ts +36 -0
- package/dist/modules.d.ts.map +1 -0
- package/dist/modules.js +71 -0
- package/dist/package_json.d.ts +32 -0
- package/dist/package_json.d.ts.map +1 -0
- package/dist/package_json.js +178 -0
- package/dist/parse_exports.d.ts +20 -0
- package/dist/parse_exports.d.ts.map +1 -0
- package/dist/parse_exports.js +65 -0
- package/dist/parse_exports_context.d.ts +21 -0
- package/dist/parse_exports_context.d.ts.map +1 -0
- package/dist/parse_exports_context.js +332 -0
- package/dist/parse_imports.d.ts +5 -0
- package/dist/parse_imports.d.ts.map +1 -0
- package/dist/parse_imports.js +140 -0
- package/dist/paths.d.ts +41 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +69 -0
- package/dist/plugin.d.ts +36 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +78 -0
- package/dist/publish.task.d.ts +26 -0
- package/dist/publish.task.d.ts.map +1 -0
- package/dist/publish.task.js +176 -0
- package/dist/register.d.ts +2 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +2 -0
- package/dist/reinstall.task.d.ts +8 -0
- package/dist/reinstall.task.d.ts.map +1 -0
- package/dist/reinstall.task.js +35 -0
- package/dist/release.task.d.ts +8 -0
- package/dist/release.task.d.ts.map +1 -0
- package/dist/release.task.js +20 -0
- package/dist/resolve.task.d.ts +11 -0
- package/dist/resolve.task.d.ts.map +1 -0
- package/dist/resolve.task.js +38 -0
- package/dist/resolve_specifier.d.ts +22 -0
- package/dist/resolve_specifier.d.ts.map +1 -0
- package/dist/resolve_specifier.js +57 -0
- package/dist/run.task.d.ts +16 -0
- package/dist/run.task.d.ts.map +1 -0
- package/dist/run.task.js +52 -0
- package/dist/run_gen.d.ts +10 -0
- package/dist/run_gen.d.ts.map +1 -0
- package/dist/run_gen.js +73 -0
- package/dist/run_task.d.ts +17 -0
- package/dist/run_task.d.ts.map +1 -0
- package/dist/run_task.js +45 -0
- package/dist/source_json.d.ts +7 -0
- package/dist/source_json.d.ts.map +1 -0
- package/dist/source_json.js +145 -0
- package/dist/svelte_config.d.ts +57 -0
- package/dist/svelte_config.d.ts.map +1 -0
- package/dist/svelte_config.js +81 -0
- package/dist/sveltekit_helpers.d.ts +75 -0
- package/dist/sveltekit_helpers.d.ts.map +1 -0
- package/dist/sveltekit_helpers.js +94 -0
- package/dist/sveltekit_shim_app.d.ts +11 -0
- package/dist/sveltekit_shim_app.d.ts.map +1 -0
- package/dist/sveltekit_shim_app.js +31 -0
- package/dist/sveltekit_shim_app_environment.d.ts +13 -0
- package/dist/sveltekit_shim_app_environment.d.ts.map +1 -0
- package/dist/sveltekit_shim_app_environment.js +14 -0
- package/dist/sveltekit_shim_app_forms.d.ts +5 -0
- package/dist/sveltekit_shim_app_forms.d.ts.map +1 -0
- package/dist/sveltekit_shim_app_forms.js +6 -0
- package/dist/sveltekit_shim_app_navigation.d.ts +10 -0
- package/dist/sveltekit_shim_app_navigation.d.ts.map +1 -0
- package/dist/sveltekit_shim_app_navigation.js +11 -0
- package/dist/sveltekit_shim_app_paths.d.ts +17 -0
- package/dist/sveltekit_shim_app_paths.d.ts.map +1 -0
- package/dist/sveltekit_shim_app_paths.js +10 -0
- package/dist/sveltekit_shim_app_state.d.ts +5 -0
- package/dist/sveltekit_shim_app_state.d.ts.map +1 -0
- package/dist/sveltekit_shim_app_state.js +26 -0
- package/dist/sveltekit_shim_env.d.ts +5 -0
- package/dist/sveltekit_shim_env.d.ts.map +1 -0
- package/dist/sveltekit_shim_env.js +23 -0
- package/dist/sync.task.d.ts +16 -0
- package/dist/sync.task.d.ts.map +1 -0
- package/dist/sync.task.js +39 -0
- package/dist/task.d.ts +98 -0
- package/dist/task.d.ts.map +1 -0
- package/dist/task.js +109 -0
- package/dist/task_logging.d.ts +6 -0
- package/dist/task_logging.d.ts.map +1 -0
- package/dist/task_logging.js +201 -0
- package/dist/test.task.d.ts +13 -0
- package/dist/test.task.d.ts.map +1 -0
- package/dist/test.task.js +53 -0
- package/dist/typecheck.task.d.ts +13 -0
- package/dist/typecheck.task.d.ts.map +1 -0
- package/dist/typecheck.task.js +68 -0
- package/dist/upgrade.task.d.ts +20 -0
- package/dist/upgrade.task.d.ts.map +1 -0
- package/dist/upgrade.task.js +111 -0
- package/dist/watch_dir.d.ts +36 -0
- package/dist/watch_dir.d.ts.map +1 -0
- package/dist/watch_dir.js +69 -0
- package/package.json +149 -0
- package/src/lib/args.ts +115 -0
- package/src/lib/build.task.ts +151 -0
- package/src/lib/build_cache.ts +378 -0
- package/src/lib/changelog.ts +69 -0
- package/src/lib/changeset.task.ts +228 -0
- package/src/lib/changeset_helpers.ts +14 -0
- package/src/lib/check.task.ts +132 -0
- package/src/lib/child_process_logging.ts +38 -0
- package/src/lib/clean.task.ts +48 -0
- package/src/lib/clean_fs.ts +54 -0
- package/src/lib/cli.ts +98 -0
- package/src/lib/commit.task.ts +34 -0
- package/src/lib/constants.ts +56 -0
- package/src/lib/deploy.task.ts +287 -0
- package/src/lib/dev.task.ts +52 -0
- package/src/lib/disknode.ts +26 -0
- package/src/lib/env.ts +78 -0
- package/src/lib/esbuild_helpers.ts +49 -0
- package/src/lib/esbuild_plugin_external_worker.ts +94 -0
- package/src/lib/esbuild_plugin_svelte.ts +134 -0
- package/src/lib/esbuild_plugin_sveltekit_local_imports.ts +38 -0
- package/src/lib/esbuild_plugin_sveltekit_shim_alias.ts +27 -0
- package/src/lib/esbuild_plugin_sveltekit_shim_app.ts +42 -0
- package/src/lib/esbuild_plugin_sveltekit_shim_env.ts +47 -0
- package/src/lib/filer.ts +458 -0
- package/src/lib/format.task.ts +44 -0
- package/src/lib/format_directory.ts +65 -0
- package/src/lib/format_file.ts +49 -0
- package/src/lib/gen.task.ts +206 -0
- package/src/lib/gen.ts +406 -0
- package/src/lib/gen_helpers.ts +131 -0
- package/src/lib/github.ts +46 -0
- package/src/lib/gro.config.default.ts +42 -0
- package/src/lib/gro.ts +29 -0
- package/src/lib/gro_config.ts +254 -0
- package/src/lib/gro_helpers.ts +108 -0
- package/src/lib/gro_plugin_gen.ts +149 -0
- package/src/lib/gro_plugin_server.ts +288 -0
- package/src/lib/gro_plugin_sveltekit_app.ts +58 -0
- package/src/lib/gro_plugin_sveltekit_library.ts +63 -0
- package/src/lib/index.ts +8 -0
- package/src/lib/input_path.ts +254 -0
- package/src/lib/invoke.ts +34 -0
- package/src/lib/invoke_task.ts +139 -0
- package/src/lib/lint.task.ts +39 -0
- package/src/lib/loader.ts +229 -0
- package/src/lib/module.ts +13 -0
- package/src/lib/modules.ts +117 -0
- package/src/lib/package_json.ts +255 -0
- package/src/lib/parse_exports.ts +100 -0
- package/src/lib/parse_exports_context.ts +395 -0
- package/src/lib/parse_imports.ts +180 -0
- package/src/lib/paths.ts +111 -0
- package/src/lib/plugin.ts +106 -0
- package/src/lib/publish.task.ts +228 -0
- package/src/lib/register.ts +3 -0
- package/src/lib/reinstall.task.ts +45 -0
- package/src/lib/release.task.ts +26 -0
- package/src/lib/resolve.task.ts +43 -0
- package/src/lib/resolve_specifier.ts +81 -0
- package/src/lib/run.task.ts +65 -0
- package/src/lib/run_gen.ts +110 -0
- package/src/lib/run_task.ts +82 -0
- package/src/lib/source_json.ts +183 -0
- package/src/lib/svelte_config.ts +140 -0
- package/src/lib/sveltekit_helpers.ts +193 -0
- package/src/lib/sveltekit_shim_app.ts +41 -0
- package/src/lib/sveltekit_shim_app_environment.ts +16 -0
- package/src/lib/sveltekit_shim_app_forms.ts +13 -0
- package/src/lib/sveltekit_shim_app_navigation.ts +23 -0
- package/src/lib/sveltekit_shim_app_paths.ts +26 -0
- package/src/lib/sveltekit_shim_app_state.ts +35 -0
- package/src/lib/sveltekit_shim_env.ts +45 -0
- package/src/lib/sync.task.ts +47 -0
- package/src/lib/task.ts +245 -0
- package/src/lib/task_logging.ts +255 -0
- package/src/lib/test.task.ts +63 -0
- package/src/lib/typecheck.task.ts +81 -0
- package/src/lib/upgrade.task.ts +148 -0
- package/src/lib/watch_dir.ts +115 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {LIB_DIRNAME} from './paths.ts';
|
|
2
|
+
import {SOURCE_DIR, SOURCE_DIRNAME} from './constants.ts';
|
|
3
|
+
|
|
4
|
+
export const MODULE_PATH_SRC_PREFIX = SOURCE_DIR;
|
|
5
|
+
export const MODULE_PATH_LIB_PREFIX = `$${LIB_DIRNAME}/`;
|
|
6
|
+
|
|
7
|
+
const INTERNAL_MODULE_MATCHER = new RegExp(
|
|
8
|
+
`^(\\.?\\.?|${SOURCE_DIRNAME}|\\$${LIB_DIRNAME})\\/`,
|
|
9
|
+
'u',
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
export const is_external_module = (module_name: string): boolean =>
|
|
13
|
+
!INTERNAL_MODULE_MATCHER.test(module_name);
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type {Timings} from '@fuzdev/fuz_util/timings.js';
|
|
2
|
+
import {UnreachableError} from '@fuzdev/fuz_util/error.js';
|
|
3
|
+
import type {Result} from '@fuzdev/fuz_util/result.js';
|
|
4
|
+
import {print_error} from '@fuzdev/fuz_util/print.js';
|
|
5
|
+
import {pathToFileURL} from 'node:url';
|
|
6
|
+
import type {PathId} from '@fuzdev/fuz_util/path.js';
|
|
7
|
+
|
|
8
|
+
import type {ResolvedInputFile} from './input_path.ts';
|
|
9
|
+
import {print_path} from './paths.ts';
|
|
10
|
+
|
|
11
|
+
export interface ModuleMeta<TModule extends Record<string, any> = Record<string, any>> {
|
|
12
|
+
id: PathId;
|
|
13
|
+
mod: TModule;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type LoadModuleResult<TModule> = Result<{id: PathId; mod: TModule}, LoadModuleFailure>;
|
|
17
|
+
export type LoadModuleFailure =
|
|
18
|
+
| {ok: false; type: 'failed_import'; id: PathId; error: Error}
|
|
19
|
+
| {
|
|
20
|
+
ok: false;
|
|
21
|
+
type: 'failed_validation';
|
|
22
|
+
id: PathId;
|
|
23
|
+
mod: Record<string, any>;
|
|
24
|
+
validation: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const load_module = async <TModule extends Record<string, any>>(
|
|
28
|
+
id: PathId,
|
|
29
|
+
validate?: (mod: Record<string, any>) => mod is TModule,
|
|
30
|
+
bust_cache?: boolean,
|
|
31
|
+
): Promise<LoadModuleResult<TModule>> => {
|
|
32
|
+
let mod;
|
|
33
|
+
try {
|
|
34
|
+
let import_path = id;
|
|
35
|
+
if (bust_cache) {
|
|
36
|
+
const url = pathToFileURL(id);
|
|
37
|
+
url.searchParams.set('t', Date.now().toString());
|
|
38
|
+
import_path = url.href;
|
|
39
|
+
}
|
|
40
|
+
mod = await import(import_path);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
return {ok: false, type: 'failed_import', id, error};
|
|
43
|
+
}
|
|
44
|
+
if (validate && !validate(mod)) {
|
|
45
|
+
return {ok: false, type: 'failed_validation', id, mod, validation: validate.name};
|
|
46
|
+
}
|
|
47
|
+
return {ok: true, id, mod};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export interface LoadModulesFailure<TModuleMeta extends ModuleMeta> {
|
|
51
|
+
type: 'load_module_failures';
|
|
52
|
+
load_module_failures: Array<LoadModuleFailure>;
|
|
53
|
+
reasons: Array<string>;
|
|
54
|
+
// still return the modules and timings, deferring to the caller
|
|
55
|
+
modules: Array<TModuleMeta>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type LoadModulesResult<TModuleMeta extends ModuleMeta> = Result<
|
|
59
|
+
{
|
|
60
|
+
modules: Array<TModuleMeta>;
|
|
61
|
+
},
|
|
62
|
+
LoadModulesFailure<TModuleMeta>
|
|
63
|
+
>;
|
|
64
|
+
|
|
65
|
+
// TODO parallelize and sort afterwards
|
|
66
|
+
export const load_modules = async <
|
|
67
|
+
TModule extends Record<string, any>,
|
|
68
|
+
TModuleMeta extends ModuleMeta<TModule>,
|
|
69
|
+
>(
|
|
70
|
+
resolved_input_files: Array<ResolvedInputFile>,
|
|
71
|
+
validate: (mod: any) => mod is TModule,
|
|
72
|
+
map_module_meta: (resolved_input_file: ResolvedInputFile, mod: TModule) => TModuleMeta,
|
|
73
|
+
timings?: Timings,
|
|
74
|
+
): Promise<LoadModulesResult<TModuleMeta>> => {
|
|
75
|
+
const timing_to_load_modules = timings?.start('load modules');
|
|
76
|
+
const modules: Array<TModuleMeta> = [];
|
|
77
|
+
const load_module_failures: Array<LoadModuleFailure> = [];
|
|
78
|
+
const reasons: Array<string> = [];
|
|
79
|
+
for (const resolved_input_file of resolved_input_files.values()) {
|
|
80
|
+
const {id, input_path} = resolved_input_file;
|
|
81
|
+
const result = await load_module(id, validate); // eslint-disable-line no-await-in-loop
|
|
82
|
+
if (result.ok) {
|
|
83
|
+
modules.push(map_module_meta(resolved_input_file, result.mod));
|
|
84
|
+
} else {
|
|
85
|
+
load_module_failures.push(result);
|
|
86
|
+
switch (result.type) {
|
|
87
|
+
case 'failed_import': {
|
|
88
|
+
reasons.push(
|
|
89
|
+
`Module import ${print_path(id)} failed from input ${print_path(
|
|
90
|
+
input_path,
|
|
91
|
+
)}: ${print_error(result.error)}`,
|
|
92
|
+
);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
case 'failed_validation': {
|
|
96
|
+
reasons.push(`Module ${print_path(id)} failed validation '${result.validation}'.`);
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
default:
|
|
100
|
+
throw new UnreachableError(result);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
timing_to_load_modules?.();
|
|
105
|
+
|
|
106
|
+
if (load_module_failures.length) {
|
|
107
|
+
return {
|
|
108
|
+
ok: false,
|
|
109
|
+
type: 'load_module_failures',
|
|
110
|
+
load_module_failures,
|
|
111
|
+
reasons,
|
|
112
|
+
modules,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return {ok: true, modules};
|
|
117
|
+
};
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import {z} from 'zod';
|
|
2
|
+
import {join} from 'node:path';
|
|
3
|
+
import {readFile, writeFile} from 'node:fs/promises';
|
|
4
|
+
import {plural, strip_end} from '@fuzdev/fuz_util/string.js';
|
|
5
|
+
import type {Logger} from '@fuzdev/fuz_util/log.js';
|
|
6
|
+
import {styleText as st} from 'node:util';
|
|
7
|
+
import {PackageJson, PackageJsonExports} from '@fuzdev/fuz_util/package_json.js';
|
|
8
|
+
import {fs_search} from '@fuzdev/fuz_util/fs.js';
|
|
9
|
+
|
|
10
|
+
import {paths, gro_paths, IS_THIS_GRO} from './paths.ts';
|
|
11
|
+
import {
|
|
12
|
+
PACKAGE_JSON_FILENAME,
|
|
13
|
+
SVELTEKIT_DIST_DIRNAME,
|
|
14
|
+
TS_MATCHER,
|
|
15
|
+
JS_MATCHER,
|
|
16
|
+
SVELTE_MATCHER,
|
|
17
|
+
JSON_MATCHER,
|
|
18
|
+
CSS_MATCHER,
|
|
19
|
+
} from './constants.ts';
|
|
20
|
+
import {has_sveltekit_library} from './sveltekit_helpers.ts';
|
|
21
|
+
import {GITHUB_REPO_MATCHER} from './github.ts';
|
|
22
|
+
|
|
23
|
+
export type PackageJsonMapper = (
|
|
24
|
+
package_json: PackageJson,
|
|
25
|
+
) => PackageJson | null | Promise<PackageJson | null>;
|
|
26
|
+
|
|
27
|
+
export const PACKAGE_JSON_EMPTY: PackageJson = {name: '', version: ''};
|
|
28
|
+
|
|
29
|
+
export const package_json_load = async (
|
|
30
|
+
dir = IS_THIS_GRO ? gro_paths.root : paths.root,
|
|
31
|
+
cache?: Record<string, PackageJson>,
|
|
32
|
+
parse = true, // TODO pass `false` here in more places, especially anything perf-sensitive like work on startup
|
|
33
|
+
log?: Logger,
|
|
34
|
+
): Promise<PackageJson> => {
|
|
35
|
+
let package_json: PackageJson;
|
|
36
|
+
if (cache && dir in cache) {
|
|
37
|
+
return cache[dir]!;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
package_json = JSON.parse(await package_json_load_contents(dir));
|
|
41
|
+
} catch (error) {
|
|
42
|
+
log?.error(st('yellow', `Failed to load package.json in ${dir}`), error);
|
|
43
|
+
return PACKAGE_JSON_EMPTY;
|
|
44
|
+
}
|
|
45
|
+
if (parse) {
|
|
46
|
+
package_json = parse_package_json(PackageJson, package_json);
|
|
47
|
+
}
|
|
48
|
+
if (cache) {
|
|
49
|
+
cache[dir] = package_json;
|
|
50
|
+
}
|
|
51
|
+
return package_json;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const package_json_sync = async (
|
|
55
|
+
map_package_json: PackageJsonMapper,
|
|
56
|
+
log: Logger,
|
|
57
|
+
write = true,
|
|
58
|
+
dir = paths.root,
|
|
59
|
+
exports_dir = paths.lib,
|
|
60
|
+
): Promise<{package_json: PackageJson | null; changed: boolean}> => {
|
|
61
|
+
const exported_files = await fs_search(exports_dir);
|
|
62
|
+
const exported_paths = exported_files.map((f) => f.path);
|
|
63
|
+
const updated = await package_json_update(
|
|
64
|
+
async (package_json) => {
|
|
65
|
+
if ((await has_sveltekit_library(package_json)).ok) {
|
|
66
|
+
package_json.exports = package_json_to_exports(exported_paths);
|
|
67
|
+
}
|
|
68
|
+
const mapped = await map_package_json(package_json);
|
|
69
|
+
return mapped ? parse_package_json(PackageJson, mapped) : mapped;
|
|
70
|
+
},
|
|
71
|
+
dir,
|
|
72
|
+
write,
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const exports_count =
|
|
76
|
+
updated.changed && updated.package_json?.exports
|
|
77
|
+
? Object.keys(updated.package_json.exports).length
|
|
78
|
+
: 0;
|
|
79
|
+
log.info(
|
|
80
|
+
updated.changed
|
|
81
|
+
? `updated package.json exports with ${exports_count} total export${plural(exports_count)}`
|
|
82
|
+
: 'no changes to exports in package.json',
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
return updated;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const package_json_load_for_gro = (): Promise<PackageJson> =>
|
|
89
|
+
package_json_load(gro_paths.root);
|
|
90
|
+
|
|
91
|
+
// TODO probably make this nullable and make callers handle failures
|
|
92
|
+
const package_json_load_contents = (dir: string): Promise<string> =>
|
|
93
|
+
readFile(join(dir, PACKAGE_JSON_FILENAME), 'utf8');
|
|
94
|
+
|
|
95
|
+
export const package_json_write = (serialized_package_json: string): Promise<void> =>
|
|
96
|
+
writeFile(join(paths.root, PACKAGE_JSON_FILENAME), serialized_package_json);
|
|
97
|
+
|
|
98
|
+
export const package_json_serialize = (package_json: PackageJson): string =>
|
|
99
|
+
JSON.stringify(parse_package_json(PackageJson, package_json), null, 2) + '\n';
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Updates package.json. Writes to the filesystem only when contents change.
|
|
103
|
+
*/
|
|
104
|
+
export const package_json_update = async (
|
|
105
|
+
update: (package_json: PackageJson) => PackageJson | null | Promise<PackageJson | null>,
|
|
106
|
+
dir = paths.root,
|
|
107
|
+
write = true,
|
|
108
|
+
): Promise<{package_json: PackageJson | null; changed: boolean}> => {
|
|
109
|
+
const original_contents = await package_json_load_contents(dir);
|
|
110
|
+
const original = JSON.parse(original_contents);
|
|
111
|
+
const updated = await update(original);
|
|
112
|
+
if (updated === null) {
|
|
113
|
+
return {package_json: original, changed: false};
|
|
114
|
+
}
|
|
115
|
+
const updated_contents = package_json_serialize(updated);
|
|
116
|
+
if (updated_contents === original_contents) {
|
|
117
|
+
return {package_json: original, changed: false};
|
|
118
|
+
}
|
|
119
|
+
if (write) await package_json_write(updated_contents);
|
|
120
|
+
return {package_json: updated, changed: true};
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const is_index = (path: string): boolean => path === 'index.ts' || path === 'index.js';
|
|
124
|
+
|
|
125
|
+
export const package_json_to_exports = (paths: Array<string>): PackageJsonExports => {
|
|
126
|
+
const has_index = paths.some(is_index);
|
|
127
|
+
const has_js = paths.some((p) => TS_MATCHER.test(p) || JS_MATCHER.test(p));
|
|
128
|
+
const has_svelte = paths.some((p) => SVELTE_MATCHER.test(p));
|
|
129
|
+
const has_json = paths.some((p) => JSON_MATCHER.test(p));
|
|
130
|
+
const has_css = paths.some((p) => CSS_MATCHER.test(p));
|
|
131
|
+
|
|
132
|
+
const exports: PackageJsonExports = {
|
|
133
|
+
'./package.json': './package.json',
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
if (has_index) {
|
|
137
|
+
exports['.'] = {
|
|
138
|
+
types: IMPORT_PREFIX + 'index.d.ts',
|
|
139
|
+
default: IMPORT_PREFIX + 'index.js',
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (has_js) {
|
|
144
|
+
exports['./*.js'] = {
|
|
145
|
+
types: IMPORT_PREFIX + '*.d.ts',
|
|
146
|
+
default: IMPORT_PREFIX + '*.js',
|
|
147
|
+
};
|
|
148
|
+
exports['./*.ts'] = {
|
|
149
|
+
types: IMPORT_PREFIX + '*.d.ts',
|
|
150
|
+
default: IMPORT_PREFIX + '*.js',
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (has_svelte) {
|
|
155
|
+
exports['./*.svelte'] = {
|
|
156
|
+
types: IMPORT_PREFIX + '*.svelte.d.ts',
|
|
157
|
+
svelte: IMPORT_PREFIX + '*.svelte',
|
|
158
|
+
default: IMPORT_PREFIX + '*.svelte',
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (has_json) {
|
|
163
|
+
exports['./*.json'] = {
|
|
164
|
+
types: IMPORT_PREFIX + '*.json.d.ts',
|
|
165
|
+
default: IMPORT_PREFIX + '*.json',
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (has_css) {
|
|
170
|
+
exports['./*.css'] = {
|
|
171
|
+
default: IMPORT_PREFIX + '*.css',
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return parse_or_throw_formatted_error('package.json#exports', PackageJsonExports, exports);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const IMPORT_PREFIX = './' + SVELTEKIT_DIST_DIRNAME + '/';
|
|
179
|
+
|
|
180
|
+
export const package_json_parse_repo_url = (
|
|
181
|
+
package_json: PackageJson,
|
|
182
|
+
): {owner: string; repo: string} | undefined => {
|
|
183
|
+
const {repository} = package_json;
|
|
184
|
+
const repo_url = repository
|
|
185
|
+
? typeof repository === 'string'
|
|
186
|
+
? repository
|
|
187
|
+
: repository.url
|
|
188
|
+
: undefined;
|
|
189
|
+
if (!repo_url) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const parsed_repo_url = GITHUB_REPO_MATCHER.exec(strip_end(strip_end(repo_url, '/'), '.git'));
|
|
193
|
+
if (!parsed_repo_url) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const [, owner, repo] = parsed_repo_url;
|
|
197
|
+
return {owner: owner!, repo: repo!};
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Parses a `PackageJson` object but preserves the order of the original keys.
|
|
202
|
+
*/
|
|
203
|
+
const parse_package_json = (schema: typeof PackageJson, value: any): PackageJson => {
|
|
204
|
+
const parsed = parse_or_throw_formatted_error(PACKAGE_JSON_FILENAME, schema, value);
|
|
205
|
+
const keys = Object.keys(value);
|
|
206
|
+
return Object.fromEntries(
|
|
207
|
+
Object.entries(parsed).sort(([a], [b]) => keys.indexOf(a) - keys.indexOf(b)),
|
|
208
|
+
) as any;
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// TODO maybe extract to zod helpers? see also everything in `task_logging.ts`
|
|
212
|
+
const parse_or_throw_formatted_error = <T extends z.ZodType>(
|
|
213
|
+
name: string,
|
|
214
|
+
schema: T,
|
|
215
|
+
value: any,
|
|
216
|
+
): z.infer<T> => {
|
|
217
|
+
const parsed = schema.safeParse(value);
|
|
218
|
+
if (!parsed.success) {
|
|
219
|
+
let msg = st('red', `Failed to parse ${name}:\n`);
|
|
220
|
+
for (const issue of parsed.error.issues) {
|
|
221
|
+
msg += st('red', `\n\t"${issue.path}" ${issue.message}\n`);
|
|
222
|
+
}
|
|
223
|
+
throw Error(msg);
|
|
224
|
+
}
|
|
225
|
+
return parsed.data;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
export const package_json_has_dependency = (dep_name: string, package_json: PackageJson): boolean =>
|
|
229
|
+
!!package_json.devDependencies?.[dep_name] ||
|
|
230
|
+
!!package_json.dependencies?.[dep_name] ||
|
|
231
|
+
!!package_json.peerDependencies?.[dep_name];
|
|
232
|
+
|
|
233
|
+
export interface PackageJsonDep {
|
|
234
|
+
name: string;
|
|
235
|
+
version: string;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export const package_json_extract_dependencies = (
|
|
239
|
+
package_json: PackageJson,
|
|
240
|
+
): Array<PackageJsonDep> => {
|
|
241
|
+
const deps_by_name: Map<string, PackageJsonDep> = new Map();
|
|
242
|
+
// Earlier versions override later ones, so peer deps goes last.
|
|
243
|
+
const add_deps = (deps: Record<string, string> | undefined) => {
|
|
244
|
+
if (!deps) return;
|
|
245
|
+
for (const [name, version] of Object.entries(deps)) {
|
|
246
|
+
if (!deps_by_name.has(name)) {
|
|
247
|
+
deps_by_name.set(name, {name, version});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
add_deps(package_json.dependencies);
|
|
252
|
+
add_deps(package_json.devDependencies);
|
|
253
|
+
add_deps(package_json.peerDependencies);
|
|
254
|
+
return Array.from(deps_by_name.values());
|
|
255
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import {extname} from 'node:path';
|
|
3
|
+
import type {Flavored} from '@fuzdev/fuz_util/types.js';
|
|
4
|
+
import type {Logger} from '@fuzdev/fuz_util/log.js';
|
|
5
|
+
import type {DeclarationKind} from '@fuzdev/fuz_util/source_json.js';
|
|
6
|
+
import type {PathId} from '@fuzdev/fuz_util/path.js';
|
|
7
|
+
|
|
8
|
+
import {TS_MATCHER} from './constants.ts';
|
|
9
|
+
import {ParseExportsContext} from './parse_exports_context.ts';
|
|
10
|
+
|
|
11
|
+
export interface Declaration {
|
|
12
|
+
name: string;
|
|
13
|
+
kind: DeclarationKind | null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type ExportDeclaration = Flavored<Declaration, 'ExportDeclaration'>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Parse exports from a file based on its file type and content.
|
|
20
|
+
*/
|
|
21
|
+
export const parse_exports = (
|
|
22
|
+
id: PathId,
|
|
23
|
+
program?: ts.Program,
|
|
24
|
+
declarations: Array<ExportDeclaration> = [],
|
|
25
|
+
log?: Logger,
|
|
26
|
+
): Array<ExportDeclaration> => {
|
|
27
|
+
// First, infer declarations based on file extension
|
|
28
|
+
infer_declarations_from_file_type(id, declarations);
|
|
29
|
+
|
|
30
|
+
// For TypeScript files with program, perform detailed export analysis
|
|
31
|
+
if (TS_MATCHER.test(id) && program) {
|
|
32
|
+
const source_file = program.getSourceFile(id);
|
|
33
|
+
if (!source_file) return declarations;
|
|
34
|
+
|
|
35
|
+
const checker = program.getTypeChecker();
|
|
36
|
+
|
|
37
|
+
// Get the exports of the source file (module)
|
|
38
|
+
const symbol = checker.getSymbolAtLocation(source_file);
|
|
39
|
+
if (!symbol) return declarations;
|
|
40
|
+
|
|
41
|
+
// Get the module exports
|
|
42
|
+
const exports = checker.getExportsOfModule(symbol);
|
|
43
|
+
|
|
44
|
+
// Process TypeScript declarations
|
|
45
|
+
const export_context = new ParseExportsContext(program, log);
|
|
46
|
+
export_context.analyze_source_file(source_file);
|
|
47
|
+
export_context.process_exports(source_file, exports, declarations);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return declarations;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// TODO temporary until proper type inference
|
|
54
|
+
export const infer_declarations_from_file_type = (
|
|
55
|
+
file_path: PathId,
|
|
56
|
+
declarations: Array<ExportDeclaration> = [],
|
|
57
|
+
): Array<ExportDeclaration> => {
|
|
58
|
+
const extension = extname(file_path).toLowerCase();
|
|
59
|
+
|
|
60
|
+
switch (extension) {
|
|
61
|
+
case '.svelte': {
|
|
62
|
+
declarations.push({
|
|
63
|
+
name: 'default',
|
|
64
|
+
kind: 'component',
|
|
65
|
+
});
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
case '.css': {
|
|
69
|
+
declarations.push({
|
|
70
|
+
name: 'default',
|
|
71
|
+
kind: 'css',
|
|
72
|
+
});
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
case '.json': {
|
|
76
|
+
declarations.push({
|
|
77
|
+
name: 'default',
|
|
78
|
+
kind: 'json',
|
|
79
|
+
});
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return declarations;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Process TypeScript exports, identifying their kinds.
|
|
89
|
+
*/
|
|
90
|
+
export const process_ts_exports = (
|
|
91
|
+
source_file: ts.SourceFile,
|
|
92
|
+
program: ts.Program,
|
|
93
|
+
exports: Array<ts.Symbol>,
|
|
94
|
+
declarations: Array<ExportDeclaration> = [],
|
|
95
|
+
log?: Logger,
|
|
96
|
+
): Array<ExportDeclaration> => {
|
|
97
|
+
const export_context = new ParseExportsContext(program, log);
|
|
98
|
+
export_context.analyze_source_file(source_file);
|
|
99
|
+
return export_context.process_exports(source_file, exports, declarations);
|
|
100
|
+
};
|