Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ const ignoreFormat = createFormat({
const unique = (array) => Array.from(new Set() < T[number] > array).sort()
await fs.writeFile(resolvedPath, unique(expected).join('\n'), 'utf8')
},
// Optional: define a 'clone' function to control how the result of 'read' is cloned before being passed to 'update'
// Defaults to `structuredClone`[1] if available, otherwise `v8.deserialize(v8.serialize(obj))`.
clone(actual) {
return myCustomClone(actual)
},
})

export default async (_workspaceDir) => {
Expand Down
22 changes: 13 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ type UpdateError =

export async function performUpdates<
FileNameWithOptions extends string,
UserDefinedFormatPlugins extends BaseFormatPlugins
UserDefinedFormatPlugins extends BaseFormatPlugins,
>(
workspaceDir: string,
updateParam:
| UpdateOptionsLegacy<FileNameWithOptions>
| UpdateOptions<FileNameWithOptions>
| UpdateOptionsWithFormats<FileNameWithOptions, UserDefinedFormatPlugins>,
opts?: { test?: boolean }
opts?: { test?: boolean },
): Promise<null | UpdateError[]> {
const update = 'files' in updateParam ? updateParam : { files: updateParam }
let pkgs = await findWorkspacePackagesNoCheck(workspaceDir)
Expand All @@ -88,7 +88,11 @@ export async function performUpdates<
_writeProjectManifest: writeProjectManifest,
}
const actual = (await fileExists(resolvedPath)) ? await formatPlugin.read(formatHandlerOptions) : null
const expected = await formatPlugin.update(clone(actual), updateFile as any, formatHandlerOptions)
const expected = await formatPlugin.update(
formatPlugin.clone ? formatPlugin.clone(actual, formatHandlerOptions) : clone(actual),
Comment thread
b0o marked this conversation as resolved.
Outdated
updateFile as any,
formatHandlerOptions,
)
const equal =
(actual == null && expected == null) ||
(actual != null && expected != null && (await formatPlugin.equal(expected, actual, formatHandlerOptions)))
Expand All @@ -107,8 +111,8 @@ export async function performUpdates<

errors.push({ actual, expected, path: resolvedPath })
} catch (error) {
const errorMessage = `Error while processing ${resolvedPath}: ${error.message}`;
errors.push({ exception: errorMessage });
const errorMessage = `Error while processing ${resolvedPath}: ${error.message}`
errors.push({ exception: errorMessage })
}
}
}
Expand All @@ -120,7 +124,7 @@ function printJsonDiff(actual: unknown, expected: unknown, out: NodeJS.WriteStre
printDiff(
typeof actual !== 'string' ? JSON.stringify(actual, null, 2) : actual,
typeof expected !== 'string' ? JSON.stringify(expected, null, 2) : expected,
out
out,
)
}

Expand All @@ -141,7 +145,7 @@ function parseFileKey(fileKey: string, formatPlugins: Record<string, FormatPlugi

if (!formatPlugin) {
throw new Error(
`Configuration error: there is no format plugin for fileKey "${fileKey}" with explicit format specifier "${extension}"`
`Configuration error: there is no format plugin for fileKey "${fileKey}" with explicit format specifier "${extension}"`,
)
}

Expand All @@ -156,8 +160,8 @@ function parseFileKey(fileKey: string, formatPlugins: Record<string, FormatPlugi
if (!extension) {
throw new Error(
`Configuration error: there is no format plugin for fileKey "${fileKey}", supported extensions are ${Object.keys(
formatPlugins
)}`
formatPlugins,
)}`,
)
}

Expand Down
9 changes: 8 additions & 1 deletion src/updater/formatPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,21 @@ export interface FormatPlugin<Content> {
update(
actual: Content | null,
updater: Updater<Content>,
options: FormatPluginFnOptions
options: FormatPluginFnOptions,
): PromiseOrValue<Content | null>

/** Called only if check for equality is required (`actual != null` & `expected != null`) */
equal(expected: Content, actual: Content, options: FormatPluginFnOptions): PromiseOrValue<boolean>

/** Called only if write is required (`--test` isn't specified, `expected != null` and `expected` is not equal to `actual`) */
write(expected: Content, options: FormatPluginFnOptions): PromiseOrValue<void>

/**
* Used to clone the object returned by `read` before passing it to `update`.
* Defaults to `structuredClone`[1] if available, otherwise `v8.deserialize(v8.serialize(obj))`.
* [1]: https://developer.mozilla.org/en-US/docs/web/api/structuredclone
*/
clone?(value: Content, options: FormatPluginFnOptions): Content
}

export interface FormatPluginFnOptions {
Expand Down