UNPKG

@dillonkearns/elm-graphql

Version:

<img src="https://cdn.rawgit.com/martimatix/logo-graphqelm/master/logo.svg" alt="dillonearns/elm-graphql logo" width="40%" align="right">

147 lines (138 loc) 5.4 kB
const { Elm } = require("./Main.elm"); import * as fs from "fs-extra"; import { GraphQLClient } from "graphql-request"; import * as http from "http"; import * as minimist from "minimist"; import * as request from "request"; import { writeFile } from "./formatted-write"; import { introspectionQuery } from "./introspection-query"; import * as glob from "glob"; import * as path from "path"; const npmPackageVersion = require("../../package.json").version; const elmPackageVersion = require("../../elm.json").version; const usage = `Usage: elm-graphql url # generate files based on the schema at \`url\` in folder ./src/Api elm-graphql url --base My.Api.Submodule # generate files based on the schema at \`url\` in folder ./src/My/Api/Submodule elm-graphql url --output path/to/src # generates code within path/to/src/Api elm-graphql url --output path/to/src --base My.Api.Submodule # generates code within path/to/src/My/Api/Submodule elm-graphql url --excludeDeprecated # excludes deprecated enums and fields (they are included by default) # Schema file instead of URL elm-graphql --introspection-file path/to/introspection-response.json elm-graphql --version # print the current @dillonkearns/elm-graphql version and target elm package version elm-graphql url [--header 'headerKey: header value'...] # you can supply multiple header args`; function isGenerated(path: string): boolean { return ( fs .readFileSync(path) .indexOf("Do not manually edit this file, it was auto-generated by") >= 0 ); } function warnIfContainsNonGenerated(path: string): void { const files: string[] = glob.sync(path + "/**/*.elm"); const nonGenerated = files.filter(file => !isGenerated(file)); if (nonGenerated.length > 0) { console.log( "@dillonkearns/elm-graphql found some files that it did not generate. Please move or delete the following files and run @dillonkearns/elm-graphql again.", nonGenerated ); process.exit(1); } } function removeGenerated(path: string): void { glob.sync(path + "/**/*.elm").forEach(fs.unlinkSync); } const targetComment = `-- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql -- https://github.com/dillonkearns/elm-graphql `; const args = minimist(process.argv.slice(2)); if (args.version) { console.log("npm version ", npmPackageVersion); console.log( `Targeting elm package dillonkearns/elm-graphql@${elmPackageVersion}` ); process.exit(0); } const baseArgRegex = /^[A-Z][A-Za-z_]*(\.[A-Z][A-Za-z_]*)*$/; const baseModuleArg: undefined | string = args.base; const outputPath: string = args.output || "./src"; function isValidBaseArg(baseArg: string): boolean { return !!baseArg.match(baseArgRegex); } if (baseModuleArg && !isValidBaseArg(baseModuleArg)) { console.log( `--base was '${baseModuleArg}' but must be in format ${baseArgRegex}` ); process.exit(1); } const excludeDeprecated: boolean = args.excludeDeprecated === null || args.excludeDeprecated === undefined ? false : args.excludeDeprecated; const headerArg: undefined | string | [string] = args.header; const addHeader = (object: any, header: string) => { const [headerKey, headerValue] = header.split(":"); object[headerKey] = headerValue; return object; }; let headers = {}; if (typeof headerArg === "string") { addHeader(headers, headerArg); } else if (headerArg == undefined) { } else { headerArg.forEach(header => { addHeader(headers, header); }); } const baseModule = baseModuleArg ? baseModuleArg.split(".") : ["Api"]; function prependBasePath(suffixPath: string): string { return path.join(outputPath, baseModule.join("/"), suffixPath); } const graphqlUrl: undefined | string = args._[0]; const introspectionFile: undefined | string = args["introspection-file"]; if (!(graphqlUrl || introspectionFile)) { console.log(usage); process.exit(0); } warnIfContainsNonGenerated(prependBasePath("/")); const onDataAvailable = (data: {}) => { console.log("Generating files..."); let app = Elm.Main.init({ flags: { data, baseModule } }); app.ports.generatedFiles.subscribe(function(generatedFile: any) { removeGenerated(prependBasePath("/")); fs.mkdirpSync(prependBasePath("InputObject")); fs.mkdirpSync(prependBasePath("Object")); fs.mkdirpSync(prependBasePath("Interface")); fs.mkdirpSync(prependBasePath("Union")); fs.mkdirpSync(prependBasePath("Enum")); for (let key in generatedFile) { let filePath = path.join(outputPath, key); let value = generatedFile[key]; writeFile(filePath, targetComment + value); } fs.writeFileSync( prependBasePath("elm-graphql-metadata.json"), `{"targetElmPackageVersion": "${elmPackageVersion}", "generatedByNpmPackageVersion": "${npmPackageVersion}"}` ); console.log("Success!"); }); }; if (introspectionFile) { const introspectionFileJson = JSON.parse( fs.readFileSync(introspectionFile).toString() ); onDataAvailable(introspectionFileJson.data || introspectionFileJson); } else { console.log("Fetching GraphQL schema..."); new GraphQLClient(graphqlUrl, { mode: "cors", headers: headers }) .request(introspectionQuery, { includeDeprecated: !excludeDeprecated }) .then(data => { onDataAvailable(data); }) .catch(err => { console.log(err.response || err); process.exit(1); }); }