@graphql-codegen/cli 2.7.0 → 2.8.0-alpha-c108f8a9c.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/bin.js +13 -0
- package/cjs/cli.js +60 -0
- package/cjs/codegen.js +332 -0
- package/cjs/config.js +303 -0
- package/cjs/generate-and-save.js +110 -0
- package/cjs/graphql-config.js +69 -0
- package/cjs/hooks.js +87 -0
- package/cjs/index.js +13 -0
- package/cjs/init/helpers.js +64 -0
- package/cjs/init/index.js +60 -0
- package/cjs/init/plugins.js +163 -0
- package/cjs/init/questions.js +147 -0
- package/cjs/init/targets.js +44 -0
- package/cjs/init/types.js +14 -0
- package/cjs/load.js +93 -0
- package/cjs/package.json +1 -0
- package/cjs/plugins.js +45 -0
- package/cjs/presets.js +46 -0
- package/cjs/utils/cli-error.js +25 -0
- package/cjs/utils/debugging.js +27 -0
- package/cjs/utils/file-system.js +26 -0
- package/cjs/utils/indentString.js +37 -0
- package/cjs/utils/listr-renderer.js +136 -0
- package/cjs/utils/logger.js +25 -0
- package/cjs/utils/watcher.js +140 -0
- package/esm/bin.js +11 -0
- package/esm/cli.js +32 -0
- package/esm/codegen.js +327 -0
- package/esm/config.js +290 -0
- package/esm/generate-and-save.js +105 -0
- package/esm/graphql-config.js +64 -0
- package/esm/hooks.js +83 -0
- package/esm/index.js +7 -0
- package/esm/init/helpers.js +55 -0
- package/esm/init/index.js +55 -0
- package/esm/init/plugins.js +160 -0
- package/esm/init/questions.js +140 -0
- package/esm/init/targets.js +40 -0
- package/esm/init/types.js +11 -0
- package/esm/load.js +88 -0
- package/esm/plugins.js +41 -0
- package/esm/presets.js +42 -0
- package/esm/utils/cli-error.js +20 -0
- package/esm/utils/debugging.js +21 -0
- package/esm/utils/file-system.js +19 -0
- package/esm/utils/indentString.js +33 -0
- package/esm/utils/listr-renderer.js +130 -0
- package/esm/utils/logger.js +18 -0
- package/esm/utils/watcher.js +135 -0
- package/package.json +31 -23
- package/typings/bin.d.ts +2 -0
- package/{cli.d.ts → typings/cli.d.ts} +0 -0
- package/{codegen.d.ts → typings/codegen.d.ts} +1 -1
- package/{config.d.ts → typings/config.d.ts} +0 -0
- package/{generate-and-save.d.ts → typings/generate-and-save.d.ts} +1 -1
- package/{graphql-config.d.ts → typings/graphql-config.d.ts} +0 -0
- package/{hooks.d.ts → typings/hooks.d.ts} +0 -0
- package/typings/index.d.ts +7 -0
- package/{init → typings/init}/helpers.d.ts +1 -1
- package/{init → typings/init}/index.d.ts +0 -0
- package/{init → typings/init}/plugins.d.ts +1 -1
- package/{init → typings/init}/questions.d.ts +1 -1
- package/{init → typings/init}/targets.d.ts +1 -1
- package/{init → typings/init}/types.d.ts +0 -0
- package/{load.d.ts → typings/load.d.ts} +0 -0
- package/{plugins.d.ts → typings/plugins.d.ts} +0 -0
- package/{presets.d.ts → typings/presets.d.ts} +0 -0
- package/{utils → typings/utils}/cli-error.d.ts +0 -0
- package/{utils → typings/utils}/debugging.d.ts +0 -0
- package/{utils → typings/utils}/file-system.d.ts +0 -0
- package/{utils → typings/utils}/indentString.d.ts +0 -0
- package/{utils → typings/utils}/listr-renderer.d.ts +0 -0
- package/{utils → typings/utils}/logger.d.ts +0 -0
- package/{utils → typings/utils}/watcher.d.ts +1 -1
- package/bin.d.ts +0 -1
- package/bin.js +0 -1891
- package/index.d.ts +0 -7
- package/index.js +0 -1902
- package/index.mjs +0 -1858
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { resolve } from 'path';
|
|
2
|
+
import { readFileSync } from 'fs';
|
|
3
|
+
import { Tags } from './types.js';
|
|
4
|
+
export async function guessTargets() {
|
|
5
|
+
const pkg = JSON.parse(readFileSync(resolve(process.cwd(), 'package.json'), {
|
|
6
|
+
encoding: 'utf-8',
|
|
7
|
+
}));
|
|
8
|
+
const dependencies = Object.keys({
|
|
9
|
+
...pkg.dependencies,
|
|
10
|
+
...pkg.devDependencies,
|
|
11
|
+
});
|
|
12
|
+
return {
|
|
13
|
+
[Tags.angular]: isAngular(dependencies),
|
|
14
|
+
[Tags.react]: isReact(dependencies),
|
|
15
|
+
[Tags.stencil]: isStencil(dependencies),
|
|
16
|
+
[Tags.vue]: isVue(dependencies),
|
|
17
|
+
[Tags.browser]: false,
|
|
18
|
+
[Tags.node]: false,
|
|
19
|
+
[Tags.typescript]: isTypescript(dependencies),
|
|
20
|
+
[Tags.flow]: isFlow(dependencies),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function isAngular(dependencies) {
|
|
24
|
+
return dependencies.includes('@angular/core');
|
|
25
|
+
}
|
|
26
|
+
function isReact(dependencies) {
|
|
27
|
+
return dependencies.includes('react');
|
|
28
|
+
}
|
|
29
|
+
function isStencil(dependencies) {
|
|
30
|
+
return dependencies.includes('@stencil/core');
|
|
31
|
+
}
|
|
32
|
+
function isVue(dependencies) {
|
|
33
|
+
return dependencies.includes('vue') || dependencies.includes('nuxt');
|
|
34
|
+
}
|
|
35
|
+
function isTypescript(dependencies) {
|
|
36
|
+
return dependencies.includes('typescript');
|
|
37
|
+
}
|
|
38
|
+
function isFlow(dependencies) {
|
|
39
|
+
return dependencies.includes('flow');
|
|
40
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export var Tags;
|
|
2
|
+
(function (Tags) {
|
|
3
|
+
Tags["browser"] = "Browser";
|
|
4
|
+
Tags["node"] = "Node";
|
|
5
|
+
Tags["typescript"] = "TypeScript";
|
|
6
|
+
Tags["flow"] = "Flow";
|
|
7
|
+
Tags["angular"] = "Angular";
|
|
8
|
+
Tags["stencil"] = "Stencil";
|
|
9
|
+
Tags["react"] = "React";
|
|
10
|
+
Tags["vue"] = "Vue";
|
|
11
|
+
})(Tags || (Tags = {}));
|
package/esm/load.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { loadSchema as loadSchemaToolkit, loadDocuments as loadDocumentsToolkit, } from '@graphql-tools/load';
|
|
2
|
+
import { DetailedError } from '@graphql-codegen/plugin-helpers';
|
|
3
|
+
import { CodeFileLoader } from '@graphql-tools/code-file-loader';
|
|
4
|
+
import { GitLoader } from '@graphql-tools/git-loader';
|
|
5
|
+
import { GithubLoader } from '@graphql-tools/github-loader';
|
|
6
|
+
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
|
|
7
|
+
import { JsonFileLoader } from '@graphql-tools/json-file-loader';
|
|
8
|
+
import { UrlLoader } from '@graphql-tools/url-loader';
|
|
9
|
+
import { ApolloEngineLoader } from '@graphql-tools/apollo-engine-loader';
|
|
10
|
+
import { PrismaLoader } from '@graphql-tools/prisma-loader';
|
|
11
|
+
import { join, extname } from 'path';
|
|
12
|
+
export const defaultSchemaLoadOptions = {
|
|
13
|
+
assumeValidSDL: true,
|
|
14
|
+
sort: true,
|
|
15
|
+
convertExtensions: true,
|
|
16
|
+
includeSources: true,
|
|
17
|
+
};
|
|
18
|
+
export const defaultDocumentsLoadOptions = {
|
|
19
|
+
sort: true,
|
|
20
|
+
skipGraphQLImport: true,
|
|
21
|
+
};
|
|
22
|
+
export async function loadSchema(schemaPointers, config) {
|
|
23
|
+
try {
|
|
24
|
+
const loaders = [
|
|
25
|
+
new CodeFileLoader(),
|
|
26
|
+
new GitLoader(),
|
|
27
|
+
new GithubLoader(),
|
|
28
|
+
new GraphQLFileLoader(),
|
|
29
|
+
new JsonFileLoader(),
|
|
30
|
+
new UrlLoader(),
|
|
31
|
+
new ApolloEngineLoader(),
|
|
32
|
+
new PrismaLoader(),
|
|
33
|
+
];
|
|
34
|
+
const schema = await loadSchemaToolkit(schemaPointers, {
|
|
35
|
+
...defaultSchemaLoadOptions,
|
|
36
|
+
loaders,
|
|
37
|
+
...config,
|
|
38
|
+
...config.config,
|
|
39
|
+
});
|
|
40
|
+
return schema;
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
throw new DetailedError('Failed to load schema', `
|
|
44
|
+
Failed to load schema from ${Object.keys(schemaPointers).join(',')}:
|
|
45
|
+
|
|
46
|
+
${e.message || e}
|
|
47
|
+
${e.stack || ''}
|
|
48
|
+
|
|
49
|
+
GraphQL Code Generator supports:
|
|
50
|
+
- ES Modules and CommonJS exports (export as default or named export "schema")
|
|
51
|
+
- Introspection JSON File
|
|
52
|
+
- URL of GraphQL endpoint
|
|
53
|
+
- Multiple files with type definitions (glob expression)
|
|
54
|
+
- String in config file
|
|
55
|
+
|
|
56
|
+
Try to use one of above options and run codegen again.
|
|
57
|
+
|
|
58
|
+
`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export async function loadDocuments(documentPointers, config) {
|
|
62
|
+
const loaders = [
|
|
63
|
+
new CodeFileLoader({
|
|
64
|
+
pluckConfig: {
|
|
65
|
+
skipIndent: true,
|
|
66
|
+
},
|
|
67
|
+
}),
|
|
68
|
+
new GitLoader(),
|
|
69
|
+
new GithubLoader(),
|
|
70
|
+
new GraphQLFileLoader(),
|
|
71
|
+
];
|
|
72
|
+
const ignore = [];
|
|
73
|
+
for (const generatePath of Object.keys(config.generates)) {
|
|
74
|
+
if (extname(generatePath) === '') {
|
|
75
|
+
// we omit paths that don't resolve to a specific file
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
ignore.push(join(process.cwd(), generatePath));
|
|
79
|
+
}
|
|
80
|
+
const loadedFromToolkit = await loadDocumentsToolkit(documentPointers, {
|
|
81
|
+
...defaultDocumentsLoadOptions,
|
|
82
|
+
ignore,
|
|
83
|
+
loaders,
|
|
84
|
+
...config,
|
|
85
|
+
...config.config,
|
|
86
|
+
});
|
|
87
|
+
return loadedFromToolkit;
|
|
88
|
+
}
|
package/esm/plugins.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { DetailedError } from '@graphql-codegen/plugin-helpers';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
export async function getPluginByName(name, pluginLoader) {
|
|
4
|
+
const possibleNames = [
|
|
5
|
+
`@graphql-codegen/${name}`,
|
|
6
|
+
`@graphql-codegen/${name}-template`,
|
|
7
|
+
`@graphql-codegen/${name}-plugin`,
|
|
8
|
+
`graphql-codegen-${name}`,
|
|
9
|
+
`graphql-codegen-${name}-template`,
|
|
10
|
+
`graphql-codegen-${name}-plugin`,
|
|
11
|
+
`codegen-${name}`,
|
|
12
|
+
`codegen-${name}-template`,
|
|
13
|
+
name,
|
|
14
|
+
];
|
|
15
|
+
const possibleModules = possibleNames.concat(resolve(process.cwd(), name));
|
|
16
|
+
for (const moduleName of possibleModules) {
|
|
17
|
+
try {
|
|
18
|
+
return await pluginLoader(moduleName);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
if (err.code !== 'MODULE_NOT_FOUND') {
|
|
22
|
+
throw new DetailedError(`Unable to load template plugin matching ${name}`, `
|
|
23
|
+
Unable to load template plugin matching '${name}'.
|
|
24
|
+
Reason:
|
|
25
|
+
${err.message}
|
|
26
|
+
`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const possibleNamesMsg = possibleNames
|
|
31
|
+
.map(name => `
|
|
32
|
+
- ${name}
|
|
33
|
+
`.trimRight())
|
|
34
|
+
.join('');
|
|
35
|
+
throw new DetailedError(`Unable to find template plugin matching ${name}`, `
|
|
36
|
+
Unable to find template plugin matching '${name}'
|
|
37
|
+
Install one of the following packages:
|
|
38
|
+
|
|
39
|
+
${possibleNamesMsg}
|
|
40
|
+
`);
|
|
41
|
+
}
|
package/esm/presets.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { DetailedError } from '@graphql-codegen/plugin-helpers';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
export async function getPresetByName(name, loader) {
|
|
4
|
+
const possibleNames = [
|
|
5
|
+
`@graphql-codegen/${name}`,
|
|
6
|
+
`@graphql-codegen/${name}-preset`,
|
|
7
|
+
name,
|
|
8
|
+
resolve(process.cwd(), name),
|
|
9
|
+
];
|
|
10
|
+
for (const moduleName of possibleNames) {
|
|
11
|
+
try {
|
|
12
|
+
const loaded = await loader(moduleName);
|
|
13
|
+
if (loaded && loaded.preset) {
|
|
14
|
+
return loaded.preset;
|
|
15
|
+
}
|
|
16
|
+
if (loaded && loaded.default) {
|
|
17
|
+
return loaded.default;
|
|
18
|
+
}
|
|
19
|
+
return loaded;
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
if (err.code !== 'MODULE_NOT_FOUND') {
|
|
23
|
+
throw new DetailedError(`Unable to load preset matching ${name}`, `
|
|
24
|
+
Unable to load preset matching '${name}'.
|
|
25
|
+
Reason:
|
|
26
|
+
${err.message}
|
|
27
|
+
`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const possibleNamesMsg = possibleNames
|
|
32
|
+
.map(name => `
|
|
33
|
+
- ${name}
|
|
34
|
+
`.trimRight())
|
|
35
|
+
.join('');
|
|
36
|
+
throw new DetailedError(`Unable to find preset matching ${name}`, `
|
|
37
|
+
Unable to find preset matching '${name}'
|
|
38
|
+
Install one of the following packages:
|
|
39
|
+
|
|
40
|
+
${possibleNamesMsg}
|
|
41
|
+
`);
|
|
42
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function isListrError(err) {
|
|
2
|
+
return err.name === 'ListrError' && Array.isArray(err.errors) && err.errors.length > 0;
|
|
3
|
+
}
|
|
4
|
+
export function cliError(err, exitOnError = true) {
|
|
5
|
+
let msg;
|
|
6
|
+
if (err instanceof Error) {
|
|
7
|
+
msg = err.message || err.toString();
|
|
8
|
+
}
|
|
9
|
+
else if (typeof err === 'string') {
|
|
10
|
+
msg = err;
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
msg = JSON.stringify(err);
|
|
14
|
+
}
|
|
15
|
+
// eslint-disable-next-line no-console
|
|
16
|
+
console.error(msg);
|
|
17
|
+
if (exitOnError) {
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { getLogger } from './logger.js';
|
|
2
|
+
let queue = [];
|
|
3
|
+
export function debugLog(message, ...meta) {
|
|
4
|
+
if (!process.env.GQL_CODEGEN_NODEBUG && process.env.DEBUG !== undefined) {
|
|
5
|
+
queue.push({
|
|
6
|
+
message,
|
|
7
|
+
meta,
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function printLogs() {
|
|
12
|
+
if (!process.env.GQL_CODEGEN_NODEBUG && process.env.DEBUG !== undefined) {
|
|
13
|
+
queue.forEach(log => {
|
|
14
|
+
getLogger().info(log.message, ...log.meta);
|
|
15
|
+
});
|
|
16
|
+
resetLogs();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function resetLogs() {
|
|
20
|
+
queue = [];
|
|
21
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { unlink as fsUnlink, promises } from 'fs';
|
|
2
|
+
const { writeFile: fsWriteFile, readFile: fsReadFile, stat: fsStat } = promises;
|
|
3
|
+
export function writeFile(filepath, content) {
|
|
4
|
+
return fsWriteFile(filepath, content);
|
|
5
|
+
}
|
|
6
|
+
export function readFile(filepath) {
|
|
7
|
+
return fsReadFile(filepath, 'utf-8');
|
|
8
|
+
}
|
|
9
|
+
export async function fileExists(filePath) {
|
|
10
|
+
try {
|
|
11
|
+
return (await fsStat(filePath)).isFile();
|
|
12
|
+
}
|
|
13
|
+
catch (err) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function unlinkFile(filePath, cb) {
|
|
18
|
+
fsUnlink(filePath, cb);
|
|
19
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Indent each line in a string.
|
|
3
|
+
@param string - The string to indent.
|
|
4
|
+
@param count - How many times you want `options.indent` repeated. Default: `1`.
|
|
5
|
+
@example
|
|
6
|
+
```
|
|
7
|
+
import indentString from 'indent-string';
|
|
8
|
+
indentString('Unicorns\nRainbows', 4);
|
|
9
|
+
//=> ' Unicorns\n Rainbows'
|
|
10
|
+
indentString('Unicorns\nRainbows', 4, {indent: '♥'});
|
|
11
|
+
//=> '♥♥♥♥Unicorns\n♥♥♥♥Rainbows'
|
|
12
|
+
```
|
|
13
|
+
*/
|
|
14
|
+
export function indentString(string, count = 1, options = {}) {
|
|
15
|
+
const { indent = ' ', includeEmptyLines = false } = options;
|
|
16
|
+
if (typeof string !== 'string') {
|
|
17
|
+
throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof string}\``);
|
|
18
|
+
}
|
|
19
|
+
if (typeof count !== 'number') {
|
|
20
|
+
throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof count}\``);
|
|
21
|
+
}
|
|
22
|
+
if (count < 0) {
|
|
23
|
+
throw new RangeError(`Expected \`count\` to be at least 0, got \`${count}\``);
|
|
24
|
+
}
|
|
25
|
+
if (typeof indent !== 'string') {
|
|
26
|
+
throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof indent}\``);
|
|
27
|
+
}
|
|
28
|
+
if (count === 0) {
|
|
29
|
+
return string;
|
|
30
|
+
}
|
|
31
|
+
const regex = includeEmptyLines ? /^/gm : /^(?!\s*$)/gm;
|
|
32
|
+
return string.replace(regex, indent.repeat(count));
|
|
33
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { indentString } from './indentString.js';
|
|
3
|
+
import logSymbol from 'log-symbols';
|
|
4
|
+
import ansiEscapes from 'ansi-escapes';
|
|
5
|
+
import wrapAnsi from 'wrap-ansi';
|
|
6
|
+
import { stripIndent } from 'common-tags';
|
|
7
|
+
import { isDetailedError } from '@graphql-codegen/plugin-helpers';
|
|
8
|
+
import { debugLog, printLogs } from './debugging.js';
|
|
9
|
+
import UpdateRenderer from 'listr-update-renderer';
|
|
10
|
+
export class Renderer {
|
|
11
|
+
constructor(tasks, options) {
|
|
12
|
+
this.updateRenderer = new UpdateRenderer(tasks, options);
|
|
13
|
+
}
|
|
14
|
+
render() {
|
|
15
|
+
return this.updateRenderer.render();
|
|
16
|
+
}
|
|
17
|
+
end(err) {
|
|
18
|
+
this.updateRenderer.end(err);
|
|
19
|
+
if (typeof err === 'undefined') {
|
|
20
|
+
logUpdate.clear();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
// persist the output
|
|
24
|
+
logUpdate.done();
|
|
25
|
+
// show errors
|
|
26
|
+
if (err) {
|
|
27
|
+
const errorCount = err.errors ? err.errors.length : 0;
|
|
28
|
+
if (errorCount > 0) {
|
|
29
|
+
const count = indentString(chalk.red.bold(`Found ${errorCount} error${errorCount > 1 ? 's' : ''}`), 1);
|
|
30
|
+
const details = err.errors
|
|
31
|
+
.map(error => {
|
|
32
|
+
debugLog(`[CLI] Exited with an error`, error);
|
|
33
|
+
return { msg: isDetailedError(error) ? error.details : null, rawError: error };
|
|
34
|
+
})
|
|
35
|
+
.map(({ msg, rawError }, i) => {
|
|
36
|
+
const source = err.errors[i].source;
|
|
37
|
+
msg = msg ? chalk.gray(indentString(stripIndent(`${msg}`), 4)) : null;
|
|
38
|
+
const stack = rawError.stack ? chalk.gray(indentString(stripIndent(rawError.stack), 4)) : null;
|
|
39
|
+
if (source) {
|
|
40
|
+
const sourceOfError = typeof source === 'string' ? source : source.name;
|
|
41
|
+
const title = indentString(`${logSymbol.error} ${sourceOfError}`, 2);
|
|
42
|
+
return [title, msg, stack, stack].filter(Boolean).join('\n');
|
|
43
|
+
}
|
|
44
|
+
return [msg, stack].filter(Boolean).join('\n');
|
|
45
|
+
})
|
|
46
|
+
.join('\n\n');
|
|
47
|
+
logUpdate.emit(['', count, details, ''].join('\n\n'));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const details = err.details ? err.details : '';
|
|
51
|
+
logUpdate.emit(`${chalk.red.bold(`${indentString(err.message, 2)}`)}\n${details}\n${chalk.grey(err.stack)}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
logUpdate.done();
|
|
55
|
+
printLogs();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const render = tasks => {
|
|
59
|
+
for (const task of tasks) {
|
|
60
|
+
task.subscribe(event => {
|
|
61
|
+
if (event.type === 'SUBTASKS') {
|
|
62
|
+
render(task.subtasks);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (event.type === 'DATA') {
|
|
66
|
+
logUpdate.emit(chalk.dim(`${event.data}`));
|
|
67
|
+
}
|
|
68
|
+
logUpdate.done();
|
|
69
|
+
}, err => {
|
|
70
|
+
logUpdate.emit(err);
|
|
71
|
+
logUpdate.done();
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
export class ErrorRenderer {
|
|
76
|
+
constructor(tasks, _options) {
|
|
77
|
+
this.tasks = tasks;
|
|
78
|
+
}
|
|
79
|
+
render() {
|
|
80
|
+
render(this.tasks);
|
|
81
|
+
}
|
|
82
|
+
static get nonTTY() {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
end() { }
|
|
86
|
+
}
|
|
87
|
+
class LogUpdate {
|
|
88
|
+
constructor() {
|
|
89
|
+
this.stream = process.stdout;
|
|
90
|
+
// state
|
|
91
|
+
this.previousLineCount = 0;
|
|
92
|
+
this.previousOutput = '';
|
|
93
|
+
this.previousWidth = this.getWidth();
|
|
94
|
+
}
|
|
95
|
+
emit(...args) {
|
|
96
|
+
let output = args.join(' ') + '\n';
|
|
97
|
+
const width = this.getWidth();
|
|
98
|
+
if (output === this.previousOutput && this.previousWidth === width) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
this.previousOutput = output;
|
|
102
|
+
this.previousWidth = width;
|
|
103
|
+
output = wrapAnsi(output, width, {
|
|
104
|
+
trim: false,
|
|
105
|
+
hard: true,
|
|
106
|
+
wordWrap: false,
|
|
107
|
+
});
|
|
108
|
+
this.stream.write(ansiEscapes.eraseLines(this.previousLineCount) + output);
|
|
109
|
+
this.previousLineCount = output.split('\n').length;
|
|
110
|
+
}
|
|
111
|
+
clear() {
|
|
112
|
+
this.stream.write(ansiEscapes.eraseLines(this.previousLineCount));
|
|
113
|
+
this.previousOutput = '';
|
|
114
|
+
this.previousWidth = this.getWidth();
|
|
115
|
+
this.previousLineCount = 0;
|
|
116
|
+
}
|
|
117
|
+
done() {
|
|
118
|
+
this.previousOutput = '';
|
|
119
|
+
this.previousWidth = this.getWidth();
|
|
120
|
+
this.previousLineCount = 0;
|
|
121
|
+
}
|
|
122
|
+
getWidth() {
|
|
123
|
+
const { columns } = this.stream;
|
|
124
|
+
if (!columns) {
|
|
125
|
+
return 80;
|
|
126
|
+
}
|
|
127
|
+
return columns;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const logUpdate = new LogUpdate();
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { dummyLogger } from 'ts-log';
|
|
2
|
+
let logger;
|
|
3
|
+
export function getLogger() {
|
|
4
|
+
return logger || dummyLogger;
|
|
5
|
+
}
|
|
6
|
+
useWinstonLogger();
|
|
7
|
+
export function setLogger(newLogger) {
|
|
8
|
+
logger = newLogger;
|
|
9
|
+
}
|
|
10
|
+
export function setSilentLogger() {
|
|
11
|
+
logger = dummyLogger;
|
|
12
|
+
}
|
|
13
|
+
export function useWinstonLogger() {
|
|
14
|
+
if (logger && logger.levels) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
logger = console;
|
|
18
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { executeCodegen } from '../codegen.js';
|
|
2
|
+
import { normalizeInstanceOrArray, normalizeOutputParam } from '@graphql-codegen/plugin-helpers';
|
|
3
|
+
import isGlob from 'is-glob';
|
|
4
|
+
import debounce from 'debounce';
|
|
5
|
+
import logSymbols from 'log-symbols';
|
|
6
|
+
import { debugLog } from './debugging.js';
|
|
7
|
+
import { getLogger } from './logger.js';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import { lifecycleHooks } from '../hooks.js';
|
|
10
|
+
import { loadContext } from '../config.js';
|
|
11
|
+
import { isValidPath } from '@graphql-tools/utils';
|
|
12
|
+
function log(msg) {
|
|
13
|
+
// double spaces to inline the message with Listr
|
|
14
|
+
getLogger().info(` ${msg}`);
|
|
15
|
+
}
|
|
16
|
+
function emitWatching() {
|
|
17
|
+
log(`${logSymbols.info} Watching for changes...`);
|
|
18
|
+
}
|
|
19
|
+
export const createWatcher = (initalContext, onNext) => {
|
|
20
|
+
debugLog(`[Watcher] Starting watcher...`);
|
|
21
|
+
let config = initalContext.getConfig();
|
|
22
|
+
const files = [initalContext.filepath].filter(a => a);
|
|
23
|
+
const documents = normalizeInstanceOrArray(config.documents);
|
|
24
|
+
const schemas = normalizeInstanceOrArray(config.schema);
|
|
25
|
+
// Add schemas and documents from "generates"
|
|
26
|
+
Object.keys(config.generates)
|
|
27
|
+
.map(filename => normalizeOutputParam(config.generates[filename]))
|
|
28
|
+
.forEach(conf => {
|
|
29
|
+
schemas.push(...normalizeInstanceOrArray(conf.schema));
|
|
30
|
+
documents.push(...normalizeInstanceOrArray(conf.documents));
|
|
31
|
+
});
|
|
32
|
+
if (documents) {
|
|
33
|
+
documents.forEach(doc => {
|
|
34
|
+
if (typeof doc === 'string') {
|
|
35
|
+
files.push(doc);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
files.push(...Object.keys(doc));
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
schemas.forEach((schema) => {
|
|
43
|
+
if (isGlob(schema) || isValidPath(schema)) {
|
|
44
|
+
files.push(schema);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
if (typeof config.watch !== 'boolean') {
|
|
48
|
+
files.push(...normalizeInstanceOrArray(config.watch));
|
|
49
|
+
}
|
|
50
|
+
let watcher;
|
|
51
|
+
const runWatcher = async () => {
|
|
52
|
+
var _a, _b;
|
|
53
|
+
const chokidar = await import('chokidar');
|
|
54
|
+
let isShutdown = false;
|
|
55
|
+
const debouncedExec = debounce(() => {
|
|
56
|
+
if (!isShutdown) {
|
|
57
|
+
executeCodegen(initalContext)
|
|
58
|
+
.then(onNext, () => Promise.resolve())
|
|
59
|
+
.then(() => emitWatching());
|
|
60
|
+
}
|
|
61
|
+
}, 100);
|
|
62
|
+
emitWatching();
|
|
63
|
+
const ignored = [];
|
|
64
|
+
Object.keys(config.generates)
|
|
65
|
+
.map(filename => ({ filename, config: normalizeOutputParam(config.generates[filename]) }))
|
|
66
|
+
.forEach(entry => {
|
|
67
|
+
if (entry.config.preset) {
|
|
68
|
+
const extension = entry.config.presetConfig && entry.config.presetConfig.extension;
|
|
69
|
+
if (extension) {
|
|
70
|
+
ignored.push(join(entry.filename, '**', '*' + extension));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
ignored.push(entry.filename);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
watcher = chokidar.watch(files, {
|
|
78
|
+
persistent: true,
|
|
79
|
+
ignoreInitial: true,
|
|
80
|
+
followSymlinks: true,
|
|
81
|
+
cwd: process.cwd(),
|
|
82
|
+
disableGlobbing: false,
|
|
83
|
+
usePolling: (_a = config.watchConfig) === null || _a === void 0 ? void 0 : _a.usePolling,
|
|
84
|
+
interval: (_b = config.watchConfig) === null || _b === void 0 ? void 0 : _b.interval,
|
|
85
|
+
depth: 99,
|
|
86
|
+
awaitWriteFinish: true,
|
|
87
|
+
ignorePermissionErrors: false,
|
|
88
|
+
atomic: true,
|
|
89
|
+
ignored,
|
|
90
|
+
});
|
|
91
|
+
debugLog(`[Watcher] Started`);
|
|
92
|
+
const shutdown = () => {
|
|
93
|
+
isShutdown = true;
|
|
94
|
+
debugLog(`[Watcher] Shutting down`);
|
|
95
|
+
log(`Shutting down watch...`);
|
|
96
|
+
watcher.close();
|
|
97
|
+
lifecycleHooks(config.hooks).beforeDone();
|
|
98
|
+
};
|
|
99
|
+
// it doesn't matter what has changed, need to run whole process anyway
|
|
100
|
+
watcher.on('all', async (eventName, path) => {
|
|
101
|
+
lifecycleHooks(config.hooks).onWatchTriggered(eventName, path);
|
|
102
|
+
debugLog(`[Watcher] triggered due to a file ${eventName} event: ${path}`);
|
|
103
|
+
const fullPath = join(process.cwd(), path);
|
|
104
|
+
// In ESM require is not defined
|
|
105
|
+
try {
|
|
106
|
+
delete require.cache[fullPath];
|
|
107
|
+
}
|
|
108
|
+
catch (err) { }
|
|
109
|
+
if (eventName === 'change' && config.configFilePath && fullPath === config.configFilePath) {
|
|
110
|
+
log(`${logSymbols.info} Config file has changed, reloading...`);
|
|
111
|
+
const context = await loadContext(config.configFilePath);
|
|
112
|
+
const newParsedConfig = context.getConfig();
|
|
113
|
+
newParsedConfig.watch = config.watch;
|
|
114
|
+
newParsedConfig.silent = config.silent;
|
|
115
|
+
newParsedConfig.overwrite = config.overwrite;
|
|
116
|
+
newParsedConfig.configFilePath = config.configFilePath;
|
|
117
|
+
config = newParsedConfig;
|
|
118
|
+
initalContext.updateConfig(config);
|
|
119
|
+
}
|
|
120
|
+
debouncedExec();
|
|
121
|
+
});
|
|
122
|
+
process.once('SIGINT', shutdown);
|
|
123
|
+
process.once('SIGTERM', shutdown);
|
|
124
|
+
};
|
|
125
|
+
// the promise never resolves to keep process running
|
|
126
|
+
return new Promise((resolve, reject) => {
|
|
127
|
+
executeCodegen(initalContext)
|
|
128
|
+
.then(onNext, () => Promise.resolve())
|
|
129
|
+
.then(runWatcher)
|
|
130
|
+
.catch(err => {
|
|
131
|
+
watcher.close();
|
|
132
|
+
reject(err);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
};
|