@ryanatkn/gro 0.189.2 → 0.190.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.
@@ -1,5 +1,5 @@
1
- import type { Logger } from '@fuzdev/fuz_util/log.js';
2
1
  import { z } from 'zod';
2
+ import type { Logger } from '@fuzdev/fuz_util/log.js';
3
3
  import type { GroConfig } from './gro_config.ts';
4
4
  export declare const BUILD_CACHE_METADATA_FILENAME = "build.json";
5
5
  export declare const BUILD_CACHE_VERSION = "1";
@@ -1 +1 @@
1
- {"version":3,"file":"build_cache.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/build_cache.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAKpD,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAGtB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAI/C,eAAO,MAAM,6BAA6B,eAAe,CAAC;AAC1D,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;;;kBAW3B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;kBAU7B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GACnC,QAAQ,SAAS,EACjB,KAAK,MAAM,EACX,aAAa,MAAM,GAAG,IAAI,KACxB,OAAO,CAAC;IACV,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,uBAAuB,EAAE,MAAM,CAAC;CAChC,CAYA,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,QAAa,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAoCnF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,GACrC,UAAU,kBAAkB,EAC5B,MAAM,MAAM,KACV,OAAO,CAAC,IAAI,CAcd,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAU,UAAU,kBAAkB,KAAG,OAAO,CAAC,OAAO,CAmCxF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAChC,QAAQ,SAAS,EACjB,KAAK,MAAM,EACX,aAAa,MAAM,GAAG,IAAI,KACxB,OAAO,CAAC,OAAO,CA+BjB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,GACjC,YAAY,KAAK,CAAC,MAAM,CAAC,KACvB,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAkEjC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,QAAa,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAkCxE,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,GACvC,QAAQ,SAAS,EACjB,KAAK,MAAM,EACX,aAAa,MAAM,GAAG,IAAI,EAC1B,aAAa,KAAK,CAAC,MAAM,CAAC,KACxB,OAAO,CAAC,kBAAkB,CAW5B,CAAC"}
1
+ {"version":3,"file":"build_cache.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/build_cache.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAMpD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAI/C,eAAO,MAAM,6BAA6B,eAAe,CAAC;AAC1D,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;;;kBAW3B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;kBAU7B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GACnC,QAAQ,SAAS,EACjB,KAAK,MAAM,EACX,aAAa,MAAM,GAAG,IAAI,KACxB,OAAO,CAAC;IACV,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,uBAAuB,EAAE,MAAM,CAAC;CAChC,CAYA,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,QAAa,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAoCnF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,GACrC,UAAU,kBAAkB,EAC5B,MAAM,MAAM,KACV,OAAO,CAAC,IAAI,CAcd,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAU,UAAU,kBAAkB,KAAG,OAAO,CAAC,OAAO,CAmCxF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAChC,QAAQ,SAAS,EACjB,KAAK,MAAM,EACX,aAAa,MAAM,GAAG,IAAI,KACxB,OAAO,CAAC,OAAO,CA+BjB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,GACjC,YAAY,KAAK,CAAC,MAAM,CAAC,KACvB,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAkEjC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,QAAa,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAkCxE,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,GACvC,QAAQ,SAAS,EACjB,KAAK,MAAM,EACX,aAAa,MAAM,GAAG,IAAI,EAC1B,aAAa,KAAK,CAAC,MAAM,CAAC,KACxB,OAAO,CAAC,kBAAkB,CAW5B,CAAC"}
@@ -1,11 +1,11 @@
1
1
  import { mkdir, readdir, readFile, rm, stat, writeFile } from 'node:fs/promises';
2
2
  import { join } from 'node:path';
3
3
  import { styleText as st } from 'node:util';
4
+ import { z } from 'zod';
4
5
  import { git_current_commit_hash } from '@fuzdev/fuz_util/git.js';
5
6
  import { fs_exists } from '@fuzdev/fuz_util/fs.js';
6
7
  import { map_concurrent } from '@fuzdev/fuz_util/async.js';
7
- import { z } from 'zod';
8
- import { to_hash } from "./hash.js";
8
+ import { hash_secure } from '@fuzdev/fuz_util/hash.js';
9
9
  import { paths } from "./paths.js";
10
10
  import { SVELTEKIT_BUILD_DIRNAME, SVELTEKIT_DIST_DIRNAME, GRO_DIST_PREFIX } from "./constants.js";
11
11
  export const BUILD_CACHE_METADATA_FILENAME = 'build.json';
@@ -142,7 +142,7 @@ export const validate_build_cache = async (metadata) => {
142
142
  const results = await map_concurrent(metadata.outputs, async (output) => {
143
143
  try {
144
144
  const contents = await readFile(output.path);
145
- const actual_hash = await to_hash(contents);
145
+ const actual_hash = await hash_secure(contents);
146
146
  return actual_hash === output.hash;
147
147
  }
148
148
  catch {
@@ -197,7 +197,7 @@ export const is_build_cache_valid = async (config, log, git_commit) => {
197
197
  * @param build_dirs Array of output directories to scan (e.g., ['build', 'dist', 'dist_server'])
198
198
  */
199
199
  export const collect_build_outputs = async (build_dirs) => {
200
- const files_to_hash = [];
200
+ const files_hash_secure = [];
201
201
  // Recursively collect files
202
202
  const collect_files = async (dir, relative_base, dir_prefix) => {
203
203
  const entries = await readdir(dir, { withFileTypes: true });
@@ -214,7 +214,7 @@ export const collect_build_outputs = async (build_dirs) => {
214
214
  await collect_files(full_path, relative_path, dir_prefix);
215
215
  }
216
216
  else if (entry.isFile()) {
217
- files_to_hash.push({ full_path, cache_key });
217
+ files_hash_secure.push({ full_path, cache_key });
218
218
  }
219
219
  // Symlinks are intentionally ignored - we only hash regular files
220
220
  }
@@ -229,10 +229,10 @@ export const collect_build_outputs = async (build_dirs) => {
229
229
  await collect_files(build_dir, '', build_dir);
230
230
  }
231
231
  // Hash files with controlled concurrency and collect stats (could be 10k+ files)
232
- return map_concurrent(files_to_hash, async ({ full_path, cache_key }) => {
232
+ return map_concurrent(files_hash_secure, async ({ full_path, cache_key }) => {
233
233
  const stats = await stat(full_path);
234
234
  const contents = await readFile(full_path);
235
- const hash = await to_hash(contents);
235
+ const hash = await hash_secure(contents);
236
236
  return {
237
237
  path: cache_key,
238
238
  hash,
@@ -10,7 +10,7 @@ export declare const Args: z.ZodObject<{
10
10
  install: z.ZodDefault<z.ZodBoolean>;
11
11
  }, z.core.$strict>;
12
12
  export type Args = z.infer<typeof Args>;
13
- export type DevTask_Context = PluginContext<Args>;
13
+ export type DevTaskContext = PluginContext<Args>;
14
14
  /** @nodocs */
15
15
  export declare const task: Task<Args>;
16
16
  //# sourceMappingURL=dev.task.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dev.task.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/dev.task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,EAAU,KAAK,aAAa,EAAC,MAAM,aAAa,CAAC;AAGxD,cAAc;AACd,eAAO,MAAM,IAAI;;;;;;kBAWf,CAAC;AACH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;AAExC,MAAM,MAAM,eAAe,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;AAElD,cAAc;AACd,eAAO,MAAM,IAAI,EAAE,IAAI,CAAC,IAAI,CA2B3B,CAAC"}
1
+ {"version":3,"file":"dev.task.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/dev.task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,EAAU,KAAK,aAAa,EAAC,MAAM,aAAa,CAAC;AAGxD,cAAc;AACd,eAAO,MAAM,IAAI;;;;;;kBAWf,CAAC;AACH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;AAExC,MAAM,MAAM,cAAc,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;AAEjD,cAAc;AACd,eAAO,MAAM,IAAI,EAAE,IAAI,CAAC,IAAI,CA2B3B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"filer.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/filer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,2BAA2B,CAAC;AAI1D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,kCAAkC,CAAC;AAClE,OAAO,KAAK,EAAC,UAAU,EAAE,MAAM,EAAC,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EACN,SAAS,EAET,KAAK,aAAa,EAClB,KAAK,eAAe,EAEpB,MAAM,gBAAgB,CAAC;AAOxB,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAC;AAK5C,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;AAEhF,MAAM,WAAW,YAAY;IAC5B,SAAS,CAAC,EAAE,OAAO,SAAS,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC,CAAC;IACtE,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,qBAAa,KAAK;;IACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAG1B,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAa;gBAetC,OAAO,GAAE,YAA2B;IAUhD,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,SAAS,GAAI,IAAI,MAAM,KAAG,QAAQ,GAAG,SAAS,CAE5C;IAEF,aAAa,GAAI,IAAI,MAAM,KAAG,QAAQ,CAqBpC;IAEF,MAAM,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI;IAU1E;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAsDrB,KAAK,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC;IAmBzD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CA8OtB;AAGD,eAAO,MAAM,iBAAiB,GAC7B,UAAU,QAAQ,EAClB,WAAW,CAAC,EAAE,EAAE,MAAM,KAAK,QAAQ,GAAG,SAAS,EAC/C,SAAS,UAAU,EACnB,UAAS,GAAG,CAAC,MAAM,CAAa,EAChC,WAAU,GAAG,CAAC,MAAM,CAAa,EACjC,MAAM,MAAM,KACV,GAAG,CAAC,MAAM,CAuBZ,CAAC"}
1
+ {"version":3,"file":"filer.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/filer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,2BAA2B,CAAC;AAI1D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,kCAAkC,CAAC;AAClE,OAAO,KAAK,EAAC,UAAU,EAAE,MAAM,EAAC,MAAM,0BAA0B,CAAC;AAGjE,OAAO,EACN,SAAS,EAET,KAAK,aAAa,EAClB,KAAK,eAAe,EAEpB,MAAM,gBAAgB,CAAC;AAOxB,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAC;AAI5C,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;AAEhF,MAAM,WAAW,YAAY;IAC5B,SAAS,CAAC,EAAE,OAAO,SAAS,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC,CAAC;IACtE,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,qBAAa,KAAK;;IACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAG1B,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAa;gBAetC,OAAO,GAAE,YAA2B;IAUhD,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,SAAS,GAAI,IAAI,MAAM,KAAG,QAAQ,GAAG,SAAS,CAE5C;IAEF,aAAa,GAAI,IAAI,MAAM,KAAG,QAAQ,CAqBpC;IAEF,MAAM,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI;IAU1E;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAsDrB,KAAK,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC;IAmBzD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CA8OtB;AAGD,eAAO,MAAM,iBAAiB,GAC7B,UAAU,QAAQ,EAClB,WAAW,CAAC,EAAE,EAAE,MAAM,KAAK,QAAQ,GAAG,SAAS,EAC/C,SAAS,UAAU,EACnB,UAAS,GAAG,CAAC,MAAM,CAAa,EAChC,WAAU,GAAG,CAAC,MAAM,CAAa,EACjC,MAAM,MAAM,KACV,GAAG,CAAC,MAAM,CAuBZ,CAAC"}
package/dist/filer.js CHANGED
@@ -4,6 +4,7 @@ import { dirname, resolve } from 'node:path';
4
4
  import { isBuiltin } from 'node:module';
5
5
  import { fileURLToPath, pathToFileURL } from 'node:url';
6
6
  import { UnreachableError } from '@fuzdev/fuz_util/error.js';
7
+ import { hash_secure } from '@fuzdev/fuz_util/hash.js';
7
8
  import { watch_dir, } from "./watch_dir.js";
8
9
  import { paths } from "./paths.js";
9
10
  import { parse_imports } from "./parse_imports.js";
@@ -11,7 +12,6 @@ import { resolve_specifier } from "./resolve_specifier.js";
11
12
  import { default_svelte_config } from "./svelte_config.js";
12
13
  import { map_sveltekit_aliases } from "./sveltekit_helpers.js";
13
14
  import { SVELTEKIT_GLOBAL_SPECIFIER } from "./constants.js";
14
- import { to_hash } from "./hash.js";
15
15
  const aliases = Object.entries(default_svelte_config.alias);
16
16
  export class Filer {
17
17
  root_dir;
@@ -201,7 +201,7 @@ export class Filer {
201
201
  }
202
202
  }
203
203
  // Compute hash for new contents
204
- const new_hash = new_contents !== null ? await to_hash(new_contents) : null;
204
+ const new_hash = new_contents !== null ? await hash_secure(new_contents) : null;
205
205
  file.ctime = stats?.ctimeMs ?? null;
206
206
  file.mtime = stats?.mtimeMs ?? null;
207
207
  // Use hash comparison for change detection (content-based, not mtime-based)
@@ -2,6 +2,7 @@ import { z } from 'zod';
2
2
  import { type Task } from './task.ts';
3
3
  /** @nodocs */
4
4
  export declare const Args: z.ZodObject<{
5
+ _: z.ZodOptional<z.ZodArray<z.ZodString>>;
5
6
  check: z.ZodDefault<z.ZodBoolean>;
6
7
  }, z.core.$strict>;
7
8
  export type Args = z.infer<typeof Args>;
@@ -1 +1 @@
1
- {"version":3,"file":"format.task.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/format.task.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAY,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AAI/C,cAAc;AACd,eAAO,MAAM,IAAI;;kBAKf,CAAC;AACH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;AAExC,cAAc;AACd,eAAO,MAAM,IAAI,EAAE,IAAI,CAAC,IAAI,CAqB3B,CAAC"}
1
+ {"version":3,"file":"format.task.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/format.task.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAMtB,OAAO,EAAY,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AAE/C,cAAc;AACd,eAAO,MAAM,IAAI;;;kBAMf,CAAC;AACH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;AAExC,cAAc;AACd,eAAO,MAAM,IAAI,EAAE,IAAI,CAAC,IAAI,CAuB3B,CAAC"}
@@ -1,10 +1,13 @@
1
1
  import { print_spawn_result } from '@fuzdev/fuz_util/process.js';
2
2
  import { z } from 'zod';
3
- import { TaskError } from "./task.js";
3
+ import { to_implicit_forwarded_args } from "./args.js";
4
+ import { PRETTIER_CLI_DEFAULT } from "./constants.js";
4
5
  import { format_directory } from "./format_directory.js";
5
6
  import { paths } from "./paths.js";
7
+ import { TaskError } from "./task.js";
6
8
  /** @nodocs */
7
9
  export const Args = z.strictObject({
10
+ _: z.array(z.string()).meta({ description: 'files or directories to format' }).optional(),
8
11
  check: z
9
12
  .boolean()
10
13
  .meta({ description: 'exit with a nonzero code if any files are unformatted' })
@@ -15,9 +18,8 @@ export const task = {
15
18
  summary: 'format source files',
16
19
  Args,
17
20
  run: async ({ args, log, config }) => {
18
- const { check } = args;
19
- // TODO forward prettier args
20
- const format_result = await format_directory(log, paths.source, check, undefined, undefined, undefined, config.pm_cli);
21
+ const { _: patterns, check } = args;
22
+ const format_result = await format_directory(log, paths.source, check, undefined, undefined, undefined, config.pm_cli, to_implicit_forwarded_args(PRETTIER_CLI_DEFAULT), patterns);
21
23
  if (!format_result.ok) {
22
24
  throw new TaskError(`Failed ${check ? 'formatting check' : 'to format'}. ${print_spawn_result(format_result)}`);
23
25
  }
@@ -1,11 +1,13 @@
1
+ import { type Args } from '@fuzdev/fuz_util/args.js';
1
2
  import type { Logger } from '@fuzdev/fuz_util/log.js';
2
3
  import type { SpawnResult } from '@fuzdev/fuz_util/process.js';
3
4
  import { type Cli } from './cli.ts';
4
5
  /**
5
- * Formats a directory on the filesystem.
6
- * If the source directory is given, it also formats all of the root directory files.
6
+ * Formats files on the filesystem.
7
+ * When `patterns` is provided, formats those specific files/patterns.
8
+ * Otherwise formats `dir` with default extensions, plus root files if `dir` is `paths.source`.
7
9
  * This is separated from `./format_file` to avoid importing all of the `prettier` code
8
10
  * inside modules that import this one. (which has a nontrivial cost)
9
11
  */
10
- export declare const format_directory: (log: Logger, dir: string, check?: boolean, extensions?: string, root_paths?: string, prettier_cli?: string | Cli, pm_cli?: string) => Promise<SpawnResult>;
12
+ export declare const format_directory: (log: Logger, dir: string, check?: boolean, extensions?: string, root_paths?: string, prettier_cli?: string | Cli, pm_cli?: string, additional_args?: Args, patterns?: Array<string>) => Promise<SpawnResult>;
11
13
  //# sourceMappingURL=format_directory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"format_directory.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/format_directory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,6BAA6B,CAAC;AAG7D,OAAO,EAAyB,KAAK,GAAG,EAAC,MAAM,UAAU,CAAC;AAuB1D;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAC5B,KAAK,MAAM,EACX,KAAK,MAAM,EACX,eAAa,EACb,mBAA+B,EAC/B,mBAA+B,EAC/B,eAAc,MAAM,GAAG,GAA0B,EACjD,SAAQ,MAAuB,KAC7B,OAAO,CAAC,WAAW,CAcrB,CAAC"}
1
+ {"version":3,"file":"format_directory.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/format_directory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,IAAI,EAAC,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,6BAA6B,CAAC;AAE7D,OAAO,EAAyB,KAAK,GAAG,EAAC,MAAM,UAAU,CAAC;AAuB1D;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAC5B,KAAK,MAAM,EACX,KAAK,MAAM,EACX,eAAa,EACb,mBAA+B,EAC/B,mBAA+B,EAC/B,eAAc,MAAM,GAAG,GAA0B,EACjD,SAAQ,MAAuB,EAC/B,kBAAkB,IAAI,EACtB,WAAW,KAAK,CAAC,MAAM,CAAC,KACtB,OAAO,CAAC,WAAW,CAoBrB,CAAC"}
@@ -1,5 +1,4 @@
1
1
  import { args_serialize } from '@fuzdev/fuz_util/args.js';
2
- import { to_forwarded_args } from "./args.js";
3
2
  import { spawn_cli, to_cli_name } from "./cli.js";
4
3
  import { GITHUB_DIRNAME, README_FILENAME, SVELTE_CONFIG_FILENAME, VITE_CONFIG_FILENAME, TSCONFIG_FILENAME, GRO_CONFIG_FILENAME, PM_CLI_DEFAULT, PRETTIER_CLI_DEFAULT, } from "./constants.js";
5
4
  import { paths } from "./paths.js";
@@ -13,18 +12,26 @@ const ROOT_PATHS_DEFAULT = `${[
13
12
  GITHUB_DIRNAME,
14
13
  ].join(',')}/**/*`;
15
14
  /**
16
- * Formats a directory on the filesystem.
17
- * If the source directory is given, it also formats all of the root directory files.
15
+ * Formats files on the filesystem.
16
+ * When `patterns` is provided, formats those specific files/patterns.
17
+ * Otherwise formats `dir` with default extensions, plus root files if `dir` is `paths.source`.
18
18
  * This is separated from `./format_file` to avoid importing all of the `prettier` code
19
19
  * inside modules that import this one. (which has a nontrivial cost)
20
20
  */
21
- export const format_directory = async (log, dir, check = false, extensions = EXTENSIONS_DEFAULT, root_paths = ROOT_PATHS_DEFAULT, prettier_cli = PRETTIER_CLI_DEFAULT, pm_cli = PM_CLI_DEFAULT) => {
22
- const forwarded_args = to_forwarded_args(to_cli_name(prettier_cli));
23
- forwarded_args[check ? 'check' : 'write'] = true;
21
+ export const format_directory = async (log, dir, check = false, extensions = EXTENSIONS_DEFAULT, root_paths = ROOT_PATHS_DEFAULT, prettier_cli = PRETTIER_CLI_DEFAULT, pm_cli = PM_CLI_DEFAULT, additional_args, patterns) => {
22
+ const forwarded_args = { ...additional_args };
23
+ if (forwarded_args.check === undefined && forwarded_args.write === undefined) {
24
+ forwarded_args[check ? 'check' : 'write'] = true;
25
+ }
24
26
  const serialized_args = args_serialize(forwarded_args);
25
- serialized_args.push(`${dir}**/*.{${extensions}}`);
26
- if (dir === paths.source) {
27
- serialized_args.push(`${paths.root}{${root_paths}}`);
27
+ if (patterns?.length) {
28
+ serialized_args.push(...patterns);
29
+ }
30
+ else {
31
+ serialized_args.push(`${dir}**/*.{${extensions}}`);
32
+ if (dir === paths.source) {
33
+ serialized_args.push(`${paths.root}{${root_paths}}`);
34
+ }
28
35
  }
29
36
  const spawned = await spawn_cli(prettier_cli, serialized_args, log);
30
37
  if (!spawned)
@@ -1 +1 @@
1
- {"version":3,"file":"gro_config.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/gro_config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,UAAU,EAAE,MAAM,EAAC,MAAM,0BAA0B,CAAC;AAcjE,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAG3D;;;GAGG;AACH,eAAO,MAAM,6BAA6B,qEACyB,CAAC;AAEpE;;;;GAIG;AACH,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC9C;;OAEG;IACH,OAAO,EAAE,mBAAmB,CAAC;IAC7B;;;;OAIG;IACH,gBAAgB,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC3C;;;OAGG;IACH,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9B;;;OAGG;IACH,cAAc,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAClC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;OAKG;IACH,uBAAuB,EAAE,MAAM,CAAC;CAChC;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC5B,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,gBAAgB,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC5C,cAAc,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/B,cAAc,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;;;;OAcG;IACH,kBAAkB,CAAC,EAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CACtE;AAED,MAAM,MAAM,eAAe,GAAG,CAC7B,WAAW,EAAE,SAAS,EACtB,aAAa,CAAC,EAAE,kBAAkB,KAC9B,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAE1C,eAAO,MAAM,uBAAuB,QAAO,SAazC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,QAUnC,CAAC;AAEF,eAAO,MAAM,wBAAwB,QAA+C,CAAC;AAErF;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAU,YAAY,YAAY,KAAG,OAAO,CAAC,SAAS,CA6CjF,CAAC;AAEF,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,eAAe,CAAC;CACjD;AAED,eAAO,MAAM,eAAe,GAAU,YAAgB,KAAG,OAAO,CAAC,SAAS,CAqBzE,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,CACxC,aAAa,EAAE,GAAG,EAClB,WAAW,EAAE,MAAM,KACf,OAAO,CAAC,aAAa,IAAI,eAS7B,CAAC"}
1
+ {"version":3,"file":"gro_config.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/gro_config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,UAAU,EAAE,MAAM,EAAC,MAAM,0BAA0B,CAAC;AAejE,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAE3D;;;GAGG;AACH,eAAO,MAAM,6BAA6B,qEACyB,CAAC;AAEpE;;;;GAIG;AACH,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC9C;;OAEG;IACH,OAAO,EAAE,mBAAmB,CAAC;IAC7B;;;;OAIG;IACH,gBAAgB,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC3C;;;OAGG;IACH,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9B;;;OAGG;IACH,cAAc,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAClC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;OAKG;IACH,uBAAuB,EAAE,MAAM,CAAC;CAChC;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC5B,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,gBAAgB,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC5C,cAAc,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/B,cAAc,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;;;;OAcG;IACH,kBAAkB,CAAC,EAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CACtE;AAED,MAAM,MAAM,eAAe,GAAG,CAC7B,WAAW,EAAE,SAAS,EACtB,aAAa,CAAC,EAAE,kBAAkB,KAC9B,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAE1C,eAAO,MAAM,uBAAuB,QAAO,SAazC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,QAYnC,CAAC;AAEF,eAAO,MAAM,wBAAwB,QAA+C,CAAC;AAErF;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAU,YAAY,YAAY,KAAG,OAAO,CAAC,SAAS,CA6CjF,CAAC;AAEF,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,eAAe,CAAC;CACjD;AAED,eAAO,MAAM,eAAe,GAAU,YAAgB,KAAG,OAAO,CAAC,SAAS,CAqBzE,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,CACxC,aAAa,EAAE,GAAG,EAClB,WAAW,EAAE,MAAM,KACf,OAAO,CAAC,aAAa,IAAI,eAS7B,CAAC"}
@@ -10,10 +10,10 @@ import { join, resolve } from 'node:path';
10
10
  import { fs_exists } from '@fuzdev/fuz_util/fs.js';
11
11
  import { identity } from '@fuzdev/fuz_util/function.js';
12
12
  import { json_stringify_deterministic } from '@fuzdev/fuz_util/json.js';
13
+ import { hash_secure } from '@fuzdev/fuz_util/hash.js';
13
14
  import { GRO_DIST_DIR, IS_THIS_GRO, paths } from "./paths.js";
14
15
  import { GRO_CONFIG_FILENAME, JS_CLI_DEFAULT, NODE_MODULES_DIRNAME, PM_CLI_DEFAULT, SERVER_DIST_PATH, SVELTEKIT_BUILD_DIRNAME, SVELTEKIT_DIST_DIRNAME, } from "./constants.js";
15
16
  import create_default_config from "./gro.config.default.js";
16
- import { to_hash } from "./hash.js";
17
17
  /**
18
18
  * SHA-256 hash of empty string, used for configs without build_cache_config.
19
19
  * This ensures consistent cache behavior when no custom config is provided.
@@ -44,7 +44,9 @@ export const SEARCH_EXCLUDER_DEFAULT = new RegExp(`(${'(^|/)\\.[^/]+' + // exclu
44
44
  `|(^|/)${NODE_MODULES_DIRNAME}(?!/(@[^/]+/)?gro/${SVELTEKIT_DIST_DIRNAME})` + // exclude `node_modules` unless it's to the Gro directory
45
45
  `|(^|/)${SVELTEKIT_BUILD_DIRNAME}` + // exclude the SvelteKit build directory
46
46
  `|(^|/)(?<!(^|/)gro/)${SVELTEKIT_DIST_DIRNAME}` + // exclude the SvelteKit dist directory unless it's in the Gro directory
47
- `|(^|/)${SERVER_DIST_PATH}` // exclude the Gro server plugin dist directory
47
+ `|(^|/)${SERVER_DIST_PATH}` + // exclude the Gro server plugin dist directory
48
+ '|(^|/)test' + // exclude test directories
49
+ '|(^|/)benchmark' // exclude benchmark directories
48
50
  })($|/)`, 'u');
49
51
  export const EXPORTS_EXCLUDER_DEFAULT = /(\.md|\.(test|ignore)\.|\/(test|ignore)\/)/;
50
52
  /**
@@ -67,7 +69,7 @@ export const cook_gro_config = async (raw_config) => {
67
69
  // Resolve if it's a function
68
70
  const resolved = typeof build_cache_config === 'function' ? await build_cache_config() : build_cache_config;
69
71
  // Hash the JSON representation with deterministic key ordering
70
- build_cache_config_hash = await to_hash(json_stringify_deterministic(resolved));
72
+ build_cache_config_hash = await hash_secure(json_stringify_deterministic(resolved));
71
73
  }
72
74
  // Delete the raw value to ensure it doesn't persist in memory
73
75
  delete raw_config.build_cache_config;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryanatkn/gro",
3
- "version": "0.189.2",
3
+ "version": "0.190.0",
4
4
  "description": "task runner and toolkit extending SvelteKit",
5
5
  "motto": "generate, run, optimize",
6
6
  "glyph": "🌰",
@@ -59,7 +59,7 @@
59
59
  "zod": "^4.1.13"
60
60
  },
61
61
  "peerDependencies": {
62
- "@fuzdev/fuz_util": ">=0.48.0",
62
+ "@fuzdev/fuz_util": ">=0.48.3",
63
63
  "@sveltejs/kit": "^2",
64
64
  "esbuild": "^0.27.0",
65
65
  "svelte": "^5",
@@ -80,10 +80,10 @@
80
80
  "devDependencies": {
81
81
  "@changesets/changelog-git": "^0.2.1",
82
82
  "@changesets/types": "^6.1.0",
83
- "@fuzdev/fuz_code": "^0.40.0",
84
- "@fuzdev/fuz_css": "^0.44.1",
85
- "@fuzdev/fuz_ui": "^0.179.0",
86
- "@fuzdev/fuz_util": "^0.48.0",
83
+ "@fuzdev/fuz_code": "^0.41.0",
84
+ "@fuzdev/fuz_css": "^0.45.0",
85
+ "@fuzdev/fuz_ui": "^0.180.0",
86
+ "@fuzdev/fuz_util": "^0.48.3",
87
87
  "@ryanatkn/eslint-config": "^0.9.0",
88
88
  "@sveltejs/adapter-static": "^3.0.10",
89
89
  "@sveltejs/kit": "^2.50.1",
@@ -94,7 +94,7 @@
94
94
  "esbuild": "^0.27.1",
95
95
  "eslint": "^9.39.1",
96
96
  "eslint-plugin-svelte": "^3.13.1",
97
- "svelte": "^5.48.2",
97
+ "svelte": "^5.48.5",
98
98
  "svelte-check": "^4.3.5",
99
99
  "typescript": "^5.9.3",
100
100
  "typescript-eslint": "^8.48.1",
@@ -1,13 +1,13 @@
1
1
  import {mkdir, readdir, readFile, rm, stat, writeFile} from 'node:fs/promises';
2
2
  import {join} from 'node:path';
3
- import type {Logger} from '@fuzdev/fuz_util/log.js';
4
3
  import {styleText as st} from 'node:util';
4
+ import {z} from 'zod';
5
+ import type {Logger} from '@fuzdev/fuz_util/log.js';
5
6
  import {git_current_commit_hash} from '@fuzdev/fuz_util/git.js';
6
7
  import {fs_exists} from '@fuzdev/fuz_util/fs.js';
7
8
  import {map_concurrent} from '@fuzdev/fuz_util/async.js';
8
- import {z} from 'zod';
9
+ import {hash_secure} from '@fuzdev/fuz_util/hash.js';
9
10
 
10
- import {to_hash} from './hash.ts';
11
11
  import type {GroConfig} from './gro_config.ts';
12
12
  import {paths} from './paths.ts';
13
13
  import {SVELTEKIT_BUILD_DIRNAME, SVELTEKIT_DIST_DIRNAME, GRO_DIST_PREFIX} from './constants.ts';
@@ -174,7 +174,7 @@ export const validate_build_cache = async (metadata: BuildCacheMetadata): Promis
174
174
  async (output) => {
175
175
  try {
176
176
  const contents = await readFile(output.path);
177
- const actual_hash = await to_hash(contents);
177
+ const actual_hash = await hash_secure(contents);
178
178
  return actual_hash === output.hash;
179
179
  } catch {
180
180
  // File deleted/inaccessible between checks = cache invalid
@@ -249,7 +249,7 @@ export const collect_build_outputs = async (
249
249
  cache_key: string;
250
250
  }
251
251
 
252
- const files_to_hash: Array<FileEntry> = [];
252
+ const files_hash_secure: Array<FileEntry> = [];
253
253
 
254
254
  // Recursively collect files
255
255
  const collect_files = async (
@@ -273,7 +273,7 @@ export const collect_build_outputs = async (
273
273
  // eslint-disable-next-line no-await-in-loop
274
274
  await collect_files(full_path, relative_path, dir_prefix);
275
275
  } else if (entry.isFile()) {
276
- files_to_hash.push({full_path, cache_key});
276
+ files_hash_secure.push({full_path, cache_key});
277
277
  }
278
278
  // Symlinks are intentionally ignored - we only hash regular files
279
279
  }
@@ -291,11 +291,11 @@ export const collect_build_outputs = async (
291
291
 
292
292
  // Hash files with controlled concurrency and collect stats (could be 10k+ files)
293
293
  return map_concurrent(
294
- files_to_hash,
294
+ files_hash_secure,
295
295
  async ({full_path, cache_key}): Promise<BuildOutputEntry> => {
296
296
  const stats = await stat(full_path);
297
297
  const contents = await readFile(full_path);
298
- const hash = await to_hash(contents);
298
+ const hash = await hash_secure(contents);
299
299
 
300
300
  return {
301
301
  path: cache_key,
@@ -19,7 +19,7 @@ export const Args = z.strictObject({
19
19
  });
20
20
  export type Args = z.infer<typeof Args>;
21
21
 
22
- export type DevTask_Context = PluginContext<Args>;
22
+ export type DevTaskContext = PluginContext<Args>;
23
23
 
24
24
  /** @nodocs */
25
25
  export const task: Task<Args> = {
package/src/lib/filer.ts CHANGED
@@ -8,6 +8,7 @@ import {UnreachableError} from '@fuzdev/fuz_util/error.js';
8
8
  import type {Logger} from '@fuzdev/fuz_util/log.js';
9
9
  import type {PackageJson} from '@fuzdev/fuz_util/package_json.js';
10
10
  import type {FileFilter, PathId} from '@fuzdev/fuz_util/path.js';
11
+ import {hash_secure} from '@fuzdev/fuz_util/hash.js';
11
12
 
12
13
  import {
13
14
  watch_dir,
@@ -23,7 +24,6 @@ import {default_svelte_config} from './svelte_config.ts';
23
24
  import {map_sveltekit_aliases} from './sveltekit_helpers.ts';
24
25
  import {SVELTEKIT_GLOBAL_SPECIFIER} from './constants.ts';
25
26
  import type {Disknode} from './disknode.ts';
26
- import {to_hash} from './hash.ts';
27
27
 
28
28
  const aliases = Object.entries(default_svelte_config.alias);
29
29
 
@@ -245,7 +245,7 @@ export class Filer {
245
245
  }
246
246
 
247
247
  // Compute hash for new contents
248
- const new_hash = new_contents !== null ? await to_hash(new_contents) : null;
248
+ const new_hash = new_contents !== null ? await hash_secure(new_contents) : null;
249
249
 
250
250
  file.ctime = stats?.ctimeMs ?? null;
251
251
  file.mtime = stats?.mtimeMs ?? null;
@@ -1,12 +1,15 @@
1
1
  import {print_spawn_result} from '@fuzdev/fuz_util/process.js';
2
2
  import {z} from 'zod';
3
3
 
4
- import {TaskError, type Task} from './task.ts';
4
+ import {to_implicit_forwarded_args} from './args.ts';
5
+ import {PRETTIER_CLI_DEFAULT} from './constants.ts';
5
6
  import {format_directory} from './format_directory.ts';
6
7
  import {paths} from './paths.ts';
8
+ import {TaskError, type Task} from './task.ts';
7
9
 
8
10
  /** @nodocs */
9
11
  export const Args = z.strictObject({
12
+ _: z.array(z.string()).meta({description: 'files or directories to format'}).optional(),
10
13
  check: z
11
14
  .boolean()
12
15
  .meta({description: 'exit with a nonzero code if any files are unformatted'})
@@ -19,8 +22,8 @@ export const task: Task<Args> = {
19
22
  summary: 'format source files',
20
23
  Args,
21
24
  run: async ({args, log, config}) => {
22
- const {check} = args;
23
- // TODO forward prettier args
25
+ const {_: patterns, check} = args;
26
+
24
27
  const format_result = await format_directory(
25
28
  log,
26
29
  paths.source,
@@ -29,6 +32,8 @@ export const task: Task<Args> = {
29
32
  undefined,
30
33
  undefined,
31
34
  config.pm_cli,
35
+ to_implicit_forwarded_args(PRETTIER_CLI_DEFAULT),
36
+ patterns,
32
37
  );
33
38
  if (!format_result.ok) {
34
39
  throw new TaskError(
@@ -1,8 +1,7 @@
1
- import {args_serialize} from '@fuzdev/fuz_util/args.js';
1
+ import {args_serialize, type Args} from '@fuzdev/fuz_util/args.js';
2
2
  import type {Logger} from '@fuzdev/fuz_util/log.js';
3
3
  import type {SpawnResult} from '@fuzdev/fuz_util/process.js';
4
4
 
5
- import {to_forwarded_args} from './args.ts';
6
5
  import {spawn_cli, to_cli_name, type Cli} from './cli.ts';
7
6
  import {
8
7
  GITHUB_DIRNAME,
@@ -27,8 +26,9 @@ const ROOT_PATHS_DEFAULT = `${[
27
26
  ].join(',')}/**/*`;
28
27
 
29
28
  /**
30
- * Formats a directory on the filesystem.
31
- * If the source directory is given, it also formats all of the root directory files.
29
+ * Formats files on the filesystem.
30
+ * When `patterns` is provided, formats those specific files/patterns.
31
+ * Otherwise formats `dir` with default extensions, plus root files if `dir` is `paths.source`.
32
32
  * This is separated from `./format_file` to avoid importing all of the `prettier` code
33
33
  * inside modules that import this one. (which has a nontrivial cost)
34
34
  */
@@ -40,13 +40,21 @@ export const format_directory = async (
40
40
  root_paths = ROOT_PATHS_DEFAULT,
41
41
  prettier_cli: string | Cli = PRETTIER_CLI_DEFAULT,
42
42
  pm_cli: string = PM_CLI_DEFAULT,
43
+ additional_args?: Args,
44
+ patterns?: Array<string>,
43
45
  ): Promise<SpawnResult> => {
44
- const forwarded_args = to_forwarded_args(to_cli_name(prettier_cli));
45
- forwarded_args[check ? 'check' : 'write'] = true;
46
+ const forwarded_args = {...additional_args};
47
+ if (forwarded_args.check === undefined && forwarded_args.write === undefined) {
48
+ forwarded_args[check ? 'check' : 'write'] = true;
49
+ }
46
50
  const serialized_args = args_serialize(forwarded_args);
47
- serialized_args.push(`${dir}**/*.{${extensions}}`);
48
- if (dir === paths.source) {
49
- serialized_args.push(`${paths.root}{${root_paths}}`);
51
+ if (patterns?.length) {
52
+ serialized_args.push(...patterns);
53
+ } else {
54
+ serialized_args.push(`${dir}**/*.{${extensions}}`);
55
+ if (dir === paths.source) {
56
+ serialized_args.push(`${paths.root}{${root_paths}}`);
57
+ }
50
58
  }
51
59
  const spawned = await spawn_cli(prettier_cli, serialized_args, log);
52
60
  if (!spawned)
@@ -3,6 +3,7 @@ import {fs_exists} from '@fuzdev/fuz_util/fs.js';
3
3
  import {identity} from '@fuzdev/fuz_util/function.js';
4
4
  import type {PathFilter, PathId} from '@fuzdev/fuz_util/path.js';
5
5
  import {json_stringify_deterministic} from '@fuzdev/fuz_util/json.js';
6
+ import {hash_secure} from '@fuzdev/fuz_util/hash.js';
6
7
 
7
8
  import {GRO_DIST_DIR, IS_THIS_GRO, paths} from './paths.ts';
8
9
  import {
@@ -18,7 +19,6 @@ import create_default_config from './gro.config.default.ts';
18
19
  import type {PluginsCreateConfig} from './plugin.ts';
19
20
  import type {PackageJsonMapper} from './package_json.ts';
20
21
  import type {ParsedSvelteConfig} from './svelte_config.ts';
21
- import {to_hash} from './hash.ts';
22
22
 
23
23
  /**
24
24
  * SHA-256 hash of empty string, used for configs without build_cache_config.
@@ -137,7 +137,9 @@ export const SEARCH_EXCLUDER_DEFAULT = new RegExp(
137
137
  `|(^|/)${NODE_MODULES_DIRNAME}(?!/(@[^/]+/)?gro/${SVELTEKIT_DIST_DIRNAME})` + // exclude `node_modules` unless it's to the Gro directory
138
138
  `|(^|/)${SVELTEKIT_BUILD_DIRNAME}` + // exclude the SvelteKit build directory
139
139
  `|(^|/)(?<!(^|/)gro/)${SVELTEKIT_DIST_DIRNAME}` + // exclude the SvelteKit dist directory unless it's in the Gro directory
140
- `|(^|/)${SERVER_DIST_PATH}` // exclude the Gro server plugin dist directory
140
+ `|(^|/)${SERVER_DIST_PATH}` + // exclude the Gro server plugin dist directory
141
+ '|(^|/)test' + // exclude test directories
142
+ '|(^|/)benchmark' // exclude benchmark directories
141
143
  })($|/)`,
142
144
  'u',
143
145
  );
@@ -175,7 +177,7 @@ export const cook_gro_config = async (raw_config: RawGroConfig): Promise<GroConf
175
177
  typeof build_cache_config === 'function' ? await build_cache_config() : build_cache_config;
176
178
 
177
179
  // Hash the JSON representation with deterministic key ordering
178
- build_cache_config_hash = await to_hash(json_stringify_deterministic(resolved));
180
+ build_cache_config_hash = await hash_secure(json_stringify_deterministic(resolved));
179
181
  }
180
182
 
181
183
  // Delete the raw value to ensure it doesn't persist in memory
package/dist/hash.d.ts DELETED
@@ -1,11 +0,0 @@
1
- /**
2
- * Computes a cryptographic hash of the given data.
3
- *
4
- * @param data - String or binary data to hash. Strings are UTF-8 encoded internally.
5
- * @param algorithm - Hash algorithm to use. Defaults to SHA-256.
6
- * @returns Hexadecimal hash string.
7
- *
8
- * @see https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
9
- */
10
- export declare const to_hash: (data: BufferSource | string, algorithm?: "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512") => Promise<string>;
11
- //# sourceMappingURL=hash.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hash.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/hash.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,GACnB,MAAM,YAAY,GAAG,MAAM,EAC3B,YAAW,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,SAAqB,KAChE,OAAO,CAAC,MAAM,CAShB,CAAC"}
package/dist/hash.js DELETED
@@ -1,21 +0,0 @@
1
- const { subtle } = globalThis.crypto;
2
- const encoder = new TextEncoder();
3
- /**
4
- * Computes a cryptographic hash of the given data.
5
- *
6
- * @param data - String or binary data to hash. Strings are UTF-8 encoded internally.
7
- * @param algorithm - Hash algorithm to use. Defaults to SHA-256.
8
- * @returns Hexadecimal hash string.
9
- *
10
- * @see https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
11
- */
12
- export const to_hash = async (data, algorithm = 'SHA-256') => {
13
- const buffer = typeof data === 'string' ? encoder.encode(data) : data;
14
- const digested = await subtle.digest(algorithm, buffer);
15
- const bytes = Array.from(new Uint8Array(digested));
16
- let hex = '';
17
- for (const h of bytes) {
18
- hex += h.toString(16).padStart(2, '0');
19
- }
20
- return hex;
21
- };
package/src/lib/hash.ts DELETED
@@ -1,26 +0,0 @@
1
- const {subtle} = globalThis.crypto;
2
-
3
- const encoder = new TextEncoder();
4
-
5
- /**
6
- * Computes a cryptographic hash of the given data.
7
- *
8
- * @param data - String or binary data to hash. Strings are UTF-8 encoded internally.
9
- * @param algorithm - Hash algorithm to use. Defaults to SHA-256.
10
- * @returns Hexadecimal hash string.
11
- *
12
- * @see https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
13
- */
14
- export const to_hash = async (
15
- data: BufferSource | string,
16
- algorithm: 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512' = 'SHA-256',
17
- ): Promise<string> => {
18
- const buffer = typeof data === 'string' ? encoder.encode(data) : data;
19
- const digested = await subtle.digest(algorithm, buffer);
20
- const bytes = Array.from(new Uint8Array(digested));
21
- let hex = '';
22
- for (const h of bytes) {
23
- hex += h.toString(16).padStart(2, '0');
24
- }
25
- return hex;
26
- };