@graphql-tools/load 7.6.0 → 7.7.0-alpha-b76ec274.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.
Files changed (45) hide show
  1. package/cjs/documents.js +39 -0
  2. package/cjs/filter-document-kind.js +35 -0
  3. package/cjs/index.js +7 -0
  4. package/cjs/load-typedefs/collect-sources.js +195 -0
  5. package/cjs/load-typedefs/load-file.js +86 -0
  6. package/cjs/load-typedefs/options.js +10 -0
  7. package/cjs/load-typedefs/parse.js +62 -0
  8. package/cjs/load-typedefs.js +84 -0
  9. package/cjs/package.json +1 -0
  10. package/cjs/schema.js +86 -0
  11. package/cjs/utils/custom-loader.js +50 -0
  12. package/cjs/utils/helpers.js +42 -0
  13. package/cjs/utils/pointers.js +31 -0
  14. package/cjs/utils/queue.js +32 -0
  15. package/esm/documents.js +34 -0
  16. package/esm/filter-document-kind.js +31 -0
  17. package/esm/index.js +4 -0
  18. package/esm/load-typedefs/collect-sources.js +167 -0
  19. package/esm/load-typedefs/load-file.js +81 -0
  20. package/esm/load-typedefs/options.js +6 -0
  21. package/esm/load-typedefs/parse.js +58 -0
  22. package/esm/load-typedefs.js +79 -0
  23. package/esm/schema.js +81 -0
  24. package/esm/utils/custom-loader.js +44 -0
  25. package/esm/utils/helpers.js +35 -0
  26. package/esm/utils/pointers.js +27 -0
  27. package/esm/utils/queue.js +26 -0
  28. package/package.json +33 -12
  29. package/{documents.d.ts → typings/documents.d.ts} +1 -1
  30. package/{filter-document-kind.d.ts → typings/filter-document-kind.d.ts} +0 -0
  31. package/typings/index.d.ts +4 -0
  32. package/{load-typedefs → typings/load-typedefs}/collect-sources.d.ts +1 -1
  33. package/{load-typedefs → typings/load-typedefs}/load-file.d.ts +1 -1
  34. package/{load-typedefs → typings/load-typedefs}/options.d.ts +1 -1
  35. package/{load-typedefs → typings/load-typedefs}/parse.d.ts +0 -0
  36. package/{load-typedefs.d.ts → typings/load-typedefs.d.ts} +0 -0
  37. package/{schema.d.ts → typings/schema.d.ts} +1 -1
  38. package/{utils → typings/utils}/custom-loader.d.ts +0 -0
  39. package/{utils → typings/utils}/helpers.d.ts +0 -0
  40. package/{utils → typings/utils}/pointers.d.ts +1 -1
  41. package/{utils → typings/utils}/queue.d.ts +0 -0
  42. package/README.md +0 -8
  43. package/index.d.ts +0 -4
  44. package/index.js +0 -691
  45. package/index.mjs +0 -658
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useLimit = exports.useStack = exports.stringToHash = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const p_limit_1 = tslib_1.__importDefault(require("p-limit"));
6
+ /**
7
+ * Converts a string to 32bit integer
8
+ */
9
+ function stringToHash(str) {
10
+ let hash = 0;
11
+ if (str.length === 0) {
12
+ return hash;
13
+ }
14
+ let char;
15
+ for (let i = 0; i < str.length; i++) {
16
+ char = str.charCodeAt(i);
17
+ // tslint:disable-next-line: no-bitwise
18
+ hash = (hash << 5) - hash + char;
19
+ // tslint:disable-next-line: no-bitwise
20
+ hash = hash & hash;
21
+ }
22
+ return hash;
23
+ }
24
+ exports.stringToHash = stringToHash;
25
+ function useStack(...fns) {
26
+ return (input) => {
27
+ function createNext(i) {
28
+ if (i >= fns.length) {
29
+ return () => { };
30
+ }
31
+ return function next() {
32
+ fns[i](input, createNext(i + 1));
33
+ };
34
+ }
35
+ fns[0](input, createNext(1));
36
+ };
37
+ }
38
+ exports.useStack = useStack;
39
+ function useLimit(concurrency) {
40
+ return (0, p_limit_1.default)(concurrency);
41
+ }
42
+ exports.useLimit = useLimit;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizePointers = void 0;
4
+ const utils_1 = require("@graphql-tools/utils");
5
+ function normalizePointers(unnormalizedPointerOrPointers) {
6
+ const ignore = [];
7
+ const pointerOptionMap = {};
8
+ const handlePointer = (rawPointer, options = {}) => {
9
+ if (rawPointer.startsWith('!')) {
10
+ ignore.push(rawPointer.replace('!', ''));
11
+ }
12
+ else {
13
+ pointerOptionMap[rawPointer] = options;
14
+ }
15
+ };
16
+ for (const rawPointer of (0, utils_1.asArray)(unnormalizedPointerOrPointers)) {
17
+ if (typeof rawPointer === 'string') {
18
+ handlePointer(rawPointer);
19
+ }
20
+ else if (typeof rawPointer === 'object') {
21
+ for (const [path, options] of Object.entries(rawPointer)) {
22
+ handlePointer(path, options);
23
+ }
24
+ }
25
+ else {
26
+ throw new Error(`Invalid pointer '${rawPointer}'.`);
27
+ }
28
+ }
29
+ return { ignore, pointerOptionMap };
30
+ }
31
+ exports.normalizePointers = normalizePointers;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useSyncQueue = exports.useQueue = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const p_limit_1 = tslib_1.__importDefault(require("p-limit"));
6
+ function useQueue(options) {
7
+ const queue = [];
8
+ const limit = (options === null || options === void 0 ? void 0 : options.concurrency) ? (0, p_limit_1.default)(options.concurrency) : async (fn) => fn();
9
+ return {
10
+ add(fn) {
11
+ queue.push(() => limit(fn));
12
+ },
13
+ runAll() {
14
+ return Promise.all(queue.map(fn => fn()));
15
+ },
16
+ };
17
+ }
18
+ exports.useQueue = useQueue;
19
+ function useSyncQueue() {
20
+ const queue = [];
21
+ return {
22
+ add(fn) {
23
+ queue.push(fn);
24
+ },
25
+ runAll() {
26
+ for (const fn of queue) {
27
+ fn();
28
+ }
29
+ },
30
+ };
31
+ }
32
+ exports.useSyncQueue = useSyncQueue;
@@ -0,0 +1,34 @@
1
+ import { Kind } from 'graphql';
2
+ import { loadTypedefs, loadTypedefsSync } from './load-typedefs.js';
3
+ /**
4
+ * Kinds of AST nodes that are included in executable documents
5
+ */
6
+ export const OPERATION_KINDS = [Kind.OPERATION_DEFINITION, Kind.FRAGMENT_DEFINITION];
7
+ /**
8
+ * Kinds of AST nodes that are included in type system definition documents
9
+ */
10
+ export const NON_OPERATION_KINDS = Object.keys(Kind)
11
+ .reduce((prev, v) => [...prev, Kind[v]], [])
12
+ .filter(v => !OPERATION_KINDS.includes(v));
13
+ /**
14
+ * Asynchronously loads executable documents (i.e. operations and fragments) from
15
+ * the provided pointers. The pointers may be individual files or a glob pattern.
16
+ * The files themselves may be `.graphql` files or `.js` and `.ts` (in which
17
+ * case they will be parsed using graphql-tag-pluck).
18
+ * @param pointerOrPointers Pointers to the files to load the documents from
19
+ * @param options Additional options
20
+ */
21
+ export function loadDocuments(pointerOrPointers, options) {
22
+ return loadTypedefs(pointerOrPointers, { noRequire: true, filterKinds: NON_OPERATION_KINDS, ...options });
23
+ }
24
+ /**
25
+ * Synchronously loads executable documents (i.e. operations and fragments) from
26
+ * the provided pointers. The pointers may be individual files or a glob pattern.
27
+ * The files themselves may be `.graphql` files or `.js` and `.ts` (in which
28
+ * case they will be parsed using graphql-tag-pluck).
29
+ * @param pointerOrPointers Pointers to the files to load the documents from
30
+ * @param options Additional options
31
+ */
32
+ export function loadDocumentsSync(pointerOrPointers, options) {
33
+ return loadTypedefsSync(pointerOrPointers, { noRequire: true, filterKinds: NON_OPERATION_KINDS, ...options });
34
+ }
@@ -0,0 +1,31 @@
1
+ import { Kind } from 'graphql';
2
+ import { env } from 'process';
3
+ /**
4
+ * @internal
5
+ */
6
+ export const filterKind = (content, filterKinds) => {
7
+ if (content && content.definitions && content.definitions.length && filterKinds && filterKinds.length > 0) {
8
+ const invalidDefinitions = [];
9
+ const validDefinitions = [];
10
+ for (const definitionNode of content.definitions) {
11
+ if (filterKinds.includes(definitionNode.kind)) {
12
+ invalidDefinitions.push(definitionNode);
13
+ }
14
+ else {
15
+ validDefinitions.push(definitionNode);
16
+ }
17
+ }
18
+ if (invalidDefinitions.length > 0) {
19
+ if (env['DEBUG']) {
20
+ for (const d of invalidDefinitions) {
21
+ console.log(`Filtered document of kind ${d.kind} due to filter policy (${filterKinds.join(', ')})`);
22
+ }
23
+ }
24
+ }
25
+ return {
26
+ kind: Kind.DOCUMENT,
27
+ definitions: validDefinitions,
28
+ };
29
+ }
30
+ return content;
31
+ };
package/esm/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from './load-typedefs.js';
2
+ export * from './schema.js';
3
+ export * from './documents.js';
4
+ export * from './filter-document-kind.js';
@@ -0,0 +1,167 @@
1
+ import { isDocumentString, parseGraphQLSDL, getDocumentNodeFromSchema, asArray } from '@graphql-tools/utils';
2
+ import { isSchema, Kind } from 'graphql';
3
+ import { loadFile, loadFileSync } from './load-file.js';
4
+ import { stringToHash, useStack } from '../utils/helpers.js';
5
+ import { useCustomLoader, useCustomLoaderSync } from '../utils/custom-loader.js';
6
+ import { useQueue, useSyncQueue } from '../utils/queue.js';
7
+ import { createRequire } from 'module';
8
+ import { cwd } from 'process';
9
+ const CONCURRENCY_LIMIT = 50;
10
+ export async function collectSources({ pointerOptionMap, options, }) {
11
+ const sources = [];
12
+ const queue = useQueue({ concurrency: CONCURRENCY_LIMIT });
13
+ const { addSource, collect } = createHelpers({
14
+ sources,
15
+ stack: [collectDocumentString, collectCustomLoader, collectFallback],
16
+ });
17
+ for (const pointer in pointerOptionMap) {
18
+ const pointerOptions = pointerOptionMap[pointer];
19
+ collect({
20
+ pointer,
21
+ pointerOptions,
22
+ pointerOptionMap,
23
+ options,
24
+ addSource,
25
+ queue: queue.add,
26
+ });
27
+ }
28
+ await queue.runAll();
29
+ return sources;
30
+ }
31
+ export function collectSourcesSync({ pointerOptionMap, options, }) {
32
+ const sources = [];
33
+ const queue = useSyncQueue();
34
+ const { addSource, collect } = createHelpers({
35
+ sources,
36
+ stack: [collectDocumentString, collectCustomLoaderSync, collectFallbackSync],
37
+ });
38
+ for (const pointer in pointerOptionMap) {
39
+ const pointerOptions = pointerOptionMap[pointer];
40
+ collect({
41
+ pointer,
42
+ pointerOptions,
43
+ pointerOptionMap,
44
+ options,
45
+ addSource,
46
+ queue: queue.add,
47
+ });
48
+ }
49
+ queue.runAll();
50
+ return sources;
51
+ }
52
+ function createHelpers({ sources, stack }) {
53
+ const addSource = ({ source }) => {
54
+ sources.push(source);
55
+ };
56
+ const collect = useStack(...stack);
57
+ return {
58
+ addSource,
59
+ collect,
60
+ };
61
+ }
62
+ function addResultOfCustomLoader({ pointer, result, addSource, }) {
63
+ if (isSchema(result)) {
64
+ addSource({
65
+ source: {
66
+ location: pointer,
67
+ schema: result,
68
+ document: getDocumentNodeFromSchema(result),
69
+ },
70
+ pointer,
71
+ noCache: true,
72
+ });
73
+ }
74
+ else if (result.kind && result.kind === Kind.DOCUMENT) {
75
+ addSource({
76
+ source: {
77
+ document: result,
78
+ location: pointer,
79
+ },
80
+ pointer,
81
+ });
82
+ }
83
+ else if (result.document) {
84
+ addSource({
85
+ source: {
86
+ location: pointer,
87
+ ...result,
88
+ },
89
+ pointer,
90
+ });
91
+ }
92
+ }
93
+ function collectDocumentString({ pointer, pointerOptions, options, addSource, queue }, next) {
94
+ if (isDocumentString(pointer)) {
95
+ return queue(() => {
96
+ const source = parseGraphQLSDL(`${stringToHash(pointer)}.graphql`, pointer, {
97
+ ...options,
98
+ ...pointerOptions,
99
+ });
100
+ addSource({
101
+ source,
102
+ pointer,
103
+ });
104
+ });
105
+ }
106
+ next();
107
+ }
108
+ function collectCustomLoader({ pointer, pointerOptions, queue, addSource, options, pointerOptionMap }, next) {
109
+ if (pointerOptions.loader) {
110
+ return queue(async () => {
111
+ await Promise.all(asArray(pointerOptions.require).map(m => import(m)));
112
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
113
+ // @ts-ignore TODO options.cwd is possibly undefined, but it seems like no test covers this path
114
+ const loader = await useCustomLoader(pointerOptions.loader, options.cwd);
115
+ const result = await loader(pointer, { ...options, ...pointerOptions }, pointerOptionMap);
116
+ if (!result) {
117
+ return;
118
+ }
119
+ addResultOfCustomLoader({ pointer, result, addSource });
120
+ });
121
+ }
122
+ next();
123
+ }
124
+ function collectCustomLoaderSync({ pointer, pointerOptions, queue, addSource, options, pointerOptionMap }, next) {
125
+ if (pointerOptions.loader) {
126
+ return queue(() => {
127
+ const cwdRequire = createRequire(options.cwd || cwd());
128
+ for (const m of asArray(pointerOptions.require)) {
129
+ cwdRequire(m);
130
+ }
131
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
132
+ // @ts-ignore TODO options.cwd is possibly undefined, but it seems like no test covers this path
133
+ const loader = useCustomLoaderSync(pointerOptions.loader, options.cwd);
134
+ const result = loader(pointer, { ...options, ...pointerOptions }, pointerOptionMap);
135
+ if (result) {
136
+ addResultOfCustomLoader({ pointer, result, addSource });
137
+ }
138
+ });
139
+ }
140
+ next();
141
+ }
142
+ function collectFallback({ queue, pointer, options, pointerOptions, addSource }) {
143
+ return queue(async () => {
144
+ const sources = await loadFile(pointer, {
145
+ ...options,
146
+ ...pointerOptions,
147
+ });
148
+ if (sources) {
149
+ for (const source of sources) {
150
+ addSource({ source, pointer });
151
+ }
152
+ }
153
+ });
154
+ }
155
+ function collectFallbackSync({ queue, pointer, options, pointerOptions, addSource }) {
156
+ return queue(() => {
157
+ const sources = loadFileSync(pointer, {
158
+ ...options,
159
+ ...pointerOptions,
160
+ });
161
+ if (sources) {
162
+ for (const source of sources) {
163
+ addSource({ source, pointer });
164
+ }
165
+ }
166
+ });
167
+ }
@@ -0,0 +1,81 @@
1
+ import { AggregateError } from '@graphql-tools/utils';
2
+ import { env } from 'process';
3
+ export async function loadFile(pointer, options) {
4
+ var _a;
5
+ let results = (_a = options.cache) === null || _a === void 0 ? void 0 : _a[pointer];
6
+ if (!results) {
7
+ results = [];
8
+ const errors = [];
9
+ await Promise.all(options.loaders.map(async (loader) => {
10
+ try {
11
+ const loaderResults = await loader.load(pointer, options);
12
+ loaderResults === null || loaderResults === void 0 ? void 0 : loaderResults.forEach(result => results.push(result));
13
+ }
14
+ catch (error) {
15
+ if (env['DEBUG']) {
16
+ console.error(error);
17
+ }
18
+ if (error instanceof AggregateError) {
19
+ for (const errorElement of error.errors) {
20
+ errors.push(errorElement);
21
+ }
22
+ }
23
+ else {
24
+ errors.push(error);
25
+ }
26
+ }
27
+ }));
28
+ if (results.length === 0 && errors.length > 0) {
29
+ if (errors.length === 1) {
30
+ throw errors[0];
31
+ }
32
+ throw new AggregateError(errors, `Failed to find any GraphQL type definitions in: ${pointer};\n - ${errors
33
+ .map(error => error.message)
34
+ .join('\n - ')}`);
35
+ }
36
+ if (options.cache) {
37
+ options.cache[pointer] = results;
38
+ }
39
+ }
40
+ return results;
41
+ }
42
+ export function loadFileSync(pointer, options) {
43
+ var _a;
44
+ let results = (_a = options.cache) === null || _a === void 0 ? void 0 : _a[pointer];
45
+ if (!results) {
46
+ results = [];
47
+ const errors = [];
48
+ for (const loader of options.loaders) {
49
+ try {
50
+ // We check for the existence so it is okay to force non null
51
+ const loaderResults = loader.loadSync(pointer, options);
52
+ loaderResults === null || loaderResults === void 0 ? void 0 : loaderResults.forEach(result => results.push(result));
53
+ }
54
+ catch (error) {
55
+ if (env['DEBUG']) {
56
+ console.error(error);
57
+ }
58
+ if (error instanceof AggregateError) {
59
+ for (const errorElement of error.errors) {
60
+ errors.push(errorElement);
61
+ }
62
+ }
63
+ else {
64
+ errors.push(error);
65
+ }
66
+ }
67
+ }
68
+ if (results.length === 0 && errors.length > 0) {
69
+ if (errors.length === 1) {
70
+ throw errors[0];
71
+ }
72
+ throw new AggregateError(errors, `Failed to find any GraphQL type definitions in: ${pointer};\n - ${errors
73
+ .map(error => error.message)
74
+ .join('\n - ')}`);
75
+ }
76
+ if (options.cache) {
77
+ options.cache[pointer] = results;
78
+ }
79
+ }
80
+ return results;
81
+ }
@@ -0,0 +1,6 @@
1
+ import { cwd } from 'process';
2
+ export function applyDefaultOptions(options) {
3
+ options.cache = options.cache || {};
4
+ options.cwd = options.cwd || cwd();
5
+ options.sort = 'sort' in options ? options.sort : true;
6
+ }
@@ -0,0 +1,58 @@
1
+ import { printSchemaWithDirectives, parseGraphQLSDL, printWithComments, resetComments, } from '@graphql-tools/utils';
2
+ import { filterKind } from '../filter-document-kind.js';
3
+ export function parseSource({ partialSource, options, pointerOptionMap, addValidSource }) {
4
+ if (partialSource) {
5
+ const input = prepareInput({
6
+ source: partialSource,
7
+ options,
8
+ pointerOptionMap,
9
+ });
10
+ parseSchema(input);
11
+ parseRawSDL(input);
12
+ if (input.source.document) {
13
+ useKindsFilter(input);
14
+ useComments(input);
15
+ collectValidSources(input, addValidSource);
16
+ }
17
+ }
18
+ }
19
+ //
20
+ function prepareInput({ source, options, pointerOptionMap, }) {
21
+ let specificOptions = {
22
+ ...options,
23
+ };
24
+ if (source.location) {
25
+ specificOptions = {
26
+ ...specificOptions,
27
+ ...pointerOptionMap[source.location],
28
+ };
29
+ }
30
+ return { source: { ...source }, options: specificOptions };
31
+ }
32
+ function parseSchema(input) {
33
+ if (input.source.schema) {
34
+ input.source.rawSDL = printSchemaWithDirectives(input.source.schema, input.options);
35
+ }
36
+ }
37
+ function parseRawSDL(input) {
38
+ if (input.source.rawSDL) {
39
+ input.source.document = parseGraphQLSDL(input.source.location, input.source.rawSDL, input.options).document;
40
+ }
41
+ }
42
+ function useKindsFilter(input) {
43
+ if (input.options.filterKinds) {
44
+ input.source.document = filterKind(input.source.document, input.options.filterKinds);
45
+ }
46
+ }
47
+ function useComments(input) {
48
+ if (!input.source.rawSDL && input.source.document) {
49
+ input.source.rawSDL = printWithComments(input.source.document);
50
+ resetComments();
51
+ }
52
+ }
53
+ function collectValidSources(input, addValidSource) {
54
+ var _a;
55
+ if (((_a = input.source.document) === null || _a === void 0 ? void 0 : _a.definitions) && input.source.document.definitions.length > 0) {
56
+ addValidSource(input.source);
57
+ }
58
+ }
@@ -0,0 +1,79 @@
1
+ import { compareStrings, asArray } from '@graphql-tools/utils';
2
+ import { normalizePointers } from './utils/pointers.js';
3
+ import { applyDefaultOptions } from './load-typedefs/options.js';
4
+ import { collectSources, collectSourcesSync } from './load-typedefs/collect-sources.js';
5
+ import { parseSource } from './load-typedefs/parse.js';
6
+ import { useLimit } from './utils/helpers.js';
7
+ const CONCURRENCY_LIMIT = 100;
8
+ /**
9
+ * Asynchronously loads any GraphQL documents (i.e. executable documents like
10
+ * operations and fragments as well as type system definitions) from the
11
+ * provided pointers.
12
+ * loadTypedefs does not merge the typeDefs when `#import` is used ( https://github.com/ardatan/graphql-tools/issues/2980#issuecomment-1003692728 )
13
+ * @param pointerOrPointers Pointers to the sources to load the documents from
14
+ * @param options Additional options
15
+ */
16
+ export async function loadTypedefs(pointerOrPointers, options) {
17
+ const { ignore, pointerOptionMap } = normalizePointers(pointerOrPointers);
18
+ options.ignore = asArray(options.ignore || []);
19
+ options.ignore.push(...ignore);
20
+ applyDefaultOptions(options);
21
+ const sources = await collectSources({
22
+ pointerOptionMap,
23
+ options,
24
+ });
25
+ const validSources = [];
26
+ // If we have few k of files it may be an issue
27
+ const limit = useLimit(CONCURRENCY_LIMIT);
28
+ await Promise.all(sources.map(partialSource => limit(() => parseSource({
29
+ partialSource,
30
+ options,
31
+ pointerOptionMap,
32
+ addValidSource(source) {
33
+ validSources.push(source);
34
+ },
35
+ }))));
36
+ return prepareResult({ options, pointerOptionMap, validSources });
37
+ }
38
+ /**
39
+ * Synchronously loads any GraphQL documents (i.e. executable documents like
40
+ * operations and fragments as well as type system definitions) from the
41
+ * provided pointers.
42
+ * @param pointerOrPointers Pointers to the sources to load the documents from
43
+ * @param options Additional options
44
+ */
45
+ export function loadTypedefsSync(pointerOrPointers, options) {
46
+ const { ignore, pointerOptionMap } = normalizePointers(pointerOrPointers);
47
+ options.ignore = asArray(options.ignore || []).concat(ignore);
48
+ applyDefaultOptions(options);
49
+ const sources = collectSourcesSync({
50
+ pointerOptionMap,
51
+ options,
52
+ });
53
+ const validSources = [];
54
+ for (const partialSource of sources) {
55
+ parseSource({
56
+ partialSource,
57
+ options,
58
+ pointerOptionMap,
59
+ addValidSource(source) {
60
+ validSources.push(source);
61
+ },
62
+ });
63
+ }
64
+ return prepareResult({ options, pointerOptionMap, validSources });
65
+ }
66
+ //
67
+ function prepareResult({ options, pointerOptionMap, validSources, }) {
68
+ const pointerList = Object.keys(pointerOptionMap);
69
+ if (pointerList.length > 0 && validSources.length === 0) {
70
+ throw new Error(`
71
+ Unable to find any GraphQL type definitions for the following pointers:
72
+ ${pointerList.map(p => `
73
+ - ${p}
74
+ `)}`);
75
+ }
76
+ return options.sort
77
+ ? validSources.sort((left, right) => compareStrings(left.location, right.location))
78
+ : validSources;
79
+ }
package/esm/schema.js ADDED
@@ -0,0 +1,81 @@
1
+ import { loadTypedefs, loadTypedefsSync } from './load-typedefs.js';
2
+ import { Source as GraphQLSource, print, lexicographicSortSchema, } from 'graphql';
3
+ import { OPERATION_KINDS } from './documents.js';
4
+ import { mergeSchemas } from '@graphql-tools/schema';
5
+ /**
6
+ * Asynchronously loads a schema from the provided pointers.
7
+ * @param schemaPointers Pointers to the sources to load the schema from
8
+ * @param options Additional options
9
+ */
10
+ export async function loadSchema(schemaPointers, options) {
11
+ var _a, _b;
12
+ const sources = await loadTypedefs(schemaPointers, {
13
+ ...options,
14
+ filterKinds: OPERATION_KINDS,
15
+ });
16
+ const { schemas, typeDefs } = collectSchemasAndTypeDefs(sources);
17
+ schemas.push(...((_a = options.schemas) !== null && _a !== void 0 ? _a : []));
18
+ const mergeSchemasOptions = {
19
+ ...options,
20
+ schemas: schemas.concat((_b = options.schemas) !== null && _b !== void 0 ? _b : []),
21
+ typeDefs,
22
+ };
23
+ const schema = (typeDefs === null || typeDefs === void 0 ? void 0 : typeDefs.length) === 0 && (schemas === null || schemas === void 0 ? void 0 : schemas.length) === 1 ? schemas[0] : mergeSchemas(mergeSchemasOptions);
24
+ if (options === null || options === void 0 ? void 0 : options.includeSources) {
25
+ includeSources(schema, sources);
26
+ }
27
+ return options.sort ? lexicographicSortSchema(schema) : schema;
28
+ }
29
+ /**
30
+ * Synchronously loads a schema from the provided pointers.
31
+ * @param schemaPointers Pointers to the sources to load the schema from
32
+ * @param options Additional options
33
+ */
34
+ export function loadSchemaSync(schemaPointers, options) {
35
+ const sources = loadTypedefsSync(schemaPointers, {
36
+ filterKinds: OPERATION_KINDS,
37
+ ...options,
38
+ });
39
+ const { schemas, typeDefs } = collectSchemasAndTypeDefs(sources);
40
+ const schema = mergeSchemas({
41
+ schemas,
42
+ typeDefs,
43
+ ...options,
44
+ });
45
+ if (options === null || options === void 0 ? void 0 : options.includeSources) {
46
+ includeSources(schema, sources);
47
+ }
48
+ return options.sort ? lexicographicSortSchema(schema) : schema;
49
+ }
50
+ function includeSources(schema, sources) {
51
+ const finalSources = [];
52
+ for (const source of sources) {
53
+ if (source.rawSDL) {
54
+ finalSources.push(new GraphQLSource(source.rawSDL, source.location));
55
+ }
56
+ else if (source.document) {
57
+ finalSources.push(new GraphQLSource(print(source.document), source.location));
58
+ }
59
+ }
60
+ schema.extensions = {
61
+ ...schema.extensions,
62
+ sources: finalSources,
63
+ extendedSources: sources,
64
+ };
65
+ }
66
+ function collectSchemasAndTypeDefs(sources) {
67
+ const schemas = [];
68
+ const typeDefs = [];
69
+ for (const source of sources) {
70
+ if (source.schema) {
71
+ schemas.push(source.schema);
72
+ }
73
+ else if (source.document) {
74
+ typeDefs.push(source.document);
75
+ }
76
+ }
77
+ return {
78
+ schemas,
79
+ typeDefs,
80
+ };
81
+ }