mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-11-15 09:11:33 +00:00
fix(group): only inline interpolated templates under a gql tag
Cooked reconstruction is not the runtime value for String.raw or unknown tags, so those interpolations stay fail-closed. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
ffe85ed1da
commit
826cae2cf3
2 changed files with 38 additions and 1 deletions
|
|
@ -141,6 +141,14 @@ function substitutionIdentifier(substitution: Parser.SyntaxNode): string | null
|
|||
return expr.type === 'identifier' ? expr.text : null;
|
||||
}
|
||||
|
||||
function isGraphqlTagCall(call: Parser.SyntaxNode): boolean {
|
||||
const callee = call.childForFieldName('function');
|
||||
if (!callee) return false;
|
||||
if (callee.type === 'identifier') return callee.text === 'gql';
|
||||
if (callee.type !== 'member_expression') return false;
|
||||
return callee.childForFieldName('property')?.text === 'gql';
|
||||
}
|
||||
|
||||
function uniqueStaticSource(
|
||||
name: string,
|
||||
declarators: GeneratedSymbolIndex,
|
||||
|
|
@ -340,7 +348,14 @@ function staticGraphqlSource(
|
|||
|
||||
if (value.type === 'call_expression') {
|
||||
const template = value.namedChildren.find((child) => child.type === 'template_string');
|
||||
return template ? staticGraphqlSource(template, declarators, resolving) : null;
|
||||
if (!template) return null;
|
||||
const hasSubstitution = template.namedChildren.some(
|
||||
(child) => child.type === 'template_substitution',
|
||||
);
|
||||
// Interpolated reconstruction is the cooked template. Only `gql` is
|
||||
// treated as preserving that source; String.raw / unknown tags stay fail-closed.
|
||||
if (hasSubstitution && !isGraphqlTagCall(value)) return null;
|
||||
return staticGraphqlSource(template, declarators, resolving);
|
||||
}
|
||||
|
||||
if (value.type !== 'new_expression') return null;
|
||||
|
|
|
|||
|
|
@ -733,4 +733,26 @@ export const QDocument = gql\`query Q { q }\\n\${QFragmentDoc}\`;
|
|||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it('fails closed for interpolated templates under a non-gql tag (#3201)', async () => {
|
||||
const { root, repo } = await makeRepo({
|
||||
'src/q.graphql': `query Q { q }`,
|
||||
'src/generated.ts': `
|
||||
export const QFragmentDoc = /*#__PURE__*/ \`
|
||||
fragment extra on Query { q }
|
||||
\`;
|
||||
export const QDocument = String.raw\`query Q { q }\\n\${QFragmentDoc}\`;
|
||||
`,
|
||||
});
|
||||
|
||||
const contracts = await new GraphqlExtractor().extract(
|
||||
executor({
|
||||
QDocument: [{ uid: 'const:q', name: 'QDocument', filePath: 'src/generated.ts' }],
|
||||
}),
|
||||
root,
|
||||
repo,
|
||||
);
|
||||
|
||||
expect(contracts).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue