Skip to content

Commit

Permalink
Prefer using a local version of Prettier when writing typegen files
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist committed Apr 20, 2023
1 parent d1e290d commit e796065
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 47 deletions.
5 changes: 5 additions & 0 deletions .changeset/smooth-ducks-relax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@xstate/cli': minor
---

A local version of Prettier (if available) should now be used when writing typegen files.
5 changes: 5 additions & 0 deletions .changeset/tough-foxes-deliver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@xstate/tools-shared': major
---

Removed some FS-related utils from the package.
1 change: 1 addition & 0 deletions apps/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@xstate/tools-shared": "^2.0.2",
"chokidar": "^3.5.3",
"commander": "^8.0.0",
"prettier": "^2.8.7",
"xstate": "^4.33.4"
},
"author": "Stately Team",
Expand Down
59 changes: 54 additions & 5 deletions apps/cli/src/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,62 @@

import { extractMachinesFromFile } from '@xstate/machine-extractor';
import {
TypegenData,
getTsTypesEdits,
getTypegenData,
getTypegenOutput,
processFileEdits,
writeToTypegenFile,
} from '@xstate/tools-shared';
import { watch } from 'chokidar';
import { Command } from 'commander';
import * as fs from 'fs/promises';
import * as path from 'path';
import { version } from '../package.json';

async function removeFile(filePath: string) {
try {
await fs.unlink(filePath);
} catch (e: any) {
if (e?.code === 'ENOENT') {
return;
}
throw e;
}
}

let prettier: typeof import('prettier') | undefined;

function getPrettierInstance(cwd: string): typeof import('prettier') {
if (prettier) {
return prettier;
}
try {
return require(require.resolve('prettier', { paths: [cwd] }));
} catch (err) {
if (!err || (err as any).code !== 'MODULE_NOT_FOUND') {
throw err;
}
// we load our own prettier instance lazily on purpose to speed up the init time
return (prettier = require('prettier'));
}
}

const writeToTypegenFile = async (
typegenUri: string,
types: TypegenData[],
{ cwd }: { cwd: string },
) => {
const prettierInstance = getPrettierInstance(cwd);
await fs.writeFile(
typegenUri,
// // Prettier v3 returns a promise
await prettierInstance.format(getTypegenOutput(types), {
...(await prettierInstance.resolveConfig(typegenUri)),
parser: 'typescript',
}),
);
};

// TODO: just use the native one when support for node 12 gets dropped
const allSettled: typeof Promise.allSettled = (promises: Promise<any>[]) =>
Promise.all(
Expand All @@ -28,7 +73,7 @@ const program = new Command();

program.version(version);

const writeToFiles = async (uriArray: string[]) => {
const writeToFiles = async (uriArray: string[], { cwd }: { cwd: string }) => {
/**
* TODO - implement pretty readout
*/
Expand All @@ -43,6 +88,9 @@ const writeToFiles = async (uriArray: string[]) => {
return;
}

const typegenUri =
uri.slice(0, -path.extname(uri).length) + '.typegen.ts';

const types = extracted.machines
.filter(
(
Expand All @@ -54,7 +102,7 @@ const writeToFiles = async (uriArray: string[]) => {
getTypegenData(path.basename(uri), index, machineResult),
);

await writeToTypegenFile(uri, types);
await writeToTypegenFile(typegenUri, types, { cwd });

const edits = getTsTypesEdits(types);
if (edits.length > 0) {
Expand All @@ -80,13 +128,14 @@ program
.argument('<files>', 'The files to target, expressed as a glob pattern')
.option('-w, --watch', 'Run the typegen in watch mode')
.action(async (filesPattern: string, opts: { watch?: boolean }) => {
const cwd = process.cwd();
if (opts.watch) {
// TODO: implement per path queuing to avoid tasks related to the same file from overlapping their execution
const processFile = (path: string) => {
if (path.endsWith('.typegen.ts')) {
return;
}
writeToFiles([path]).catch(() => {});
writeToFiles([path], { cwd }).catch(() => {});
};
// TODO: handle removals
watch(filesPattern, { awaitWriteFinish: true })
Expand All @@ -100,7 +149,7 @@ program
if (path.endsWith('.typegen.ts')) {
return;
}
tasks.push(writeToFiles([path]));
tasks.push(writeToFiles([path], { cwd }));
})
.on('ready', async () => {
const settled = await allSettled(tasks);
Expand Down
1 change: 0 additions & 1 deletion packages/shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
"test": "jest"
},
"peerDependencies": {
"prettier": "^2.3.1",
"xstate": "^4"
},
"devDependencies": {
Expand Down
2 changes: 0 additions & 2 deletions packages/shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,5 @@ export * from './getTypegenOutput';
export * from './introspectMachine';
export * from './isCursorInPosition';
export * from './processFileEdits';
export * from './removeFile';
export * from './resolveUriToFilePrefix';
export * from './types';
export * from './writeToTypegenFile';
12 changes: 0 additions & 12 deletions packages/shared/src/removeFile.ts

This file was deleted.

27 changes: 0 additions & 27 deletions packages/shared/src/writeToTypegenFile.ts

This file was deleted.

0 comments on commit e796065

Please sign in to comment.