@graphitation/supermassive 3.11.12 → 3.13.0

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.
@@ -0,0 +1,338 @@
1
+ // src/utilities/subtractSchemaDefinitions.ts
2
+ import {
3
+ getDirectiveDefinitionArgs,
4
+ getDirectiveName,
5
+ getEnumValues,
6
+ getFieldTypeReference,
7
+ getFieldArgs,
8
+ getFields,
9
+ getInputObjectFields,
10
+ getInputValueTypeReference,
11
+ getUnionTypeMembers,
12
+ isEnumTypeDefinition,
13
+ isInputObjectTypeDefinition,
14
+ isInterfaceTypeDefinition,
15
+ isObjectTypeDefinition,
16
+ isScalarTypeDefinition,
17
+ isUnionTypeDefinition,
18
+ createEnumTypeDefinition,
19
+ createInputObjectTypeDefinition,
20
+ createInterfaceTypeDefinition,
21
+ createObjectTypeDefinition,
22
+ createUnionTypeDefinition,
23
+ getObjectTypeInterfaces,
24
+ getInterfaceTypeInterfaces
25
+ } from "../schema/definition.mjs";
26
+ import { inspect } from "../jsutils/inspect.mjs";
27
+ function subtractSchemaDefinitions(minuend, subtrahend, strict = false) {
28
+ const result = {
29
+ types: {},
30
+ directives: []
31
+ };
32
+ if (minuend.types && subtrahend.types) {
33
+ result.types = subtractTypes(minuend.types, subtrahend.types, strict);
34
+ } else if (minuend.types) {
35
+ result.types = { ...minuend.types };
36
+ }
37
+ if (minuend.directives && subtrahend.directives) {
38
+ result.directives = subtractDirectives(
39
+ minuend.directives,
40
+ subtrahend.directives,
41
+ strict
42
+ );
43
+ } else if (minuend.directives) {
44
+ result.directives = [...minuend.directives];
45
+ }
46
+ return result;
47
+ }
48
+ function subtractTypes(minuend, subtrahend, strict) {
49
+ const result = {};
50
+ for (const [typeName, minuendDef] of Object.entries(minuend)) {
51
+ const subtrahendDef = subtrahend[typeName];
52
+ if (!subtrahendDef) {
53
+ result[typeName] = minuendDef;
54
+ continue;
55
+ }
56
+ if (minuendDef[0] !== subtrahendDef[0]) {
57
+ throw new Error(
58
+ `Type ${typeName} is represented differently in different schema fragments:
59
+ ` + inspect(minuendDef) + `
60
+ ` + inspect(subtrahendDef)
61
+ );
62
+ }
63
+ const subtractedType = subtractType(
64
+ typeName,
65
+ minuendDef,
66
+ subtrahendDef,
67
+ strict
68
+ );
69
+ if (subtractedType) {
70
+ result[typeName] = subtractedType;
71
+ }
72
+ }
73
+ for (const typeName of Object.keys(subtrahend)) {
74
+ if (!(typeName in minuend)) {
75
+ if (strict) {
76
+ throw new Error(`Type ${typeName} does not exist in minuend`);
77
+ }
78
+ }
79
+ }
80
+ return result;
81
+ }
82
+ function subtractType(typeName, minuendDef, subtrahendDef, strict) {
83
+ if (isObjectTypeDefinition(minuendDef) && isObjectTypeDefinition(subtrahendDef)) {
84
+ const subtractedFields = subtractFields(
85
+ typeName,
86
+ getFields(minuendDef),
87
+ getFields(subtrahendDef),
88
+ strict
89
+ );
90
+ if (Object.keys(subtractedFields).length === 0) {
91
+ return null;
92
+ }
93
+ const interfaces = getObjectTypeInterfaces(minuendDef);
94
+ return createObjectTypeDefinition(
95
+ subtractedFields,
96
+ interfaces.length > 0 ? interfaces : void 0
97
+ );
98
+ }
99
+ if (isInterfaceTypeDefinition(minuendDef) && isInterfaceTypeDefinition(subtrahendDef)) {
100
+ const subtractedFields = subtractFields(
101
+ typeName,
102
+ getFields(minuendDef),
103
+ getFields(subtrahendDef),
104
+ strict
105
+ );
106
+ if (Object.keys(subtractedFields).length === 0) {
107
+ return null;
108
+ }
109
+ const interfaces = getInterfaceTypeInterfaces(minuendDef);
110
+ return createInterfaceTypeDefinition(
111
+ subtractedFields,
112
+ interfaces.length > 0 ? interfaces : void 0
113
+ );
114
+ }
115
+ if (isInputObjectTypeDefinition(minuendDef) && isInputObjectTypeDefinition(subtrahendDef)) {
116
+ const subtractedFields = subtractInputFields(
117
+ typeName,
118
+ getInputObjectFields(minuendDef),
119
+ getInputObjectFields(subtrahendDef),
120
+ strict
121
+ );
122
+ if (Object.keys(subtractedFields).length === 0) {
123
+ return null;
124
+ }
125
+ return createInputObjectTypeDefinition(subtractedFields);
126
+ }
127
+ if (isUnionTypeDefinition(minuendDef) && isUnionTypeDefinition(subtrahendDef)) {
128
+ const subtractedMembers = subtractUnionMembers(
129
+ typeName,
130
+ getUnionTypeMembers(minuendDef),
131
+ getUnionTypeMembers(subtrahendDef),
132
+ strict
133
+ );
134
+ if (subtractedMembers.length === 0) {
135
+ return null;
136
+ }
137
+ return createUnionTypeDefinition(subtractedMembers);
138
+ }
139
+ if (isEnumTypeDefinition(minuendDef) && isEnumTypeDefinition(subtrahendDef)) {
140
+ const subtractedValues = subtractEnumValues(
141
+ typeName,
142
+ getEnumValues(minuendDef),
143
+ getEnumValues(subtrahendDef),
144
+ strict
145
+ );
146
+ if (subtractedValues.length === 0) {
147
+ return null;
148
+ }
149
+ return createEnumTypeDefinition(subtractedValues);
150
+ }
151
+ if (isScalarTypeDefinition(minuendDef) && isScalarTypeDefinition(subtrahendDef)) {
152
+ return null;
153
+ }
154
+ return null;
155
+ }
156
+ function subtractFields(typeName, minuendFields, subtrahendFields, strict) {
157
+ const result = {};
158
+ for (const [fieldName, minuendField] of Object.entries(minuendFields)) {
159
+ const subtrahendField = subtrahendFields[fieldName];
160
+ if (!subtrahendField) {
161
+ result[fieldName] = minuendField;
162
+ continue;
163
+ }
164
+ const minuendType = getFieldTypeReference(minuendField);
165
+ const subtrahendType = getFieldTypeReference(subtrahendField);
166
+ if (minuendType !== subtrahendType) {
167
+ throw new Error(
168
+ `Field ${typeName}.${fieldName} has different type: ${inspect(
169
+ minuendType
170
+ )} vs ${inspect(subtrahendType)}`
171
+ );
172
+ }
173
+ const minuendArgs = getFieldArgs(minuendField);
174
+ const subtrahendArgs = getFieldArgs(subtrahendField);
175
+ if (!minuendArgs && !subtrahendArgs) {
176
+ } else if (!minuendArgs || !subtrahendArgs) {
177
+ throw new Error(
178
+ `Field arguments must match exactly for subtraction. Field ${typeName}.${fieldName} has different argument structures.`
179
+ );
180
+ } else {
181
+ const minuendArgKeys = Object.keys(minuendArgs).sort();
182
+ const subtrahendArgKeys = Object.keys(subtrahendArgs).sort();
183
+ if (minuendArgKeys.length !== subtrahendArgKeys.length || !minuendArgKeys.every((key, index) => key === subtrahendArgKeys[index])) {
184
+ throw new Error(
185
+ `Field arguments must match exactly for subtraction. Field ${typeName}.${fieldName} has different argument keys.`
186
+ );
187
+ }
188
+ for (const argName of minuendArgKeys) {
189
+ const minuendArgType = getInputValueTypeReference(minuendArgs[argName]);
190
+ const subtrahendArgType = getInputValueTypeReference(
191
+ subtrahendArgs[argName]
192
+ );
193
+ if (minuendArgType !== subtrahendArgType) {
194
+ throw new Error(
195
+ `Field arguments must match exactly for subtraction. Field ${typeName}.${fieldName} argument ${argName} has different types.`
196
+ );
197
+ }
198
+ }
199
+ }
200
+ }
201
+ for (const fieldName of Object.keys(subtrahendFields)) {
202
+ if (!(fieldName in minuendFields)) {
203
+ if (strict) {
204
+ throw new Error(
205
+ `Field ${typeName}.${fieldName} does not exist in minuend`
206
+ );
207
+ }
208
+ }
209
+ }
210
+ return result;
211
+ }
212
+ function subtractInputFields(typeName, minuendFields, subtrahendFields, strict) {
213
+ const result = {};
214
+ for (const [fieldName, minuendField] of Object.entries(minuendFields)) {
215
+ const subtrahendField = subtrahendFields[fieldName];
216
+ if (!subtrahendField) {
217
+ result[fieldName] = minuendField;
218
+ continue;
219
+ }
220
+ const minuendType = getInputValueTypeReference(minuendField);
221
+ const subtrahendType = getInputValueTypeReference(subtrahendField);
222
+ if (minuendType !== subtrahendType) {
223
+ throw new Error(
224
+ `Input field ${typeName}.${fieldName} has different type: ${inspect(
225
+ minuendType
226
+ )} vs ${inspect(subtrahendType)}`
227
+ );
228
+ }
229
+ }
230
+ for (const fieldName of Object.keys(subtrahendFields)) {
231
+ if (!(fieldName in minuendFields)) {
232
+ if (strict) {
233
+ throw new Error(
234
+ `Input field ${typeName}.${fieldName} does not exist in minuend`
235
+ );
236
+ }
237
+ }
238
+ }
239
+ return result;
240
+ }
241
+ function subtractUnionMembers(typeName, minuendMembers, subtrahendMembers, strict) {
242
+ const minuendSet = new Set(minuendMembers);
243
+ const subtrahendSet = new Set(subtrahendMembers);
244
+ if (minuendMembers.length === subtrahendMembers.length && minuendMembers.every((member) => subtrahendSet.has(member))) {
245
+ return [];
246
+ }
247
+ for (const member of subtrahendMembers) {
248
+ if (!minuendSet.has(member)) {
249
+ if (strict) {
250
+ throw new Error(
251
+ `Union ${typeName}: member ${member} does not exist in minuend`
252
+ );
253
+ }
254
+ return minuendMembers;
255
+ }
256
+ }
257
+ throw new Error(
258
+ `Union types must match exactly for subtraction. Union ${typeName} has different member sets.`
259
+ );
260
+ }
261
+ function subtractEnumValues(typeName, minuendValues, subtrahendValues, strict) {
262
+ const minuendSet = new Set(minuendValues);
263
+ const subtrahendSet = new Set(subtrahendValues);
264
+ if (minuendValues.length === subtrahendValues.length && minuendValues.every((value) => subtrahendSet.has(value))) {
265
+ return [];
266
+ }
267
+ for (const value of subtrahendValues) {
268
+ if (!minuendSet.has(value)) {
269
+ if (strict) {
270
+ throw new Error(
271
+ `Enum ${typeName}: value ${value} does not exist in minuend`
272
+ );
273
+ }
274
+ return minuendValues;
275
+ }
276
+ }
277
+ throw new Error(
278
+ `Enum types must match exactly for subtraction. Enum ${typeName} has different value sets.`
279
+ );
280
+ }
281
+ function subtractDirectives(minuendDirectives, subtrahendDirectives, strict) {
282
+ const result = [];
283
+ for (const minuendDirective of minuendDirectives) {
284
+ const minuendName = getDirectiveName(minuendDirective);
285
+ const subtrahendDirective = subtrahendDirectives.find(
286
+ (d) => getDirectiveName(d) === minuendName
287
+ );
288
+ if (!subtrahendDirective) {
289
+ result.push(minuendDirective);
290
+ continue;
291
+ }
292
+ const minuendArgs = getDirectiveDefinitionArgs(minuendDirective);
293
+ const subtrahendArgs = getDirectiveDefinitionArgs(subtrahendDirective);
294
+ if (!minuendArgs && !subtrahendArgs) {
295
+ continue;
296
+ }
297
+ if (!minuendArgs || !subtrahendArgs) {
298
+ throw new Error(
299
+ `Directive arguments must match exactly for subtraction. Directive ${minuendName} has different argument structures.`
300
+ );
301
+ }
302
+ const minuendArgKeys = Object.keys(minuendArgs).sort();
303
+ const subtrahendArgKeys = Object.keys(subtrahendArgs).sort();
304
+ if (minuendArgKeys.length !== subtrahendArgKeys.length || !minuendArgKeys.every((key, index) => key === subtrahendArgKeys[index])) {
305
+ throw new Error(
306
+ `Directive arguments must match exactly for subtraction. Directive ${minuendName} has different argument keys.`
307
+ );
308
+ }
309
+ for (const argName of minuendArgKeys) {
310
+ const minuendArgType = getInputValueTypeReference(minuendArgs[argName]);
311
+ const subtrahendArgType = getInputValueTypeReference(
312
+ subtrahendArgs[argName]
313
+ );
314
+ if (minuendArgType !== subtrahendArgType) {
315
+ throw new Error(
316
+ `Directive arguments must match exactly for subtraction. Directive ${minuendName} argument ${argName} has different types.`
317
+ );
318
+ }
319
+ }
320
+ }
321
+ for (const subtrahendDirective of subtrahendDirectives) {
322
+ const subtrahendName = getDirectiveName(subtrahendDirective);
323
+ const exists = minuendDirectives.some(
324
+ (d) => getDirectiveName(d) === subtrahendName
325
+ );
326
+ if (!exists) {
327
+ if (strict) {
328
+ throw new Error(
329
+ `Directive ${subtrahendName} does not exist in minuend`
330
+ );
331
+ }
332
+ }
333
+ }
334
+ return result;
335
+ }
336
+ export {
337
+ subtractSchemaDefinitions
338
+ };
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utilities/subtractSchemaDefinitions.ts"],
4
+ "sourcesContent": ["// Note: this utility is vibe-coded. Use at your own risk! :)\nimport {\n SchemaDefinitions,\n DirectiveDefinitionTuple,\n FieldDefinitionRecord,\n InputValueDefinitionRecord,\n TypeDefinitionsRecord,\n TypeDefinitionTuple,\n getDirectiveDefinitionArgs,\n getDirectiveName,\n getEnumValues,\n getFieldTypeReference,\n getFieldArgs,\n getFields,\n getInputObjectFields,\n getInputValueTypeReference,\n getUnionTypeMembers,\n isEnumTypeDefinition,\n isInputObjectTypeDefinition,\n isInterfaceTypeDefinition,\n isObjectTypeDefinition,\n isScalarTypeDefinition,\n isUnionTypeDefinition,\n createEnumTypeDefinition,\n createInputObjectTypeDefinition,\n createInterfaceTypeDefinition,\n createObjectTypeDefinition,\n createUnionTypeDefinition,\n getObjectTypeInterfaces,\n getInterfaceTypeInterfaces,\n} from \"../schema/definition\";\nimport { inspect } from \"../jsutils/inspect\";\n\n/**\n * Subtracts schema definitions from minuend that exist in subtrahend.\n * Returns a new SchemaDefinitions object without mutating inputs.\n *\n * @param minuend - The schema definitions to subtract from\n * @param subtrahend - The schema definitions to subtract\n * @param strict - If true, throws errors on items in subtrahend that are not in minuend; if false, ignores them\n * @returns A new SchemaDefinitions with elements from minuend not in subtrahend\n */\nexport function subtractSchemaDefinitions(\n minuend: SchemaDefinitions,\n subtrahend: SchemaDefinitions,\n strict = false,\n): SchemaDefinitions {\n const result: SchemaDefinitions = {\n types: {},\n directives: [],\n };\n\n // Subtract types\n if (minuend.types && subtrahend.types) {\n result.types = subtractTypes(minuend.types, subtrahend.types, strict);\n } else if (minuend.types) {\n result.types = { ...minuend.types };\n }\n\n // Subtract directives\n if (minuend.directives && subtrahend.directives) {\n result.directives = subtractDirectives(\n minuend.directives,\n subtrahend.directives,\n strict,\n );\n } else if (minuend.directives) {\n result.directives = [...minuend.directives];\n }\n\n return result;\n}\n\n/**\n * Subtracts types from minuend that exist in subtrahend.\n */\nfunction subtractTypes(\n minuend: TypeDefinitionsRecord,\n subtrahend: TypeDefinitionsRecord,\n strict: boolean,\n): TypeDefinitionsRecord {\n const result: TypeDefinitionsRecord = {};\n\n for (const [typeName, minuendDef] of Object.entries(minuend)) {\n const subtrahendDef = subtrahend[typeName];\n\n if (!subtrahendDef) {\n // Type doesn't exist in subtrahend, keep it\n result[typeName] = minuendDef;\n continue;\n }\n\n // Validate type kinds match\n if (minuendDef[0] !== subtrahendDef[0]) {\n throw new Error(\n `Type ${typeName} is represented differently in different schema fragments:\\n` +\n inspect(minuendDef) +\n `\\n` +\n inspect(subtrahendDef),\n );\n }\n\n // Handle different type kinds\n const subtractedType = subtractType(\n typeName,\n minuendDef,\n subtrahendDef,\n strict,\n );\n if (subtractedType) {\n result[typeName] = subtractedType;\n }\n }\n\n // Check for types in subtrahend that don't exist in minuend\n for (const typeName of Object.keys(subtrahend)) {\n if (!(typeName in minuend)) {\n if (strict) {\n throw new Error(`Type ${typeName} does not exist in minuend`);\n }\n // In non-strict mode, ignore missing types\n }\n }\n\n return result;\n}\n\n/**\n * Subtracts a single type definition.\n */\nfunction subtractType(\n typeName: string,\n minuendDef: TypeDefinitionTuple,\n subtrahendDef: TypeDefinitionTuple,\n strict: boolean,\n): TypeDefinitionTuple | null {\n if (\n isObjectTypeDefinition(minuendDef) &&\n isObjectTypeDefinition(subtrahendDef)\n ) {\n const subtractedFields = subtractFields(\n typeName,\n getFields(minuendDef),\n getFields(subtrahendDef),\n strict,\n );\n if (Object.keys(subtractedFields).length === 0) {\n return null; // All fields removed\n }\n const interfaces = getObjectTypeInterfaces(minuendDef);\n return createObjectTypeDefinition(\n subtractedFields,\n interfaces.length > 0 ? interfaces : undefined,\n );\n }\n\n if (\n isInterfaceTypeDefinition(minuendDef) &&\n isInterfaceTypeDefinition(subtrahendDef)\n ) {\n const subtractedFields = subtractFields(\n typeName,\n getFields(minuendDef),\n getFields(subtrahendDef),\n strict,\n );\n if (Object.keys(subtractedFields).length === 0) {\n return null; // All fields removed\n }\n const interfaces = getInterfaceTypeInterfaces(minuendDef);\n return createInterfaceTypeDefinition(\n subtractedFields,\n interfaces.length > 0 ? interfaces : undefined,\n );\n }\n\n if (\n isInputObjectTypeDefinition(minuendDef) &&\n isInputObjectTypeDefinition(subtrahendDef)\n ) {\n const subtractedFields = subtractInputFields(\n typeName,\n getInputObjectFields(minuendDef),\n getInputObjectFields(subtrahendDef),\n strict,\n );\n if (Object.keys(subtractedFields).length === 0) {\n return null; // All fields removed\n }\n return createInputObjectTypeDefinition(subtractedFields);\n }\n\n if (\n isUnionTypeDefinition(minuendDef) &&\n isUnionTypeDefinition(subtrahendDef)\n ) {\n const subtractedMembers = subtractUnionMembers(\n typeName,\n getUnionTypeMembers(minuendDef),\n getUnionTypeMembers(subtrahendDef),\n strict,\n );\n if (subtractedMembers.length === 0) {\n return null; // All members removed\n }\n return createUnionTypeDefinition(subtractedMembers);\n }\n\n if (isEnumTypeDefinition(minuendDef) && isEnumTypeDefinition(subtrahendDef)) {\n const subtractedValues = subtractEnumValues(\n typeName,\n getEnumValues(minuendDef),\n getEnumValues(subtrahendDef),\n strict,\n );\n if (subtractedValues.length === 0) {\n return null; // All values removed\n }\n return createEnumTypeDefinition(subtractedValues);\n }\n\n if (\n isScalarTypeDefinition(minuendDef) &&\n isScalarTypeDefinition(subtrahendDef)\n ) {\n // Scalars are atomic - if subtrahend has it, remove entire scalar\n return null;\n }\n\n return null;\n}\n\n/**\n * Subtracts fields from object/interface types.\n */\nfunction subtractFields(\n typeName: string,\n minuendFields: FieldDefinitionRecord,\n subtrahendFields: FieldDefinitionRecord,\n strict: boolean,\n): FieldDefinitionRecord {\n const result: FieldDefinitionRecord = {};\n\n for (const [fieldName, minuendField] of Object.entries(minuendFields)) {\n const subtrahendField = subtrahendFields[fieldName];\n\n if (!subtrahendField) {\n // Field doesn't exist in subtrahend, keep it\n result[fieldName] = minuendField;\n continue;\n }\n\n // Validate field types match\n const minuendType = getFieldTypeReference(minuendField);\n const subtrahendType = getFieldTypeReference(subtrahendField);\n if (minuendType !== subtrahendType) {\n throw new Error(\n `Field ${typeName}.${fieldName} has different type: ${inspect(\n minuendType,\n )} vs ${inspect(subtrahendType)}`,\n );\n }\n\n // Validate field arguments match exactly\n const minuendArgs = getFieldArgs(minuendField);\n const subtrahendArgs = getFieldArgs(subtrahendField);\n\n // Both must have same argument structure\n if (!minuendArgs && !subtrahendArgs) {\n // Both have no arguments, field can be subtracted\n } else if (!minuendArgs || !subtrahendArgs) {\n // One has args, other doesn't - not exact match\n throw new Error(\n `Field arguments must match exactly for subtraction. Field ${typeName}.${fieldName} has different argument structures.`,\n );\n } else {\n // Both have arguments, compare them\n const minuendArgKeys = Object.keys(minuendArgs).sort();\n const subtrahendArgKeys = Object.keys(subtrahendArgs).sort();\n\n if (\n minuendArgKeys.length !== subtrahendArgKeys.length ||\n !minuendArgKeys.every((key, index) => key === subtrahendArgKeys[index])\n ) {\n throw new Error(\n `Field arguments must match exactly for subtraction. Field ${typeName}.${fieldName} has different argument keys.`,\n );\n }\n\n // Check each argument type matches\n for (const argName of minuendArgKeys) {\n const minuendArgType = getInputValueTypeReference(minuendArgs[argName]);\n const subtrahendArgType = getInputValueTypeReference(\n subtrahendArgs[argName],\n );\n if (minuendArgType !== subtrahendArgType) {\n throw new Error(\n `Field arguments must match exactly for subtraction. Field ${typeName}.${fieldName} argument ${argName} has different types.`,\n );\n }\n }\n }\n\n // Field exists in subtrahend and matches exactly, remove it\n }\n\n // Check for fields in subtrahend that don't exist in minuend\n for (const fieldName of Object.keys(subtrahendFields)) {\n if (!(fieldName in minuendFields)) {\n if (strict) {\n throw new Error(\n `Field ${typeName}.${fieldName} does not exist in minuend`,\n );\n }\n // In non-strict mode, ignore missing fields\n }\n }\n\n return result;\n}\n\n/**\n * Subtracts input fields from input object types.\n */\nfunction subtractInputFields(\n typeName: string,\n minuendFields: InputValueDefinitionRecord,\n subtrahendFields: InputValueDefinitionRecord,\n strict: boolean,\n): InputValueDefinitionRecord {\n const result: InputValueDefinitionRecord = {};\n\n for (const [fieldName, minuendField] of Object.entries(minuendFields)) {\n const subtrahendField = subtrahendFields[fieldName];\n\n if (!subtrahendField) {\n // Field doesn't exist in subtrahend, keep it\n result[fieldName] = minuendField;\n continue;\n }\n\n // Validate field types match\n const minuendType = getInputValueTypeReference(minuendField);\n const subtrahendType = getInputValueTypeReference(subtrahendField);\n if (minuendType !== subtrahendType) {\n throw new Error(\n `Input field ${typeName}.${fieldName} has different type: ${inspect(\n minuendType,\n )} vs ${inspect(subtrahendType)}`,\n );\n }\n\n // Field exists in subtrahend, remove it\n }\n\n // Check for fields in subtrahend that don't exist in minuend\n for (const fieldName of Object.keys(subtrahendFields)) {\n if (!(fieldName in minuendFields)) {\n if (strict) {\n throw new Error(\n `Input field ${typeName}.${fieldName} does not exist in minuend`,\n );\n }\n // In non-strict mode, ignore missing fields\n }\n }\n\n return result;\n}\n\n/**\n * Subtracts union members.\n */\nfunction subtractUnionMembers(\n typeName: string,\n minuendMembers: string[],\n subtrahendMembers: string[],\n strict: boolean,\n): string[] {\n // Union types must match exactly for subtraction\n const minuendSet = new Set(minuendMembers);\n const subtrahendSet = new Set(subtrahendMembers);\n\n // Check if they have the same members\n if (\n minuendMembers.length === subtrahendMembers.length &&\n minuendMembers.every((member) => subtrahendSet.has(member))\n ) {\n // Exact match - remove the entire union\n return [];\n }\n\n // Check for members in subtrahend that don't exist in minuend\n for (const member of subtrahendMembers) {\n if (!minuendSet.has(member)) {\n if (strict) {\n throw new Error(\n `Union ${typeName}: member ${member} does not exist in minuend`,\n );\n }\n // In non-strict mode, ignore missing members and keep the original union\n return minuendMembers;\n }\n }\n\n // If we get here, all subtrahend members exist in minuend but they don't match exactly\n throw new Error(\n `Union types must match exactly for subtraction. Union ${typeName} has different member sets.`,\n );\n}\n\n/**\n * Subtracts enum values.\n */\nfunction subtractEnumValues(\n typeName: string,\n minuendValues: string[],\n subtrahendValues: string[],\n strict: boolean,\n): string[] {\n // Enum types must match exactly for subtraction\n const minuendSet = new Set(minuendValues);\n const subtrahendSet = new Set(subtrahendValues);\n\n // Check if they have the same values\n if (\n minuendValues.length === subtrahendValues.length &&\n minuendValues.every((value) => subtrahendSet.has(value))\n ) {\n // Exact match - remove the entire enum\n return [];\n }\n\n // Check for values in subtrahend that don't exist in minuend\n for (const value of subtrahendValues) {\n if (!minuendSet.has(value)) {\n if (strict) {\n throw new Error(\n `Enum ${typeName}: value ${value} does not exist in minuend`,\n );\n }\n // In non-strict mode, ignore missing values and keep the original enum\n return minuendValues;\n }\n }\n\n // If we get here, all subtrahend values exist in minuend but they don't match exactly\n throw new Error(\n `Enum types must match exactly for subtraction. Enum ${typeName} has different value sets.`,\n );\n}\n\n/**\n * Subtracts directives.\n */\nfunction subtractDirectives(\n minuendDirectives: DirectiveDefinitionTuple[],\n subtrahendDirectives: DirectiveDefinitionTuple[],\n strict: boolean,\n): DirectiveDefinitionTuple[] {\n const result: DirectiveDefinitionTuple[] = [];\n\n for (const minuendDirective of minuendDirectives) {\n const minuendName = getDirectiveName(minuendDirective);\n const subtrahendDirective = subtrahendDirectives.find(\n (d) => getDirectiveName(d) === minuendName,\n );\n\n if (!subtrahendDirective) {\n // Directive doesn't exist in subtrahend, keep it\n result.push(minuendDirective);\n continue;\n }\n\n // Directive exists, check arguments\n const minuendArgs = getDirectiveDefinitionArgs(minuendDirective);\n const subtrahendArgs = getDirectiveDefinitionArgs(subtrahendDirective);\n\n if (!minuendArgs && !subtrahendArgs) {\n // Both have no arguments, remove entire directive\n continue;\n }\n\n if (!minuendArgs || !subtrahendArgs) {\n // One has args, other doesn't - arguments don't match exactly\n throw new Error(\n `Directive arguments must match exactly for subtraction. Directive ${minuendName} has different argument structures.`,\n );\n }\n\n // Both have arguments, check if they match exactly\n const minuendArgKeys = Object.keys(minuendArgs).sort();\n const subtrahendArgKeys = Object.keys(subtrahendArgs).sort();\n\n if (\n minuendArgKeys.length !== subtrahendArgKeys.length ||\n !minuendArgKeys.every((key, index) => key === subtrahendArgKeys[index])\n ) {\n throw new Error(\n `Directive arguments must match exactly for subtraction. Directive ${minuendName} has different argument keys.`,\n );\n }\n\n // Check each argument type matches\n for (const argName of minuendArgKeys) {\n const minuendArgType = getInputValueTypeReference(minuendArgs[argName]);\n const subtrahendArgType = getInputValueTypeReference(\n subtrahendArgs[argName],\n );\n if (minuendArgType !== subtrahendArgType) {\n throw new Error(\n `Directive arguments must match exactly for subtraction. Directive ${minuendName} argument ${argName} has different types.`,\n );\n }\n }\n\n // Arguments match exactly, remove entire directive\n }\n\n // Check for directives in subtrahend that don't exist in minuend\n for (const subtrahendDirective of subtrahendDirectives) {\n const subtrahendName = getDirectiveName(subtrahendDirective);\n const exists = minuendDirectives.some(\n (d) => getDirectiveName(d) === subtrahendName,\n );\n if (!exists) {\n if (strict) {\n throw new Error(\n `Directive ${subtrahendName} does not exist in minuend`,\n );\n }\n // In non-strict mode, ignore missing directives\n }\n }\n\n return result;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@graphitation/supermassive",
3
3
  "license": "MIT",
4
- "version": "3.11.12",
4
+ "version": "3.13.0",
5
5
  "main": "./lib/index",
6
6
  "repository": {
7
7
  "type": "git",