diff --git a/package.json b/package.json index d929268f..34263f62 100644 --- a/package.json +++ b/package.json @@ -132,10 +132,11 @@ "@dprint/formatter": "^0.4.0", "@dprint/typescript": "^0.93.0", "@opentelemetry/api": "^1.9.0", - "graphql": "14 - 16" + "graphql": "14 - 16", + "prettier": "^3.3.3" }, "peerDependenciesMeta": { - "dprint": { + "prettier": { "optional": true }, "@opentelemetry/api": { @@ -168,6 +169,7 @@ "@typescript-eslint/parser": "^8.11.0", "async-cleanup": "^1.0.0", "doctoc": "^2.2.1", + "dprint": "^0.47.4", "dripip": "^0.10.0", "es-toolkit": "^1.26.1", "eslint": "^9.13.0", @@ -188,6 +190,7 @@ "graphql-upload-minimal": "^1.6.1", "graphql-yoga": "^5.7.0", "jsdom": "^25.0.1", + "prettier": "^3.3.3", "publint": "^0.2.12", "strip-ansi": "^7.1.0", "tsx": "^4.19.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c076fe09..2da02426 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -75,6 +75,9 @@ importers: doctoc: specifier: ^2.2.1 version: 2.2.1 + dprint: + specifier: ^0.47.4 + version: 0.47.4 dripip: specifier: ^0.10.0 version: 0.10.0 @@ -135,6 +138,9 @@ importers: jsdom: specifier: ^25.0.1 version: 25.0.1 + prettier: + specifier: ^3.3.3 + version: 3.3.3 publint: specifier: ^0.2.12 version: 0.2.12 @@ -321,12 +327,52 @@ packages: search-insights: optional: true + '@dprint/darwin-arm64@0.47.4': + resolution: {integrity: sha512-TZKDhU3YfPwij66sMAnFjyqACwz0jrJoVLV1x00IR7CluWBas2hOBWQd2UhhncF+llnltQ8U0+m7lU7jrBHEew==} + cpu: [arm64] + os: [darwin] + + '@dprint/darwin-x64@0.47.4': + resolution: {integrity: sha512-6C0p8x9lN8Y81OZHQWCFCn7oE7NDFkeARvG1TIgO9EouKWoa9vNUNoxA5DNhDhlFPSejWfxiwLXn0ZKrPEnCHQ==} + cpu: [x64] + os: [darwin] + '@dprint/formatter@0.4.1': resolution: {integrity: sha512-IB/GXdlMOvi0UhQQ9mcY15Fxcrc2JPadmo6tqefCNV0bptFq7YBpggzpqYXldBXDa04CbKJ+rDwO2eNRPE2+/g==} + '@dprint/linux-arm64-glibc@0.47.4': + resolution: {integrity: sha512-eQk6DCHNKtvZMmpaBKnmJABUx5uKR3gWR+2I7XCCGaIS5VCM4RV2bA7x9gCUAUaLzmvm17rragHnSkzX+672oQ==} + cpu: [arm64] + os: [linux] + + '@dprint/linux-arm64-musl@0.47.4': + resolution: {integrity: sha512-bHnohA+pnU1ybIYNcw28Z761OXt9q149Izo30gwi2GgY6JJR+3h9Nl4NAsvIPzd0kwL1Unz1ZFGcVMp+wI82Fg==} + cpu: [arm64] + os: [linux] + + '@dprint/linux-x64-glibc@0.47.4': + resolution: {integrity: sha512-hmOA/edKJErs0yw8hHubzBjGuYasvWNRvv3y7FBl5Ega9nq7hCfUhupTs/4g0lTWabcdU2xFA8xVJnaT95uOQw==} + cpu: [x64] + os: [linux] + + '@dprint/linux-x64-musl@0.47.4': + resolution: {integrity: sha512-1gBQ7uyMw+Ix8uJd1WmdCXRm53VpIjZsQraPZUr+uOtUitZFMFK+dw1bNFpjxGTalahFDHp3XEnTQxLlw2MD1A==} + cpu: [x64] + os: [linux] + '@dprint/typescript@0.93.0': resolution: {integrity: sha512-FxzxkheBbQnp7dHZJzkn4RwkP3keG/mvz0jyAGzEQ3P7Wl+ELSA8O2aZ6UJGmErOtP7lA8PbIbwMSu6VSBLSXw==} + '@dprint/win32-arm64@0.47.4': + resolution: {integrity: sha512-05UJS2ggH65BmdJGDkSaUF61CJyau65oqSlpPydmu+RKK5/sEUj/b6A0QCpR57fLh0Q3e9CqkwzfYf4qUJ55ew==} + cpu: [arm64] + os: [win32] + + '@dprint/win32-x64@0.47.4': + resolution: {integrity: sha512-aQtujd8xtJ84I90pLCTwAl4SvkAhhQPRfDE5BkZYnK+5iMkigA1eQd7UCqAEUKeCJrO5N41OXaEWgmOhBctvJg==} + cpu: [x64] + os: [win32] + '@envelop/core@5.0.2': resolution: {integrity: sha512-tVL6OrMe6UjqLosiE+EH9uxh2TQC0469GwF4tE014ugRaDDKKVWwFwZe0TBMlcyHKh5MD4ZxktWo/1hqUxIuhw==} engines: {node: '>=18.0.0'} @@ -1822,6 +1868,10 @@ packages: domutils@2.8.0: resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + dprint@0.47.4: + resolution: {integrity: sha512-eyjiV7+aW34tTSTwXe0v6aQtl9zM3UrjAMc3VggcvvvwWBlzHXA4651w1odnY58wja3kxiwnP6ok0kzfOZHmrg==} + hasBin: true + dripip@0.10.0: resolution: {integrity: sha512-FaHkW6uXAa57pJwz+SRxTvTDiybSH9w4PGWXkheoIPNs4HcHM688rfsKzvedoaLvQul4UaAoRr+2CHc7V25biA==} hasBin: true @@ -4123,10 +4173,34 @@ snapshots: transitivePeerDependencies: - '@algolia/client-search' + '@dprint/darwin-arm64@0.47.4': + optional: true + + '@dprint/darwin-x64@0.47.4': + optional: true + '@dprint/formatter@0.4.1': {} + '@dprint/linux-arm64-glibc@0.47.4': + optional: true + + '@dprint/linux-arm64-musl@0.47.4': + optional: true + + '@dprint/linux-x64-glibc@0.47.4': + optional: true + + '@dprint/linux-x64-musl@0.47.4': + optional: true + '@dprint/typescript@0.93.0': {} + '@dprint/win32-arm64@0.47.4': + optional: true + + '@dprint/win32-x64@0.47.4': + optional: true + '@envelop/core@5.0.2': dependencies: '@envelop/types': 5.0.0 @@ -5708,6 +5782,17 @@ snapshots: domelementtype: 2.3.0 domhandler: 4.3.1 + dprint@0.47.4: + optionalDependencies: + '@dprint/darwin-arm64': 0.47.4 + '@dprint/darwin-x64': 0.47.4 + '@dprint/linux-arm64-glibc': 0.47.4 + '@dprint/linux-arm64-musl': 0.47.4 + '@dprint/linux-x64-glibc': 0.47.4 + '@dprint/linux-x64-musl': 0.47.4 + '@dprint/win32-arm64': 0.47.4 + '@dprint/win32-x64': 0.47.4 + dripip@0.10.0: dependencies: '@oclif/command': 1.8.36(@oclif/config@1.18.17) diff --git a/src/lib/typescript-formatter.ts b/src/lib/typescript-formatter.ts index 8a9270cf..01d7ae38 100644 --- a/src/lib/typescript-formatter.ts +++ b/src/lib/typescript-formatter.ts @@ -10,21 +10,36 @@ export const passthroughFormatter: Formatter = { formatText: (content) => Promise.resolve(content), } +export const getTypeScriptFormatter = async (): Promise => { + return await getTypeScriptFormatterDprint() ?? await getTypeScriptFormatterPrettier() +} + +export const getTypeScriptFormatterPrettier = async (): Promise => { + try { + const prettier = await import(`prettier`) + return { + formatText: (content) => prettier.format(content, { parser: `typescript` }), + } + } catch (error) { + return null + } +} + /** * Attempt to get a TypeScript formatter using dynamic imports. If none succeed then returns null. * * This allows users to bring their own formatters (within an allow list of what we try to dynamically import). */ -export const getTypeScriptFormatter = async (): Promise => { +export const getTypeScriptFormatterDprint = async (): Promise => { try { const { createFromBuffer } = await import(`@dprint/formatter`) const { getPath } = await import(`@dprint/typescript`) const formatter = createFromBuffer(await fs.readFile(getPath())) + // todo handle failing to read configuration file gracefully. Don't swallow those errors. + // TODO don't read config file manually? https://github.com/dprint/js-formatter/issues/13 + const localConfig = await readJsonFile<{ typescript?: JsonObject }>(`dprint.json`) ?? {} return { formatText: async (fileText, customFormatterConfig) => { - // todo handle failing to read configuration file gracefully. - // TODO don't read config file manually? https://github.com/dprint/js-formatter/issues/13 - const localConfig = await readJsonFile<{ typescript?: JsonObject }>(`dprint.json`) ?? {} const overrideConfig = { ...localConfig.typescript, ...customFormatterConfig, diff --git a/tests/e2e/e2e.test.ts b/tests/e2e/e2e.test.ts index 11416dd4..76bc1f93 100644 --- a/tests/e2e/e2e.test.ts +++ b/tests/e2e/e2e.test.ts @@ -87,3 +87,16 @@ test(`client uses dprint formatter if installed`, async ({ project }) => { await project.run`pnpm dprint check graffle/**/*` }) + +test(`client uses prettier formatter if installed`, async ({ project }) => { + // await project.addDprintConfig() + const path = await project.addPokemonSchemaSDL() + + await project.run`pnpm add --save-dev prettier` + + const genResult = await project.run`pnpm graffle --schema ${path.relative} --format` + const genResultStdout = genResult.stdout as string + expect(genResultStdout.includes(`No TypeScript formatter found`)).toEqual(false) + + await project.run`pnpm prettier --check graffle/**/*` +})