Skip to content
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
13 changes: 13 additions & 0 deletions .changeset/strict-typescript-operations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
'@graphql-codegen/typescript-operations': patch
'@graphql-codegen/visitor-plugin-common': patch
'@graphql-codegen/plugin-helpers': patch
---

Fix type errors in `typescript-operations` under `strict: true` by widening the shared types it calls into:

- `@graphql-codegen/plugin-helpers`: `Types.ComplexPluginOutput`'s `prepend` and `append` now accept `null` items. Core already skipped them.
- `@graphql-codegen/visitor-plugin-common`: `DeclarationBlock.withComment` accepts `undefined`, `parseEnumValues`'s `mapOrStr` is optional (it already defaulted to `{}`), `ImportSource.namespace` accepts `null`, and `optimizeOperations`'s `includeFragments` is optional.
- `@graphql-codegen/typescript-operations`: skips document files without a `document`, and no longer throws when called without the plugin info argument.

Generated output is unchanged.
3 changes: 3 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ updates:
- '/packages/plugins/*/*'
- '/packages/presets/*'
- '/packages/utils/*'
# Keep ranges like `^1.7.3` when the new version already satisfies them: only the lockfile moves.
# Raising the floor would force a needless release of the published package.
versioning-strategy: increase-if-necessary
schedule:
interval: weekly
day: monday
Expand Down
45 changes: 45 additions & 0 deletions .github/workflows/dependabot-lockfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: dependabot-lockfile
on:
pull_request:
branches:
- master
paths:
- '**/package.json'

permissions: {}

jobs:
# Dependabot jobs that run from a workspace member directory (e.g. /dev-test/*, /examples/*)
# update that package.json but not the root pnpm-lock.yaml. Regenerate it and push it back.
update-lockfile:
name: Update pnpm-lock.yaml
if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' }}
runs-on: ubuntu-latest
permissions:
contents: write # allows pushing the lockfile to the Dependabot branch
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.head_ref }} # the Dependabot branch, not the PR merge commit
- name: Install pnpm and Node
uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0
with:
install: false # a frozen install would fail on the stale lockfile
- name: Update lockfile
run: pnpm install --lockfile-only --no-frozen-lockfile --ignore-scripts
- name: Commit and push
env:
HEAD_REF: ${{ github.head_ref }}
run: |
if git diff --quiet -- pnpm-lock.yaml; then
echo "pnpm-lock.yaml is up to date"
exit 0
fi
git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
git add pnpm-lock.yaml
git commit -m 'chore(deps): update pnpm-lock.yaml'
# Other workflows (e.g. changesets-dependencies) may push to the same branch
git pull --rebase origin "$HEAD_REF"
git push origin "HEAD:$HEAD_REF"
32 changes: 16 additions & 16 deletions packages/plugins/other/fragment-matcher/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { extname } from 'path';
import { execute, GraphQLSchema, parse } from 'graphql';
import { execute, GraphQLSchema, parse, type ExecutionResult } from 'graphql';
import {
PluginFunction,
PluginValidateFn,
Expand Down Expand Up @@ -131,7 +131,7 @@ export const plugin: PluginFunction = async (
schema: GraphQLSchema,
_documents,
pluginConfig: FragmentMatcherConfig,
info,
info = {},
): Promise<string> => {
const config: Required<FragmentMatcherConfig> = {
module: 'es2015',
Expand Down Expand Up @@ -161,8 +161,8 @@ export const plugin: PluginFunction = async (
}
}
`),
})) as any;
const ext = extname(info.outputFile).toLowerCase();
})) as unknown as ExecutionResult<IntrospectionResultData>;
const ext = extname(info.outputFile || '').toLowerCase();

if (!introspection.data) {
throw new Error(`Plugin "fragment-matcher" couldn't introspect the schema`);
Expand All @@ -179,15 +179,6 @@ export const plugin: PluginFunction = async (
.filter(type => type.kind === 'UNION' || type.kind === 'INTERFACE')
.sort((a, b) => sortStringsLexicographically(a.name, b.name));

const createPossibleTypesCollection = (acc, type) => {
return {
...acc,
[type.name]: type.possibleTypes
.map(possibleType => possibleType.name)
.sort(sortStringsLexicographically),
};
};

const filteredData: IntrospectionResultData | PossibleTypesResultData =
apolloClientVersion === 2
? {
Expand All @@ -197,7 +188,16 @@ export const plugin: PluginFunction = async (
},
}
: {
possibleTypes: unionAndInterfaceTypes.reduce(createPossibleTypesCollection, {}),
possibleTypes: unionAndInterfaceTypes.reduce((acc, type) => {
return {
...acc,
// Unions and interfaces always have possibleTypes
// This `|| []` is only to satisfy type safety
[type.name]: (type.possibleTypes || [])
.map(possibleType => possibleType.name)
.sort(sortStringsLexicographically),
};
}, {}),
};

const content = JSON.stringify(filteredData, null, 2);
Expand All @@ -216,14 +216,14 @@ export const plugin: PluginFunction = async (
}

if (extensions.ts.includes(ext)) {
let typename: string;
let typename: string | undefined;
if (apolloClientVersion === 2) {
typename = `IntrospectionResultData`;
} else if (apolloClientVersion === 3) {
typename = `PossibleTypesResultData`;
}

let type: string;
let type: string | undefined;
if (useExplicitTyping) {
type = `export type ${typename} = ${content};`;
} else if (apolloClientVersion === 2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function parseEnumValues({
naming,
}: {
schema: GraphQLSchema;
mapOrStr: EnumValuesMap;
mapOrStr?: EnumValuesMap;
ignoreEnumValuesFromSchema?: boolean;
naming: {
convert: ConvertFn;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export type ImportSource<T = string> = {
/**
* Namespace to import source as
*/
namespace?: string;
namespace?: string | null;
/**
* Entity names to import
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { optimizeDocuments } from '@graphql-tools/relay-operation-optimizer';
export function optimizeOperations(
schema: GraphQLSchema,
documents: Types.DocumentFile[],
options?: { includeFragments: boolean },
options?: { includeFragments?: boolean },
): Types.DocumentFile[] {
const newDocuments = optimizeDocuments(
schema,
Expand Down
9 changes: 6 additions & 3 deletions packages/plugins/other/visitor-plugin-common/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export class DeclarationBlock {
_content = null;
_block = null;
_nameGenerics = null;
_comment = null;
_comment: string | null = null;
_ignoreBlockWrapper = false;

constructor(private _config: DeclarationBlockConfig) {
Expand Down Expand Up @@ -168,10 +168,13 @@ export class DeclarationBlock {
return this;
}

withComment(comment: string | StringValueNode | null, disabled = false): DeclarationBlock {
withComment(
comment: string | StringValueNode | null | undefined,
disabled = false,
): DeclarationBlock {
const nonEmptyComment = !!(isStringValueNode(comment) ? comment.value : comment);

if (nonEmptyComment && !disabled) {
if (comment && nonEmptyComment && !disabled) {
this._comment = transformComment(comment, 0);
}

Expand Down
8 changes: 6 additions & 2 deletions packages/plugins/typescript/operations/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { TypeScriptDocumentsVisitor } from './visitor.js';
export const plugin: PluginFunction<
TypeScriptDocumentsPluginConfig,
Types.ComplexPluginOutput
> = async (inputSchema, rawDocuments, config, { outputFile }) => {
> = async (inputSchema, rawDocuments, config, { outputFile = '' } = {}) => {
const schema = config.nullability?.errorHandlingClient
? await semanticToStrict(inputSchema)
: inputSchema;
Expand All @@ -41,6 +41,10 @@ export const plugin: PluginFunction<
};
}>(
(prev, document) => {
if (!document.document) {
return prev;
}

prev.all.documentFiles.push(document);
prev.all.documentNodes.push(document.document);

Expand Down Expand Up @@ -83,7 +87,7 @@ export const plugin: PluginFunction<
const operationsDefinitions: string[] = operationsResult.definitions as string[];
if (config.addOperationExport) {
for (const d of allDocumentsAST.definitions) {
if ('name' in d) {
if ('name' in d && d.name) {
operationsDefinitions.push(
`export declare const ${d.name.value}: import("graphql").DocumentNode;`,
);
Expand Down
4 changes: 2 additions & 2 deletions packages/utils/plugins-helpers/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -618,8 +618,8 @@ export namespace Types {

export type ComplexPluginOutput<M = Record<string, unknown>> = {
content: string;
prepend?: string[];
append?: string[];
prepend?: Array<string | null>;
append?: Array<string | null>;
meta?: M;
};
export type PluginOutput = string | ComplexPluginOutput;
Expand Down
Loading