Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(cli-utils): Add missing deduplication and normalization to generate persisted output #275

Merged
merged 5 commits into from
Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from all 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 .changeset/slimy-boxes-try.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@gql.tada/cli-utils": patch
---

Add missing fragment deduplication to `generate persisted` command's output and add document normalization, which can be disabled using the `--disable-normalization` argument.
2 changes: 1 addition & 1 deletion packages/cli-utils/src/commands/generate-output/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface OutputOptions {
forceTSFormat?: boolean;
/** Whether to disable the optimized output format for `.d.ts` files.
* @defaultValue `false` */
disablePreprocessing: boolean;
disablePreprocessing?: boolean;
/** The filename to write the cache file to.
* @defaultValue The `tadaTurboLocation` configuration option */
output: string | undefined;
Expand Down
5 changes: 5 additions & 0 deletions packages/cli-utils/src/commands/generate-persisted/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ export class GeneratePersisted extends Command {
description: 'Specify the `tsconfig.json` used to read, unless `--output` is passed.',
});

disableNormalization = Option.Boolean('--disable-normalization', false, {
description: 'Disables normalizing of GraphQL documents (parsing then printing documents)',
});

failOnWarn = Option.Boolean('--fail-on-warn', false, {
description: 'Triggers an error and a non-zero exit code if any warnings have been reported',
});
Expand All @@ -25,6 +29,7 @@ export class GeneratePersisted extends Command {
const tty = initTTY();
const result = await tty.start(
run(tty, {
disableNormalization: this.disableNormalization,
failOnWarn: this.failOnWarn,
output: this.output,
tsconfig: this.tsconfig,
Expand Down
8 changes: 8 additions & 0 deletions packages/cli-utils/src/commands/generate-persisted/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ import type { PersistedDocument } from './types';
import * as logger from './logger';

export interface PersistedOptions {
/** Whether to disable normalization of GraphQL documents in the output.
* @defaultValue `false`
* @remarks
* Normalizing a GraphQL document means to parse then print them, which
* removes comments and normalizes formatting.
*/
disableNormalization?: boolean;
/** The `tsconfig.json` to use for configurations and the TypeScript program.
* @defaultValue A `tsconfig.json` in the current or any parent directory. */
tsconfig: string | undefined;
Expand All @@ -35,6 +42,7 @@ export async function* run(tty: TTY, opts: PersistedOptions): AsyncIterable<Comp
if (tty.isInteractive) yield logger.runningPersisted();

const generator = runPersisted({
disableNormalization: !!opts.disableNormalization,
rootPath: configResult.rootPath,
configPath: configResult.configPath,
pluginConfig,
Expand Down
37 changes: 32 additions & 5 deletions packages/cli-utils/src/commands/generate-persisted/thread.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ts from 'typescript';
import { print } from '@0no-co/graphql.web';
import { parse, print } from '@0no-co/graphql.web';

import type { FragmentDefinitionNode } from '@0no-co/graphql.web';
import type { GraphQLSPConfig } from '@gql.tada/internal';
Expand All @@ -18,6 +18,7 @@ import { expose } from '../../threads';
import type { PersistedSignal, PersistedWarning, PersistedDocument } from './types';

export interface PersistedParams {
disableNormalization: boolean;
rootPath: string;
configPath: string;
pluginConfig: GraphQLSPConfig;
Expand Down Expand Up @@ -139,18 +140,44 @@ async function* _runPersisted(params: PersistedParams): AsyncIterableIterator<Pe
continue;
}

const fragments: FragmentDefinitionNode[] = [];
const fragmentDefs: FragmentDefinitionNode[] = [];
const operation = foundNode.arguments[0].getText().slice(1, -1);
if (foundNode.arguments[1] && ts.isArrayLiteralExpression(foundNode.arguments[1])) {
unrollTadaFragments(
foundNode.arguments[1],
fragments,
fragmentDefs,
container.buildPluginInfo(params.pluginConfig)
);
}

let document = operation;
for (const fragment of fragments) document += '\n\n' + print(fragment);
const seen = new Set<string>();
let document: string;
if (params.disableNormalization) {
document = operation;
} else {
try {
document = print(parse(operation));
} catch (_error) {
warnings.push({
message:
`The referenced document of "${referencingNode.getText()}" could not be parsed.\n` +
'Run `check` to see specific validation errors.',
file: position.fileName,
line: position.line,
col: position.col,
});
continue;
}
}

// NOTE: Update graphqlsp not to pre-parse fragments, which also swallows errors
for (const fragmentDef of fragmentDefs) {
const printedFragmentDef = print(fragmentDef);
if (!seen.has(printedFragmentDef)) {
document += '\n\n' + print(fragmentDef);
seen.add(printedFragmentDef);
}
}

documents.push({
schemaName: call.schema,
Expand Down
2 changes: 2 additions & 0 deletions website/reference/gql-tada-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ When this command is run inside a GitHub Action, [workflow commands](https://doc

| Option | Description |
| ------------------- | ------------------------------------------------------------------------------------------------ |
| `--disable-normalization` | Whether to disable normalizing the GraphQL document. (Default: false) |
| `--tsconfig,-c` | Optionally, a `tsconfig.json` file to use instead of an automatically discovered one. |
| `--fail-on-warn,-w` | Triggers an error and a non-zero exit code if any warnings have been reported. |
| `--output,-o` | Specify where to output the file to. (Default: The `tadaPersistedLocation` configuration option) |
Expand Down Expand Up @@ -172,6 +173,7 @@ await generateOutput({

| | Description |
| ------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `disableNormalization` | Disables normalizing the GraphQL document |
| `output` option | The filename to write the persisted JSON manifest file to (Default: the `tadaPersistedLocation` configuration option) |
| `tsconfig` option | The `tsconfig.json` to use instead of an automatically discovered one. |
| `failOnWarn` option | Whether to throw an error instead of logging warnings. |
Expand Down
Loading