@shopify/hydrogen-codegen 0.0.0-next-112ac42-20230517085234
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/dist/cjs/index.cjs +40 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/pluck.cjs +49 -0
- package/dist/cjs/pluck.cjs.map +1 -0
- package/dist/cjs/plugin.cjs +74 -0
- package/dist/cjs/plugin.cjs.map +1 -0
- package/dist/cjs/preset.cjs +98 -0
- package/dist/cjs/preset.cjs.map +1 -0
- package/dist/cjs/schema.cjs +19 -0
- package/dist/cjs/schema.cjs.map +1 -0
- package/dist/cjs/sources.cjs +43 -0
- package/dist/cjs/sources.cjs.map +1 -0
- package/dist/esm/index.d.ts +8 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/pluck.d.ts +23 -0
- package/dist/esm/pluck.js +46 -0
- package/dist/esm/pluck.js.map +1 -0
- package/dist/esm/plugin.d.ts +18 -0
- package/dist/esm/plugin.js +72 -0
- package/dist/esm/plugin.js.map +1 -0
- package/dist/esm/preset.d.ts +8 -0
- package/dist/esm/preset.js +74 -0
- package/dist/esm/preset.js.map +1 -0
- package/dist/esm/schema.d.ts +4 -0
- package/dist/esm/schema.js +16 -0
- package/dist/esm/schema.js.map +1 -0
- package/dist/esm/sources.d.ts +8 -0
- package/dist/esm/sources.js +41 -0
- package/dist/esm/sources.js.map +1 -0
- package/package.json +51 -0
- package/vendor/graphql-tag-pluck/visitor.cjs +377 -0
- package/vendor/graphql-tag-pluck/visitor.mjs +383 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as addPlugin from '@graphql-codegen/add';
|
|
2
|
+
import * as typescriptOperationPlugin from '@graphql-codegen/typescript-operations';
|
|
3
|
+
import { processSources } from './sources.js';
|
|
4
|
+
import { plugin } from './plugin.js';
|
|
5
|
+
import { getSchema } from './schema.js';
|
|
6
|
+
|
|
7
|
+
const namespacedImportName = "StorefrontAPI";
|
|
8
|
+
const interfaceExtensionCode = `
|
|
9
|
+
declare module '@shopify/hydrogen' {
|
|
10
|
+
interface QueryTypes extends GeneratedQueryTypes {}
|
|
11
|
+
interface MutationTypes extends GeneratedMutationTypes {}
|
|
12
|
+
}`;
|
|
13
|
+
const preset = {
|
|
14
|
+
buildGeneratesSection: (options) => {
|
|
15
|
+
if (!options.baseOutputDir.endsWith(".d.ts")) {
|
|
16
|
+
throw new Error("[hydrogen-preset] target output should be a .d.ts file");
|
|
17
|
+
}
|
|
18
|
+
if (options.plugins?.length > 0 && Object.keys(options.plugins).some((p) => p.startsWith("typescript"))) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
"[hydrogen-preset] providing additional typescript-based `plugins` leads to duplicated generated types"
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
const sourcesWithOperations = processSources(options.documents);
|
|
24
|
+
const sources = sourcesWithOperations.map(({ source }) => source);
|
|
25
|
+
const pluginMap = {
|
|
26
|
+
...options.pluginMap,
|
|
27
|
+
[`add`]: addPlugin,
|
|
28
|
+
[`typescript-operations`]: typescriptOperationPlugin,
|
|
29
|
+
[`gen-dts`]: { plugin: plugin }
|
|
30
|
+
};
|
|
31
|
+
const plugins = [
|
|
32
|
+
{
|
|
33
|
+
[`add`]: {
|
|
34
|
+
content: `/* eslint-disable eslint-comments/disable-enable-pair */
|
|
35
|
+
/* eslint-disable eslint-comments/no-unlimited-disable */
|
|
36
|
+
/* eslint-disable */`
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
[`add`]: {
|
|
41
|
+
content: `import * as ${namespacedImportName} from '@shopify/hydrogen/storefront-api-types';
|
|
42
|
+
`
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
[`typescript-operations`]: {
|
|
47
|
+
skipTypename: true,
|
|
48
|
+
useTypeImports: true,
|
|
49
|
+
preResolveTypes: false
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
{ [`gen-dts`]: { sourcesWithOperations, interfaceExtensionCode } },
|
|
53
|
+
...options.plugins
|
|
54
|
+
];
|
|
55
|
+
return [
|
|
56
|
+
{
|
|
57
|
+
filename: options.baseOutputDir,
|
|
58
|
+
plugins,
|
|
59
|
+
pluginMap,
|
|
60
|
+
schema: options.schema || getSchema(),
|
|
61
|
+
config: {
|
|
62
|
+
...options.config,
|
|
63
|
+
namespacedImportName
|
|
64
|
+
},
|
|
65
|
+
documents: sources,
|
|
66
|
+
documentTransforms: options.documentTransforms
|
|
67
|
+
}
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export { interfaceExtensionCode, namespacedImportName, preset };
|
|
73
|
+
//# sourceMappingURL=out.js.map
|
|
74
|
+
//# sourceMappingURL=preset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/preset.ts"],"names":[],"mappings":"AACA,YAAY,eAAe;AAC3B,YAAY,+BAA+B;AAC3C,SAAQ,sBAAqB;AAC7B,SAAQ,UAAU,iBAAgB;AAClC,SAAQ,iBAAgB;AAIjB,MAAM,uBAAuB;AAE7B,MAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAM/B,MAAM,SAA2C;AAAA,EACtD,uBAAuB,CAAC,YAAY;AAClC,QAAI,CAAC,QAAQ,cAAc,SAAS,OAAO,GAAG;AAC5C,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC1E;AAEA,QACE,QAAQ,SAAS,SAAS,KAC1B,OAAO,KAAK,QAAQ,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,YAAY,CAAC,GACnE;AACA,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,wBAAwB,eAAe,QAAQ,SAAS;AAC9D,UAAM,UAAU,sBAAsB,IAAI,CAAC,EAAC,OAAM,MAAM,MAAM;AAE9D,UAAM,YAAY;AAAA,MAChB,GAAG,QAAQ;AAAA,MACX,CAAC,QAAQ;AAAA,MACT,CAAC,0BAA0B;AAAA,MAC3B,CAAC,YAAY,EAAC,QAAQ,UAAS;AAAA,IACjC;AAEA,UAAM,UAAyC;AAAA,MAE7C;AAAA,QACE,CAAC,QAAQ;AAAA,UACP,SAAS;AAAA;AAAA;AAAA,QACX;AAAA,MACF;AAAA,MAEA;AAAA,QACE,CAAC,QAAQ;AAAA,UACP,SAAS,eAAe;AAAA;AAAA,QAC1B;AAAA,MACF;AAAA,MAEA;AAAA,QACE,CAAC,0BAA0B;AAAA,UACzB,cAAc;AAAA,UACd,gBAAgB;AAAA,UAChB,iBAAiB;AAAA,QACnB;AAAA,MACF;AAAA,MAEA,EAAC,CAAC,YAAY,EAAC,uBAAuB,uBAAsB,EAAC;AAAA,MAE7D,GAAG,QAAQ;AAAA,IACb;AAEA,WAAO;AAAA,MACL;AAAA,QACE,UAAU,QAAQ;AAAA,QAClB;AAAA,QACA;AAAA,QACA,QAAQ,QAAQ,UAAU,UAAU;AAAA,QACpC,QAAQ;AAAA,UACN,GAAG,QAAQ;AAAA,UAEX;AAAA,QACF;AAAA,QACA,WAAW;AAAA,QACX,oBAAoB,QAAQ;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AACF","sourcesContent":["import type {Types} from '@graphql-codegen/plugin-helpers';\nimport * as addPlugin from '@graphql-codegen/add';\nimport * as typescriptOperationPlugin from '@graphql-codegen/typescript-operations';\nimport {processSources} from './sources.js';\nimport {plugin as dtsPlugin} from './plugin.js';\nimport {getSchema} from './schema.js';\n\nexport type GqlTagConfig = {};\n\nexport const namespacedImportName = 'StorefrontAPI';\n\nexport const interfaceExtensionCode = `\ndeclare module '@shopify/hydrogen' {\n interface QueryTypes extends GeneratedQueryTypes {}\n interface MutationTypes extends GeneratedMutationTypes {}\n}`;\n\nexport const preset: Types.OutputPreset<GqlTagConfig> = {\n buildGeneratesSection: (options) => {\n if (!options.baseOutputDir.endsWith('.d.ts')) {\n throw new Error('[hydrogen-preset] target output should be a .d.ts file');\n }\n\n if (\n options.plugins?.length > 0 &&\n Object.keys(options.plugins).some((p) => p.startsWith('typescript'))\n ) {\n throw new Error(\n '[hydrogen-preset] providing additional typescript-based `plugins` leads to duplicated generated types',\n );\n }\n\n const sourcesWithOperations = processSources(options.documents);\n const sources = sourcesWithOperations.map(({source}) => source);\n\n const pluginMap = {\n ...options.pluginMap,\n [`add`]: addPlugin,\n [`typescript-operations`]: typescriptOperationPlugin,\n [`gen-dts`]: {plugin: dtsPlugin},\n };\n\n const plugins: Array<Types.ConfiguredPlugin> = [\n // 1. Disable eslint for the generated file\n {\n [`add`]: {\n content: `/* eslint-disable eslint-comments/disable-enable-pair */\\n/* eslint-disable eslint-comments/no-unlimited-disable */\\n/* eslint-disable */`,\n },\n },\n // 2. Import all the generated API types from Hydrogen\n {\n [`add`]: {\n content: `import * as ${namespacedImportName} from '@shopify/hydrogen/storefront-api-types';\\n`,\n },\n },\n // 3. Generate the operations (i.e. queries, mutations, and fragments types)\n {\n [`typescript-operations`]: {\n skipTypename: true, // Skip __typename fields\n useTypeImports: true, // Use `import type` instead of `import`\n preResolveTypes: false, // Use Pick<...> instead of primitives\n },\n },\n // 4. Augment Hydrogen query/mutation interfaces with the generated operations\n {[`gen-dts`]: {sourcesWithOperations, interfaceExtensionCode}},\n // 5. Custom plugins from the user\n ...options.plugins,\n ];\n\n return [\n {\n filename: options.baseOutputDir,\n plugins,\n pluginMap,\n schema: options.schema || getSchema(),\n config: {\n ...options.config,\n // This is for the operations plugin\n namespacedImportName,\n },\n documents: sources,\n documentTransforms: options.documentTransforms,\n },\n ];\n },\n};\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {createRequire} from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
+
const getSchema = () => require.resolve("@shopify/hydrogen-react/storefront.schema.json");
|
|
3
|
+
let staticSchema = "";
|
|
4
|
+
try {
|
|
5
|
+
staticSchema = getSchema();
|
|
6
|
+
} catch (error) {
|
|
7
|
+
console.warn(
|
|
8
|
+
"[hydrogen-codegen] storefront.schema.json not found. Is `@shopify/hydrogen` installed?\n",
|
|
9
|
+
error.message
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
const schema = staticSchema;
|
|
13
|
+
|
|
14
|
+
export { getSchema, schema };
|
|
15
|
+
//# sourceMappingURL=out.js.map
|
|
16
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/schema.ts"],"names":[],"mappings":"AACA;AACO,MAAM,YAAY,MACP;AAElB,IAAI,eAAe;AAEnB,IAAI;AACF,iBAAe,UAAU;AAC3B,SAAS,OAAP;AAGA,UAAQ;AAAA,IACN;AAAA,IACC,MAAgB;AAAA,EACnB;AACF;AAEO,MAAM,SAAS","sourcesContent":["// This comment is used during ESM build:\n//! import {createRequire} from 'module'; const require = createRequire(import.meta.url);\nexport const getSchema = () =>\n require.resolve('@shopify/hydrogen-react/storefront.schema.json');\n\nlet staticSchema = '';\n\ntry {\n staticSchema = getSchema();\n} catch (error) {\n // This can happen at build time or when '@shopify/hydrogen-react' is not found.\n // Generally this shouldn't be an issue in real apps so let's ignore the error.\n console.warn(\n '[hydrogen-codegen] storefront.schema.json not found. Is `@shopify/hydrogen` installed?\\n',\n (error as Error).message,\n );\n}\n\nexport const schema = staticSchema;\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SourceWithOperations } from './plugin.js';
|
|
2
|
+
import { Source } from '@graphql-tools/utils';
|
|
3
|
+
import { OperationDefinitionNode, FragmentDefinitionNode } from 'graphql';
|
|
4
|
+
import '@graphql-codegen/plugin-helpers';
|
|
5
|
+
|
|
6
|
+
declare function processSources(sources: Array<Source>, buildName?: (node: OperationDefinitionNode | FragmentDefinitionNode) => string): SourceWithOperations[];
|
|
7
|
+
|
|
8
|
+
export { processSources };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
|
2
|
+
const capitalizeQueries = (node) => {
|
|
3
|
+
if (node.kind === "FragmentDefinition") {
|
|
4
|
+
return "not used";
|
|
5
|
+
}
|
|
6
|
+
return capitalize(node.name.value) + capitalize(node.operation);
|
|
7
|
+
};
|
|
8
|
+
function processSources(sources, buildName = capitalizeQueries) {
|
|
9
|
+
const sourcesWithOperations = [];
|
|
10
|
+
for (const originalSource of sources) {
|
|
11
|
+
const source = fixLinebreaks(originalSource);
|
|
12
|
+
const { document } = source;
|
|
13
|
+
const operations = [];
|
|
14
|
+
for (const definition of document?.definitions ?? []) {
|
|
15
|
+
if (definition?.kind !== "OperationDefinition" && definition?.kind !== "FragmentDefinition")
|
|
16
|
+
continue;
|
|
17
|
+
if (definition.name?.kind !== `Name`)
|
|
18
|
+
continue;
|
|
19
|
+
operations.push({
|
|
20
|
+
initialName: buildName(definition),
|
|
21
|
+
definition
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
if (operations.length === 0)
|
|
25
|
+
continue;
|
|
26
|
+
sourcesWithOperations.push({
|
|
27
|
+
source,
|
|
28
|
+
operations
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return sourcesWithOperations;
|
|
32
|
+
}
|
|
33
|
+
function fixLinebreaks(source) {
|
|
34
|
+
const fixedSource = { ...source };
|
|
35
|
+
fixedSource.rawSDL = source.rawSDL?.replace(/\r\n/g, "\n");
|
|
36
|
+
return fixedSource;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { processSources };
|
|
40
|
+
//# sourceMappingURL=out.js.map
|
|
41
|
+
//# sourceMappingURL=sources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/sources.ts"],"names":[],"mappings":"AAIA,MAAM,aAAa,CAAC,QAAgB,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAE7E,MAAM,oBAAoB,CACxB,SACG;AACH,MAAI,KAAK,SAAS,sBAAsB;AACtC,WAAO;AAAA,EACT;AAKA,SAAO,WAAW,KAAK,KAAM,KAAK,IAAI,WAAW,KAAK,SAAS;AACjE;AAEO,SAAS,eACd,SACA,YAAY,mBACZ;AACA,QAAM,wBAAqD,CAAC;AAE5D,aAAW,kBAAkB,SAAS;AACpC,UAAM,SAAS,cAAc,cAAc;AAC3C,UAAM,EAAC,SAAQ,IAAI;AACnB,UAAM,aAAyC,CAAC;AAEhD,eAAW,cAAc,UAAU,eAAe,CAAC,GAAG;AACpD,UACE,YAAY,SAAS,yBACrB,YAAY,SAAS;AAErB;AAEF,UAAI,WAAW,MAAM,SAAS;AAAQ;AAEtC,iBAAW,KAAK;AAAA,QACd,aAAa,UAAU,UAAU;AAAA,QACjC;AAAA,MACF,CAAC;AAAA,IACH;AAEA,QAAI,WAAW,WAAW;AAAG;AAE7B,0BAAsB,KAAK;AAAA,MACzB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AA6CA,SAAS,cAAc,QAAgB;AACrC,QAAM,cAAc,EAAC,GAAG,OAAM;AAE9B,cAAY,SAAS,OAAO,QAAQ,QAAQ,SAAS,IAAI;AAEzD,SAAO;AACT","sourcesContent":["import type {OperationOrFragment, SourceWithOperations} from './plugin.js';\nimport type {Source} from '@graphql-tools/utils';\nimport type {FragmentDefinitionNode, OperationDefinitionNode} from 'graphql';\n\nconst capitalize = (str: string) => str.charAt(0).toUpperCase() + str.slice(1);\n\nconst capitalizeQueries = (\n node: OperationDefinitionNode | FragmentDefinitionNode,\n) => {\n if (node.kind === 'FragmentDefinition') {\n return 'not used';\n }\n\n // Match the names generated by typescript-operations plugin:\n // e.g. 'query Hello {...}' => HelloQuery\n // -- Anonymous queries are not supported.\n return capitalize(node.name!.value) + capitalize(node.operation);\n};\n\nexport function processSources(\n sources: Array<Source>,\n buildName = capitalizeQueries,\n) {\n const sourcesWithOperations: Array<SourceWithOperations> = [];\n\n for (const originalSource of sources) {\n const source = fixLinebreaks(originalSource);\n const {document} = source;\n const operations: Array<OperationOrFragment> = [];\n\n for (const definition of document?.definitions ?? []) {\n if (\n definition?.kind !== 'OperationDefinition' &&\n definition?.kind !== 'FragmentDefinition'\n )\n continue;\n\n if (definition.name?.kind !== `Name`) continue;\n\n operations.push({\n initialName: buildName(definition),\n definition,\n });\n }\n\n if (operations.length === 0) continue;\n\n sourcesWithOperations.push({\n source,\n operations,\n });\n }\n\n return sourcesWithOperations;\n}\n\n/**\n * https://github.com/dotansimha/graphql-code-generator/issues/7362\n *\n * Source file is read by @graphql/tools using fs.promises.readFile,\n * which means that the linebreaks are read as-is and the result will be different\n * depending on the OS: it will contain LF (\\n) on Linux/MacOS and CRLF (\\r\\n) on Windows.\n *\n * In most scenarios that would be OK. However, gql-tag-operation is using the resulting string\n * as a TypeScript type. Which means that the string will be compared against a template literal,\n * for example:\n *\n * <pre><code>\n * `\n * query a {\n * a\n * }\n * ` === '\\n query a {\\n a\\n }\\n '\n * </code></pre>\n *\n * According to clause 12.8.6.2 of ECMAScript Language Specification\n * (https://tc39.es/ecma262/#sec-static-semantics-trv),\n * when comparing strings, JavaScript doesn't care which linebreaks does the source file contain,\n * any linebreak (CR, LF or CRLF) is LF from JavaScript standpoint\n * (otherwise the result of the above comparison would be OS-dependent, which doesn't make sense).\n *\n * Therefore gql-tag-operation would break on Windows as it would generate\n *\n * '\\r\\n query a {\\r\\n a\\r\\n }\\r\\n '\n *\n * which is NOT equal to\n *\n * <pre><code>\n * `\n * query a {\n * a\n * }\n * `\n * </code></pre>\n *\n * Therefore we need to replace \\r\\n with \\n in the string.\n *\n * @param source\n */\nfunction fixLinebreaks(source: Source) {\n const fixedSource = {...source};\n\n fixedSource.rawSDL = source.rawSDL?.replace(/\\r\\n/g, '\\n');\n\n return fixedSource;\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shopify/hydrogen-codegen",
|
|
3
|
+
"publishConfig": {
|
|
4
|
+
"access": "public",
|
|
5
|
+
"@shopify:registry": "https://registry.npmjs.org"
|
|
6
|
+
},
|
|
7
|
+
"version": "0.0.0-next-112ac42-20230517085234",
|
|
8
|
+
"license": "SEE LICENSE IN LICENSE.md",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"main": "dist/cjs/index.cjs",
|
|
11
|
+
"module": "dist/esm/index.js",
|
|
12
|
+
"types": "dist/esm/index.d.ts",
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsup --clean --config ./tsup.config.ts",
|
|
16
|
+
"dev": "tsup --watch --config ./tsup.config.ts",
|
|
17
|
+
"typecheck": "tsc --noEmit",
|
|
18
|
+
"test": "cross-env SHOPIFY_UNIT_TEST=1 vitest run",
|
|
19
|
+
"test:watch": "cross-env SHOPIFY_UNIT_TEST=1 vitest"
|
|
20
|
+
},
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/esm/index.d.ts",
|
|
24
|
+
"require": "./dist/cjs/index.cjs",
|
|
25
|
+
"import": "./dist/esm/index.js",
|
|
26
|
+
"default": "./dist/esm/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./package.json": "./package.json"
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/shopify/hydrogen.git",
|
|
33
|
+
"directory": "packages/hydrogen-codegen"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"vendor"
|
|
38
|
+
],
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@graphql-codegen/cli": "3.3.1",
|
|
41
|
+
"@graphql-codegen/plugin-helpers": "^4.1.0",
|
|
42
|
+
"@graphql-tools/utils": "^9.0.0"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@graphql-codegen/add": "^4.0.1",
|
|
46
|
+
"@graphql-codegen/typescript-operations": "^3.0.1"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"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"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
Object.defineProperty(exports, '__esModule', {value: true});
|
|
3
|
+
const utils_js_1 = require('./utils.js');
|
|
4
|
+
const types_1 = require('@babel/types');
|
|
5
|
+
const utils_1 = require('@graphql-tools/utils');
|
|
6
|
+
const defaults = {
|
|
7
|
+
modules: [
|
|
8
|
+
{
|
|
9
|
+
name: 'graphql-tag',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
name: 'graphql-tag.macro',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: '@apollo/client',
|
|
16
|
+
identifier: 'gql',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: '@apollo/client/core',
|
|
20
|
+
identifier: 'gql',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'apollo-angular',
|
|
24
|
+
identifier: 'gql',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'gatsby',
|
|
28
|
+
identifier: 'graphql',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'apollo-server-express',
|
|
32
|
+
identifier: 'gql',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'apollo-server',
|
|
36
|
+
identifier: 'gql',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'react-relay',
|
|
40
|
+
identifier: 'graphql',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'react-relay/hooks',
|
|
44
|
+
identifier: 'graphql',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'relay-runtime',
|
|
48
|
+
identifier: 'graphql',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'babel-plugin-relay/macro',
|
|
52
|
+
identifier: 'graphql',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'apollo-boost',
|
|
56
|
+
identifier: 'gql',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'apollo-server-koa',
|
|
60
|
+
identifier: 'gql',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'apollo-server-hapi',
|
|
64
|
+
identifier: 'gql',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: 'apollo-server-fastify',
|
|
68
|
+
identifier: 'gql',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: ' apollo-server-lambda',
|
|
72
|
+
identifier: 'gql',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'apollo-server-micro',
|
|
76
|
+
identifier: 'gql',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: 'apollo-server-azure-functions',
|
|
80
|
+
identifier: 'gql',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: 'apollo-server-cloud-functions',
|
|
84
|
+
identifier: 'gql',
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'apollo-server-cloudflare',
|
|
88
|
+
identifier: 'gql',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: 'graphql.macro',
|
|
92
|
+
identifier: 'gql',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: '@urql/core',
|
|
96
|
+
identifier: 'gql',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'urql',
|
|
100
|
+
identifier: 'gql',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: '@urql/preact',
|
|
104
|
+
identifier: 'gql',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: '@urql/svelte',
|
|
108
|
+
identifier: 'gql',
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: '@urql/vue',
|
|
112
|
+
identifier: 'gql',
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
gqlMagicComment: 'graphql',
|
|
116
|
+
globalGqlIdentifierName: ['gql', 'graphql'],
|
|
117
|
+
};
|
|
118
|
+
function defaultPluckStringFromFile(code, {start, end}, options = {}) {
|
|
119
|
+
return (0, utils_js_1.freeText)(
|
|
120
|
+
code
|
|
121
|
+
// Slice quotes
|
|
122
|
+
.slice(start + 1, end - 1)
|
|
123
|
+
// Erase string interpolations as we gonna export everything as a single
|
|
124
|
+
// string anyway
|
|
125
|
+
.replace(/\$\{[^}]*\}/g, '')
|
|
126
|
+
.split('\\`')
|
|
127
|
+
.join('`'),
|
|
128
|
+
options.skipIndent,
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
function defaultIsGqlTemplateLiteral(node, options) {
|
|
132
|
+
const leadingComments = node.leadingComments;
|
|
133
|
+
if (!leadingComments) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (!leadingComments.length) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const leadingComment = leadingComments[leadingComments.length - 1];
|
|
140
|
+
const leadingCommentValue = leadingComment.value.trim().toLowerCase();
|
|
141
|
+
if (leadingCommentValue === options.gqlMagicComment) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
exports.default = (code, out, options = {}) => {
|
|
147
|
+
// Apply defaults to options
|
|
148
|
+
let {
|
|
149
|
+
modules = [],
|
|
150
|
+
globalGqlIdentifierName,
|
|
151
|
+
gqlMagicComment,
|
|
152
|
+
skipIndent,
|
|
153
|
+
isGqlTemplateLiteral = defaultIsGqlTemplateLiteral,
|
|
154
|
+
pluckStringFromFile = defaultPluckStringFromFile,
|
|
155
|
+
} = {
|
|
156
|
+
...defaults,
|
|
157
|
+
...options,
|
|
158
|
+
};
|
|
159
|
+
// Prevent case related potential errors
|
|
160
|
+
gqlMagicComment = gqlMagicComment.toLowerCase();
|
|
161
|
+
// normalize `name` and `identifier` values
|
|
162
|
+
modules = modules.map((mod) => {
|
|
163
|
+
return {
|
|
164
|
+
name: mod.name,
|
|
165
|
+
identifier: mod.identifier && mod.identifier.toLowerCase(),
|
|
166
|
+
};
|
|
167
|
+
});
|
|
168
|
+
globalGqlIdentifierName = (0, utils_1.asArray)(globalGqlIdentifierName).map(
|
|
169
|
+
(s) => s.toLowerCase(),
|
|
170
|
+
);
|
|
171
|
+
const hooksOptions = {
|
|
172
|
+
skipIndent,
|
|
173
|
+
gqlMagicComment,
|
|
174
|
+
modules,
|
|
175
|
+
globalGqlIdentifierName,
|
|
176
|
+
};
|
|
177
|
+
// Keep imported identifiers
|
|
178
|
+
// import gql from 'graphql-tag' -> gql
|
|
179
|
+
// import { graphql } from 'gatsby' -> graphql
|
|
180
|
+
// Will result with ['gql', 'graphql']
|
|
181
|
+
const definedIdentifierNames = [];
|
|
182
|
+
const alreadyProcessedOperationsCache = new Set();
|
|
183
|
+
// Will accumulate all template literals
|
|
184
|
+
const gqlTemplateLiterals = [];
|
|
185
|
+
// Check if package is registered
|
|
186
|
+
function isValidPackage(name) {
|
|
187
|
+
return modules.some(
|
|
188
|
+
(pkg) =>
|
|
189
|
+
pkg.name && name && pkg.name.toLowerCase() === name.toLowerCase(),
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
// Check if identifier is defined and imported from registered packages
|
|
193
|
+
function isValidIdentifier(name) {
|
|
194
|
+
return (
|
|
195
|
+
definedIdentifierNames.some((id) => id === name) ||
|
|
196
|
+
globalGqlIdentifierName.includes(name)
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
const addTemplateLiteralToResult = (content) => {
|
|
200
|
+
const cacheKey = `end/${content.end}/start/${content.start}/${content.content}`;
|
|
201
|
+
if (alreadyProcessedOperationsCache.has(cacheKey)) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
alreadyProcessedOperationsCache.add(cacheKey);
|
|
205
|
+
gqlTemplateLiterals.push(content);
|
|
206
|
+
};
|
|
207
|
+
// Push all template literals leaded by graphql magic comment
|
|
208
|
+
// e.g. /* GraphQL */ `query myQuery {}` -> query myQuery {}
|
|
209
|
+
const pluckMagicTemplateLiteral = (node, takeExpression = false) => {
|
|
210
|
+
if (!isGqlTemplateLiteral(node, hooksOptions)) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const nodeToUse = takeExpression ? node.expression : node;
|
|
214
|
+
const gqlTemplateLiteral = pluckStringFromFile(
|
|
215
|
+
code,
|
|
216
|
+
nodeToUse,
|
|
217
|
+
hooksOptions,
|
|
218
|
+
);
|
|
219
|
+
if (gqlTemplateLiteral) {
|
|
220
|
+
addTemplateLiteralToResult({
|
|
221
|
+
content: gqlTemplateLiteral,
|
|
222
|
+
loc: node.loc,
|
|
223
|
+
end: node.end,
|
|
224
|
+
start: node.start,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
const visitor = {
|
|
229
|
+
CallExpression: {
|
|
230
|
+
enter(path) {
|
|
231
|
+
// Find the identifier name used from graphql-tag, commonJS
|
|
232
|
+
// e.g. import gql from 'graphql-tag' -> gql
|
|
233
|
+
const arg0 = path.node.arguments[0];
|
|
234
|
+
if (
|
|
235
|
+
'name' in path.node.callee &&
|
|
236
|
+
path.node.callee.name === 'require' &&
|
|
237
|
+
'value' in arg0 &&
|
|
238
|
+
typeof arg0.value === 'string' &&
|
|
239
|
+
isValidPackage(arg0.value)
|
|
240
|
+
) {
|
|
241
|
+
if (!(0, types_1.isVariableDeclarator)(path.parent)) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (!(0, types_1.isIdentifier)(path.parent.id)) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
definedIdentifierNames.push(path.parent.id.name);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
// Checks to see if a node represents a typescript '<expression> as const' expression
|
|
251
|
+
function isTSAsConstExpression(node) {
|
|
252
|
+
return (
|
|
253
|
+
(0, types_1.isTSAsExpression)(node) &&
|
|
254
|
+
(0, types_1.isTSTypeReference)(node.typeAnnotation) &&
|
|
255
|
+
(0, types_1.isIdentifier)(node.typeAnnotation.typeName) &&
|
|
256
|
+
node.typeAnnotation.typeName.name === 'const'
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
// Extract template literal from as const expression if applicable
|
|
260
|
+
// e.g. gql(`query myQuery {}` as const)
|
|
261
|
+
const unwrappedExpression = isTSAsConstExpression(arg0)
|
|
262
|
+
? arg0.expression
|
|
263
|
+
: arg0;
|
|
264
|
+
// Push strings template literals to gql calls
|
|
265
|
+
// e.g. gql(`query myQuery {}`) -> query myQuery {}
|
|
266
|
+
if (
|
|
267
|
+
(0, types_1.isIdentifier)(path.node.callee) &&
|
|
268
|
+
isValidIdentifier(path.node.callee.name) &&
|
|
269
|
+
(0, types_1.isTemplateLiteral)(unwrappedExpression)
|
|
270
|
+
) {
|
|
271
|
+
const {start, end, loc} = unwrappedExpression;
|
|
272
|
+
if (start != null && end != null && start != null && loc != null) {
|
|
273
|
+
const gqlTemplateLiteral = pluckStringFromFile(
|
|
274
|
+
code,
|
|
275
|
+
unwrappedExpression,
|
|
276
|
+
hooksOptions,
|
|
277
|
+
);
|
|
278
|
+
// If the entire template was made out of interpolations it should be an empty
|
|
279
|
+
// string by now and thus should be ignored
|
|
280
|
+
if (gqlTemplateLiteral) {
|
|
281
|
+
addTemplateLiteralToResult({
|
|
282
|
+
content: gqlTemplateLiteral,
|
|
283
|
+
loc,
|
|
284
|
+
end,
|
|
285
|
+
start,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
ImportDeclaration: {
|
|
293
|
+
enter(path) {
|
|
294
|
+
// Find the identifier name used from graphql-tag, es6
|
|
295
|
+
// e.g. import gql from 'graphql-tag' -> gql
|
|
296
|
+
if (!isValidPackage(path.node.source.value)) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
const moduleNode = modules.find(
|
|
300
|
+
(pkg) =>
|
|
301
|
+
pkg.name.toLowerCase() === path.node.source.value.toLowerCase(),
|
|
302
|
+
);
|
|
303
|
+
if (moduleNode == null) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
const gqlImportSpecifier = path.node.specifiers.find(
|
|
307
|
+
(importSpecifier) => {
|
|
308
|
+
// When it's a default import and registered package has no named identifier
|
|
309
|
+
if (
|
|
310
|
+
(0, types_1.isImportDefaultSpecifier)(importSpecifier) &&
|
|
311
|
+
!moduleNode.identifier
|
|
312
|
+
) {
|
|
313
|
+
return true;
|
|
314
|
+
}
|
|
315
|
+
// When it's a named import that matches registered package's identifier
|
|
316
|
+
if (
|
|
317
|
+
(0, types_1.isImportSpecifier)(importSpecifier) &&
|
|
318
|
+
'name' in importSpecifier.imported &&
|
|
319
|
+
importSpecifier.imported.name === moduleNode.identifier
|
|
320
|
+
) {
|
|
321
|
+
return true;
|
|
322
|
+
}
|
|
323
|
+
return false;
|
|
324
|
+
},
|
|
325
|
+
);
|
|
326
|
+
if (!gqlImportSpecifier) {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
definedIdentifierNames.push(gqlImportSpecifier.local.name);
|
|
330
|
+
},
|
|
331
|
+
},
|
|
332
|
+
ExpressionStatement: {
|
|
333
|
+
exit(path) {
|
|
334
|
+
// Push all template literals leaded by graphql magic comment
|
|
335
|
+
// e.g. /* GraphQL */ `query myQuery {}` -> query myQuery {}
|
|
336
|
+
if (!(0, types_1.isTemplateLiteral)(path.node.expression)) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
pluckMagicTemplateLiteral(path.node, true);
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
TemplateLiteral: {
|
|
343
|
+
exit(path) {
|
|
344
|
+
pluckMagicTemplateLiteral(path.node);
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
TaggedTemplateExpression: {
|
|
348
|
+
exit(path) {
|
|
349
|
+
// Push all template literals provided to the found identifier name
|
|
350
|
+
// e.g. gql `query myQuery {}` -> query myQuery {}
|
|
351
|
+
if (
|
|
352
|
+
!(0, types_1.isIdentifier)(path.node.tag) ||
|
|
353
|
+
!isValidIdentifier(path.node.tag.name)
|
|
354
|
+
) {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
const gqlTemplateLiteral = pluckStringFromFile(
|
|
358
|
+
code,
|
|
359
|
+
path.node.quasi,
|
|
360
|
+
hooksOptions,
|
|
361
|
+
);
|
|
362
|
+
if (gqlTemplateLiteral) {
|
|
363
|
+
addTemplateLiteralToResult({
|
|
364
|
+
content: gqlTemplateLiteral,
|
|
365
|
+
end: path.node.quasi.end,
|
|
366
|
+
start: path.node.quasi.start,
|
|
367
|
+
loc: path.node.quasi.loc,
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
exit() {
|
|
373
|
+
out.returnValue = gqlTemplateLiterals;
|
|
374
|
+
},
|
|
375
|
+
};
|
|
376
|
+
return visitor;
|
|
377
|
+
};
|