fauna-gql-upload
Version:
Manage your FaunaDB resources in within your project and upload them using a single command
226 lines (215 loc) • 7.5 kB
text/typescript
import path from "path";
import fs from "fs";
import { Plugin } from "../types";
import yargs from "yargs";
export interface IOptions{
apiEndpointEnv: string;
graphqlEndpointEnv: string;
schemaPath?: string;
schemaDir?: string;
region?: "classic" | "eu" | "us" | "preview" | "local";
tsconfigPath?: string;
mode?: "merge" | "override" | "replace";
envPath: string;
secretEnv: string;
fnsDir: string;
rolesDir: string;
indexesDir: string;
dataDir: string;
providersDir: string;
codegen?: {
typescript: boolean;
operations: boolean;
outputFile: string;
headers: { [key: string]: string };
documents: string[];
plugins: Plugin[];
pluginOptions: { [key: string]: string }
} | null
}
export const argv = yargs
// Config options
.option("override", {
alias: "o",
description: "Override the schema, this will delete all your data in the database. This option is deprecated.",
type: "boolean",
deprecated: "`override` flag is deprecated and will be removed in a future version of Fauna GQL Upload. Use `--mode override` instead."
})
.option("mode", {
alias: "m",
description: "The mode to use when uploading GraphQL schema.",
type: "string",
choices: ["merge", "override", "replace"]
})
.option("yes", {
alias: "y",
description: "Answer yes to all potential prompts.",
type: "boolean"
})
.option("config", {
alias: "c",
description: "Specify custom path to config file",
type: "string"
})
.option("apiEndpointEnv", {
description: "Specify environment variable for custom API endpoint",
type: "string"
})
.option("graphqlEndpointEnv", {
description: "Specify environment variable for custom GraphQL endpoint",
type: "string"
})
.option("region", {
description: "Specify database region.",
type: "string"
})
.option("schemaPath", {
description: "Specify custom path for GraphQL schema",
type: "string"
})
.option("schemaDir", {
description: "Specify custom directory for GraphQL schema files",
type: "string"
})
.option("tsconfigPath", {
description: "Specify custom path for tsconfig file",
type: "string"
})
.option("envPath", {
description: "Specify custom path to environment file",
type: "string"
})
.option("secretEnv", {
description: "Specify custom environment variable for database secret",
type: "string"
})
.option("fnsDir", {
description: "Specify custom path to functions directory",
type: "string"
})
.option("rolesDir", {
description: "Specify custom path to roles directory",
type: "string"
})
.option("indexesDir", {
description: "Specify custom path to indexes directory",
type: "string"
})
.option("dataDir", {
description: "Specify custom path to data directory",
type: "string"
})
.option("providersDir", {
description: "Specify custom path to providers directory",
type: "string"
})
.option("codegen", {
description: "Whether or not to enable codegen",
type: "boolean"
})
.option("codegenDisableTypescript", {
description: "Whether or not to enable typescript plugin",
type: "boolean"
})
.option("codegenDisableOperations", {
description: "Whether or not to enable typescript operations plugin",
type: "boolean"
})
.option("codegenOutputFile", {
description: "Specify destination file for generated code",
type: "string"
})
.option("codegenHeaders", {
description: "Optional headers to include when fetching GraphQL schema",
type: "string"
})
.option("codegenDocuments", {
description: "Specify documents containing GraphQL operations and/or fragments",
type: "array"
})
.option("codegenPlugins", {
description: "Specify plugins to use with GraphQL Codegen",
type: "array"
})
.option("codegenPluginOptions", {
description: "Specify options for GraphQL codegen plugins",
type: "string"
})
// Select resources
.option("schema", {
description: "Upload schema",
type: "boolean"
})
.option("data", {
description: "Upload data",
type: "boolean"
})
.option("functions", {
description: "Upload functions",
type: "boolean"
})
.option("indexes", {
description: "Upload indexes",
type: "boolean"
})
.option("providers", {
description: "Upload providers",
type: "boolean"
})
.option("roles", {
description: "Upload roles",
type: "boolean"
})
.option("ignoreAll", {
description: "Ignore all resources",
type: "boolean"
})
.argv;
const cwd = process.cwd();
export const defaultSchema = fs.existsSync("./fauna/schema.gql") ? "./fauna/schema.gql" : "./fauna/schema.graphql"
export const defaultRolesDir = path.join("fauna", "roles");
export const defaultFnsDir = path.join("fauna", "functions");
export const defaultIndexesDir = path.join("fauna", "indexes");
export const defaultDataDir = path.join("fauna", "data");
export const defaultProvidersDir = path.join("fauna", "providers");
export const defaultSecretEnv = "FGU_SECRET";
export const defaultApiEndpointEnv = "FGU_API_ENDPOINT";
export const defaultGraphqlEndpointEnv = "FGU_GRAPHQL_ENDPOINT"
let globalConfig: IOptions | null = null;
export default function getConfig(verifyConfig = false){
if(globalConfig) return globalConfig;
const customConfig = argv?.config;
const configPath = path.join(cwd, (customConfig || ".fauna.json"));
if(customConfig && verifyConfig && !fs.existsSync(configPath)){
throw new Error("Could not find custom config at path " + configPath)
}
const providedConfig = fs.existsSync(configPath) ? JSON.parse(fs.readFileSync(configPath, "utf8")) : {};
const codegenTypescript = providedConfig.codegen?.typescript ?? true;
const config: IOptions = {
apiEndpointEnv: argv?.apiEndpointEnv || providedConfig.apiEndpointEnv || defaultApiEndpointEnv,
graphqlEndpointEnv: argv?.graphqlEndpointEnv || providedConfig.graphqlEndpointEnv || defaultGraphqlEndpointEnv,
region: argv?.region || providedConfig?.region || undefined,
mode: argv?.mode || providedConfig.mode || "merge",
schemaPath: argv?.schemaPath || providedConfig.schemaPath || defaultSchema,
schemaDir: argv?.schemaDir || providedConfig.schemaDir || undefined,
tsconfigPath: argv?.tsconfigPath || providedConfig.tsconfigPath,
envPath: argv?.envPath || providedConfig.envPath || ".env",
secretEnv: argv?.secretEnv || providedConfig.secretEnv || defaultSecretEnv,
fnsDir: argv?.fnsDir || providedConfig.fnsDir || defaultFnsDir,
rolesDir: argv?.rolesDir || providedConfig.rolesDir || defaultRolesDir,
indexesDir: argv?.indexesDir || providedConfig.indexesDir || defaultIndexesDir,
dataDir: argv?.dataDir || providedConfig.dataDir || defaultDataDir,
providersDir: argv?.providersDir || providedConfig.providersDir || defaultProvidersDir,
codegen: (argv?.codegen ?? providedConfig.codegen) ? {
typescript: !argv?.codegenDisableTypescript ?? codegenTypescript,
operations: !argv?.codegenDisableOperations ?? providedConfig?.codegen?.operations ?? true,
outputFile: argv?.codegenOutputFile || providedConfig?.codegen?.outputFile || (codegenTypescript ? "generated/graphql.ts" : "generated/graphql.js"),
headers: (argv?.codegenHeaders ? JSON.parse(argv.codegenHeaders) : null) || providedConfig?.codegen?.headers || {},
documents: argv?.codegenDocuments || providedConfig?.codegen?.documents || [],
plugins: argv?.codegenPlugins || providedConfig?.codegen?.plugins || [],
pluginOptions: (argv?.codegenPluginOptions ? JSON.parse(argv.codegenPluginOptions) : null) || providedConfig?.codegen?.pluginOptions || {}
} : null
}
globalConfig = config;
return config;
}