@ryanatkn/gro 0.117.0 → 0.119.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/README.md +37 -19
- package/dist/build.task.d.ts +3 -0
- package/dist/build.task.js +5 -1
- package/dist/changeset.task.d.ts +2 -2
- package/dist/changeset.task.js +10 -6
- package/dist/check.task.js +1 -1
- package/dist/clean_fs.js +2 -1
- package/dist/cli.js +1 -1
- package/dist/config.js +3 -2
- package/dist/deploy.task.d.ts +0 -6
- package/dist/deploy.task.js +7 -11
- package/dist/dev.task.d.ts +2 -2
- package/dist/docs/gen.md +27 -0
- package/dist/docs/publish.md +1 -8
- package/dist/docs/task.md +7 -0
- package/dist/docs/tasks.gen.md.js +2 -3
- package/dist/docs/tasks.md +1 -0
- package/dist/esbuild_plugin_external_worker.js +1 -2
- package/dist/esbuild_plugin_svelte.js +1 -2
- package/dist/esbuild_plugin_sveltekit_shim_alias.js +1 -2
- package/dist/format_directory.d.ts +8 -2
- package/dist/format_directory.js +18 -12
- package/dist/gen.d.ts +19 -0
- package/dist/gen.js +45 -0
- package/dist/gen.task.js +19 -19
- package/dist/gen_module.d.ts +1 -14
- package/dist/gen_module.js +0 -22
- package/dist/git.d.ts +5 -0
- package/dist/git.js +15 -0
- package/dist/git.test.js +4 -1
- package/dist/gro.config.default.js +8 -11
- package/dist/gro_helpers.js +18 -17
- package/dist/gro_plugin_gen.js +1 -1
- package/dist/gro_plugin_server.d.ts +4 -1
- package/dist/gro_plugin_server.js +15 -6
- package/dist/gro_plugin_sveltekit_app.d.ts +0 -1
- package/dist/gro_plugin_sveltekit_app.js +2 -4
- package/dist/gro_plugin_sveltekit_library.d.ts +0 -2
- package/dist/gro_plugin_sveltekit_library.js +10 -11
- package/dist/index.d.ts +1 -1
- package/dist/index.js +0 -1
- package/dist/input_path.d.ts +1 -1
- package/dist/input_path.js +1 -1
- package/dist/input_path.test.js +3 -3
- package/dist/invoke.js +2 -0
- package/dist/invoke_task.d.ts +1 -1
- package/dist/invoke_task.js +10 -11
- package/dist/lint.task.js +1 -1
- package/dist/loader.js +11 -4
- package/dist/module.d.ts +1 -1
- package/dist/module.js +2 -2
- package/dist/modules.test.js +2 -2
- package/dist/package.d.ts +52 -0
- package/dist/package.js +80 -36
- package/dist/package_json.d.ts +5 -0
- package/dist/package_json.js +8 -3
- package/dist/package_meta.d.ts +1 -2
- package/dist/path_constants.d.ts +21 -0
- package/dist/path_constants.js +28 -0
- package/dist/paths.d.ts +2 -26
- package/dist/paths.js +10 -33
- package/dist/publish.task.d.ts +9 -6
- package/dist/publish.task.js +26 -14
- package/dist/register.d.ts +1 -0
- package/dist/register.js +2 -0
- package/dist/reinstall.task.d.ts +5 -0
- package/dist/reinstall.task.js +32 -0
- package/dist/release.task.js +5 -7
- package/dist/resolve_node_specifier.js +2 -1
- package/dist/run.task.js +1 -1
- package/dist/run_gen.d.ts +2 -1
- package/dist/run_gen.js +2 -2
- package/dist/run_gen.test.js +3 -2
- package/dist/run_task.js +1 -1
- package/dist/sveltekit_config.d.ts +1 -1
- package/dist/sveltekit_config.js +9 -5
- package/dist/sveltekit_config_global.d.ts +4 -0
- package/dist/sveltekit_config_global.js +5 -0
- package/dist/sveltekit_helpers.d.ts +17 -0
- package/dist/sveltekit_helpers.js +54 -0
- package/dist/sync.task.d.ts +0 -1
- package/dist/sync.task.js +5 -11
- package/dist/task.d.ts +1 -1
- package/dist/task.js +11 -7
- package/dist/task.test.js +9 -13
- package/dist/task_logging.d.ts +2 -2
- package/dist/task_logging.js +29 -15
- package/dist/task_module.d.ts +3 -3
- package/dist/task_module.js +6 -6
- package/dist/task_module.test.js +4 -7
- package/dist/typecheck.task.js +1 -1
- package/dist/upgrade.task.d.ts +4 -1
- package/dist/upgrade.task.js +30 -5
- package/package.json +23 -3
package/dist/gen.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { join, basename, dirname, isAbsolute } from 'node:path';
|
|
2
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
3
|
import { z } from 'zod';
|
|
3
4
|
import { gen_module_meta, to_gen_module_type } from './gen_module.js';
|
|
5
|
+
import { print_path } from './paths.js';
|
|
6
|
+
import { exists } from './fs.js';
|
|
4
7
|
export const Gen_Config = z.object({
|
|
5
8
|
imports: z.record(z.string(), z.string()).default({}),
|
|
6
9
|
});
|
|
@@ -79,3 +82,45 @@ const validate_gen_files = (files) => {
|
|
|
79
82
|
ids.add(file.id);
|
|
80
83
|
}
|
|
81
84
|
};
|
|
85
|
+
export const analyze_gen_results = (gen_results) => Promise.all(gen_results.successes
|
|
86
|
+
.map((result) => result.files.map((file) => analyze_gen_result(file)))
|
|
87
|
+
.flat());
|
|
88
|
+
export const analyze_gen_result = async (file) => {
|
|
89
|
+
if (!(await exists(file.id))) {
|
|
90
|
+
return {
|
|
91
|
+
file,
|
|
92
|
+
existing_content: null,
|
|
93
|
+
is_new: true,
|
|
94
|
+
has_changed: true,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
const existing_content = await readFile(file.id, 'utf8');
|
|
98
|
+
return {
|
|
99
|
+
file,
|
|
100
|
+
existing_content,
|
|
101
|
+
is_new: false,
|
|
102
|
+
has_changed: file.content !== existing_content,
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
export const write_gen_results = async (gen_results, analyzed_gen_results, log) => {
|
|
106
|
+
await Promise.all(gen_results.successes
|
|
107
|
+
.map((result) => result.files.map(async (file) => {
|
|
108
|
+
const analyzed = analyzed_gen_results.find((r) => r.file.id === file.id);
|
|
109
|
+
if (!analyzed)
|
|
110
|
+
throw Error('Expected to find analyzed result: ' + file.id);
|
|
111
|
+
const log_args = [print_path(file.id), 'generated from', print_path(file.origin_id)];
|
|
112
|
+
if (analyzed.is_new) {
|
|
113
|
+
log.info('writing new', ...log_args);
|
|
114
|
+
await mkdir(dirname(file.id), { recursive: true });
|
|
115
|
+
await writeFile(file.id, file.content);
|
|
116
|
+
}
|
|
117
|
+
else if (analyzed.has_changed) {
|
|
118
|
+
log.info('writing changed', ...log_args);
|
|
119
|
+
await writeFile(file.id, file.content);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
log.info('skipping unchanged', ...log_args);
|
|
123
|
+
}
|
|
124
|
+
}))
|
|
125
|
+
.flat());
|
|
126
|
+
};
|
package/dist/gen.task.js
CHANGED
|
@@ -2,16 +2,15 @@ import { red, green, gray } from 'kleur/colors';
|
|
|
2
2
|
import { print_ms, print_error } from '@ryanatkn/belt/print.js';
|
|
3
3
|
import { plural } from '@ryanatkn/belt/string.js';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
-
import { dirname } from 'node:path';
|
|
6
|
-
import { mkdir, writeFile } from 'node:fs/promises';
|
|
7
5
|
import { Task_Error } from './task.js';
|
|
8
6
|
import { run_gen } from './run_gen.js';
|
|
9
|
-
import { load_gen_module,
|
|
7
|
+
import { load_gen_module, find_gen_modules } from './gen_module.js';
|
|
10
8
|
import { Raw_Input_Path, to_input_paths } from './input_path.js';
|
|
11
9
|
import { load_modules } from './modules.js';
|
|
12
10
|
import { format_file } from './format_file.js';
|
|
13
11
|
import { paths, print_path } from './paths.js';
|
|
14
12
|
import { log_error_reasons } from './task_logging.js';
|
|
13
|
+
import { write_gen_results, analyze_gen_results } from './gen.js';
|
|
15
14
|
export const Args = z
|
|
16
15
|
.object({
|
|
17
16
|
_: z.array(Raw_Input_Path, { description: 'paths to generate' }).default([]),
|
|
@@ -25,7 +24,7 @@ export const Args = z
|
|
|
25
24
|
export const task = {
|
|
26
25
|
summary: 'run code generation scripts',
|
|
27
26
|
Args,
|
|
28
|
-
run: async ({ args, log, timings }) => {
|
|
27
|
+
run: async ({ args, log, timings, config }) => {
|
|
29
28
|
const { _: raw_input_paths, check } = args;
|
|
30
29
|
const input_paths = raw_input_paths.length ? to_input_paths(raw_input_paths) : [paths.source];
|
|
31
30
|
// load all of the gen modules
|
|
@@ -48,23 +47,23 @@ export const task = {
|
|
|
48
47
|
}
|
|
49
48
|
// run `gen` on each of the modules
|
|
50
49
|
const timing_to_generate_code = timings.start('generate code'); // TODO this ignores `gen_results.elapsed` - should it return `Timings` instead?
|
|
51
|
-
const gen_results = await run_gen(load_modules_result.modules, log, timings, format_file);
|
|
50
|
+
const gen_results = await run_gen(load_modules_result.modules, config, log, timings, format_file);
|
|
52
51
|
timing_to_generate_code();
|
|
53
52
|
const fail_count = gen_results.failures.length;
|
|
53
|
+
const analyzed_gen_results = await analyze_gen_results(gen_results);
|
|
54
54
|
if (check) {
|
|
55
55
|
// check if any files changed, and if so, throw errors,
|
|
56
56
|
// but if there are gen failures, skip the check and defer to their errors
|
|
57
57
|
if (!fail_count) {
|
|
58
58
|
log.info('checking generated files for changes');
|
|
59
59
|
const timing_to_check_results = timings.start('check results for changes');
|
|
60
|
-
const check_gen_modules_results = await check_gen_modules(gen_results);
|
|
61
60
|
timing_to_check_results();
|
|
62
61
|
let has_unexpected_changes = false;
|
|
63
|
-
for (const
|
|
64
|
-
if (!
|
|
62
|
+
for (const analyzed of analyzed_gen_results) {
|
|
63
|
+
if (!analyzed.has_changed)
|
|
65
64
|
continue;
|
|
66
65
|
has_unexpected_changes = true;
|
|
67
|
-
log.error(red(`Generated file ${print_path(
|
|
66
|
+
log.error(red(`Generated file ${print_path(analyzed.file.id)} via ${print_path(analyzed.file.origin_id)} ${analyzed.is_new ? 'is new' : 'has changed'}.`));
|
|
68
67
|
}
|
|
69
68
|
if (has_unexpected_changes) {
|
|
70
69
|
throw new Task_Error('Failed gen check. Some generated files have unexpectedly changed.' +
|
|
@@ -77,20 +76,21 @@ export const task = {
|
|
|
77
76
|
// write generated files to disk
|
|
78
77
|
log.info('writing generated files to disk');
|
|
79
78
|
const timing_to_output_results = timings.start('output results');
|
|
80
|
-
await
|
|
81
|
-
.map((result) => result.files.map(async (file) => {
|
|
82
|
-
log.info('writing', print_path(file.id), 'generated from', print_path(file.origin_id));
|
|
83
|
-
await mkdir(dirname(file.id), { recursive: true });
|
|
84
|
-
await writeFile(file.id, file.content);
|
|
85
|
-
}))
|
|
86
|
-
.flat());
|
|
79
|
+
await write_gen_results(gen_results, analyzed_gen_results, log);
|
|
87
80
|
timing_to_output_results();
|
|
88
81
|
}
|
|
89
|
-
|
|
82
|
+
// TODO these final printed results could be improved showing a breakdown per file id
|
|
83
|
+
const new_count = analyzed_gen_results.filter((r) => r.is_new).length;
|
|
84
|
+
const changed_count = analyzed_gen_results.filter((r) => r.has_changed).length;
|
|
85
|
+
const skipped_count = analyzed_gen_results.filter((r) => !r.is_new && !r.has_changed).length;
|
|
86
|
+
let log_result = green('gen results:');
|
|
87
|
+
log_result += `\n\t${new_count} ` + gray('new');
|
|
88
|
+
log_result += `\n\t${changed_count} ` + gray('changed');
|
|
89
|
+
log_result += `\n\t${skipped_count} ` + gray('skipped');
|
|
90
90
|
for (const result of gen_results.results) {
|
|
91
|
-
|
|
91
|
+
log_result += `\n\t${result.ok ? green('✓') : red('🞩')} ${result.ok ? result.files.length : 0} ${gray('in')} ${print_ms(result.elapsed)} ${gray('←')} ${print_path(result.id)}`;
|
|
92
92
|
}
|
|
93
|
-
log.info(
|
|
93
|
+
log.info(log_result);
|
|
94
94
|
log.info(green(`generated ${gen_results.output_count} file${plural(gen_results.output_count)} from ${gen_results.successes.length} input file${plural(gen_results.successes.length)}`));
|
|
95
95
|
if (fail_count) {
|
|
96
96
|
for (const result of gen_results.failures) {
|
package/dist/gen_module.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Module_Meta, type Load_Module_Result, type Find_Modules_Result } from './modules.js';
|
|
2
|
-
import type { Gen
|
|
2
|
+
import type { Gen } from './gen.js';
|
|
3
3
|
import { Input_Path } from './input_path.js';
|
|
4
4
|
export declare const GEN_FILE_PATTERN_TEXT = "gen";
|
|
5
5
|
export declare const GEN_FILE_PATTERN: string;
|
|
@@ -31,17 +31,4 @@ export interface Basic_Gen_Module_Meta extends Module_Meta<Gen_Module> {
|
|
|
31
31
|
mod: Basic_Gen_Module;
|
|
32
32
|
}
|
|
33
33
|
export declare const load_gen_module: (id: string) => Promise<Load_Module_Result<Gen_Module_Meta>>;
|
|
34
|
-
export type Check_Gen_Module_Result = {
|
|
35
|
-
file: Gen_File;
|
|
36
|
-
existing_content: string;
|
|
37
|
-
is_new: false;
|
|
38
|
-
has_changed: boolean;
|
|
39
|
-
} | {
|
|
40
|
-
file: Gen_File;
|
|
41
|
-
existing_content: null;
|
|
42
|
-
is_new: true;
|
|
43
|
-
has_changed: true;
|
|
44
|
-
};
|
|
45
|
-
export declare const check_gen_modules: (gen_results: Gen_Results) => Promise<Check_Gen_Module_Result[]>;
|
|
46
|
-
export declare const check_gen_module: (file: Gen_File) => Promise<Check_Gen_Module_Result>;
|
|
47
34
|
export declare const find_gen_modules: (input_paths?: Input_Path[], extensions?: string[], root_dirs?: string[]) => Promise<Find_Modules_Result>;
|
package/dist/gen_module.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { readFile } from 'node:fs/promises';
|
|
2
1
|
import { load_module, find_modules, } from './modules.js';
|
|
3
2
|
import { Input_Path, get_possible_source_ids } from './input_path.js';
|
|
4
3
|
import { paths } from './paths.js';
|
|
5
4
|
import { search_fs } from './search_fs.js';
|
|
6
|
-
import { exists } from './fs.js';
|
|
7
5
|
export const GEN_FILE_PATTERN_TEXT = 'gen';
|
|
8
6
|
export const GEN_FILE_PATTERN = '.' + GEN_FILE_PATTERN_TEXT + '.';
|
|
9
7
|
export const is_gen_path = (path) => path.includes(GEN_FILE_PATTERN);
|
|
@@ -28,26 +26,6 @@ export const load_gen_module = async (id) => {
|
|
|
28
26
|
}
|
|
29
27
|
return result;
|
|
30
28
|
};
|
|
31
|
-
export const check_gen_modules = (gen_results) => Promise.all(gen_results.successes
|
|
32
|
-
.map((result) => result.files.map((file) => check_gen_module(file)))
|
|
33
|
-
.flat());
|
|
34
|
-
export const check_gen_module = async (file) => {
|
|
35
|
-
if (!(await exists(file.id))) {
|
|
36
|
-
return {
|
|
37
|
-
file,
|
|
38
|
-
existing_content: null,
|
|
39
|
-
is_new: true,
|
|
40
|
-
has_changed: true,
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
const existing_content = await readFile(file.id, 'utf8');
|
|
44
|
-
return {
|
|
45
|
-
file,
|
|
46
|
-
existing_content,
|
|
47
|
-
is_new: false,
|
|
48
|
-
has_changed: file.content !== existing_content,
|
|
49
|
-
};
|
|
50
|
-
};
|
|
51
29
|
export const find_gen_modules = (input_paths = [paths.source],
|
|
52
30
|
// TODO improve this API to allow config, maybe just a simple `gen` filter function, so the user could return a Rollup pluginutils filter,
|
|
53
31
|
// gets a little tricky with the `get_possible_source_ids` API usage, which would probably need to change
|
package/dist/git.d.ts
CHANGED
|
@@ -22,6 +22,11 @@ export declare const git_local_branch_exists: (branch: Git_Branch, options?: Spa
|
|
|
22
22
|
* @returns an error message if the git workspace has any unstaged or uncommitted changes, or `null` if it's clean
|
|
23
23
|
*/
|
|
24
24
|
export declare const git_check_clean_workspace: (options?: SpawnOptions) => Promise<string | null>;
|
|
25
|
+
/**
|
|
26
|
+
* TODO make this return an enum and separate the text into a different function
|
|
27
|
+
* @returns an error message if the git workspace has any unstaged stages, or `null` if it's clean
|
|
28
|
+
*/
|
|
29
|
+
export declare const git_check_fully_staged_workspace: (options?: SpawnOptions) => Promise<string | null>;
|
|
25
30
|
/**
|
|
26
31
|
* Calls `git fetch` and throws if anything goes wrong.
|
|
27
32
|
*/
|
package/dist/git.js
CHANGED
|
@@ -63,6 +63,21 @@ export const git_check_clean_workspace = async (options) => {
|
|
|
63
63
|
}
|
|
64
64
|
return null;
|
|
65
65
|
};
|
|
66
|
+
/**
|
|
67
|
+
* TODO make this return an enum and separate the text into a different function
|
|
68
|
+
* @returns an error message if the git workspace has any unstaged stages, or `null` if it's clean
|
|
69
|
+
*/
|
|
70
|
+
export const git_check_fully_staged_workspace = async (options) => {
|
|
71
|
+
const unstaged_result = await spawn('git', ['diff', '--exit-code', '--quiet'], options);
|
|
72
|
+
if (!unstaged_result.ok) {
|
|
73
|
+
return 'git has unstaged changes';
|
|
74
|
+
}
|
|
75
|
+
const status_result = await spawn_out('git', ['status', '--porcelain'], options);
|
|
76
|
+
if (status_result.stdout?.includes('??')) {
|
|
77
|
+
return 'git has untracked files';
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
};
|
|
66
81
|
/**
|
|
67
82
|
* Calls `git fetch` and throws if anything goes wrong.
|
|
68
83
|
*/
|
package/dist/git.test.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { test } from 'uvu';
|
|
2
2
|
import * as assert from 'uvu/assert';
|
|
3
|
-
import { git_check_clean_workspace, git_current_branch_first_commit_hash, git_current_branch_name, git_current_commit_hash, } from './git.js';
|
|
3
|
+
import { git_check_clean_workspace, git_check_fully_staged_workspace, git_current_branch_first_commit_hash, git_current_branch_name, git_current_commit_hash, } from './git.js';
|
|
4
4
|
test('git_current_branch_name', async () => {
|
|
5
5
|
const branch_name = await git_current_branch_name();
|
|
6
6
|
assert.ok(branch_name);
|
|
@@ -8,6 +8,9 @@ test('git_current_branch_name', async () => {
|
|
|
8
8
|
test('git_check_clean_workspace', async () => {
|
|
9
9
|
await git_check_clean_workspace();
|
|
10
10
|
});
|
|
11
|
+
test('git_check_fully_staged_workspace', async () => {
|
|
12
|
+
await git_check_fully_staged_workspace();
|
|
13
|
+
});
|
|
11
14
|
test('git_current_commit_hash', async () => {
|
|
12
15
|
await git_current_commit_hash();
|
|
13
16
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { gro_plugin_sveltekit_library } from './gro_plugin_sveltekit_library.js';
|
|
2
2
|
import { has_server, gro_plugin_server } from './gro_plugin_server.js';
|
|
3
|
-
import {
|
|
3
|
+
import { gro_plugin_sveltekit_app } from './gro_plugin_sveltekit_app.js';
|
|
4
|
+
import { has_sveltekit_app, has_sveltekit_library } from './sveltekit_helpers.js';
|
|
4
5
|
/**
|
|
5
6
|
* This is the default config that's passed to `gro.config.ts`
|
|
6
7
|
* if it exists in the current project, and if not, this is the final config.
|
|
@@ -11,16 +12,12 @@ import { has_sveltekit_app, gro_plugin_sveltekit_app } from './gro_plugin_svelte
|
|
|
11
12
|
* - if `src/lib/server/server.ts`, assumes a Node server
|
|
12
13
|
*/
|
|
13
14
|
const config = async (cfg) => {
|
|
14
|
-
const [
|
|
15
|
-
has_sveltekit_library(),
|
|
16
|
-
has_server(),
|
|
17
|
-
has_sveltekit_app(),
|
|
18
|
-
]);
|
|
15
|
+
const [has_sveltekit_library_result, has_server_result, has_sveltekit_app_result] = await Promise.all([has_sveltekit_library(), has_server(), has_sveltekit_app()]);
|
|
19
16
|
cfg.plugins = async () => [
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
? gro_plugin_sveltekit_app({ host_target:
|
|
17
|
+
has_sveltekit_library_result.ok ? gro_plugin_sveltekit_library() : null,
|
|
18
|
+
has_server_result.ok ? gro_plugin_server() : null,
|
|
19
|
+
has_sveltekit_app_result.ok
|
|
20
|
+
? gro_plugin_sveltekit_app({ host_target: has_server_result.ok ? 'node' : 'github_pages' })
|
|
24
21
|
: null,
|
|
25
22
|
// TODO replace with an esbuild plugin, see the module for more
|
|
26
23
|
// import {gro_plugin_gen} from './gro_plugin_gen.js';
|
package/dist/gro_helpers.js
CHANGED
|
@@ -3,7 +3,12 @@ import { join, resolve } from 'node:path';
|
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { spawn } from '@ryanatkn/belt/process.js';
|
|
5
5
|
import { exists } from './fs.js';
|
|
6
|
-
import { NODE_MODULES_DIRNAME } from './
|
|
6
|
+
import { NODE_MODULES_DIRNAME, SVELTEKIT_DIST_DIRNAME } from './path_constants.js';
|
|
7
|
+
/*
|
|
8
|
+
|
|
9
|
+
This module is intended to have minimal dependencies to avoid over-imports in the CLI.
|
|
10
|
+
|
|
11
|
+
*/
|
|
7
12
|
/**
|
|
8
13
|
* Resolves a path to an internal Gro file.
|
|
9
14
|
* Prefers any local installation of Gro and falls back to the current CLI context.
|
|
@@ -40,26 +45,22 @@ import { NODE_MODULES_DIRNAME } from './paths.js';
|
|
|
40
45
|
*/
|
|
41
46
|
export const resolve_gro_module_path = async (path = '') => {
|
|
42
47
|
const gro_bin_path = resolve(NODE_MODULES_DIRNAME, '.bin/gro');
|
|
48
|
+
// case 1
|
|
49
|
+
// Prefer any locally installed version of Gro.
|
|
43
50
|
if (await exists(gro_bin_path)) {
|
|
44
|
-
// case 1
|
|
45
|
-
// Prefer any locally installed version of Gro.
|
|
46
51
|
return join(await realpath(gro_bin_path), '..', path);
|
|
47
52
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if ((await exists(join(base_path, 'gro.js'))) && (await exists(join(base_path, path)))) {
|
|
55
|
-
return join(file_path, '../..', base_path, path);
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
// case 3
|
|
59
|
-
// Fall back to the version associated with the running CLI.
|
|
60
|
-
return join(file_path, '..', path);
|
|
61
|
-
}
|
|
53
|
+
// case 2
|
|
54
|
+
// If running Gro inside its own repo, require the local dist.
|
|
55
|
+
// If the local dist is not yet built it will fall back to the global.
|
|
56
|
+
if ((await exists(join(SVELTEKIT_DIST_DIRNAME, 'gro.js'))) &&
|
|
57
|
+
(await exists(join(SVELTEKIT_DIST_DIRNAME, path)))) {
|
|
58
|
+
return resolve(SVELTEKIT_DIST_DIRNAME, path);
|
|
62
59
|
}
|
|
60
|
+
// case 3
|
|
61
|
+
// Fall back to the version associated with the running CLI.
|
|
62
|
+
const file_path = fileURLToPath(import.meta.url);
|
|
63
|
+
return join(file_path, '..', path);
|
|
63
64
|
};
|
|
64
65
|
/**
|
|
65
66
|
* Runs a file using the Gro loader.
|
package/dist/gro_plugin_gen.js
CHANGED
|
@@ -32,7 +32,7 @@ export const plugin = () => {
|
|
|
32
32
|
void flush_gen_queue();
|
|
33
33
|
}
|
|
34
34
|
}, FLUSH_DEBOUNCE_DELAY);
|
|
35
|
-
const gen = (files = []) =>
|
|
35
|
+
const gen = (files = []) => spawn_cli('gro', ['gen', ...files]);
|
|
36
36
|
return {
|
|
37
37
|
name: 'gro_plugin_gen',
|
|
38
38
|
setup: async ({ args: { watch }, dev, log }) => {
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import * as esbuild from 'esbuild';
|
|
2
2
|
import type { Config as SvelteKitConfig } from '@sveltejs/kit';
|
|
3
|
+
import type { Result } from '@ryanatkn/belt/result.js';
|
|
3
4
|
import type { Plugin, Plugin_Context } from './plugin.js';
|
|
4
5
|
export declare const SERVER_SOURCE_ID: Flavored<string, "Source_Id">;
|
|
5
|
-
export declare const has_server: (path?: Flavored<string, "Source_Id">) => Promise<
|
|
6
|
+
export declare const has_server: (path?: Flavored<string, "Source_Id">) => Promise<Result<object, {
|
|
7
|
+
message: string;
|
|
8
|
+
}>>;
|
|
6
9
|
export interface Options {
|
|
7
10
|
/**
|
|
8
11
|
* same as esbuild's `entryPoints`
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { spawn_restartable_process } from '@ryanatkn/belt/process.js';
|
|
2
2
|
import * as esbuild from 'esbuild';
|
|
3
|
-
import { cwd } from 'node:process';
|
|
4
3
|
import { join, resolve } from 'node:path';
|
|
5
4
|
import { identity } from '@ryanatkn/belt/function.js';
|
|
6
|
-
import { strip_before } from '@ryanatkn/belt/string.js';
|
|
7
|
-
import { base_path_to_source_id,
|
|
5
|
+
import { strip_before, strip_end } from '@ryanatkn/belt/string.js';
|
|
6
|
+
import { base_path_to_source_id, LIB_DIRNAME, paths } from './paths.js';
|
|
7
|
+
import { GRO_DEV_DIRNAME, SERVER_DIST_PATH } from './path_constants.js';
|
|
8
8
|
import { watch_dir } from './watch_dir.js';
|
|
9
9
|
import { init_sveltekit_config } from './sveltekit_config.js';
|
|
10
10
|
import { esbuild_plugin_sveltekit_shim_app } from './esbuild_plugin_sveltekit_shim_app.js';
|
|
@@ -16,10 +16,16 @@ import { esbuild_plugin_sveltekit_local_imports } from './esbuild_plugin_sveltek
|
|
|
16
16
|
import { exists } from './fs.js';
|
|
17
17
|
import { esbuild_plugin_svelte } from './esbuild_plugin_svelte.js';
|
|
18
18
|
import { throttle } from './throttle.js';
|
|
19
|
+
import { sveltekit_config_global } from './sveltekit_config_global.js';
|
|
19
20
|
// TODO sourcemap as a hoisted option? disable for production by default - or like `outpaths`, passed a `dev` param
|
|
20
21
|
export const SERVER_SOURCE_ID = base_path_to_source_id(LIB_DIRNAME + '/server/server.ts');
|
|
21
|
-
export const has_server = (path = SERVER_SOURCE_ID) =>
|
|
22
|
-
|
|
22
|
+
export const has_server = async (path = SERVER_SOURCE_ID) => {
|
|
23
|
+
if (!(await exists(path))) {
|
|
24
|
+
return { ok: false, message: `no server file found at ${path}` };
|
|
25
|
+
}
|
|
26
|
+
return { ok: true };
|
|
27
|
+
};
|
|
28
|
+
export const gro_plugin_server = ({ entry_points = [SERVER_SOURCE_ID], dir = process.cwd(), outpaths = (dev) => ({
|
|
23
29
|
outdir: join(dir, dev ? GRO_DEV_DIRNAME : SERVER_DIST_PATH),
|
|
24
30
|
outbase: paths.lib,
|
|
25
31
|
outname: 'server/server.js',
|
|
@@ -32,7 +38,10 @@ export const gro_plugin_server = ({ entry_points = [SERVER_SOURCE_ID], dir = cwd
|
|
|
32
38
|
return {
|
|
33
39
|
name: 'gro_plugin_server',
|
|
34
40
|
setup: async ({ dev, watch, timings, log }) => {
|
|
35
|
-
const
|
|
41
|
+
const parsed_sveltekit_config = !sveltekit_config && strip_end(dir, '/') === process.cwd()
|
|
42
|
+
? sveltekit_config_global
|
|
43
|
+
: await init_sveltekit_config(sveltekit_config ?? dir);
|
|
44
|
+
const { alias, base_url, assets_url, env_dir, private_prefix, public_prefix, svelte_compile_options, svelte_compile_module_options, svelte_preprocessors, } = parsed_sveltekit_config;
|
|
36
45
|
// TODO hacky
|
|
37
46
|
if (svelte_compile_options.generate === undefined) {
|
|
38
47
|
svelte_compile_options.generate = 'server';
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Plugin, Plugin_Context } from './plugin.js';
|
|
2
2
|
import { type Map_Package_Json } from './package_json.js';
|
|
3
3
|
import { type Map_Src_Json } from './src_json.js';
|
|
4
|
-
export declare const has_sveltekit_app: () => Promise<boolean>;
|
|
5
4
|
export interface Options {
|
|
6
5
|
/**
|
|
7
6
|
* Used for finalizing a SvelteKit build like adding a `.nojekyll` file for GitHub Pages.
|
|
@@ -4,13 +4,11 @@ import { dirname, join } from 'node:path';
|
|
|
4
4
|
import { print_command_args, serialize_args, to_forwarded_args } from './args.js';
|
|
5
5
|
import { exists } from './fs.js';
|
|
6
6
|
import { serialize_package_json, load_package_json } from './package_json.js';
|
|
7
|
-
import { init_sveltekit_config } from './sveltekit_config.js';
|
|
8
7
|
import { Task_Error } from './task.js';
|
|
9
8
|
import { spawn_cli } from './cli.js';
|
|
10
9
|
import { serialize_src_json, create_src_json } from './src_json.js';
|
|
11
10
|
import { DEFAULT_EXPORTS_EXCLUDER } from './config.js';
|
|
12
|
-
import {
|
|
13
|
-
export const has_sveltekit_app = () => exists(SVELTEKIT_CONFIG_FILENAME);
|
|
11
|
+
import { sveltekit_config_global } from './sveltekit_config_global.js';
|
|
14
12
|
export const gro_plugin_sveltekit_app = ({ host_target = 'github_pages', well_known_package_json, well_known_src_json, well_known_src_files, } = {}) => {
|
|
15
13
|
let sveltekit_process = null;
|
|
16
14
|
return {
|
|
@@ -57,7 +55,7 @@ export const gro_plugin_sveltekit_app = ({ host_target = 'github_pages', well_kn
|
|
|
57
55
|
// maybe a Vite middleware is best? what if this plugin added its plugin to your `vite.config.ts`?
|
|
58
56
|
// copy files to `static` before building, in such a way
|
|
59
57
|
// that's non-destructive to existing files and dirs and easy to clean up
|
|
60
|
-
const { assets_path } =
|
|
58
|
+
const { assets_path } = sveltekit_config_global;
|
|
61
59
|
const cleanups = [
|
|
62
60
|
serialized_package_json
|
|
63
61
|
? await create_temporarily(join(assets_path, '.well-known/package.json'), serialized_package_json)
|
|
@@ -1,4 +1,2 @@
|
|
|
1
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
2
|
export declare const gro_plugin_sveltekit_library: () => Plugin<Plugin_Context>;
|
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
import { print_spawn_result, spawn } from '@ryanatkn/belt/process.js';
|
|
2
2
|
import { Task_Error } from './task.js';
|
|
3
|
-
import {
|
|
3
|
+
import { load_package_json } from './package_json.js';
|
|
4
4
|
import { print_command_args, serialize_args, to_forwarded_args } from './args.js';
|
|
5
5
|
import { find_cli, spawn_cli } from './cli.js';
|
|
6
|
-
|
|
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
|
-
};
|
|
6
|
+
import { SVELTE_PACKAGE_CLI, has_sveltekit_library } from './sveltekit_helpers.js';
|
|
12
7
|
export const gro_plugin_sveltekit_library = () => {
|
|
13
8
|
return {
|
|
14
9
|
name: 'gro_plugin_sveltekit_library',
|
|
15
10
|
setup: async ({ log }) => {
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
const has_sveltekit_library_result = await has_sveltekit_library();
|
|
12
|
+
if (!has_sveltekit_library_result.ok) {
|
|
13
|
+
throw new Task_Error('Failed to find SvelteKit library: ' + has_sveltekit_library_result.message);
|
|
14
|
+
}
|
|
15
|
+
if ((await find_cli(SVELTE_PACKAGE_CLI)) !== 'local') {
|
|
16
|
+
throw new Task_Error(`Failed to find ${SVELTE_PACKAGE_CLI}, run \`npm i\``);
|
|
18
17
|
}
|
|
19
|
-
const serialized_args = serialize_args(to_forwarded_args(
|
|
18
|
+
const serialized_args = serialize_args(to_forwarded_args(SVELTE_PACKAGE_CLI));
|
|
20
19
|
log.info(print_command_args(serialized_args));
|
|
21
|
-
await spawn_cli(
|
|
20
|
+
await spawn_cli(SVELTE_PACKAGE_CLI, serialized_args);
|
|
22
21
|
},
|
|
23
22
|
adapt: async ({ log, timings }) => {
|
|
24
23
|
const package_json = await load_package_json();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export type { Gro_Config, Create_Gro_Config } from './config.js';
|
|
2
2
|
export { type Plugin, replace_plugin } from './plugin.js';
|
|
3
|
-
export {
|
|
3
|
+
export type { Gen, Gen_Context } from './gen.js';
|
|
4
4
|
export { type Task, type Task_Context, Task_Error } from './task.js';
|
package/dist/index.js
CHANGED
package/dist/input_path.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export declare const to_input_paths: (raw_input_paths: Raw_Input_Path[], root_pa
|
|
|
26
26
|
* This is first used to fall back to the Gro dir to search for tasks.
|
|
27
27
|
* It's the helper used in implementations of `get_possible_source_ids_for_input_path` below.
|
|
28
28
|
*/
|
|
29
|
-
export declare const get_possible_source_ids: (input_path: Flavored<string, "Input_Path">, extensions: string[], root_dirs
|
|
29
|
+
export declare const get_possible_source_ids: (input_path: Flavored<string, "Input_Path">, extensions: string[], root_dirs: string[]) => Source_Id[];
|
|
30
30
|
/**
|
|
31
31
|
* Gets the path data for each input path, checking the filesystem for the possibilities
|
|
32
32
|
* and stopping at the first existing file or falling back to the first existing directory.
|
package/dist/input_path.js
CHANGED
|
@@ -59,7 +59,7 @@ export const get_possible_source_ids = (input_path, extensions, root_dirs) => {
|
|
|
59
59
|
if (isAbsolute(input_path)) {
|
|
60
60
|
add_possible_source_ids(input_path);
|
|
61
61
|
}
|
|
62
|
-
else
|
|
62
|
+
else {
|
|
63
63
|
for (const root_dir of root_dirs) {
|
|
64
64
|
add_possible_source_ids(join(root_dir, input_path));
|
|
65
65
|
}
|
package/dist/input_path.test.js
CHANGED
|
@@ -22,14 +22,14 @@ test('to_input_paths', () => {
|
|
|
22
22
|
});
|
|
23
23
|
test('get_possible_source_ids in the gro directory', () => {
|
|
24
24
|
const input_path = resolve('src/foo/bar');
|
|
25
|
-
assert.equal(get_possible_source_ids(input_path, ['.baz.ts']), [
|
|
25
|
+
assert.equal(get_possible_source_ids(input_path, ['.baz.ts'], []), [
|
|
26
26
|
input_path,
|
|
27
27
|
input_path + '.baz.ts',
|
|
28
28
|
]);
|
|
29
29
|
});
|
|
30
30
|
test('get_possible_source_ids does not repeat the extension', () => {
|
|
31
31
|
const input_path = resolve('src/foo/bar.baz.ts');
|
|
32
|
-
assert.equal(get_possible_source_ids(input_path, ['.baz.ts']), [input_path]);
|
|
32
|
+
assert.equal(get_possible_source_ids(input_path, ['.baz.ts'], []), [input_path]);
|
|
33
33
|
});
|
|
34
34
|
test('get_possible_source_ids does not repeat with the same root directory', () => {
|
|
35
35
|
const input_path = resolve('src/foo/bar.baz.ts');
|
|
@@ -39,7 +39,7 @@ test('get_possible_source_ids does not repeat with the same root directory', ()
|
|
|
39
39
|
});
|
|
40
40
|
test('get_possible_source_ids implied to be a directory by trailing slash', () => {
|
|
41
41
|
const input_path = resolve('src/foo/bar') + '/';
|
|
42
|
-
assert.equal(get_possible_source_ids(input_path, ['.baz.ts']), [input_path]);
|
|
42
|
+
assert.equal(get_possible_source_ids(input_path, ['.baz.ts'], []), [input_path]);
|
|
43
43
|
});
|
|
44
44
|
test('load_source_ids_by_input_path', async () => {
|
|
45
45
|
const test_files = {
|
package/dist/invoke.js
CHANGED
|
@@ -2,6 +2,7 @@ import { attach_process_error_handlers } from '@ryanatkn/belt/process.js';
|
|
|
2
2
|
import { invoke_task } from './invoke_task.js';
|
|
3
3
|
import { to_task_args } from './args.js';
|
|
4
4
|
import { load_config } from './config.js';
|
|
5
|
+
import { sveltekit_sync_if_obviously_needed } from './sveltekit_helpers.js';
|
|
5
6
|
/*
|
|
6
7
|
|
|
7
8
|
This module invokes the Gro CLI which in turn invokes tasks.
|
|
@@ -14,5 +15,6 @@ and the rest of the args are forwarded to the task's `run` function.
|
|
|
14
15
|
*/
|
|
15
16
|
// handle uncaught errors
|
|
16
17
|
attach_process_error_handlers((err) => err?.constructor?.name === 'Task_Error' ? 'Task_Error' : null);
|
|
18
|
+
await sveltekit_sync_if_obviously_needed();
|
|
17
19
|
const { task_name, args } = to_task_args();
|
|
18
20
|
await invoke_task(task_name, args, await load_config());
|
package/dist/invoke_task.d.ts
CHANGED
|
@@ -17,4 +17,4 @@ import type { Gro_Config } from './config.js';
|
|
|
17
17
|
* there are some subtle differences in the complex logical branches.
|
|
18
18
|
* The comments describe each condition.
|
|
19
19
|
*/
|
|
20
|
-
export declare const invoke_task: (task_name: Flavored<string, "Raw_Input_Path">, args: Args, config: Gro_Config, timings?: any) => Promise<void>;
|
|
20
|
+
export declare const invoke_task: (task_name: Flavored<string, "Raw_Input_Path">, args: Args | undefined, config: Gro_Config, timings?: any) => Promise<void>;
|