@ryanatkn/gro 0.155.0 → 0.157.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/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +5 -0
- package/dist/esbuild_plugin_svelte.d.ts.map +1 -1
- package/dist/esbuild_plugin_svelte.js +1 -2
- package/dist/gro_plugin_sveltekit_app.js +1 -1
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +33 -27
- package/dist/package.d.ts +44 -13
- package/dist/package.d.ts.map +1 -1
- package/dist/package.gen.js +1 -1
- package/dist/package.js +42 -21
- 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.map +1 -1
- package/dist/parse_imports.js +1 -2
- package/dist/paths.d.ts +8 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +6 -3
- package/dist/src_json.d.ts +68 -66
- package/dist/src_json.d.ts.map +1 -1
- package/dist/src_json.js +58 -55
- package/dist/test_helpers.d.ts +21 -0
- package/dist/test_helpers.d.ts.map +1 -0
- package/dist/test_helpers.js +122 -0
- package/package.json +20 -12
- package/src/lib/constants.ts +5 -0
- package/src/lib/esbuild_plugin_svelte.ts +1 -2
- package/src/lib/gro_plugin_sveltekit_app.ts +1 -1
- package/src/lib/loader.ts +38 -23
- package/src/lib/package.gen.ts +1 -1
- package/src/lib/package.ts +42 -21
- package/src/lib/parse_exports.ts +108 -0
- package/src/lib/parse_exports_context.ts +394 -0
- package/src/lib/parse_imports.ts +1 -2
- package/src/lib/paths.ts +13 -3
- package/src/lib/src_json.ts +80 -68
- package/src/lib/test_helpers.ts +159 -0
- package/dist/svelte_helpers.d.ts +0 -3
- package/dist/svelte_helpers.d.ts.map +0 -1
- package/dist/svelte_helpers.js +0 -2
- package/src/lib/svelte_helpers.ts +0 -2
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import ts from 'typescript';
|
|
4
|
+
export const SOME_PUBLIC_ENV_VAR_NAME = 'PUBLIC_SOME_PUBLIC_ENV_VAR';
|
|
5
|
+
export const SOME_PUBLIC_ENV_VAR_VALUE = 'SOME_PUBLIC_ENV_VAR';
|
|
6
|
+
const name_equals = SOME_PUBLIC_ENV_VAR_NAME + '=';
|
|
7
|
+
const line = name_equals + SOME_PUBLIC_ENV_VAR_VALUE;
|
|
8
|
+
let inited = false;
|
|
9
|
+
/**
|
|
10
|
+
* Hacky global helper to init the test env.
|
|
11
|
+
*
|
|
12
|
+
* @returns boolean indicating if the env file was created or not
|
|
13
|
+
*/
|
|
14
|
+
export const init_test_env = (dir = process.cwd(), env_filename = '.env') => {
|
|
15
|
+
if (inited)
|
|
16
|
+
return false;
|
|
17
|
+
inited = true;
|
|
18
|
+
const env_file = join(dir, env_filename);
|
|
19
|
+
if (!existsSync(env_file)) {
|
|
20
|
+
writeFileSync(env_file, line + '\n', 'utf8');
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
const contents = readFileSync(env_file, 'utf8');
|
|
24
|
+
const lines = contents.split('\n');
|
|
25
|
+
if (lines.includes(line)) {
|
|
26
|
+
return false; // already exists
|
|
27
|
+
}
|
|
28
|
+
let new_contents;
|
|
29
|
+
const found_index = lines.findIndex((l) => l.startsWith(name_equals));
|
|
30
|
+
if (found_index === -1) {
|
|
31
|
+
// if the line does not exist, add it
|
|
32
|
+
new_contents = contents + (contents.endsWith('\n') ? '' : '\n') + line + '\n';
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
// if the line exists but with a different value, replace it
|
|
36
|
+
new_contents = contents.replace(new RegExp(`${SOME_PUBLIC_ENV_VAR_NAME}=.*`), line);
|
|
37
|
+
}
|
|
38
|
+
writeFileSync(env_file, new_contents, 'utf8');
|
|
39
|
+
return true;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Creates a TypeScript environment for testing.
|
|
43
|
+
* Change to `typescript-go` when it's more ready.
|
|
44
|
+
* @see https://github.com/microsoft/typescript-go?tab=readme-ov-file#what-works-so-far
|
|
45
|
+
*/
|
|
46
|
+
export const create_ts_test_env = (source_code, dir = process.cwd(), virtual_files = {}) => {
|
|
47
|
+
// Create a virtual file path for testing
|
|
48
|
+
const file_path = join(dir, 'virtual_test_file.ts');
|
|
49
|
+
// Create a compiler host with custom module resolution
|
|
50
|
+
const host = ts.createCompilerHost({});
|
|
51
|
+
const original_get_source_file = host.getSourceFile.bind(host);
|
|
52
|
+
// Override getSourceFile to return our test files
|
|
53
|
+
host.getSourceFile = (fileName, languageVersion) => {
|
|
54
|
+
if (fileName === file_path) {
|
|
55
|
+
return ts.createSourceFile(fileName, source_code, languageVersion);
|
|
56
|
+
}
|
|
57
|
+
// Check if we have a virtual file for this path
|
|
58
|
+
for (const [virtual_path, content] of Object.entries(virtual_files)) {
|
|
59
|
+
const full_path = join(dir, virtual_path);
|
|
60
|
+
if (fileName === full_path) {
|
|
61
|
+
return ts.createSourceFile(fileName, content, languageVersion);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return original_get_source_file(fileName, languageVersion);
|
|
65
|
+
};
|
|
66
|
+
// TODO simplify?
|
|
67
|
+
// Add custom module resolution using resolveModuleNameLiterals
|
|
68
|
+
host.resolveModuleNameLiterals = (module_literals, containing_file, _redirected_reference, options) => {
|
|
69
|
+
return module_literals.map((module_literal) => {
|
|
70
|
+
const module_name = module_literal.text;
|
|
71
|
+
// Handle relative imports that might be in our virtual files
|
|
72
|
+
if (module_name.startsWith('./') || module_name.startsWith('../')) {
|
|
73
|
+
const module_path = join(containing_file, '..', module_name);
|
|
74
|
+
// Normalize the path handling for the virtual files
|
|
75
|
+
for (const virtual_path of Object.keys(virtual_files)) {
|
|
76
|
+
const full_path = join(dir, virtual_path);
|
|
77
|
+
const normalized_module_path = module_path.replace(/\.ts$/, '') + '.ts';
|
|
78
|
+
if (normalized_module_path === full_path) {
|
|
79
|
+
return {
|
|
80
|
+
resolvedModule: {
|
|
81
|
+
resolvedFileName: full_path,
|
|
82
|
+
isExternalLibraryImport: false,
|
|
83
|
+
extension: ts.Extension.Ts,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// If it's our main file
|
|
90
|
+
if (join(dir, module_name) === file_path) {
|
|
91
|
+
return {
|
|
92
|
+
resolvedModule: {
|
|
93
|
+
resolvedFileName: file_path,
|
|
94
|
+
isExternalLibraryImport: false,
|
|
95
|
+
extension: ts.Extension.Ts,
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
// For non-virtual modules, try standard resolution
|
|
100
|
+
return ts.resolveModuleName(module_name, containing_file, options, host);
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
// Include all virtual files in the program files list
|
|
104
|
+
const program_files = [file_path, ...Object.keys(virtual_files).map((path) => join(dir, path))];
|
|
105
|
+
// TODO get from tsconfig?
|
|
106
|
+
// Create program options
|
|
107
|
+
const compiler_options = {
|
|
108
|
+
target: ts.ScriptTarget.ESNext,
|
|
109
|
+
module: ts.ModuleKind.ESNext,
|
|
110
|
+
moduleResolution: ts.ModuleResolutionKind.NodeNext,
|
|
111
|
+
verbatimModuleSyntax: true,
|
|
112
|
+
isolatedModules: true,
|
|
113
|
+
};
|
|
114
|
+
// Create a program with our virtual files
|
|
115
|
+
const program = ts.createProgram(program_files, compiler_options, host);
|
|
116
|
+
const source_file = program.getSourceFile(file_path);
|
|
117
|
+
const checker = program.getTypeChecker();
|
|
118
|
+
// Get the exports from the source file
|
|
119
|
+
const symbol = checker.getSymbolAtLocation(source_file);
|
|
120
|
+
const exports = symbol ? checker.getExportsOfModule(symbol) : [];
|
|
121
|
+
return { source_file, checker, program, exports };
|
|
122
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ryanatkn/gro",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.157.0",
|
|
4
4
|
"description": "task runner and toolkit extending SvelteKit",
|
|
5
5
|
"motto": "generate, run, optimize",
|
|
6
6
|
"glyph": "🌰",
|
|
@@ -54,17 +54,17 @@
|
|
|
54
54
|
"dotenv": "^16.5.0",
|
|
55
55
|
"esm-env": "^1.2.2",
|
|
56
56
|
"mri": "^1.2.0",
|
|
57
|
-
"oxc-parser": "^0.
|
|
57
|
+
"oxc-parser": "^0.68.1",
|
|
58
58
|
"prettier": "^3.5.3",
|
|
59
59
|
"prettier-plugin-svelte": "^3.3.3",
|
|
60
60
|
"ts-blank-space": "^0.6.1",
|
|
61
|
-
"ts-morph": "^25.0.1",
|
|
62
61
|
"tslib": "^2.8.1",
|
|
63
|
-
"zod": "^3.24.
|
|
62
|
+
"zod": "^3.24.4"
|
|
64
63
|
},
|
|
65
64
|
"peerDependencies": {
|
|
66
65
|
"esbuild": "^0.25",
|
|
67
|
-
"svelte": "^5"
|
|
66
|
+
"svelte": "^5",
|
|
67
|
+
"typescript": "^5"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@changesets/changelog-git": "^0.2.1",
|
|
@@ -78,12 +78,12 @@
|
|
|
78
78
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
|
79
79
|
"@types/node": "^22.15.3",
|
|
80
80
|
"esbuild": "^0.25.3",
|
|
81
|
-
"eslint": "
|
|
81
|
+
"eslint": "9.25.1",
|
|
82
82
|
"eslint-plugin-svelte": "^3.5.1",
|
|
83
83
|
"svelte": "^5.28.2",
|
|
84
|
-
"svelte-check": "^4.1.
|
|
84
|
+
"svelte-check": "^4.1.7",
|
|
85
85
|
"typescript": "^5.8.3",
|
|
86
|
-
"typescript-eslint": "^8.
|
|
86
|
+
"typescript-eslint": "^8.32.0",
|
|
87
87
|
"uvu": "^0.5.6"
|
|
88
88
|
},
|
|
89
89
|
"optionalDependencies": {
|
|
@@ -325,6 +325,14 @@
|
|
|
325
325
|
"types": "./dist/package.d.ts",
|
|
326
326
|
"default": "./dist/package.js"
|
|
327
327
|
},
|
|
328
|
+
"./parse_exports_context.js": {
|
|
329
|
+
"types": "./dist/parse_exports_context.d.ts",
|
|
330
|
+
"default": "./dist/parse_exports_context.js"
|
|
331
|
+
},
|
|
332
|
+
"./parse_exports.js": {
|
|
333
|
+
"types": "./dist/parse_exports.d.ts",
|
|
334
|
+
"default": "./dist/parse_exports.js"
|
|
335
|
+
},
|
|
328
336
|
"./parse_imports.js": {
|
|
329
337
|
"types": "./dist/parse_imports.d.ts",
|
|
330
338
|
"default": "./dist/parse_imports.js"
|
|
@@ -389,10 +397,6 @@
|
|
|
389
397
|
"types": "./dist/svelte_config.d.ts",
|
|
390
398
|
"default": "./dist/svelte_config.js"
|
|
391
399
|
},
|
|
392
|
-
"./svelte_helpers.js": {
|
|
393
|
-
"types": "./dist/svelte_helpers.d.ts",
|
|
394
|
-
"default": "./dist/svelte_helpers.js"
|
|
395
|
-
},
|
|
396
400
|
"./sveltekit_helpers.js": {
|
|
397
401
|
"types": "./dist/sveltekit_helpers.d.ts",
|
|
398
402
|
"default": "./dist/sveltekit_helpers.js"
|
|
@@ -437,6 +441,10 @@
|
|
|
437
441
|
"types": "./dist/task.d.ts",
|
|
438
442
|
"default": "./dist/task.js"
|
|
439
443
|
},
|
|
444
|
+
"./test_helpers.js": {
|
|
445
|
+
"types": "./dist/test_helpers.d.ts",
|
|
446
|
+
"default": "./dist/test_helpers.js"
|
|
447
|
+
},
|
|
440
448
|
"./test.task.js": {
|
|
441
449
|
"types": "./dist/test.task.d.ts",
|
|
442
450
|
"default": "./dist/test.task.js"
|
package/src/lib/constants.ts
CHANGED
|
@@ -12,8 +12,11 @@ export const GRO_DIRNAME = '.gro';
|
|
|
12
12
|
export const GRO_DIST_PREFIX = 'dist_'; //
|
|
13
13
|
export const SERVER_DIST_PATH = 'dist_server'; // TODO should all of these be `_PATH` or should this be `DIRNAME`? also, add `_PLUGIN` to this name?
|
|
14
14
|
export const GRO_DEV_DIRNAME = GRO_DIRNAME + '/dev';
|
|
15
|
+
/** @trailing_slash */
|
|
15
16
|
export const SOURCE_DIR = SOURCE_DIRNAME + '/';
|
|
17
|
+
/** @trailing_slash */
|
|
16
18
|
export const GRO_DIR = GRO_DIRNAME + '/';
|
|
19
|
+
/** @trailing_slash */
|
|
17
20
|
export const GRO_DEV_DIR = GRO_DEV_DIRNAME + '/';
|
|
18
21
|
export const GRO_CONFIG_PATH = 'gro.config.ts';
|
|
19
22
|
export const README_FILENAME = 'README.md';
|
|
@@ -32,6 +35,8 @@ export const TSCONFIG_FILENAME = 'tsconfig.json';
|
|
|
32
35
|
export const TS_MATCHER = /\.(ts|tsx|mts|cts)$/;
|
|
33
36
|
export const JS_MATCHER = /\.(js|jsx|mjs|cjs)$/;
|
|
34
37
|
export const JSON_MATCHER = /\.json$/;
|
|
38
|
+
export const SVELTE_MATCHER = /\.svelte$/;
|
|
39
|
+
export const SVELTE_RUNES_MATCHER = /\.svelte\.(js|ts)$/; // TODO probably let `.svelte.` appear anywhere - https://github.com/sveltejs/svelte/issues/11536
|
|
35
40
|
/** Extracts the script content from Svelte files. */
|
|
36
41
|
export const SVELTE_SCRIPT_MATCHER = /<script(?:\s+[^>]*)?>([\s\S]*?)<\/script>/gim; // TODO maybe this shouldnt be global? or make a getter?
|
|
37
42
|
export const EVERYTHING_MATCHER = /.*/;
|
|
@@ -10,14 +10,13 @@ import {
|
|
|
10
10
|
import {readFile} from 'node:fs/promises';
|
|
11
11
|
import {relative} from 'node:path';
|
|
12
12
|
|
|
13
|
-
import {SVELTE_MATCHER, SVELTE_RUNES_MATCHER} from './svelte_helpers.ts';
|
|
14
13
|
import {to_define_import_meta_env, default_ts_transform_options} from './esbuild_helpers.ts';
|
|
15
14
|
import {
|
|
16
15
|
default_svelte_config,
|
|
17
16
|
to_default_compile_module_options,
|
|
18
17
|
type Parsed_Svelte_Config,
|
|
19
18
|
} from './svelte_config.ts';
|
|
20
|
-
import {TS_MATCHER} from './constants.ts';
|
|
19
|
+
import {TS_MATCHER, SVELTE_MATCHER, SVELTE_RUNES_MATCHER} from './constants.ts';
|
|
21
20
|
|
|
22
21
|
export interface Esbuild_Plugin_Svelte_Options {
|
|
23
22
|
dev: boolean;
|
|
@@ -92,7 +92,7 @@ export const gro_plugin_sveltekit_app = ({
|
|
|
92
92
|
|
|
93
93
|
// `.well-known/src.json` and `.well-known/src/`
|
|
94
94
|
const final_package_json = mapped_package_json ?? package_json;
|
|
95
|
-
const src_json = create_src_json(final_package_json);
|
|
95
|
+
const src_json = create_src_json(final_package_json, undefined);
|
|
96
96
|
if (well_known_src_json === undefined) {
|
|
97
97
|
well_known_src_json = final_package_json.public; // eslint-disable-line no-param-reassign
|
|
98
98
|
}
|
package/src/lib/loader.ts
CHANGED
|
@@ -15,9 +15,13 @@ import {
|
|
|
15
15
|
sveltekit_shim_app_specifiers,
|
|
16
16
|
} from './sveltekit_shim_app.ts';
|
|
17
17
|
import {default_svelte_config} from './svelte_config.ts';
|
|
18
|
-
import {SVELTE_MATCHER, SVELTE_RUNES_MATCHER} from './svelte_helpers.ts';
|
|
19
18
|
import {IS_THIS_GRO, paths} from './paths.ts';
|
|
20
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
NODE_MODULES_DIRNAME,
|
|
21
|
+
TS_MATCHER,
|
|
22
|
+
SVELTE_MATCHER,
|
|
23
|
+
SVELTE_RUNES_MATCHER,
|
|
24
|
+
} from './constants.ts';
|
|
21
25
|
import {resolve_specifier} from './resolve_specifier.ts';
|
|
22
26
|
import {map_sveltekit_aliases} from './sveltekit_helpers.ts';
|
|
23
27
|
|
|
@@ -93,7 +97,7 @@ export const load: LoadHook = async (url, context, nextLoad) => {
|
|
|
93
97
|
const filename = fileURLToPath(url);
|
|
94
98
|
const loaded = await nextLoad(url, {...context, format: 'module-typescript'});
|
|
95
99
|
const raw_source = loaded.source?.toString(); // eslint-disable-line @typescript-eslint/no-base-to-string
|
|
96
|
-
if (raw_source == null) throw
|
|
100
|
+
if (raw_source == null) throw Error(`Failed to load ${url}`);
|
|
97
101
|
// TODO should be nice if we could use Node's builtin amaro transform, but I couldn't find a way after digging into the source, AFAICT it's internal and not exposed
|
|
98
102
|
const source = ts_blank_space(raw_source); // TODO was using oxc-transform and probably should, but this doesn't require sourcemaps, and it's still alpha as of May 2025
|
|
99
103
|
const transformed = compileModule(source, {
|
|
@@ -116,13 +120,14 @@ export const load: LoadHook = async (url, context, nextLoad) => {
|
|
|
116
120
|
const source = preprocessed?.code ?? raw_source;
|
|
117
121
|
const transformed = compile(source, {...svelte_compile_options, dev, filename});
|
|
118
122
|
return {format: 'module', shortCircuit: true, source: transformed.js.code};
|
|
119
|
-
} else if (
|
|
120
|
-
//
|
|
121
|
-
// json
|
|
123
|
+
} else if (context.importAttributes.type === 'json') {
|
|
124
|
+
// json - any file extension
|
|
122
125
|
// TODO probably follow esbuild and also export every top-level property for objects from the module for good treeshaking - https://esbuild.github.io/content-types/#json (type generation?)
|
|
123
|
-
|
|
126
|
+
// TODO why is removing the importAttributes needed? can't pass no context either -
|
|
127
|
+
// error: `Module "file:///home/user/dev/repo/foo.json" is not of type "json"`
|
|
128
|
+
const loaded = await nextLoad(url, {...context, importAttributes: undefined});
|
|
124
129
|
const raw_source = loaded.source?.toString(); // eslint-disable-line @typescript-eslint/no-base-to-string
|
|
125
|
-
if (raw_source == null) throw
|
|
130
|
+
if (raw_source == null) throw Error(`Failed to load ${url}`);
|
|
126
131
|
const source = `export default ` + raw_source;
|
|
127
132
|
return {format: 'module', shortCircuit: true, source};
|
|
128
133
|
} else if (RAW_MATCHER.test(url)) {
|
|
@@ -138,20 +143,30 @@ export const load: LoadHook = async (url, context, nextLoad) => {
|
|
|
138
143
|
if (context.format === 'sveltekit-env') {
|
|
139
144
|
let mode: 'static' | 'dynamic';
|
|
140
145
|
let visibility: 'public' | 'private';
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
146
|
+
switch (context.importAttributes.virtual) {
|
|
147
|
+
case '$env/static/public': {
|
|
148
|
+
mode = 'static';
|
|
149
|
+
visibility = 'public';
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
case '$env/static/private': {
|
|
153
|
+
mode = 'static';
|
|
154
|
+
visibility = 'private';
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
case '$env/dynamic/public': {
|
|
158
|
+
mode = 'dynamic';
|
|
159
|
+
visibility = 'public';
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
case '$env/dynamic/private': {
|
|
163
|
+
mode = 'dynamic';
|
|
164
|
+
visibility = 'private';
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
default: {
|
|
168
|
+
throw Error(`Unknown $env import: ${context.importAttributes.virtual}`);
|
|
169
|
+
}
|
|
155
170
|
}
|
|
156
171
|
const source = render_env_shim_module(
|
|
157
172
|
dev,
|
|
@@ -162,7 +177,7 @@ export const load: LoadHook = async (url, context, nextLoad) => {
|
|
|
162
177
|
env_dir,
|
|
163
178
|
);
|
|
164
179
|
return {format: 'module', shortCircuit: true, source};
|
|
165
|
-
}
|
|
180
|
+
}
|
|
166
181
|
}
|
|
167
182
|
|
|
168
183
|
// fallback to default behavior
|
package/src/lib/package.gen.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {create_src_json} from './src_json.ts';
|
|
|
14
14
|
*/
|
|
15
15
|
export const gen: Gen = ({origin_path}) => {
|
|
16
16
|
const package_json = load_package_json();
|
|
17
|
-
const src_json = create_src_json(package_json);
|
|
17
|
+
const src_json = create_src_json(package_json, undefined);
|
|
18
18
|
|
|
19
19
|
return `
|
|
20
20
|
// generated by ${origin_path}
|
package/src/lib/package.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type {Src_Json} from './src_json.ts';
|
|
|
5
5
|
|
|
6
6
|
export const package_json = {
|
|
7
7
|
name: '@ryanatkn/gro',
|
|
8
|
-
version: '0.
|
|
8
|
+
version: '0.157.0',
|
|
9
9
|
description: 'task runner and toolkit extending SvelteKit',
|
|
10
10
|
motto: 'generate, run, optimize',
|
|
11
11
|
glyph: '🌰',
|
|
@@ -49,15 +49,14 @@ export const package_json = {
|
|
|
49
49
|
dotenv: '^16.5.0',
|
|
50
50
|
'esm-env': '^1.2.2',
|
|
51
51
|
mri: '^1.2.0',
|
|
52
|
-
'oxc-parser': '^0.
|
|
52
|
+
'oxc-parser': '^0.68.1',
|
|
53
53
|
prettier: '^3.5.3',
|
|
54
54
|
'prettier-plugin-svelte': '^3.3.3',
|
|
55
55
|
'ts-blank-space': '^0.6.1',
|
|
56
|
-
'ts-morph': '^25.0.1',
|
|
57
56
|
tslib: '^2.8.1',
|
|
58
|
-
zod: '^3.24.
|
|
57
|
+
zod: '^3.24.4',
|
|
59
58
|
},
|
|
60
|
-
peerDependencies: {esbuild: '^0.25', svelte: '^5'},
|
|
59
|
+
peerDependencies: {esbuild: '^0.25', svelte: '^5', typescript: '^5'},
|
|
61
60
|
devDependencies: {
|
|
62
61
|
'@changesets/changelog-git': '^0.2.1',
|
|
63
62
|
'@changesets/types': '^6.1.0',
|
|
@@ -70,12 +69,12 @@ export const package_json = {
|
|
|
70
69
|
'@sveltejs/vite-plugin-svelte': '^5.0.3',
|
|
71
70
|
'@types/node': '^22.15.3',
|
|
72
71
|
esbuild: '^0.25.3',
|
|
73
|
-
eslint: '
|
|
72
|
+
eslint: '9.25.1',
|
|
74
73
|
'eslint-plugin-svelte': '^3.5.1',
|
|
75
74
|
svelte: '^5.28.2',
|
|
76
|
-
'svelte-check': '^4.1.
|
|
75
|
+
'svelte-check': '^4.1.7',
|
|
77
76
|
typescript: '^5.8.3',
|
|
78
|
-
'typescript-eslint': '^8.
|
|
77
|
+
'typescript-eslint': '^8.32.0',
|
|
79
78
|
uvu: '^0.5.6',
|
|
80
79
|
},
|
|
81
80
|
optionalDependencies: {'@ryanatkn/moss': '>=0.27.0 <0.29.0'},
|
|
@@ -191,6 +190,11 @@ export const package_json = {
|
|
|
191
190
|
'./package_meta.js': {types: './dist/package_meta.d.ts', default: './dist/package_meta.js'},
|
|
192
191
|
'./package.gen.js': {types: './dist/package.gen.d.ts', default: './dist/package.gen.js'},
|
|
193
192
|
'./package.js': {types: './dist/package.d.ts', default: './dist/package.js'},
|
|
193
|
+
'./parse_exports_context.js': {
|
|
194
|
+
types: './dist/parse_exports_context.d.ts',
|
|
195
|
+
default: './dist/parse_exports_context.js',
|
|
196
|
+
},
|
|
197
|
+
'./parse_exports.js': {types: './dist/parse_exports.d.ts', default: './dist/parse_exports.js'},
|
|
194
198
|
'./parse_imports.js': {types: './dist/parse_imports.d.ts', default: './dist/parse_imports.js'},
|
|
195
199
|
'./path.js': {types: './dist/path.d.ts', default: './dist/path.js'},
|
|
196
200
|
'./paths.js': {types: './dist/paths.d.ts', default: './dist/paths.js'},
|
|
@@ -213,10 +217,6 @@ export const package_json = {
|
|
|
213
217
|
'./search_fs.js': {types: './dist/search_fs.d.ts', default: './dist/search_fs.js'},
|
|
214
218
|
'./src_json.js': {types: './dist/src_json.d.ts', default: './dist/src_json.js'},
|
|
215
219
|
'./svelte_config.js': {types: './dist/svelte_config.d.ts', default: './dist/svelte_config.js'},
|
|
216
|
-
'./svelte_helpers.js': {
|
|
217
|
-
types: './dist/svelte_helpers.d.ts',
|
|
218
|
-
default: './dist/svelte_helpers.js',
|
|
219
|
-
},
|
|
220
220
|
'./sveltekit_helpers.js': {
|
|
221
221
|
types: './dist/sveltekit_helpers.d.ts',
|
|
222
222
|
default: './dist/sveltekit_helpers.js',
|
|
@@ -252,6 +252,7 @@ export const package_json = {
|
|
|
252
252
|
'./sync.task.js': {types: './dist/sync.task.d.ts', default: './dist/sync.task.js'},
|
|
253
253
|
'./task_logging.js': {types: './dist/task_logging.d.ts', default: './dist/task_logging.js'},
|
|
254
254
|
'./task.js': {types: './dist/task.d.ts', default: './dist/task.js'},
|
|
255
|
+
'./test_helpers.js': {types: './dist/test_helpers.d.ts', default: './dist/test_helpers.js'},
|
|
255
256
|
'./test.task.js': {types: './dist/test.task.d.ts', default: './dist/test.task.js'},
|
|
256
257
|
'./typecheck.task.js': {
|
|
257
258
|
types: './dist/typecheck.task.d.ts',
|
|
@@ -264,7 +265,7 @@ export const package_json = {
|
|
|
264
265
|
|
|
265
266
|
export const src_json = {
|
|
266
267
|
name: '@ryanatkn/gro',
|
|
267
|
-
version: '0.
|
|
268
|
+
version: '0.157.0',
|
|
268
269
|
modules: {
|
|
269
270
|
'.': {
|
|
270
271
|
path: 'index.ts',
|
|
@@ -281,7 +282,7 @@ export const src_json = {
|
|
|
281
282
|
{name: 'Task_Error', kind: 'class'},
|
|
282
283
|
],
|
|
283
284
|
},
|
|
284
|
-
'./package.json': {path: 'package.json', declarations: []},
|
|
285
|
+
'./package.json': {path: 'package.json', declarations: [{name: 'default', kind: 'json'}]},
|
|
285
286
|
'./args.js': {
|
|
286
287
|
path: 'args.ts',
|
|
287
288
|
declarations: [
|
|
@@ -393,6 +394,8 @@ export const src_json = {
|
|
|
393
394
|
{name: 'TS_MATCHER', kind: 'variable'},
|
|
394
395
|
{name: 'JS_MATCHER', kind: 'variable'},
|
|
395
396
|
{name: 'JSON_MATCHER', kind: 'variable'},
|
|
397
|
+
{name: 'SVELTE_MATCHER', kind: 'variable'},
|
|
398
|
+
{name: 'SVELTE_RUNES_MATCHER', kind: 'variable'},
|
|
396
399
|
{name: 'SVELTE_SCRIPT_MATCHER', kind: 'variable'},
|
|
397
400
|
{name: 'EVERYTHING_MATCHER', kind: 'variable'},
|
|
398
401
|
{name: 'JS_CLI_DEFAULT', kind: 'variable'},
|
|
@@ -737,6 +740,21 @@ export const src_json = {
|
|
|
737
740
|
{name: 'src_json', kind: 'variable'},
|
|
738
741
|
],
|
|
739
742
|
},
|
|
743
|
+
'./parse_exports_context.js': {
|
|
744
|
+
path: 'parse_exports_context.ts',
|
|
745
|
+
declarations: [{name: 'Parse_Exports_Context', kind: 'class'}],
|
|
746
|
+
},
|
|
747
|
+
'./parse_exports.js': {
|
|
748
|
+
path: 'parse_exports.ts',
|
|
749
|
+
declarations: [
|
|
750
|
+
{name: 'Declaration_Kind', kind: 'type'},
|
|
751
|
+
{name: 'Declaration', kind: 'type'},
|
|
752
|
+
{name: 'Export_Declaration', kind: 'type'},
|
|
753
|
+
{name: 'parse_exports', kind: 'function'},
|
|
754
|
+
{name: 'infer_declarations_from_file_type', kind: 'function'},
|
|
755
|
+
{name: 'process_ts_exports', kind: 'function'},
|
|
756
|
+
],
|
|
757
|
+
},
|
|
740
758
|
'./parse_imports.js': {
|
|
741
759
|
path: 'parse_imports.ts',
|
|
742
760
|
declarations: [
|
|
@@ -856,6 +874,7 @@ export const src_json = {
|
|
|
856
874
|
'./src_json.js': {
|
|
857
875
|
path: 'src_json.ts',
|
|
858
876
|
declarations: [
|
|
877
|
+
{name: 'Src_Module_Declaration_Kind', kind: 'variable'},
|
|
859
878
|
{name: 'Src_Module_Declaration', kind: 'variable'},
|
|
860
879
|
{name: 'Src_Module', kind: 'variable'},
|
|
861
880
|
{name: 'Src_Modules', kind: 'variable'},
|
|
@@ -876,13 +895,6 @@ export const src_json = {
|
|
|
876
895
|
{name: 'default_svelte_config', kind: 'variable'},
|
|
877
896
|
],
|
|
878
897
|
},
|
|
879
|
-
'./svelte_helpers.js': {
|
|
880
|
-
path: 'svelte_helpers.ts',
|
|
881
|
-
declarations: [
|
|
882
|
-
{name: 'SVELTE_MATCHER', kind: 'variable'},
|
|
883
|
-
{name: 'SVELTE_RUNES_MATCHER', kind: 'variable'},
|
|
884
|
-
],
|
|
885
|
-
},
|
|
886
898
|
'./sveltekit_helpers.js': {
|
|
887
899
|
path: 'sveltekit_helpers.ts',
|
|
888
900
|
declarations: [
|
|
@@ -1004,6 +1016,15 @@ export const src_json = {
|
|
|
1004
1016
|
{name: 'validate_task_module', kind: 'function'},
|
|
1005
1017
|
],
|
|
1006
1018
|
},
|
|
1019
|
+
'./test_helpers.js': {
|
|
1020
|
+
path: 'test_helpers.ts',
|
|
1021
|
+
declarations: [
|
|
1022
|
+
{name: 'SOME_PUBLIC_ENV_VAR_NAME', kind: 'variable'},
|
|
1023
|
+
{name: 'SOME_PUBLIC_ENV_VAR_VALUE', kind: 'variable'},
|
|
1024
|
+
{name: 'init_test_env', kind: 'function'},
|
|
1025
|
+
{name: 'create_ts_test_env', kind: 'function'},
|
|
1026
|
+
],
|
|
1027
|
+
},
|
|
1007
1028
|
'./test.task.js': {
|
|
1008
1029
|
path: 'test.task.ts',
|
|
1009
1030
|
declarations: [
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import {extname} from 'node:path';
|
|
3
|
+
import type {Flavored} from '@ryanatkn/belt/types.js';
|
|
4
|
+
|
|
5
|
+
import type {Path_Id} from './path.ts';
|
|
6
|
+
import {TS_MATCHER} from './constants.ts';
|
|
7
|
+
import {Parse_Exports_Context} from './parse_exports_context.ts';
|
|
8
|
+
import type {Logger} from '@ryanatkn/belt/log.js';
|
|
9
|
+
|
|
10
|
+
export type Declaration_Kind =
|
|
11
|
+
| 'type'
|
|
12
|
+
| 'function'
|
|
13
|
+
| 'variable' // TODO maybe expand this to have literals/primitives?
|
|
14
|
+
| 'class'
|
|
15
|
+
| 'component'
|
|
16
|
+
| 'json'
|
|
17
|
+
| 'css';
|
|
18
|
+
|
|
19
|
+
export interface Declaration {
|
|
20
|
+
name: string;
|
|
21
|
+
kind: Declaration_Kind | null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type Export_Declaration = Flavored<Declaration, 'Export_Declaration'>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Parse exports from a file based on its file type and content.
|
|
28
|
+
*/
|
|
29
|
+
export const parse_exports = (
|
|
30
|
+
id: Path_Id,
|
|
31
|
+
program?: ts.Program,
|
|
32
|
+
declarations: Array<Export_Declaration> = [],
|
|
33
|
+
log?: Logger,
|
|
34
|
+
): Array<Export_Declaration> => {
|
|
35
|
+
// First, infer declarations based on file extension
|
|
36
|
+
infer_declarations_from_file_type(id, declarations);
|
|
37
|
+
|
|
38
|
+
// For TypeScript files with program, perform detailed export analysis
|
|
39
|
+
if (TS_MATCHER.test(id) && program) {
|
|
40
|
+
const source_file = program.getSourceFile(id);
|
|
41
|
+
if (!source_file) return declarations;
|
|
42
|
+
|
|
43
|
+
const checker = program.getTypeChecker();
|
|
44
|
+
|
|
45
|
+
// Get the exports of the source file (module)
|
|
46
|
+
const symbol = checker.getSymbolAtLocation(source_file);
|
|
47
|
+
if (!symbol) return declarations;
|
|
48
|
+
|
|
49
|
+
// Get the module exports
|
|
50
|
+
const exports = checker.getExportsOfModule(symbol);
|
|
51
|
+
|
|
52
|
+
// Process TypeScript declarations
|
|
53
|
+
const export_context = new Parse_Exports_Context(program, log);
|
|
54
|
+
export_context.analyze_source_file(source_file);
|
|
55
|
+
export_context.process_exports(source_file, exports, declarations);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return declarations;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// TODO temporary until proper type inference
|
|
62
|
+
export const infer_declarations_from_file_type = (
|
|
63
|
+
file_path: Path_Id,
|
|
64
|
+
declarations: Array<Export_Declaration> = [],
|
|
65
|
+
): Array<Export_Declaration> => {
|
|
66
|
+
const extension = extname(file_path).toLowerCase();
|
|
67
|
+
|
|
68
|
+
switch (extension) {
|
|
69
|
+
case '.svelte': {
|
|
70
|
+
declarations.push({
|
|
71
|
+
name: 'default',
|
|
72
|
+
kind: 'component',
|
|
73
|
+
});
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
case '.css': {
|
|
77
|
+
declarations.push({
|
|
78
|
+
name: 'default',
|
|
79
|
+
kind: 'css',
|
|
80
|
+
});
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
case '.json': {
|
|
84
|
+
declarations.push({
|
|
85
|
+
name: 'default',
|
|
86
|
+
kind: 'json',
|
|
87
|
+
});
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return declarations;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Process TypeScript exports, identifying their kinds.
|
|
97
|
+
*/
|
|
98
|
+
export const process_ts_exports = (
|
|
99
|
+
source_file: ts.SourceFile,
|
|
100
|
+
program: ts.Program,
|
|
101
|
+
exports: Array<ts.Symbol>,
|
|
102
|
+
declarations: Array<Export_Declaration> = [],
|
|
103
|
+
log?: Logger,
|
|
104
|
+
): Array<Export_Declaration> => {
|
|
105
|
+
const export_context = new Parse_Exports_Context(program, log);
|
|
106
|
+
export_context.analyze_source_file(source_file);
|
|
107
|
+
return export_context.process_exports(source_file, exports, declarations);
|
|
108
|
+
};
|