@ryanatkn/gro 0.112.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +257 -0
  3. package/dist/args.d.ts +59 -0
  4. package/dist/args.js +132 -0
  5. package/dist/args.test.d.ts +1 -0
  6. package/dist/args.test.js +43 -0
  7. package/dist/build.task.d.ts +11 -0
  8. package/dist/build.task.js +24 -0
  9. package/dist/changelog.d.ts +8 -0
  10. package/dist/changelog.js +47 -0
  11. package/dist/changelog.test.d.ts +1 -0
  12. package/dist/changelog.test.js +118 -0
  13. package/dist/changeset.task.d.ts +49 -0
  14. package/dist/changeset.task.js +141 -0
  15. package/dist/check.task.d.ts +47 -0
  16. package/dist/check.task.js +77 -0
  17. package/dist/clean.task.d.ts +26 -0
  18. package/dist/clean.task.js +41 -0
  19. package/dist/clean_fs.d.ts +9 -0
  20. package/dist/clean_fs.js +27 -0
  21. package/dist/cli.d.ts +11 -0
  22. package/dist/cli.js +25 -0
  23. package/dist/commit.task.d.ts +11 -0
  24. package/dist/commit.task.js +22 -0
  25. package/dist/config.d.ts +21 -0
  26. package/dist/config.js +42 -0
  27. package/dist/config.test.d.ts +1 -0
  28. package/dist/config.test.js +8 -0
  29. package/dist/deploy.task.d.ts +47 -0
  30. package/dist/deploy.task.js +198 -0
  31. package/dist/dev.task.d.ts +22 -0
  32. package/dist/dev.task.js +32 -0
  33. package/dist/docs/README.gen.md.d.ts +5 -0
  34. package/dist/docs/README.gen.md.js +53 -0
  35. package/dist/docs/README.md +20 -0
  36. package/dist/docs/build.md +41 -0
  37. package/dist/docs/config.md +162 -0
  38. package/dist/docs/deploy.md +32 -0
  39. package/dist/docs/dev.md +40 -0
  40. package/dist/docs/gen.md +241 -0
  41. package/dist/docs/gro_plugin_sveltekit_frontend.md +97 -0
  42. package/dist/docs/package_json.md +29 -0
  43. package/dist/docs/plugin.md +50 -0
  44. package/dist/docs/publish.md +144 -0
  45. package/dist/docs/task.md +377 -0
  46. package/dist/docs/tasks.gen.md.d.ts +2 -0
  47. package/dist/docs/tasks.gen.md.js +60 -0
  48. package/dist/docs/tasks.md +35 -0
  49. package/dist/docs/test.md +52 -0
  50. package/dist/env.d.ts +10 -0
  51. package/dist/env.js +47 -0
  52. package/dist/esbuild_helpers.d.ts +14 -0
  53. package/dist/esbuild_helpers.js +36 -0
  54. package/dist/esbuild_plugin_external_worker.d.ts +22 -0
  55. package/dist/esbuild_plugin_external_worker.js +49 -0
  56. package/dist/esbuild_plugin_svelte.d.ts +9 -0
  57. package/dist/esbuild_plugin_svelte.js +49 -0
  58. package/dist/esbuild_plugin_sveltekit_local_imports.d.ts +7 -0
  59. package/dist/esbuild_plugin_sveltekit_local_imports.js +30 -0
  60. package/dist/esbuild_plugin_sveltekit_shim_alias.d.ts +6 -0
  61. package/dist/esbuild_plugin_sveltekit_shim_alias.js +16 -0
  62. package/dist/esbuild_plugin_sveltekit_shim_app.d.ts +8 -0
  63. package/dist/esbuild_plugin_sveltekit_shim_app.js +23 -0
  64. package/dist/esbuild_plugin_sveltekit_shim_env.d.ts +10 -0
  65. package/dist/esbuild_plugin_sveltekit_shim_env.js +18 -0
  66. package/dist/format.task.d.ts +11 -0
  67. package/dist/format.task.js +24 -0
  68. package/dist/format_directory.d.ts +2 -0
  69. package/dist/format_directory.js +27 -0
  70. package/dist/format_file.d.ts +8 -0
  71. package/dist/format_file.js +42 -0
  72. package/dist/format_file.test.d.ts +1 -0
  73. package/dist/format_file.test.js +16 -0
  74. package/dist/fs.d.ts +7 -0
  75. package/dist/fs.js +19 -0
  76. package/dist/fs.test.d.ts +1 -0
  77. package/dist/fs.test.js +16 -0
  78. package/dist/gen.d.ts +57 -0
  79. package/dist/gen.js +81 -0
  80. package/dist/gen.task.d.ts +14 -0
  81. package/dist/gen.task.js +103 -0
  82. package/dist/gen.test.d.ts +1 -0
  83. package/dist/gen.test.js +239 -0
  84. package/dist/gen_module.d.ts +46 -0
  85. package/dist/gen_module.js +54 -0
  86. package/dist/gen_module.test.d.ts +1 -0
  87. package/dist/gen_module.test.js +30 -0
  88. package/dist/git.d.ts +76 -0
  89. package/dist/git.js +200 -0
  90. package/dist/git.test.d.ts +1 -0
  91. package/dist/git.test.js +18 -0
  92. package/dist/github.d.ts +35 -0
  93. package/dist/github.js +32 -0
  94. package/dist/gro.config.default.d.ts +12 -0
  95. package/dist/gro.config.default.js +31 -0
  96. package/dist/gro.d.ts +2 -0
  97. package/dist/gro.js +19 -0
  98. package/dist/gro_helpers.d.ts +43 -0
  99. package/dist/gro_helpers.js +79 -0
  100. package/dist/gro_plugin_gen.d.ts +6 -0
  101. package/dist/gro_plugin_gen.js +80 -0
  102. package/dist/gro_plugin_server.d.ts +77 -0
  103. package/dist/gro_plugin_server.js +152 -0
  104. package/dist/gro_plugin_sveltekit_app.d.ts +27 -0
  105. package/dist/gro_plugin_sveltekit_app.js +180 -0
  106. package/dist/gro_plugin_sveltekit_library.d.ts +4 -0
  107. package/dist/gro_plugin_sveltekit_library.js +42 -0
  108. package/dist/hash.d.ts +5 -0
  109. package/dist/hash.js +14 -0
  110. package/dist/hash.test.d.ts +1 -0
  111. package/dist/hash.test.js +25 -0
  112. package/dist/index.d.ts +4 -0
  113. package/dist/index.js +3 -0
  114. package/dist/input_path.d.ts +48 -0
  115. package/dist/input_path.js +161 -0
  116. package/dist/input_path.test.d.ts +1 -0
  117. package/dist/input_path.test.js +106 -0
  118. package/dist/invoke.d.ts +1 -0
  119. package/dist/invoke.js +18 -0
  120. package/dist/invoke_task.d.ts +20 -0
  121. package/dist/invoke_task.js +140 -0
  122. package/dist/lint.task.d.ts +11 -0
  123. package/dist/lint.task.js +29 -0
  124. package/dist/loader.d.ts +4 -0
  125. package/dist/loader.js +153 -0
  126. package/dist/module.d.ts +3 -0
  127. package/dist/module.js +6 -0
  128. package/dist/module.test.d.ts +1 -0
  129. package/dist/module.test.js +41 -0
  130. package/dist/modules.d.ts +60 -0
  131. package/dist/modules.js +103 -0
  132. package/dist/modules.test.d.ts +1 -0
  133. package/dist/modules.test.js +182 -0
  134. package/dist/package.d.ts +939 -0
  135. package/dist/package.gen.d.ts +7 -0
  136. package/dist/package.gen.js +26 -0
  137. package/dist/package.js +887 -0
  138. package/dist/package_json.d.ts +342 -0
  139. package/dist/package_json.js +212 -0
  140. package/dist/package_json.test.d.ts +1 -0
  141. package/dist/package_json.test.js +77 -0
  142. package/dist/path.d.ts +12 -0
  143. package/dist/path.js +8 -0
  144. package/dist/paths.d.ts +60 -0
  145. package/dist/paths.js +128 -0
  146. package/dist/paths.test.d.ts +1 -0
  147. package/dist/paths.test.js +49 -0
  148. package/dist/plugin.d.ts +36 -0
  149. package/dist/plugin.js +80 -0
  150. package/dist/plugin.test.d.ts +1 -0
  151. package/dist/plugin.test.js +54 -0
  152. package/dist/print_task.d.ts +4 -0
  153. package/dist/print_task.js +124 -0
  154. package/dist/publish.task.d.ts +32 -0
  155. package/dist/publish.task.js +125 -0
  156. package/dist/release.task.d.ts +5 -0
  157. package/dist/release.task.js +18 -0
  158. package/dist/resolve_node_specifier.d.ts +8 -0
  159. package/dist/resolve_node_specifier.js +39 -0
  160. package/dist/resolve_node_specifier.test.d.ts +1 -0
  161. package/dist/resolve_node_specifier.test.js +21 -0
  162. package/dist/resolve_specifier.d.ts +15 -0
  163. package/dist/resolve_specifier.js +51 -0
  164. package/dist/resolve_specifier.test.d.ts +1 -0
  165. package/dist/resolve_specifier.test.js +66 -0
  166. package/dist/run.task.d.ts +11 -0
  167. package/dist/run.task.js +31 -0
  168. package/dist/run_gen.d.ts +6 -0
  169. package/dist/run_gen.js +74 -0
  170. package/dist/run_gen.test.d.ts +1 -0
  171. package/dist/run_gen.test.js +182 -0
  172. package/dist/run_task.d.ts +13 -0
  173. package/dist/run_task.js +44 -0
  174. package/dist/run_task.test.d.ts +1 -0
  175. package/dist/run_task.test.js +63 -0
  176. package/dist/search_fs.d.ts +11 -0
  177. package/dist/search_fs.js +22 -0
  178. package/dist/search_fs.test.d.ts +1 -0
  179. package/dist/search_fs.test.js +46 -0
  180. package/dist/src_json.d.ts +256 -0
  181. package/dist/src_json.js +110 -0
  182. package/dist/src_json.test.d.ts +1 -0
  183. package/dist/src_json.test.js +52 -0
  184. package/dist/sveltekit_config.d.ts +36 -0
  185. package/dist/sveltekit_config.js +51 -0
  186. package/dist/sveltekit_shim_app.d.ts +10 -0
  187. package/dist/sveltekit_shim_app.js +31 -0
  188. package/dist/sveltekit_shim_app_environment.d.ts +10 -0
  189. package/dist/sveltekit_shim_app_environment.js +12 -0
  190. package/dist/sveltekit_shim_app_forms.d.ts +5 -0
  191. package/dist/sveltekit_shim_app_forms.js +13 -0
  192. package/dist/sveltekit_shim_app_navigation.d.ts +10 -0
  193. package/dist/sveltekit_shim_app_navigation.js +11 -0
  194. package/dist/sveltekit_shim_app_paths.d.ts +11 -0
  195. package/dist/sveltekit_shim_app_paths.js +6 -0
  196. package/dist/sveltekit_shim_app_stores.d.ts +6 -0
  197. package/dist/sveltekit_shim_app_stores.js +17 -0
  198. package/dist/sveltekit_shim_env.d.ts +4 -0
  199. package/dist/sveltekit_shim_env.js +23 -0
  200. package/dist/sync.task.d.ts +30 -0
  201. package/dist/sync.task.js +45 -0
  202. package/dist/task.d.ts +29 -0
  203. package/dist/task.js +17 -0
  204. package/dist/task.test.d.ts +1 -0
  205. package/dist/task.test.js +22 -0
  206. package/dist/task_module.d.ts +14 -0
  207. package/dist/task_module.js +19 -0
  208. package/dist/task_module.test.d.ts +1 -0
  209. package/dist/task_module.test.js +70 -0
  210. package/dist/test.task.d.ts +20 -0
  211. package/dist/test.task.js +43 -0
  212. package/dist/throttle.d.ts +16 -0
  213. package/dist/throttle.js +59 -0
  214. package/dist/throttle.test.d.ts +1 -0
  215. package/dist/throttle.test.js +49 -0
  216. package/dist/typecheck.task.d.ts +5 -0
  217. package/dist/typecheck.task.js +38 -0
  218. package/dist/upgrade.task.d.ts +14 -0
  219. package/dist/upgrade.task.js +37 -0
  220. package/dist/watch_dir.d.ts +30 -0
  221. package/dist/watch_dir.js +59 -0
  222. package/package.json +422 -0
@@ -0,0 +1,49 @@
1
+ import * as esbuild from 'esbuild';
2
+ import { basename } from 'node:path';
3
+ import { cwd } from 'node:process';
4
+ import { print_build_result, to_define_import_meta_env } from './esbuild_helpers.js';
5
+ import { resolve_specifier } from './resolve_specifier.js';
6
+ import { esbuild_plugin_sveltekit_shim_alias } from './esbuild_plugin_sveltekit_shim_alias.js';
7
+ import { esbuild_plugin_sveltekit_shim_env } from './esbuild_plugin_sveltekit_shim_env.js';
8
+ import { esbuild_plugin_sveltekit_shim_app } from './esbuild_plugin_sveltekit_shim_app.js';
9
+ import { esbuild_plugin_sveltekit_local_imports } from './esbuild_plugin_sveltekit_local_imports.js';
10
+ import { esbuild_plugin_svelte } from './esbuild_plugin_svelte.js';
11
+ export const esbuild_plugin_external_worker = ({ dev, build_options, dir = cwd(), svelte_compile_options, svelte_preprocessors, alias, base_url, assets_url, public_prefix, private_prefix, env_dir, env_files, ambient_env, log, }) => ({
12
+ name: 'external_worker',
13
+ setup: (build) => {
14
+ const builds = new Map();
15
+ const build_worker = async (source_id) => {
16
+ if (builds.has(source_id))
17
+ return builds.get(source_id);
18
+ const building = esbuild.build({
19
+ entryPoints: [source_id],
20
+ plugins: [
21
+ esbuild_plugin_sveltekit_shim_app({ dev, base_url, assets_url }),
22
+ esbuild_plugin_sveltekit_shim_env({
23
+ dev,
24
+ public_prefix,
25
+ private_prefix,
26
+ env_dir,
27
+ env_files,
28
+ ambient_env,
29
+ }),
30
+ esbuild_plugin_sveltekit_shim_alias({ dir, alias }),
31
+ esbuild_plugin_svelte({ dir, svelte_compile_options, svelte_preprocessors }),
32
+ esbuild_plugin_sveltekit_local_imports(),
33
+ ],
34
+ define: to_define_import_meta_env(dev, base_url),
35
+ ...build_options,
36
+ });
37
+ builds.set(source_id, building);
38
+ return building;
39
+ };
40
+ build.onResolve({ filter: /\.worker(|\.js|\.ts)$/u }, async ({ path, resolveDir }) => {
41
+ const parsed = await resolve_specifier(path, resolveDir);
42
+ const { specifier, source_id, namespace } = parsed;
43
+ const build_result = await build_worker(source_id);
44
+ if (log)
45
+ print_build_result(log, build_result);
46
+ return { path: './' + basename(specifier), external: true, namespace };
47
+ });
48
+ },
49
+ });
@@ -0,0 +1,9 @@
1
+ /// <reference types="svelte" />
2
+ import type * as esbuild from 'esbuild';
3
+ import { type CompileOptions, type PreprocessorGroup } from 'svelte/compiler';
4
+ export interface Options {
5
+ dir?: string;
6
+ svelte_compile_options?: CompileOptions;
7
+ svelte_preprocessors?: PreprocessorGroup | PreprocessorGroup[];
8
+ }
9
+ export declare const esbuild_plugin_svelte: ({ dir, svelte_compile_options, svelte_preprocessors, }: Options) => esbuild.Plugin;
@@ -0,0 +1,49 @@
1
+ import { compile, preprocess } from 'svelte/compiler';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { relative } from 'node:path';
4
+ import { cwd } from 'node:process';
5
+ export const esbuild_plugin_svelte = ({ dir = cwd(), svelte_compile_options, svelte_preprocessors, }) => ({
6
+ name: 'svelte',
7
+ setup: (build) => {
8
+ build.onLoad({ filter: /\.svelte$/u }, async ({ path }) => {
9
+ let source = await readFile(path, 'utf8');
10
+ try {
11
+ const filename = relative(dir, path);
12
+ const preprocessed = svelte_preprocessors
13
+ ? await preprocess(source, svelte_preprocessors, { filename })
14
+ : null;
15
+ // TODO handle preprocessor sourcemaps, same as in loader - merge?
16
+ if (preprocessed?.code)
17
+ source = preprocessed?.code;
18
+ const { js, warnings } = compile(source, svelte_compile_options);
19
+ const contents = js.map ? js.code + '//# sourceMappingURL=' + js.map.toUrl() : js.code;
20
+ return {
21
+ contents,
22
+ warnings: warnings.map((w) => to_sveltekit_message(filename, source, w)),
23
+ };
24
+ }
25
+ catch (err) {
26
+ return { errors: [to_sveltekit_message(path, source, err)] };
27
+ }
28
+ });
29
+ },
30
+ });
31
+ /**
32
+ * Following the example in the esbuild docs:
33
+ * https://esbuild.github.io/plugins/#svelte-plugin
34
+ */
35
+ const to_sveltekit_message = (path, source, { message, start, end }) => {
36
+ let location = null;
37
+ if (start && end) {
38
+ const lineText = source.split(/\r\n|\r|\n/gu)[start.line - 1];
39
+ const lineEnd = start.line === end.line ? end.column : lineText.length;
40
+ location = {
41
+ file: path,
42
+ line: start.line,
43
+ lineText,
44
+ column: start.column,
45
+ length: lineEnd - start.column,
46
+ };
47
+ }
48
+ return { text: message, location };
49
+ };
@@ -0,0 +1,7 @@
1
+ import type * as esbuild from 'esbuild';
2
+ /**
3
+ * Adds support for imports to both `.ts` and `.js`,
4
+ * as well as imports without extensions that resolve to `.js` or `.ts`.
5
+ * Prefers `.ts` over any `.js`, and falls back to `.ts` if no file is found.
6
+ */
7
+ export declare const esbuild_plugin_sveltekit_local_imports: () => esbuild.Plugin;
@@ -0,0 +1,30 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { dirname } from 'node:path';
3
+ import { resolve_specifier } from './resolve_specifier.js';
4
+ /**
5
+ * Adds support for imports to both `.ts` and `.js`,
6
+ * as well as imports without extensions that resolve to `.js` or `.ts`.
7
+ * Prefers `.ts` over any `.js`, and falls back to `.ts` if no file is found.
8
+ */
9
+ export const esbuild_plugin_sveltekit_local_imports = () => ({
10
+ name: 'sveltekit_local_imports',
11
+ setup: (build) => {
12
+ build.onResolve({ filter: /^(\/|\.)/u }, async (args) => {
13
+ const { path, importer } = args;
14
+ if (!importer)
15
+ return { path };
16
+ const { source_id, namespace } = await resolve_specifier(path, dirname(importer));
17
+ return { path: source_id, namespace }; // `namespace` may be `undefined`, but esbuild needs the absolute path for json etc
18
+ });
19
+ build.onLoad({ filter: /.*/u, namespace: 'sveltekit_local_imports_ts' }, async ({ path }) => ({
20
+ contents: await readFile(path),
21
+ loader: 'ts',
22
+ resolveDir: dirname(path),
23
+ }));
24
+ build.onLoad({ filter: /.*/u, namespace: 'sveltekit_local_imports_js' }, async ({ path }) => ({
25
+ contents: await readFile(path),
26
+ loader: 'js',
27
+ resolveDir: dirname(path),
28
+ }));
29
+ },
30
+ });
@@ -0,0 +1,6 @@
1
+ import type * as esbuild from 'esbuild';
2
+ export interface Options {
3
+ dir?: string;
4
+ alias?: Record<string, string>;
5
+ }
6
+ export declare const esbuild_plugin_sveltekit_shim_alias: ({ dir, alias, }: Options) => esbuild.Plugin;
@@ -0,0 +1,16 @@
1
+ import { escape_regexp } from '@ryanatkn/belt/regexp.js';
2
+ import { cwd } from 'node:process';
3
+ import { join } from 'node:path';
4
+ export const esbuild_plugin_sveltekit_shim_alias = ({ dir = cwd(), alias, }) => ({
5
+ name: 'sveltekit_shim_alias',
6
+ setup: (build) => {
7
+ const aliases = { $lib: 'src/lib', ...alias };
8
+ const alias_regexp_prefixes = Object.keys(aliases).map((a) => escape_regexp(a));
9
+ const filter = new RegExp('^(' + alias_regexp_prefixes.join('|') + ')', 'u');
10
+ build.onResolve({ filter }, async (args) => {
11
+ const { path, ...rest } = args;
12
+ const prefix = filter.exec(path)[1];
13
+ return build.resolve(join(dir, aliases[prefix] + path.substring(prefix.length)), rest);
14
+ });
15
+ },
16
+ });
@@ -0,0 +1,8 @@
1
+ import type * as esbuild from 'esbuild';
2
+ import type { Parsed_Sveltekit_Config } from './sveltekit_config.js';
3
+ export interface Options {
4
+ dev: boolean;
5
+ base_url: Parsed_Sveltekit_Config['base_url'];
6
+ assets_url: Parsed_Sveltekit_Config['assets_url'];
7
+ }
8
+ export declare const esbuild_plugin_sveltekit_shim_app: ({ dev, base_url, assets_url, }: Options) => esbuild.Plugin;
@@ -0,0 +1,23 @@
1
+ import { render_sveltekit_shim_app_environment, render_sveltekit_shim_app_paths, sveltekit_shim_app_specifiers, } from './sveltekit_shim_app.js';
2
+ export const esbuild_plugin_sveltekit_shim_app = ({ dev, base_url, assets_url, }) => ({
3
+ name: 'sveltekit_shim_app',
4
+ setup: (build) => {
5
+ build.onResolve({ filter: /^\$app\/(forms|navigation|stores)$/u }, ({ path, ...rest }) => build.resolve(sveltekit_shim_app_specifiers.get(path), rest));
6
+ build.onResolve({ filter: /^\$app\/paths$/u }, ({ path }) => ({
7
+ path: sveltekit_shim_app_specifiers.get(path),
8
+ namespace: 'sveltekit_shim_app_paths',
9
+ }));
10
+ build.onLoad({ filter: /.*/u, namespace: 'sveltekit_shim_app_paths' }, () => ({
11
+ loader: 'js',
12
+ contents: render_sveltekit_shim_app_paths(base_url, assets_url),
13
+ }));
14
+ build.onResolve({ filter: /^\$app\/environment$/u }, ({ path }) => ({
15
+ path: sveltekit_shim_app_specifiers.get(path),
16
+ namespace: 'sveltekit_shim_app_environment',
17
+ }));
18
+ build.onLoad({ filter: /.*/u, namespace: 'sveltekit_shim_app_environment' }, () => ({
19
+ loader: 'js',
20
+ contents: render_sveltekit_shim_app_environment(dev),
21
+ }));
22
+ },
23
+ });
@@ -0,0 +1,10 @@
1
+ import type * as esbuild from 'esbuild';
2
+ export interface Options {
3
+ dev: boolean;
4
+ public_prefix?: string;
5
+ private_prefix?: string;
6
+ env_dir?: string;
7
+ env_files?: string[];
8
+ ambient_env?: Record<string, string>;
9
+ }
10
+ export declare const esbuild_plugin_sveltekit_shim_env: ({ dev, public_prefix, private_prefix, env_dir, env_files, ambient_env, }: Options) => esbuild.Plugin;
@@ -0,0 +1,18 @@
1
+ import { render_env_shim_module } from './sveltekit_shim_env.js';
2
+ export const esbuild_plugin_sveltekit_shim_env = ({ dev, public_prefix, private_prefix, env_dir, env_files, ambient_env, }) => ({
3
+ name: 'sveltekit_shim_env',
4
+ setup: (build) => {
5
+ const namespace = 'sveltekit_shim_env';
6
+ const filter = /^\$env\/(static|dynamic)\/(public|private)$/u;
7
+ build.onResolve({ filter }, ({ path }) => ({ path, namespace }));
8
+ build.onLoad({ filter: /.*/u, namespace }, async ({ path }) => {
9
+ const matches = filter.exec(path);
10
+ const mode = matches[1];
11
+ const visibility = matches[2];
12
+ return {
13
+ loader: 'ts',
14
+ contents: await render_env_shim_module(dev, mode, visibility, public_prefix, private_prefix, env_dir, env_files, ambient_env),
15
+ };
16
+ });
17
+ },
18
+ });
@@ -0,0 +1,11 @@
1
+ import { z } from 'zod';
2
+ import { type Task } from './task.js';
3
+ export declare const Args: z.ZodObject<{
4
+ check: z.ZodDefault<z.ZodBoolean>;
5
+ }, "strict", z.ZodTypeAny, {
6
+ check: boolean;
7
+ }, {
8
+ check?: boolean | undefined;
9
+ }>;
10
+ export type Args = z.infer<typeof Args>;
11
+ export declare const task: Task<Args>;
@@ -0,0 +1,24 @@
1
+ import { print_spawn_result } from '@ryanatkn/belt/process.js';
2
+ import { z } from 'zod';
3
+ import { Task_Error } from './task.js';
4
+ import { format_directory } from './format_directory.js';
5
+ import { paths } from './paths.js';
6
+ export const Args = z
7
+ .object({
8
+ check: z
9
+ .boolean({ description: 'exit with a nonzero code if any files are unformatted' })
10
+ .default(false),
11
+ })
12
+ .strict();
13
+ export const task = {
14
+ summary: 'format source files',
15
+ Args,
16
+ run: async ({ args, log }) => {
17
+ const { check } = args;
18
+ // TODO forward prettier args
19
+ const format_result = await format_directory(log, paths.source, check);
20
+ if (!format_result.ok) {
21
+ throw new Task_Error(`Failed ${check ? 'formatting check' : 'to format'}. ${print_spawn_result(format_result)}`);
22
+ }
23
+ },
24
+ };
@@ -0,0 +1,2 @@
1
+ import { type Spawn_Result } from '@ryanatkn/belt/process.js';
2
+ export declare const format_directory: (log: Logger, directory: string, check?: boolean, extensions?: string, root_paths?: string) => Promise<Spawn_Result>;
@@ -0,0 +1,27 @@
1
+ import { spawn } from '@ryanatkn/belt/process.js';
2
+ import { GITHUB_DIRNAME, paths, README_FILENAME, SVELTEKIT_CONFIG_FILENAME, VITE_CONFIG_FILENAME, TSCONFIG_FILENAME, CONFIG_PATH, } from './paths.js';
3
+ import { print_command_args, serialize_args, to_forwarded_args } from './args.js';
4
+ const DEFAULT_EXTENSIONS = 'ts,js,json,svelte,html,css,md,yml';
5
+ const DEFAULT_ROOT_PATHS = `${[
6
+ README_FILENAME,
7
+ CONFIG_PATH,
8
+ SVELTEKIT_CONFIG_FILENAME,
9
+ VITE_CONFIG_FILENAME,
10
+ TSCONFIG_FILENAME,
11
+ GITHUB_DIRNAME,
12
+ ].join(',')}/**/*`;
13
+ // This formats a directory on the filesystem.
14
+ // If the source directory is given, it also formats all of the root directory files.
15
+ // This is separated from `./format_file` to avoid importing all of the `prettier` code
16
+ // inside modules that import this one. (which has a nontrivial cost)
17
+ export const format_directory = (log, directory, check = false, extensions = DEFAULT_EXTENSIONS, root_paths = DEFAULT_ROOT_PATHS) => {
18
+ const forwarded_args = to_forwarded_args('prettier');
19
+ forwarded_args[check ? 'check' : 'write'] = true;
20
+ const serialized_args = ['prettier', ...serialize_args(forwarded_args)];
21
+ serialized_args.push(`${directory}**/*.{${extensions}}`);
22
+ if (directory === paths.source) {
23
+ serialized_args.push(`${paths.root}{${root_paths}}`);
24
+ }
25
+ log.info(print_command_args(serialized_args));
26
+ return spawn('npx', serialized_args);
27
+ };
@@ -0,0 +1,8 @@
1
+ import prettier from 'prettier';
2
+ /**
3
+ * Formats a file with Prettier.
4
+ * @param content
5
+ * @param options
6
+ * @param base_options - defaults to the the cwd's package.json `prettier` value
7
+ */
8
+ export declare const format_file: (content: string, options: prettier.Options, base_options?: prettier.Options | null | undefined) => Promise<string>;
@@ -0,0 +1,42 @@
1
+ import prettier from 'prettier';
2
+ import { extname } from 'node:path';
3
+ import { load_package_json } from './package_json.js';
4
+ let cached_base_options;
5
+ /**
6
+ * Formats a file with Prettier.
7
+ * @param content
8
+ * @param options
9
+ * @param base_options - defaults to the the cwd's package.json `prettier` value
10
+ */
11
+ export const format_file = async (content, options, base_options = cached_base_options) => {
12
+ const final_base_options = base_options !== undefined
13
+ ? base_options
14
+ : (cached_base_options = (await load_package_json()).prettier);
15
+ let final_options = options;
16
+ if (options.filepath && !options.parser) {
17
+ const { filepath, ...rest } = options;
18
+ const parser = infer_parser(filepath);
19
+ if (parser)
20
+ final_options = { ...rest, parser };
21
+ }
22
+ try {
23
+ return await prettier.format(content, { ...final_base_options, ...final_options });
24
+ }
25
+ catch (err) {
26
+ return content;
27
+ }
28
+ };
29
+ // This is just a simple convenience for callers so they can pass a file path.
30
+ // They can provide the Prettier `options.parser` for custom extensions.
31
+ const infer_parser = (path) => {
32
+ const extension = extname(path).substring(1);
33
+ switch (extension) {
34
+ case 'svelte':
35
+ case 'xml': {
36
+ return extension;
37
+ }
38
+ default: {
39
+ return null;
40
+ }
41
+ }
42
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ import { test } from 'uvu';
2
+ import * as assert from 'uvu/assert';
3
+ import { format_file } from './format_file.js';
4
+ test('format ts', async () => {
5
+ const ts_unformatted = 'hey (1)';
6
+ const ts_formatted = 'hey(1);\n';
7
+ assert.is(await format_file(ts_unformatted, { filepath: 'foo.ts' }), ts_formatted);
8
+ assert.is(await format_file(ts_unformatted, { parser: 'typescript' }), ts_formatted);
9
+ });
10
+ test('format svelte', async () => {
11
+ const svelte_unformatted = '<style>a{color: red}</style>';
12
+ const svelte_formatted = '<style>\n\ta {\n\t\tcolor: red;\n\t}\n</style>\n';
13
+ assert.is(await format_file(svelte_unformatted, { filepath: 'foo.svelte' }), svelte_formatted);
14
+ assert.is(await format_file(svelte_unformatted, { parser: 'svelte' }), svelte_formatted);
15
+ });
16
+ test.run();
package/dist/fs.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ /// <reference types="node" />
2
+ import type { RmOptions } from 'node:fs';
3
+ export declare const exists: (path: string) => Promise<boolean>;
4
+ /**
5
+ * Empties a directory with an optional `filter`.
6
+ */
7
+ export declare const empty_dir: (dir: string, filter?: ((path: string) => boolean) | undefined, options?: RmOptions) => Promise<void>;
package/dist/fs.js ADDED
@@ -0,0 +1,19 @@
1
+ import { access, constants, readdir, rm } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ export const exists = async (path) => {
4
+ try {
5
+ await access(path, constants.F_OK);
6
+ return true;
7
+ }
8
+ catch (err) {
9
+ if (err.code === 'ENOENT')
10
+ return false;
11
+ throw err;
12
+ }
13
+ };
14
+ /**
15
+ * Empties a directory with an optional `filter`.
16
+ */
17
+ export const empty_dir = async (dir, filter, options) => {
18
+ await Promise.all((await readdir(dir)).map((path) => filter && !filter(path) ? null : rm(join(dir, path), { ...options, recursive: true })));
19
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ import { test } from 'uvu';
2
+ import * as assert from 'uvu/assert';
3
+ import { exists } from './fs.js';
4
+ test('file exists', async () => {
5
+ assert.ok(await exists('./src/lib/fs.ts'));
6
+ });
7
+ test('file does not exist', async () => {
8
+ assert.ok(!(await exists('./src/lib/existsssss.ts')));
9
+ });
10
+ test('directory exists', async () => {
11
+ assert.ok(await exists('./src/lib'));
12
+ });
13
+ test('directory does not exist', async () => {
14
+ assert.ok(!(await exists('./src/libbbbbbbb')));
15
+ });
16
+ test.run();
package/dist/gen.d.ts ADDED
@@ -0,0 +1,57 @@
1
+ import type { Logger } from '@ryanatkn/belt/log.js';
2
+ import { z } from 'zod';
3
+ export type Gen_Result = {
4
+ origin_id: string;
5
+ files: Gen_File[];
6
+ };
7
+ export interface Gen_File {
8
+ id: string;
9
+ content: string;
10
+ origin_id: string;
11
+ format: boolean;
12
+ }
13
+ export interface Gen {
14
+ (ctx: Gen_Context): Raw_Gen_Result | Promise<Raw_Gen_Result>;
15
+ }
16
+ export interface Gen_Context {
17
+ origin_id: string;
18
+ log: Logger;
19
+ }
20
+ export type Raw_Gen_Result = string | Raw_Gen_File | null | Raw_Gen_Result[];
21
+ export interface Raw_Gen_File {
22
+ content: string;
23
+ filename?: string;
24
+ format?: boolean;
25
+ }
26
+ export declare const Gen_Config: z.ZodObject<{
27
+ imports: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
28
+ }, "strip", z.ZodTypeAny, {
29
+ imports: Record<string, string>;
30
+ }, {
31
+ imports?: Record<string, string> | undefined;
32
+ }>;
33
+ export type Gen_Config = z.infer<typeof Gen_Config>;
34
+ export type Gen_Results = {
35
+ results: Gen_Module_Result[];
36
+ successes: Gen_Module_Result_Success[];
37
+ failures: Gen_Module_Result_Failure[];
38
+ input_count: number;
39
+ output_count: number;
40
+ elapsed: number;
41
+ };
42
+ export type Gen_Module_Result = Gen_Module_Result_Success | Gen_Module_Result_Failure;
43
+ export type Gen_Module_Result_Success = {
44
+ ok: true;
45
+ id: string;
46
+ files: Gen_File[];
47
+ elapsed: number;
48
+ };
49
+ export type Gen_Module_Result_Failure = {
50
+ ok: false;
51
+ id: string;
52
+ reason: string;
53
+ error: Error;
54
+ elapsed: number;
55
+ };
56
+ export declare const to_gen_result: (origin_id: Flavored<string, "Source_Id">, raw_result: Raw_Gen_Result) => Gen_Result;
57
+ export declare const to_output_file_name: (filename: string) => string;
package/dist/gen.js ADDED
@@ -0,0 +1,81 @@
1
+ import { join, basename, dirname, isAbsolute } from 'node:path';
2
+ import { z } from 'zod';
3
+ import { gen_module_meta, to_gen_module_type } from './gen_module.js';
4
+ export const Gen_Config = z.object({
5
+ imports: z.record(z.string(), z.string()).default({}),
6
+ });
7
+ export const to_gen_result = (origin_id, raw_result) => {
8
+ return {
9
+ origin_id,
10
+ files: to_gen_files(origin_id, raw_result),
11
+ };
12
+ };
13
+ const to_gen_files = (origin_id, raw_result) => {
14
+ if (raw_result === null) {
15
+ return [];
16
+ }
17
+ else if (typeof raw_result === 'string') {
18
+ return [to_gen_file(origin_id, { content: raw_result })];
19
+ }
20
+ else if (Array.isArray(raw_result)) {
21
+ const files = raw_result.flatMap((f) => to_gen_files(origin_id, f));
22
+ validate_gen_files(files);
23
+ return files;
24
+ }
25
+ return [to_gen_file(origin_id, raw_result)];
26
+ };
27
+ const to_gen_file = (origin_id, raw_gen_file) => {
28
+ const { content, filename, format = true } = raw_gen_file;
29
+ const id = to_output_file_id(origin_id, filename);
30
+ return { id, content, origin_id, format };
31
+ };
32
+ const to_output_file_id = (origin_id, raw_file_name) => {
33
+ if (raw_file_name === '') {
34
+ throw Error(`Output file name cannot be an empty string`);
35
+ }
36
+ const filename = raw_file_name || to_output_file_name(basename(origin_id));
37
+ if (isAbsolute(filename))
38
+ return filename;
39
+ const dir = dirname(origin_id);
40
+ const output_file_id = join(dir, filename);
41
+ if (output_file_id === origin_id) {
42
+ throw Error('Gen origin and output file ids cannot be the same');
43
+ }
44
+ return output_file_id;
45
+ };
46
+ export const to_output_file_name = (filename) => {
47
+ const { pattern, text } = gen_module_meta[to_gen_module_type(filename)];
48
+ const parts = filename.split('.');
49
+ const gen_pattern_index = parts.indexOf(text);
50
+ if (gen_pattern_index === -1) {
51
+ throw Error(`Invalid gen file name - '${text}' not found in '${filename}'`);
52
+ }
53
+ if (gen_pattern_index !== parts.lastIndexOf(text)) {
54
+ throw Error(`Invalid gen file name - multiple instances of '${text}' found in '${filename}'`);
55
+ }
56
+ if (gen_pattern_index < parts.length - 3) {
57
+ // This check is technically unneccessary,
58
+ // but ensures a consistent file naming convention.
59
+ throw Error(`Invalid gen file name - only one additional extension is allowed to follow '${pattern}' in '${filename}'`);
60
+ }
61
+ const final_parts = [];
62
+ const has_different_ext = gen_pattern_index === parts.length - 3;
63
+ const length = has_different_ext ? parts.length - 1 : parts.length;
64
+ for (let i = 0; i < length; i++) {
65
+ if (i === gen_pattern_index)
66
+ continue; // skip the `.gen.` pattern
67
+ if (i === length - 1 && parts[i] === '')
68
+ continue; // allow empty extension
69
+ final_parts.push(parts[i]);
70
+ }
71
+ return final_parts.join('.');
72
+ };
73
+ const validate_gen_files = (files) => {
74
+ const ids = new Set();
75
+ for (const file of files) {
76
+ if (ids.has(file.id)) {
77
+ throw Error(`Duplicate gen file id: ${file.id}`);
78
+ }
79
+ ids.add(file.id);
80
+ }
81
+ };
@@ -0,0 +1,14 @@
1
+ import { z } from 'zod';
2
+ import { type Task } from './task.js';
3
+ export declare const Args: z.ZodObject<{
4
+ _: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
5
+ check: z.ZodDefault<z.ZodBoolean>;
6
+ }, "strict", z.ZodTypeAny, {
7
+ _: string[];
8
+ check: boolean;
9
+ }, {
10
+ _?: string[] | undefined;
11
+ check?: boolean | undefined;
12
+ }>;
13
+ export type Args = z.infer<typeof Args>;
14
+ export declare const task: Task<Args>;