Skip to content

Commit 8a28fd0

Browse files
NadenNaden
authored andcommitted
Added support for Scala
1 parent be2864e commit 8a28fd0

26 files changed

+3631
-60
lines changed

.github/ISSUE_TEMPLATE/bug_report.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ body:
6565
- '@graphql-codegen/typescript-vue-urql'
6666
- '@graphql-codegen/import-types-preset'
6767
- '@graphql-codegen/near-operation-file-preset'
68+
- '@graphql-codegen/scala'
69+
- '@graphql-codegen/scalajs'
70+
- '@graphql-codegen/scala-common'
6871
validations:
6972
required: false
7073
- type: textarea

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ plugins:
6565
`@graphql-codegen/java-apollo-android`
6666
- [![npm version](https://badge.fury.io/js/%40graphql-codegen%2Ftypescript-nest.svg)](https://badge.fury.io/js/%40graphql-codegen%2Ftypescript-nest) -
6767
`@graphql-codegen/typescript-nest`
68+
- [![npm version](https://badge.fury.io/js/%40graphql-codegen%2Fscala.svg)](https://badge.fury.io/js/%40graphql-codegen%2Fscala) -
69+
`@graphql-codegen/scala`
70+
- [![npm version](https://badge.fury.io/js/%40graphql-codegen%2Fscalajs.svg)](https://badge.fury.io/js/%40graphql-codegen%2Fscalajs) -
71+
`@graphql-codegen/scalajs`
72+
- [![npm version](https://badge.fury.io/js/%40graphql-codegen%2Fscala-common.svg)](https://badge.fury.io/js/%40graphql-codegen%2Fscala-common) -
73+
`@graphql-codegen/scala-common`
6874

6975
### Getting started with codegen
7076

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"packages/plugins/c-sharp/*",
99
"packages/plugins/dart/*",
1010
"packages/plugins/typescript/*",
11+
"packages/plugins/scala/*",
1112
"packages/plugins/other/*",
1213
"packages/presets/*"
1314
],
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('../../../../jest.project')({ dirname: __dirname });
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"name": "@graphql-codegen/scala-common",
3+
"version": "3.0.0",
4+
"type": "module",
5+
"description": "GraphQL Code Generator utils library for developing Scala plugins",
6+
"repository": {
7+
"type": "git",
8+
"url": "https://github.com/dotansimha/graphql-code-generator-community.git",
9+
"directory": "packages/plugins/scala/common"
10+
},
11+
"license": "MIT",
12+
"engines": {
13+
"node": ">= 16.0.0"
14+
},
15+
"main": "dist/cjs/index.js",
16+
"module": "dist/esm/index.js",
17+
"exports": {
18+
".": {
19+
"require": {
20+
"types": "./dist/typings/index.d.cts",
21+
"default": "./dist/cjs/index.js"
22+
},
23+
"import": {
24+
"types": "./dist/typings/index.d.ts",
25+
"default": "./dist/esm/index.js"
26+
},
27+
"default": {
28+
"types": "./dist/typings/index.d.ts",
29+
"default": "./dist/esm/index.js"
30+
}
31+
},
32+
"./package.json": "./package.json"
33+
},
34+
"typings": "dist/typings/index.d.ts",
35+
"scripts": {
36+
"lint": "eslint **/*.ts"
37+
},
38+
"peerDependencies": {
39+
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
40+
},
41+
"dependencies": {
42+
"@graphql-codegen/plugin-helpers": "^3.0.0",
43+
"@graphql-codegen/visitor-plugin-common": "2.13.8",
44+
"auto-bind": "~4.0.0",
45+
"min-indent": "1.0.1",
46+
"tslib": "^2.8.1",
47+
"unixify": "^1.0.0"
48+
},
49+
"publishConfig": {
50+
"directory": "dist",
51+
"access": "public"
52+
},
53+
"typescript": {
54+
"definition": "dist/typings/index.d.ts"
55+
}
56+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import { GraphQLSchema } from 'graphql';
2+
import { Types } from '@graphql-codegen/plugin-helpers';
3+
import { ScalaBaseVisitor } from './base-visitor';
4+
import { ScalaPluginCommonRawConfig } from './config';
5+
6+
export type BasePluginFunction<TRawConfig extends ScalaPluginCommonRawConfig> = (
7+
schema: GraphQLSchema,
8+
documents: Types.DocumentFile[],
9+
config: TRawConfig,
10+
info: { outputFile?: string },
11+
) => Types.PluginOutput;
12+
13+
export const createBasePlugin = <
14+
TRawConfig extends ScalaPluginCommonRawConfig,
15+
TVisitor extends ScalaBaseVisitor<TRawConfig, any>,
16+
>(
17+
createVisitor: (
18+
schema: GraphQLSchema,
19+
config: TRawConfig,
20+
outputFileInfo: { outputFile?: string },
21+
) => TVisitor,
22+
): BasePluginFunction<TRawConfig> => {
23+
return (
24+
schema: GraphQLSchema,
25+
_: Types.DocumentFile[],
26+
config: TRawConfig,
27+
info: { outputFile?: string },
28+
): Types.PluginOutput => {
29+
if (!config.packageName && info.outputFile) {
30+
const parts = info.outputFile.split('/');
31+
parts.pop();
32+
33+
if (parts.length > 0) {
34+
config = {
35+
...config,
36+
packageName: parts.join('.'),
37+
};
38+
}
39+
}
40+
41+
const visitor = createVisitor(schema, config, { outputFile: info.outputFile });
42+
const typeNames = Object.keys(schema.getTypeMap()).filter(
43+
typeName => !typeName.startsWith('__'),
44+
);
45+
46+
const header = [
47+
visitor.getPackage(),
48+
'',
49+
visitor.getImports(),
50+
'',
51+
'getTypeClassDefinitions' in visitor ? (visitor as any).getTypeClassDefinitions() : '',
52+
]
53+
.filter(Boolean)
54+
.join('\n');
55+
56+
const schemaScalarTypeNames = typeNames.filter(typeName => {
57+
const type = schema.getTypeMap()[typeName];
58+
return type.astNode?.kind === 'ScalarTypeDefinition';
59+
});
60+
61+
const customScalarDefinitions: string[] = [];
62+
if (config.scalars) {
63+
Object.keys(config.scalars).forEach(scalarName => {
64+
if (typeof config.scalars[scalarName] === 'string') {
65+
const scalarType = config.scalars[scalarName];
66+
customScalarDefinitions.push(`type ${scalarName} = ${scalarType}`);
67+
}
68+
});
69+
}
70+
71+
const defaultScalars = visitor.generateCustomScalars
72+
? visitor.generateCustomScalars([
73+
...schemaScalarTypeNames,
74+
...Object.keys(config.scalars || {}),
75+
])
76+
: [];
77+
78+
const contentFragments = typeNames.map(typeName => {
79+
const type = schema.getTypeMap()[typeName];
80+
81+
if (
82+
type.astNode?.kind === 'ScalarTypeDefinition' &&
83+
config.scalars &&
84+
typeof config.scalars[typeName] === 'string'
85+
) {
86+
return '';
87+
}
88+
89+
const astNodeKind = type.astNode?.kind as string | undefined;
90+
if (astNodeKind && astNodeKind in visitor) {
91+
const handler = (visitor as any)[astNodeKind];
92+
if (typeof handler === 'function') {
93+
return handler.call(visitor, type.astNode);
94+
}
95+
}
96+
97+
return '';
98+
});
99+
100+
const content = [
101+
header,
102+
...customScalarDefinitions,
103+
...defaultScalars,
104+
...contentFragments.filter(Boolean),
105+
].join('\n\n');
106+
107+
return {
108+
content,
109+
prepend: [],
110+
append: [],
111+
};
112+
};
113+
};

0 commit comments

Comments
 (0)