@graphql-codegen/graphql-modules-preset 2.3.14 → 2.4.0-alpha-bd464a586.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.
- package/cjs/builder.js +344 -0
- package/cjs/config.js +2 -0
- package/cjs/index.js +111 -0
- package/cjs/package.json +1 -0
- package/cjs/utils.js +189 -0
- package/{index.mjs → esm/builder.js} +3 -282
- package/esm/config.js +1 -0
- package/esm/index.js +108 -0
- package/esm/utils.js +171 -0
- package/package.json +24 -17
- package/{builder.d.ts → typings/builder.d.ts} +1 -1
- package/{config.d.ts → typings/config.d.ts} +0 -0
- package/{index.d.ts → typings/index.d.ts} +1 -1
- package/{utils.d.ts → typings/utils.d.ts} +0 -0
- package/index.js +0 -625
|
@@ -1,182 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { resolve, relative, join } from 'path';
|
|
3
|
-
import parse from 'parse-filepath';
|
|
1
|
+
import { visit, Kind, isScalarType, } from 'graphql';
|
|
4
2
|
import { pascalCase } from 'change-case-all';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
const sep = '/';
|
|
8
|
-
/**
|
|
9
|
-
* Searches every node to collect used types
|
|
10
|
-
*/
|
|
11
|
-
function collectUsedTypes(doc) {
|
|
12
|
-
const used = [];
|
|
13
|
-
doc.definitions.forEach(findRelated);
|
|
14
|
-
function markAsUsed(type) {
|
|
15
|
-
pushUnique(used, type);
|
|
16
|
-
}
|
|
17
|
-
function findRelated(node) {
|
|
18
|
-
if (node.kind === Kind.OBJECT_TYPE_DEFINITION || node.kind === Kind.OBJECT_TYPE_EXTENSION) {
|
|
19
|
-
// Object
|
|
20
|
-
markAsUsed(node.name.value);
|
|
21
|
-
if (node.fields) {
|
|
22
|
-
node.fields.forEach(findRelated);
|
|
23
|
-
}
|
|
24
|
-
if (node.interfaces) {
|
|
25
|
-
node.interfaces.forEach(findRelated);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
else if (node.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION || node.kind === Kind.INPUT_OBJECT_TYPE_EXTENSION) {
|
|
29
|
-
// Input
|
|
30
|
-
markAsUsed(node.name.value);
|
|
31
|
-
if (node.fields) {
|
|
32
|
-
node.fields.forEach(findRelated);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
else if (node.kind === Kind.INTERFACE_TYPE_DEFINITION || node.kind === Kind.INTERFACE_TYPE_EXTENSION) {
|
|
36
|
-
// Interface
|
|
37
|
-
markAsUsed(node.name.value);
|
|
38
|
-
if (node.fields) {
|
|
39
|
-
node.fields.forEach(findRelated);
|
|
40
|
-
}
|
|
41
|
-
if (node.interfaces) {
|
|
42
|
-
node.interfaces.forEach(findRelated);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
else if (node.kind === Kind.UNION_TYPE_DEFINITION || node.kind === Kind.UNION_TYPE_EXTENSION) {
|
|
46
|
-
// Union
|
|
47
|
-
markAsUsed(node.name.value);
|
|
48
|
-
if (node.types) {
|
|
49
|
-
node.types.forEach(findRelated);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
else if (node.kind === Kind.ENUM_TYPE_DEFINITION || node.kind === Kind.ENUM_TYPE_EXTENSION) {
|
|
53
|
-
// Enum
|
|
54
|
-
markAsUsed(node.name.value);
|
|
55
|
-
}
|
|
56
|
-
else if (node.kind === Kind.SCALAR_TYPE_DEFINITION || node.kind === Kind.SCALAR_TYPE_EXTENSION) {
|
|
57
|
-
// Scalar
|
|
58
|
-
if (!isGraphQLPrimitive(node.name.value)) {
|
|
59
|
-
markAsUsed(node.name.value);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
else if (node.kind === Kind.INPUT_VALUE_DEFINITION) {
|
|
63
|
-
// Argument
|
|
64
|
-
findRelated(resolveTypeNode(node.type));
|
|
65
|
-
}
|
|
66
|
-
else if (node.kind === Kind.FIELD_DEFINITION) {
|
|
67
|
-
// Field
|
|
68
|
-
findRelated(resolveTypeNode(node.type));
|
|
69
|
-
if (node.arguments) {
|
|
70
|
-
node.arguments.forEach(findRelated);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
else if (node.kind === Kind.NAMED_TYPE &&
|
|
74
|
-
// Named type
|
|
75
|
-
!isGraphQLPrimitive(node.name.value)) {
|
|
76
|
-
markAsUsed(node.name.value);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return used;
|
|
80
|
-
}
|
|
81
|
-
function resolveTypeNode(node) {
|
|
82
|
-
if (node.kind === Kind.LIST_TYPE) {
|
|
83
|
-
return resolveTypeNode(node.type);
|
|
84
|
-
}
|
|
85
|
-
if (node.kind === Kind.NON_NULL_TYPE) {
|
|
86
|
-
return resolveTypeNode(node.type);
|
|
87
|
-
}
|
|
88
|
-
return node;
|
|
89
|
-
}
|
|
90
|
-
function isGraphQLPrimitive(name) {
|
|
91
|
-
return ['String', 'Boolean', 'ID', 'Float', 'Int'].includes(name);
|
|
92
|
-
}
|
|
93
|
-
function unique(val, i, all) {
|
|
94
|
-
return i === all.indexOf(val);
|
|
95
|
-
}
|
|
96
|
-
function withQuotes(val) {
|
|
97
|
-
return `'${val}'`;
|
|
98
|
-
}
|
|
99
|
-
function indent(size) {
|
|
100
|
-
const space = new Array(size).fill(' ').join('');
|
|
101
|
-
function indentInner(val) {
|
|
102
|
-
return val
|
|
103
|
-
.split('\n')
|
|
104
|
-
.map(line => `${space}${line}`)
|
|
105
|
-
.join('\n');
|
|
106
|
-
}
|
|
107
|
-
return indentInner;
|
|
108
|
-
}
|
|
109
|
-
function buildBlock({ name, lines }) {
|
|
110
|
-
if (!lines.length) {
|
|
111
|
-
return '';
|
|
112
|
-
}
|
|
113
|
-
return [`${name} {`, ...lines.map(indent(2)), '};'].join('\n');
|
|
114
|
-
}
|
|
115
|
-
const getRelativePath = function (filepath, basePath) {
|
|
116
|
-
const normalizedFilepath = normalize(filepath);
|
|
117
|
-
const normalizedBasePath = ensureStartsWithSeparator(normalize(ensureEndsWithSeparator(basePath)));
|
|
118
|
-
const [, relativePath] = normalizedFilepath.split(normalizedBasePath);
|
|
119
|
-
return relativePath;
|
|
120
|
-
};
|
|
121
|
-
function groupSourcesByModule(sources, basePath) {
|
|
122
|
-
const grouped = {};
|
|
123
|
-
sources.forEach(source => {
|
|
124
|
-
const relativePath = getRelativePath(source.location, basePath);
|
|
125
|
-
if (relativePath) {
|
|
126
|
-
// PERF: we could guess the module by matching source.location with a list of already resolved paths
|
|
127
|
-
const mod = extractModuleDirectory(source.location, basePath);
|
|
128
|
-
if (!grouped[mod]) {
|
|
129
|
-
grouped[mod] = [];
|
|
130
|
-
}
|
|
131
|
-
grouped[mod].push(source);
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
return grouped;
|
|
135
|
-
}
|
|
136
|
-
function extractModuleDirectory(filepath, basePath) {
|
|
137
|
-
const relativePath = getRelativePath(filepath, basePath);
|
|
138
|
-
const [moduleDirectory] = relativePath.split(sep);
|
|
139
|
-
return moduleDirectory;
|
|
140
|
-
}
|
|
141
|
-
function stripFilename(path) {
|
|
142
|
-
const parsedPath = parse(path);
|
|
143
|
-
return normalize(parsedPath.dir);
|
|
144
|
-
}
|
|
145
|
-
function normalize(path) {
|
|
146
|
-
return path.replace(/\\/g, '/');
|
|
147
|
-
}
|
|
148
|
-
function ensureEndsWithSeparator(path) {
|
|
149
|
-
return path.endsWith(sep) ? path : path + sep;
|
|
150
|
-
}
|
|
151
|
-
function ensureStartsWithSeparator(path) {
|
|
152
|
-
return path.startsWith('.') ? path.replace(/^(..\/)|(.\/)/, '/') : path.startsWith('/') ? path : '/' + path;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Pushes an item to a list only if the list doesn't include the item
|
|
156
|
-
*/
|
|
157
|
-
function pushUnique(list, item) {
|
|
158
|
-
if (!list.includes(item)) {
|
|
159
|
-
list.push(item);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
function concatByKey(left, right, key) {
|
|
163
|
-
// Remove duplicate, if an element is in right & left, it will be only once in the returned array.
|
|
164
|
-
return [...new Set([...left[key], ...right[key]])];
|
|
165
|
-
}
|
|
166
|
-
function uniqueByKey(left, right, key) {
|
|
167
|
-
return left[key].filter(item => !right[key].includes(item));
|
|
168
|
-
}
|
|
169
|
-
function createObject(keys, valueFn) {
|
|
170
|
-
const obj = {};
|
|
171
|
-
keys.forEach(key => {
|
|
172
|
-
obj[key] = valueFn(key);
|
|
173
|
-
});
|
|
174
|
-
return obj;
|
|
175
|
-
}
|
|
176
|
-
|
|
3
|
+
import { unique, withQuotes, buildBlock, pushUnique, concatByKey, uniqueByKey, createObject, collectUsedTypes, indent, } from './utils.js';
|
|
177
4
|
const registryKeys = ['objects', 'inputs', 'interfaces', 'scalars', 'unions', 'enums'];
|
|
178
5
|
const resolverKeys = ['scalars', 'objects', 'enums'];
|
|
179
|
-
function buildModule(name, doc, { importNamespace, importPath, encapsulate, shouldDeclare, rootTypes, schema, baseVisitor, useGraphQLModules, }) {
|
|
6
|
+
export function buildModule(name, doc, { importNamespace, importPath, encapsulate, shouldDeclare, rootTypes, schema, baseVisitor, useGraphQLModules, }) {
|
|
180
7
|
const picks = createObject(registryKeys, () => ({}));
|
|
181
8
|
const defined = createObject(registryKeys, () => []);
|
|
182
9
|
const extended = createObject(registryKeys, () => []);
|
|
@@ -511,109 +338,3 @@ function buildModule(name, doc, { importNamespace, importPath, encapsulate, shou
|
|
|
511
338
|
}
|
|
512
339
|
}
|
|
513
340
|
}
|
|
514
|
-
|
|
515
|
-
const preset = {
|
|
516
|
-
buildGeneratesSection: options => {
|
|
517
|
-
const useGraphQLModules = getConfigValue(options === null || options === void 0 ? void 0 : options.presetConfig.useGraphQLModules, true);
|
|
518
|
-
const { baseOutputDir } = options;
|
|
519
|
-
const { baseTypesPath, encapsulateModuleTypes } = options.presetConfig;
|
|
520
|
-
const cwd = resolve(options.presetConfig.cwd || process.cwd());
|
|
521
|
-
const importTypesNamespace = options.presetConfig.importTypesNamespace || 'Types';
|
|
522
|
-
if (!baseTypesPath) {
|
|
523
|
-
throw new Error(`Preset "graphql-modules" requires you to specify "baseTypesPath" configuration and point it to your base types file (generated by "typescript" plugin)!`);
|
|
524
|
-
}
|
|
525
|
-
if (!options.schemaAst || !options.schemaAst.extensions.sources) {
|
|
526
|
-
throw new Error(`Preset "graphql-modules" requires to use GraphQL SDL`);
|
|
527
|
-
}
|
|
528
|
-
const extensions = options.schemaAst.extensions;
|
|
529
|
-
const sourcesByModuleMap = groupSourcesByModule(extensions.extendedSources, baseOutputDir);
|
|
530
|
-
const modules = Object.keys(sourcesByModuleMap);
|
|
531
|
-
const baseVisitor = new BaseVisitor(options.config, {});
|
|
532
|
-
// One file with an output from all plugins
|
|
533
|
-
const baseOutput = {
|
|
534
|
-
filename: resolve(cwd, baseOutputDir, baseTypesPath),
|
|
535
|
-
schema: options.schema,
|
|
536
|
-
documents: options.documents,
|
|
537
|
-
plugins: [
|
|
538
|
-
...options.plugins,
|
|
539
|
-
{
|
|
540
|
-
'modules-exported-scalars': {},
|
|
541
|
-
},
|
|
542
|
-
],
|
|
543
|
-
pluginMap: {
|
|
544
|
-
...options.pluginMap,
|
|
545
|
-
'modules-exported-scalars': {
|
|
546
|
-
plugin: schema => {
|
|
547
|
-
const typeMap = schema.getTypeMap();
|
|
548
|
-
return Object.keys(typeMap)
|
|
549
|
-
.map(t => {
|
|
550
|
-
if (t && typeMap[t] && isScalarType(typeMap[t]) && !isGraphQLPrimitive(t)) {
|
|
551
|
-
const convertedName = baseVisitor.convertName(t);
|
|
552
|
-
return `export type ${convertedName} = Scalars["${t}"];`;
|
|
553
|
-
}
|
|
554
|
-
return null;
|
|
555
|
-
})
|
|
556
|
-
.filter(Boolean)
|
|
557
|
-
.join('\n');
|
|
558
|
-
},
|
|
559
|
-
},
|
|
560
|
-
},
|
|
561
|
-
config: {
|
|
562
|
-
...options.config,
|
|
563
|
-
enumsAsTypes: true,
|
|
564
|
-
},
|
|
565
|
-
schemaAst: options.schemaAst,
|
|
566
|
-
};
|
|
567
|
-
const baseTypesFilename = baseTypesPath.replace(/\.(js|ts|d.ts)$/, '');
|
|
568
|
-
const baseTypesDir = stripFilename(baseOutput.filename);
|
|
569
|
-
// One file per each module
|
|
570
|
-
const outputs = modules.map(moduleName => {
|
|
571
|
-
const filename = resolve(cwd, baseOutputDir, moduleName, options.presetConfig.filename);
|
|
572
|
-
const dirpath = stripFilename(filename);
|
|
573
|
-
const relativePath = relative(dirpath, baseTypesDir);
|
|
574
|
-
const importPath = options.presetConfig.importBaseTypesFrom || normalize(join(relativePath, baseTypesFilename));
|
|
575
|
-
const sources = sourcesByModuleMap[moduleName];
|
|
576
|
-
const moduleDocument = concatAST(sources.map(source => source.document));
|
|
577
|
-
const shouldDeclare = filename.endsWith('.d.ts');
|
|
578
|
-
return {
|
|
579
|
-
filename,
|
|
580
|
-
schema: options.schema,
|
|
581
|
-
documents: [],
|
|
582
|
-
plugins: [
|
|
583
|
-
...options.plugins.filter(p => typeof p === 'object' && !!p.add),
|
|
584
|
-
{
|
|
585
|
-
'graphql-modules-plugin': {},
|
|
586
|
-
},
|
|
587
|
-
],
|
|
588
|
-
pluginMap: {
|
|
589
|
-
...options.pluginMap,
|
|
590
|
-
'graphql-modules-plugin': {
|
|
591
|
-
plugin: schema => {
|
|
592
|
-
var _a, _b, _c;
|
|
593
|
-
return buildModule(moduleName, moduleDocument, {
|
|
594
|
-
importNamespace: importTypesNamespace,
|
|
595
|
-
importPath,
|
|
596
|
-
encapsulate: encapsulateModuleTypes || 'namespace',
|
|
597
|
-
shouldDeclare,
|
|
598
|
-
schema,
|
|
599
|
-
baseVisitor,
|
|
600
|
-
useGraphQLModules,
|
|
601
|
-
rootTypes: [
|
|
602
|
-
(_a = schema.getQueryType()) === null || _a === void 0 ? void 0 : _a.name,
|
|
603
|
-
(_b = schema.getMutationType()) === null || _b === void 0 ? void 0 : _b.name,
|
|
604
|
-
(_c = schema.getSubscriptionType()) === null || _c === void 0 ? void 0 : _c.name,
|
|
605
|
-
].filter(Boolean),
|
|
606
|
-
});
|
|
607
|
-
},
|
|
608
|
-
},
|
|
609
|
-
},
|
|
610
|
-
config: options.config,
|
|
611
|
-
schemaAst: options.schemaAst,
|
|
612
|
-
};
|
|
613
|
-
});
|
|
614
|
-
return [baseOutput].concat(outputs);
|
|
615
|
-
},
|
|
616
|
-
};
|
|
617
|
-
|
|
618
|
-
export default preset;
|
|
619
|
-
export { preset };
|
package/esm/config.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/esm/index.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { concatAST, isScalarType } from 'graphql';
|
|
2
|
+
import { resolve, relative, join } from 'path';
|
|
3
|
+
import { groupSourcesByModule, stripFilename, normalize, isGraphQLPrimitive } from './utils.js';
|
|
4
|
+
import { buildModule } from './builder.js';
|
|
5
|
+
import { BaseVisitor, getConfigValue } from '@graphql-codegen/visitor-plugin-common';
|
|
6
|
+
export const preset = {
|
|
7
|
+
buildGeneratesSection: options => {
|
|
8
|
+
const useGraphQLModules = getConfigValue(options === null || options === void 0 ? void 0 : options.presetConfig.useGraphQLModules, true);
|
|
9
|
+
const { baseOutputDir } = options;
|
|
10
|
+
const { baseTypesPath, encapsulateModuleTypes } = options.presetConfig;
|
|
11
|
+
const cwd = resolve(options.presetConfig.cwd || process.cwd());
|
|
12
|
+
const importTypesNamespace = options.presetConfig.importTypesNamespace || 'Types';
|
|
13
|
+
if (!baseTypesPath) {
|
|
14
|
+
throw new Error(`Preset "graphql-modules" requires you to specify "baseTypesPath" configuration and point it to your base types file (generated by "typescript" plugin)!`);
|
|
15
|
+
}
|
|
16
|
+
if (!options.schemaAst || !options.schemaAst.extensions.sources) {
|
|
17
|
+
throw new Error(`Preset "graphql-modules" requires to use GraphQL SDL`);
|
|
18
|
+
}
|
|
19
|
+
const extensions = options.schemaAst.extensions;
|
|
20
|
+
const sourcesByModuleMap = groupSourcesByModule(extensions.extendedSources, baseOutputDir);
|
|
21
|
+
const modules = Object.keys(sourcesByModuleMap);
|
|
22
|
+
const baseVisitor = new BaseVisitor(options.config, {});
|
|
23
|
+
// One file with an output from all plugins
|
|
24
|
+
const baseOutput = {
|
|
25
|
+
filename: resolve(cwd, baseOutputDir, baseTypesPath),
|
|
26
|
+
schema: options.schema,
|
|
27
|
+
documents: options.documents,
|
|
28
|
+
plugins: [
|
|
29
|
+
...options.plugins,
|
|
30
|
+
{
|
|
31
|
+
'modules-exported-scalars': {},
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
pluginMap: {
|
|
35
|
+
...options.pluginMap,
|
|
36
|
+
'modules-exported-scalars': {
|
|
37
|
+
plugin: schema => {
|
|
38
|
+
const typeMap = schema.getTypeMap();
|
|
39
|
+
return Object.keys(typeMap)
|
|
40
|
+
.map(t => {
|
|
41
|
+
if (t && typeMap[t] && isScalarType(typeMap[t]) && !isGraphQLPrimitive(t)) {
|
|
42
|
+
const convertedName = baseVisitor.convertName(t);
|
|
43
|
+
return `export type ${convertedName} = Scalars["${t}"];`;
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
})
|
|
47
|
+
.filter(Boolean)
|
|
48
|
+
.join('\n');
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
config: {
|
|
53
|
+
...options.config,
|
|
54
|
+
enumsAsTypes: true,
|
|
55
|
+
},
|
|
56
|
+
schemaAst: options.schemaAst,
|
|
57
|
+
};
|
|
58
|
+
const baseTypesFilename = baseTypesPath.replace(/\.(js|ts|d.ts)$/, '');
|
|
59
|
+
const baseTypesDir = stripFilename(baseOutput.filename);
|
|
60
|
+
// One file per each module
|
|
61
|
+
const outputs = modules.map(moduleName => {
|
|
62
|
+
const filename = resolve(cwd, baseOutputDir, moduleName, options.presetConfig.filename);
|
|
63
|
+
const dirpath = stripFilename(filename);
|
|
64
|
+
const relativePath = relative(dirpath, baseTypesDir);
|
|
65
|
+
const importPath = options.presetConfig.importBaseTypesFrom || normalize(join(relativePath, baseTypesFilename));
|
|
66
|
+
const sources = sourcesByModuleMap[moduleName];
|
|
67
|
+
const moduleDocument = concatAST(sources.map(source => source.document));
|
|
68
|
+
const shouldDeclare = filename.endsWith('.d.ts');
|
|
69
|
+
return {
|
|
70
|
+
filename,
|
|
71
|
+
schema: options.schema,
|
|
72
|
+
documents: [],
|
|
73
|
+
plugins: [
|
|
74
|
+
...options.plugins.filter(p => typeof p === 'object' && !!p.add),
|
|
75
|
+
{
|
|
76
|
+
'graphql-modules-plugin': {},
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
pluginMap: {
|
|
80
|
+
...options.pluginMap,
|
|
81
|
+
'graphql-modules-plugin': {
|
|
82
|
+
plugin: schema => {
|
|
83
|
+
var _a, _b, _c;
|
|
84
|
+
return buildModule(moduleName, moduleDocument, {
|
|
85
|
+
importNamespace: importTypesNamespace,
|
|
86
|
+
importPath,
|
|
87
|
+
encapsulate: encapsulateModuleTypes || 'namespace',
|
|
88
|
+
shouldDeclare,
|
|
89
|
+
schema,
|
|
90
|
+
baseVisitor,
|
|
91
|
+
useGraphQLModules,
|
|
92
|
+
rootTypes: [
|
|
93
|
+
(_a = schema.getQueryType()) === null || _a === void 0 ? void 0 : _a.name,
|
|
94
|
+
(_b = schema.getMutationType()) === null || _b === void 0 ? void 0 : _b.name,
|
|
95
|
+
(_c = schema.getSubscriptionType()) === null || _c === void 0 ? void 0 : _c.name,
|
|
96
|
+
].filter(Boolean),
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
config: options.config,
|
|
102
|
+
schemaAst: options.schemaAst,
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
return [baseOutput].concat(outputs);
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
export default preset;
|
package/esm/utils.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { Kind, } from 'graphql';
|
|
2
|
+
import parse from 'parse-filepath';
|
|
3
|
+
const sep = '/';
|
|
4
|
+
/**
|
|
5
|
+
* Searches every node to collect used types
|
|
6
|
+
*/
|
|
7
|
+
export function collectUsedTypes(doc) {
|
|
8
|
+
const used = [];
|
|
9
|
+
doc.definitions.forEach(findRelated);
|
|
10
|
+
function markAsUsed(type) {
|
|
11
|
+
pushUnique(used, type);
|
|
12
|
+
}
|
|
13
|
+
function findRelated(node) {
|
|
14
|
+
if (node.kind === Kind.OBJECT_TYPE_DEFINITION || node.kind === Kind.OBJECT_TYPE_EXTENSION) {
|
|
15
|
+
// Object
|
|
16
|
+
markAsUsed(node.name.value);
|
|
17
|
+
if (node.fields) {
|
|
18
|
+
node.fields.forEach(findRelated);
|
|
19
|
+
}
|
|
20
|
+
if (node.interfaces) {
|
|
21
|
+
node.interfaces.forEach(findRelated);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else if (node.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION || node.kind === Kind.INPUT_OBJECT_TYPE_EXTENSION) {
|
|
25
|
+
// Input
|
|
26
|
+
markAsUsed(node.name.value);
|
|
27
|
+
if (node.fields) {
|
|
28
|
+
node.fields.forEach(findRelated);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else if (node.kind === Kind.INTERFACE_TYPE_DEFINITION || node.kind === Kind.INTERFACE_TYPE_EXTENSION) {
|
|
32
|
+
// Interface
|
|
33
|
+
markAsUsed(node.name.value);
|
|
34
|
+
if (node.fields) {
|
|
35
|
+
node.fields.forEach(findRelated);
|
|
36
|
+
}
|
|
37
|
+
if (node.interfaces) {
|
|
38
|
+
node.interfaces.forEach(findRelated);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else if (node.kind === Kind.UNION_TYPE_DEFINITION || node.kind === Kind.UNION_TYPE_EXTENSION) {
|
|
42
|
+
// Union
|
|
43
|
+
markAsUsed(node.name.value);
|
|
44
|
+
if (node.types) {
|
|
45
|
+
node.types.forEach(findRelated);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (node.kind === Kind.ENUM_TYPE_DEFINITION || node.kind === Kind.ENUM_TYPE_EXTENSION) {
|
|
49
|
+
// Enum
|
|
50
|
+
markAsUsed(node.name.value);
|
|
51
|
+
}
|
|
52
|
+
else if (node.kind === Kind.SCALAR_TYPE_DEFINITION || node.kind === Kind.SCALAR_TYPE_EXTENSION) {
|
|
53
|
+
// Scalar
|
|
54
|
+
if (!isGraphQLPrimitive(node.name.value)) {
|
|
55
|
+
markAsUsed(node.name.value);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else if (node.kind === Kind.INPUT_VALUE_DEFINITION) {
|
|
59
|
+
// Argument
|
|
60
|
+
findRelated(resolveTypeNode(node.type));
|
|
61
|
+
}
|
|
62
|
+
else if (node.kind === Kind.FIELD_DEFINITION) {
|
|
63
|
+
// Field
|
|
64
|
+
findRelated(resolveTypeNode(node.type));
|
|
65
|
+
if (node.arguments) {
|
|
66
|
+
node.arguments.forEach(findRelated);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else if (node.kind === Kind.NAMED_TYPE &&
|
|
70
|
+
// Named type
|
|
71
|
+
!isGraphQLPrimitive(node.name.value)) {
|
|
72
|
+
markAsUsed(node.name.value);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return used;
|
|
76
|
+
}
|
|
77
|
+
export function resolveTypeNode(node) {
|
|
78
|
+
if (node.kind === Kind.LIST_TYPE) {
|
|
79
|
+
return resolveTypeNode(node.type);
|
|
80
|
+
}
|
|
81
|
+
if (node.kind === Kind.NON_NULL_TYPE) {
|
|
82
|
+
return resolveTypeNode(node.type);
|
|
83
|
+
}
|
|
84
|
+
return node;
|
|
85
|
+
}
|
|
86
|
+
export function isGraphQLPrimitive(name) {
|
|
87
|
+
return ['String', 'Boolean', 'ID', 'Float', 'Int'].includes(name);
|
|
88
|
+
}
|
|
89
|
+
export function unique(val, i, all) {
|
|
90
|
+
return i === all.indexOf(val);
|
|
91
|
+
}
|
|
92
|
+
export function withQuotes(val) {
|
|
93
|
+
return `'${val}'`;
|
|
94
|
+
}
|
|
95
|
+
export function indent(size) {
|
|
96
|
+
const space = new Array(size).fill(' ').join('');
|
|
97
|
+
function indentInner(val) {
|
|
98
|
+
return val
|
|
99
|
+
.split('\n')
|
|
100
|
+
.map(line => `${space}${line}`)
|
|
101
|
+
.join('\n');
|
|
102
|
+
}
|
|
103
|
+
return indentInner;
|
|
104
|
+
}
|
|
105
|
+
export function buildBlock({ name, lines }) {
|
|
106
|
+
if (!lines.length) {
|
|
107
|
+
return '';
|
|
108
|
+
}
|
|
109
|
+
return [`${name} {`, ...lines.map(indent(2)), '};'].join('\n');
|
|
110
|
+
}
|
|
111
|
+
const getRelativePath = function (filepath, basePath) {
|
|
112
|
+
const normalizedFilepath = normalize(filepath);
|
|
113
|
+
const normalizedBasePath = ensureStartsWithSeparator(normalize(ensureEndsWithSeparator(basePath)));
|
|
114
|
+
const [, relativePath] = normalizedFilepath.split(normalizedBasePath);
|
|
115
|
+
return relativePath;
|
|
116
|
+
};
|
|
117
|
+
export function groupSourcesByModule(sources, basePath) {
|
|
118
|
+
const grouped = {};
|
|
119
|
+
sources.forEach(source => {
|
|
120
|
+
const relativePath = getRelativePath(source.location, basePath);
|
|
121
|
+
if (relativePath) {
|
|
122
|
+
// PERF: we could guess the module by matching source.location with a list of already resolved paths
|
|
123
|
+
const mod = extractModuleDirectory(source.location, basePath);
|
|
124
|
+
if (!grouped[mod]) {
|
|
125
|
+
grouped[mod] = [];
|
|
126
|
+
}
|
|
127
|
+
grouped[mod].push(source);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
return grouped;
|
|
131
|
+
}
|
|
132
|
+
function extractModuleDirectory(filepath, basePath) {
|
|
133
|
+
const relativePath = getRelativePath(filepath, basePath);
|
|
134
|
+
const [moduleDirectory] = relativePath.split(sep);
|
|
135
|
+
return moduleDirectory;
|
|
136
|
+
}
|
|
137
|
+
export function stripFilename(path) {
|
|
138
|
+
const parsedPath = parse(path);
|
|
139
|
+
return normalize(parsedPath.dir);
|
|
140
|
+
}
|
|
141
|
+
export function normalize(path) {
|
|
142
|
+
return path.replace(/\\/g, '/');
|
|
143
|
+
}
|
|
144
|
+
function ensureEndsWithSeparator(path) {
|
|
145
|
+
return path.endsWith(sep) ? path : path + sep;
|
|
146
|
+
}
|
|
147
|
+
function ensureStartsWithSeparator(path) {
|
|
148
|
+
return path.startsWith('.') ? path.replace(/^(..\/)|(.\/)/, '/') : path.startsWith('/') ? path : '/' + path;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Pushes an item to a list only if the list doesn't include the item
|
|
152
|
+
*/
|
|
153
|
+
export function pushUnique(list, item) {
|
|
154
|
+
if (!list.includes(item)) {
|
|
155
|
+
list.push(item);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
export function concatByKey(left, right, key) {
|
|
159
|
+
// Remove duplicate, if an element is in right & left, it will be only once in the returned array.
|
|
160
|
+
return [...new Set([...left[key], ...right[key]])];
|
|
161
|
+
}
|
|
162
|
+
export function uniqueByKey(left, right, key) {
|
|
163
|
+
return left[key].filter(item => !right[key].includes(item));
|
|
164
|
+
}
|
|
165
|
+
export function createObject(keys, valueFn) {
|
|
166
|
+
const obj = {};
|
|
167
|
+
keys.forEach(key => {
|
|
168
|
+
obj[key] = valueFn(key);
|
|
169
|
+
});
|
|
170
|
+
return obj;
|
|
171
|
+
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-codegen/graphql-modules-preset",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0-alpha-bd464a586.0",
|
|
4
4
|
"description": "GraphQL Code Generator preset for modularized schema",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"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"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@graphql-codegen/plugin-helpers": "^2.
|
|
10
|
-
"@graphql-codegen/visitor-plugin-common": "2.
|
|
11
|
-
"@graphql-tools/utils": "8.8.0",
|
|
12
|
-
"change-case-all": "1.0.14",
|
|
9
|
+
"@graphql-codegen/plugin-helpers": "^2.5.0-alpha-bd464a586.0",
|
|
10
|
+
"@graphql-codegen/visitor-plugin-common": "2.11.0-alpha-bd464a586.0",
|
|
11
|
+
"@graphql-tools/utils": "^8.8.0",
|
|
13
12
|
"parse-filepath": "^1.0.2",
|
|
13
|
+
"change-case-all": "1.0.14",
|
|
14
14
|
"tslib": "~2.4.0"
|
|
15
15
|
},
|
|
16
16
|
"repository": {
|
|
@@ -19,21 +19,28 @@
|
|
|
19
19
|
"directory": "packages/presets/graphql-modules"
|
|
20
20
|
},
|
|
21
21
|
"license": "MIT",
|
|
22
|
-
"main": "index.js",
|
|
23
|
-
"module": "index.
|
|
24
|
-
"typings": "index.d.ts",
|
|
22
|
+
"main": "cjs/index.js",
|
|
23
|
+
"module": "esm/index.js",
|
|
24
|
+
"typings": "typings/index.d.ts",
|
|
25
25
|
"typescript": {
|
|
26
|
-
"definition": "index.d.ts"
|
|
26
|
+
"definition": "typings/index.d.ts"
|
|
27
27
|
},
|
|
28
|
+
"type": "module",
|
|
28
29
|
"exports": {
|
|
29
|
-
"./package.json": "./package.json",
|
|
30
30
|
".": {
|
|
31
|
-
"require":
|
|
32
|
-
|
|
31
|
+
"require": {
|
|
32
|
+
"types": "./typings/index.d.ts",
|
|
33
|
+
"default": "./cjs/index.js"
|
|
34
|
+
},
|
|
35
|
+
"import": {
|
|
36
|
+
"types": "./typings/index.d.ts",
|
|
37
|
+
"default": "./esm/index.js"
|
|
38
|
+
},
|
|
39
|
+
"default": {
|
|
40
|
+
"types": "./typings/index.d.ts",
|
|
41
|
+
"default": "./esm/index.js"
|
|
42
|
+
}
|
|
33
43
|
},
|
|
34
|
-
"
|
|
35
|
-
"require": "./*.js",
|
|
36
|
-
"import": "./*.mjs"
|
|
37
|
-
}
|
|
44
|
+
"./package.json": "./package.json"
|
|
38
45
|
}
|
|
39
|
-
}
|
|
46
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DocumentNode, GraphQLSchema } from 'graphql';
|
|
2
|
-
import { ModulesConfig } from './config';
|
|
2
|
+
import { ModulesConfig } from './config.js';
|
|
3
3
|
import { BaseVisitor } from '@graphql-codegen/visitor-plugin-common';
|
|
4
4
|
export declare function buildModule(name: string, doc: DocumentNode, { importNamespace, importPath, encapsulate, shouldDeclare, rootTypes, schema, baseVisitor, useGraphQLModules, }: {
|
|
5
5
|
importNamespace: string;
|
|
File without changes
|
|
File without changes
|