@soda-gql/typegen 0.12.1 → 0.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +70 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +18 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +70 -28
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -74,6 +74,7 @@ let __swc_core = require("@swc/core");
|
|
|
74
74
|
const groupBySchema = (fieldSelections, schemas) => {
|
|
75
75
|
const grouped = new Map();
|
|
76
76
|
const warnings = [];
|
|
77
|
+
let skippedFragmentCount = 0;
|
|
77
78
|
for (const schemaName of Object.keys(schemas)) {
|
|
78
79
|
grouped.set(schemaName, {
|
|
79
80
|
fragments: [],
|
|
@@ -95,7 +96,8 @@ const groupBySchema = (fieldSelections, schemas) => {
|
|
|
95
96
|
};
|
|
96
97
|
if (selection.type === "fragment") {
|
|
97
98
|
if (!selection.key) {
|
|
98
|
-
|
|
99
|
+
skippedFragmentCount++;
|
|
100
|
+
warnings.push(`[prebuilt] Fragment "${canonicalId}" skipped: missing 'key' property. ` + `Use tagged template syntax fragment("Name", "Type")\`{ ... }\` to auto-assign a key, ` + `or set 'key' explicitly in the callback builder.`);
|
|
99
101
|
continue;
|
|
100
102
|
}
|
|
101
103
|
try {
|
|
@@ -136,7 +138,8 @@ const groupBySchema = (fieldSelections, schemas) => {
|
|
|
136
138
|
}
|
|
137
139
|
return (0, neverthrow.ok)({
|
|
138
140
|
grouped,
|
|
139
|
-
warnings
|
|
141
|
+
warnings,
|
|
142
|
+
skippedFragmentCount
|
|
140
143
|
});
|
|
141
144
|
};
|
|
142
145
|
/**
|
|
@@ -343,14 +346,15 @@ const emitPrebuiltTypes = async (options) => {
|
|
|
343
346
|
if (groupResult.isErr()) {
|
|
344
347
|
return (0, neverthrow.err)(groupResult.error);
|
|
345
348
|
}
|
|
346
|
-
const { grouped, warnings } = groupResult.value;
|
|
349
|
+
const { grouped, warnings, skippedFragmentCount } = groupResult.value;
|
|
347
350
|
const code = generateTypesCode(grouped, schemas, injectsModulePath);
|
|
348
351
|
const typesPath = (0, node_path.join)(outdir, "types.prebuilt.ts");
|
|
349
352
|
try {
|
|
350
353
|
await (0, node_fs_promises.writeFile)(typesPath, code, "utf-8");
|
|
351
354
|
return (0, neverthrow.ok)({
|
|
352
355
|
path: typesPath,
|
|
353
|
-
warnings
|
|
356
|
+
warnings,
|
|
357
|
+
skippedFragmentCount
|
|
354
358
|
});
|
|
355
359
|
} catch (error) {
|
|
356
360
|
return (0, neverthrow.err)(__soda_gql_builder.builderErrors.writeFailed(typesPath, `Failed to write prebuilt types: ${error instanceof Error ? error.message : String(error)}`, error));
|
|
@@ -776,15 +780,38 @@ const filterPlaceholderSpreads = (selectionSet) => ({
|
|
|
776
780
|
return sel;
|
|
777
781
|
})
|
|
778
782
|
});
|
|
783
|
+
/** Simple matching-paren finder for template content (no comments/strings to handle). */
|
|
784
|
+
const findClosingParen = (source, openIndex) => {
|
|
785
|
+
let depth = 0;
|
|
786
|
+
for (let i = openIndex; i < source.length; i++) {
|
|
787
|
+
if (source[i] === "(") depth++;
|
|
788
|
+
else if (source[i] === ")") {
|
|
789
|
+
depth--;
|
|
790
|
+
if (depth === 0) return i;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
return -1;
|
|
794
|
+
};
|
|
779
795
|
/**
|
|
780
796
|
* Reconstruct full GraphQL source from an extracted template.
|
|
781
797
|
* For curried syntax (new), prepends the definition header from tag call arguments.
|
|
798
|
+
* For curried fragments with Fragment Arguments, repositions variable declarations
|
|
799
|
+
* before the on-clause to produce RFC-compliant syntax.
|
|
782
800
|
* For old syntax, returns content as-is.
|
|
783
801
|
*/
|
|
784
802
|
const reconstructGraphql = (template) => {
|
|
785
803
|
if (template.elementName) {
|
|
786
804
|
if (template.kind === "fragment" && template.typeName) {
|
|
787
|
-
|
|
805
|
+
const trimmed = template.content.trim();
|
|
806
|
+
if (trimmed.startsWith("(")) {
|
|
807
|
+
const closeIdx = findClosingParen(trimmed, 0);
|
|
808
|
+
if (closeIdx !== -1) {
|
|
809
|
+
const varDecls = trimmed.slice(0, closeIdx + 1);
|
|
810
|
+
const selectionSet = trimmed.slice(closeIdx + 1).trim();
|
|
811
|
+
return `fragment ${template.elementName}${varDecls} on ${template.typeName} ${selectionSet}`;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
return `fragment ${template.elementName} on ${template.typeName} ${trimmed}`;
|
|
788
815
|
}
|
|
789
816
|
return `${template.kind} ${template.elementName} ${template.content}`;
|
|
790
817
|
}
|
|
@@ -958,28 +985,7 @@ const runTypegen = async (options) => {
|
|
|
958
985
|
helper: graphqlHelper
|
|
959
986
|
});
|
|
960
987
|
const templateSelections = convertTemplatesToSelections(scanResult.templates, schemas);
|
|
961
|
-
const
|
|
962
|
-
const filePart = id.split("::")[0] ?? "";
|
|
963
|
-
if (filePart.startsWith("/")) {
|
|
964
|
-
return (0, node_path.relative)(config.baseDir, filePart);
|
|
965
|
-
}
|
|
966
|
-
return filePart;
|
|
967
|
-
};
|
|
968
|
-
const extractElementName = (data) => data.type === "fragment" ? data.key : data.operationName;
|
|
969
|
-
const templateElements = new Set();
|
|
970
|
-
for (const [id, data] of templateSelections.selections) {
|
|
971
|
-
const name = extractElementName(data);
|
|
972
|
-
if (name) templateElements.add(`${extractFilePart(id)}::${name}`);
|
|
973
|
-
}
|
|
974
|
-
const fieldSelections = new Map();
|
|
975
|
-
for (const [id, data] of builderSelections) {
|
|
976
|
-
const name = extractElementName(data);
|
|
977
|
-
if (name && templateElements.has(`${extractFilePart(id)}::${name}`)) continue;
|
|
978
|
-
fieldSelections.set(id, data);
|
|
979
|
-
}
|
|
980
|
-
for (const [id, data] of templateSelections.selections) {
|
|
981
|
-
fieldSelections.set(id, data);
|
|
982
|
-
}
|
|
988
|
+
const fieldSelections = mergeSelections(builderSelections, templateSelections.selections, config.baseDir);
|
|
983
989
|
const scanWarnings = [...scanResult.warnings, ...templateSelections.warnings];
|
|
984
990
|
const emitResult = await emitPrebuiltTypes({
|
|
985
991
|
schemas,
|
|
@@ -990,7 +996,7 @@ const runTypegen = async (options) => {
|
|
|
990
996
|
if (emitResult.isErr()) {
|
|
991
997
|
return (0, neverthrow.err)(emitResult.error);
|
|
992
998
|
}
|
|
993
|
-
const { warnings: emitWarnings } = emitResult.value;
|
|
999
|
+
const { warnings: emitWarnings, skippedFragmentCount } = emitResult.value;
|
|
994
1000
|
let fragmentCount = 0;
|
|
995
1001
|
let operationCount = 0;
|
|
996
1002
|
for (const selection of fieldSelections.values()) {
|
|
@@ -1009,9 +1015,45 @@ const runTypegen = async (options) => {
|
|
|
1009
1015
|
prebuiltTypesPath,
|
|
1010
1016
|
fragmentCount,
|
|
1011
1017
|
operationCount,
|
|
1018
|
+
skippedFragmentCount,
|
|
1012
1019
|
warnings: allWarnings
|
|
1013
1020
|
});
|
|
1014
1021
|
};
|
|
1022
|
+
const extractElementName = (data) => data.type === "fragment" ? data.key : data.operationName;
|
|
1023
|
+
/**
|
|
1024
|
+
* Merge builder and template selections into a combined map.
|
|
1025
|
+
*
|
|
1026
|
+
* Builder selections are authoritative — VM evaluation correctly resolves
|
|
1027
|
+
* fragment spreads that static template analysis cannot handle.
|
|
1028
|
+
* Template selections serve as fallback for elements only found by the scanner.
|
|
1029
|
+
*
|
|
1030
|
+
* Deduplication is per-element (file + GraphQL name), not per-file, so that
|
|
1031
|
+
* callback-builder operations in files that also contain tagged templates are preserved.
|
|
1032
|
+
*/
|
|
1033
|
+
const mergeSelections = (builderSelections, templateSelections, baseDir) => {
|
|
1034
|
+
const extractFilePart = (id) => {
|
|
1035
|
+
const filePart = id.split("::")[0] ?? "";
|
|
1036
|
+
if (filePart.startsWith("/")) {
|
|
1037
|
+
return (0, node_path.relative)(baseDir, filePart);
|
|
1038
|
+
}
|
|
1039
|
+
return filePart;
|
|
1040
|
+
};
|
|
1041
|
+
const builderElements = new Set();
|
|
1042
|
+
for (const [id, data] of builderSelections) {
|
|
1043
|
+
const name = extractElementName(data);
|
|
1044
|
+
if (name) builderElements.add(`${extractFilePart(id)}::${name}`);
|
|
1045
|
+
}
|
|
1046
|
+
const fieldSelections = new Map();
|
|
1047
|
+
for (const [id, data] of builderSelections) {
|
|
1048
|
+
fieldSelections.set(id, data);
|
|
1049
|
+
}
|
|
1050
|
+
for (const [id, data] of templateSelections) {
|
|
1051
|
+
const name = extractElementName(data);
|
|
1052
|
+
if (name && builderElements.has(`${extractFilePart(id)}::${name}`)) continue;
|
|
1053
|
+
fieldSelections.set(id, data);
|
|
1054
|
+
}
|
|
1055
|
+
return fieldSelections;
|
|
1056
|
+
};
|
|
1015
1057
|
|
|
1016
1058
|
//#endregion
|
|
1017
1059
|
exports.emitPrebuiltTypes = emitPrebuiltTypes;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["warnings: string[]","builderErrors","outputFormatters: TypeFormatters","inputFormatters: TypeFormatters","Kind","lines: string[]","formatters: TypeFormatters","lines: string[]","module","declaration: ImportDeclaration | null","templates: ExtractedTemplate[]","kind: string","elementName: string | undefined","typeName: string | undefined","content: string","parts: string[]","warnings: string[]","warnings: string[]","fg","warnings: string[]","Kind","extensionMap: Record<string, string>","withPrefix","currentExt"],"sources":["../src/emitter.ts","../src/errors.ts","../src/template-extractor.ts","../src/template-scanner.ts","../src/template-to-selections.ts","../src/runner.ts"],"sourcesContent":["/**\n * Prebuilt types emitter.\n *\n * Generates TypeScript type definitions for PrebuiltTypes registry\n * from field selection data and schema.\n *\n * ## Error Handling Strategy\n *\n * The emitter uses a partial failure approach for type calculation errors:\n *\n * **Recoverable errors** (result in warnings, element skipped):\n * - Type calculation failures (e.g., `calculateFieldsType` throws)\n * - Input type generation failures (e.g., `generateInputType` throws)\n * - These are caught per-element, logged as warnings, and the element is omitted\n *\n * **Fatal errors** (result in error result):\n * - `SCHEMA_NOT_FOUND`: Selection references non-existent schema\n * - `WRITE_FAILED`: Cannot write output file to disk\n *\n * This allows builds to succeed with partial type coverage when some elements\n * have issues, while providing visibility into problems via warnings.\n *\n * @module\n */\n\nimport { writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { type BuilderError, builderErrors, type FieldSelectionsMap } from \"@soda-gql/builder\";\nimport type { AnyGraphqlSchema, InputTypeSpecifiers, TypeFormatters } from \"@soda-gql/core\";\nimport {\n calculateFieldsType,\n generateInputObjectType,\n generateInputType,\n generateInputTypeFromVarDefs,\n parseInputSpecifier,\n} from \"@soda-gql/core\";\nimport { Kind, type TypeNode, type VariableDefinitionNode } from \"graphql\";\nimport { err, ok, type Result } from \"neverthrow\";\nimport type { TypegenError } from \"./errors\";\n\n/**\n * Options for emitting prebuilt types.\n */\nexport type PrebuiltTypesEmitterOptions = {\n /**\n * Schema definitions per schema name.\n * These come from the codegen output.\n */\n readonly schemas: Record<string, AnyGraphqlSchema>;\n /**\n * Field selections extracted from the builder.\n */\n readonly fieldSelections: FieldSelectionsMap;\n /**\n * Output directory (where types.prebuilt.ts should be written).\n * This should be the same as config.outdir.\n */\n readonly outdir: string;\n /**\n * Relative import path to _internal-injects.ts from types.prebuilt.ts.\n * Example: \"./_internal-injects\"\n */\n readonly injectsModulePath: string;\n};\n\ntype PrebuiltFragmentEntry = {\n readonly key: string;\n readonly typename: string;\n readonly inputType: string;\n readonly outputType: string;\n};\n\ntype PrebuiltOperationEntry = {\n readonly key: string;\n readonly inputType: string;\n readonly outputType: string;\n};\n\ntype SchemaGroup = {\n fragments: PrebuiltFragmentEntry[];\n operations: PrebuiltOperationEntry[];\n inputObjects: Set<string>;\n};\n\ntype GroupBySchemaResult = {\n readonly grouped: Map<string, SchemaGroup>;\n readonly warnings: string[];\n};\n\n/**\n * Group field selections by schema.\n * Uses the schemaLabel from each selection to group them correctly.\n *\n * Fragments without a 'key' property are skipped (not included in PrebuiltTypes)\n * and a warning is added. This allows projects to use fragments without keys\n * while still generating prebuilt types for those that have keys.\n *\n * @returns Result containing grouped selections and warnings, or error if schema not found\n */\nconst groupBySchema = (\n fieldSelections: FieldSelectionsMap,\n schemas: Record<string, AnyGraphqlSchema>,\n): Result<GroupBySchemaResult, BuilderError | TypegenError> => {\n const grouped = new Map<string, SchemaGroup>();\n const warnings: string[] = [];\n\n // Initialize groups for each schema\n for (const schemaName of Object.keys(schemas)) {\n grouped.set(schemaName, { fragments: [], operations: [], inputObjects: new Set() });\n }\n\n for (const [canonicalId, selection] of fieldSelections) {\n // Use schemaLabel to determine which schema this selection belongs to\n const schemaName = selection.schemaLabel;\n const schema = schemas[schemaName];\n const group = grouped.get(schemaName);\n\n if (!schema || !group) {\n return err(builderErrors.schemaNotFound(schemaName, canonicalId));\n }\n\n // Create formatters for schema-specific type names\n const outputFormatters: TypeFormatters = {\n scalarOutput: (name) => `ScalarOutput_${schemaName}<\"${name}\">`,\n };\n const inputFormatters: TypeFormatters = {\n scalarInput: (name) => `ScalarInput_${schemaName}<\"${name}\">`,\n inputObject: (name) => `Input_${schemaName}_${name}`,\n };\n\n if (selection.type === \"fragment\") {\n // Skip fragments without keys (they won't be included in PrebuiltTypes)\n if (!selection.key) {\n warnings.push(`[prebuilt] Fragment \"${canonicalId}\" skipped: missing 'key' property`);\n continue;\n }\n\n try {\n // Collect input objects used in fragment variables\n const usedInputObjects = collectUsedInputObjectsFromVarDefs(schema, selection.variableDefinitions);\n for (const inputName of usedInputObjects) {\n group.inputObjects.add(inputName);\n }\n\n // Generate output type with schema-specific scalar names\n const outputType = calculateFieldsType(schema, selection.fields, outputFormatters, selection.typename);\n\n // Generate input type from variableDefinitions with schema-specific names\n const hasVariables = Object.keys(selection.variableDefinitions).length > 0;\n const inputType = hasVariables\n ? generateInputTypeFromVarDefs(schema, selection.variableDefinitions, { formatters: inputFormatters })\n : \"void\";\n\n group.fragments.push({\n key: selection.key,\n typename: selection.typename,\n inputType,\n outputType,\n });\n } catch (error) {\n warnings.push(\n `[prebuilt] Failed to calculate type for fragment \"${selection.key}\": ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n } else if (selection.type === \"operation\") {\n try {\n // Collect input objects used in this operation\n const usedInputObjects = collectUsedInputObjects(schema, selection.variableDefinitions);\n for (const inputName of usedInputObjects) {\n group.inputObjects.add(inputName);\n }\n\n // Generate output type with schema-specific scalar names\n // Get the root type name from schema operations (Query, Mutation, Subscription)\n const rootTypeName = schema.operations[selection.operationType as keyof typeof schema.operations];\n const outputType = calculateFieldsType(schema, selection.fields, outputFormatters, rootTypeName ?? undefined);\n\n // Generate input type with schema-specific scalar and input object names\n const inputType = generateInputType(schema, selection.variableDefinitions, inputFormatters);\n\n group.operations.push({\n key: selection.operationName,\n inputType,\n outputType,\n });\n } catch (error) {\n warnings.push(\n `[prebuilt] Failed to calculate type for operation \"${selection.operationName}\": ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n }\n\n return ok({ grouped, warnings });\n};\n\n/**\n * Extract input object names from a GraphQL TypeNode.\n */\nconst extractInputObjectsFromType = (schema: AnyGraphqlSchema, typeNode: TypeNode, inputObjects: Set<string>): void => {\n switch (typeNode.kind) {\n case Kind.NON_NULL_TYPE:\n extractInputObjectsFromType(schema, typeNode.type, inputObjects);\n break;\n case Kind.LIST_TYPE:\n extractInputObjectsFromType(schema, typeNode.type, inputObjects);\n break;\n case Kind.NAMED_TYPE: {\n const name = typeNode.name.value;\n // Check if it's an input object (not a scalar or enum)\n if (!schema.scalar[name] && !schema.enum[name] && schema.input[name]) {\n inputObjects.add(name);\n }\n break;\n }\n }\n};\n\n/**\n * Recursively collect nested input objects from schema definitions.\n * Takes a set of initial input names and expands to include all nested inputs.\n */\nconst collectNestedInputObjects = (schema: AnyGraphqlSchema, initialInputNames: Set<string>): Set<string> => {\n const inputObjects = new Set(initialInputNames);\n\n const collectNested = (inputName: string, seen: Set<string>): void => {\n if (seen.has(inputName)) {\n return;\n }\n seen.add(inputName);\n\n const inputDef = schema.input[inputName];\n if (!inputDef) {\n return;\n }\n\n for (const fieldSpec of Object.values(inputDef.fields)) {\n const parsed = parseInputSpecifier(fieldSpec);\n if (parsed.kind === \"input\" && !inputObjects.has(parsed.name)) {\n inputObjects.add(parsed.name);\n collectNested(parsed.name, seen);\n }\n }\n };\n\n for (const inputName of Array.from(initialInputNames)) {\n collectNested(inputName, new Set());\n }\n\n return inputObjects;\n};\n\n/**\n * Collect all input object types used in variable definitions.\n * Recursively collects nested input objects from the schema.\n */\nconst collectUsedInputObjects = (\n schema: AnyGraphqlSchema,\n variableDefinitions: readonly VariableDefinitionNode[],\n): Set<string> => {\n const directInputs = new Set<string>();\n for (const varDef of variableDefinitions) {\n extractInputObjectsFromType(schema, varDef.type, directInputs);\n }\n return collectNestedInputObjects(schema, directInputs);\n};\n\n/**\n * Collect all input object types used in InputTypeSpecifiers.\n * Recursively collects nested input objects from the schema.\n */\nconst _collectUsedInputObjectsFromSpecifiers = (schema: AnyGraphqlSchema, specifiers: InputTypeSpecifiers): Set<string> => {\n const directInputs = new Set<string>();\n for (const specStr of Object.values(specifiers)) {\n const parsed = parseInputSpecifier(specStr);\n if (parsed.kind === \"input\" && schema.input[parsed.name]) {\n directInputs.add(parsed.name);\n }\n }\n return collectNestedInputObjects(schema, directInputs);\n};\n\n/**\n * Collect all input object types used in VariableDefinitions (VarSpecifier objects).\n * Used for fragment variable definitions.\n */\nconst collectUsedInputObjectsFromVarDefs = (\n schema: AnyGraphqlSchema,\n varDefs: Record<string, { kind: string; name: string }>,\n): Set<string> => {\n const directInputs = new Set<string>();\n for (const varSpec of Object.values(varDefs)) {\n if (varSpec.kind === \"input\" && schema.input[varSpec.name]) {\n directInputs.add(varSpec.name);\n }\n }\n return collectNestedInputObjects(schema, directInputs);\n};\n\n/**\n * Generate type definitions for input objects.\n */\nconst generateInputObjectTypeDefinitions = (schema: AnyGraphqlSchema, schemaName: string, inputNames: Set<string>): string[] => {\n const lines: string[] = [];\n\n // Get depth config from schema (optional properties defined in AnyGraphqlSchema)\n const defaultDepth = schema.__defaultInputDepth ?? 3;\n const depthOverrides = schema.__inputDepthOverrides ?? {};\n\n // Create formatters for schema-specific type names\n const formatters: TypeFormatters = {\n scalarInput: (name) => `ScalarInput_${schemaName}<\"${name}\">`,\n inputObject: (name) => `Input_${schemaName}_${name}`,\n };\n\n // Sort for deterministic output\n const sortedNames = Array.from(inputNames).sort();\n\n for (const inputName of sortedNames) {\n const typeString = generateInputObjectType(schema, inputName, {\n defaultDepth,\n depthOverrides,\n formatters,\n });\n\n lines.push(`export type Input_${schemaName}_${inputName} = ${typeString};`);\n }\n\n return lines;\n};\n\n/**\n * Generate the TypeScript code for prebuilt types.\n */\nconst generateTypesCode = (\n grouped: Map<string, SchemaGroup>,\n schemas: Record<string, AnyGraphqlSchema>,\n injectsModulePath: string,\n): string => {\n const schemaNames = Object.keys(schemas);\n\n const lines: string[] = [\n \"/**\",\n \" * Prebuilt type registry.\",\n \" *\",\n \" * This file is auto-generated by @soda-gql/typegen.\",\n \" * Do not edit manually.\",\n \" *\",\n \" * @module\",\n \" * @generated\",\n \" */\",\n \"\",\n 'import type { AssertExtends, PrebuiltTypeRegistry } from \"@soda-gql/core\";',\n ];\n\n // Generate import from _internal-injects.ts\n const scalarImports = schemaNames.map((name) => `scalar_${name}`).join(\", \");\n lines.push(`import type { ${scalarImports} } from \"${injectsModulePath}\";`);\n\n lines.push(\"\");\n\n // Generate ScalarInput and ScalarOutput helper types\n for (const schemaName of schemaNames) {\n lines.push(\n `type ScalarInput_${schemaName}<T extends keyof typeof scalar_${schemaName}> = ` +\n `typeof scalar_${schemaName}[T][\"$type\"][\"input\"];`,\n );\n lines.push(\n `type ScalarOutput_${schemaName}<T extends keyof typeof scalar_${schemaName}> = ` +\n `typeof scalar_${schemaName}[T][\"$type\"][\"output\"];`,\n );\n }\n\n lines.push(\"\");\n\n for (const [schemaName, { fragments, operations, inputObjects }] of grouped) {\n const schema = schemas[schemaName];\n\n // Generate input object type definitions if there are any\n if (inputObjects.size > 0 && schema) {\n lines.push(\"// Input object types\");\n const inputTypeLines = generateInputObjectTypeDefinitions(schema, schemaName, inputObjects);\n lines.push(...inputTypeLines);\n lines.push(\"\");\n }\n\n // Generate fragments type (deduplicate by key — last occurrence wins)\n const deduplicatedFragments = new Map<string, PrebuiltFragmentEntry>();\n for (const f of fragments) {\n deduplicatedFragments.set(f.key, f);\n }\n const fragmentEntries = Array.from(deduplicatedFragments.values())\n .sort((a, b) => a.key.localeCompare(b.key))\n .map(\n (f) =>\n ` readonly \"${f.key}\": { readonly typename: \"${f.typename}\"; readonly input: ${f.inputType}; readonly output: ${f.outputType} };`,\n );\n\n // Generate operations type (deduplicate by key — last occurrence wins)\n const deduplicatedOperations = new Map<string, PrebuiltOperationEntry>();\n for (const o of operations) {\n deduplicatedOperations.set(o.key, o);\n }\n const operationEntries = Array.from(deduplicatedOperations.values())\n .sort((a, b) => a.key.localeCompare(b.key))\n .map((o) => ` readonly \"${o.key}\": { readonly input: ${o.inputType}; readonly output: ${o.outputType} };`);\n\n lines.push(`export type PrebuiltTypes_${schemaName} = {`);\n lines.push(\" readonly fragments: {\");\n if (fragmentEntries.length > 0) {\n lines.push(...fragmentEntries);\n }\n lines.push(\" };\");\n lines.push(\" readonly operations: {\");\n if (operationEntries.length > 0) {\n lines.push(...operationEntries);\n }\n lines.push(\" };\");\n lines.push(\"};\");\n lines.push(`type _AssertPrebuiltTypes_${schemaName} = AssertExtends<PrebuiltTypes_${schemaName}, PrebuiltTypeRegistry>;`);\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n};\n\n/**\n * Result of emitting prebuilt types.\n */\nexport type PrebuiltTypesEmitResult = {\n readonly path: string;\n readonly warnings: readonly string[];\n};\n\n/**\n * Emit prebuilt types to the types.prebuilt.ts file.\n *\n * This function uses a partial failure strategy: if type calculation fails for\n * individual elements (e.g., due to invalid field selections or missing schema\n * types), those elements are skipped and warnings are collected rather than\n * failing the entire emission. This allows builds to succeed even when some\n * elements have issues, while still reporting problems via warnings.\n *\n * @param options - Emitter options including schemas, field selections, and output directory\n * @returns Result containing output path and warnings, or error if a hard failure occurs\n *\n * @example\n * ```typescript\n * const result = await emitPrebuiltTypes({\n * schemas: { mySchema: schema },\n * fieldSelections,\n * outdir: \"./generated\",\n * injects: { mySchema: { scalars: \"./scalars.ts\" } },\n * });\n *\n * if (result.isOk()) {\n * console.log(`Generated: ${result.value.path}`);\n * if (result.value.warnings.length > 0) {\n * console.warn(\"Warnings:\", result.value.warnings);\n * }\n * }\n * ```\n */\nexport const emitPrebuiltTypes = async (\n options: PrebuiltTypesEmitterOptions,\n): Promise<Result<PrebuiltTypesEmitResult, BuilderError | TypegenError>> => {\n const { schemas, fieldSelections, outdir, injectsModulePath } = options;\n\n // Group selections by schema\n const groupResult = groupBySchema(fieldSelections, schemas);\n if (groupResult.isErr()) {\n return err(groupResult.error);\n }\n const { grouped, warnings } = groupResult.value;\n\n // Generate the types code\n const code = generateTypesCode(grouped, schemas, injectsModulePath);\n\n // Write to types.prebuilt.ts\n const typesPath = join(outdir, \"types.prebuilt.ts\");\n\n try {\n await writeFile(typesPath, code, \"utf-8\");\n return ok({ path: typesPath, warnings });\n } catch (error) {\n return err(\n builderErrors.writeFailed(\n typesPath,\n `Failed to write prebuilt types: ${error instanceof Error ? error.message : String(error)}`,\n error,\n ),\n );\n }\n};\n","/**\n * Error types for typegen package.\n *\n * @module\n */\n\nimport type { BuilderError } from \"@soda-gql/builder\";\n\n/**\n * Error codes specific to typegen operations.\n */\nexport type TypegenErrorCode = \"TYPEGEN_CODEGEN_REQUIRED\" | \"TYPEGEN_SCHEMA_LOAD_FAILED\" | \"TYPEGEN_BUILD_FAILED\";\n\n/**\n * Typegen-specific error type.\n */\nexport type TypegenSpecificError =\n | {\n readonly code: \"TYPEGEN_CODEGEN_REQUIRED\";\n readonly message: string;\n readonly outdir: string;\n }\n | {\n readonly code: \"TYPEGEN_SCHEMA_LOAD_FAILED\";\n readonly message: string;\n readonly schemaNames: readonly string[];\n readonly cause?: unknown;\n }\n | {\n readonly code: \"TYPEGEN_BUILD_FAILED\";\n readonly message: string;\n readonly cause?: unknown;\n };\n\n/**\n * Union of all typegen errors (specific + builder errors).\n */\nexport type TypegenError = TypegenSpecificError | BuilderError;\n\n/**\n * Error constructor helpers for concise error creation.\n */\nexport const typegenErrors = {\n codegenRequired: (outdir: string): TypegenSpecificError => ({\n code: \"TYPEGEN_CODEGEN_REQUIRED\",\n message: `Generated graphql-system module not found at '${outdir}'. Run 'soda-gql codegen' first.`,\n outdir,\n }),\n\n schemaLoadFailed: (schemaNames: readonly string[], cause?: unknown): TypegenSpecificError => ({\n code: \"TYPEGEN_SCHEMA_LOAD_FAILED\",\n message: `Failed to load schemas: ${schemaNames.join(\", \")}`,\n schemaNames,\n cause,\n }),\n\n buildFailed: (message: string, cause?: unknown): TypegenSpecificError => ({\n code: \"TYPEGEN_BUILD_FAILED\",\n message,\n cause,\n }),\n} as const;\n\n/**\n * Format TypegenError for console output (human-readable).\n */\nexport const formatTypegenError = (error: TypegenError): string => {\n const lines: string[] = [];\n\n lines.push(`Error [${error.code}]: ${error.message}`);\n\n switch (error.code) {\n case \"TYPEGEN_CODEGEN_REQUIRED\":\n lines.push(` Output directory: ${error.outdir}`);\n lines.push(\" Hint: Run 'soda-gql codegen' to generate the graphql-system module first.\");\n break;\n case \"TYPEGEN_SCHEMA_LOAD_FAILED\":\n lines.push(` Schemas: ${error.schemaNames.join(\", \")}`);\n break;\n }\n\n if (\"cause\" in error && error.cause) {\n lines.push(` Caused by: ${error.cause}`);\n }\n\n return lines.join(\"\\n\");\n};\n","/**\n * Template extractor for typegen.\n *\n * Extracts tagged template GraphQL content from TypeScript source files\n * using SWC parsing. Adapted from the LSP document-manager pattern\n * but simplified for batch extraction (no position tracking, no state management).\n *\n * @module\n */\n\nimport type { GraphqlSystemIdentifyHelper } from \"@soda-gql/builder\";\n\nimport { parseSync } from \"@swc/core\";\nimport type {\n ArrowFunctionExpression,\n CallExpression,\n ImportDeclaration,\n MemberExpression,\n Module,\n Node,\n TaggedTemplateExpression,\n} from \"@swc/types\";\n\n/** Operation kind extracted from tagged template tag name. */\nexport type OperationKind = \"query\" | \"mutation\" | \"subscription\" | \"fragment\";\n\n/** A single tagged template extracted from a TypeScript source file. */\nexport type ExtractedTemplate = {\n /** Resolved schema name from gql.{schemaName}. */\n readonly schemaName: string;\n /** Operation kind from tag name. */\n readonly kind: OperationKind;\n /** Raw GraphQL content between backticks (may contain __FRAG_SPREAD_N__ placeholders). */\n readonly content: string;\n /** Element name from curried tag call (e.g., \"GetUser\" from query(\"GetUser\")). */\n readonly elementName?: string;\n /** Type name from curried fragment call (e.g., \"User\" from fragment(\"UserFields\", \"User\")). */\n readonly typeName?: string;\n};\n\n/** Result of extracting templates from a source file. */\nexport type ExtractionResult = {\n readonly templates: readonly ExtractedTemplate[];\n readonly warnings: readonly string[];\n};\n\nconst OPERATION_KINDS = new Set<string>([\"query\", \"mutation\", \"subscription\", \"fragment\"]);\n\nconst isOperationKind = (value: string): value is OperationKind => OPERATION_KINDS.has(value);\n\n/**\n * Parse TypeScript source with SWC, returning null on failure.\n */\nconst safeParseSync = (source: string, tsx: boolean): ReturnType<typeof parseSync> | null => {\n try {\n return parseSync(source, {\n syntax: \"typescript\",\n tsx,\n decorators: false,\n dynamicImport: true,\n });\n } catch {\n return null;\n }\n};\n\n/**\n * Collect gql identifiers from import declarations.\n * Finds imports like `import { gql } from \"./graphql-system\"`.\n */\nconst collectGqlIdentifiers = (module: Module, filePath: string, helper: GraphqlSystemIdentifyHelper): ReadonlySet<string> => {\n const identifiers = new Set<string>();\n\n for (const item of module.body) {\n let declaration: ImportDeclaration | null = null;\n\n if (item.type === \"ImportDeclaration\") {\n declaration = item;\n } else if (\n \"declaration\" in item &&\n item.declaration &&\n // biome-ignore lint/suspicious/noExplicitAny: SWC AST type checking\n (item.declaration as any).type === \"ImportDeclaration\"\n ) {\n declaration = item.declaration as unknown as ImportDeclaration;\n }\n\n if (!declaration) {\n continue;\n }\n\n if (!helper.isGraphqlSystemImportSpecifier({ filePath, specifier: declaration.source.value })) {\n continue;\n }\n\n for (const specifier of declaration.specifiers ?? []) {\n if (specifier.type === \"ImportSpecifier\") {\n const imported = specifier.imported ? specifier.imported.value : specifier.local.value;\n if (imported === \"gql\" && !specifier.imported) {\n identifiers.add(specifier.local.value);\n }\n }\n }\n }\n\n return identifiers;\n};\n\n/**\n * Check if a call expression is a gql.{schemaName}(...) call.\n * Returns the schema name if it is, null otherwise.\n */\nconst getGqlCallSchemaName = (identifiers: ReadonlySet<string>, call: CallExpression): string | null => {\n const callee = call.callee;\n if (callee.type !== \"MemberExpression\") {\n return null;\n }\n\n const member = callee as MemberExpression;\n if (member.object.type !== \"Identifier\" || !identifiers.has(member.object.value)) {\n return null;\n }\n\n if (member.property.type !== \"Identifier\") {\n return null;\n }\n\n const firstArg = call.arguments[0];\n if (!firstArg?.expression || firstArg.expression.type !== \"ArrowFunctionExpression\") {\n return null;\n }\n\n return member.property.value;\n};\n\n/**\n * Extract templates from a gql callback's arrow function body.\n * Handles both expression bodies and block bodies with return statements.\n */\nconst extractTemplatesFromCallback = (arrow: ArrowFunctionExpression, schemaName: string): ExtractedTemplate[] => {\n const templates: ExtractedTemplate[] = [];\n\n const processExpression = (expr: Node): void => {\n // Direct tagged template: query(\"Name\")`...`\n if (expr.type === \"TaggedTemplateExpression\") {\n const tagged = expr as unknown as TaggedTemplateExpression;\n extractFromTaggedTemplate(tagged, schemaName, templates);\n return;\n }\n\n // Metadata chaining: query(\"Name\")`...`({ metadata: {} })\n if (expr.type === \"CallExpression\") {\n const call = expr as unknown as CallExpression;\n if (call.callee.type === \"TaggedTemplateExpression\") {\n extractFromTaggedTemplate(call.callee as TaggedTemplateExpression, schemaName, templates);\n }\n }\n };\n\n // Expression body: ({ query }) => query(\"Name\")`...`\n if (arrow.body.type !== \"BlockStatement\") {\n processExpression(arrow.body);\n return templates;\n }\n\n // Block body: ({ query }) => { return query(\"Name\")`...`; }\n for (const stmt of arrow.body.stmts) {\n if (stmt.type === \"ReturnStatement\" && stmt.argument) {\n processExpression(stmt.argument);\n }\n }\n\n return templates;\n};\n\nconst extractFromTaggedTemplate = (\n tagged: TaggedTemplateExpression,\n schemaName: string,\n templates: ExtractedTemplate[],\n): void => {\n // Tag can be:\n // - CallExpression: query(\"name\")`...` or fragment(\"name\", \"type\")`...` (curried syntax)\n // - Identifier: legacy bare-tag form (skipped if it contains interpolations)\n let kind: string;\n let elementName: string | undefined;\n let typeName: string | undefined;\n\n if (tagged.tag.type === \"Identifier\") {\n kind = tagged.tag.value;\n } else if (tagged.tag.type === \"CallExpression\") {\n const tagCall = tagged.tag as CallExpression;\n if (tagCall.callee.type === \"Identifier\") {\n kind = tagCall.callee.value;\n } else {\n return;\n }\n // Extract elementName and typeName from call arguments\n const firstArg = tagCall.arguments[0]?.expression;\n if (firstArg?.type === \"StringLiteral\") {\n elementName = (firstArg as { value: string }).value;\n }\n const secondArg = tagCall.arguments[1]?.expression;\n if (secondArg?.type === \"StringLiteral\") {\n typeName = (secondArg as { value: string }).value;\n }\n } else {\n return;\n }\n\n if (!isOperationKind(kind)) {\n return;\n }\n\n const { quasis, expressions } = tagged.template;\n\n // For legacy Identifier tag, skip templates with interpolations\n // For new syntax (CallExpression tag), handle interpolations with placeholders\n if (tagged.tag.type === \"Identifier\" && expressions.length > 0) {\n return;\n }\n\n if (quasis.length === 0) {\n return;\n }\n\n let content: string;\n if (expressions.length === 0) {\n // No interpolations — simple case\n const quasi = quasis[0];\n if (!quasi) return;\n content = quasi.cooked ?? quasi.raw;\n } else {\n // Build content with placeholder tokens for interpolations\n const parts: string[] = [];\n for (let i = 0; i < quasis.length; i++) {\n const quasi = quasis[i];\n if (!quasi) continue;\n parts.push(quasi.cooked ?? quasi.raw);\n if (i < expressions.length) {\n parts.push(`__FRAG_SPREAD_${i}__`);\n }\n }\n content = parts.join(\"\");\n }\n\n templates.push({\n schemaName,\n kind,\n content,\n ...(elementName !== undefined ? { elementName } : {}),\n ...(typeName !== undefined ? { typeName } : {}),\n });\n};\n\n/**\n * Find the innermost gql call, unwrapping method chains like .attach().\n */\nconst findGqlCall = (identifiers: ReadonlySet<string>, node: Node): CallExpression | null => {\n if (!node || node.type !== \"CallExpression\") {\n return null;\n }\n\n const call = node as unknown as CallExpression;\n if (getGqlCallSchemaName(identifiers, call) !== null) {\n return call;\n }\n\n const callee = call.callee;\n if (callee.type !== \"MemberExpression\") {\n return null;\n }\n\n return findGqlCall(identifiers, callee.object as unknown as Node);\n};\n\n/**\n * Walk AST to find gql calls and extract templates.\n */\nconst walkAndExtract = (node: Node, identifiers: ReadonlySet<string>): ExtractedTemplate[] => {\n const templates: ExtractedTemplate[] = [];\n\n const visit = (n: Node | ReadonlyArray<Node> | Record<string, unknown>): void => {\n if (!n || typeof n !== \"object\") {\n return;\n }\n\n if (\"type\" in n && n.type === \"CallExpression\") {\n const gqlCall = findGqlCall(identifiers, n as Node);\n if (gqlCall) {\n const schemaName = getGqlCallSchemaName(identifiers, gqlCall);\n if (schemaName) {\n const arrow = gqlCall.arguments[0]?.expression as ArrowFunctionExpression;\n templates.push(...extractTemplatesFromCallback(arrow, schemaName));\n }\n return; // Don't recurse into gql calls\n }\n }\n\n // Recurse into all array and object properties\n if (Array.isArray(n)) {\n for (const item of n) {\n visit(item as Node);\n }\n return;\n }\n\n for (const key of Object.keys(n)) {\n if (key === \"span\" || key === \"type\") {\n continue;\n }\n const value = (n as Record<string, unknown>)[key];\n if (value && typeof value === \"object\") {\n visit(value as Node);\n }\n }\n };\n\n visit(node);\n return templates;\n};\n\n/**\n * Extract all tagged templates from a TypeScript source file.\n *\n * @param filePath - Absolute path to the source file (used for import resolution)\n * @param source - TypeScript source code\n * @param helper - GraphQL system identifier for resolving gql imports\n * @returns Extracted templates and any warnings\n */\nexport const extractTemplatesFromSource = (\n filePath: string,\n source: string,\n helper: GraphqlSystemIdentifyHelper,\n): ExtractionResult => {\n const warnings: string[] = [];\n const isTsx = filePath.endsWith(\".tsx\");\n\n const program = safeParseSync(source, isTsx);\n if (!program || program.type !== \"Module\") {\n if (source.includes(\"gql\")) {\n warnings.push(`[typegen-extract] Failed to parse ${filePath}`);\n }\n return { templates: [], warnings };\n }\n\n const gqlIdentifiers = collectGqlIdentifiers(program, filePath, helper);\n if (gqlIdentifiers.size === 0) {\n return { templates: [], warnings };\n }\n\n return { templates: walkAndExtract(program, gqlIdentifiers), warnings };\n};\n","/**\n * Source file scanner for tagged template extraction.\n *\n * Discovers source files from config include/exclude patterns,\n * reads them, and extracts tagged templates using the template extractor.\n *\n * @module\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { normalize, resolve } from \"node:path\";\nimport type { GraphqlSystemIdentifyHelper } from \"@soda-gql/builder\";\nimport fg from \"fast-glob\";\nimport { type ExtractedTemplate, extractTemplatesFromSource } from \"./template-extractor\";\n\nexport type ScanSourceFilesOptions = {\n /** Glob patterns for source files to include. */\n readonly include: readonly string[];\n /** Glob patterns for source files to exclude. */\n readonly exclude: readonly string[];\n /** Base directory for resolving glob patterns. */\n readonly baseDir: string;\n /** Helper for identifying graphql-system imports. */\n readonly helper: GraphqlSystemIdentifyHelper;\n};\n\nexport type ScanResult = {\n /** Templates keyed by file path. */\n readonly templates: ReadonlyMap<string, readonly ExtractedTemplate[]>;\n /** Warnings from scanning. */\n readonly warnings: readonly string[];\n};\n\n/**\n * Scan source files for tagged templates.\n *\n * Uses fast-glob to discover files matching include/exclude patterns,\n * then extracts tagged templates from each file.\n */\nexport const scanSourceFiles = (options: ScanSourceFilesOptions): ScanResult => {\n const { include, exclude, baseDir, helper } = options;\n const warnings: string[] = [];\n\n // Build exclusion patterns\n const ignorePatterns = exclude.map((pattern) => (pattern.startsWith(\"!\") ? pattern.slice(1) : pattern));\n\n // Discover files via fast-glob\n const matchedFiles = fg.sync(include as string[], {\n cwd: baseDir,\n ignore: ignorePatterns,\n onlyFiles: true,\n absolute: true,\n });\n\n const templates = new Map<string, readonly ExtractedTemplate[]>();\n\n for (const filePath of matchedFiles) {\n const normalizedPath = normalize(resolve(filePath)).replace(/\\\\/g, \"/\");\n\n try {\n const source = readFileSync(normalizedPath, \"utf-8\");\n const { templates: extracted, warnings: extractionWarnings } = extractTemplatesFromSource(normalizedPath, source, helper);\n warnings.push(...extractionWarnings);\n\n if (extracted.length > 0) {\n templates.set(normalizedPath, extracted);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n warnings.push(`[typegen-scan] Failed to read ${normalizedPath}: ${message}`);\n }\n }\n\n return { templates, warnings };\n};\n","/**\n * Converts extracted tagged template GraphQL content into FieldSelectionData.\n *\n * Takes the output of template-extractor and produces FieldSelectionData entries\n * compatible with the emitter pipeline. Uses the shared field-building utilities\n * from core to produce AnyFieldsExtended from GraphQL AST.\n *\n * @module\n */\n\nimport type { FieldSelectionData, FieldSelectionsMap } from \"@soda-gql/builder\";\nimport type { CanonicalId } from \"@soda-gql/common\";\nimport {\n type AnyGraphqlSchema,\n buildFieldsFromSelectionSet,\n createSchemaIndexFromSchema,\n extractFragmentVariables,\n preprocessFragmentArgs,\n} from \"@soda-gql/core\";\nimport { Kind, parse as parseGraphql, type SelectionSetNode } from \"graphql\";\nimport type { ExtractedTemplate } from \"./template-extractor\";\n\n/** Result of converting templates to field selections. */\nexport type TemplateConversionResult = {\n readonly selections: FieldSelectionsMap;\n readonly warnings: readonly string[];\n};\n\n/**\n * Convert extracted templates into field selections for the emitter.\n *\n * @param templates - Templates extracted from source files, keyed by file path\n * @param schemas - Loaded schema objects keyed by schema name\n * @returns Map of canonical IDs to field selection data, plus any warnings\n */\nexport const convertTemplatesToSelections = (\n templates: ReadonlyMap<string, readonly ExtractedTemplate[]>,\n schemas: Record<string, AnyGraphqlSchema>,\n): TemplateConversionResult => {\n const selections = new Map<CanonicalId, FieldSelectionData>();\n const warnings: string[] = [];\n\n // Build schema indexes once per schema\n const schemaIndexes = new Map(Object.entries(schemas).map(([name, schema]) => [name, createSchemaIndexFromSchema(schema)]));\n\n for (const [filePath, fileTemplates] of templates) {\n for (const template of fileTemplates) {\n const schema = schemas[template.schemaName];\n if (!schema) {\n warnings.push(`[typegen-template] Unknown schema \"${template.schemaName}\" in ${filePath}`);\n continue;\n }\n\n const schemaIndex = schemaIndexes.get(template.schemaName);\n if (!schemaIndex) {\n continue;\n }\n\n try {\n if (template.kind === \"fragment\") {\n const selection = convertFragmentTemplate(template, schema, filePath);\n if (selection) {\n selections.set(selection.id, selection.data);\n }\n } else {\n const selection = convertOperationTemplate(template, schema, filePath);\n if (selection) {\n selections.set(selection.id, selection.data);\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n warnings.push(`[typegen-template] Failed to process ${template.kind} in ${filePath}: ${message}`);\n }\n }\n }\n\n return { selections, warnings };\n};\n\n/**\n * Recursively filter out __FRAG_SPREAD_ placeholder nodes from a selection set.\n * These placeholders are created by template-extractor for interpolated fragment references.\n * buildFieldsFromSelectionSet would throw on them since no interpolationMap is available.\n */\nconst filterPlaceholderSpreads = (selectionSet: SelectionSetNode): SelectionSetNode => ({\n ...selectionSet,\n selections: selectionSet.selections\n .filter((sel) => !(sel.kind === Kind.FRAGMENT_SPREAD && sel.name.value.startsWith(\"__FRAG_SPREAD_\")))\n .map((sel) => {\n if (sel.kind === Kind.FIELD && sel.selectionSet) {\n return { ...sel, selectionSet: filterPlaceholderSpreads(sel.selectionSet) };\n }\n if (sel.kind === Kind.INLINE_FRAGMENT && sel.selectionSet) {\n return { ...sel, selectionSet: filterPlaceholderSpreads(sel.selectionSet) };\n }\n return sel;\n }),\n});\n\n/**\n * Reconstruct full GraphQL source from an extracted template.\n * For curried syntax (new), prepends the definition header from tag call arguments.\n * For old syntax, returns content as-is.\n */\nconst reconstructGraphql = (template: ExtractedTemplate): string => {\n if (template.elementName) {\n if (template.kind === \"fragment\" && template.typeName) {\n return `fragment ${template.elementName} on ${template.typeName} ${template.content}`;\n }\n return `${template.kind} ${template.elementName} ${template.content}`;\n }\n return template.content;\n};\n\n/**\n * Convert a fragment template into FieldSelectionData.\n */\nconst convertFragmentTemplate = (\n template: ExtractedTemplate,\n schema: AnyGraphqlSchema,\n filePath: string,\n): { id: CanonicalId; data: FieldSelectionData } | null => {\n const schemaIndex = createSchemaIndexFromSchema(schema);\n const graphqlSource = reconstructGraphql(template);\n\n // Extract variable definitions from Fragment Arguments syntax\n const variableDefinitions = extractFragmentVariables(graphqlSource, schemaIndex);\n\n // Preprocess to strip Fragment Arguments\n const { preprocessed } = preprocessFragmentArgs(graphqlSource);\n\n const document = parseGraphql(preprocessed);\n const fragDef = document.definitions.find((d) => d.kind === Kind.FRAGMENT_DEFINITION);\n if (!fragDef || fragDef.kind !== Kind.FRAGMENT_DEFINITION) {\n return null;\n }\n\n const fragmentName = fragDef.name.value;\n const onType = fragDef.typeCondition.name.value;\n\n // Build fields from selection set (filter placeholder spreads from interpolated fragments)\n const fields = buildFieldsFromSelectionSet(filterPlaceholderSpreads(fragDef.selectionSet), schema, onType);\n\n // Generate a canonical ID from file path + fragment name\n const id = `${filePath}::${fragmentName}` as CanonicalId;\n\n return {\n id,\n data: {\n type: \"fragment\",\n schemaLabel: schema.label,\n key: fragmentName,\n typename: onType,\n fields,\n variableDefinitions,\n },\n };\n};\n\n/**\n * Convert an operation template into FieldSelectionData.\n */\nconst convertOperationTemplate = (\n template: ExtractedTemplate,\n schema: AnyGraphqlSchema,\n filePath: string,\n): { id: CanonicalId; data: FieldSelectionData } | null => {\n const graphqlSource = reconstructGraphql(template);\n const document = parseGraphql(graphqlSource);\n const opDef = document.definitions.find((d) => d.kind === Kind.OPERATION_DEFINITION);\n if (!opDef || opDef.kind !== Kind.OPERATION_DEFINITION) {\n return null;\n }\n\n const operationName = opDef.name?.value ?? \"Anonymous\";\n const operationType = opDef.operation;\n\n // Determine root type name based on operation type\n const rootTypeName = getRootTypeName(schema, operationType);\n\n // Build fields from selection set (filter placeholder spreads from interpolated fragments)\n const fields = buildFieldsFromSelectionSet(filterPlaceholderSpreads(opDef.selectionSet), schema, rootTypeName);\n\n // Variable definitions from the operation AST\n const variableDefinitions = opDef.variableDefinitions ?? [];\n\n // Generate a canonical ID from file path + operation name\n const id = `${filePath}::${operationName}` as CanonicalId;\n\n return {\n id,\n data: {\n type: \"operation\",\n schemaLabel: schema.label,\n operationName,\n operationType,\n fields,\n variableDefinitions: [...variableDefinitions],\n },\n };\n};\n\n/**\n * Get the root type name for an operation type from the schema.\n */\nconst getRootTypeName = (schema: AnyGraphqlSchema, operationType: string): string => {\n switch (operationType) {\n case \"query\":\n return schema.operations.query ?? \"Query\";\n case \"mutation\":\n return schema.operations.mutation ?? \"Mutation\";\n case \"subscription\":\n return schema.operations.subscription ?? \"Subscription\";\n default:\n return \"Query\";\n }\n};\n","/**\n * Main typegen runner.\n *\n * Orchestrates the prebuilt type generation process:\n * 1. Load schemas from generated CJS bundle\n * 2. Build artifact to evaluate elements\n * 3. Extract field selections from builder\n * 4. Scan source files for tagged templates and merge selections\n * 5. Emit types.prebuilt.ts\n *\n * @module\n */\n\nimport { existsSync } from \"node:fs\";\nimport { dirname, extname, join, relative, resolve } from \"node:path\";\nimport {\n createBuilderService,\n createGraphqlSystemIdentifyHelper,\n extractFieldSelections,\n type FieldSelectionData,\n type IntermediateArtifactElement,\n loadSchemasFromBundle,\n} from \"@soda-gql/builder\";\nimport type { CanonicalId } from \"@soda-gql/common\";\nimport type { ResolvedSodaGqlConfig } from \"@soda-gql/config\";\nimport { err, ok } from \"neverthrow\";\nimport { emitPrebuiltTypes } from \"./emitter\";\nimport { typegenErrors } from \"./errors\";\nimport { scanSourceFiles } from \"./template-scanner\";\nimport { convertTemplatesToSelections } from \"./template-to-selections\";\nimport type { TypegenResult, TypegenSuccess } from \"./types\";\n\n/**\n * Options for running typegen.\n */\nexport type RunTypegenOptions = {\n /**\n * Resolved soda-gql configuration.\n */\n readonly config: ResolvedSodaGqlConfig;\n};\n\nconst extensionMap: Record<string, string> = {\n \".ts\": \".js\",\n \".tsx\": \".js\",\n \".mts\": \".mjs\",\n \".cts\": \".cjs\",\n \".js\": \".js\",\n \".mjs\": \".mjs\",\n \".cjs\": \".cjs\",\n};\n\ntype ImportSpecifierOptions = {\n includeExtension?: boolean;\n};\n\nconst toImportSpecifier = (fromPath: string, targetPath: string, options?: ImportSpecifierOptions): string => {\n const fromDir = dirname(fromPath);\n const normalized = relative(fromDir, targetPath).replace(/\\\\/g, \"/\");\n const sourceExt = extname(targetPath);\n\n // When includeExtension is false (default), strip the extension entirely\n if (!options?.includeExtension) {\n if (normalized.length === 0) {\n return `./${targetPath.slice(0, -sourceExt.length).split(\"/\").pop()}`;\n }\n const withPrefix = normalized.startsWith(\".\") ? normalized : `./${normalized}`;\n const currentExt = extname(withPrefix);\n return currentExt ? withPrefix.slice(0, -currentExt.length) : withPrefix;\n }\n\n // When includeExtension is true, convert to runtime extension\n const runtimeExt = extensionMap[sourceExt] ?? sourceExt;\n\n if (normalized.length === 0) {\n const base = runtimeExt !== sourceExt ? targetPath.slice(0, -sourceExt.length).split(\"/\").pop() : targetPath.split(\"/\").pop();\n return `./${base}${runtimeExt}`;\n }\n\n const withPrefix = normalized.startsWith(\".\") ? normalized : `./${normalized}`;\n if (!runtimeExt) {\n return withPrefix;\n }\n if (withPrefix.endsWith(runtimeExt)) {\n return withPrefix;\n }\n\n const currentExt = extname(withPrefix);\n const withoutExt = currentExt ? withPrefix.slice(0, -currentExt.length) : withPrefix;\n return `${withoutExt}${runtimeExt}`;\n};\n\n/**\n * Run the typegen process.\n *\n * This function:\n * 1. Loads schemas from the generated CJS bundle\n * 2. Creates a BuilderService and builds the artifact\n * 3. Extracts field selections from the artifact\n * 4. Scans source files for tagged templates and merges selections\n * 5. Emits types.prebuilt.ts using emitPrebuiltTypes\n *\n * @param options - Typegen options including config\n * @returns Result containing success data or error\n */\nexport const runTypegen = async (options: RunTypegenOptions): Promise<TypegenResult> => {\n const { config } = options;\n const outdir = resolve(config.outdir);\n const cjsPath = join(outdir, \"index.cjs\");\n const importSpecifierOptions = { includeExtension: config.styles.importExtension };\n\n // Step 1: Check if codegen has been run\n if (!existsSync(cjsPath)) {\n return err(typegenErrors.codegenRequired(outdir));\n }\n\n // Step 2: Load schemas from CJS bundle\n const schemaNames = Object.keys(config.schemas);\n const schemasResult = loadSchemasFromBundle(cjsPath, schemaNames);\n if (schemasResult.isErr()) {\n return err(typegenErrors.schemaLoadFailed(schemaNames, schemasResult.error));\n }\n const schemas = schemasResult.value;\n\n // Calculate import path for types.prebuilt.ts to _internal-injects.ts\n const prebuiltTypesPath = join(outdir, \"types.prebuilt.ts\");\n const injectsModulePath = toImportSpecifier(prebuiltTypesPath, join(outdir, \"_internal-injects.ts\"), importSpecifierOptions);\n\n // Step 3: Build artifact using BuilderService\n const builderService = createBuilderService({\n config,\n });\n\n const artifactResult = await builderService.buildAsync();\n\n if (artifactResult.isErr()) {\n return err(typegenErrors.buildFailed(`Builder failed: ${artifactResult.error.message}`, artifactResult.error));\n }\n\n // Step 4: Extract field selections from intermediate elements\n const intermediateElements = builderService.getIntermediateElements();\n if (!intermediateElements) {\n return err(typegenErrors.buildFailed(\"No intermediate elements available after build\", undefined));\n }\n\n const fieldSelectionsResult = extractFieldSelections(intermediateElements as Record<CanonicalId, IntermediateArtifactElement>);\n const { selections: builderSelections, warnings: extractWarnings } = fieldSelectionsResult;\n\n // Step 4b: Scan source files for tagged templates and merge selections\n const graphqlHelper = createGraphqlSystemIdentifyHelper(config);\n const scanResult = scanSourceFiles({\n include: [...config.include],\n exclude: [...config.exclude],\n baseDir: config.baseDir,\n helper: graphqlHelper,\n });\n\n const templateSelections = convertTemplatesToSelections(scanResult.templates, schemas);\n\n // Merge builder and template selections into a combined map.\n // Template selections are authoritative for elements found by both scanners.\n // Deduplication is per-element (file + GraphQL name), not per-file, so that\n // callback-builder operations in files that also contain tagged templates are preserved.\n // Builder uses relative paths (e.g. \"src/foo.ts::varName\"), template scanner uses\n // absolute paths (e.g. \"/abs/path/src/foo.ts::FragmentName\"). Normalize to relative.\n const extractFilePart = (id: string): string => {\n const filePart = id.split(\"::\")[0] ?? \"\";\n // Normalize absolute paths to relative using baseDir\n if (filePart.startsWith(\"/\")) {\n return relative(config.baseDir, filePart);\n }\n return filePart;\n };\n\n const extractElementName = (data: FieldSelectionData): string | undefined =>\n data.type === \"fragment\" ? data.key : data.operationName;\n\n // Build set of (file, elementName) pairs from template selections\n const templateElements = new Set<string>();\n for (const [id, data] of templateSelections.selections) {\n const name = extractElementName(data);\n if (name) templateElements.add(`${extractFilePart(id)}::${name}`);\n }\n\n const fieldSelections = new Map<CanonicalId, FieldSelectionData>();\n for (const [id, data] of builderSelections) {\n // Only skip builder elements that were also found by the template scanner\n const name = extractElementName(data);\n if (name && templateElements.has(`${extractFilePart(id)}::${name}`)) continue;\n fieldSelections.set(id, data);\n }\n for (const [id, data] of templateSelections.selections) {\n fieldSelections.set(id, data);\n }\n\n const scanWarnings = [...scanResult.warnings, ...templateSelections.warnings];\n\n // Step 5: Emit types.prebuilt.ts\n const emitResult = await emitPrebuiltTypes({\n schemas,\n fieldSelections,\n outdir,\n injectsModulePath,\n });\n\n if (emitResult.isErr()) {\n return err(emitResult.error);\n }\n\n const { warnings: emitWarnings } = emitResult.value;\n\n // Count fragments and operations\n let fragmentCount = 0;\n let operationCount = 0;\n for (const selection of fieldSelections.values()) {\n if (selection.type === \"fragment\" && selection.key) {\n fragmentCount++;\n } else if (selection.type === \"operation\") {\n operationCount++;\n }\n }\n\n const allWarnings = [...extractWarnings, ...scanWarnings, ...emitWarnings];\n\n return ok({\n prebuiltTypesPath,\n fragmentCount,\n operationCount,\n warnings: allWarnings,\n } satisfies TypegenSuccess);\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["warnings: string[]","builderErrors","outputFormatters: TypeFormatters","inputFormatters: TypeFormatters","Kind","lines: string[]","formatters: TypeFormatters","lines: string[]","module","declaration: ImportDeclaration | null","templates: ExtractedTemplate[]","kind: string","elementName: string | undefined","typeName: string | undefined","content: string","parts: string[]","warnings: string[]","warnings: string[]","fg","warnings: string[]","Kind","extensionMap: Record<string, string>","withPrefix","currentExt"],"sources":["../src/emitter.ts","../src/errors.ts","../src/template-extractor.ts","../src/template-scanner.ts","../src/template-to-selections.ts","../src/runner.ts"],"sourcesContent":["/**\n * Prebuilt types emitter.\n *\n * Generates TypeScript type definitions for PrebuiltTypes registry\n * from field selection data and schema.\n *\n * ## Error Handling Strategy\n *\n * The emitter uses a partial failure approach for type calculation errors:\n *\n * **Recoverable errors** (result in warnings, element skipped):\n * - Type calculation failures (e.g., `calculateFieldsType` throws)\n * - Input type generation failures (e.g., `generateInputType` throws)\n * - These are caught per-element, logged as warnings, and the element is omitted\n *\n * **Fatal errors** (result in error result):\n * - `SCHEMA_NOT_FOUND`: Selection references non-existent schema\n * - `WRITE_FAILED`: Cannot write output file to disk\n *\n * This allows builds to succeed with partial type coverage when some elements\n * have issues, while providing visibility into problems via warnings.\n *\n * @module\n */\n\nimport { writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { type BuilderError, builderErrors, type FieldSelectionsMap } from \"@soda-gql/builder\";\nimport type { AnyGraphqlSchema, InputTypeSpecifiers, TypeFormatters } from \"@soda-gql/core\";\nimport {\n calculateFieldsType,\n generateInputObjectType,\n generateInputType,\n generateInputTypeFromVarDefs,\n parseInputSpecifier,\n} from \"@soda-gql/core\";\nimport { Kind, type TypeNode, type VariableDefinitionNode } from \"graphql\";\nimport { err, ok, type Result } from \"neverthrow\";\nimport type { TypegenError } from \"./errors\";\n\n/**\n * Options for emitting prebuilt types.\n */\nexport type PrebuiltTypesEmitterOptions = {\n /**\n * Schema definitions per schema name.\n * These come from the codegen output.\n */\n readonly schemas: Record<string, AnyGraphqlSchema>;\n /**\n * Field selections extracted from the builder.\n */\n readonly fieldSelections: FieldSelectionsMap;\n /**\n * Output directory (where types.prebuilt.ts should be written).\n * This should be the same as config.outdir.\n */\n readonly outdir: string;\n /**\n * Relative import path to _internal-injects.ts from types.prebuilt.ts.\n * Example: \"./_internal-injects\"\n */\n readonly injectsModulePath: string;\n};\n\ntype PrebuiltFragmentEntry = {\n readonly key: string;\n readonly typename: string;\n readonly inputType: string;\n readonly outputType: string;\n};\n\ntype PrebuiltOperationEntry = {\n readonly key: string;\n readonly inputType: string;\n readonly outputType: string;\n};\n\ntype SchemaGroup = {\n fragments: PrebuiltFragmentEntry[];\n operations: PrebuiltOperationEntry[];\n inputObjects: Set<string>;\n};\n\ntype GroupBySchemaResult = {\n readonly grouped: Map<string, SchemaGroup>;\n readonly warnings: string[];\n readonly skippedFragmentCount: number;\n};\n\n/**\n * Group field selections by schema.\n * Uses the schemaLabel from each selection to group them correctly.\n *\n * Fragments without a 'key' property are skipped (not included in PrebuiltTypes)\n * and a warning is added. This allows projects to use fragments without keys\n * while still generating prebuilt types for those that have keys.\n *\n * @returns Result containing grouped selections and warnings, or error if schema not found\n */\nconst groupBySchema = (\n fieldSelections: FieldSelectionsMap,\n schemas: Record<string, AnyGraphqlSchema>,\n): Result<GroupBySchemaResult, BuilderError | TypegenError> => {\n const grouped = new Map<string, SchemaGroup>();\n const warnings: string[] = [];\n let skippedFragmentCount = 0;\n\n // Initialize groups for each schema\n for (const schemaName of Object.keys(schemas)) {\n grouped.set(schemaName, { fragments: [], operations: [], inputObjects: new Set() });\n }\n\n for (const [canonicalId, selection] of fieldSelections) {\n // Use schemaLabel to determine which schema this selection belongs to\n const schemaName = selection.schemaLabel;\n const schema = schemas[schemaName];\n const group = grouped.get(schemaName);\n\n if (!schema || !group) {\n return err(builderErrors.schemaNotFound(schemaName, canonicalId));\n }\n\n // Create formatters for schema-specific type names\n const outputFormatters: TypeFormatters = {\n scalarOutput: (name) => `ScalarOutput_${schemaName}<\"${name}\">`,\n };\n const inputFormatters: TypeFormatters = {\n scalarInput: (name) => `ScalarInput_${schemaName}<\"${name}\">`,\n inputObject: (name) => `Input_${schemaName}_${name}`,\n };\n\n if (selection.type === \"fragment\") {\n // Skip fragments without keys (they won't be included in PrebuiltTypes)\n if (!selection.key) {\n skippedFragmentCount++;\n warnings.push(\n `[prebuilt] Fragment \"${canonicalId}\" skipped: missing 'key' property. ` +\n `Use tagged template syntax fragment(\"Name\", \"Type\")\\`{ ... }\\` to auto-assign a key, ` +\n `or set 'key' explicitly in the callback builder.`,\n );\n continue;\n }\n\n try {\n // Collect input objects used in fragment variables\n const usedInputObjects = collectUsedInputObjectsFromVarDefs(schema, selection.variableDefinitions);\n for (const inputName of usedInputObjects) {\n group.inputObjects.add(inputName);\n }\n\n // Generate output type with schema-specific scalar names\n const outputType = calculateFieldsType(schema, selection.fields, outputFormatters, selection.typename);\n\n // Generate input type from variableDefinitions with schema-specific names\n const hasVariables = Object.keys(selection.variableDefinitions).length > 0;\n const inputType = hasVariables\n ? generateInputTypeFromVarDefs(schema, selection.variableDefinitions, { formatters: inputFormatters })\n : \"void\";\n\n group.fragments.push({\n key: selection.key,\n typename: selection.typename,\n inputType,\n outputType,\n });\n } catch (error) {\n warnings.push(\n `[prebuilt] Failed to calculate type for fragment \"${selection.key}\": ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n } else if (selection.type === \"operation\") {\n try {\n // Collect input objects used in this operation\n const usedInputObjects = collectUsedInputObjects(schema, selection.variableDefinitions);\n for (const inputName of usedInputObjects) {\n group.inputObjects.add(inputName);\n }\n\n // Generate output type with schema-specific scalar names\n // Get the root type name from schema operations (Query, Mutation, Subscription)\n const rootTypeName = schema.operations[selection.operationType as keyof typeof schema.operations];\n const outputType = calculateFieldsType(schema, selection.fields, outputFormatters, rootTypeName ?? undefined);\n\n // Generate input type with schema-specific scalar and input object names\n const inputType = generateInputType(schema, selection.variableDefinitions, inputFormatters);\n\n group.operations.push({\n key: selection.operationName,\n inputType,\n outputType,\n });\n } catch (error) {\n warnings.push(\n `[prebuilt] Failed to calculate type for operation \"${selection.operationName}\": ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n }\n\n return ok({ grouped, warnings, skippedFragmentCount });\n};\n\n/**\n * Extract input object names from a GraphQL TypeNode.\n */\nconst extractInputObjectsFromType = (schema: AnyGraphqlSchema, typeNode: TypeNode, inputObjects: Set<string>): void => {\n switch (typeNode.kind) {\n case Kind.NON_NULL_TYPE:\n extractInputObjectsFromType(schema, typeNode.type, inputObjects);\n break;\n case Kind.LIST_TYPE:\n extractInputObjectsFromType(schema, typeNode.type, inputObjects);\n break;\n case Kind.NAMED_TYPE: {\n const name = typeNode.name.value;\n // Check if it's an input object (not a scalar or enum)\n if (!schema.scalar[name] && !schema.enum[name] && schema.input[name]) {\n inputObjects.add(name);\n }\n break;\n }\n }\n};\n\n/**\n * Recursively collect nested input objects from schema definitions.\n * Takes a set of initial input names and expands to include all nested inputs.\n */\nconst collectNestedInputObjects = (schema: AnyGraphqlSchema, initialInputNames: Set<string>): Set<string> => {\n const inputObjects = new Set(initialInputNames);\n\n const collectNested = (inputName: string, seen: Set<string>): void => {\n if (seen.has(inputName)) {\n return;\n }\n seen.add(inputName);\n\n const inputDef = schema.input[inputName];\n if (!inputDef) {\n return;\n }\n\n for (const fieldSpec of Object.values(inputDef.fields)) {\n const parsed = parseInputSpecifier(fieldSpec);\n if (parsed.kind === \"input\" && !inputObjects.has(parsed.name)) {\n inputObjects.add(parsed.name);\n collectNested(parsed.name, seen);\n }\n }\n };\n\n for (const inputName of Array.from(initialInputNames)) {\n collectNested(inputName, new Set());\n }\n\n return inputObjects;\n};\n\n/**\n * Collect all input object types used in variable definitions.\n * Recursively collects nested input objects from the schema.\n */\nconst collectUsedInputObjects = (\n schema: AnyGraphqlSchema,\n variableDefinitions: readonly VariableDefinitionNode[],\n): Set<string> => {\n const directInputs = new Set<string>();\n for (const varDef of variableDefinitions) {\n extractInputObjectsFromType(schema, varDef.type, directInputs);\n }\n return collectNestedInputObjects(schema, directInputs);\n};\n\n/**\n * Collect all input object types used in InputTypeSpecifiers.\n * Recursively collects nested input objects from the schema.\n */\nconst _collectUsedInputObjectsFromSpecifiers = (schema: AnyGraphqlSchema, specifiers: InputTypeSpecifiers): Set<string> => {\n const directInputs = new Set<string>();\n for (const specStr of Object.values(specifiers)) {\n const parsed = parseInputSpecifier(specStr);\n if (parsed.kind === \"input\" && schema.input[parsed.name]) {\n directInputs.add(parsed.name);\n }\n }\n return collectNestedInputObjects(schema, directInputs);\n};\n\n/**\n * Collect all input object types used in VariableDefinitions (VarSpecifier objects).\n * Used for fragment variable definitions.\n */\nconst collectUsedInputObjectsFromVarDefs = (\n schema: AnyGraphqlSchema,\n varDefs: Record<string, { kind: string; name: string }>,\n): Set<string> => {\n const directInputs = new Set<string>();\n for (const varSpec of Object.values(varDefs)) {\n if (varSpec.kind === \"input\" && schema.input[varSpec.name]) {\n directInputs.add(varSpec.name);\n }\n }\n return collectNestedInputObjects(schema, directInputs);\n};\n\n/**\n * Generate type definitions for input objects.\n */\nconst generateInputObjectTypeDefinitions = (schema: AnyGraphqlSchema, schemaName: string, inputNames: Set<string>): string[] => {\n const lines: string[] = [];\n\n // Get depth config from schema (optional properties defined in AnyGraphqlSchema)\n const defaultDepth = schema.__defaultInputDepth ?? 3;\n const depthOverrides = schema.__inputDepthOverrides ?? {};\n\n // Create formatters for schema-specific type names\n const formatters: TypeFormatters = {\n scalarInput: (name) => `ScalarInput_${schemaName}<\"${name}\">`,\n inputObject: (name) => `Input_${schemaName}_${name}`,\n };\n\n // Sort for deterministic output\n const sortedNames = Array.from(inputNames).sort();\n\n for (const inputName of sortedNames) {\n const typeString = generateInputObjectType(schema, inputName, {\n defaultDepth,\n depthOverrides,\n formatters,\n });\n\n lines.push(`export type Input_${schemaName}_${inputName} = ${typeString};`);\n }\n\n return lines;\n};\n\n/**\n * Generate the TypeScript code for prebuilt types.\n */\nconst generateTypesCode = (\n grouped: Map<string, SchemaGroup>,\n schemas: Record<string, AnyGraphqlSchema>,\n injectsModulePath: string,\n): string => {\n const schemaNames = Object.keys(schemas);\n\n const lines: string[] = [\n \"/**\",\n \" * Prebuilt type registry.\",\n \" *\",\n \" * This file is auto-generated by @soda-gql/typegen.\",\n \" * Do not edit manually.\",\n \" *\",\n \" * @module\",\n \" * @generated\",\n \" */\",\n \"\",\n 'import type { AssertExtends, PrebuiltTypeRegistry } from \"@soda-gql/core\";',\n ];\n\n // Generate import from _internal-injects.ts\n const scalarImports = schemaNames.map((name) => `scalar_${name}`).join(\", \");\n lines.push(`import type { ${scalarImports} } from \"${injectsModulePath}\";`);\n\n lines.push(\"\");\n\n // Generate ScalarInput and ScalarOutput helper types\n for (const schemaName of schemaNames) {\n lines.push(\n `type ScalarInput_${schemaName}<T extends keyof typeof scalar_${schemaName}> = ` +\n `typeof scalar_${schemaName}[T][\"$type\"][\"input\"];`,\n );\n lines.push(\n `type ScalarOutput_${schemaName}<T extends keyof typeof scalar_${schemaName}> = ` +\n `typeof scalar_${schemaName}[T][\"$type\"][\"output\"];`,\n );\n }\n\n lines.push(\"\");\n\n for (const [schemaName, { fragments, operations, inputObjects }] of grouped) {\n const schema = schemas[schemaName];\n\n // Generate input object type definitions if there are any\n if (inputObjects.size > 0 && schema) {\n lines.push(\"// Input object types\");\n const inputTypeLines = generateInputObjectTypeDefinitions(schema, schemaName, inputObjects);\n lines.push(...inputTypeLines);\n lines.push(\"\");\n }\n\n // Generate fragments type (deduplicate by key — last occurrence wins)\n const deduplicatedFragments = new Map<string, PrebuiltFragmentEntry>();\n for (const f of fragments) {\n deduplicatedFragments.set(f.key, f);\n }\n const fragmentEntries = Array.from(deduplicatedFragments.values())\n .sort((a, b) => a.key.localeCompare(b.key))\n .map(\n (f) =>\n ` readonly \"${f.key}\": { readonly typename: \"${f.typename}\"; readonly input: ${f.inputType}; readonly output: ${f.outputType} };`,\n );\n\n // Generate operations type (deduplicate by key — last occurrence wins)\n const deduplicatedOperations = new Map<string, PrebuiltOperationEntry>();\n for (const o of operations) {\n deduplicatedOperations.set(o.key, o);\n }\n const operationEntries = Array.from(deduplicatedOperations.values())\n .sort((a, b) => a.key.localeCompare(b.key))\n .map((o) => ` readonly \"${o.key}\": { readonly input: ${o.inputType}; readonly output: ${o.outputType} };`);\n\n lines.push(`export type PrebuiltTypes_${schemaName} = {`);\n lines.push(\" readonly fragments: {\");\n if (fragmentEntries.length > 0) {\n lines.push(...fragmentEntries);\n }\n lines.push(\" };\");\n lines.push(\" readonly operations: {\");\n if (operationEntries.length > 0) {\n lines.push(...operationEntries);\n }\n lines.push(\" };\");\n lines.push(\"};\");\n lines.push(`type _AssertPrebuiltTypes_${schemaName} = AssertExtends<PrebuiltTypes_${schemaName}, PrebuiltTypeRegistry>;`);\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n};\n\n/**\n * Result of emitting prebuilt types.\n */\nexport type PrebuiltTypesEmitResult = {\n readonly path: string;\n readonly warnings: readonly string[];\n readonly skippedFragmentCount: number;\n};\n\n/**\n * Emit prebuilt types to the types.prebuilt.ts file.\n *\n * This function uses a partial failure strategy: if type calculation fails for\n * individual elements (e.g., due to invalid field selections or missing schema\n * types), those elements are skipped and warnings are collected rather than\n * failing the entire emission. This allows builds to succeed even when some\n * elements have issues, while still reporting problems via warnings.\n *\n * @param options - Emitter options including schemas, field selections, and output directory\n * @returns Result containing output path and warnings, or error if a hard failure occurs\n *\n * @example\n * ```typescript\n * const result = await emitPrebuiltTypes({\n * schemas: { mySchema: schema },\n * fieldSelections,\n * outdir: \"./generated\",\n * injects: { mySchema: { scalars: \"./scalars.ts\" } },\n * });\n *\n * if (result.isOk()) {\n * console.log(`Generated: ${result.value.path}`);\n * if (result.value.warnings.length > 0) {\n * console.warn(\"Warnings:\", result.value.warnings);\n * }\n * }\n * ```\n */\nexport const emitPrebuiltTypes = async (\n options: PrebuiltTypesEmitterOptions,\n): Promise<Result<PrebuiltTypesEmitResult, BuilderError | TypegenError>> => {\n const { schemas, fieldSelections, outdir, injectsModulePath } = options;\n\n // Group selections by schema\n const groupResult = groupBySchema(fieldSelections, schemas);\n if (groupResult.isErr()) {\n return err(groupResult.error);\n }\n const { grouped, warnings, skippedFragmentCount } = groupResult.value;\n\n // Generate the types code\n const code = generateTypesCode(grouped, schemas, injectsModulePath);\n\n // Write to types.prebuilt.ts\n const typesPath = join(outdir, \"types.prebuilt.ts\");\n\n try {\n await writeFile(typesPath, code, \"utf-8\");\n return ok({ path: typesPath, warnings, skippedFragmentCount });\n } catch (error) {\n return err(\n builderErrors.writeFailed(\n typesPath,\n `Failed to write prebuilt types: ${error instanceof Error ? error.message : String(error)}`,\n error,\n ),\n );\n }\n};\n","/**\n * Error types for typegen package.\n *\n * @module\n */\n\nimport type { BuilderError } from \"@soda-gql/builder\";\n\n/**\n * Error codes specific to typegen operations.\n */\nexport type TypegenErrorCode = \"TYPEGEN_CODEGEN_REQUIRED\" | \"TYPEGEN_SCHEMA_LOAD_FAILED\" | \"TYPEGEN_BUILD_FAILED\";\n\n/**\n * Typegen-specific error type.\n */\nexport type TypegenSpecificError =\n | {\n readonly code: \"TYPEGEN_CODEGEN_REQUIRED\";\n readonly message: string;\n readonly outdir: string;\n }\n | {\n readonly code: \"TYPEGEN_SCHEMA_LOAD_FAILED\";\n readonly message: string;\n readonly schemaNames: readonly string[];\n readonly cause?: unknown;\n }\n | {\n readonly code: \"TYPEGEN_BUILD_FAILED\";\n readonly message: string;\n readonly cause?: unknown;\n };\n\n/**\n * Union of all typegen errors (specific + builder errors).\n */\nexport type TypegenError = TypegenSpecificError | BuilderError;\n\n/**\n * Error constructor helpers for concise error creation.\n */\nexport const typegenErrors = {\n codegenRequired: (outdir: string): TypegenSpecificError => ({\n code: \"TYPEGEN_CODEGEN_REQUIRED\",\n message: `Generated graphql-system module not found at '${outdir}'. Run 'soda-gql codegen' first.`,\n outdir,\n }),\n\n schemaLoadFailed: (schemaNames: readonly string[], cause?: unknown): TypegenSpecificError => ({\n code: \"TYPEGEN_SCHEMA_LOAD_FAILED\",\n message: `Failed to load schemas: ${schemaNames.join(\", \")}`,\n schemaNames,\n cause,\n }),\n\n buildFailed: (message: string, cause?: unknown): TypegenSpecificError => ({\n code: \"TYPEGEN_BUILD_FAILED\",\n message,\n cause,\n }),\n} as const;\n\n/**\n * Format TypegenError for console output (human-readable).\n */\nexport const formatTypegenError = (error: TypegenError): string => {\n const lines: string[] = [];\n\n lines.push(`Error [${error.code}]: ${error.message}`);\n\n switch (error.code) {\n case \"TYPEGEN_CODEGEN_REQUIRED\":\n lines.push(` Output directory: ${error.outdir}`);\n lines.push(\" Hint: Run 'soda-gql codegen' to generate the graphql-system module first.\");\n break;\n case \"TYPEGEN_SCHEMA_LOAD_FAILED\":\n lines.push(` Schemas: ${error.schemaNames.join(\", \")}`);\n break;\n }\n\n if (\"cause\" in error && error.cause) {\n lines.push(` Caused by: ${error.cause}`);\n }\n\n return lines.join(\"\\n\");\n};\n","/**\n * Template extractor for typegen.\n *\n * Extracts tagged template GraphQL content from TypeScript source files\n * using SWC parsing. Adapted from the LSP document-manager pattern\n * but simplified for batch extraction (no position tracking, no state management).\n *\n * @module\n */\n\nimport type { GraphqlSystemIdentifyHelper } from \"@soda-gql/builder\";\n\nimport { parseSync } from \"@swc/core\";\nimport type {\n ArrowFunctionExpression,\n CallExpression,\n ImportDeclaration,\n MemberExpression,\n Module,\n Node,\n TaggedTemplateExpression,\n} from \"@swc/types\";\n\n/** Operation kind extracted from tagged template tag name. */\nexport type OperationKind = \"query\" | \"mutation\" | \"subscription\" | \"fragment\";\n\n/** A single tagged template extracted from a TypeScript source file. */\nexport type ExtractedTemplate = {\n /** Resolved schema name from gql.{schemaName}. */\n readonly schemaName: string;\n /** Operation kind from tag name. */\n readonly kind: OperationKind;\n /** Raw GraphQL content between backticks (may contain __FRAG_SPREAD_N__ placeholders). */\n readonly content: string;\n /** Element name from curried tag call (e.g., \"GetUser\" from query(\"GetUser\")). */\n readonly elementName?: string;\n /** Type name from curried fragment call (e.g., \"User\" from fragment(\"UserFields\", \"User\")). */\n readonly typeName?: string;\n};\n\n/** Result of extracting templates from a source file. */\nexport type ExtractionResult = {\n readonly templates: readonly ExtractedTemplate[];\n readonly warnings: readonly string[];\n};\n\nconst OPERATION_KINDS = new Set<string>([\"query\", \"mutation\", \"subscription\", \"fragment\"]);\n\nconst isOperationKind = (value: string): value is OperationKind => OPERATION_KINDS.has(value);\n\n/**\n * Parse TypeScript source with SWC, returning null on failure.\n */\nconst safeParseSync = (source: string, tsx: boolean): ReturnType<typeof parseSync> | null => {\n try {\n return parseSync(source, {\n syntax: \"typescript\",\n tsx,\n decorators: false,\n dynamicImport: true,\n });\n } catch {\n return null;\n }\n};\n\n/**\n * Collect gql identifiers from import declarations.\n * Finds imports like `import { gql } from \"./graphql-system\"`.\n */\nconst collectGqlIdentifiers = (module: Module, filePath: string, helper: GraphqlSystemIdentifyHelper): ReadonlySet<string> => {\n const identifiers = new Set<string>();\n\n for (const item of module.body) {\n let declaration: ImportDeclaration | null = null;\n\n if (item.type === \"ImportDeclaration\") {\n declaration = item;\n } else if (\n \"declaration\" in item &&\n item.declaration &&\n // biome-ignore lint/suspicious/noExplicitAny: SWC AST type checking\n (item.declaration as any).type === \"ImportDeclaration\"\n ) {\n declaration = item.declaration as unknown as ImportDeclaration;\n }\n\n if (!declaration) {\n continue;\n }\n\n if (!helper.isGraphqlSystemImportSpecifier({ filePath, specifier: declaration.source.value })) {\n continue;\n }\n\n for (const specifier of declaration.specifiers ?? []) {\n if (specifier.type === \"ImportSpecifier\") {\n const imported = specifier.imported ? specifier.imported.value : specifier.local.value;\n if (imported === \"gql\" && !specifier.imported) {\n identifiers.add(specifier.local.value);\n }\n }\n }\n }\n\n return identifiers;\n};\n\n/**\n * Check if a call expression is a gql.{schemaName}(...) call.\n * Returns the schema name if it is, null otherwise.\n */\nconst getGqlCallSchemaName = (identifiers: ReadonlySet<string>, call: CallExpression): string | null => {\n const callee = call.callee;\n if (callee.type !== \"MemberExpression\") {\n return null;\n }\n\n const member = callee as MemberExpression;\n if (member.object.type !== \"Identifier\" || !identifiers.has(member.object.value)) {\n return null;\n }\n\n if (member.property.type !== \"Identifier\") {\n return null;\n }\n\n const firstArg = call.arguments[0];\n if (!firstArg?.expression || firstArg.expression.type !== \"ArrowFunctionExpression\") {\n return null;\n }\n\n return member.property.value;\n};\n\n/**\n * Extract templates from a gql callback's arrow function body.\n * Handles both expression bodies and block bodies with return statements.\n */\nconst extractTemplatesFromCallback = (arrow: ArrowFunctionExpression, schemaName: string): ExtractedTemplate[] => {\n const templates: ExtractedTemplate[] = [];\n\n const processExpression = (expr: Node): void => {\n // Direct tagged template: query(\"Name\")`...`\n if (expr.type === \"TaggedTemplateExpression\") {\n const tagged = expr as unknown as TaggedTemplateExpression;\n extractFromTaggedTemplate(tagged, schemaName, templates);\n return;\n }\n\n // Metadata chaining: query(\"Name\")`...`({ metadata: {} })\n if (expr.type === \"CallExpression\") {\n const call = expr as unknown as CallExpression;\n if (call.callee.type === \"TaggedTemplateExpression\") {\n extractFromTaggedTemplate(call.callee as TaggedTemplateExpression, schemaName, templates);\n }\n }\n };\n\n // Expression body: ({ query }) => query(\"Name\")`...`\n if (arrow.body.type !== \"BlockStatement\") {\n processExpression(arrow.body);\n return templates;\n }\n\n // Block body: ({ query }) => { return query(\"Name\")`...`; }\n for (const stmt of arrow.body.stmts) {\n if (stmt.type === \"ReturnStatement\" && stmt.argument) {\n processExpression(stmt.argument);\n }\n }\n\n return templates;\n};\n\nconst extractFromTaggedTemplate = (\n tagged: TaggedTemplateExpression,\n schemaName: string,\n templates: ExtractedTemplate[],\n): void => {\n // Tag can be:\n // - CallExpression: query(\"name\")`...` or fragment(\"name\", \"type\")`...` (curried syntax)\n // - Identifier: legacy bare-tag form (skipped if it contains interpolations)\n let kind: string;\n let elementName: string | undefined;\n let typeName: string | undefined;\n\n if (tagged.tag.type === \"Identifier\") {\n kind = tagged.tag.value;\n } else if (tagged.tag.type === \"CallExpression\") {\n const tagCall = tagged.tag as CallExpression;\n if (tagCall.callee.type === \"Identifier\") {\n kind = tagCall.callee.value;\n } else {\n return;\n }\n // Extract elementName and typeName from call arguments\n const firstArg = tagCall.arguments[0]?.expression;\n if (firstArg?.type === \"StringLiteral\") {\n elementName = (firstArg as { value: string }).value;\n }\n const secondArg = tagCall.arguments[1]?.expression;\n if (secondArg?.type === \"StringLiteral\") {\n typeName = (secondArg as { value: string }).value;\n }\n } else {\n return;\n }\n\n if (!isOperationKind(kind)) {\n return;\n }\n\n const { quasis, expressions } = tagged.template;\n\n // For legacy Identifier tag, skip templates with interpolations\n // For new syntax (CallExpression tag), handle interpolations with placeholders\n if (tagged.tag.type === \"Identifier\" && expressions.length > 0) {\n return;\n }\n\n if (quasis.length === 0) {\n return;\n }\n\n let content: string;\n if (expressions.length === 0) {\n // No interpolations — simple case\n const quasi = quasis[0];\n if (!quasi) return;\n content = quasi.cooked ?? quasi.raw;\n } else {\n // Build content with placeholder tokens for interpolations\n const parts: string[] = [];\n for (let i = 0; i < quasis.length; i++) {\n const quasi = quasis[i];\n if (!quasi) continue;\n parts.push(quasi.cooked ?? quasi.raw);\n if (i < expressions.length) {\n parts.push(`__FRAG_SPREAD_${i}__`);\n }\n }\n content = parts.join(\"\");\n }\n\n templates.push({\n schemaName,\n kind,\n content,\n ...(elementName !== undefined ? { elementName } : {}),\n ...(typeName !== undefined ? { typeName } : {}),\n });\n};\n\n/**\n * Find the innermost gql call, unwrapping method chains like .attach().\n */\nconst findGqlCall = (identifiers: ReadonlySet<string>, node: Node): CallExpression | null => {\n if (!node || node.type !== \"CallExpression\") {\n return null;\n }\n\n const call = node as unknown as CallExpression;\n if (getGqlCallSchemaName(identifiers, call) !== null) {\n return call;\n }\n\n const callee = call.callee;\n if (callee.type !== \"MemberExpression\") {\n return null;\n }\n\n return findGqlCall(identifiers, callee.object as unknown as Node);\n};\n\n/**\n * Walk AST to find gql calls and extract templates.\n */\nconst walkAndExtract = (node: Node, identifiers: ReadonlySet<string>): ExtractedTemplate[] => {\n const templates: ExtractedTemplate[] = [];\n\n const visit = (n: Node | ReadonlyArray<Node> | Record<string, unknown>): void => {\n if (!n || typeof n !== \"object\") {\n return;\n }\n\n if (\"type\" in n && n.type === \"CallExpression\") {\n const gqlCall = findGqlCall(identifiers, n as Node);\n if (gqlCall) {\n const schemaName = getGqlCallSchemaName(identifiers, gqlCall);\n if (schemaName) {\n const arrow = gqlCall.arguments[0]?.expression as ArrowFunctionExpression;\n templates.push(...extractTemplatesFromCallback(arrow, schemaName));\n }\n return; // Don't recurse into gql calls\n }\n }\n\n // Recurse into all array and object properties\n if (Array.isArray(n)) {\n for (const item of n) {\n visit(item as Node);\n }\n return;\n }\n\n for (const key of Object.keys(n)) {\n if (key === \"span\" || key === \"type\") {\n continue;\n }\n const value = (n as Record<string, unknown>)[key];\n if (value && typeof value === \"object\") {\n visit(value as Node);\n }\n }\n };\n\n visit(node);\n return templates;\n};\n\n/**\n * Extract all tagged templates from a TypeScript source file.\n *\n * @param filePath - Absolute path to the source file (used for import resolution)\n * @param source - TypeScript source code\n * @param helper - GraphQL system identifier for resolving gql imports\n * @returns Extracted templates and any warnings\n */\nexport const extractTemplatesFromSource = (\n filePath: string,\n source: string,\n helper: GraphqlSystemIdentifyHelper,\n): ExtractionResult => {\n const warnings: string[] = [];\n const isTsx = filePath.endsWith(\".tsx\");\n\n const program = safeParseSync(source, isTsx);\n if (!program || program.type !== \"Module\") {\n if (source.includes(\"gql\")) {\n warnings.push(`[typegen-extract] Failed to parse ${filePath}`);\n }\n return { templates: [], warnings };\n }\n\n const gqlIdentifiers = collectGqlIdentifiers(program, filePath, helper);\n if (gqlIdentifiers.size === 0) {\n return { templates: [], warnings };\n }\n\n return { templates: walkAndExtract(program, gqlIdentifiers), warnings };\n};\n","/**\n * Source file scanner for tagged template extraction.\n *\n * Discovers source files from config include/exclude patterns,\n * reads them, and extracts tagged templates using the template extractor.\n *\n * @module\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { normalize, resolve } from \"node:path\";\nimport type { GraphqlSystemIdentifyHelper } from \"@soda-gql/builder\";\nimport fg from \"fast-glob\";\nimport { type ExtractedTemplate, extractTemplatesFromSource } from \"./template-extractor\";\n\nexport type ScanSourceFilesOptions = {\n /** Glob patterns for source files to include. */\n readonly include: readonly string[];\n /** Glob patterns for source files to exclude. */\n readonly exclude: readonly string[];\n /** Base directory for resolving glob patterns. */\n readonly baseDir: string;\n /** Helper for identifying graphql-system imports. */\n readonly helper: GraphqlSystemIdentifyHelper;\n};\n\nexport type ScanResult = {\n /** Templates keyed by file path. */\n readonly templates: ReadonlyMap<string, readonly ExtractedTemplate[]>;\n /** Warnings from scanning. */\n readonly warnings: readonly string[];\n};\n\n/**\n * Scan source files for tagged templates.\n *\n * Uses fast-glob to discover files matching include/exclude patterns,\n * then extracts tagged templates from each file.\n */\nexport const scanSourceFiles = (options: ScanSourceFilesOptions): ScanResult => {\n const { include, exclude, baseDir, helper } = options;\n const warnings: string[] = [];\n\n // Build exclusion patterns\n const ignorePatterns = exclude.map((pattern) => (pattern.startsWith(\"!\") ? pattern.slice(1) : pattern));\n\n // Discover files via fast-glob\n const matchedFiles = fg.sync(include as string[], {\n cwd: baseDir,\n ignore: ignorePatterns,\n onlyFiles: true,\n absolute: true,\n });\n\n const templates = new Map<string, readonly ExtractedTemplate[]>();\n\n for (const filePath of matchedFiles) {\n const normalizedPath = normalize(resolve(filePath)).replace(/\\\\/g, \"/\");\n\n try {\n const source = readFileSync(normalizedPath, \"utf-8\");\n const { templates: extracted, warnings: extractionWarnings } = extractTemplatesFromSource(normalizedPath, source, helper);\n warnings.push(...extractionWarnings);\n\n if (extracted.length > 0) {\n templates.set(normalizedPath, extracted);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n warnings.push(`[typegen-scan] Failed to read ${normalizedPath}: ${message}`);\n }\n }\n\n return { templates, warnings };\n};\n","/**\n * Converts extracted tagged template GraphQL content into FieldSelectionData.\n *\n * Takes the output of template-extractor and produces FieldSelectionData entries\n * compatible with the emitter pipeline. Uses the shared field-building utilities\n * from core to produce AnyFieldsExtended from GraphQL AST.\n *\n * @module\n */\n\nimport type { FieldSelectionData, FieldSelectionsMap } from \"@soda-gql/builder\";\nimport type { CanonicalId } from \"@soda-gql/common\";\nimport {\n type AnyGraphqlSchema,\n buildFieldsFromSelectionSet,\n createSchemaIndexFromSchema,\n extractFragmentVariables,\n preprocessFragmentArgs,\n} from \"@soda-gql/core\";\nimport { Kind, parse as parseGraphql, type SelectionSetNode } from \"graphql\";\nimport type { ExtractedTemplate } from \"./template-extractor\";\n\n/** Result of converting templates to field selections. */\nexport type TemplateConversionResult = {\n readonly selections: FieldSelectionsMap;\n readonly warnings: readonly string[];\n};\n\n/**\n * Convert extracted templates into field selections for the emitter.\n *\n * @param templates - Templates extracted from source files, keyed by file path\n * @param schemas - Loaded schema objects keyed by schema name\n * @returns Map of canonical IDs to field selection data, plus any warnings\n */\nexport const convertTemplatesToSelections = (\n templates: ReadonlyMap<string, readonly ExtractedTemplate[]>,\n schemas: Record<string, AnyGraphqlSchema>,\n): TemplateConversionResult => {\n const selections = new Map<CanonicalId, FieldSelectionData>();\n const warnings: string[] = [];\n\n // Build schema indexes once per schema\n const schemaIndexes = new Map(Object.entries(schemas).map(([name, schema]) => [name, createSchemaIndexFromSchema(schema)]));\n\n for (const [filePath, fileTemplates] of templates) {\n for (const template of fileTemplates) {\n const schema = schemas[template.schemaName];\n if (!schema) {\n warnings.push(`[typegen-template] Unknown schema \"${template.schemaName}\" in ${filePath}`);\n continue;\n }\n\n const schemaIndex = schemaIndexes.get(template.schemaName);\n if (!schemaIndex) {\n continue;\n }\n\n try {\n if (template.kind === \"fragment\") {\n const selection = convertFragmentTemplate(template, schema, filePath);\n if (selection) {\n selections.set(selection.id, selection.data);\n }\n } else {\n const selection = convertOperationTemplate(template, schema, filePath);\n if (selection) {\n selections.set(selection.id, selection.data);\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n warnings.push(`[typegen-template] Failed to process ${template.kind} in ${filePath}: ${message}`);\n }\n }\n }\n\n return { selections, warnings };\n};\n\n/**\n * Recursively filter out __FRAG_SPREAD_ placeholder nodes from a selection set.\n * These placeholders are created by template-extractor for interpolated fragment references.\n * buildFieldsFromSelectionSet would throw on them since no interpolationMap is available.\n */\nconst filterPlaceholderSpreads = (selectionSet: SelectionSetNode): SelectionSetNode => ({\n ...selectionSet,\n selections: selectionSet.selections\n .filter((sel) => !(sel.kind === Kind.FRAGMENT_SPREAD && sel.name.value.startsWith(\"__FRAG_SPREAD_\")))\n .map((sel) => {\n if (sel.kind === Kind.FIELD && sel.selectionSet) {\n return { ...sel, selectionSet: filterPlaceholderSpreads(sel.selectionSet) };\n }\n if (sel.kind === Kind.INLINE_FRAGMENT && sel.selectionSet) {\n return { ...sel, selectionSet: filterPlaceholderSpreads(sel.selectionSet) };\n }\n return sel;\n }),\n});\n\n/** Simple matching-paren finder for template content (no comments/strings to handle). */\nconst findClosingParen = (source: string, openIndex: number): number => {\n let depth = 0;\n for (let i = openIndex; i < source.length; i++) {\n if (source[i] === \"(\") depth++;\n else if (source[i] === \")\") {\n depth--;\n if (depth === 0) return i;\n }\n }\n return -1;\n};\n\n/**\n * Reconstruct full GraphQL source from an extracted template.\n * For curried syntax (new), prepends the definition header from tag call arguments.\n * For curried fragments with Fragment Arguments, repositions variable declarations\n * before the on-clause to produce RFC-compliant syntax.\n * For old syntax, returns content as-is.\n */\nconst reconstructGraphql = (template: ExtractedTemplate): string => {\n if (template.elementName) {\n if (template.kind === \"fragment\" && template.typeName) {\n const trimmed = template.content.trim();\n if (trimmed.startsWith(\"(\")) {\n const closeIdx = findClosingParen(trimmed, 0);\n if (closeIdx !== -1) {\n const varDecls = trimmed.slice(0, closeIdx + 1);\n const selectionSet = trimmed.slice(closeIdx + 1).trim();\n return `fragment ${template.elementName}${varDecls} on ${template.typeName} ${selectionSet}`;\n }\n }\n return `fragment ${template.elementName} on ${template.typeName} ${trimmed}`;\n }\n return `${template.kind} ${template.elementName} ${template.content}`;\n }\n return template.content;\n};\n\n/**\n * Convert a fragment template into FieldSelectionData.\n */\nconst convertFragmentTemplate = (\n template: ExtractedTemplate,\n schema: AnyGraphqlSchema,\n filePath: string,\n): { id: CanonicalId; data: FieldSelectionData } | null => {\n const schemaIndex = createSchemaIndexFromSchema(schema);\n const graphqlSource = reconstructGraphql(template);\n\n // Extract variable definitions from Fragment Arguments syntax\n const variableDefinitions = extractFragmentVariables(graphqlSource, schemaIndex);\n\n // Preprocess to strip Fragment Arguments\n const { preprocessed } = preprocessFragmentArgs(graphqlSource);\n\n const document = parseGraphql(preprocessed);\n const fragDef = document.definitions.find((d) => d.kind === Kind.FRAGMENT_DEFINITION);\n if (!fragDef || fragDef.kind !== Kind.FRAGMENT_DEFINITION) {\n return null;\n }\n\n const fragmentName = fragDef.name.value;\n const onType = fragDef.typeCondition.name.value;\n\n // Build fields from selection set (filter placeholder spreads from interpolated fragments)\n const fields = buildFieldsFromSelectionSet(filterPlaceholderSpreads(fragDef.selectionSet), schema, onType);\n\n // Generate a canonical ID from file path + fragment name\n const id = `${filePath}::${fragmentName}` as CanonicalId;\n\n return {\n id,\n data: {\n type: \"fragment\",\n schemaLabel: schema.label,\n key: fragmentName,\n typename: onType,\n fields,\n variableDefinitions,\n },\n };\n};\n\n/**\n * Convert an operation template into FieldSelectionData.\n */\nconst convertOperationTemplate = (\n template: ExtractedTemplate,\n schema: AnyGraphqlSchema,\n filePath: string,\n): { id: CanonicalId; data: FieldSelectionData } | null => {\n const graphqlSource = reconstructGraphql(template);\n const document = parseGraphql(graphqlSource);\n const opDef = document.definitions.find((d) => d.kind === Kind.OPERATION_DEFINITION);\n if (!opDef || opDef.kind !== Kind.OPERATION_DEFINITION) {\n return null;\n }\n\n const operationName = opDef.name?.value ?? \"Anonymous\";\n const operationType = opDef.operation;\n\n // Determine root type name based on operation type\n const rootTypeName = getRootTypeName(schema, operationType);\n\n // Build fields from selection set (filter placeholder spreads from interpolated fragments)\n const fields = buildFieldsFromSelectionSet(filterPlaceholderSpreads(opDef.selectionSet), schema, rootTypeName);\n\n // Variable definitions from the operation AST\n const variableDefinitions = opDef.variableDefinitions ?? [];\n\n // Generate a canonical ID from file path + operation name\n const id = `${filePath}::${operationName}` as CanonicalId;\n\n return {\n id,\n data: {\n type: \"operation\",\n schemaLabel: schema.label,\n operationName,\n operationType,\n fields,\n variableDefinitions: [...variableDefinitions],\n },\n };\n};\n\n/**\n * Get the root type name for an operation type from the schema.\n */\nconst getRootTypeName = (schema: AnyGraphqlSchema, operationType: string): string => {\n switch (operationType) {\n case \"query\":\n return schema.operations.query ?? \"Query\";\n case \"mutation\":\n return schema.operations.mutation ?? \"Mutation\";\n case \"subscription\":\n return schema.operations.subscription ?? \"Subscription\";\n default:\n return \"Query\";\n }\n};\n","/**\n * Main typegen runner.\n *\n * Orchestrates the prebuilt type generation process:\n * 1. Load schemas from generated CJS bundle\n * 2. Build artifact to evaluate elements\n * 3. Extract field selections from builder\n * 4. Scan source files for tagged templates and merge selections\n * 5. Emit types.prebuilt.ts\n *\n * @module\n */\n\nimport { existsSync } from \"node:fs\";\nimport { dirname, extname, join, relative, resolve } from \"node:path\";\nimport {\n createBuilderService,\n createGraphqlSystemIdentifyHelper,\n extractFieldSelections,\n type FieldSelectionData,\n type IntermediateArtifactElement,\n loadSchemasFromBundle,\n} from \"@soda-gql/builder\";\nimport type { CanonicalId } from \"@soda-gql/common\";\nimport type { ResolvedSodaGqlConfig } from \"@soda-gql/config\";\nimport { err, ok } from \"neverthrow\";\nimport { emitPrebuiltTypes } from \"./emitter\";\nimport { typegenErrors } from \"./errors\";\nimport { scanSourceFiles } from \"./template-scanner\";\nimport { convertTemplatesToSelections } from \"./template-to-selections\";\nimport type { TypegenResult, TypegenSuccess } from \"./types\";\n\n/**\n * Options for running typegen.\n */\nexport type RunTypegenOptions = {\n /**\n * Resolved soda-gql configuration.\n */\n readonly config: ResolvedSodaGqlConfig;\n};\n\nconst extensionMap: Record<string, string> = {\n \".ts\": \".js\",\n \".tsx\": \".js\",\n \".mts\": \".mjs\",\n \".cts\": \".cjs\",\n \".js\": \".js\",\n \".mjs\": \".mjs\",\n \".cjs\": \".cjs\",\n};\n\ntype ImportSpecifierOptions = {\n includeExtension?: boolean;\n};\n\nconst toImportSpecifier = (fromPath: string, targetPath: string, options?: ImportSpecifierOptions): string => {\n const fromDir = dirname(fromPath);\n const normalized = relative(fromDir, targetPath).replace(/\\\\/g, \"/\");\n const sourceExt = extname(targetPath);\n\n // When includeExtension is false (default), strip the extension entirely\n if (!options?.includeExtension) {\n if (normalized.length === 0) {\n return `./${targetPath.slice(0, -sourceExt.length).split(\"/\").pop()}`;\n }\n const withPrefix = normalized.startsWith(\".\") ? normalized : `./${normalized}`;\n const currentExt = extname(withPrefix);\n return currentExt ? withPrefix.slice(0, -currentExt.length) : withPrefix;\n }\n\n // When includeExtension is true, convert to runtime extension\n const runtimeExt = extensionMap[sourceExt] ?? sourceExt;\n\n if (normalized.length === 0) {\n const base = runtimeExt !== sourceExt ? targetPath.slice(0, -sourceExt.length).split(\"/\").pop() : targetPath.split(\"/\").pop();\n return `./${base}${runtimeExt}`;\n }\n\n const withPrefix = normalized.startsWith(\".\") ? normalized : `./${normalized}`;\n if (!runtimeExt) {\n return withPrefix;\n }\n if (withPrefix.endsWith(runtimeExt)) {\n return withPrefix;\n }\n\n const currentExt = extname(withPrefix);\n const withoutExt = currentExt ? withPrefix.slice(0, -currentExt.length) : withPrefix;\n return `${withoutExt}${runtimeExt}`;\n};\n\n/**\n * Run the typegen process.\n *\n * This function:\n * 1. Loads schemas from the generated CJS bundle\n * 2. Creates a BuilderService and builds the artifact\n * 3. Extracts field selections from the artifact\n * 4. Scans source files for tagged templates and merges selections\n * 5. Emits types.prebuilt.ts using emitPrebuiltTypes\n *\n * @param options - Typegen options including config\n * @returns Result containing success data or error\n */\nexport const runTypegen = async (options: RunTypegenOptions): Promise<TypegenResult> => {\n const { config } = options;\n const outdir = resolve(config.outdir);\n const cjsPath = join(outdir, \"index.cjs\");\n const importSpecifierOptions = { includeExtension: config.styles.importExtension };\n\n // Step 1: Check if codegen has been run\n if (!existsSync(cjsPath)) {\n return err(typegenErrors.codegenRequired(outdir));\n }\n\n // Step 2: Load schemas from CJS bundle\n const schemaNames = Object.keys(config.schemas);\n const schemasResult = loadSchemasFromBundle(cjsPath, schemaNames);\n if (schemasResult.isErr()) {\n return err(typegenErrors.schemaLoadFailed(schemaNames, schemasResult.error));\n }\n const schemas = schemasResult.value;\n\n // Calculate import path for types.prebuilt.ts to _internal-injects.ts\n const prebuiltTypesPath = join(outdir, \"types.prebuilt.ts\");\n const injectsModulePath = toImportSpecifier(prebuiltTypesPath, join(outdir, \"_internal-injects.ts\"), importSpecifierOptions);\n\n // Step 3: Build artifact using BuilderService\n const builderService = createBuilderService({\n config,\n });\n\n const artifactResult = await builderService.buildAsync();\n\n if (artifactResult.isErr()) {\n return err(typegenErrors.buildFailed(`Builder failed: ${artifactResult.error.message}`, artifactResult.error));\n }\n\n // Step 4: Extract field selections from intermediate elements\n const intermediateElements = builderService.getIntermediateElements();\n if (!intermediateElements) {\n return err(typegenErrors.buildFailed(\"No intermediate elements available after build\", undefined));\n }\n\n const fieldSelectionsResult = extractFieldSelections(intermediateElements as Record<CanonicalId, IntermediateArtifactElement>);\n const { selections: builderSelections, warnings: extractWarnings } = fieldSelectionsResult;\n\n // Step 4b: Scan source files for tagged templates and merge selections\n const graphqlHelper = createGraphqlSystemIdentifyHelper(config);\n const scanResult = scanSourceFiles({\n include: [...config.include],\n exclude: [...config.exclude],\n baseDir: config.baseDir,\n helper: graphqlHelper,\n });\n\n const templateSelections = convertTemplatesToSelections(scanResult.templates, schemas);\n\n const fieldSelections = mergeSelections(builderSelections, templateSelections.selections, config.baseDir);\n\n const scanWarnings = [...scanResult.warnings, ...templateSelections.warnings];\n\n // Step 5: Emit types.prebuilt.ts\n const emitResult = await emitPrebuiltTypes({\n schemas,\n fieldSelections,\n outdir,\n injectsModulePath,\n });\n\n if (emitResult.isErr()) {\n return err(emitResult.error);\n }\n\n const { warnings: emitWarnings, skippedFragmentCount } = emitResult.value;\n\n // Count fragments and operations\n let fragmentCount = 0;\n let operationCount = 0;\n for (const selection of fieldSelections.values()) {\n if (selection.type === \"fragment\" && selection.key) {\n fragmentCount++;\n } else if (selection.type === \"operation\") {\n operationCount++;\n }\n }\n\n const allWarnings = [...extractWarnings, ...scanWarnings, ...emitWarnings];\n\n return ok({\n prebuiltTypesPath,\n fragmentCount,\n operationCount,\n skippedFragmentCount,\n warnings: allWarnings,\n } satisfies TypegenSuccess);\n};\n\nconst extractElementName = (data: FieldSelectionData): string | undefined =>\n data.type === \"fragment\" ? data.key : data.operationName;\n\n/**\n * Merge builder and template selections into a combined map.\n *\n * Builder selections are authoritative — VM evaluation correctly resolves\n * fragment spreads that static template analysis cannot handle.\n * Template selections serve as fallback for elements only found by the scanner.\n *\n * Deduplication is per-element (file + GraphQL name), not per-file, so that\n * callback-builder operations in files that also contain tagged templates are preserved.\n */\nexport const mergeSelections = (\n builderSelections: ReadonlyMap<CanonicalId, FieldSelectionData>,\n templateSelections: ReadonlyMap<CanonicalId, FieldSelectionData>,\n baseDir: string,\n): Map<CanonicalId, FieldSelectionData> => {\n // Builder uses relative paths (e.g. \"src/foo.ts::varName\"), template scanner uses\n // absolute paths (e.g. \"/abs/path/src/foo.ts::FragmentName\"). Normalize to relative.\n const extractFilePart = (id: string): string => {\n const filePart = id.split(\"::\")[0] ?? \"\";\n if (filePart.startsWith(\"/\")) {\n return relative(baseDir, filePart);\n }\n return filePart;\n };\n\n // Build set of (file, elementName) pairs from builder selections\n const builderElements = new Set<string>();\n for (const [id, data] of builderSelections) {\n const name = extractElementName(data);\n if (name) builderElements.add(`${extractFilePart(id)}::${name}`);\n }\n\n const fieldSelections = new Map<CanonicalId, FieldSelectionData>();\n // Builder selections first (authoritative)\n for (const [id, data] of builderSelections) {\n fieldSelections.set(id, data);\n }\n // Template selections as fallback for elements not found by builder\n for (const [id, data] of templateSelections) {\n const name = extractElementName(data);\n if (name && builderElements.has(`${extractFilePart(id)}::${name}`)) continue;\n fieldSelections.set(id, data);\n }\n\n return fieldSelections;\n};\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { BuilderError, FieldSelectionsMap } from "@soda-gql/builder";
|
|
1
|
+
import { BuilderError, FieldSelectionData, FieldSelectionsMap } from "@soda-gql/builder";
|
|
2
2
|
import { AnyGraphqlSchema } from "@soda-gql/core";
|
|
3
3
|
import { Result } from "neverthrow";
|
|
4
|
+
import { CanonicalId } from "@soda-gql/common";
|
|
4
5
|
import { ResolvedSodaGqlConfig } from "@soda-gql/config";
|
|
5
6
|
|
|
6
7
|
//#region packages/typegen/src/errors.d.ts
|
|
@@ -75,6 +76,7 @@ type PrebuiltTypesEmitterOptions = {
|
|
|
75
76
|
type PrebuiltTypesEmitResult = {
|
|
76
77
|
readonly path: string;
|
|
77
78
|
readonly warnings: readonly string[];
|
|
79
|
+
readonly skippedFragmentCount: number;
|
|
78
80
|
};
|
|
79
81
|
/**
|
|
80
82
|
* Emit prebuilt types to the types.prebuilt.ts file.
|
|
@@ -149,6 +151,10 @@ type TypegenSuccess = {
|
|
|
149
151
|
* Number of operations processed.
|
|
150
152
|
*/
|
|
151
153
|
readonly operationCount: number;
|
|
154
|
+
/**
|
|
155
|
+
* Number of fragments skipped due to missing 'key' property.
|
|
156
|
+
*/
|
|
157
|
+
readonly skippedFragmentCount: number;
|
|
152
158
|
/**
|
|
153
159
|
* Warnings encountered during type generation.
|
|
154
160
|
*/
|
|
@@ -183,6 +189,17 @@ type RunTypegenOptions = {
|
|
|
183
189
|
* @returns Result containing success data or error
|
|
184
190
|
*/
|
|
185
191
|
declare const runTypegen: (options: RunTypegenOptions) => Promise<TypegenResult>;
|
|
192
|
+
/**
|
|
193
|
+
* Merge builder and template selections into a combined map.
|
|
194
|
+
*
|
|
195
|
+
* Builder selections are authoritative — VM evaluation correctly resolves
|
|
196
|
+
* fragment spreads that static template analysis cannot handle.
|
|
197
|
+
* Template selections serve as fallback for elements only found by the scanner.
|
|
198
|
+
*
|
|
199
|
+
* Deduplication is per-element (file + GraphQL name), not per-file, so that
|
|
200
|
+
* callback-builder operations in files that also contain tagged templates are preserved.
|
|
201
|
+
*/
|
|
202
|
+
declare const mergeSelections: (builderSelections: ReadonlyMap<CanonicalId, FieldSelectionData>, templateSelections: ReadonlyMap<CanonicalId, FieldSelectionData>, baseDir: string) => Map<CanonicalId, FieldSelectionData>;
|
|
186
203
|
//#endregion
|
|
187
204
|
export { type PrebuiltTypesEmitResult, type PrebuiltTypesEmitterOptions, type RunTypegenOptions, type TypegenError, type TypegenErrorCode, type TypegenOptions, type TypegenResult, type TypegenSpecificError, type TypegenSuccess, emitPrebuiltTypes, formatTypegenError, runTypegen, typegenErrors };
|
|
188
205
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors.ts","../src/emitter.ts","../src/types.ts","../src/runner.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors.ts","../src/emitter.ts","../src/types.ts","../src/runner.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { BuilderError, FieldSelectionsMap } from "@soda-gql/builder";
|
|
1
|
+
import { BuilderError, FieldSelectionData, FieldSelectionsMap } from "@soda-gql/builder";
|
|
2
2
|
import { AnyGraphqlSchema } from "@soda-gql/core";
|
|
3
3
|
import { Result } from "neverthrow";
|
|
4
|
+
import { CanonicalId } from "@soda-gql/common";
|
|
4
5
|
import { ResolvedSodaGqlConfig } from "@soda-gql/config";
|
|
5
6
|
|
|
6
7
|
//#region packages/typegen/src/errors.d.ts
|
|
@@ -75,6 +76,7 @@ type PrebuiltTypesEmitterOptions = {
|
|
|
75
76
|
type PrebuiltTypesEmitResult = {
|
|
76
77
|
readonly path: string;
|
|
77
78
|
readonly warnings: readonly string[];
|
|
79
|
+
readonly skippedFragmentCount: number;
|
|
78
80
|
};
|
|
79
81
|
/**
|
|
80
82
|
* Emit prebuilt types to the types.prebuilt.ts file.
|
|
@@ -149,6 +151,10 @@ type TypegenSuccess = {
|
|
|
149
151
|
* Number of operations processed.
|
|
150
152
|
*/
|
|
151
153
|
readonly operationCount: number;
|
|
154
|
+
/**
|
|
155
|
+
* Number of fragments skipped due to missing 'key' property.
|
|
156
|
+
*/
|
|
157
|
+
readonly skippedFragmentCount: number;
|
|
152
158
|
/**
|
|
153
159
|
* Warnings encountered during type generation.
|
|
154
160
|
*/
|
|
@@ -183,6 +189,17 @@ type RunTypegenOptions = {
|
|
|
183
189
|
* @returns Result containing success data or error
|
|
184
190
|
*/
|
|
185
191
|
declare const runTypegen: (options: RunTypegenOptions) => Promise<TypegenResult>;
|
|
192
|
+
/**
|
|
193
|
+
* Merge builder and template selections into a combined map.
|
|
194
|
+
*
|
|
195
|
+
* Builder selections are authoritative — VM evaluation correctly resolves
|
|
196
|
+
* fragment spreads that static template analysis cannot handle.
|
|
197
|
+
* Template selections serve as fallback for elements only found by the scanner.
|
|
198
|
+
*
|
|
199
|
+
* Deduplication is per-element (file + GraphQL name), not per-file, so that
|
|
200
|
+
* callback-builder operations in files that also contain tagged templates are preserved.
|
|
201
|
+
*/
|
|
202
|
+
declare const mergeSelections: (builderSelections: ReadonlyMap<CanonicalId, FieldSelectionData>, templateSelections: ReadonlyMap<CanonicalId, FieldSelectionData>, baseDir: string) => Map<CanonicalId, FieldSelectionData>;
|
|
186
203
|
//#endregion
|
|
187
204
|
export { type PrebuiltTypesEmitResult, type PrebuiltTypesEmitterOptions, type RunTypegenOptions, type TypegenError, type TypegenErrorCode, type TypegenOptions, type TypegenResult, type TypegenSpecificError, type TypegenSuccess, emitPrebuiltTypes, formatTypegenError, runTypegen, typegenErrors };
|
|
188
205
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/errors.ts","../src/emitter.ts","../src/types.ts","../src/runner.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/errors.ts","../src/emitter.ts","../src/types.ts","../src/runner.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -46,6 +46,7 @@ import { parseSync } from "@swc/core";
|
|
|
46
46
|
const groupBySchema = (fieldSelections, schemas) => {
|
|
47
47
|
const grouped = new Map();
|
|
48
48
|
const warnings = [];
|
|
49
|
+
let skippedFragmentCount = 0;
|
|
49
50
|
for (const schemaName of Object.keys(schemas)) {
|
|
50
51
|
grouped.set(schemaName, {
|
|
51
52
|
fragments: [],
|
|
@@ -67,7 +68,8 @@ const groupBySchema = (fieldSelections, schemas) => {
|
|
|
67
68
|
};
|
|
68
69
|
if (selection.type === "fragment") {
|
|
69
70
|
if (!selection.key) {
|
|
70
|
-
|
|
71
|
+
skippedFragmentCount++;
|
|
72
|
+
warnings.push(`[prebuilt] Fragment "${canonicalId}" skipped: missing 'key' property. ` + `Use tagged template syntax fragment("Name", "Type")\`{ ... }\` to auto-assign a key, ` + `or set 'key' explicitly in the callback builder.`);
|
|
71
73
|
continue;
|
|
72
74
|
}
|
|
73
75
|
try {
|
|
@@ -108,7 +110,8 @@ const groupBySchema = (fieldSelections, schemas) => {
|
|
|
108
110
|
}
|
|
109
111
|
return ok({
|
|
110
112
|
grouped,
|
|
111
|
-
warnings
|
|
113
|
+
warnings,
|
|
114
|
+
skippedFragmentCount
|
|
112
115
|
});
|
|
113
116
|
};
|
|
114
117
|
/**
|
|
@@ -315,14 +318,15 @@ const emitPrebuiltTypes = async (options) => {
|
|
|
315
318
|
if (groupResult.isErr()) {
|
|
316
319
|
return err(groupResult.error);
|
|
317
320
|
}
|
|
318
|
-
const { grouped, warnings } = groupResult.value;
|
|
321
|
+
const { grouped, warnings, skippedFragmentCount } = groupResult.value;
|
|
319
322
|
const code = generateTypesCode(grouped, schemas, injectsModulePath);
|
|
320
323
|
const typesPath = join(outdir, "types.prebuilt.ts");
|
|
321
324
|
try {
|
|
322
325
|
await writeFile(typesPath, code, "utf-8");
|
|
323
326
|
return ok({
|
|
324
327
|
path: typesPath,
|
|
325
|
-
warnings
|
|
328
|
+
warnings,
|
|
329
|
+
skippedFragmentCount
|
|
326
330
|
});
|
|
327
331
|
} catch (error) {
|
|
328
332
|
return err(builderErrors.writeFailed(typesPath, `Failed to write prebuilt types: ${error instanceof Error ? error.message : String(error)}`, error));
|
|
@@ -748,15 +752,38 @@ const filterPlaceholderSpreads = (selectionSet) => ({
|
|
|
748
752
|
return sel;
|
|
749
753
|
})
|
|
750
754
|
});
|
|
755
|
+
/** Simple matching-paren finder for template content (no comments/strings to handle). */
|
|
756
|
+
const findClosingParen = (source, openIndex) => {
|
|
757
|
+
let depth = 0;
|
|
758
|
+
for (let i = openIndex; i < source.length; i++) {
|
|
759
|
+
if (source[i] === "(") depth++;
|
|
760
|
+
else if (source[i] === ")") {
|
|
761
|
+
depth--;
|
|
762
|
+
if (depth === 0) return i;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
return -1;
|
|
766
|
+
};
|
|
751
767
|
/**
|
|
752
768
|
* Reconstruct full GraphQL source from an extracted template.
|
|
753
769
|
* For curried syntax (new), prepends the definition header from tag call arguments.
|
|
770
|
+
* For curried fragments with Fragment Arguments, repositions variable declarations
|
|
771
|
+
* before the on-clause to produce RFC-compliant syntax.
|
|
754
772
|
* For old syntax, returns content as-is.
|
|
755
773
|
*/
|
|
756
774
|
const reconstructGraphql = (template) => {
|
|
757
775
|
if (template.elementName) {
|
|
758
776
|
if (template.kind === "fragment" && template.typeName) {
|
|
759
|
-
|
|
777
|
+
const trimmed = template.content.trim();
|
|
778
|
+
if (trimmed.startsWith("(")) {
|
|
779
|
+
const closeIdx = findClosingParen(trimmed, 0);
|
|
780
|
+
if (closeIdx !== -1) {
|
|
781
|
+
const varDecls = trimmed.slice(0, closeIdx + 1);
|
|
782
|
+
const selectionSet = trimmed.slice(closeIdx + 1).trim();
|
|
783
|
+
return `fragment ${template.elementName}${varDecls} on ${template.typeName} ${selectionSet}`;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
return `fragment ${template.elementName} on ${template.typeName} ${trimmed}`;
|
|
760
787
|
}
|
|
761
788
|
return `${template.kind} ${template.elementName} ${template.content}`;
|
|
762
789
|
}
|
|
@@ -930,28 +957,7 @@ const runTypegen = async (options) => {
|
|
|
930
957
|
helper: graphqlHelper
|
|
931
958
|
});
|
|
932
959
|
const templateSelections = convertTemplatesToSelections(scanResult.templates, schemas);
|
|
933
|
-
const
|
|
934
|
-
const filePart = id.split("::")[0] ?? "";
|
|
935
|
-
if (filePart.startsWith("/")) {
|
|
936
|
-
return relative(config.baseDir, filePart);
|
|
937
|
-
}
|
|
938
|
-
return filePart;
|
|
939
|
-
};
|
|
940
|
-
const extractElementName = (data) => data.type === "fragment" ? data.key : data.operationName;
|
|
941
|
-
const templateElements = new Set();
|
|
942
|
-
for (const [id, data] of templateSelections.selections) {
|
|
943
|
-
const name = extractElementName(data);
|
|
944
|
-
if (name) templateElements.add(`${extractFilePart(id)}::${name}`);
|
|
945
|
-
}
|
|
946
|
-
const fieldSelections = new Map();
|
|
947
|
-
for (const [id, data] of builderSelections) {
|
|
948
|
-
const name = extractElementName(data);
|
|
949
|
-
if (name && templateElements.has(`${extractFilePart(id)}::${name}`)) continue;
|
|
950
|
-
fieldSelections.set(id, data);
|
|
951
|
-
}
|
|
952
|
-
for (const [id, data] of templateSelections.selections) {
|
|
953
|
-
fieldSelections.set(id, data);
|
|
954
|
-
}
|
|
960
|
+
const fieldSelections = mergeSelections(builderSelections, templateSelections.selections, config.baseDir);
|
|
955
961
|
const scanWarnings = [...scanResult.warnings, ...templateSelections.warnings];
|
|
956
962
|
const emitResult = await emitPrebuiltTypes({
|
|
957
963
|
schemas,
|
|
@@ -962,7 +968,7 @@ const runTypegen = async (options) => {
|
|
|
962
968
|
if (emitResult.isErr()) {
|
|
963
969
|
return err(emitResult.error);
|
|
964
970
|
}
|
|
965
|
-
const { warnings: emitWarnings } = emitResult.value;
|
|
971
|
+
const { warnings: emitWarnings, skippedFragmentCount } = emitResult.value;
|
|
966
972
|
let fragmentCount = 0;
|
|
967
973
|
let operationCount = 0;
|
|
968
974
|
for (const selection of fieldSelections.values()) {
|
|
@@ -981,9 +987,45 @@ const runTypegen = async (options) => {
|
|
|
981
987
|
prebuiltTypesPath,
|
|
982
988
|
fragmentCount,
|
|
983
989
|
operationCount,
|
|
990
|
+
skippedFragmentCount,
|
|
984
991
|
warnings: allWarnings
|
|
985
992
|
});
|
|
986
993
|
};
|
|
994
|
+
const extractElementName = (data) => data.type === "fragment" ? data.key : data.operationName;
|
|
995
|
+
/**
|
|
996
|
+
* Merge builder and template selections into a combined map.
|
|
997
|
+
*
|
|
998
|
+
* Builder selections are authoritative — VM evaluation correctly resolves
|
|
999
|
+
* fragment spreads that static template analysis cannot handle.
|
|
1000
|
+
* Template selections serve as fallback for elements only found by the scanner.
|
|
1001
|
+
*
|
|
1002
|
+
* Deduplication is per-element (file + GraphQL name), not per-file, so that
|
|
1003
|
+
* callback-builder operations in files that also contain tagged templates are preserved.
|
|
1004
|
+
*/
|
|
1005
|
+
const mergeSelections = (builderSelections, templateSelections, baseDir) => {
|
|
1006
|
+
const extractFilePart = (id) => {
|
|
1007
|
+
const filePart = id.split("::")[0] ?? "";
|
|
1008
|
+
if (filePart.startsWith("/")) {
|
|
1009
|
+
return relative(baseDir, filePart);
|
|
1010
|
+
}
|
|
1011
|
+
return filePart;
|
|
1012
|
+
};
|
|
1013
|
+
const builderElements = new Set();
|
|
1014
|
+
for (const [id, data] of builderSelections) {
|
|
1015
|
+
const name = extractElementName(data);
|
|
1016
|
+
if (name) builderElements.add(`${extractFilePart(id)}::${name}`);
|
|
1017
|
+
}
|
|
1018
|
+
const fieldSelections = new Map();
|
|
1019
|
+
for (const [id, data] of builderSelections) {
|
|
1020
|
+
fieldSelections.set(id, data);
|
|
1021
|
+
}
|
|
1022
|
+
for (const [id, data] of templateSelections) {
|
|
1023
|
+
const name = extractElementName(data);
|
|
1024
|
+
if (name && builderElements.has(`${extractFilePart(id)}::${name}`)) continue;
|
|
1025
|
+
fieldSelections.set(id, data);
|
|
1026
|
+
}
|
|
1027
|
+
return fieldSelections;
|
|
1028
|
+
};
|
|
987
1029
|
|
|
988
1030
|
//#endregion
|
|
989
1031
|
export { emitPrebuiltTypes, formatTypegenError, runTypegen, typegenErrors };
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["warnings: string[]","outputFormatters: TypeFormatters","inputFormatters: TypeFormatters","lines: string[]","formatters: TypeFormatters","lines: string[]","declaration: ImportDeclaration | null","templates: ExtractedTemplate[]","kind: string","elementName: string | undefined","typeName: string | undefined","content: string","parts: string[]","warnings: string[]","warnings: string[]","warnings: string[]","parseGraphql","extensionMap: Record<string, string>","withPrefix","currentExt"],"sources":["../src/emitter.ts","../src/errors.ts","../src/template-extractor.ts","../src/template-scanner.ts","../src/template-to-selections.ts","../src/runner.ts"],"sourcesContent":["/**\n * Prebuilt types emitter.\n *\n * Generates TypeScript type definitions for PrebuiltTypes registry\n * from field selection data and schema.\n *\n * ## Error Handling Strategy\n *\n * The emitter uses a partial failure approach for type calculation errors:\n *\n * **Recoverable errors** (result in warnings, element skipped):\n * - Type calculation failures (e.g., `calculateFieldsType` throws)\n * - Input type generation failures (e.g., `generateInputType` throws)\n * - These are caught per-element, logged as warnings, and the element is omitted\n *\n * **Fatal errors** (result in error result):\n * - `SCHEMA_NOT_FOUND`: Selection references non-existent schema\n * - `WRITE_FAILED`: Cannot write output file to disk\n *\n * This allows builds to succeed with partial type coverage when some elements\n * have issues, while providing visibility into problems via warnings.\n *\n * @module\n */\n\nimport { writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { type BuilderError, builderErrors, type FieldSelectionsMap } from \"@soda-gql/builder\";\nimport type { AnyGraphqlSchema, InputTypeSpecifiers, TypeFormatters } from \"@soda-gql/core\";\nimport {\n calculateFieldsType,\n generateInputObjectType,\n generateInputType,\n generateInputTypeFromVarDefs,\n parseInputSpecifier,\n} from \"@soda-gql/core\";\nimport { Kind, type TypeNode, type VariableDefinitionNode } from \"graphql\";\nimport { err, ok, type Result } from \"neverthrow\";\nimport type { TypegenError } from \"./errors\";\n\n/**\n * Options for emitting prebuilt types.\n */\nexport type PrebuiltTypesEmitterOptions = {\n /**\n * Schema definitions per schema name.\n * These come from the codegen output.\n */\n readonly schemas: Record<string, AnyGraphqlSchema>;\n /**\n * Field selections extracted from the builder.\n */\n readonly fieldSelections: FieldSelectionsMap;\n /**\n * Output directory (where types.prebuilt.ts should be written).\n * This should be the same as config.outdir.\n */\n readonly outdir: string;\n /**\n * Relative import path to _internal-injects.ts from types.prebuilt.ts.\n * Example: \"./_internal-injects\"\n */\n readonly injectsModulePath: string;\n};\n\ntype PrebuiltFragmentEntry = {\n readonly key: string;\n readonly typename: string;\n readonly inputType: string;\n readonly outputType: string;\n};\n\ntype PrebuiltOperationEntry = {\n readonly key: string;\n readonly inputType: string;\n readonly outputType: string;\n};\n\ntype SchemaGroup = {\n fragments: PrebuiltFragmentEntry[];\n operations: PrebuiltOperationEntry[];\n inputObjects: Set<string>;\n};\n\ntype GroupBySchemaResult = {\n readonly grouped: Map<string, SchemaGroup>;\n readonly warnings: string[];\n};\n\n/**\n * Group field selections by schema.\n * Uses the schemaLabel from each selection to group them correctly.\n *\n * Fragments without a 'key' property are skipped (not included in PrebuiltTypes)\n * and a warning is added. This allows projects to use fragments without keys\n * while still generating prebuilt types for those that have keys.\n *\n * @returns Result containing grouped selections and warnings, or error if schema not found\n */\nconst groupBySchema = (\n fieldSelections: FieldSelectionsMap,\n schemas: Record<string, AnyGraphqlSchema>,\n): Result<GroupBySchemaResult, BuilderError | TypegenError> => {\n const grouped = new Map<string, SchemaGroup>();\n const warnings: string[] = [];\n\n // Initialize groups for each schema\n for (const schemaName of Object.keys(schemas)) {\n grouped.set(schemaName, { fragments: [], operations: [], inputObjects: new Set() });\n }\n\n for (const [canonicalId, selection] of fieldSelections) {\n // Use schemaLabel to determine which schema this selection belongs to\n const schemaName = selection.schemaLabel;\n const schema = schemas[schemaName];\n const group = grouped.get(schemaName);\n\n if (!schema || !group) {\n return err(builderErrors.schemaNotFound(schemaName, canonicalId));\n }\n\n // Create formatters for schema-specific type names\n const outputFormatters: TypeFormatters = {\n scalarOutput: (name) => `ScalarOutput_${schemaName}<\"${name}\">`,\n };\n const inputFormatters: TypeFormatters = {\n scalarInput: (name) => `ScalarInput_${schemaName}<\"${name}\">`,\n inputObject: (name) => `Input_${schemaName}_${name}`,\n };\n\n if (selection.type === \"fragment\") {\n // Skip fragments without keys (they won't be included in PrebuiltTypes)\n if (!selection.key) {\n warnings.push(`[prebuilt] Fragment \"${canonicalId}\" skipped: missing 'key' property`);\n continue;\n }\n\n try {\n // Collect input objects used in fragment variables\n const usedInputObjects = collectUsedInputObjectsFromVarDefs(schema, selection.variableDefinitions);\n for (const inputName of usedInputObjects) {\n group.inputObjects.add(inputName);\n }\n\n // Generate output type with schema-specific scalar names\n const outputType = calculateFieldsType(schema, selection.fields, outputFormatters, selection.typename);\n\n // Generate input type from variableDefinitions with schema-specific names\n const hasVariables = Object.keys(selection.variableDefinitions).length > 0;\n const inputType = hasVariables\n ? generateInputTypeFromVarDefs(schema, selection.variableDefinitions, { formatters: inputFormatters })\n : \"void\";\n\n group.fragments.push({\n key: selection.key,\n typename: selection.typename,\n inputType,\n outputType,\n });\n } catch (error) {\n warnings.push(\n `[prebuilt] Failed to calculate type for fragment \"${selection.key}\": ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n } else if (selection.type === \"operation\") {\n try {\n // Collect input objects used in this operation\n const usedInputObjects = collectUsedInputObjects(schema, selection.variableDefinitions);\n for (const inputName of usedInputObjects) {\n group.inputObjects.add(inputName);\n }\n\n // Generate output type with schema-specific scalar names\n // Get the root type name from schema operations (Query, Mutation, Subscription)\n const rootTypeName = schema.operations[selection.operationType as keyof typeof schema.operations];\n const outputType = calculateFieldsType(schema, selection.fields, outputFormatters, rootTypeName ?? undefined);\n\n // Generate input type with schema-specific scalar and input object names\n const inputType = generateInputType(schema, selection.variableDefinitions, inputFormatters);\n\n group.operations.push({\n key: selection.operationName,\n inputType,\n outputType,\n });\n } catch (error) {\n warnings.push(\n `[prebuilt] Failed to calculate type for operation \"${selection.operationName}\": ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n }\n\n return ok({ grouped, warnings });\n};\n\n/**\n * Extract input object names from a GraphQL TypeNode.\n */\nconst extractInputObjectsFromType = (schema: AnyGraphqlSchema, typeNode: TypeNode, inputObjects: Set<string>): void => {\n switch (typeNode.kind) {\n case Kind.NON_NULL_TYPE:\n extractInputObjectsFromType(schema, typeNode.type, inputObjects);\n break;\n case Kind.LIST_TYPE:\n extractInputObjectsFromType(schema, typeNode.type, inputObjects);\n break;\n case Kind.NAMED_TYPE: {\n const name = typeNode.name.value;\n // Check if it's an input object (not a scalar or enum)\n if (!schema.scalar[name] && !schema.enum[name] && schema.input[name]) {\n inputObjects.add(name);\n }\n break;\n }\n }\n};\n\n/**\n * Recursively collect nested input objects from schema definitions.\n * Takes a set of initial input names and expands to include all nested inputs.\n */\nconst collectNestedInputObjects = (schema: AnyGraphqlSchema, initialInputNames: Set<string>): Set<string> => {\n const inputObjects = new Set(initialInputNames);\n\n const collectNested = (inputName: string, seen: Set<string>): void => {\n if (seen.has(inputName)) {\n return;\n }\n seen.add(inputName);\n\n const inputDef = schema.input[inputName];\n if (!inputDef) {\n return;\n }\n\n for (const fieldSpec of Object.values(inputDef.fields)) {\n const parsed = parseInputSpecifier(fieldSpec);\n if (parsed.kind === \"input\" && !inputObjects.has(parsed.name)) {\n inputObjects.add(parsed.name);\n collectNested(parsed.name, seen);\n }\n }\n };\n\n for (const inputName of Array.from(initialInputNames)) {\n collectNested(inputName, new Set());\n }\n\n return inputObjects;\n};\n\n/**\n * Collect all input object types used in variable definitions.\n * Recursively collects nested input objects from the schema.\n */\nconst collectUsedInputObjects = (\n schema: AnyGraphqlSchema,\n variableDefinitions: readonly VariableDefinitionNode[],\n): Set<string> => {\n const directInputs = new Set<string>();\n for (const varDef of variableDefinitions) {\n extractInputObjectsFromType(schema, varDef.type, directInputs);\n }\n return collectNestedInputObjects(schema, directInputs);\n};\n\n/**\n * Collect all input object types used in InputTypeSpecifiers.\n * Recursively collects nested input objects from the schema.\n */\nconst _collectUsedInputObjectsFromSpecifiers = (schema: AnyGraphqlSchema, specifiers: InputTypeSpecifiers): Set<string> => {\n const directInputs = new Set<string>();\n for (const specStr of Object.values(specifiers)) {\n const parsed = parseInputSpecifier(specStr);\n if (parsed.kind === \"input\" && schema.input[parsed.name]) {\n directInputs.add(parsed.name);\n }\n }\n return collectNestedInputObjects(schema, directInputs);\n};\n\n/**\n * Collect all input object types used in VariableDefinitions (VarSpecifier objects).\n * Used for fragment variable definitions.\n */\nconst collectUsedInputObjectsFromVarDefs = (\n schema: AnyGraphqlSchema,\n varDefs: Record<string, { kind: string; name: string }>,\n): Set<string> => {\n const directInputs = new Set<string>();\n for (const varSpec of Object.values(varDefs)) {\n if (varSpec.kind === \"input\" && schema.input[varSpec.name]) {\n directInputs.add(varSpec.name);\n }\n }\n return collectNestedInputObjects(schema, directInputs);\n};\n\n/**\n * Generate type definitions for input objects.\n */\nconst generateInputObjectTypeDefinitions = (schema: AnyGraphqlSchema, schemaName: string, inputNames: Set<string>): string[] => {\n const lines: string[] = [];\n\n // Get depth config from schema (optional properties defined in AnyGraphqlSchema)\n const defaultDepth = schema.__defaultInputDepth ?? 3;\n const depthOverrides = schema.__inputDepthOverrides ?? {};\n\n // Create formatters for schema-specific type names\n const formatters: TypeFormatters = {\n scalarInput: (name) => `ScalarInput_${schemaName}<\"${name}\">`,\n inputObject: (name) => `Input_${schemaName}_${name}`,\n };\n\n // Sort for deterministic output\n const sortedNames = Array.from(inputNames).sort();\n\n for (const inputName of sortedNames) {\n const typeString = generateInputObjectType(schema, inputName, {\n defaultDepth,\n depthOverrides,\n formatters,\n });\n\n lines.push(`export type Input_${schemaName}_${inputName} = ${typeString};`);\n }\n\n return lines;\n};\n\n/**\n * Generate the TypeScript code for prebuilt types.\n */\nconst generateTypesCode = (\n grouped: Map<string, SchemaGroup>,\n schemas: Record<string, AnyGraphqlSchema>,\n injectsModulePath: string,\n): string => {\n const schemaNames = Object.keys(schemas);\n\n const lines: string[] = [\n \"/**\",\n \" * Prebuilt type registry.\",\n \" *\",\n \" * This file is auto-generated by @soda-gql/typegen.\",\n \" * Do not edit manually.\",\n \" *\",\n \" * @module\",\n \" * @generated\",\n \" */\",\n \"\",\n 'import type { AssertExtends, PrebuiltTypeRegistry } from \"@soda-gql/core\";',\n ];\n\n // Generate import from _internal-injects.ts\n const scalarImports = schemaNames.map((name) => `scalar_${name}`).join(\", \");\n lines.push(`import type { ${scalarImports} } from \"${injectsModulePath}\";`);\n\n lines.push(\"\");\n\n // Generate ScalarInput and ScalarOutput helper types\n for (const schemaName of schemaNames) {\n lines.push(\n `type ScalarInput_${schemaName}<T extends keyof typeof scalar_${schemaName}> = ` +\n `typeof scalar_${schemaName}[T][\"$type\"][\"input\"];`,\n );\n lines.push(\n `type ScalarOutput_${schemaName}<T extends keyof typeof scalar_${schemaName}> = ` +\n `typeof scalar_${schemaName}[T][\"$type\"][\"output\"];`,\n );\n }\n\n lines.push(\"\");\n\n for (const [schemaName, { fragments, operations, inputObjects }] of grouped) {\n const schema = schemas[schemaName];\n\n // Generate input object type definitions if there are any\n if (inputObjects.size > 0 && schema) {\n lines.push(\"// Input object types\");\n const inputTypeLines = generateInputObjectTypeDefinitions(schema, schemaName, inputObjects);\n lines.push(...inputTypeLines);\n lines.push(\"\");\n }\n\n // Generate fragments type (deduplicate by key — last occurrence wins)\n const deduplicatedFragments = new Map<string, PrebuiltFragmentEntry>();\n for (const f of fragments) {\n deduplicatedFragments.set(f.key, f);\n }\n const fragmentEntries = Array.from(deduplicatedFragments.values())\n .sort((a, b) => a.key.localeCompare(b.key))\n .map(\n (f) =>\n ` readonly \"${f.key}\": { readonly typename: \"${f.typename}\"; readonly input: ${f.inputType}; readonly output: ${f.outputType} };`,\n );\n\n // Generate operations type (deduplicate by key — last occurrence wins)\n const deduplicatedOperations = new Map<string, PrebuiltOperationEntry>();\n for (const o of operations) {\n deduplicatedOperations.set(o.key, o);\n }\n const operationEntries = Array.from(deduplicatedOperations.values())\n .sort((a, b) => a.key.localeCompare(b.key))\n .map((o) => ` readonly \"${o.key}\": { readonly input: ${o.inputType}; readonly output: ${o.outputType} };`);\n\n lines.push(`export type PrebuiltTypes_${schemaName} = {`);\n lines.push(\" readonly fragments: {\");\n if (fragmentEntries.length > 0) {\n lines.push(...fragmentEntries);\n }\n lines.push(\" };\");\n lines.push(\" readonly operations: {\");\n if (operationEntries.length > 0) {\n lines.push(...operationEntries);\n }\n lines.push(\" };\");\n lines.push(\"};\");\n lines.push(`type _AssertPrebuiltTypes_${schemaName} = AssertExtends<PrebuiltTypes_${schemaName}, PrebuiltTypeRegistry>;`);\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n};\n\n/**\n * Result of emitting prebuilt types.\n */\nexport type PrebuiltTypesEmitResult = {\n readonly path: string;\n readonly warnings: readonly string[];\n};\n\n/**\n * Emit prebuilt types to the types.prebuilt.ts file.\n *\n * This function uses a partial failure strategy: if type calculation fails for\n * individual elements (e.g., due to invalid field selections or missing schema\n * types), those elements are skipped and warnings are collected rather than\n * failing the entire emission. This allows builds to succeed even when some\n * elements have issues, while still reporting problems via warnings.\n *\n * @param options - Emitter options including schemas, field selections, and output directory\n * @returns Result containing output path and warnings, or error if a hard failure occurs\n *\n * @example\n * ```typescript\n * const result = await emitPrebuiltTypes({\n * schemas: { mySchema: schema },\n * fieldSelections,\n * outdir: \"./generated\",\n * injects: { mySchema: { scalars: \"./scalars.ts\" } },\n * });\n *\n * if (result.isOk()) {\n * console.log(`Generated: ${result.value.path}`);\n * if (result.value.warnings.length > 0) {\n * console.warn(\"Warnings:\", result.value.warnings);\n * }\n * }\n * ```\n */\nexport const emitPrebuiltTypes = async (\n options: PrebuiltTypesEmitterOptions,\n): Promise<Result<PrebuiltTypesEmitResult, BuilderError | TypegenError>> => {\n const { schemas, fieldSelections, outdir, injectsModulePath } = options;\n\n // Group selections by schema\n const groupResult = groupBySchema(fieldSelections, schemas);\n if (groupResult.isErr()) {\n return err(groupResult.error);\n }\n const { grouped, warnings } = groupResult.value;\n\n // Generate the types code\n const code = generateTypesCode(grouped, schemas, injectsModulePath);\n\n // Write to types.prebuilt.ts\n const typesPath = join(outdir, \"types.prebuilt.ts\");\n\n try {\n await writeFile(typesPath, code, \"utf-8\");\n return ok({ path: typesPath, warnings });\n } catch (error) {\n return err(\n builderErrors.writeFailed(\n typesPath,\n `Failed to write prebuilt types: ${error instanceof Error ? error.message : String(error)}`,\n error,\n ),\n );\n }\n};\n","/**\n * Error types for typegen package.\n *\n * @module\n */\n\nimport type { BuilderError } from \"@soda-gql/builder\";\n\n/**\n * Error codes specific to typegen operations.\n */\nexport type TypegenErrorCode = \"TYPEGEN_CODEGEN_REQUIRED\" | \"TYPEGEN_SCHEMA_LOAD_FAILED\" | \"TYPEGEN_BUILD_FAILED\";\n\n/**\n * Typegen-specific error type.\n */\nexport type TypegenSpecificError =\n | {\n readonly code: \"TYPEGEN_CODEGEN_REQUIRED\";\n readonly message: string;\n readonly outdir: string;\n }\n | {\n readonly code: \"TYPEGEN_SCHEMA_LOAD_FAILED\";\n readonly message: string;\n readonly schemaNames: readonly string[];\n readonly cause?: unknown;\n }\n | {\n readonly code: \"TYPEGEN_BUILD_FAILED\";\n readonly message: string;\n readonly cause?: unknown;\n };\n\n/**\n * Union of all typegen errors (specific + builder errors).\n */\nexport type TypegenError = TypegenSpecificError | BuilderError;\n\n/**\n * Error constructor helpers for concise error creation.\n */\nexport const typegenErrors = {\n codegenRequired: (outdir: string): TypegenSpecificError => ({\n code: \"TYPEGEN_CODEGEN_REQUIRED\",\n message: `Generated graphql-system module not found at '${outdir}'. Run 'soda-gql codegen' first.`,\n outdir,\n }),\n\n schemaLoadFailed: (schemaNames: readonly string[], cause?: unknown): TypegenSpecificError => ({\n code: \"TYPEGEN_SCHEMA_LOAD_FAILED\",\n message: `Failed to load schemas: ${schemaNames.join(\", \")}`,\n schemaNames,\n cause,\n }),\n\n buildFailed: (message: string, cause?: unknown): TypegenSpecificError => ({\n code: \"TYPEGEN_BUILD_FAILED\",\n message,\n cause,\n }),\n} as const;\n\n/**\n * Format TypegenError for console output (human-readable).\n */\nexport const formatTypegenError = (error: TypegenError): string => {\n const lines: string[] = [];\n\n lines.push(`Error [${error.code}]: ${error.message}`);\n\n switch (error.code) {\n case \"TYPEGEN_CODEGEN_REQUIRED\":\n lines.push(` Output directory: ${error.outdir}`);\n lines.push(\" Hint: Run 'soda-gql codegen' to generate the graphql-system module first.\");\n break;\n case \"TYPEGEN_SCHEMA_LOAD_FAILED\":\n lines.push(` Schemas: ${error.schemaNames.join(\", \")}`);\n break;\n }\n\n if (\"cause\" in error && error.cause) {\n lines.push(` Caused by: ${error.cause}`);\n }\n\n return lines.join(\"\\n\");\n};\n","/**\n * Template extractor for typegen.\n *\n * Extracts tagged template GraphQL content from TypeScript source files\n * using SWC parsing. Adapted from the LSP document-manager pattern\n * but simplified for batch extraction (no position tracking, no state management).\n *\n * @module\n */\n\nimport type { GraphqlSystemIdentifyHelper } from \"@soda-gql/builder\";\n\nimport { parseSync } from \"@swc/core\";\nimport type {\n ArrowFunctionExpression,\n CallExpression,\n ImportDeclaration,\n MemberExpression,\n Module,\n Node,\n TaggedTemplateExpression,\n} from \"@swc/types\";\n\n/** Operation kind extracted from tagged template tag name. */\nexport type OperationKind = \"query\" | \"mutation\" | \"subscription\" | \"fragment\";\n\n/** A single tagged template extracted from a TypeScript source file. */\nexport type ExtractedTemplate = {\n /** Resolved schema name from gql.{schemaName}. */\n readonly schemaName: string;\n /** Operation kind from tag name. */\n readonly kind: OperationKind;\n /** Raw GraphQL content between backticks (may contain __FRAG_SPREAD_N__ placeholders). */\n readonly content: string;\n /** Element name from curried tag call (e.g., \"GetUser\" from query(\"GetUser\")). */\n readonly elementName?: string;\n /** Type name from curried fragment call (e.g., \"User\" from fragment(\"UserFields\", \"User\")). */\n readonly typeName?: string;\n};\n\n/** Result of extracting templates from a source file. */\nexport type ExtractionResult = {\n readonly templates: readonly ExtractedTemplate[];\n readonly warnings: readonly string[];\n};\n\nconst OPERATION_KINDS = new Set<string>([\"query\", \"mutation\", \"subscription\", \"fragment\"]);\n\nconst isOperationKind = (value: string): value is OperationKind => OPERATION_KINDS.has(value);\n\n/**\n * Parse TypeScript source with SWC, returning null on failure.\n */\nconst safeParseSync = (source: string, tsx: boolean): ReturnType<typeof parseSync> | null => {\n try {\n return parseSync(source, {\n syntax: \"typescript\",\n tsx,\n decorators: false,\n dynamicImport: true,\n });\n } catch {\n return null;\n }\n};\n\n/**\n * Collect gql identifiers from import declarations.\n * Finds imports like `import { gql } from \"./graphql-system\"`.\n */\nconst collectGqlIdentifiers = (module: Module, filePath: string, helper: GraphqlSystemIdentifyHelper): ReadonlySet<string> => {\n const identifiers = new Set<string>();\n\n for (const item of module.body) {\n let declaration: ImportDeclaration | null = null;\n\n if (item.type === \"ImportDeclaration\") {\n declaration = item;\n } else if (\n \"declaration\" in item &&\n item.declaration &&\n // biome-ignore lint/suspicious/noExplicitAny: SWC AST type checking\n (item.declaration as any).type === \"ImportDeclaration\"\n ) {\n declaration = item.declaration as unknown as ImportDeclaration;\n }\n\n if (!declaration) {\n continue;\n }\n\n if (!helper.isGraphqlSystemImportSpecifier({ filePath, specifier: declaration.source.value })) {\n continue;\n }\n\n for (const specifier of declaration.specifiers ?? []) {\n if (specifier.type === \"ImportSpecifier\") {\n const imported = specifier.imported ? specifier.imported.value : specifier.local.value;\n if (imported === \"gql\" && !specifier.imported) {\n identifiers.add(specifier.local.value);\n }\n }\n }\n }\n\n return identifiers;\n};\n\n/**\n * Check if a call expression is a gql.{schemaName}(...) call.\n * Returns the schema name if it is, null otherwise.\n */\nconst getGqlCallSchemaName = (identifiers: ReadonlySet<string>, call: CallExpression): string | null => {\n const callee = call.callee;\n if (callee.type !== \"MemberExpression\") {\n return null;\n }\n\n const member = callee as MemberExpression;\n if (member.object.type !== \"Identifier\" || !identifiers.has(member.object.value)) {\n return null;\n }\n\n if (member.property.type !== \"Identifier\") {\n return null;\n }\n\n const firstArg = call.arguments[0];\n if (!firstArg?.expression || firstArg.expression.type !== \"ArrowFunctionExpression\") {\n return null;\n }\n\n return member.property.value;\n};\n\n/**\n * Extract templates from a gql callback's arrow function body.\n * Handles both expression bodies and block bodies with return statements.\n */\nconst extractTemplatesFromCallback = (arrow: ArrowFunctionExpression, schemaName: string): ExtractedTemplate[] => {\n const templates: ExtractedTemplate[] = [];\n\n const processExpression = (expr: Node): void => {\n // Direct tagged template: query(\"Name\")`...`\n if (expr.type === \"TaggedTemplateExpression\") {\n const tagged = expr as unknown as TaggedTemplateExpression;\n extractFromTaggedTemplate(tagged, schemaName, templates);\n return;\n }\n\n // Metadata chaining: query(\"Name\")`...`({ metadata: {} })\n if (expr.type === \"CallExpression\") {\n const call = expr as unknown as CallExpression;\n if (call.callee.type === \"TaggedTemplateExpression\") {\n extractFromTaggedTemplate(call.callee as TaggedTemplateExpression, schemaName, templates);\n }\n }\n };\n\n // Expression body: ({ query }) => query(\"Name\")`...`\n if (arrow.body.type !== \"BlockStatement\") {\n processExpression(arrow.body);\n return templates;\n }\n\n // Block body: ({ query }) => { return query(\"Name\")`...`; }\n for (const stmt of arrow.body.stmts) {\n if (stmt.type === \"ReturnStatement\" && stmt.argument) {\n processExpression(stmt.argument);\n }\n }\n\n return templates;\n};\n\nconst extractFromTaggedTemplate = (\n tagged: TaggedTemplateExpression,\n schemaName: string,\n templates: ExtractedTemplate[],\n): void => {\n // Tag can be:\n // - CallExpression: query(\"name\")`...` or fragment(\"name\", \"type\")`...` (curried syntax)\n // - Identifier: legacy bare-tag form (skipped if it contains interpolations)\n let kind: string;\n let elementName: string | undefined;\n let typeName: string | undefined;\n\n if (tagged.tag.type === \"Identifier\") {\n kind = tagged.tag.value;\n } else if (tagged.tag.type === \"CallExpression\") {\n const tagCall = tagged.tag as CallExpression;\n if (tagCall.callee.type === \"Identifier\") {\n kind = tagCall.callee.value;\n } else {\n return;\n }\n // Extract elementName and typeName from call arguments\n const firstArg = tagCall.arguments[0]?.expression;\n if (firstArg?.type === \"StringLiteral\") {\n elementName = (firstArg as { value: string }).value;\n }\n const secondArg = tagCall.arguments[1]?.expression;\n if (secondArg?.type === \"StringLiteral\") {\n typeName = (secondArg as { value: string }).value;\n }\n } else {\n return;\n }\n\n if (!isOperationKind(kind)) {\n return;\n }\n\n const { quasis, expressions } = tagged.template;\n\n // For legacy Identifier tag, skip templates with interpolations\n // For new syntax (CallExpression tag), handle interpolations with placeholders\n if (tagged.tag.type === \"Identifier\" && expressions.length > 0) {\n return;\n }\n\n if (quasis.length === 0) {\n return;\n }\n\n let content: string;\n if (expressions.length === 0) {\n // No interpolations — simple case\n const quasi = quasis[0];\n if (!quasi) return;\n content = quasi.cooked ?? quasi.raw;\n } else {\n // Build content with placeholder tokens for interpolations\n const parts: string[] = [];\n for (let i = 0; i < quasis.length; i++) {\n const quasi = quasis[i];\n if (!quasi) continue;\n parts.push(quasi.cooked ?? quasi.raw);\n if (i < expressions.length) {\n parts.push(`__FRAG_SPREAD_${i}__`);\n }\n }\n content = parts.join(\"\");\n }\n\n templates.push({\n schemaName,\n kind,\n content,\n ...(elementName !== undefined ? { elementName } : {}),\n ...(typeName !== undefined ? { typeName } : {}),\n });\n};\n\n/**\n * Find the innermost gql call, unwrapping method chains like .attach().\n */\nconst findGqlCall = (identifiers: ReadonlySet<string>, node: Node): CallExpression | null => {\n if (!node || node.type !== \"CallExpression\") {\n return null;\n }\n\n const call = node as unknown as CallExpression;\n if (getGqlCallSchemaName(identifiers, call) !== null) {\n return call;\n }\n\n const callee = call.callee;\n if (callee.type !== \"MemberExpression\") {\n return null;\n }\n\n return findGqlCall(identifiers, callee.object as unknown as Node);\n};\n\n/**\n * Walk AST to find gql calls and extract templates.\n */\nconst walkAndExtract = (node: Node, identifiers: ReadonlySet<string>): ExtractedTemplate[] => {\n const templates: ExtractedTemplate[] = [];\n\n const visit = (n: Node | ReadonlyArray<Node> | Record<string, unknown>): void => {\n if (!n || typeof n !== \"object\") {\n return;\n }\n\n if (\"type\" in n && n.type === \"CallExpression\") {\n const gqlCall = findGqlCall(identifiers, n as Node);\n if (gqlCall) {\n const schemaName = getGqlCallSchemaName(identifiers, gqlCall);\n if (schemaName) {\n const arrow = gqlCall.arguments[0]?.expression as ArrowFunctionExpression;\n templates.push(...extractTemplatesFromCallback(arrow, schemaName));\n }\n return; // Don't recurse into gql calls\n }\n }\n\n // Recurse into all array and object properties\n if (Array.isArray(n)) {\n for (const item of n) {\n visit(item as Node);\n }\n return;\n }\n\n for (const key of Object.keys(n)) {\n if (key === \"span\" || key === \"type\") {\n continue;\n }\n const value = (n as Record<string, unknown>)[key];\n if (value && typeof value === \"object\") {\n visit(value as Node);\n }\n }\n };\n\n visit(node);\n return templates;\n};\n\n/**\n * Extract all tagged templates from a TypeScript source file.\n *\n * @param filePath - Absolute path to the source file (used for import resolution)\n * @param source - TypeScript source code\n * @param helper - GraphQL system identifier for resolving gql imports\n * @returns Extracted templates and any warnings\n */\nexport const extractTemplatesFromSource = (\n filePath: string,\n source: string,\n helper: GraphqlSystemIdentifyHelper,\n): ExtractionResult => {\n const warnings: string[] = [];\n const isTsx = filePath.endsWith(\".tsx\");\n\n const program = safeParseSync(source, isTsx);\n if (!program || program.type !== \"Module\") {\n if (source.includes(\"gql\")) {\n warnings.push(`[typegen-extract] Failed to parse ${filePath}`);\n }\n return { templates: [], warnings };\n }\n\n const gqlIdentifiers = collectGqlIdentifiers(program, filePath, helper);\n if (gqlIdentifiers.size === 0) {\n return { templates: [], warnings };\n }\n\n return { templates: walkAndExtract(program, gqlIdentifiers), warnings };\n};\n","/**\n * Source file scanner for tagged template extraction.\n *\n * Discovers source files from config include/exclude patterns,\n * reads them, and extracts tagged templates using the template extractor.\n *\n * @module\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { normalize, resolve } from \"node:path\";\nimport type { GraphqlSystemIdentifyHelper } from \"@soda-gql/builder\";\nimport fg from \"fast-glob\";\nimport { type ExtractedTemplate, extractTemplatesFromSource } from \"./template-extractor\";\n\nexport type ScanSourceFilesOptions = {\n /** Glob patterns for source files to include. */\n readonly include: readonly string[];\n /** Glob patterns for source files to exclude. */\n readonly exclude: readonly string[];\n /** Base directory for resolving glob patterns. */\n readonly baseDir: string;\n /** Helper for identifying graphql-system imports. */\n readonly helper: GraphqlSystemIdentifyHelper;\n};\n\nexport type ScanResult = {\n /** Templates keyed by file path. */\n readonly templates: ReadonlyMap<string, readonly ExtractedTemplate[]>;\n /** Warnings from scanning. */\n readonly warnings: readonly string[];\n};\n\n/**\n * Scan source files for tagged templates.\n *\n * Uses fast-glob to discover files matching include/exclude patterns,\n * then extracts tagged templates from each file.\n */\nexport const scanSourceFiles = (options: ScanSourceFilesOptions): ScanResult => {\n const { include, exclude, baseDir, helper } = options;\n const warnings: string[] = [];\n\n // Build exclusion patterns\n const ignorePatterns = exclude.map((pattern) => (pattern.startsWith(\"!\") ? pattern.slice(1) : pattern));\n\n // Discover files via fast-glob\n const matchedFiles = fg.sync(include as string[], {\n cwd: baseDir,\n ignore: ignorePatterns,\n onlyFiles: true,\n absolute: true,\n });\n\n const templates = new Map<string, readonly ExtractedTemplate[]>();\n\n for (const filePath of matchedFiles) {\n const normalizedPath = normalize(resolve(filePath)).replace(/\\\\/g, \"/\");\n\n try {\n const source = readFileSync(normalizedPath, \"utf-8\");\n const { templates: extracted, warnings: extractionWarnings } = extractTemplatesFromSource(normalizedPath, source, helper);\n warnings.push(...extractionWarnings);\n\n if (extracted.length > 0) {\n templates.set(normalizedPath, extracted);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n warnings.push(`[typegen-scan] Failed to read ${normalizedPath}: ${message}`);\n }\n }\n\n return { templates, warnings };\n};\n","/**\n * Converts extracted tagged template GraphQL content into FieldSelectionData.\n *\n * Takes the output of template-extractor and produces FieldSelectionData entries\n * compatible with the emitter pipeline. Uses the shared field-building utilities\n * from core to produce AnyFieldsExtended from GraphQL AST.\n *\n * @module\n */\n\nimport type { FieldSelectionData, FieldSelectionsMap } from \"@soda-gql/builder\";\nimport type { CanonicalId } from \"@soda-gql/common\";\nimport {\n type AnyGraphqlSchema,\n buildFieldsFromSelectionSet,\n createSchemaIndexFromSchema,\n extractFragmentVariables,\n preprocessFragmentArgs,\n} from \"@soda-gql/core\";\nimport { Kind, parse as parseGraphql, type SelectionSetNode } from \"graphql\";\nimport type { ExtractedTemplate } from \"./template-extractor\";\n\n/** Result of converting templates to field selections. */\nexport type TemplateConversionResult = {\n readonly selections: FieldSelectionsMap;\n readonly warnings: readonly string[];\n};\n\n/**\n * Convert extracted templates into field selections for the emitter.\n *\n * @param templates - Templates extracted from source files, keyed by file path\n * @param schemas - Loaded schema objects keyed by schema name\n * @returns Map of canonical IDs to field selection data, plus any warnings\n */\nexport const convertTemplatesToSelections = (\n templates: ReadonlyMap<string, readonly ExtractedTemplate[]>,\n schemas: Record<string, AnyGraphqlSchema>,\n): TemplateConversionResult => {\n const selections = new Map<CanonicalId, FieldSelectionData>();\n const warnings: string[] = [];\n\n // Build schema indexes once per schema\n const schemaIndexes = new Map(Object.entries(schemas).map(([name, schema]) => [name, createSchemaIndexFromSchema(schema)]));\n\n for (const [filePath, fileTemplates] of templates) {\n for (const template of fileTemplates) {\n const schema = schemas[template.schemaName];\n if (!schema) {\n warnings.push(`[typegen-template] Unknown schema \"${template.schemaName}\" in ${filePath}`);\n continue;\n }\n\n const schemaIndex = schemaIndexes.get(template.schemaName);\n if (!schemaIndex) {\n continue;\n }\n\n try {\n if (template.kind === \"fragment\") {\n const selection = convertFragmentTemplate(template, schema, filePath);\n if (selection) {\n selections.set(selection.id, selection.data);\n }\n } else {\n const selection = convertOperationTemplate(template, schema, filePath);\n if (selection) {\n selections.set(selection.id, selection.data);\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n warnings.push(`[typegen-template] Failed to process ${template.kind} in ${filePath}: ${message}`);\n }\n }\n }\n\n return { selections, warnings };\n};\n\n/**\n * Recursively filter out __FRAG_SPREAD_ placeholder nodes from a selection set.\n * These placeholders are created by template-extractor for interpolated fragment references.\n * buildFieldsFromSelectionSet would throw on them since no interpolationMap is available.\n */\nconst filterPlaceholderSpreads = (selectionSet: SelectionSetNode): SelectionSetNode => ({\n ...selectionSet,\n selections: selectionSet.selections\n .filter((sel) => !(sel.kind === Kind.FRAGMENT_SPREAD && sel.name.value.startsWith(\"__FRAG_SPREAD_\")))\n .map((sel) => {\n if (sel.kind === Kind.FIELD && sel.selectionSet) {\n return { ...sel, selectionSet: filterPlaceholderSpreads(sel.selectionSet) };\n }\n if (sel.kind === Kind.INLINE_FRAGMENT && sel.selectionSet) {\n return { ...sel, selectionSet: filterPlaceholderSpreads(sel.selectionSet) };\n }\n return sel;\n }),\n});\n\n/**\n * Reconstruct full GraphQL source from an extracted template.\n * For curried syntax (new), prepends the definition header from tag call arguments.\n * For old syntax, returns content as-is.\n */\nconst reconstructGraphql = (template: ExtractedTemplate): string => {\n if (template.elementName) {\n if (template.kind === \"fragment\" && template.typeName) {\n return `fragment ${template.elementName} on ${template.typeName} ${template.content}`;\n }\n return `${template.kind} ${template.elementName} ${template.content}`;\n }\n return template.content;\n};\n\n/**\n * Convert a fragment template into FieldSelectionData.\n */\nconst convertFragmentTemplate = (\n template: ExtractedTemplate,\n schema: AnyGraphqlSchema,\n filePath: string,\n): { id: CanonicalId; data: FieldSelectionData } | null => {\n const schemaIndex = createSchemaIndexFromSchema(schema);\n const graphqlSource = reconstructGraphql(template);\n\n // Extract variable definitions from Fragment Arguments syntax\n const variableDefinitions = extractFragmentVariables(graphqlSource, schemaIndex);\n\n // Preprocess to strip Fragment Arguments\n const { preprocessed } = preprocessFragmentArgs(graphqlSource);\n\n const document = parseGraphql(preprocessed);\n const fragDef = document.definitions.find((d) => d.kind === Kind.FRAGMENT_DEFINITION);\n if (!fragDef || fragDef.kind !== Kind.FRAGMENT_DEFINITION) {\n return null;\n }\n\n const fragmentName = fragDef.name.value;\n const onType = fragDef.typeCondition.name.value;\n\n // Build fields from selection set (filter placeholder spreads from interpolated fragments)\n const fields = buildFieldsFromSelectionSet(filterPlaceholderSpreads(fragDef.selectionSet), schema, onType);\n\n // Generate a canonical ID from file path + fragment name\n const id = `${filePath}::${fragmentName}` as CanonicalId;\n\n return {\n id,\n data: {\n type: \"fragment\",\n schemaLabel: schema.label,\n key: fragmentName,\n typename: onType,\n fields,\n variableDefinitions,\n },\n };\n};\n\n/**\n * Convert an operation template into FieldSelectionData.\n */\nconst convertOperationTemplate = (\n template: ExtractedTemplate,\n schema: AnyGraphqlSchema,\n filePath: string,\n): { id: CanonicalId; data: FieldSelectionData } | null => {\n const graphqlSource = reconstructGraphql(template);\n const document = parseGraphql(graphqlSource);\n const opDef = document.definitions.find((d) => d.kind === Kind.OPERATION_DEFINITION);\n if (!opDef || opDef.kind !== Kind.OPERATION_DEFINITION) {\n return null;\n }\n\n const operationName = opDef.name?.value ?? \"Anonymous\";\n const operationType = opDef.operation;\n\n // Determine root type name based on operation type\n const rootTypeName = getRootTypeName(schema, operationType);\n\n // Build fields from selection set (filter placeholder spreads from interpolated fragments)\n const fields = buildFieldsFromSelectionSet(filterPlaceholderSpreads(opDef.selectionSet), schema, rootTypeName);\n\n // Variable definitions from the operation AST\n const variableDefinitions = opDef.variableDefinitions ?? [];\n\n // Generate a canonical ID from file path + operation name\n const id = `${filePath}::${operationName}` as CanonicalId;\n\n return {\n id,\n data: {\n type: \"operation\",\n schemaLabel: schema.label,\n operationName,\n operationType,\n fields,\n variableDefinitions: [...variableDefinitions],\n },\n };\n};\n\n/**\n * Get the root type name for an operation type from the schema.\n */\nconst getRootTypeName = (schema: AnyGraphqlSchema, operationType: string): string => {\n switch (operationType) {\n case \"query\":\n return schema.operations.query ?? \"Query\";\n case \"mutation\":\n return schema.operations.mutation ?? \"Mutation\";\n case \"subscription\":\n return schema.operations.subscription ?? \"Subscription\";\n default:\n return \"Query\";\n }\n};\n","/**\n * Main typegen runner.\n *\n * Orchestrates the prebuilt type generation process:\n * 1. Load schemas from generated CJS bundle\n * 2. Build artifact to evaluate elements\n * 3. Extract field selections from builder\n * 4. Scan source files for tagged templates and merge selections\n * 5. Emit types.prebuilt.ts\n *\n * @module\n */\n\nimport { existsSync } from \"node:fs\";\nimport { dirname, extname, join, relative, resolve } from \"node:path\";\nimport {\n createBuilderService,\n createGraphqlSystemIdentifyHelper,\n extractFieldSelections,\n type FieldSelectionData,\n type IntermediateArtifactElement,\n loadSchemasFromBundle,\n} from \"@soda-gql/builder\";\nimport type { CanonicalId } from \"@soda-gql/common\";\nimport type { ResolvedSodaGqlConfig } from \"@soda-gql/config\";\nimport { err, ok } from \"neverthrow\";\nimport { emitPrebuiltTypes } from \"./emitter\";\nimport { typegenErrors } from \"./errors\";\nimport { scanSourceFiles } from \"./template-scanner\";\nimport { convertTemplatesToSelections } from \"./template-to-selections\";\nimport type { TypegenResult, TypegenSuccess } from \"./types\";\n\n/**\n * Options for running typegen.\n */\nexport type RunTypegenOptions = {\n /**\n * Resolved soda-gql configuration.\n */\n readonly config: ResolvedSodaGqlConfig;\n};\n\nconst extensionMap: Record<string, string> = {\n \".ts\": \".js\",\n \".tsx\": \".js\",\n \".mts\": \".mjs\",\n \".cts\": \".cjs\",\n \".js\": \".js\",\n \".mjs\": \".mjs\",\n \".cjs\": \".cjs\",\n};\n\ntype ImportSpecifierOptions = {\n includeExtension?: boolean;\n};\n\nconst toImportSpecifier = (fromPath: string, targetPath: string, options?: ImportSpecifierOptions): string => {\n const fromDir = dirname(fromPath);\n const normalized = relative(fromDir, targetPath).replace(/\\\\/g, \"/\");\n const sourceExt = extname(targetPath);\n\n // When includeExtension is false (default), strip the extension entirely\n if (!options?.includeExtension) {\n if (normalized.length === 0) {\n return `./${targetPath.slice(0, -sourceExt.length).split(\"/\").pop()}`;\n }\n const withPrefix = normalized.startsWith(\".\") ? normalized : `./${normalized}`;\n const currentExt = extname(withPrefix);\n return currentExt ? withPrefix.slice(0, -currentExt.length) : withPrefix;\n }\n\n // When includeExtension is true, convert to runtime extension\n const runtimeExt = extensionMap[sourceExt] ?? sourceExt;\n\n if (normalized.length === 0) {\n const base = runtimeExt !== sourceExt ? targetPath.slice(0, -sourceExt.length).split(\"/\").pop() : targetPath.split(\"/\").pop();\n return `./${base}${runtimeExt}`;\n }\n\n const withPrefix = normalized.startsWith(\".\") ? normalized : `./${normalized}`;\n if (!runtimeExt) {\n return withPrefix;\n }\n if (withPrefix.endsWith(runtimeExt)) {\n return withPrefix;\n }\n\n const currentExt = extname(withPrefix);\n const withoutExt = currentExt ? withPrefix.slice(0, -currentExt.length) : withPrefix;\n return `${withoutExt}${runtimeExt}`;\n};\n\n/**\n * Run the typegen process.\n *\n * This function:\n * 1. Loads schemas from the generated CJS bundle\n * 2. Creates a BuilderService and builds the artifact\n * 3. Extracts field selections from the artifact\n * 4. Scans source files for tagged templates and merges selections\n * 5. Emits types.prebuilt.ts using emitPrebuiltTypes\n *\n * @param options - Typegen options including config\n * @returns Result containing success data or error\n */\nexport const runTypegen = async (options: RunTypegenOptions): Promise<TypegenResult> => {\n const { config } = options;\n const outdir = resolve(config.outdir);\n const cjsPath = join(outdir, \"index.cjs\");\n const importSpecifierOptions = { includeExtension: config.styles.importExtension };\n\n // Step 1: Check if codegen has been run\n if (!existsSync(cjsPath)) {\n return err(typegenErrors.codegenRequired(outdir));\n }\n\n // Step 2: Load schemas from CJS bundle\n const schemaNames = Object.keys(config.schemas);\n const schemasResult = loadSchemasFromBundle(cjsPath, schemaNames);\n if (schemasResult.isErr()) {\n return err(typegenErrors.schemaLoadFailed(schemaNames, schemasResult.error));\n }\n const schemas = schemasResult.value;\n\n // Calculate import path for types.prebuilt.ts to _internal-injects.ts\n const prebuiltTypesPath = join(outdir, \"types.prebuilt.ts\");\n const injectsModulePath = toImportSpecifier(prebuiltTypesPath, join(outdir, \"_internal-injects.ts\"), importSpecifierOptions);\n\n // Step 3: Build artifact using BuilderService\n const builderService = createBuilderService({\n config,\n });\n\n const artifactResult = await builderService.buildAsync();\n\n if (artifactResult.isErr()) {\n return err(typegenErrors.buildFailed(`Builder failed: ${artifactResult.error.message}`, artifactResult.error));\n }\n\n // Step 4: Extract field selections from intermediate elements\n const intermediateElements = builderService.getIntermediateElements();\n if (!intermediateElements) {\n return err(typegenErrors.buildFailed(\"No intermediate elements available after build\", undefined));\n }\n\n const fieldSelectionsResult = extractFieldSelections(intermediateElements as Record<CanonicalId, IntermediateArtifactElement>);\n const { selections: builderSelections, warnings: extractWarnings } = fieldSelectionsResult;\n\n // Step 4b: Scan source files for tagged templates and merge selections\n const graphqlHelper = createGraphqlSystemIdentifyHelper(config);\n const scanResult = scanSourceFiles({\n include: [...config.include],\n exclude: [...config.exclude],\n baseDir: config.baseDir,\n helper: graphqlHelper,\n });\n\n const templateSelections = convertTemplatesToSelections(scanResult.templates, schemas);\n\n // Merge builder and template selections into a combined map.\n // Template selections are authoritative for elements found by both scanners.\n // Deduplication is per-element (file + GraphQL name), not per-file, so that\n // callback-builder operations in files that also contain tagged templates are preserved.\n // Builder uses relative paths (e.g. \"src/foo.ts::varName\"), template scanner uses\n // absolute paths (e.g. \"/abs/path/src/foo.ts::FragmentName\"). Normalize to relative.\n const extractFilePart = (id: string): string => {\n const filePart = id.split(\"::\")[0] ?? \"\";\n // Normalize absolute paths to relative using baseDir\n if (filePart.startsWith(\"/\")) {\n return relative(config.baseDir, filePart);\n }\n return filePart;\n };\n\n const extractElementName = (data: FieldSelectionData): string | undefined =>\n data.type === \"fragment\" ? data.key : data.operationName;\n\n // Build set of (file, elementName) pairs from template selections\n const templateElements = new Set<string>();\n for (const [id, data] of templateSelections.selections) {\n const name = extractElementName(data);\n if (name) templateElements.add(`${extractFilePart(id)}::${name}`);\n }\n\n const fieldSelections = new Map<CanonicalId, FieldSelectionData>();\n for (const [id, data] of builderSelections) {\n // Only skip builder elements that were also found by the template scanner\n const name = extractElementName(data);\n if (name && templateElements.has(`${extractFilePart(id)}::${name}`)) continue;\n fieldSelections.set(id, data);\n }\n for (const [id, data] of templateSelections.selections) {\n fieldSelections.set(id, data);\n }\n\n const scanWarnings = [...scanResult.warnings, ...templateSelections.warnings];\n\n // Step 5: Emit types.prebuilt.ts\n const emitResult = await emitPrebuiltTypes({\n schemas,\n fieldSelections,\n outdir,\n injectsModulePath,\n });\n\n if (emitResult.isErr()) {\n return err(emitResult.error);\n }\n\n const { warnings: emitWarnings } = emitResult.value;\n\n // Count fragments and operations\n let fragmentCount = 0;\n let operationCount = 0;\n for (const selection of fieldSelections.values()) {\n if (selection.type === \"fragment\" && selection.key) {\n fragmentCount++;\n } else if (selection.type === \"operation\") {\n operationCount++;\n }\n }\n\n const allWarnings = [...extractWarnings, ...scanWarnings, ...emitWarnings];\n\n return ok({\n prebuiltTypesPath,\n fragmentCount,\n operationCount,\n warnings: allWarnings,\n } satisfies TypegenSuccess);\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["warnings: string[]","outputFormatters: TypeFormatters","inputFormatters: TypeFormatters","lines: string[]","formatters: TypeFormatters","lines: string[]","declaration: ImportDeclaration | null","templates: ExtractedTemplate[]","kind: string","elementName: string | undefined","typeName: string | undefined","content: string","parts: string[]","warnings: string[]","warnings: string[]","warnings: string[]","parseGraphql","extensionMap: Record<string, string>","withPrefix","currentExt"],"sources":["../src/emitter.ts","../src/errors.ts","../src/template-extractor.ts","../src/template-scanner.ts","../src/template-to-selections.ts","../src/runner.ts"],"sourcesContent":["/**\n * Prebuilt types emitter.\n *\n * Generates TypeScript type definitions for PrebuiltTypes registry\n * from field selection data and schema.\n *\n * ## Error Handling Strategy\n *\n * The emitter uses a partial failure approach for type calculation errors:\n *\n * **Recoverable errors** (result in warnings, element skipped):\n * - Type calculation failures (e.g., `calculateFieldsType` throws)\n * - Input type generation failures (e.g., `generateInputType` throws)\n * - These are caught per-element, logged as warnings, and the element is omitted\n *\n * **Fatal errors** (result in error result):\n * - `SCHEMA_NOT_FOUND`: Selection references non-existent schema\n * - `WRITE_FAILED`: Cannot write output file to disk\n *\n * This allows builds to succeed with partial type coverage when some elements\n * have issues, while providing visibility into problems via warnings.\n *\n * @module\n */\n\nimport { writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { type BuilderError, builderErrors, type FieldSelectionsMap } from \"@soda-gql/builder\";\nimport type { AnyGraphqlSchema, InputTypeSpecifiers, TypeFormatters } from \"@soda-gql/core\";\nimport {\n calculateFieldsType,\n generateInputObjectType,\n generateInputType,\n generateInputTypeFromVarDefs,\n parseInputSpecifier,\n} from \"@soda-gql/core\";\nimport { Kind, type TypeNode, type VariableDefinitionNode } from \"graphql\";\nimport { err, ok, type Result } from \"neverthrow\";\nimport type { TypegenError } from \"./errors\";\n\n/**\n * Options for emitting prebuilt types.\n */\nexport type PrebuiltTypesEmitterOptions = {\n /**\n * Schema definitions per schema name.\n * These come from the codegen output.\n */\n readonly schemas: Record<string, AnyGraphqlSchema>;\n /**\n * Field selections extracted from the builder.\n */\n readonly fieldSelections: FieldSelectionsMap;\n /**\n * Output directory (where types.prebuilt.ts should be written).\n * This should be the same as config.outdir.\n */\n readonly outdir: string;\n /**\n * Relative import path to _internal-injects.ts from types.prebuilt.ts.\n * Example: \"./_internal-injects\"\n */\n readonly injectsModulePath: string;\n};\n\ntype PrebuiltFragmentEntry = {\n readonly key: string;\n readonly typename: string;\n readonly inputType: string;\n readonly outputType: string;\n};\n\ntype PrebuiltOperationEntry = {\n readonly key: string;\n readonly inputType: string;\n readonly outputType: string;\n};\n\ntype SchemaGroup = {\n fragments: PrebuiltFragmentEntry[];\n operations: PrebuiltOperationEntry[];\n inputObjects: Set<string>;\n};\n\ntype GroupBySchemaResult = {\n readonly grouped: Map<string, SchemaGroup>;\n readonly warnings: string[];\n readonly skippedFragmentCount: number;\n};\n\n/**\n * Group field selections by schema.\n * Uses the schemaLabel from each selection to group them correctly.\n *\n * Fragments without a 'key' property are skipped (not included in PrebuiltTypes)\n * and a warning is added. This allows projects to use fragments without keys\n * while still generating prebuilt types for those that have keys.\n *\n * @returns Result containing grouped selections and warnings, or error if schema not found\n */\nconst groupBySchema = (\n fieldSelections: FieldSelectionsMap,\n schemas: Record<string, AnyGraphqlSchema>,\n): Result<GroupBySchemaResult, BuilderError | TypegenError> => {\n const grouped = new Map<string, SchemaGroup>();\n const warnings: string[] = [];\n let skippedFragmentCount = 0;\n\n // Initialize groups for each schema\n for (const schemaName of Object.keys(schemas)) {\n grouped.set(schemaName, { fragments: [], operations: [], inputObjects: new Set() });\n }\n\n for (const [canonicalId, selection] of fieldSelections) {\n // Use schemaLabel to determine which schema this selection belongs to\n const schemaName = selection.schemaLabel;\n const schema = schemas[schemaName];\n const group = grouped.get(schemaName);\n\n if (!schema || !group) {\n return err(builderErrors.schemaNotFound(schemaName, canonicalId));\n }\n\n // Create formatters for schema-specific type names\n const outputFormatters: TypeFormatters = {\n scalarOutput: (name) => `ScalarOutput_${schemaName}<\"${name}\">`,\n };\n const inputFormatters: TypeFormatters = {\n scalarInput: (name) => `ScalarInput_${schemaName}<\"${name}\">`,\n inputObject: (name) => `Input_${schemaName}_${name}`,\n };\n\n if (selection.type === \"fragment\") {\n // Skip fragments without keys (they won't be included in PrebuiltTypes)\n if (!selection.key) {\n skippedFragmentCount++;\n warnings.push(\n `[prebuilt] Fragment \"${canonicalId}\" skipped: missing 'key' property. ` +\n `Use tagged template syntax fragment(\"Name\", \"Type\")\\`{ ... }\\` to auto-assign a key, ` +\n `or set 'key' explicitly in the callback builder.`,\n );\n continue;\n }\n\n try {\n // Collect input objects used in fragment variables\n const usedInputObjects = collectUsedInputObjectsFromVarDefs(schema, selection.variableDefinitions);\n for (const inputName of usedInputObjects) {\n group.inputObjects.add(inputName);\n }\n\n // Generate output type with schema-specific scalar names\n const outputType = calculateFieldsType(schema, selection.fields, outputFormatters, selection.typename);\n\n // Generate input type from variableDefinitions with schema-specific names\n const hasVariables = Object.keys(selection.variableDefinitions).length > 0;\n const inputType = hasVariables\n ? generateInputTypeFromVarDefs(schema, selection.variableDefinitions, { formatters: inputFormatters })\n : \"void\";\n\n group.fragments.push({\n key: selection.key,\n typename: selection.typename,\n inputType,\n outputType,\n });\n } catch (error) {\n warnings.push(\n `[prebuilt] Failed to calculate type for fragment \"${selection.key}\": ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n } else if (selection.type === \"operation\") {\n try {\n // Collect input objects used in this operation\n const usedInputObjects = collectUsedInputObjects(schema, selection.variableDefinitions);\n for (const inputName of usedInputObjects) {\n group.inputObjects.add(inputName);\n }\n\n // Generate output type with schema-specific scalar names\n // Get the root type name from schema operations (Query, Mutation, Subscription)\n const rootTypeName = schema.operations[selection.operationType as keyof typeof schema.operations];\n const outputType = calculateFieldsType(schema, selection.fields, outputFormatters, rootTypeName ?? undefined);\n\n // Generate input type with schema-specific scalar and input object names\n const inputType = generateInputType(schema, selection.variableDefinitions, inputFormatters);\n\n group.operations.push({\n key: selection.operationName,\n inputType,\n outputType,\n });\n } catch (error) {\n warnings.push(\n `[prebuilt] Failed to calculate type for operation \"${selection.operationName}\": ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n }\n\n return ok({ grouped, warnings, skippedFragmentCount });\n};\n\n/**\n * Extract input object names from a GraphQL TypeNode.\n */\nconst extractInputObjectsFromType = (schema: AnyGraphqlSchema, typeNode: TypeNode, inputObjects: Set<string>): void => {\n switch (typeNode.kind) {\n case Kind.NON_NULL_TYPE:\n extractInputObjectsFromType(schema, typeNode.type, inputObjects);\n break;\n case Kind.LIST_TYPE:\n extractInputObjectsFromType(schema, typeNode.type, inputObjects);\n break;\n case Kind.NAMED_TYPE: {\n const name = typeNode.name.value;\n // Check if it's an input object (not a scalar or enum)\n if (!schema.scalar[name] && !schema.enum[name] && schema.input[name]) {\n inputObjects.add(name);\n }\n break;\n }\n }\n};\n\n/**\n * Recursively collect nested input objects from schema definitions.\n * Takes a set of initial input names and expands to include all nested inputs.\n */\nconst collectNestedInputObjects = (schema: AnyGraphqlSchema, initialInputNames: Set<string>): Set<string> => {\n const inputObjects = new Set(initialInputNames);\n\n const collectNested = (inputName: string, seen: Set<string>): void => {\n if (seen.has(inputName)) {\n return;\n }\n seen.add(inputName);\n\n const inputDef = schema.input[inputName];\n if (!inputDef) {\n return;\n }\n\n for (const fieldSpec of Object.values(inputDef.fields)) {\n const parsed = parseInputSpecifier(fieldSpec);\n if (parsed.kind === \"input\" && !inputObjects.has(parsed.name)) {\n inputObjects.add(parsed.name);\n collectNested(parsed.name, seen);\n }\n }\n };\n\n for (const inputName of Array.from(initialInputNames)) {\n collectNested(inputName, new Set());\n }\n\n return inputObjects;\n};\n\n/**\n * Collect all input object types used in variable definitions.\n * Recursively collects nested input objects from the schema.\n */\nconst collectUsedInputObjects = (\n schema: AnyGraphqlSchema,\n variableDefinitions: readonly VariableDefinitionNode[],\n): Set<string> => {\n const directInputs = new Set<string>();\n for (const varDef of variableDefinitions) {\n extractInputObjectsFromType(schema, varDef.type, directInputs);\n }\n return collectNestedInputObjects(schema, directInputs);\n};\n\n/**\n * Collect all input object types used in InputTypeSpecifiers.\n * Recursively collects nested input objects from the schema.\n */\nconst _collectUsedInputObjectsFromSpecifiers = (schema: AnyGraphqlSchema, specifiers: InputTypeSpecifiers): Set<string> => {\n const directInputs = new Set<string>();\n for (const specStr of Object.values(specifiers)) {\n const parsed = parseInputSpecifier(specStr);\n if (parsed.kind === \"input\" && schema.input[parsed.name]) {\n directInputs.add(parsed.name);\n }\n }\n return collectNestedInputObjects(schema, directInputs);\n};\n\n/**\n * Collect all input object types used in VariableDefinitions (VarSpecifier objects).\n * Used for fragment variable definitions.\n */\nconst collectUsedInputObjectsFromVarDefs = (\n schema: AnyGraphqlSchema,\n varDefs: Record<string, { kind: string; name: string }>,\n): Set<string> => {\n const directInputs = new Set<string>();\n for (const varSpec of Object.values(varDefs)) {\n if (varSpec.kind === \"input\" && schema.input[varSpec.name]) {\n directInputs.add(varSpec.name);\n }\n }\n return collectNestedInputObjects(schema, directInputs);\n};\n\n/**\n * Generate type definitions for input objects.\n */\nconst generateInputObjectTypeDefinitions = (schema: AnyGraphqlSchema, schemaName: string, inputNames: Set<string>): string[] => {\n const lines: string[] = [];\n\n // Get depth config from schema (optional properties defined in AnyGraphqlSchema)\n const defaultDepth = schema.__defaultInputDepth ?? 3;\n const depthOverrides = schema.__inputDepthOverrides ?? {};\n\n // Create formatters for schema-specific type names\n const formatters: TypeFormatters = {\n scalarInput: (name) => `ScalarInput_${schemaName}<\"${name}\">`,\n inputObject: (name) => `Input_${schemaName}_${name}`,\n };\n\n // Sort for deterministic output\n const sortedNames = Array.from(inputNames).sort();\n\n for (const inputName of sortedNames) {\n const typeString = generateInputObjectType(schema, inputName, {\n defaultDepth,\n depthOverrides,\n formatters,\n });\n\n lines.push(`export type Input_${schemaName}_${inputName} = ${typeString};`);\n }\n\n return lines;\n};\n\n/**\n * Generate the TypeScript code for prebuilt types.\n */\nconst generateTypesCode = (\n grouped: Map<string, SchemaGroup>,\n schemas: Record<string, AnyGraphqlSchema>,\n injectsModulePath: string,\n): string => {\n const schemaNames = Object.keys(schemas);\n\n const lines: string[] = [\n \"/**\",\n \" * Prebuilt type registry.\",\n \" *\",\n \" * This file is auto-generated by @soda-gql/typegen.\",\n \" * Do not edit manually.\",\n \" *\",\n \" * @module\",\n \" * @generated\",\n \" */\",\n \"\",\n 'import type { AssertExtends, PrebuiltTypeRegistry } from \"@soda-gql/core\";',\n ];\n\n // Generate import from _internal-injects.ts\n const scalarImports = schemaNames.map((name) => `scalar_${name}`).join(\", \");\n lines.push(`import type { ${scalarImports} } from \"${injectsModulePath}\";`);\n\n lines.push(\"\");\n\n // Generate ScalarInput and ScalarOutput helper types\n for (const schemaName of schemaNames) {\n lines.push(\n `type ScalarInput_${schemaName}<T extends keyof typeof scalar_${schemaName}> = ` +\n `typeof scalar_${schemaName}[T][\"$type\"][\"input\"];`,\n );\n lines.push(\n `type ScalarOutput_${schemaName}<T extends keyof typeof scalar_${schemaName}> = ` +\n `typeof scalar_${schemaName}[T][\"$type\"][\"output\"];`,\n );\n }\n\n lines.push(\"\");\n\n for (const [schemaName, { fragments, operations, inputObjects }] of grouped) {\n const schema = schemas[schemaName];\n\n // Generate input object type definitions if there are any\n if (inputObjects.size > 0 && schema) {\n lines.push(\"// Input object types\");\n const inputTypeLines = generateInputObjectTypeDefinitions(schema, schemaName, inputObjects);\n lines.push(...inputTypeLines);\n lines.push(\"\");\n }\n\n // Generate fragments type (deduplicate by key — last occurrence wins)\n const deduplicatedFragments = new Map<string, PrebuiltFragmentEntry>();\n for (const f of fragments) {\n deduplicatedFragments.set(f.key, f);\n }\n const fragmentEntries = Array.from(deduplicatedFragments.values())\n .sort((a, b) => a.key.localeCompare(b.key))\n .map(\n (f) =>\n ` readonly \"${f.key}\": { readonly typename: \"${f.typename}\"; readonly input: ${f.inputType}; readonly output: ${f.outputType} };`,\n );\n\n // Generate operations type (deduplicate by key — last occurrence wins)\n const deduplicatedOperations = new Map<string, PrebuiltOperationEntry>();\n for (const o of operations) {\n deduplicatedOperations.set(o.key, o);\n }\n const operationEntries = Array.from(deduplicatedOperations.values())\n .sort((a, b) => a.key.localeCompare(b.key))\n .map((o) => ` readonly \"${o.key}\": { readonly input: ${o.inputType}; readonly output: ${o.outputType} };`);\n\n lines.push(`export type PrebuiltTypes_${schemaName} = {`);\n lines.push(\" readonly fragments: {\");\n if (fragmentEntries.length > 0) {\n lines.push(...fragmentEntries);\n }\n lines.push(\" };\");\n lines.push(\" readonly operations: {\");\n if (operationEntries.length > 0) {\n lines.push(...operationEntries);\n }\n lines.push(\" };\");\n lines.push(\"};\");\n lines.push(`type _AssertPrebuiltTypes_${schemaName} = AssertExtends<PrebuiltTypes_${schemaName}, PrebuiltTypeRegistry>;`);\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n};\n\n/**\n * Result of emitting prebuilt types.\n */\nexport type PrebuiltTypesEmitResult = {\n readonly path: string;\n readonly warnings: readonly string[];\n readonly skippedFragmentCount: number;\n};\n\n/**\n * Emit prebuilt types to the types.prebuilt.ts file.\n *\n * This function uses a partial failure strategy: if type calculation fails for\n * individual elements (e.g., due to invalid field selections or missing schema\n * types), those elements are skipped and warnings are collected rather than\n * failing the entire emission. This allows builds to succeed even when some\n * elements have issues, while still reporting problems via warnings.\n *\n * @param options - Emitter options including schemas, field selections, and output directory\n * @returns Result containing output path and warnings, or error if a hard failure occurs\n *\n * @example\n * ```typescript\n * const result = await emitPrebuiltTypes({\n * schemas: { mySchema: schema },\n * fieldSelections,\n * outdir: \"./generated\",\n * injects: { mySchema: { scalars: \"./scalars.ts\" } },\n * });\n *\n * if (result.isOk()) {\n * console.log(`Generated: ${result.value.path}`);\n * if (result.value.warnings.length > 0) {\n * console.warn(\"Warnings:\", result.value.warnings);\n * }\n * }\n * ```\n */\nexport const emitPrebuiltTypes = async (\n options: PrebuiltTypesEmitterOptions,\n): Promise<Result<PrebuiltTypesEmitResult, BuilderError | TypegenError>> => {\n const { schemas, fieldSelections, outdir, injectsModulePath } = options;\n\n // Group selections by schema\n const groupResult = groupBySchema(fieldSelections, schemas);\n if (groupResult.isErr()) {\n return err(groupResult.error);\n }\n const { grouped, warnings, skippedFragmentCount } = groupResult.value;\n\n // Generate the types code\n const code = generateTypesCode(grouped, schemas, injectsModulePath);\n\n // Write to types.prebuilt.ts\n const typesPath = join(outdir, \"types.prebuilt.ts\");\n\n try {\n await writeFile(typesPath, code, \"utf-8\");\n return ok({ path: typesPath, warnings, skippedFragmentCount });\n } catch (error) {\n return err(\n builderErrors.writeFailed(\n typesPath,\n `Failed to write prebuilt types: ${error instanceof Error ? error.message : String(error)}`,\n error,\n ),\n );\n }\n};\n","/**\n * Error types for typegen package.\n *\n * @module\n */\n\nimport type { BuilderError } from \"@soda-gql/builder\";\n\n/**\n * Error codes specific to typegen operations.\n */\nexport type TypegenErrorCode = \"TYPEGEN_CODEGEN_REQUIRED\" | \"TYPEGEN_SCHEMA_LOAD_FAILED\" | \"TYPEGEN_BUILD_FAILED\";\n\n/**\n * Typegen-specific error type.\n */\nexport type TypegenSpecificError =\n | {\n readonly code: \"TYPEGEN_CODEGEN_REQUIRED\";\n readonly message: string;\n readonly outdir: string;\n }\n | {\n readonly code: \"TYPEGEN_SCHEMA_LOAD_FAILED\";\n readonly message: string;\n readonly schemaNames: readonly string[];\n readonly cause?: unknown;\n }\n | {\n readonly code: \"TYPEGEN_BUILD_FAILED\";\n readonly message: string;\n readonly cause?: unknown;\n };\n\n/**\n * Union of all typegen errors (specific + builder errors).\n */\nexport type TypegenError = TypegenSpecificError | BuilderError;\n\n/**\n * Error constructor helpers for concise error creation.\n */\nexport const typegenErrors = {\n codegenRequired: (outdir: string): TypegenSpecificError => ({\n code: \"TYPEGEN_CODEGEN_REQUIRED\",\n message: `Generated graphql-system module not found at '${outdir}'. Run 'soda-gql codegen' first.`,\n outdir,\n }),\n\n schemaLoadFailed: (schemaNames: readonly string[], cause?: unknown): TypegenSpecificError => ({\n code: \"TYPEGEN_SCHEMA_LOAD_FAILED\",\n message: `Failed to load schemas: ${schemaNames.join(\", \")}`,\n schemaNames,\n cause,\n }),\n\n buildFailed: (message: string, cause?: unknown): TypegenSpecificError => ({\n code: \"TYPEGEN_BUILD_FAILED\",\n message,\n cause,\n }),\n} as const;\n\n/**\n * Format TypegenError for console output (human-readable).\n */\nexport const formatTypegenError = (error: TypegenError): string => {\n const lines: string[] = [];\n\n lines.push(`Error [${error.code}]: ${error.message}`);\n\n switch (error.code) {\n case \"TYPEGEN_CODEGEN_REQUIRED\":\n lines.push(` Output directory: ${error.outdir}`);\n lines.push(\" Hint: Run 'soda-gql codegen' to generate the graphql-system module first.\");\n break;\n case \"TYPEGEN_SCHEMA_LOAD_FAILED\":\n lines.push(` Schemas: ${error.schemaNames.join(\", \")}`);\n break;\n }\n\n if (\"cause\" in error && error.cause) {\n lines.push(` Caused by: ${error.cause}`);\n }\n\n return lines.join(\"\\n\");\n};\n","/**\n * Template extractor for typegen.\n *\n * Extracts tagged template GraphQL content from TypeScript source files\n * using SWC parsing. Adapted from the LSP document-manager pattern\n * but simplified for batch extraction (no position tracking, no state management).\n *\n * @module\n */\n\nimport type { GraphqlSystemIdentifyHelper } from \"@soda-gql/builder\";\n\nimport { parseSync } from \"@swc/core\";\nimport type {\n ArrowFunctionExpression,\n CallExpression,\n ImportDeclaration,\n MemberExpression,\n Module,\n Node,\n TaggedTemplateExpression,\n} from \"@swc/types\";\n\n/** Operation kind extracted from tagged template tag name. */\nexport type OperationKind = \"query\" | \"mutation\" | \"subscription\" | \"fragment\";\n\n/** A single tagged template extracted from a TypeScript source file. */\nexport type ExtractedTemplate = {\n /** Resolved schema name from gql.{schemaName}. */\n readonly schemaName: string;\n /** Operation kind from tag name. */\n readonly kind: OperationKind;\n /** Raw GraphQL content between backticks (may contain __FRAG_SPREAD_N__ placeholders). */\n readonly content: string;\n /** Element name from curried tag call (e.g., \"GetUser\" from query(\"GetUser\")). */\n readonly elementName?: string;\n /** Type name from curried fragment call (e.g., \"User\" from fragment(\"UserFields\", \"User\")). */\n readonly typeName?: string;\n};\n\n/** Result of extracting templates from a source file. */\nexport type ExtractionResult = {\n readonly templates: readonly ExtractedTemplate[];\n readonly warnings: readonly string[];\n};\n\nconst OPERATION_KINDS = new Set<string>([\"query\", \"mutation\", \"subscription\", \"fragment\"]);\n\nconst isOperationKind = (value: string): value is OperationKind => OPERATION_KINDS.has(value);\n\n/**\n * Parse TypeScript source with SWC, returning null on failure.\n */\nconst safeParseSync = (source: string, tsx: boolean): ReturnType<typeof parseSync> | null => {\n try {\n return parseSync(source, {\n syntax: \"typescript\",\n tsx,\n decorators: false,\n dynamicImport: true,\n });\n } catch {\n return null;\n }\n};\n\n/**\n * Collect gql identifiers from import declarations.\n * Finds imports like `import { gql } from \"./graphql-system\"`.\n */\nconst collectGqlIdentifiers = (module: Module, filePath: string, helper: GraphqlSystemIdentifyHelper): ReadonlySet<string> => {\n const identifiers = new Set<string>();\n\n for (const item of module.body) {\n let declaration: ImportDeclaration | null = null;\n\n if (item.type === \"ImportDeclaration\") {\n declaration = item;\n } else if (\n \"declaration\" in item &&\n item.declaration &&\n // biome-ignore lint/suspicious/noExplicitAny: SWC AST type checking\n (item.declaration as any).type === \"ImportDeclaration\"\n ) {\n declaration = item.declaration as unknown as ImportDeclaration;\n }\n\n if (!declaration) {\n continue;\n }\n\n if (!helper.isGraphqlSystemImportSpecifier({ filePath, specifier: declaration.source.value })) {\n continue;\n }\n\n for (const specifier of declaration.specifiers ?? []) {\n if (specifier.type === \"ImportSpecifier\") {\n const imported = specifier.imported ? specifier.imported.value : specifier.local.value;\n if (imported === \"gql\" && !specifier.imported) {\n identifiers.add(specifier.local.value);\n }\n }\n }\n }\n\n return identifiers;\n};\n\n/**\n * Check if a call expression is a gql.{schemaName}(...) call.\n * Returns the schema name if it is, null otherwise.\n */\nconst getGqlCallSchemaName = (identifiers: ReadonlySet<string>, call: CallExpression): string | null => {\n const callee = call.callee;\n if (callee.type !== \"MemberExpression\") {\n return null;\n }\n\n const member = callee as MemberExpression;\n if (member.object.type !== \"Identifier\" || !identifiers.has(member.object.value)) {\n return null;\n }\n\n if (member.property.type !== \"Identifier\") {\n return null;\n }\n\n const firstArg = call.arguments[0];\n if (!firstArg?.expression || firstArg.expression.type !== \"ArrowFunctionExpression\") {\n return null;\n }\n\n return member.property.value;\n};\n\n/**\n * Extract templates from a gql callback's arrow function body.\n * Handles both expression bodies and block bodies with return statements.\n */\nconst extractTemplatesFromCallback = (arrow: ArrowFunctionExpression, schemaName: string): ExtractedTemplate[] => {\n const templates: ExtractedTemplate[] = [];\n\n const processExpression = (expr: Node): void => {\n // Direct tagged template: query(\"Name\")`...`\n if (expr.type === \"TaggedTemplateExpression\") {\n const tagged = expr as unknown as TaggedTemplateExpression;\n extractFromTaggedTemplate(tagged, schemaName, templates);\n return;\n }\n\n // Metadata chaining: query(\"Name\")`...`({ metadata: {} })\n if (expr.type === \"CallExpression\") {\n const call = expr as unknown as CallExpression;\n if (call.callee.type === \"TaggedTemplateExpression\") {\n extractFromTaggedTemplate(call.callee as TaggedTemplateExpression, schemaName, templates);\n }\n }\n };\n\n // Expression body: ({ query }) => query(\"Name\")`...`\n if (arrow.body.type !== \"BlockStatement\") {\n processExpression(arrow.body);\n return templates;\n }\n\n // Block body: ({ query }) => { return query(\"Name\")`...`; }\n for (const stmt of arrow.body.stmts) {\n if (stmt.type === \"ReturnStatement\" && stmt.argument) {\n processExpression(stmt.argument);\n }\n }\n\n return templates;\n};\n\nconst extractFromTaggedTemplate = (\n tagged: TaggedTemplateExpression,\n schemaName: string,\n templates: ExtractedTemplate[],\n): void => {\n // Tag can be:\n // - CallExpression: query(\"name\")`...` or fragment(\"name\", \"type\")`...` (curried syntax)\n // - Identifier: legacy bare-tag form (skipped if it contains interpolations)\n let kind: string;\n let elementName: string | undefined;\n let typeName: string | undefined;\n\n if (tagged.tag.type === \"Identifier\") {\n kind = tagged.tag.value;\n } else if (tagged.tag.type === \"CallExpression\") {\n const tagCall = tagged.tag as CallExpression;\n if (tagCall.callee.type === \"Identifier\") {\n kind = tagCall.callee.value;\n } else {\n return;\n }\n // Extract elementName and typeName from call arguments\n const firstArg = tagCall.arguments[0]?.expression;\n if (firstArg?.type === \"StringLiteral\") {\n elementName = (firstArg as { value: string }).value;\n }\n const secondArg = tagCall.arguments[1]?.expression;\n if (secondArg?.type === \"StringLiteral\") {\n typeName = (secondArg as { value: string }).value;\n }\n } else {\n return;\n }\n\n if (!isOperationKind(kind)) {\n return;\n }\n\n const { quasis, expressions } = tagged.template;\n\n // For legacy Identifier tag, skip templates with interpolations\n // For new syntax (CallExpression tag), handle interpolations with placeholders\n if (tagged.tag.type === \"Identifier\" && expressions.length > 0) {\n return;\n }\n\n if (quasis.length === 0) {\n return;\n }\n\n let content: string;\n if (expressions.length === 0) {\n // No interpolations — simple case\n const quasi = quasis[0];\n if (!quasi) return;\n content = quasi.cooked ?? quasi.raw;\n } else {\n // Build content with placeholder tokens for interpolations\n const parts: string[] = [];\n for (let i = 0; i < quasis.length; i++) {\n const quasi = quasis[i];\n if (!quasi) continue;\n parts.push(quasi.cooked ?? quasi.raw);\n if (i < expressions.length) {\n parts.push(`__FRAG_SPREAD_${i}__`);\n }\n }\n content = parts.join(\"\");\n }\n\n templates.push({\n schemaName,\n kind,\n content,\n ...(elementName !== undefined ? { elementName } : {}),\n ...(typeName !== undefined ? { typeName } : {}),\n });\n};\n\n/**\n * Find the innermost gql call, unwrapping method chains like .attach().\n */\nconst findGqlCall = (identifiers: ReadonlySet<string>, node: Node): CallExpression | null => {\n if (!node || node.type !== \"CallExpression\") {\n return null;\n }\n\n const call = node as unknown as CallExpression;\n if (getGqlCallSchemaName(identifiers, call) !== null) {\n return call;\n }\n\n const callee = call.callee;\n if (callee.type !== \"MemberExpression\") {\n return null;\n }\n\n return findGqlCall(identifiers, callee.object as unknown as Node);\n};\n\n/**\n * Walk AST to find gql calls and extract templates.\n */\nconst walkAndExtract = (node: Node, identifiers: ReadonlySet<string>): ExtractedTemplate[] => {\n const templates: ExtractedTemplate[] = [];\n\n const visit = (n: Node | ReadonlyArray<Node> | Record<string, unknown>): void => {\n if (!n || typeof n !== \"object\") {\n return;\n }\n\n if (\"type\" in n && n.type === \"CallExpression\") {\n const gqlCall = findGqlCall(identifiers, n as Node);\n if (gqlCall) {\n const schemaName = getGqlCallSchemaName(identifiers, gqlCall);\n if (schemaName) {\n const arrow = gqlCall.arguments[0]?.expression as ArrowFunctionExpression;\n templates.push(...extractTemplatesFromCallback(arrow, schemaName));\n }\n return; // Don't recurse into gql calls\n }\n }\n\n // Recurse into all array and object properties\n if (Array.isArray(n)) {\n for (const item of n) {\n visit(item as Node);\n }\n return;\n }\n\n for (const key of Object.keys(n)) {\n if (key === \"span\" || key === \"type\") {\n continue;\n }\n const value = (n as Record<string, unknown>)[key];\n if (value && typeof value === \"object\") {\n visit(value as Node);\n }\n }\n };\n\n visit(node);\n return templates;\n};\n\n/**\n * Extract all tagged templates from a TypeScript source file.\n *\n * @param filePath - Absolute path to the source file (used for import resolution)\n * @param source - TypeScript source code\n * @param helper - GraphQL system identifier for resolving gql imports\n * @returns Extracted templates and any warnings\n */\nexport const extractTemplatesFromSource = (\n filePath: string,\n source: string,\n helper: GraphqlSystemIdentifyHelper,\n): ExtractionResult => {\n const warnings: string[] = [];\n const isTsx = filePath.endsWith(\".tsx\");\n\n const program = safeParseSync(source, isTsx);\n if (!program || program.type !== \"Module\") {\n if (source.includes(\"gql\")) {\n warnings.push(`[typegen-extract] Failed to parse ${filePath}`);\n }\n return { templates: [], warnings };\n }\n\n const gqlIdentifiers = collectGqlIdentifiers(program, filePath, helper);\n if (gqlIdentifiers.size === 0) {\n return { templates: [], warnings };\n }\n\n return { templates: walkAndExtract(program, gqlIdentifiers), warnings };\n};\n","/**\n * Source file scanner for tagged template extraction.\n *\n * Discovers source files from config include/exclude patterns,\n * reads them, and extracts tagged templates using the template extractor.\n *\n * @module\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { normalize, resolve } from \"node:path\";\nimport type { GraphqlSystemIdentifyHelper } from \"@soda-gql/builder\";\nimport fg from \"fast-glob\";\nimport { type ExtractedTemplate, extractTemplatesFromSource } from \"./template-extractor\";\n\nexport type ScanSourceFilesOptions = {\n /** Glob patterns for source files to include. */\n readonly include: readonly string[];\n /** Glob patterns for source files to exclude. */\n readonly exclude: readonly string[];\n /** Base directory for resolving glob patterns. */\n readonly baseDir: string;\n /** Helper for identifying graphql-system imports. */\n readonly helper: GraphqlSystemIdentifyHelper;\n};\n\nexport type ScanResult = {\n /** Templates keyed by file path. */\n readonly templates: ReadonlyMap<string, readonly ExtractedTemplate[]>;\n /** Warnings from scanning. */\n readonly warnings: readonly string[];\n};\n\n/**\n * Scan source files for tagged templates.\n *\n * Uses fast-glob to discover files matching include/exclude patterns,\n * then extracts tagged templates from each file.\n */\nexport const scanSourceFiles = (options: ScanSourceFilesOptions): ScanResult => {\n const { include, exclude, baseDir, helper } = options;\n const warnings: string[] = [];\n\n // Build exclusion patterns\n const ignorePatterns = exclude.map((pattern) => (pattern.startsWith(\"!\") ? pattern.slice(1) : pattern));\n\n // Discover files via fast-glob\n const matchedFiles = fg.sync(include as string[], {\n cwd: baseDir,\n ignore: ignorePatterns,\n onlyFiles: true,\n absolute: true,\n });\n\n const templates = new Map<string, readonly ExtractedTemplate[]>();\n\n for (const filePath of matchedFiles) {\n const normalizedPath = normalize(resolve(filePath)).replace(/\\\\/g, \"/\");\n\n try {\n const source = readFileSync(normalizedPath, \"utf-8\");\n const { templates: extracted, warnings: extractionWarnings } = extractTemplatesFromSource(normalizedPath, source, helper);\n warnings.push(...extractionWarnings);\n\n if (extracted.length > 0) {\n templates.set(normalizedPath, extracted);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n warnings.push(`[typegen-scan] Failed to read ${normalizedPath}: ${message}`);\n }\n }\n\n return { templates, warnings };\n};\n","/**\n * Converts extracted tagged template GraphQL content into FieldSelectionData.\n *\n * Takes the output of template-extractor and produces FieldSelectionData entries\n * compatible with the emitter pipeline. Uses the shared field-building utilities\n * from core to produce AnyFieldsExtended from GraphQL AST.\n *\n * @module\n */\n\nimport type { FieldSelectionData, FieldSelectionsMap } from \"@soda-gql/builder\";\nimport type { CanonicalId } from \"@soda-gql/common\";\nimport {\n type AnyGraphqlSchema,\n buildFieldsFromSelectionSet,\n createSchemaIndexFromSchema,\n extractFragmentVariables,\n preprocessFragmentArgs,\n} from \"@soda-gql/core\";\nimport { Kind, parse as parseGraphql, type SelectionSetNode } from \"graphql\";\nimport type { ExtractedTemplate } from \"./template-extractor\";\n\n/** Result of converting templates to field selections. */\nexport type TemplateConversionResult = {\n readonly selections: FieldSelectionsMap;\n readonly warnings: readonly string[];\n};\n\n/**\n * Convert extracted templates into field selections for the emitter.\n *\n * @param templates - Templates extracted from source files, keyed by file path\n * @param schemas - Loaded schema objects keyed by schema name\n * @returns Map of canonical IDs to field selection data, plus any warnings\n */\nexport const convertTemplatesToSelections = (\n templates: ReadonlyMap<string, readonly ExtractedTemplate[]>,\n schemas: Record<string, AnyGraphqlSchema>,\n): TemplateConversionResult => {\n const selections = new Map<CanonicalId, FieldSelectionData>();\n const warnings: string[] = [];\n\n // Build schema indexes once per schema\n const schemaIndexes = new Map(Object.entries(schemas).map(([name, schema]) => [name, createSchemaIndexFromSchema(schema)]));\n\n for (const [filePath, fileTemplates] of templates) {\n for (const template of fileTemplates) {\n const schema = schemas[template.schemaName];\n if (!schema) {\n warnings.push(`[typegen-template] Unknown schema \"${template.schemaName}\" in ${filePath}`);\n continue;\n }\n\n const schemaIndex = schemaIndexes.get(template.schemaName);\n if (!schemaIndex) {\n continue;\n }\n\n try {\n if (template.kind === \"fragment\") {\n const selection = convertFragmentTemplate(template, schema, filePath);\n if (selection) {\n selections.set(selection.id, selection.data);\n }\n } else {\n const selection = convertOperationTemplate(template, schema, filePath);\n if (selection) {\n selections.set(selection.id, selection.data);\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n warnings.push(`[typegen-template] Failed to process ${template.kind} in ${filePath}: ${message}`);\n }\n }\n }\n\n return { selections, warnings };\n};\n\n/**\n * Recursively filter out __FRAG_SPREAD_ placeholder nodes from a selection set.\n * These placeholders are created by template-extractor for interpolated fragment references.\n * buildFieldsFromSelectionSet would throw on them since no interpolationMap is available.\n */\nconst filterPlaceholderSpreads = (selectionSet: SelectionSetNode): SelectionSetNode => ({\n ...selectionSet,\n selections: selectionSet.selections\n .filter((sel) => !(sel.kind === Kind.FRAGMENT_SPREAD && sel.name.value.startsWith(\"__FRAG_SPREAD_\")))\n .map((sel) => {\n if (sel.kind === Kind.FIELD && sel.selectionSet) {\n return { ...sel, selectionSet: filterPlaceholderSpreads(sel.selectionSet) };\n }\n if (sel.kind === Kind.INLINE_FRAGMENT && sel.selectionSet) {\n return { ...sel, selectionSet: filterPlaceholderSpreads(sel.selectionSet) };\n }\n return sel;\n }),\n});\n\n/** Simple matching-paren finder for template content (no comments/strings to handle). */\nconst findClosingParen = (source: string, openIndex: number): number => {\n let depth = 0;\n for (let i = openIndex; i < source.length; i++) {\n if (source[i] === \"(\") depth++;\n else if (source[i] === \")\") {\n depth--;\n if (depth === 0) return i;\n }\n }\n return -1;\n};\n\n/**\n * Reconstruct full GraphQL source from an extracted template.\n * For curried syntax (new), prepends the definition header from tag call arguments.\n * For curried fragments with Fragment Arguments, repositions variable declarations\n * before the on-clause to produce RFC-compliant syntax.\n * For old syntax, returns content as-is.\n */\nconst reconstructGraphql = (template: ExtractedTemplate): string => {\n if (template.elementName) {\n if (template.kind === \"fragment\" && template.typeName) {\n const trimmed = template.content.trim();\n if (trimmed.startsWith(\"(\")) {\n const closeIdx = findClosingParen(trimmed, 0);\n if (closeIdx !== -1) {\n const varDecls = trimmed.slice(0, closeIdx + 1);\n const selectionSet = trimmed.slice(closeIdx + 1).trim();\n return `fragment ${template.elementName}${varDecls} on ${template.typeName} ${selectionSet}`;\n }\n }\n return `fragment ${template.elementName} on ${template.typeName} ${trimmed}`;\n }\n return `${template.kind} ${template.elementName} ${template.content}`;\n }\n return template.content;\n};\n\n/**\n * Convert a fragment template into FieldSelectionData.\n */\nconst convertFragmentTemplate = (\n template: ExtractedTemplate,\n schema: AnyGraphqlSchema,\n filePath: string,\n): { id: CanonicalId; data: FieldSelectionData } | null => {\n const schemaIndex = createSchemaIndexFromSchema(schema);\n const graphqlSource = reconstructGraphql(template);\n\n // Extract variable definitions from Fragment Arguments syntax\n const variableDefinitions = extractFragmentVariables(graphqlSource, schemaIndex);\n\n // Preprocess to strip Fragment Arguments\n const { preprocessed } = preprocessFragmentArgs(graphqlSource);\n\n const document = parseGraphql(preprocessed);\n const fragDef = document.definitions.find((d) => d.kind === Kind.FRAGMENT_DEFINITION);\n if (!fragDef || fragDef.kind !== Kind.FRAGMENT_DEFINITION) {\n return null;\n }\n\n const fragmentName = fragDef.name.value;\n const onType = fragDef.typeCondition.name.value;\n\n // Build fields from selection set (filter placeholder spreads from interpolated fragments)\n const fields = buildFieldsFromSelectionSet(filterPlaceholderSpreads(fragDef.selectionSet), schema, onType);\n\n // Generate a canonical ID from file path + fragment name\n const id = `${filePath}::${fragmentName}` as CanonicalId;\n\n return {\n id,\n data: {\n type: \"fragment\",\n schemaLabel: schema.label,\n key: fragmentName,\n typename: onType,\n fields,\n variableDefinitions,\n },\n };\n};\n\n/**\n * Convert an operation template into FieldSelectionData.\n */\nconst convertOperationTemplate = (\n template: ExtractedTemplate,\n schema: AnyGraphqlSchema,\n filePath: string,\n): { id: CanonicalId; data: FieldSelectionData } | null => {\n const graphqlSource = reconstructGraphql(template);\n const document = parseGraphql(graphqlSource);\n const opDef = document.definitions.find((d) => d.kind === Kind.OPERATION_DEFINITION);\n if (!opDef || opDef.kind !== Kind.OPERATION_DEFINITION) {\n return null;\n }\n\n const operationName = opDef.name?.value ?? \"Anonymous\";\n const operationType = opDef.operation;\n\n // Determine root type name based on operation type\n const rootTypeName = getRootTypeName(schema, operationType);\n\n // Build fields from selection set (filter placeholder spreads from interpolated fragments)\n const fields = buildFieldsFromSelectionSet(filterPlaceholderSpreads(opDef.selectionSet), schema, rootTypeName);\n\n // Variable definitions from the operation AST\n const variableDefinitions = opDef.variableDefinitions ?? [];\n\n // Generate a canonical ID from file path + operation name\n const id = `${filePath}::${operationName}` as CanonicalId;\n\n return {\n id,\n data: {\n type: \"operation\",\n schemaLabel: schema.label,\n operationName,\n operationType,\n fields,\n variableDefinitions: [...variableDefinitions],\n },\n };\n};\n\n/**\n * Get the root type name for an operation type from the schema.\n */\nconst getRootTypeName = (schema: AnyGraphqlSchema, operationType: string): string => {\n switch (operationType) {\n case \"query\":\n return schema.operations.query ?? \"Query\";\n case \"mutation\":\n return schema.operations.mutation ?? \"Mutation\";\n case \"subscription\":\n return schema.operations.subscription ?? \"Subscription\";\n default:\n return \"Query\";\n }\n};\n","/**\n * Main typegen runner.\n *\n * Orchestrates the prebuilt type generation process:\n * 1. Load schemas from generated CJS bundle\n * 2. Build artifact to evaluate elements\n * 3. Extract field selections from builder\n * 4. Scan source files for tagged templates and merge selections\n * 5. Emit types.prebuilt.ts\n *\n * @module\n */\n\nimport { existsSync } from \"node:fs\";\nimport { dirname, extname, join, relative, resolve } from \"node:path\";\nimport {\n createBuilderService,\n createGraphqlSystemIdentifyHelper,\n extractFieldSelections,\n type FieldSelectionData,\n type IntermediateArtifactElement,\n loadSchemasFromBundle,\n} from \"@soda-gql/builder\";\nimport type { CanonicalId } from \"@soda-gql/common\";\nimport type { ResolvedSodaGqlConfig } from \"@soda-gql/config\";\nimport { err, ok } from \"neverthrow\";\nimport { emitPrebuiltTypes } from \"./emitter\";\nimport { typegenErrors } from \"./errors\";\nimport { scanSourceFiles } from \"./template-scanner\";\nimport { convertTemplatesToSelections } from \"./template-to-selections\";\nimport type { TypegenResult, TypegenSuccess } from \"./types\";\n\n/**\n * Options for running typegen.\n */\nexport type RunTypegenOptions = {\n /**\n * Resolved soda-gql configuration.\n */\n readonly config: ResolvedSodaGqlConfig;\n};\n\nconst extensionMap: Record<string, string> = {\n \".ts\": \".js\",\n \".tsx\": \".js\",\n \".mts\": \".mjs\",\n \".cts\": \".cjs\",\n \".js\": \".js\",\n \".mjs\": \".mjs\",\n \".cjs\": \".cjs\",\n};\n\ntype ImportSpecifierOptions = {\n includeExtension?: boolean;\n};\n\nconst toImportSpecifier = (fromPath: string, targetPath: string, options?: ImportSpecifierOptions): string => {\n const fromDir = dirname(fromPath);\n const normalized = relative(fromDir, targetPath).replace(/\\\\/g, \"/\");\n const sourceExt = extname(targetPath);\n\n // When includeExtension is false (default), strip the extension entirely\n if (!options?.includeExtension) {\n if (normalized.length === 0) {\n return `./${targetPath.slice(0, -sourceExt.length).split(\"/\").pop()}`;\n }\n const withPrefix = normalized.startsWith(\".\") ? normalized : `./${normalized}`;\n const currentExt = extname(withPrefix);\n return currentExt ? withPrefix.slice(0, -currentExt.length) : withPrefix;\n }\n\n // When includeExtension is true, convert to runtime extension\n const runtimeExt = extensionMap[sourceExt] ?? sourceExt;\n\n if (normalized.length === 0) {\n const base = runtimeExt !== sourceExt ? targetPath.slice(0, -sourceExt.length).split(\"/\").pop() : targetPath.split(\"/\").pop();\n return `./${base}${runtimeExt}`;\n }\n\n const withPrefix = normalized.startsWith(\".\") ? normalized : `./${normalized}`;\n if (!runtimeExt) {\n return withPrefix;\n }\n if (withPrefix.endsWith(runtimeExt)) {\n return withPrefix;\n }\n\n const currentExt = extname(withPrefix);\n const withoutExt = currentExt ? withPrefix.slice(0, -currentExt.length) : withPrefix;\n return `${withoutExt}${runtimeExt}`;\n};\n\n/**\n * Run the typegen process.\n *\n * This function:\n * 1. Loads schemas from the generated CJS bundle\n * 2. Creates a BuilderService and builds the artifact\n * 3. Extracts field selections from the artifact\n * 4. Scans source files for tagged templates and merges selections\n * 5. Emits types.prebuilt.ts using emitPrebuiltTypes\n *\n * @param options - Typegen options including config\n * @returns Result containing success data or error\n */\nexport const runTypegen = async (options: RunTypegenOptions): Promise<TypegenResult> => {\n const { config } = options;\n const outdir = resolve(config.outdir);\n const cjsPath = join(outdir, \"index.cjs\");\n const importSpecifierOptions = { includeExtension: config.styles.importExtension };\n\n // Step 1: Check if codegen has been run\n if (!existsSync(cjsPath)) {\n return err(typegenErrors.codegenRequired(outdir));\n }\n\n // Step 2: Load schemas from CJS bundle\n const schemaNames = Object.keys(config.schemas);\n const schemasResult = loadSchemasFromBundle(cjsPath, schemaNames);\n if (schemasResult.isErr()) {\n return err(typegenErrors.schemaLoadFailed(schemaNames, schemasResult.error));\n }\n const schemas = schemasResult.value;\n\n // Calculate import path for types.prebuilt.ts to _internal-injects.ts\n const prebuiltTypesPath = join(outdir, \"types.prebuilt.ts\");\n const injectsModulePath = toImportSpecifier(prebuiltTypesPath, join(outdir, \"_internal-injects.ts\"), importSpecifierOptions);\n\n // Step 3: Build artifact using BuilderService\n const builderService = createBuilderService({\n config,\n });\n\n const artifactResult = await builderService.buildAsync();\n\n if (artifactResult.isErr()) {\n return err(typegenErrors.buildFailed(`Builder failed: ${artifactResult.error.message}`, artifactResult.error));\n }\n\n // Step 4: Extract field selections from intermediate elements\n const intermediateElements = builderService.getIntermediateElements();\n if (!intermediateElements) {\n return err(typegenErrors.buildFailed(\"No intermediate elements available after build\", undefined));\n }\n\n const fieldSelectionsResult = extractFieldSelections(intermediateElements as Record<CanonicalId, IntermediateArtifactElement>);\n const { selections: builderSelections, warnings: extractWarnings } = fieldSelectionsResult;\n\n // Step 4b: Scan source files for tagged templates and merge selections\n const graphqlHelper = createGraphqlSystemIdentifyHelper(config);\n const scanResult = scanSourceFiles({\n include: [...config.include],\n exclude: [...config.exclude],\n baseDir: config.baseDir,\n helper: graphqlHelper,\n });\n\n const templateSelections = convertTemplatesToSelections(scanResult.templates, schemas);\n\n const fieldSelections = mergeSelections(builderSelections, templateSelections.selections, config.baseDir);\n\n const scanWarnings = [...scanResult.warnings, ...templateSelections.warnings];\n\n // Step 5: Emit types.prebuilt.ts\n const emitResult = await emitPrebuiltTypes({\n schemas,\n fieldSelections,\n outdir,\n injectsModulePath,\n });\n\n if (emitResult.isErr()) {\n return err(emitResult.error);\n }\n\n const { warnings: emitWarnings, skippedFragmentCount } = emitResult.value;\n\n // Count fragments and operations\n let fragmentCount = 0;\n let operationCount = 0;\n for (const selection of fieldSelections.values()) {\n if (selection.type === \"fragment\" && selection.key) {\n fragmentCount++;\n } else if (selection.type === \"operation\") {\n operationCount++;\n }\n }\n\n const allWarnings = [...extractWarnings, ...scanWarnings, ...emitWarnings];\n\n return ok({\n prebuiltTypesPath,\n fragmentCount,\n operationCount,\n skippedFragmentCount,\n warnings: allWarnings,\n } satisfies TypegenSuccess);\n};\n\nconst extractElementName = (data: FieldSelectionData): string | undefined =>\n data.type === \"fragment\" ? data.key : data.operationName;\n\n/**\n * Merge builder and template selections into a combined map.\n *\n * Builder selections are authoritative — VM evaluation correctly resolves\n * fragment spreads that static template analysis cannot handle.\n * Template selections serve as fallback for elements only found by the scanner.\n *\n * Deduplication is per-element (file + GraphQL name), not per-file, so that\n * callback-builder operations in files that also contain tagged templates are preserved.\n */\nexport const mergeSelections = (\n builderSelections: ReadonlyMap<CanonicalId, FieldSelectionData>,\n templateSelections: ReadonlyMap<CanonicalId, FieldSelectionData>,\n baseDir: string,\n): Map<CanonicalId, FieldSelectionData> => {\n // Builder uses relative paths (e.g. \"src/foo.ts::varName\"), template scanner uses\n // absolute paths (e.g. \"/abs/path/src/foo.ts::FragmentName\"). Normalize to relative.\n const extractFilePart = (id: string): string => {\n const filePart = id.split(\"::\")[0] ?? \"\";\n if (filePart.startsWith(\"/\")) {\n return relative(baseDir, filePart);\n }\n return filePart;\n };\n\n // Build set of (file, elementName) pairs from builder selections\n const builderElements = new Set<string>();\n for (const [id, data] of builderSelections) {\n const name = extractElementName(data);\n if (name) builderElements.add(`${extractFilePart(id)}::${name}`);\n }\n\n const fieldSelections = new Map<CanonicalId, FieldSelectionData>();\n // Builder selections first (authoritative)\n for (const [id, data] of builderSelections) {\n fieldSelections.set(id, data);\n }\n // Template selections as fallback for elements not found by builder\n for (const [id, data] of templateSelections) {\n const name = extractElementName(data);\n if (name && builderElements.has(`${extractFilePart(id)}::${name}`)) continue;\n fieldSelections.set(id, data);\n }\n\n return fieldSelections;\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soda-gql/typegen",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"description": "Prebuilt type generation for soda-gql",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -49,10 +49,10 @@
|
|
|
49
49
|
"./package.json": "./package.json"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@soda-gql/builder": "0.12.
|
|
53
|
-
"@soda-gql/common": "0.12.
|
|
54
|
-
"@soda-gql/config": "0.12.
|
|
55
|
-
"@soda-gql/core": "0.12.
|
|
52
|
+
"@soda-gql/builder": "0.12.2",
|
|
53
|
+
"@soda-gql/common": "0.12.2",
|
|
54
|
+
"@soda-gql/config": "0.12.2",
|
|
55
|
+
"@soda-gql/core": "0.12.2",
|
|
56
56
|
"esbuild": "^0.24.0",
|
|
57
57
|
"fast-glob": "^3.3.0",
|
|
58
58
|
"graphql": "^16.11.0",
|