@wundergraph/protographic 0.11.0 → 0.12.1
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/README.md +34 -3
- package/dist/src/index.d.ts +15 -0
- package/dist/src/index.js +10 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/operation-to-proto.d.ts +48 -0
- package/dist/src/operation-to-proto.js +378 -0
- package/dist/src/operation-to-proto.js.map +1 -0
- package/dist/src/operations/field-numbering.d.ts +73 -0
- package/dist/src/operations/field-numbering.js +134 -0
- package/dist/src/operations/field-numbering.js.map +1 -0
- package/dist/src/operations/list-type-utils.d.ts +28 -0
- package/dist/src/operations/list-type-utils.js +49 -0
- package/dist/src/operations/list-type-utils.js.map +1 -0
- package/dist/src/operations/message-builder.d.ts +58 -0
- package/dist/src/operations/message-builder.js +377 -0
- package/dist/src/operations/message-builder.js.map +1 -0
- package/dist/src/operations/proto-text-generator.d.ts +74 -0
- package/dist/src/operations/proto-text-generator.js +336 -0
- package/dist/src/operations/proto-text-generator.js.map +1 -0
- package/dist/src/operations/request-builder.d.ts +56 -0
- package/dist/src/operations/request-builder.js +194 -0
- package/dist/src/operations/request-builder.js.map +1 -0
- package/dist/src/operations/type-mapper.d.ts +66 -0
- package/dist/src/operations/type-mapper.js +236 -0
- package/dist/src/operations/type-mapper.js.map +1 -0
- package/dist/src/proto-options.d.ts +23 -0
- package/dist/src/proto-options.js +45 -0
- package/dist/src/proto-options.js.map +1 -0
- package/dist/src/sdl-to-proto-visitor.d.ts +2 -14
- package/dist/src/sdl-to-proto-visitor.js +25 -38
- package/dist/src/sdl-to-proto-visitor.js.map +1 -1
- package/dist/src/types.d.ts +12 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -4,18 +4,21 @@ A tool for converting GraphQL Schema Definition Language (SDL) to Protocol Buffe
|
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
Protographic bridges GraphQL and Protocol Buffers (protobuf) ecosystems through
|
|
7
|
+
Protographic bridges GraphQL and Protocol Buffers (protobuf) ecosystems through three core functions:
|
|
8
8
|
|
|
9
9
|
1. **GraphQL SDL to Protocol Buffer (Proto) Compiler**: Transforms GraphQL schemas into Proto3 format, allowing developers to write gRPC services using GraphQL SDL and integrate them seamlessly into the Cosmo Router as standard subgraphs. This is used at build-time.
|
|
10
10
|
|
|
11
|
-
2. **GraphQL
|
|
11
|
+
2. **GraphQL Operations to Protocol Buffer Compiler** ⚠️ **ALPHA**: Converts GraphQL operations (queries, mutations, subscriptions) into Proto3 service definitions with corresponding request/response messages. This enables operation-first development where you define your API through GraphQL operations rather than schema types.
|
|
12
|
+
|
|
13
|
+
3. **GraphQL SDL to Mapping Compiler**: Creates mapping definitions that maintain the semantic relationships between GraphQL types while adapting them to Protocol Buffer's structural model. This is used by the Cosmo Router at runtime.
|
|
12
14
|
|
|
13
15
|
## Key Features
|
|
14
16
|
|
|
15
17
|
- Precise conversion of GraphQL types to Protocol Buffer messages
|
|
18
|
+
- **Operations-to-Proto** (alpha): Generate proto services directly from GraphQL operations
|
|
16
19
|
- Consistent naming conventions across GraphQL and Proto definitions
|
|
17
20
|
- Streamlined mapping of GraphQL operations to RPC methods
|
|
18
|
-
-
|
|
21
|
+
- Handles GraphQL features including unions, interfaces, directives, and fragments
|
|
19
22
|
- First-class support for Federation entity mapping
|
|
20
23
|
- Deterministic field ordering with proto.lock.json for backward compatibility
|
|
21
24
|
- Use of Protocol Buffer wrappers for nullable fields to distinguish between semantic nulls and zero values
|
|
@@ -114,6 +117,34 @@ The lock data records the order of:
|
|
|
114
117
|
|
|
115
118
|
New fields are always added at the end, maintaining backward compatibility with existing proto messages.
|
|
116
119
|
|
|
120
|
+
### Converting GraphQL Operations to Protocol Buffer ⚠️ ALPHA
|
|
121
|
+
|
|
122
|
+
> **Note**: This feature is currently in alpha. The API may change in future releases.
|
|
123
|
+
|
|
124
|
+
Protographic can generate proto services directly from GraphQL operations, enabling an operation-first development approach. For detailed documentation, see [OPERATIONS_TO_PROTO.md](OPERATIONS_TO_PROTO.md).
|
|
125
|
+
|
|
126
|
+
Quick example:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { compileOperationsToProto } from '@wundergraph/protographic';
|
|
130
|
+
|
|
131
|
+
const operation = `
|
|
132
|
+
query GetUser($userId: ID!) {
|
|
133
|
+
user(id: $userId) {
|
|
134
|
+
id
|
|
135
|
+
name
|
|
136
|
+
email
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
`;
|
|
140
|
+
|
|
141
|
+
const result = compileOperationsToProto(operation, schema, {
|
|
142
|
+
serviceName: 'UserService',
|
|
143
|
+
packageName: 'user.v1',
|
|
144
|
+
prefixOperationType: true
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
117
148
|
### Generating Mapping Definitions
|
|
118
149
|
|
|
119
150
|
```typescript
|
package/dist/src/index.d.ts
CHANGED
|
@@ -42,7 +42,22 @@ export * from './sdl-to-mapping-visitor.js';
|
|
|
42
42
|
export { GraphQLToProtoTextVisitor } from './sdl-to-proto-visitor.js';
|
|
43
43
|
export { ProtoLockManager } from './proto-lock.js';
|
|
44
44
|
export { SDLValidationVisitor } from './sdl-validation-visitor.js';
|
|
45
|
+
export { compileOperationsToProto } from './operation-to-proto.js';
|
|
46
|
+
export type { OperationsToProtoOptions, CompileOperationsToProtoResult } from './operation-to-proto.js';
|
|
47
|
+
export { mapGraphQLTypeToProto, getProtoTypeName, isGraphQLScalarType, requiresWrapperType, getRequiredImports, } from './operations/type-mapper.js';
|
|
48
|
+
export type { ProtoTypeInfo, TypeMapperOptions } from './operations/type-mapper.js';
|
|
49
|
+
export { createFieldNumberManager } from './operations/field-numbering.js';
|
|
50
|
+
export type { FieldNumberManager } from './operations/field-numbering.js';
|
|
51
|
+
export { buildMessageFromSelectionSet, buildFieldDefinition, buildNestedMessage, } from './operations/message-builder.js';
|
|
52
|
+
export type { MessageBuilderOptions } from './operations/message-builder.js';
|
|
53
|
+
export { buildRequestMessage, buildInputObjectMessage, buildEnumType } from './operations/request-builder.js';
|
|
54
|
+
export type { RequestBuilderOptions } from './operations/request-builder.js';
|
|
55
|
+
export { rootToProtoText, serviceToProtoText, messageToProtoText, enumToProtoText, formatField, } from './operations/proto-text-generator.js';
|
|
56
|
+
export type { ProtoTextOptions } from './operations/proto-text-generator.js';
|
|
57
|
+
export type { IdempotencyLevel, MethodWithIdempotency } from './types.js';
|
|
45
58
|
export type { GraphQLToProtoTextVisitorOptions, ProtoOption } from './sdl-to-proto-visitor.js';
|
|
59
|
+
export type { ProtoOptions } from './proto-options.js';
|
|
46
60
|
export type { ProtoLock } from './proto-lock.js';
|
|
47
61
|
export type { ValidationResult } from './sdl-validation-visitor.js';
|
|
48
62
|
export { GRPCMapping, OperationMapping, EntityMapping, TypeFieldMapping, FieldMapping, ArgumentMapping, EnumMapping, EnumValueMapping, OperationType, } from '@wundergraph/cosmo-connect/dist/node/v1/node_pb';
|
|
63
|
+
export { default as protobuf } from 'protobufjs';
|
package/dist/src/index.js
CHANGED
|
@@ -62,5 +62,15 @@ export * from './sdl-to-mapping-visitor.js';
|
|
|
62
62
|
export { GraphQLToProtoTextVisitor } from './sdl-to-proto-visitor.js';
|
|
63
63
|
export { ProtoLockManager } from './proto-lock.js';
|
|
64
64
|
export { SDLValidationVisitor } from './sdl-validation-visitor.js';
|
|
65
|
+
// Export operation-to-proto functionality
|
|
66
|
+
export { compileOperationsToProto } from './operation-to-proto.js';
|
|
67
|
+
// Export operation modules
|
|
68
|
+
export { mapGraphQLTypeToProto, getProtoTypeName, isGraphQLScalarType, requiresWrapperType, getRequiredImports, } from './operations/type-mapper.js';
|
|
69
|
+
export { createFieldNumberManager } from './operations/field-numbering.js';
|
|
70
|
+
export { buildMessageFromSelectionSet, buildFieldDefinition, buildNestedMessage, } from './operations/message-builder.js';
|
|
71
|
+
export { buildRequestMessage, buildInputObjectMessage, buildEnumType } from './operations/request-builder.js';
|
|
72
|
+
export { rootToProtoText, serviceToProtoText, messageToProtoText, enumToProtoText, formatField, } from './operations/proto-text-generator.js';
|
|
65
73
|
export { GRPCMapping, OperationMapping, EntityMapping, TypeFieldMapping, FieldMapping, ArgumentMapping, EnumMapping, EnumValueMapping, OperationType, } from '@wundergraph/cosmo-connect/dist/node/v1/node_pb';
|
|
74
|
+
// Export protobufjs for AST manipulation
|
|
75
|
+
export { default as protobuf } from 'protobufjs';
|
|
66
76
|
//# sourceMappingURL=index.js.map
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAiB,MAAM,SAAS,CAAC;AAErD,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAEpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAEtE,OAAO,EAAE,oBAAoB,EAAyB,MAAM,6BAA6B,CAAC;AAE1F;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CACrC,WAAmC,EACnC,cAAsB,gBAAgB;IAEtC,6CAA6C;IAC7C,MAAM,MAAM,GACV,OAAO,WAAW,KAAK,QAAQ;QAC7B,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE;YACvB,WAAW,EAAE,IAAI,EAAE,oCAAoC;YACvD,cAAc,EAAE,IAAI,EAAE,sBAAsB;SAC7C,CAAC;QACJ,CAAC,CAAC,WAAW,CAAC;IAElB,6BAA6B;IAC7B,MAAM,OAAO,GAAG,IAAI,qBAAqB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC,KAAK,EAAE,CAAC;AACzB,CAAC;AAcD;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,WAAmC,EACnC,OAA0C;IAE1C,6CAA6C;IAC7C,MAAM,MAAM,GACV,OAAO,WAAW,KAAK,QAAQ;QAC7B,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE;YACvB,WAAW,EAAE,IAAI,EAAE,oCAAoC;YACvD,cAAc,EAAE,IAAI,EAAE,sBAAsB;SAC7C,CAAC;QACJ,CAAC,CAAC,WAAW,CAAC;IAElB,yDAAyD;IACzD,MAAM,OAAO,GAAG,IAAI,yBAAyB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE/D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAE9B,8BAA8B;IAC9B,MAAM,iBAAiB,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAEzD,wDAAwD;IACxD,OAAO;QACL,KAAK;QACL,QAAQ,EAAE,iBAAiB;KAC5B,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,MAAM,OAAO,GAAG,IAAI,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC9C,OAAO,OAAO,CAAC,KAAK,EAAE,CAAC;AACzB,CAAC;AAED,cAAc,6BAA6B,CAAC;AAC5C,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import protobuf from 'protobufjs';
|
|
2
|
+
import { DocumentNode, GraphQLSchema } from 'graphql';
|
|
3
|
+
import { ProtoLock } from './proto-lock.js';
|
|
4
|
+
import { IdempotencyLevel } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Options for converting operations to proto
|
|
7
|
+
*/
|
|
8
|
+
export interface OperationsToProtoOptions {
|
|
9
|
+
serviceName?: string;
|
|
10
|
+
packageName?: string;
|
|
11
|
+
goPackage?: string;
|
|
12
|
+
javaPackage?: string;
|
|
13
|
+
javaOuterClassname?: string;
|
|
14
|
+
javaMultipleFiles?: boolean;
|
|
15
|
+
csharpNamespace?: string;
|
|
16
|
+
rubyPackage?: string;
|
|
17
|
+
phpNamespace?: string;
|
|
18
|
+
phpMetadataNamespace?: string;
|
|
19
|
+
objcClassPrefix?: string;
|
|
20
|
+
swiftPrefix?: string;
|
|
21
|
+
includeComments?: boolean;
|
|
22
|
+
queryIdempotency?: IdempotencyLevel;
|
|
23
|
+
/** Lock data from previous compilation for field number stability */
|
|
24
|
+
lockData?: ProtoLock;
|
|
25
|
+
/** Custom scalar type mappings (scalar name -> proto type) */
|
|
26
|
+
customScalarMappings?: Record<string, string>;
|
|
27
|
+
/** Maximum recursion depth to prevent stack overflow (default: 50) */
|
|
28
|
+
maxDepth?: number;
|
|
29
|
+
/** Prefix RPC method names with operation type (e.g., QueryGetUser, MutationCreateUser) */
|
|
30
|
+
prefixOperationType?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Result of compiling operations to proto
|
|
34
|
+
*/
|
|
35
|
+
export interface CompileOperationsToProtoResult {
|
|
36
|
+
proto: string;
|
|
37
|
+
root: protobuf.Root;
|
|
38
|
+
/** Lock data for field number stability across compilations */
|
|
39
|
+
lockData: ProtoLock;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Compiles a collection of GraphQL operations to protocol buffer definition
|
|
43
|
+
* @param operationSource - GraphQL operations as a string or DocumentNode
|
|
44
|
+
* @param schemaOrSDL - GraphQL schema or SDL string
|
|
45
|
+
* @param options - Configuration options for the compilation
|
|
46
|
+
* @returns Proto text and protobufjs root object
|
|
47
|
+
*/
|
|
48
|
+
export declare function compileOperationsToProto(operationSource: string | DocumentNode, schemaOrSDL: GraphQLSchema | string, options?: OperationsToProtoOptions): CompileOperationsToProtoResult;
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import protobuf from 'protobufjs';
|
|
2
|
+
import { buildSchema, OperationTypeNode, parse, TypeInfo, visit, visitWithTypeInfo, getNamedType, isInputObjectType, isEnumType, Kind, validate, specifiedRules, KnownDirectivesRule, } from 'graphql';
|
|
3
|
+
import { createFieldNumberManager } from './operations/field-numbering.js';
|
|
4
|
+
import { buildMessageFromSelectionSet } from './operations/message-builder.js';
|
|
5
|
+
import { buildRequestMessage, buildInputObjectMessage, buildEnumType } from './operations/request-builder.js';
|
|
6
|
+
import { rootToProtoText } from './operations/proto-text-generator.js';
|
|
7
|
+
import { mapGraphQLTypeToProto } from './operations/type-mapper.js';
|
|
8
|
+
import { createRequestMessageName, createResponseMessageName, } from './naming-conventions.js';
|
|
9
|
+
import { upperFirst, camelCase } from 'lodash-es';
|
|
10
|
+
import { ProtoLockManager } from './proto-lock.js';
|
|
11
|
+
/**
|
|
12
|
+
* Compiles a collection of GraphQL operations to protocol buffer definition
|
|
13
|
+
* @param operationSource - GraphQL operations as a string or DocumentNode
|
|
14
|
+
* @param schemaOrSDL - GraphQL schema or SDL string
|
|
15
|
+
* @param options - Configuration options for the compilation
|
|
16
|
+
* @returns Proto text and protobufjs root object
|
|
17
|
+
*/
|
|
18
|
+
export function compileOperationsToProto(operationSource, schemaOrSDL, options) {
|
|
19
|
+
const document = typeof operationSource === 'string' ? parse(operationSource) : operationSource;
|
|
20
|
+
// Validate that only a single named operation is present
|
|
21
|
+
const namedOperations = document.definitions.filter((def) => def.kind === 'OperationDefinition' && def.name);
|
|
22
|
+
if (namedOperations.length === 0) {
|
|
23
|
+
throw new Error('No named operations found in document. ' + 'At least one named operation is required for proto compilation.');
|
|
24
|
+
}
|
|
25
|
+
if (namedOperations.length > 1) {
|
|
26
|
+
const operationNames = namedOperations.map((op) => op.name.value).join(', ');
|
|
27
|
+
throw new Error(`Multiple operations found in document: ${operationNames}. ` +
|
|
28
|
+
'Only a single named operation per document is supported for proto reversibility. ' +
|
|
29
|
+
'Please compile each operation separately.');
|
|
30
|
+
}
|
|
31
|
+
const schema = typeof schemaOrSDL === 'string'
|
|
32
|
+
? buildSchema(schemaOrSDL, {
|
|
33
|
+
assumeValid: true,
|
|
34
|
+
assumeValidSDL: true,
|
|
35
|
+
})
|
|
36
|
+
: schemaOrSDL;
|
|
37
|
+
// Validate the GraphQL operation document against the schema
|
|
38
|
+
// This catches invalid operations including circular fragment references (NoFragmentCyclesRule)
|
|
39
|
+
// Filter out KnownDirectivesRule to allow unknown directives (e.g., @wg_openapi_operation)
|
|
40
|
+
// since directives may be used by dev tools and don't affect proto generation
|
|
41
|
+
const validationRules = specifiedRules.filter((rule) => rule !== KnownDirectivesRule);
|
|
42
|
+
const validationErrors = validate(schema, document, validationRules);
|
|
43
|
+
if (validationErrors.length > 0) {
|
|
44
|
+
const errorMessages = validationErrors.map((error) => error.message).join('\n');
|
|
45
|
+
throw new Error(`Invalid GraphQL operation:\n${errorMessages}`);
|
|
46
|
+
}
|
|
47
|
+
const visitor = new OperationsToProtoVisitor(document, schema, options);
|
|
48
|
+
const root = visitor.visit();
|
|
49
|
+
const proto = visitor.toProtoText(root);
|
|
50
|
+
// Get the updated lock data for field number stability
|
|
51
|
+
const lockData = visitor.getLockData();
|
|
52
|
+
return { proto, root, lockData };
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Visitor that converts GraphQL operations to protocol buffer definition using protobufjs ast
|
|
56
|
+
*/
|
|
57
|
+
class OperationsToProtoVisitor {
|
|
58
|
+
constructor(document, schema, options) {
|
|
59
|
+
var _a, _b;
|
|
60
|
+
// For tracking / avoiding duplicate messages and enums
|
|
61
|
+
this.createdMessages = new Set();
|
|
62
|
+
this.createdEnums = new Set();
|
|
63
|
+
// Track generated nested list wrapper messages
|
|
64
|
+
this.nestedListWrappers = new Map();
|
|
65
|
+
// Fragment definitions map
|
|
66
|
+
this.fragments = new Map();
|
|
67
|
+
this.document = document;
|
|
68
|
+
this.schema = schema;
|
|
69
|
+
this.serviceName = (options === null || options === void 0 ? void 0 : options.serviceName) || 'DefaultService';
|
|
70
|
+
this.packageName = (options === null || options === void 0 ? void 0 : options.packageName) || 'service.v1';
|
|
71
|
+
this.goPackage = options === null || options === void 0 ? void 0 : options.goPackage;
|
|
72
|
+
this.javaPackage = options === null || options === void 0 ? void 0 : options.javaPackage;
|
|
73
|
+
this.javaOuterClassname = options === null || options === void 0 ? void 0 : options.javaOuterClassname;
|
|
74
|
+
this.javaMultipleFiles = options === null || options === void 0 ? void 0 : options.javaMultipleFiles;
|
|
75
|
+
this.csharpNamespace = options === null || options === void 0 ? void 0 : options.csharpNamespace;
|
|
76
|
+
this.rubyPackage = options === null || options === void 0 ? void 0 : options.rubyPackage;
|
|
77
|
+
this.phpNamespace = options === null || options === void 0 ? void 0 : options.phpNamespace;
|
|
78
|
+
this.phpMetadataNamespace = options === null || options === void 0 ? void 0 : options.phpMetadataNamespace;
|
|
79
|
+
this.objcClassPrefix = options === null || options === void 0 ? void 0 : options.objcClassPrefix;
|
|
80
|
+
this.swiftPrefix = options === null || options === void 0 ? void 0 : options.swiftPrefix;
|
|
81
|
+
this.includeComments = (_a = options === null || options === void 0 ? void 0 : options.includeComments) !== null && _a !== void 0 ? _a : true;
|
|
82
|
+
this.queryIdempotency = options === null || options === void 0 ? void 0 : options.queryIdempotency;
|
|
83
|
+
this.customScalarMappings = options === null || options === void 0 ? void 0 : options.customScalarMappings;
|
|
84
|
+
this.maxDepth = options === null || options === void 0 ? void 0 : options.maxDepth;
|
|
85
|
+
this.prefixOperationType = (_b = options === null || options === void 0 ? void 0 : options.prefixOperationType) !== null && _b !== void 0 ? _b : false;
|
|
86
|
+
// Initialize lock manager with previous lock data if provided
|
|
87
|
+
this.lockManager = new ProtoLockManager(options === null || options === void 0 ? void 0 : options.lockData);
|
|
88
|
+
// Create field number manager with lock manager integration
|
|
89
|
+
this.fieldNumberManager = createFieldNumberManager(this.lockManager);
|
|
90
|
+
this.root = new protobuf.Root();
|
|
91
|
+
// Collect all fragment definitions from the document
|
|
92
|
+
this.collectFragments();
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Collects all fragment definitions from the document
|
|
96
|
+
*/
|
|
97
|
+
collectFragments() {
|
|
98
|
+
for (const definition of this.document.definitions) {
|
|
99
|
+
if (definition.kind === 'FragmentDefinition') {
|
|
100
|
+
this.fragments.set(definition.name.value, definition);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
visit() {
|
|
105
|
+
const service = new protobuf.Service(this.serviceName);
|
|
106
|
+
const typeInfo = new TypeInfo(this.schema);
|
|
107
|
+
// Visit each operation definition
|
|
108
|
+
visit(this.document, visitWithTypeInfo(typeInfo, {
|
|
109
|
+
OperationDefinition: (node) => {
|
|
110
|
+
this.processOperation(node, service, typeInfo);
|
|
111
|
+
// Don't traverse deeper - we handle selection sets manually
|
|
112
|
+
return false;
|
|
113
|
+
},
|
|
114
|
+
}));
|
|
115
|
+
// Add all wrapper messages to root before adding service
|
|
116
|
+
for (const wrapperMessage of this.nestedListWrappers.values()) {
|
|
117
|
+
if (!this.createdMessages.has(wrapperMessage.name)) {
|
|
118
|
+
this.root.add(wrapperMessage);
|
|
119
|
+
this.createdMessages.add(wrapperMessage.name);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
this.root.add(service);
|
|
123
|
+
return this.root;
|
|
124
|
+
}
|
|
125
|
+
processOperation(node, service, typeInfo) {
|
|
126
|
+
var _a;
|
|
127
|
+
// 1. Extract operation name
|
|
128
|
+
const operationName = (_a = node.name) === null || _a === void 0 ? void 0 : _a.value;
|
|
129
|
+
if (!operationName) {
|
|
130
|
+
// Skip anonymous operations
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
// 2. Validate no root-level field aliases (breaks reversibility)
|
|
134
|
+
if (node.selectionSet) {
|
|
135
|
+
for (const selection of node.selectionSet.selections) {
|
|
136
|
+
if (selection.kind === 'Field' && selection.alias) {
|
|
137
|
+
throw new Error(`Root-level field alias "${selection.alias.value}: ${selection.name.value}" is not supported. ` +
|
|
138
|
+
'Field aliases at the root level break proto-to-GraphQL reversibility. ' +
|
|
139
|
+
'Please remove the alias or use it only on nested fields.');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// 3. Create method name from operation name, optionally prefixed with operation type
|
|
144
|
+
let methodName = upperFirst(camelCase(operationName));
|
|
145
|
+
// Add operation type prefix if requested
|
|
146
|
+
if (this.prefixOperationType) {
|
|
147
|
+
const operationTypePrefix = upperFirst(node.operation.toLowerCase());
|
|
148
|
+
methodName = `${operationTypePrefix}${methodName}`;
|
|
149
|
+
}
|
|
150
|
+
// 4. Create request message from variables
|
|
151
|
+
const requestMessageName = createRequestMessageName(methodName);
|
|
152
|
+
const requestMessage = buildRequestMessage(requestMessageName, node.variableDefinitions || [], this.schema, {
|
|
153
|
+
includeComments: this.includeComments,
|
|
154
|
+
fieldNumberManager: this.fieldNumberManager,
|
|
155
|
+
schema: this.schema,
|
|
156
|
+
customScalarMappings: this.customScalarMappings,
|
|
157
|
+
ensureNestedListWrapper: this.createNestedListWrapperCallback.bind(this),
|
|
158
|
+
});
|
|
159
|
+
// Add request message to root
|
|
160
|
+
if (!this.createdMessages.has(requestMessageName)) {
|
|
161
|
+
this.root.add(requestMessage);
|
|
162
|
+
this.createdMessages.add(requestMessageName);
|
|
163
|
+
}
|
|
164
|
+
// 3.5. Process any input object types referenced in variables
|
|
165
|
+
if (node.variableDefinitions) {
|
|
166
|
+
for (const varDef of node.variableDefinitions) {
|
|
167
|
+
this.processInputObjectTypes(varDef.type);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// 6. Create response message from selection set
|
|
171
|
+
const responseMessageName = createResponseMessageName(methodName);
|
|
172
|
+
if (node.selectionSet) {
|
|
173
|
+
const rootType = this.getRootType(node.operation);
|
|
174
|
+
const responseMessage = buildMessageFromSelectionSet(responseMessageName, node.selectionSet, rootType, typeInfo, {
|
|
175
|
+
includeComments: this.includeComments,
|
|
176
|
+
root: this.root,
|
|
177
|
+
fieldNumberManager: this.fieldNumberManager,
|
|
178
|
+
fragments: this.fragments,
|
|
179
|
+
schema: this.schema,
|
|
180
|
+
createdEnums: this.createdEnums,
|
|
181
|
+
customScalarMappings: this.customScalarMappings,
|
|
182
|
+
maxDepth: this.maxDepth,
|
|
183
|
+
ensureNestedListWrapper: this.createNestedListWrapperCallback.bind(this),
|
|
184
|
+
});
|
|
185
|
+
// Add response message to root
|
|
186
|
+
if (!this.createdMessages.has(responseMessageName)) {
|
|
187
|
+
this.root.add(responseMessage);
|
|
188
|
+
this.createdMessages.add(responseMessageName);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// 7. Add method to service
|
|
192
|
+
const method = new protobuf.Method(methodName, 'rpc', requestMessageName, responseMessageName);
|
|
193
|
+
// Mark subscriptions as server streaming
|
|
194
|
+
if (node.operation === OperationTypeNode.SUBSCRIPTION) {
|
|
195
|
+
method.responseStream = true;
|
|
196
|
+
}
|
|
197
|
+
// Mark Query operations with idempotency level if specified
|
|
198
|
+
if (this.queryIdempotency && node.operation === OperationTypeNode.QUERY) {
|
|
199
|
+
const methodWithIdempotency = method;
|
|
200
|
+
methodWithIdempotency.idempotencyLevel = this.queryIdempotency;
|
|
201
|
+
}
|
|
202
|
+
service.add(method);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Convert protobufjs Root to proto text format
|
|
206
|
+
*/
|
|
207
|
+
toProtoText(root) {
|
|
208
|
+
return rootToProtoText(root, {
|
|
209
|
+
packageName: this.packageName,
|
|
210
|
+
goPackage: this.goPackage,
|
|
211
|
+
javaPackage: this.javaPackage,
|
|
212
|
+
javaOuterClassname: this.javaOuterClassname,
|
|
213
|
+
javaMultipleFiles: this.javaMultipleFiles,
|
|
214
|
+
csharpNamespace: this.csharpNamespace,
|
|
215
|
+
rubyPackage: this.rubyPackage,
|
|
216
|
+
phpNamespace: this.phpNamespace,
|
|
217
|
+
phpMetadataNamespace: this.phpMetadataNamespace,
|
|
218
|
+
objcClassPrefix: this.objcClassPrefix,
|
|
219
|
+
swiftPrefix: this.swiftPrefix,
|
|
220
|
+
includeComments: this.includeComments,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Process input object types and enums referenced in a type node
|
|
225
|
+
*/
|
|
226
|
+
processInputObjectTypes(typeNode) {
|
|
227
|
+
// Handle NonNullType and ListType wrappers
|
|
228
|
+
if (typeNode.kind === 'NonNullType' || typeNode.kind === 'ListType') {
|
|
229
|
+
this.processInputObjectTypes(typeNode.type);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
// Handle NamedType
|
|
233
|
+
if (typeNode.kind === 'NamedType') {
|
|
234
|
+
const typeName = typeNode.name.value;
|
|
235
|
+
const type = this.schema.getType(typeName);
|
|
236
|
+
if (type && isInputObjectType(type)) {
|
|
237
|
+
// Create message for this input object if not already created
|
|
238
|
+
if (!this.createdMessages.has(typeName)) {
|
|
239
|
+
const inputMessage = buildInputObjectMessage(type, {
|
|
240
|
+
includeComments: this.includeComments,
|
|
241
|
+
fieldNumberManager: this.fieldNumberManager,
|
|
242
|
+
customScalarMappings: this.customScalarMappings,
|
|
243
|
+
ensureNestedListWrapper: this.createNestedListWrapperCallback.bind(this),
|
|
244
|
+
});
|
|
245
|
+
this.root.add(inputMessage);
|
|
246
|
+
this.createdMessages.add(typeName);
|
|
247
|
+
// Recursively process nested input objects and enums
|
|
248
|
+
const fields = type.getFields();
|
|
249
|
+
for (const field of Object.values(fields)) {
|
|
250
|
+
const fieldType = getNamedType(field.type);
|
|
251
|
+
if (isInputObjectType(fieldType)) {
|
|
252
|
+
const namedTypeNode = {
|
|
253
|
+
kind: Kind.NAMED_TYPE,
|
|
254
|
+
name: { kind: Kind.NAME, value: fieldType.name },
|
|
255
|
+
};
|
|
256
|
+
this.processInputObjectTypes(namedTypeNode);
|
|
257
|
+
}
|
|
258
|
+
else if (isEnumType(fieldType)) {
|
|
259
|
+
this.processEnumType(fieldType);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
else if (type && isEnumType(type)) {
|
|
265
|
+
// Create enum type if not already created
|
|
266
|
+
this.processEnumType(type);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Process and add an enum type to the proto root
|
|
272
|
+
*/
|
|
273
|
+
processEnumType(enumType) {
|
|
274
|
+
const typeName = enumType.name;
|
|
275
|
+
if (!this.createdEnums.has(typeName)) {
|
|
276
|
+
const protoEnum = buildEnumType(enumType, {
|
|
277
|
+
includeComments: this.includeComments,
|
|
278
|
+
});
|
|
279
|
+
this.root.add(protoEnum);
|
|
280
|
+
this.createdEnums.add(typeName);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Helper: Get root operation type
|
|
285
|
+
*/
|
|
286
|
+
getRootType(operationType) {
|
|
287
|
+
switch (operationType) {
|
|
288
|
+
case OperationTypeNode.QUERY:
|
|
289
|
+
return this.schema.getQueryType();
|
|
290
|
+
case OperationTypeNode.MUTATION:
|
|
291
|
+
return this.schema.getMutationType();
|
|
292
|
+
case OperationTypeNode.SUBSCRIPTION:
|
|
293
|
+
return this.schema.getSubscriptionType();
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Get the current lock data for field number stability
|
|
298
|
+
*/
|
|
299
|
+
getLockData() {
|
|
300
|
+
return this.lockManager.getLockData();
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Creates wrapper messages for nested GraphQL lists
|
|
304
|
+
* Similar to sdl-to-proto-visitor.ts createNestedListWrapper
|
|
305
|
+
*
|
|
306
|
+
* @param level - The nesting level (1 for simple wrapper, >1 for nested structures)
|
|
307
|
+
* @param baseTypeName - The base type name being wrapped (e.g., "String", "User")
|
|
308
|
+
* @returns The generated wrapper message
|
|
309
|
+
*/
|
|
310
|
+
createNestedListWrapper(level, baseTypeName) {
|
|
311
|
+
const wrapperName = `${'ListOf'.repeat(level)}${baseTypeName}`;
|
|
312
|
+
// Return existing wrapper if already created
|
|
313
|
+
if (this.nestedListWrappers.has(wrapperName)) {
|
|
314
|
+
return this.nestedListWrappers.get(wrapperName);
|
|
315
|
+
}
|
|
316
|
+
// Create the wrapper message
|
|
317
|
+
const wrapperMessage = new protobuf.Type(wrapperName);
|
|
318
|
+
// Create nested List message
|
|
319
|
+
const listMessage = new protobuf.Type('List');
|
|
320
|
+
// Determine the inner type name
|
|
321
|
+
let innerTypeName;
|
|
322
|
+
if (level > 1) {
|
|
323
|
+
// For nested lists, reference the previous level wrapper
|
|
324
|
+
innerTypeName = `${'ListOf'.repeat(level - 1)}${baseTypeName}`;
|
|
325
|
+
// Ensure the inner wrapper exists
|
|
326
|
+
if (!this.nestedListWrappers.has(innerTypeName)) {
|
|
327
|
+
this.createNestedListWrapper(level - 1, baseTypeName);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
// For level 1, use the base type directly
|
|
332
|
+
innerTypeName = baseTypeName;
|
|
333
|
+
}
|
|
334
|
+
// Add repeated items field to List message
|
|
335
|
+
const itemsField = new protobuf.Field('items', 1, innerTypeName);
|
|
336
|
+
itemsField.repeated = true;
|
|
337
|
+
listMessage.add(itemsField);
|
|
338
|
+
// Add List message to wrapper
|
|
339
|
+
wrapperMessage.add(listMessage);
|
|
340
|
+
// Add list field to wrapper message
|
|
341
|
+
const listField = new protobuf.Field('list', 1, 'List');
|
|
342
|
+
wrapperMessage.add(listField);
|
|
343
|
+
// Store the wrapper
|
|
344
|
+
this.nestedListWrappers.set(wrapperName, wrapperMessage);
|
|
345
|
+
return wrapperMessage;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Callback for builders to create nested list wrappers
|
|
349
|
+
* This method is called by request-builder and message-builder when they encounter
|
|
350
|
+
* a GraphQL type that requires a nested list wrapper
|
|
351
|
+
*
|
|
352
|
+
* @param graphqlType - The GraphQL type that needs a wrapper
|
|
353
|
+
* @returns The wrapper message name
|
|
354
|
+
*/
|
|
355
|
+
createNestedListWrapperCallback(graphqlType) {
|
|
356
|
+
const typeInfo = mapGraphQLTypeToProto(graphqlType, {
|
|
357
|
+
customScalarMappings: this.customScalarMappings,
|
|
358
|
+
});
|
|
359
|
+
if (!typeInfo.requiresNestedWrapper) {
|
|
360
|
+
// This shouldn't happen, but return the type name as fallback
|
|
361
|
+
return typeInfo.typeName;
|
|
362
|
+
}
|
|
363
|
+
// Create the wrapper message
|
|
364
|
+
const wrapperName = typeInfo.typeName;
|
|
365
|
+
const nestingLevel = typeInfo.nestingLevel || 1;
|
|
366
|
+
// Extract base type name from wrapper name
|
|
367
|
+
// e.g., "ListOfListOfString" -> "String"
|
|
368
|
+
const baseTypeName = wrapperName.replace(/^(ListOf)+/, '');
|
|
369
|
+
// Ensure all wrapper levels are created
|
|
370
|
+
if (!this.nestedListWrappers.has(wrapperName) && !this.createdMessages.has(wrapperName)) {
|
|
371
|
+
for (let i = 1; i <= nestingLevel; i++) {
|
|
372
|
+
this.createNestedListWrapper(i, baseTypeName);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return wrapperName;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
//# sourceMappingURL=operation-to-proto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation-to-proto.js","sourceRoot":"","sources":["../../src/operation-to-proto.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { ProtoLockManager } from '../proto-lock.js';
|
|
2
|
+
/**
|
|
3
|
+
* Field numbering manager for Protocol Buffer messages
|
|
4
|
+
*
|
|
5
|
+
* This module handles the assignment and tracking of field numbers
|
|
6
|
+
* across multiple proto messages to ensure uniqueness within each message.
|
|
7
|
+
* Integrates with ProtoLockManager for field number stability across compilations.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Manages field number assignment for a collection of messages
|
|
11
|
+
*/
|
|
12
|
+
export interface FieldNumberManager {
|
|
13
|
+
/**
|
|
14
|
+
* Gets the next available field number for a given message
|
|
15
|
+
* @param messageName - The name of the message
|
|
16
|
+
* @returns The next available field number
|
|
17
|
+
*/
|
|
18
|
+
getNextFieldNumber(messageName: string): number;
|
|
19
|
+
/**
|
|
20
|
+
* Assigns a specific field number to a field in a message
|
|
21
|
+
* @param messageName - The name of the message
|
|
22
|
+
* @param fieldName - The name of the field
|
|
23
|
+
* @param fieldNumber - The field number to assign
|
|
24
|
+
*/
|
|
25
|
+
assignFieldNumber(messageName: string, fieldName: string, fieldNumber: number): void;
|
|
26
|
+
/**
|
|
27
|
+
* Gets the field number for a specific field if it exists
|
|
28
|
+
* @param messageName - The name of the message
|
|
29
|
+
* @param fieldName - The name of the field
|
|
30
|
+
* @returns The field number or undefined if not assigned
|
|
31
|
+
*/
|
|
32
|
+
getFieldNumber(messageName: string, fieldName: string): number | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Resets field numbering for a specific message
|
|
35
|
+
* @param messageName - The name of the message to reset
|
|
36
|
+
*/
|
|
37
|
+
resetMessage(messageName: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Resets all field numbering
|
|
40
|
+
*/
|
|
41
|
+
resetAll(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Gets all field mappings for a message
|
|
44
|
+
* @param messageName - The name of the message
|
|
45
|
+
* @returns Record of field names to field numbers
|
|
46
|
+
*/
|
|
47
|
+
getMessageFields(messageName: string): Record<string, number>;
|
|
48
|
+
/**
|
|
49
|
+
* Reconciles field order for a message using lock data
|
|
50
|
+
* @param messageName - The name of the message
|
|
51
|
+
* @param fieldNames - The field names to reconcile
|
|
52
|
+
* @returns Ordered array of field names
|
|
53
|
+
*/
|
|
54
|
+
reconcileFieldOrder(messageName: string, fieldNames: string[]): string[];
|
|
55
|
+
/**
|
|
56
|
+
* Gets the lock manager if available
|
|
57
|
+
*/
|
|
58
|
+
getLockManager(): ProtoLockManager | undefined;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Creates a new field number manager instance
|
|
62
|
+
*
|
|
63
|
+
* @param lockManager - Optional ProtoLockManager for field number stability
|
|
64
|
+
* @returns A new field number manager
|
|
65
|
+
*/
|
|
66
|
+
export declare function createFieldNumberManager(lockManager?: ProtoLockManager): FieldNumberManager;
|
|
67
|
+
/**
|
|
68
|
+
* Assigns field numbers to a message from lock data
|
|
69
|
+
* @param messageName - The name of the message
|
|
70
|
+
* @param fieldNames - The field names to assign numbers to
|
|
71
|
+
* @param fieldNumberManager - The field number manager to use
|
|
72
|
+
*/
|
|
73
|
+
export declare function assignFieldNumbersFromLockData(messageName: string, fieldNames: string[], fieldNumberManager?: FieldNumberManager): void;
|