@graphql-codegen/cli 3.2.1 → 3.2.2-alpha-20230302095206-b34166c23

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/config.js CHANGED
@@ -10,12 +10,14 @@ const plugin_helpers_1 = require("@graphql-codegen/plugin-helpers");
10
10
  const cosmiconfig_1 = require("cosmiconfig");
11
11
  const cosmiconfig_typescript_loader_1 = require("cosmiconfig-typescript-loader");
12
12
  const graphql_1 = require("graphql");
13
+ const child_process_1 = require("child_process");
13
14
  const string_env_interpolation_1 = require("string-env-interpolation");
14
15
  const yaml_1 = tslib_1.__importDefault(require("yaml"));
15
16
  const yargs_1 = tslib_1.__importDefault(require("yargs"));
16
17
  const graphql_config_js_1 = require("./graphql-config.js");
17
18
  const load_js_1 = require("./load.js");
18
- const { lstat } = fs_1.promises;
19
+ const file_system_js_1 = require("./utils/file-system.js");
20
+ const { lstat, rm } = fs_1.promises;
19
21
  function generateSearchPlaces(moduleName) {
20
22
  const extensions = ['json', 'yaml', 'yml', 'js', 'ts', 'config.js'];
21
23
  // gives codegen.json...
@@ -26,7 +28,8 @@ function generateSearchPlaces(moduleName) {
26
28
  }
27
29
  exports.generateSearchPlaces = generateSearchPlaces;
28
30
  function customLoader(ext) {
29
- function loader(filepath, content) {
31
+ return async function loader(filepath, content) {
32
+ var _a;
30
33
  if (typeof process !== 'undefined' && 'env' in process) {
31
34
  content = (0, string_env_interpolation_1.env)(content);
32
35
  }
@@ -47,12 +50,49 @@ function customLoader(ext) {
47
50
  return cosmiconfig_1.defaultLoaders['.js'](filepath, content);
48
51
  }
49
52
  if (ext === 'ts') {
50
- // #8437: conflict with `graphql-config` also using TypeScriptLoader(), causing a double `ts-node` register.
51
- const tsLoader = (0, cosmiconfig_typescript_loader_1.TypeScriptLoader)({ transpileOnly: true });
52
- return tsLoader(filepath, content);
53
+ try {
54
+ // #8437: conflict with `graphql-config` also using TypeScriptLoader(), causing a double `ts-node` register.
55
+ const tsLoader = (0, cosmiconfig_typescript_loader_1.TypeScriptLoader)({ transpileOnly: true });
56
+ return tsLoader(filepath, content);
57
+ }
58
+ catch (err) {
59
+ if (isRequireESMError(err)) {
60
+ const hash = hashContent(content, 'base64url');
61
+ const tempDir = (0, file_system_js_1.getTempDir)();
62
+ let inTempDir = [];
63
+ try {
64
+ inTempDir = await fs_1.promises.readdir(tempDir);
65
+ }
66
+ catch (err) {
67
+ if (err.code === 'ENOENT') {
68
+ // tsc will create the directory if it doesn't exist.
69
+ }
70
+ else {
71
+ throw err;
72
+ }
73
+ }
74
+ let outDir = (0, path_1.join)(tempDir, new Date().getTime() + '-' + hash);
75
+ const previousOutDir = inTempDir.find(s => s.endsWith(hash));
76
+ if (previousOutDir) {
77
+ outDir = (0, path_1.join)(tempDir, previousOutDir);
78
+ }
79
+ else {
80
+ // We're compiling the file, because ts-node doesn't work perfectly with ESM.
81
+ (0, child_process_1.execSync)(`tsc ${filepath} --module commonjs --outDir ${outDir} --skipLibCheck`);
82
+ }
83
+ const newPath = (0, path_1.join)(outDir, (0, path_1.basename)(filepath).replace(/\.ts$/, '.js'));
84
+ const config = (_a = newPath, Promise.resolve().then(() => tslib_1.__importStar(require(_a)))).then(m => {
85
+ const config = m.default;
86
+ return 'default' in config ? config.default : config;
87
+ });
88
+ // If the cache has more than 10 files, we delete the oldest one.
89
+ await removeOldestDirInCache(inTempDir, tempDir, 10);
90
+ return config;
91
+ }
92
+ throw err;
93
+ }
53
94
  }
54
- }
55
- return loader;
95
+ };
56
96
  }
57
97
  async function loadCodegenConfig({ configFilePath, moduleName, searchPlaces: additionalSearchPlaces, packageProp, loaders: customLoaders, }) {
58
98
  configFilePath || (configFilePath = process.cwd());
@@ -76,7 +116,18 @@ async function loadCodegenConfig({ configFilePath, moduleName, searchPlaces: add
76
116
  }
77
117
  exports.loadCodegenConfig = loadCodegenConfig;
78
118
  async function loadContext(configFilePath) {
79
- const graphqlConfig = await (0, graphql_config_js_1.findAndLoadGraphQLConfig)(configFilePath);
119
+ let graphqlConfig;
120
+ try {
121
+ graphqlConfig = await (0, graphql_config_js_1.findAndLoadGraphQLConfig)(configFilePath);
122
+ }
123
+ catch (err) {
124
+ if (isRequireESMError(err)) {
125
+ // TODO: This needs a fix in graphql-config
126
+ }
127
+ else {
128
+ throw err;
129
+ }
130
+ }
80
131
  if (graphqlConfig) {
81
132
  return new CodegenContext({ graphqlConfig });
82
133
  }
@@ -312,8 +363,8 @@ function ensureContext(input) {
312
363
  return input instanceof CodegenContext ? input : new CodegenContext({ config: input });
313
364
  }
314
365
  exports.ensureContext = ensureContext;
315
- function hashContent(content) {
316
- return (0, crypto_1.createHash)('sha256').update(content).digest('hex');
366
+ function hashContent(content, encoding = 'hex') {
367
+ return (0, crypto_1.createHash)('sha256').update(content).digest(encoding);
317
368
  }
318
369
  function hashSchema(schema) {
319
370
  return hashContent((0, graphql_1.print)((0, plugin_helpers_1.getCachedDocumentNodeFromSchema)(schema)));
@@ -356,3 +407,16 @@ function shouldEmitLegacyCommonJSImports(config) {
356
407
  return globalValue;
357
408
  }
358
409
  exports.shouldEmitLegacyCommonJSImports = shouldEmitLegacyCommonJSImports;
410
+ async function removeOldestDirInCache(inTempDir, tempDir, cacheLimit) {
411
+ if (inTempDir.length > cacheLimit) {
412
+ const oldest = inTempDir.sort((a, b) => {
413
+ const aTime = Number(a.split('-')[0]);
414
+ const bTime = Number(b.split('-')[0]);
415
+ return aTime - bTime;
416
+ })[0];
417
+ await rm((0, path_1.join)(tempDir, oldest), { recursive: true, force: true });
418
+ }
419
+ }
420
+ function isRequireESMError(err) {
421
+ return typeof err.stack === 'string' && err.stack.startsWith('Error [ERR_REQUIRE_ESM]:');
422
+ }
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mkdirp = exports.unlinkFile = exports.readFile = exports.writeFile = void 0;
3
+ exports.getTempDir = exports.mkdirp = exports.unlinkFile = exports.readFile = exports.writeFile = void 0;
4
4
  const fs_1 = require("fs");
5
+ const os_1 = require("os");
6
+ const path_1 = require("path");
5
7
  const { writeFile: fsWriteFile, readFile: fsReadFile, mkdir } = fs_1.promises;
6
8
  function writeFile(filepath, content) {
7
9
  return fsWriteFile(filepath, content);
@@ -19,3 +21,7 @@ function mkdirp(filePath) {
19
21
  return mkdir(filePath, { recursive: true });
20
22
  }
21
23
  exports.mkdirp = mkdirp;
24
+ function getTempDir() {
25
+ return (0, path_1.join)((0, os_1.tmpdir)(), `graphql-codegen-cli`);
26
+ }
27
+ exports.getTempDir = getTempDir;
package/esm/config.js CHANGED
@@ -1,17 +1,19 @@
1
1
  import { createHash } from 'crypto';
2
2
  import { promises } from 'fs';
3
3
  import { createRequire } from 'module';
4
- import { resolve } from 'path';
4
+ import { basename, resolve, join } from 'path';
5
5
  import { createNoopProfiler, createProfiler, getCachedDocumentNodeFromSchema, } from '@graphql-codegen/plugin-helpers';
6
6
  import { cosmiconfig, defaultLoaders } from 'cosmiconfig';
7
7
  import { TypeScriptLoader } from 'cosmiconfig-typescript-loader';
8
8
  import { print } from 'graphql';
9
+ import { execSync } from 'child_process';
9
10
  import { env } from 'string-env-interpolation';
10
11
  import yaml from 'yaml';
11
12
  import yargs from 'yargs';
12
13
  import { findAndLoadGraphQLConfig } from './graphql-config.js';
13
14
  import { defaultDocumentsLoadOptions, defaultSchemaLoadOptions, loadDocuments, loadSchema } from './load.js';
14
- const { lstat } = promises;
15
+ import { getTempDir } from './utils/file-system.js';
16
+ const { lstat, rm } = promises;
15
17
  export function generateSearchPlaces(moduleName) {
16
18
  const extensions = ['json', 'yaml', 'yml', 'js', 'ts', 'config.js'];
17
19
  // gives codegen.json...
@@ -21,7 +23,7 @@ export function generateSearchPlaces(moduleName) {
21
23
  return [...regular.concat(dot), 'package.json'];
22
24
  }
23
25
  function customLoader(ext) {
24
- function loader(filepath, content) {
26
+ return async function loader(filepath, content) {
25
27
  if (typeof process !== 'undefined' && 'env' in process) {
26
28
  content = env(content);
27
29
  }
@@ -42,12 +44,49 @@ function customLoader(ext) {
42
44
  return defaultLoaders['.js'](filepath, content);
43
45
  }
44
46
  if (ext === 'ts') {
45
- // #8437: conflict with `graphql-config` also using TypeScriptLoader(), causing a double `ts-node` register.
46
- const tsLoader = TypeScriptLoader({ transpileOnly: true });
47
- return tsLoader(filepath, content);
47
+ try {
48
+ // #8437: conflict with `graphql-config` also using TypeScriptLoader(), causing a double `ts-node` register.
49
+ const tsLoader = TypeScriptLoader({ transpileOnly: true });
50
+ return tsLoader(filepath, content);
51
+ }
52
+ catch (err) {
53
+ if (isRequireESMError(err)) {
54
+ const hash = hashContent(content, 'base64url');
55
+ const tempDir = getTempDir();
56
+ let inTempDir = [];
57
+ try {
58
+ inTempDir = await promises.readdir(tempDir);
59
+ }
60
+ catch (err) {
61
+ if (err.code === 'ENOENT') {
62
+ // tsc will create the directory if it doesn't exist.
63
+ }
64
+ else {
65
+ throw err;
66
+ }
67
+ }
68
+ let outDir = join(tempDir, new Date().getTime() + '-' + hash);
69
+ const previousOutDir = inTempDir.find(s => s.endsWith(hash));
70
+ if (previousOutDir) {
71
+ outDir = join(tempDir, previousOutDir);
72
+ }
73
+ else {
74
+ // We're compiling the file, because ts-node doesn't work perfectly with ESM.
75
+ execSync(`tsc ${filepath} --module commonjs --outDir ${outDir} --skipLibCheck`);
76
+ }
77
+ const newPath = join(outDir, basename(filepath).replace(/\.ts$/, '.js'));
78
+ const config = import(newPath).then(m => {
79
+ const config = m.default;
80
+ return 'default' in config ? config.default : config;
81
+ });
82
+ // If the cache has more than 10 files, we delete the oldest one.
83
+ await removeOldestDirInCache(inTempDir, tempDir, 10);
84
+ return config;
85
+ }
86
+ throw err;
87
+ }
48
88
  }
49
- }
50
- return loader;
89
+ };
51
90
  }
52
91
  export async function loadCodegenConfig({ configFilePath, moduleName, searchPlaces: additionalSearchPlaces, packageProp, loaders: customLoaders, }) {
53
92
  configFilePath || (configFilePath = process.cwd());
@@ -70,7 +109,18 @@ export async function loadCodegenConfig({ configFilePath, moduleName, searchPlac
70
109
  return pathStats.isDirectory() ? cosmi.search(configFilePath) : cosmi.load(configFilePath);
71
110
  }
72
111
  export async function loadContext(configFilePath) {
73
- const graphqlConfig = await findAndLoadGraphQLConfig(configFilePath);
112
+ let graphqlConfig;
113
+ try {
114
+ graphqlConfig = await findAndLoadGraphQLConfig(configFilePath);
115
+ }
116
+ catch (err) {
117
+ if (isRequireESMError(err)) {
118
+ // TODO: This needs a fix in graphql-config
119
+ }
120
+ else {
121
+ throw err;
122
+ }
123
+ }
74
124
  if (graphqlConfig) {
75
125
  return new CodegenContext({ graphqlConfig });
76
126
  }
@@ -299,8 +349,8 @@ export class CodegenContext {
299
349
  export function ensureContext(input) {
300
350
  return input instanceof CodegenContext ? input : new CodegenContext({ config: input });
301
351
  }
302
- function hashContent(content) {
303
- return createHash('sha256').update(content).digest('hex');
352
+ function hashContent(content, encoding = 'hex') {
353
+ return createHash('sha256').update(content).digest(encoding);
304
354
  }
305
355
  function hashSchema(schema) {
306
356
  return hashContent(print(getCachedDocumentNodeFromSchema(schema)));
@@ -342,3 +392,16 @@ export function shouldEmitLegacyCommonJSImports(config) {
342
392
  // }
343
393
  return globalValue;
344
394
  }
395
+ async function removeOldestDirInCache(inTempDir, tempDir, cacheLimit) {
396
+ if (inTempDir.length > cacheLimit) {
397
+ const oldest = inTempDir.sort((a, b) => {
398
+ const aTime = Number(a.split('-')[0]);
399
+ const bTime = Number(b.split('-')[0]);
400
+ return aTime - bTime;
401
+ })[0];
402
+ await rm(join(tempDir, oldest), { recursive: true, force: true });
403
+ }
404
+ }
405
+ function isRequireESMError(err) {
406
+ return typeof err.stack === 'string' && err.stack.startsWith('Error [ERR_REQUIRE_ESM]:');
407
+ }
@@ -1,4 +1,6 @@
1
1
  import { promises, unlink as fsUnlink } from 'fs';
2
+ import { tmpdir } from 'os';
3
+ import { join } from 'path';
2
4
  const { writeFile: fsWriteFile, readFile: fsReadFile, mkdir } = promises;
3
5
  export function writeFile(filepath, content) {
4
6
  return fsWriteFile(filepath, content);
@@ -12,3 +14,6 @@ export function unlinkFile(filePath, cb) {
12
14
  export function mkdirp(filePath) {
13
15
  return mkdir(filePath, { recursive: true });
14
16
  }
17
+ export function getTempDir() {
18
+ return join(tmpdir(), `graphql-codegen-cli`);
19
+ }
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@graphql-codegen/cli",
3
- "version": "3.2.1",
3
+ "version": "3.2.2-alpha-20230302095206-b34166c23",
4
4
  "peerDependencies": {
5
- "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"
5
+ "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",
6
+ "typescript": ">=3.0"
6
7
  },
7
8
  "dependencies": {
8
9
  "@babel/generator": "^7.18.13",
@@ -18,6 +18,7 @@ export type YamlCliFlags = {
18
18
  emitLegacyCommonJSImports?: boolean;
19
19
  };
20
20
  export declare function generateSearchPlaces(moduleName: string): string[];
21
+ export type CodegenConfigLoader = (filepath: string, content: string) => Promise<Types.Config> | Types.Config;
21
22
  export interface LoadCodegenConfigOptions {
22
23
  /**
23
24
  * The path to the config file or directory contains the config file.
@@ -40,7 +41,7 @@ export interface LoadCodegenConfigOptions {
40
41
  /**
41
42
  * Overrides or extends the loaders for specific file extensions
42
43
  */
43
- loaders?: Record<string, (filepath: string, content: string) => Promise<Types.Config> | Types.Config>;
44
+ loaders?: Record<string, CodegenConfigLoader>;
44
45
  }
45
46
  export interface LoadCodegenConfigResult {
46
47
  filepath: string;
@@ -18,6 +18,7 @@ export type YamlCliFlags = {
18
18
  emitLegacyCommonJSImports?: boolean;
19
19
  };
20
20
  export declare function generateSearchPlaces(moduleName: string): string[];
21
+ export type CodegenConfigLoader = (filepath: string, content: string) => Promise<Types.Config> | Types.Config;
21
22
  export interface LoadCodegenConfigOptions {
22
23
  /**
23
24
  * The path to the config file or directory contains the config file.
@@ -40,7 +41,7 @@ export interface LoadCodegenConfigOptions {
40
41
  /**
41
42
  * Overrides or extends the loaders for specific file extensions
42
43
  */
43
- loaders?: Record<string, (filepath: string, content: string) => Promise<Types.Config> | Types.Config>;
44
+ loaders?: Record<string, CodegenConfigLoader>;
44
45
  }
45
46
  export interface LoadCodegenConfigResult {
46
47
  filepath: string;
@@ -2,3 +2,4 @@ export declare function writeFile(filepath: string, content: string): Promise<vo
2
2
  export declare function readFile(filepath: string): Promise<string>;
3
3
  export declare function unlinkFile(filePath: string, cb?: (err?: Error) => any): void;
4
4
  export declare function mkdirp(filePath: string): Promise<string>;
5
+ export declare function getTempDir(): string;
@@ -2,3 +2,4 @@ export declare function writeFile(filepath: string, content: string): Promise<vo
2
2
  export declare function readFile(filepath: string): Promise<string>;
3
3
  export declare function unlinkFile(filePath: string, cb?: (err?: Error) => any): void;
4
4
  export declare function mkdirp(filePath: string): Promise<string>;
5
+ export declare function getTempDir(): string;