1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const tslib_1 = require("tslib");
|
4 | const code_file_loader_1 = require("@graphql-toolkit/code-file-loader");
|
5 | const git_loader_1 = require("@graphql-toolkit/git-loader");
|
6 | const github_loader_1 = require("@graphql-toolkit/github-loader");
|
7 | const apollo_engine_loader_1 = require("@graphql-toolkit/apollo-engine-loader");
|
8 | const prisma_loader_1 = require("@graphql-toolkit/prisma-loader");
|
9 | const fs_extra_1 = require("fs-extra");
|
10 | const fs_1 = require("fs");
|
11 | const path_1 = require("path");
|
12 | const core_1 = require("@graphback/core");
|
13 | const graphql_migrations_1 = require("graphql-migrations");
|
14 | const codegen_client_1 = require("@graphback/codegen-client");
|
15 | const codegen_resolvers_1 = require("@graphback/codegen-resolvers");
|
16 | const codegen_schema_1 = require("@graphback/codegen-schema");
|
17 | const listr_1 = tslib_1.__importDefault(require("listr"));
|
18 | const inquirer_1 = require("inquirer");
|
19 | const chokidar_1 = tslib_1.__importDefault(require("chokidar"));
|
20 | const debounce_1 = tslib_1.__importDefault(require("debounce"));
|
21 | const graphql_1 = require("graphql");
|
22 | const FormatExtensionMap = {
|
23 | 'ts': 'ts',
|
24 | 'js': 'js',
|
25 | 'gql': 'graphql',
|
26 | };
|
27 | function writeFile(path, data) {
|
28 | return new Promise(async (resolve, reject) => {
|
29 | await fs_extra_1.ensureFile(path);
|
30 | fs_1.writeFile(path, data, err => {
|
31 | if (err) {
|
32 | reject(err);
|
33 | }
|
34 | resolve();
|
35 | });
|
36 | });
|
37 | }
|
38 | exports.writeFile = writeFile;
|
39 | function globPromise(glob, options = {}) {
|
40 | return new Promise(async (resolve, reject) => {
|
41 | const { default: globAsync } = await Promise.resolve().then(() => tslib_1.__importStar(require('glob')));
|
42 | globAsync(glob, options, (err, data) => {
|
43 | if (err) {
|
44 | reject(err);
|
45 | }
|
46 | resolve(data);
|
47 | });
|
48 | });
|
49 | }
|
50 | exports.globPromise = globPromise;
|
51 | async function createSchemaFile(cwd, generatedSchema, config) {
|
52 | const extension = FormatExtensionMap[config.generator.schema.format];
|
53 | return writeFile(path_1.join(cwd, config.folders.schema, 'generated.' + extension), generatedSchema);
|
54 | }
|
55 | exports.createSchemaFile = createSchemaFile;
|
56 | async function createResolversFiles(cwd, resolvers, config) {
|
57 | const extension = FormatExtensionMap[config.generator.resolvers.format];
|
58 | return Promise.all(resolvers.types.map(typeResolver => writeFile(path_1.join(cwd, config.folders.resolvers, 'generated', typeResolver.name + '.' + extension), typeResolver.output)));
|
59 | }
|
60 | exports.createResolversFiles = createResolversFiles;
|
61 | async function createBackendFiles(cwd, inputContext, config) {
|
62 | const resolvers = codegen_resolvers_1.createResolvers(inputContext, config.generator.resolvers);
|
63 | const schema = codegen_schema_1.createSchema(inputContext, config.generator.schema);
|
64 | await Promise.all([
|
65 | createSchemaFile(cwd, schema, config),
|
66 | createResolversFiles(cwd, resolvers, config)
|
67 | ]);
|
68 | }
|
69 | exports.createBackendFiles = createBackendFiles;
|
70 | async function createFragments(cwd, generated, config) {
|
71 | const extension = FormatExtensionMap[config.generator.client.format];
|
72 | return Promise.all(generated.fragments.map((fragment) => writeFile(path_1.join(cwd, config.folders.client, 'generated', 'fragments', fragment.name + '.' + extension), fragment.implementation)));
|
73 | }
|
74 | exports.createFragments = createFragments;
|
75 | async function createQueries(cwd, generated, config) {
|
76 | const extension = FormatExtensionMap[config.generator.client.format];
|
77 | return Promise.all(generated.queries.map(query => writeFile(path_1.join(cwd, config.folders.client, 'generated', 'queries', query.name + '.' + extension), query.implementation)));
|
78 | }
|
79 | exports.createQueries = createQueries;
|
80 | async function createMutations(cwd, generated, config) {
|
81 | const extension = FormatExtensionMap[config.generator.client.format];
|
82 | return Promise.all(generated.mutations.map(mutation => writeFile(path_1.join(cwd, config.folders.client, 'generated', 'mutations', mutation.name + '.' + extension), mutation.implementation)));
|
83 | }
|
84 | exports.createMutations = createMutations;
|
85 | async function createSubscriptions(cwd, generated, config) {
|
86 | const extension = FormatExtensionMap[config.generator.client.format];
|
87 | return Promise.all(generated.subscriptions.map(subscription => writeFile(path_1.join(cwd, config.folders.client, 'generated', 'subscriptions', subscription.name + '.' + extension), subscription.implementation)));
|
88 | }
|
89 | exports.createSubscriptions = createSubscriptions;
|
90 | async function createClientFiles(cwd, inputContext, config) {
|
91 | const generated = await codegen_client_1.createClient(inputContext, { output: config.generator.client.format });
|
92 | await Promise.all([
|
93 | createFragments(cwd, generated, config),
|
94 | createQueries(cwd, generated, config),
|
95 | createMutations(cwd, generated, config),
|
96 | createSubscriptions(cwd, generated, config),
|
97 | ]);
|
98 | }
|
99 | exports.createClientFiles = createClientFiles;
|
100 | async function createDatabaseMigration(schema, config) {
|
101 | const dbConfig = {
|
102 | client: config.db.database,
|
103 | connection: config.db.dbConfig,
|
104 | };
|
105 | await graphql_migrations_1.migrateDB(dbConfig, schema);
|
106 | }
|
107 | exports.createDatabaseMigration = createDatabaseMigration;
|
108 | exports.runGeneration = async ({ db, client, backend, silent }, cwd, generateConfig, schemaString) => {
|
109 | const tasks = [];
|
110 | if (backend || client) {
|
111 |
|
112 | const inputContext = core_1.graphQLInputContext.createModelContext(schemaString, generateConfig.graphqlCRUD);
|
113 | if (backend) {
|
114 | tasks.push({
|
115 | title: 'Generating Backend Schema and Resolvers',
|
116 | task: () => createBackendFiles(cwd, inputContext, generateConfig),
|
117 | });
|
118 | }
|
119 | if (client) {
|
120 | tasks.push({
|
121 | title: 'Generating Client-side Operations',
|
122 | task: () => createClientFiles(cwd, inputContext, generateConfig),
|
123 | });
|
124 | }
|
125 | }
|
126 | if (db) {
|
127 | tasks.push({
|
128 | title: 'Running Database Migration',
|
129 | task: () => createDatabaseMigration(schemaString, generateConfig),
|
130 | });
|
131 | }
|
132 | const listr = new listr_1.default(tasks, {
|
133 | renderer: silent ? 'silent' : 'default',
|
134 |
|
135 | exitOnError: false,
|
136 |
|
137 | concurrent: 4,
|
138 | });
|
139 | await listr.run();
|
140 | };
|
141 | const GenerateExtension = api => {
|
142 |
|
143 | api.loaders.schema.register(new code_file_loader_1.CodeFileLoader());
|
144 | api.loaders.schema.register(new git_loader_1.GitLoader());
|
145 | api.loaders.schema.register(new github_loader_1.GithubLoader());
|
146 | api.loaders.schema.register(new apollo_engine_loader_1.ApolloEngineLoader());
|
147 | api.loaders.schema.register(new prisma_loader_1.PrismaLoader());
|
148 | return {
|
149 | name: 'generate'
|
150 | };
|
151 | };
|
152 | exports.plugin = {
|
153 | init({ program, loadProjectConfig, reportError }) {
|
154 | program
|
155 | .command('generate')
|
156 | .option('--db')
|
157 | .option('--client')
|
158 | .option('--backend')
|
159 | .option('--silent')
|
160 | .option('-w, --watch', 'Watch for changes and execute generation automatically')
|
161 | .action(async (cliFlags) => {
|
162 | try {
|
163 | const config = await loadProjectConfig({
|
164 | extensions: [GenerateExtension]
|
165 | });
|
166 | const generateConfig = await config.extension('generate');
|
167 | if (!generateConfig) {
|
168 | throw new Error(`You should provide a valid 'generate' config to generate schema from data model`);
|
169 | }
|
170 | if (!generateConfig.folders) {
|
171 | throw new Error(`'generate' config missing 'folders' section that is required`);
|
172 | }
|
173 | if (!cliFlags.db && !cliFlags.client && !cliFlags.backend) {
|
174 | const { selections } = await inquirer_1.prompt([
|
175 | {
|
176 | type: 'checkbox',
|
177 | name: 'selections',
|
178 | message: 'What do you want to generate?',
|
179 | choices: [
|
180 | {
|
181 | value: 'backend',
|
182 | name: 'Backend Schema and Resolvers',
|
183 | },
|
184 | {
|
185 | value: 'client',
|
186 | name: 'Client-Side Operation',
|
187 | }, {
|
188 | value: 'db',
|
189 | name: 'Database Creation and Migration',
|
190 | }
|
191 | ]
|
192 | }
|
193 | ]);
|
194 | cliFlags.db = selections.includes('db');
|
195 | cliFlags.client = selections.includes('client');
|
196 | cliFlags.backend = selections.includes('backend');
|
197 | }
|
198 | const debouncedExec = debounce_1.default(async () => {
|
199 | try {
|
200 | const schemaDocument = await config.loadSchema(path_1.join(config.dirpath, generateConfig.folders.model + '/**/*.graphql'), 'DocumentNode');
|
201 | const schemaString = graphql_1.print(schemaDocument);
|
202 | await exports.runGeneration(cliFlags, config.dirpath, generateConfig, schemaString);
|
203 | }
|
204 | catch (e) {
|
205 | reportError(e);
|
206 | }
|
207 | console.info('Watching for changes...');
|
208 | }, 100);
|
209 | if (cliFlags.watch) {
|
210 | chokidar_1.default.watch(generateConfig.folders.model, {
|
211 | persistent: true,
|
212 | cwd: config.dirpath,
|
213 | }).on('all', debouncedExec);
|
214 | }
|
215 | else {
|
216 | const schemaDocument = await config.loadSchema(path_1.join(config.dirpath, generateConfig.folders.model + '/**/*.graphql'), 'DocumentNode');
|
217 | const schemaString = graphql_1.print(schemaDocument);
|
218 | await exports.runGeneration(cliFlags, config.dirpath, generateConfig, schemaString);
|
219 | process.exit(0);
|
220 | }
|
221 | }
|
222 | catch (e) {
|
223 | reportError(e);
|
224 | }
|
225 | });
|
226 | }
|
227 | };
|
228 |
|
\ | No newline at end of file |