vite-plugin-graphql-loader
Advanced tools
Comparing version 3.0.1 to 4.0.0
@@ -1,7 +0,13 @@ | ||
export declare const vitePluginGraphqlLoader: () => { | ||
import { SourceMap } from "magic-string"; | ||
export declare const vitePluginGraphqlLoader: (options?: { | ||
noSourceMap?: boolean; | ||
}) => { | ||
name: string; | ||
enforce: "pre"; | ||
transform(source: string, id: string): string; | ||
transform(source: string, id: string): { | ||
code: string; | ||
map: SourceMap; | ||
}; | ||
}; | ||
export default vitePluginGraphqlLoader; | ||
//# sourceMappingURL=index.d.ts.map |
import { EOL } from "os"; | ||
import { gql } from "graphql-tag"; | ||
import { ONE_QUERY_FUNCTION_TEMPLATE, UNIQUE_FUNCTION_TEMPLATE, } from "./snippets.js"; | ||
import MagicString from "magic-string"; | ||
import { vitePluginGraphqlLoaderUniqueChecker, vitePluginGraphqlLoaderExtractQuery, } from "./snippets.js"; | ||
const DOC_NAME = "_gql_doc"; | ||
const expandImports = (source) => { | ||
const lines = source.split(/\r\n|\r|\n/); | ||
let outputCode; | ||
const importNames = new Set(); | ||
const imports = []; | ||
const importAppends = []; | ||
lines.some((line) => { | ||
@@ -11,17 +15,15 @@ const result = line.match(/^#\s?import (.+)$/); | ||
const [_, importFile] = result; | ||
const importName = "Import_" + importFile.replace(/[^a-z0-9]/gi, "_"); | ||
const importStatement = `import ${importName} from ${importFile};`; | ||
const appendDefinition = `doc.definitions = doc.definitions.concat(unique(${importName}.definitions));`; | ||
outputCode = | ||
(outputCode ?? UNIQUE_FUNCTION_TEMPLATE) + | ||
importStatement + | ||
EOL + | ||
appendDefinition + | ||
EOL; | ||
let importName = "Import_" + importFile.replace(/[^a-z0-9]/gi, "_"); | ||
while (importNames.has(importName)) { | ||
importName = importName + "_"; | ||
} | ||
importNames.add(importName); | ||
imports.push(`import ${importName} from ${importFile};\n`); | ||
importAppends.push(`${DOC_NAME}.definitions = ${DOC_NAME}.definitions.concat(${vitePluginGraphqlLoaderUniqueChecker.name}(${importName}.definitions));\n`); | ||
} | ||
return line.length > 0 && line[0] !== "#"; | ||
return line.length !== 0 && line[0] !== "#"; | ||
}); | ||
return outputCode ?? ""; | ||
return { imports, importAppends }; | ||
}; | ||
export const vitePluginGraphqlLoader = () => { | ||
export const vitePluginGraphqlLoader = (options) => { | ||
const graphqlRegex = /\.(?:gql|graphql)$/; | ||
@@ -35,20 +37,42 @@ return { | ||
} | ||
const documentNode = gql ` | ||
${source} | ||
`; | ||
const headerCode = ` | ||
const doc = ${JSON.stringify(documentNode)}; | ||
doc.loc.source = ${JSON.stringify(documentNode.loc.source)}; | ||
`; | ||
let outputCode = ""; | ||
let documentNode; | ||
try { | ||
documentNode = gql ` | ||
${source} | ||
`; | ||
} | ||
catch (error) { | ||
throw new Error(String(error)); | ||
} | ||
let outputCode = new MagicString(source).replaceAll("`", "\\`"); | ||
outputCode.prepend(`const _gql_source = \``); | ||
outputCode.append(`\`;\n`); | ||
const plainDocument = Object.assign({}, documentNode); | ||
Object.assign(plainDocument.loc, documentNode.loc); | ||
const documentObject = JSON.parse(JSON.stringify(documentNode)); | ||
const sourceBodyIdentifier = `_gql_uuid_${new Date().getTime()}`; | ||
if (documentNode.loc && documentNode.loc.source) { | ||
documentObject.loc.source = { | ||
name: documentNode.loc.source.name, | ||
locationOffset: documentNode.loc.source.locationOffset, | ||
body: sourceBodyIdentifier, | ||
}; | ||
} | ||
outputCode.append(`const ${DOC_NAME} = ${JSON.stringify(documentObject).replace(`"${sourceBodyIdentifier}"`, "_gql_source")};\n`); | ||
const { imports, importAppends } = expandImports(source); | ||
if (imports.length) { | ||
outputCode.prepend(imports.join("")); | ||
outputCode.append(`const ${vitePluginGraphqlLoaderUniqueChecker.name} = ${vitePluginGraphqlLoaderUniqueChecker.toString()};\n`); | ||
outputCode.append(importAppends.join("")); | ||
} | ||
const operationCount = documentNode.definitions.filter((op) => (op.kind === "OperationDefinition" || | ||
op.kind === "FragmentDefinition") && | ||
op.name).length; | ||
if (operationCount < 1) { | ||
outputCode += ` | ||
export default doc; | ||
`; | ||
} | ||
else { | ||
outputCode += ONE_QUERY_FUNCTION_TEMPLATE; | ||
const queryNames = []; | ||
const fragmentNames = []; | ||
if (operationCount >= 1) { | ||
const extractQueries = operationCount > 1 || imports.length > 0; | ||
if (extractQueries) { | ||
outputCode.append(`const ${vitePluginGraphqlLoaderExtractQuery.name} = ${vitePluginGraphqlLoaderExtractQuery.toString()};\n`); | ||
} | ||
for (const op of documentNode.definitions) { | ||
@@ -66,11 +90,8 @@ if (op.kind === "OperationDefinition" || | ||
const opName = op.name.value; | ||
outputCode += ` | ||
export const ${opName} = oneQuery(doc, "${opName}");`; | ||
outputCode.append(`export const ${opName} = ${extractQueries ? `${vitePluginGraphqlLoaderExtractQuery.name}(${DOC_NAME}, "${opName}")` : DOC_NAME};\n`); | ||
if (op.kind === "OperationDefinition") { | ||
outputCode += ` | ||
_queries["${opName}"] = ${opName};`; | ||
queryNames.push(opName); | ||
} | ||
else { | ||
outputCode += ` | ||
_fragments["${opName}"] = ${opName};`; | ||
fragmentNames.push(opName); | ||
} | ||
@@ -80,5 +101,12 @@ } | ||
} | ||
const importOutputCode = expandImports(source); | ||
const allCode = headerCode + EOL + importOutputCode + EOL + outputCode + EOL; | ||
return allCode; | ||
outputCode.append(`export const _queries = {${queryNames.join(",")}};\n`); | ||
outputCode.append(`export const _fragments = {${fragmentNames.join(",")}};\n`); | ||
outputCode.append(`export default ${DOC_NAME};\n`); | ||
outputCode.replaceAll("\n", EOL); | ||
return { | ||
code: outputCode.toString(), | ||
map: options?.noSourceMap | ||
? { mappings: "" } | ||
: outputCode.generateMap(), | ||
}; | ||
}, | ||
@@ -85,0 +113,0 @@ }; |
@@ -1,3 +0,6 @@ | ||
export declare const UNIQUE_FUNCTION_TEMPLATE: string; | ||
export declare const ONE_QUERY_FUNCTION_TEMPLATE: string; | ||
import type { DefinitionNode, DocumentNode } from "graphql"; | ||
export declare const vitePluginGraphqlLoaderUniqueChecker: (defs: DefinitionNode[]) => DefinitionNode[]; | ||
export declare const vitePluginGraphqlLoaderExtractQuery: (doc: DocumentNode, operationName: string) => DocumentNode & { | ||
definitions: (import("graphql").OperationDefinitionNode | import("graphql").FragmentDefinitionNode | import("graphql").ScalarTypeDefinitionNode | import("graphql").ObjectTypeDefinitionNode | import("graphql").InterfaceTypeDefinitionNode | import("graphql").UnionTypeDefinitionNode | import("graphql").EnumTypeDefinitionNode | import("graphql").InputObjectTypeDefinitionNode | import("graphql").DirectiveDefinitionNode | import("graphql").ScalarTypeExtensionNode | import("graphql").ObjectTypeExtensionNode | import("graphql").InterfaceTypeExtensionNode | import("graphql").UnionTypeExtensionNode | import("graphql").EnumTypeExtensionNode | import("graphql").InputObjectTypeExtensionNode)[]; | ||
}; | ||
//# sourceMappingURL=snippets.d.ts.map |
@@ -1,3 +0,3 @@ | ||
const names = {}; | ||
const unique = (defs) => { | ||
export const vitePluginGraphqlLoaderUniqueChecker = (defs) => { | ||
const names = {}; | ||
return defs.filter(function (def) { | ||
@@ -16,58 +16,54 @@ if (def.kind !== "FragmentDefinition") | ||
}; | ||
export const UNIQUE_FUNCTION_TEMPLATE = ` | ||
const names = {}; | ||
const unique = ${unique.toString()}; | ||
`; | ||
const collectFragmentReferences = (node, refs) => { | ||
if (node.kind === "FragmentSpread") { | ||
refs.add(node.name.value); | ||
} | ||
else if (node.kind === "VariableDefinition") { | ||
const type = node.type; | ||
if (type.kind === "NamedType") { | ||
refs.add(type.name.value); | ||
export const vitePluginGraphqlLoaderExtractQuery = (doc, operationName) => { | ||
const collectFragmentReferences = (node, refs) => { | ||
if (node.kind === "FragmentSpread") { | ||
refs.add(node.name.value); | ||
} | ||
} | ||
if (node.selectionSet) { | ||
node.selectionSet.selections.forEach(function (selection) { | ||
collectFragmentReferences(selection, refs); | ||
else if (node.kind === "VariableDefinition") { | ||
const type = node.type; | ||
if (type.kind === "NamedType") { | ||
refs.add(type.name.value); | ||
} | ||
} | ||
if (node && "selectionSet" in node && node.selectionSet) { | ||
node.selectionSet.selections.forEach((selection) => { | ||
collectFragmentReferences(selection, refs); | ||
}); | ||
} | ||
if (node && "variableDefinitions" in node && node.variableDefinitions) { | ||
node.variableDefinitions.forEach((def) => { | ||
collectFragmentReferences(def, refs); | ||
}); | ||
} | ||
if (node && "definitions" in node && node.definitions) { | ||
node.definitions.forEach((def) => { | ||
collectFragmentReferences(def, refs); | ||
}); | ||
} | ||
return refs; | ||
}; | ||
const extractReferences = (doc) => { | ||
const definitionRefs = {}; | ||
doc.definitions.forEach(function (def) { | ||
if ("name" in def && def.name) { | ||
definitionRefs[def.name.value] = collectFragmentReferences(def, new Set()); | ||
} | ||
}); | ||
} | ||
if (node.variableDefinitions) { | ||
node.variableDefinitions.forEach(function (def) { | ||
collectFragmentReferences(def, refs); | ||
}); | ||
} | ||
if (node.definitions) { | ||
node.definitions.forEach(function (def) { | ||
collectFragmentReferences(def, refs); | ||
}); | ||
} | ||
}; | ||
const definitionRefs = {}; | ||
const extractReferences = (doc) => { | ||
doc.definitions.forEach(function (def) { | ||
if (def.name) { | ||
const refs = new Set(); | ||
collectFragmentReferences(def, refs); | ||
definitionRefs[def.name.value] = refs; | ||
return definitionRefs; | ||
}; | ||
const findOperation = (doc, name) => { | ||
for (let i = 0; i < doc.definitions.length; i++) { | ||
const element = doc.definitions[i]; | ||
if (element && | ||
"name" in element && | ||
element.name && | ||
element.name.value == name) { | ||
return element; | ||
} | ||
} | ||
}; | ||
const definitionRefs = extractReferences(doc); | ||
const newDoc = Object.assign({}, doc, { | ||
definitions: [findOperation(doc, operationName)], | ||
}); | ||
}; | ||
const findOperation = (doc, name) => { | ||
for (let i = 0; i < doc.definitions.length; i++) { | ||
const element = doc.definitions[i]; | ||
if (element.name && element.name.value == name) { | ||
return element; | ||
} | ||
} | ||
}; | ||
const oneQuery = (doc, operationName) => { | ||
const newDoc = { | ||
kind: doc.kind, | ||
definitions: [findOperation(doc, operationName)], | ||
}; | ||
if (doc.hasOwnProperty("loc")) { | ||
newDoc.loc = doc.loc; | ||
} | ||
const opRefs = definitionRefs[operationName] || new Set(); | ||
@@ -100,15 +96,2 @@ const allRefs = new Set(); | ||
}; | ||
export const ONE_QUERY_FUNCTION_TEMPLATE = ` | ||
const collectFragmentReferences = ${collectFragmentReferences.toString()}; | ||
const definitionRefs = {}; | ||
const extractReferences = ${extractReferences.toString()}; | ||
extractReferences(doc); | ||
const findOperation = ${findOperation.toString()}; | ||
const oneQuery = ${oneQuery.toString()}; | ||
export const _queries = {}; | ||
export const _fragments = {}; | ||
export default doc; | ||
`; | ||
//# sourceMappingURL=snippets.js.map |
{ | ||
"name": "vite-plugin-graphql-loader", | ||
"version": "3.0.1", | ||
"version": "4.0.0", | ||
"description": "A Vite plugin for loading GraphQL files.", | ||
@@ -37,8 +37,11 @@ "type": "module", | ||
"graphql": "^16.8.1", | ||
"graphql-tag": "^2.12.6" | ||
"graphql-tag": "^2.12.6", | ||
"magic-string": "^0.30.10" | ||
}, | ||
"devDependencies": { | ||
"@babel/parser": "^7.24.8", | ||
"@babel/traverse": "^7.24.8", | ||
"@types/babel__traverse": "^7.20.6", | ||
"@types/node": "^20", | ||
"eslint": "^8.56.0", | ||
"glob": "^10.3.10", | ||
"prettier": "^3.2.4", | ||
@@ -45,0 +48,0 @@ "rimraf": "^5.0.5", |
@@ -6,2 +6,5 @@ # vite-plugin-graphql-loader | ||
[![npm version](https://img.shields.io/npm/v/vite-plugin-graphql-loader.svg)](https://www.npmjs.com/package/vite-plugin-graphql-loader) | ||
![Tag: Vite Plugin](https://img.shields.io/badge/Vite_Plugin-orange) | ||
![Tag: GraphQL](https://img.shields.io/badge/GraphQL-orange) | ||
![Tag: JavaScript](https://img.shields.io/badge/JavaScript-orange) | ||
@@ -95,2 +98,5 @@ A Vite plugin for loading GraphQL .gql and .graphql files, based on [graphql-tag/loader](https://github.com/apollographql/graphql-tag) | ||
import Document, { _queries, _fragments } from "./example.graphql"; | ||
console.log(Document); // Has type `DocumentNode` | ||
console.log(_queries.ExampleQuery); // Has type `DocumentNode` | ||
console.log(_fragments.ExampleFragment); // Has type `FragmentDefinitionNode` | ||
``` | ||
@@ -100,2 +106,16 @@ | ||
**_v3.0.0_**: Moved from CJS to ESM, inline with Vite 5.0's CJS deprecation. If you are using CommonJS, continue using v2.0 of this package. | ||
**_v4.0.0_**: | ||
- Added source-map generation. Can by disabled by initializing with `graphqlLoader({noSourceMap: true})`. | ||
- Refactored code generation to be more maintainable, added more test cases. | ||
- Migrated from `yarn` to `bun`. | ||
**_v3.0.1_**: | ||
- Switched `await import` statements to top-level `import` statements (fixes #5 - `Top-level await is not available` error). | ||
- Added `_queries` and `_fragments` for improved module declaration types. | ||
- Updated snippets to be defined in TypeScript and then stringified. | ||
**_v3.0.0_**: | ||
- [Moved from CJS to ESM](https://github.com/noiach/vite-plugin-graphql-loader/commit/0e0b37cfcb0ecbdf28e985aeca3454137b4b73e3), inline with Vite 5.0's CJS deprecation. If you are using CommonJS, continue using v2.0 of this package. If you have `"type": "module"`, in your `package.json` then it should work as expected. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
23518
224
119
3
10
+ Addedmagic-string@^0.30.10
+ Added@jridgewell/sourcemap-codec@1.5.0(transitive)
+ Addedmagic-string@0.30.15(transitive)