stepzen 0.18.0-beta.2 → 0.19.0-beta.1

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.
Files changed (50) hide show
  1. package/README.md +13 -3
  2. package/lib/commands/deploy.js +1 -1
  3. package/lib/commands/import.d.ts +21 -0
  4. package/lib/commands/import.js +208 -120
  5. package/lib/commands/init.js +2 -2
  6. package/lib/commands/lint.js +2 -2
  7. package/lib/commands/list.js +1 -1
  8. package/lib/commands/login.js +3 -3
  9. package/lib/commands/logout.js +1 -1
  10. package/lib/commands/start.js +14 -12
  11. package/lib/commands/transpile.js +5 -5
  12. package/lib/commands/upload.js +1 -1
  13. package/lib/commands/validate.js +6 -4
  14. package/lib/commands/whoami.js +3 -3
  15. package/lib/generate/curl2sdl.d.ts +4 -6
  16. package/lib/generate/curl2sdl.js +26 -17
  17. package/lib/generate/graphql2sdl.d.ts +5 -7
  18. package/lib/generate/graphql2sdl.js +21 -8
  19. package/lib/generate/helpers.d.ts +10 -2
  20. package/lib/generate/helpers.js +41 -22
  21. package/lib/generate/index.d.ts +5 -3
  22. package/lib/generate/index.js +6 -6
  23. package/lib/generate/sql2sdl.d.ts +23 -0
  24. package/lib/generate/sql2sdl.js +155 -0
  25. package/lib/hooks/prerun/check-upgrade.js +13 -10
  26. package/lib/hooks/prerun/ensure-config-file.js +3 -3
  27. package/lib/index.js +1 -0
  28. package/lib/shared/actions.js +9 -6
  29. package/lib/shared/configuration.js +20 -14
  30. package/lib/shared/constants.d.ts +3 -0
  31. package/lib/shared/constants.js +9 -4
  32. package/lib/shared/curl-parser.js +3 -2
  33. package/lib/shared/errors.js +2 -1
  34. package/lib/shared/header-params-parser.js +6 -4
  35. package/lib/shared/header.js +2 -1
  36. package/lib/shared/moniker.js +5 -3
  37. package/lib/shared/path-params-parser.d.ts +1 -1
  38. package/lib/shared/path-params-parser.js +5 -3
  39. package/lib/shared/stepzen-sdk.d.ts +1 -1
  40. package/lib/shared/stepzen-sdk.js +1 -1
  41. package/lib/shared/utils.d.ts +2 -0
  42. package/lib/shared/utils.js +31 -8
  43. package/lib/shared/validation.js +4 -2
  44. package/lib/shared/workspace.js +21 -16
  45. package/lib/shared/zen-command.js +7 -7
  46. package/lib/start/console.d.ts +1 -1
  47. package/lib/start/console.js +16 -9
  48. package/lib/start/index.js +1 -0
  49. package/oclif.manifest.json +1 -1
  50. package/package.json +3 -3
package/README.md CHANGED
@@ -20,6 +20,7 @@ To verify your CLI installation, use the `stepzen --version` command:
20
20
  * [Installing](#installing)
21
21
  * [Verifying your installation](#verifying-your-installation)
22
22
  * [Usage](#usage)
23
+ * [QA from cloned repo](#qa-from-cloned-repo)
23
24
  * [Commands](#commands)
24
25
  <!-- tocstop -->
25
26
  # Usage
@@ -29,13 +30,19 @@ $ npm install -g stepzen
29
30
  $ stepzen COMMAND
30
31
  running command...
31
32
  $ stepzen (-v|--version|version)
32
- stepzen/0.18.0-beta.2 darwin-x64 node-v14.19.3
33
+ stepzen/0.19.0-beta.1 darwin-x64 node-v14.19.3
33
34
  $ stepzen --help [COMMAND]
34
35
  USAGE
35
36
  $ stepzen COMMAND
36
37
  ...
37
38
  ```
38
39
  <!-- usagestop -->
40
+
41
+ # QA from cloned repo
42
+ <!-- QA -->
43
+ To run from code: `path-to-repo/bin/run start` (start or whatever command you're QAing)
44
+ <!-- QAstop -->
45
+
39
46
  # Commands
40
47
  <!-- commands -->
41
48
  * [`stepzen deploy DESTINATION`](#stepzen-deploy-destination)
@@ -84,7 +91,7 @@ _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.1.1
84
91
 
85
92
  ## `stepzen import SCHEMA`
86
93
 
87
- import a schema for an external data source or a API endpoint to your GraphQL API
94
+ import a schema for an external data source or an API endpoint to your GraphQL API
88
95
 
89
96
  ```
90
97
  USAGE
@@ -107,8 +114,11 @@ OPTIONS
107
114
  --db-host=db-host
108
115
  [mysql, postgresql] database host
109
116
 
117
+ --db-include=(tables-only|views-only|tables-and-views)
118
+ [mysql, postgresql] Should the generated GraphQL schema be based only on database views, only on tables or on both.
119
+
110
120
  --db-link-types
111
- [mysql, postgresql] Automatically link types with @materializer whenever there is database support
121
+ [mysql, postgresql] Automatically link types based on foreign key relationships using @materializer
112
122
  (https://stepzen.com/docs/features/linking-types)
113
123
 
114
124
  --db-password=db-password
@@ -27,7 +27,7 @@ class Deploy extends zen_command_1.default {
27
27
  ? `${flags.configurationsets},stepzen/public`
28
28
  : 'stepzen/public';
29
29
  }
30
- const response = await actions_1.deploy(args.destination, flags.configurationsets, flags.schema);
30
+ const response = await (0, actions_1.deploy)(args.destination, flags.configurationsets, flags.schema);
31
31
  if (response.success) {
32
32
  if (!flags.silent) {
33
33
  this.log(response.message || 'Success');
@@ -1,7 +1,10 @@
1
1
  import { flags } from '@oclif/command';
2
+ import { Input } from '@oclif/parser';
3
+ import type { CommonImportOptions } from '../generate';
2
4
  import ZenCommand from '../shared/zen-command';
3
5
  import { HeaderInput } from '../shared/header';
4
6
  import { Workspace } from '../shared/types';
7
+ declare type Flags<Command> = Command extends Input<infer F> ? F : never;
5
8
  export default class Import extends ZenCommand {
6
9
  static description: string;
7
10
  static commonIntrospectionFlags: {
@@ -20,6 +23,7 @@ export default class Import extends ZenCommand {
20
23
  'db-password': flags.IOptionFlag<string | undefined>;
21
24
  'db-database': flags.IOptionFlag<string | undefined>;
22
25
  'db-link-types': import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
26
+ 'db-include': flags.IOptionFlag<string>;
23
27
  };
24
28
  static postgresqlFlags: {
25
29
  'db-schema': flags.IOptionFlag<string | undefined>;
@@ -45,6 +49,7 @@ export default class Import extends ZenCommand {
45
49
  'db-password': flags.IOptionFlag<string | undefined>;
46
50
  'db-database': flags.IOptionFlag<string | undefined>;
47
51
  'db-link-types': import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
52
+ 'db-include': flags.IOptionFlag<string>;
48
53
  };
49
54
  schemas: string[];
50
55
  } | {
@@ -60,6 +65,7 @@ export default class Import extends ZenCommand {
60
65
  'db-password': flags.IOptionFlag<string | undefined>;
61
66
  'db-database': flags.IOptionFlag<string | undefined>;
62
67
  'db-link-types': import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
68
+ 'db-include': flags.IOptionFlag<string>;
63
69
  'query-name': flags.IOptionFlag<string | undefined>;
64
70
  'query-type': flags.IOptionFlag<string | undefined>;
65
71
  'path-params': flags.IOptionFlag<string | undefined>;
@@ -79,6 +85,10 @@ export default class Import extends ZenCommand {
79
85
  }[];
80
86
  static strict: boolean;
81
87
  run(): Promise<void>;
88
+ importCurl(argv: string[], flags: Flags<typeof Import>, commonOptions: CommonImportOptions): Promise<string>;
89
+ importGraphQL(argv: string[], flags: Flags<typeof Import>, commonOptions: CommonImportOptions): Promise<string>;
90
+ importSql(schema: 'mysql' | 'postgresql', flags: Flags<typeof Import>, fixedOptions: CommonImportOptions): Promise<string>;
91
+ importFromGeneratorEngines(schema: string, flags: any, fixedOptions: CommonImportOptions): Promise<string>;
82
92
  ensureOnConflictBehavior(workspace: Workspace, schema: string, flags: ReturnType<Import['parseWorkaround']>['flags']): Promise<"overwrite" | "append">;
83
93
  warnAboutIgnoredFlags(schema: string, usedFlags: {
84
94
  [key: string]: any;
@@ -90,6 +100,7 @@ export default class Import extends ZenCommand {
90
100
  'db-password': string | undefined;
91
101
  'db-database': string | undefined;
92
102
  'db-link-types': boolean;
103
+ 'db-include': string;
93
104
  'query-name': string | undefined;
94
105
  'query-type': string | undefined;
95
106
  'path-params': string | undefined;
@@ -106,4 +117,14 @@ export default class Import extends ZenCommand {
106
117
  [name: string]: any;
107
118
  }>;
108
119
  parseHeaderFlags(headerFlagValues?: string[], headerParamFlagValues?: string[]): HeaderInput[];
120
+ getSqlOptionsFromFlags(flags: Flags<typeof Import>): {
121
+ host: string | undefined;
122
+ user: string | undefined;
123
+ password: string | undefined;
124
+ database: string | undefined;
125
+ linkTypes: boolean;
126
+ schema: string | undefined;
127
+ include: "tables-only" | "views-only" | "tables-and-views" | undefined;
128
+ };
109
129
  }
130
+ export {};
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const chalk = require("chalk");
5
5
  const fs = require("fs-extra");
6
+ const glob = require("glob");
6
7
  const path = require("path");
7
8
  const inquirer = require("inquirer");
8
9
  const command_1 = require("@oclif/command");
@@ -16,6 +17,8 @@ const curl2sdl_1 = require("../generate/curl2sdl");
16
17
  const curl_parser_1 = require("../shared/curl-parser");
17
18
  const zen_command_1 = require("../shared/zen-command");
18
19
  const graphql2sdl_1 = require("../generate/graphql2sdl");
20
+ const sql2sdl_1 = require("../generate/sql2sdl");
21
+ const validate_1 = require("../commands/validate");
19
22
  const constants_1 = require("../shared/constants");
20
23
  const path_params_parser_1 = require("../shared/path-params-parser");
21
24
  const header_params_parser_1 = require("../shared/header-params-parser");
@@ -24,139 +27,196 @@ class Import extends zen_command_1.default {
24
27
  async run() {
25
28
  const { args, argv, flags } = this.parseWorkaround();
26
29
  // Get a list of schemas you're asking for
27
- const schema = helpers_1.getSchema(args.schema);
30
+ const schema = (0, helpers_1.getSchema)(args.schema);
28
31
  // Get or create a StepZen workspace (possibly interactive)
29
32
  const workspace = await this.ensureStepZenWorkspace({ directory: flags.dir });
33
+ if (schema !== 'curl' && schema !== 'graphql') {
34
+ try {
35
+ if (glob.sync('**/*.graphql', { cwd: workspace.schema }).length > 0) {
36
+ // The workspace schema has to be valid for import to work because when
37
+ // importing any other schemas than `curl` and `graphql` the CLI tries
38
+ // to _merge_ the imported schema into the workspace schema, and that's
39
+ // going to fail if the workspace schema is invalid to start with.
40
+ await validate_1.default.run([workspace.schema]);
41
+ }
42
+ }
43
+ catch (error) {
44
+ throw new errors_1.CLIError(`Could not import a ${schema} schema into the workspace.` +
45
+ ` The workspace needs to have a valid GraphQL schema before` +
46
+ ` ${chalk.bold(`stepzen import ${schema}`)} could start.` +
47
+ `\n` +
48
+ `\nThe following issues with the GraphQL schema were detected:` +
49
+ `\n${error.message}`);
50
+ }
51
+ }
30
52
  // Define a sane onConflict behaviour (possibly interactive)
31
53
  const onConflict = await this.ensureOnConflictBehavior(workspace, schema, flags);
32
54
  this.warnAboutIgnoredFlags(schema, flags);
33
- const headers = this.parseHeaderFlags(flags.header, flags['header-param']);
55
+ // Common options for all import schemas
56
+ const commonOptions = {
57
+ name: flags.name,
58
+ source: workspace.schema,
59
+ onConflict,
60
+ };
34
61
  // Select an import execution flow:
35
- // - v1 with `stepzen/engines` and cloud function
36
- // - v2 with the graphqlize service
37
- let result;
38
- if (schema === 'curl') {
39
- // LATER: offload the check to the graphqlize service or fetch
40
- // the list of supported data sources and compare agains it.
41
- this.log(chalk.yellow(`NOTE: ${chalk.bold('stepzen import curl')} is a ${chalk.bold('new')} feature.`));
42
- this.log(chalk.yellow('If you have any issues, please check if they have been addressed ' +
43
- 'in the latest version, or reach out to StepZen on Discord: ' +
44
- constants_1.STEPZEN_DISCORD_URL));
45
- let curl2sdlOptions;
46
- const fixedOptions = {
47
- name: flags.name,
48
- source: workspace.schema,
49
- onConflict,
50
- };
51
- const editableOptions = {
52
- queryName: flags['query-name'],
53
- rootType: flags['query-type'],
54
- typePrefix: flags.prefix,
55
- pathParams: flags['path-params'],
56
- };
57
- if (argv.length === 1) {
58
- // no parameters given: start an interactive prompt
59
- console.log();
60
- console.log('This command introspects the response of a REST endpoint and generates' +
61
- ' a GraphQL schema allowing you to access this endpoint through your ' +
62
- 'StepZen API. curl syntax is supported so that you copy and paste a ' +
63
- 'curl command instead of the URL.');
64
- console.log();
65
- const curlAnswers = await curl2sdl_1.askCurlQuestions(editableOptions);
66
- curl2sdlOptions = Object.assign(Object.assign(Object.assign({}, fixedOptions), curlAnswers), {
67
- // include boths headers passed via flags and headers entered interactively
68
- headers: headers.concat(curlAnswers.curlArgs.headers) });
69
- }
70
- else {
71
- // run non-interative
72
- const argsOrError = curl_parser_1.parseCurlArgv(argv);
73
- if ('error' in argsOrError) {
74
- throw new errors_1.CLIError(argsOrError.error);
75
- }
76
- const parsedPathParamsOrError = path_params_parser_1.parsePathParamsPattern(argsOrError.url, flags['path-params']);
77
- if ('error' in parsedPathParamsOrError) {
78
- throw new errors_1.CLIError(parsedPathParamsOrError.error);
62
+ // - v1 (deprecated) through the `generator-engines` cloud function
63
+ // - v2 (default) directly call the DB and REST introspection service APIs
64
+ const useGeneratorEngines = (0, utils_1.getFeatureFlag)(constants_1.USE_GENERATOR_ENGINES);
65
+ let importFn = undefined;
66
+ switch (schema) {
67
+ case 'curl':
68
+ importFn = () => this.importCurl(argv, flags, commonOptions);
69
+ break;
70
+ case 'graphql':
71
+ importFn = () => this.importGraphQL(argv, flags, commonOptions);
72
+ break;
73
+ case 'mysql':
74
+ case 'postgresql':
75
+ importFn = useGeneratorEngines
76
+ ? () => this.importFromGeneratorEngines(schema, flags, commonOptions)
77
+ : () => this.importSql(schema, flags, commonOptions);
78
+ break;
79
+ default:
80
+ if (useGeneratorEngines) {
81
+ importFn = () => this.importFromGeneratorEngines(schema, flags, commonOptions);
79
82
  }
80
- const maybeDuplicateParamsMessage = curl2sdl_1.makeDuplicateParamsMessage(headers, parsedPathParamsOrError, argsOrError.url);
81
- if (maybeDuplicateParamsMessage) {
82
- throw new errors_1.CLIError(maybeDuplicateParamsMessage);
83
+ else {
84
+ throw new errors_1.CLIError(`Cannot find the schema ${schema}`);
83
85
  }
84
- curl2sdlOptions = Object.assign(Object.assign(Object.assign({}, fixedOptions), editableOptions), { pathParams: parsedPathParamsOrError, headers: headers, curlArgs: argsOrError });
85
- }
86
- core_1.CliUx.ux.action.start('Starting');
87
- const resultOrError = await curl2sdl_1.curl2sdl(curl2sdlOptions);
88
- core_1.CliUx.ux.action.stop();
89
- if ('error' in resultOrError) {
90
- this.log('A problem occured while processing your import. ' +
91
- 'Please check that the given cURL command is valid.');
92
- this.log(resultOrError.error);
93
- this.exit();
94
- }
95
- result = resultOrError.outPath;
96
86
  }
97
- else if (schema === 'graphql') {
98
- const editableOptions = {
99
- typePrefix: flags.prefix,
100
- headers: headers,
101
- };
102
- let answers;
103
- if (argv.length === 1) {
104
- // interactive
105
- answers = await graphql2sdl_1.askGraphQLQuestions(editableOptions);
87
+ const result = await importFn();
88
+ // Housekeeping
89
+ fs.copySync(result, workspace.schema);
90
+ fs.removeSync(result);
91
+ // Nice message
92
+ this.log(chalk.green(`Successfully imported schema ${chalk.bold(schema)} from StepZen`));
93
+ }
94
+ async importCurl(argv, flags, commonOptions) {
95
+ const headers = this.parseHeaderFlags(flags.header, flags['header-param']);
96
+ this.log(chalk.yellow(`NOTE: ${chalk.bold('stepzen import curl')} is a ${chalk.bold('new')} feature.`));
97
+ this.log(chalk.yellow('If you have any issues, please check if they have been addressed ' +
98
+ 'in the latest version, or reach out to StepZen on Discord: ' +
99
+ constants_1.STEPZEN_DISCORD_URL));
100
+ let curl2sdlOptions;
101
+ const curlFlagValues = {
102
+ queryName: flags['query-name'],
103
+ rootType: flags['query-type'],
104
+ typePrefix: flags.prefix,
105
+ pathParams: flags['path-params'],
106
+ };
107
+ if (argv.length === 1) {
108
+ // no parameters given: start an interactive prompt
109
+ console.log();
110
+ console.log('This command introspects the response of a REST endpoint and generates' +
111
+ ' a GraphQL schema allowing you to access this endpoint through your ' +
112
+ 'StepZen API. curl syntax is supported so that you copy and paste a ' +
113
+ 'curl command instead of the URL.');
114
+ console.log();
115
+ const interactiveOptions = await (0, curl2sdl_1.askCurlQuestions)(curlFlagValues);
116
+ curl2sdlOptions = Object.assign(Object.assign(Object.assign({}, commonOptions), interactiveOptions), {
117
+ // include boths headers passed via flags and headers entered interactively
118
+ headers: headers.concat(interactiveOptions.curlArgs.headers) });
119
+ }
120
+ else {
121
+ // run non-interactively
122
+ const argsOrError = (0, curl_parser_1.parseCurlArgv)(argv);
123
+ if ('error' in argsOrError) {
124
+ throw new errors_1.CLIError(argsOrError.error);
106
125
  }
107
- else {
108
- // non-interactive
109
- answers = Object.assign(Object.assign({}, editableOptions), { endpoint: argv[1] });
126
+ const parsedPathParamsOrError = (0, path_params_parser_1.parsePathParamsPattern)(argsOrError.url, flags['path-params']);
127
+ if ('error' in parsedPathParamsOrError) {
128
+ throw new errors_1.CLIError(parsedPathParamsOrError.error);
110
129
  }
111
- const fixedOptions = {
112
- name: flags.name,
113
- source: workspace.schema,
114
- onConflict,
115
- };
116
- const options = Object.assign(Object.assign({}, fixedOptions), answers);
117
- core_1.CliUx.ux.action.start('Starting');
118
- const resultOrError = await graphql2sdl_1.graphql2sdl(options);
119
- core_1.CliUx.ux.action.stop();
120
- if ('error' in resultOrError) {
121
- this.log('A problem occured while processing your import.');
122
- this.log(resultOrError.error);
123
- this.exit();
130
+ const maybeDuplicateParamsMessage = (0, curl2sdl_1.makeDuplicateParamsMessage)(headers, parsedPathParamsOrError, argsOrError.url);
131
+ if (maybeDuplicateParamsMessage) {
132
+ throw new errors_1.CLIError(maybeDuplicateParamsMessage);
124
133
  }
125
- result = resultOrError.outPath;
134
+ curl2sdlOptions = Object.assign(Object.assign(Object.assign({}, commonOptions), curlFlagValues), { pathParams: parsedPathParamsOrError, headers: headers, curlArgs: argsOrError });
135
+ }
136
+ core_1.CliUx.ux.action.start('Starting');
137
+ const resultOrError = await (0, curl2sdl_1.curl2sdl)(curl2sdlOptions);
138
+ core_1.CliUx.ux.action.stop();
139
+ if ('error' in resultOrError) {
140
+ this.log('A problem occured while processing your import. ' +
141
+ 'Please check that the given cURL command is valid.');
142
+ this.log(resultOrError.error);
143
+ this.exit();
144
+ }
145
+ return resultOrError.outPath;
146
+ }
147
+ async importGraphQL(argv, flags, commonOptions) {
148
+ const headers = this.parseHeaderFlags(flags.header, flags['header-param']);
149
+ let graphql2sdlOptions;
150
+ const graphqlFlagValues = {
151
+ typePrefix: flags.prefix,
152
+ };
153
+ if (argv.length === 1) {
154
+ // no parameters given: start an interactive prompt
155
+ const interactiveOptions = await (0, graphql2sdl_1.askGraphQLQuestions)(graphqlFlagValues);
156
+ graphql2sdlOptions = Object.assign(Object.assign(Object.assign({}, commonOptions), interactiveOptions), {
157
+ // include boths headers passed via flags and headers entered interactively
158
+ headers: headers.concat(interactiveOptions.headers) });
159
+ }
160
+ else {
161
+ // run non-interactively
162
+ graphql2sdlOptions = Object.assign(Object.assign(Object.assign({}, commonOptions), graphqlFlagValues), { endpoint: argv[1], headers: headers });
163
+ }
164
+ core_1.CliUx.ux.action.start('Starting');
165
+ const resultOrError = await (0, graphql2sdl_1.graphql2sdl)(graphql2sdlOptions);
166
+ core_1.CliUx.ux.action.stop();
167
+ if ('error' in resultOrError) {
168
+ this.log('A problem occured while processing your import.');
169
+ this.log(resultOrError.error);
170
+ this.exit();
171
+ }
172
+ return resultOrError.outPath;
173
+ }
174
+ async importSql(schema, flags, fixedOptions) {
175
+ let sql2sdlOptions;
176
+ const sqlFlagValues = this.getSqlOptionsFromFlags(flags);
177
+ if (sqlFlagValues.host !== undefined &&
178
+ sqlFlagValues.database !== undefined &&
179
+ sqlFlagValues.user !== undefined &&
180
+ sqlFlagValues.password !== undefined) {
181
+ // run non-interactively
182
+ sql2sdlOptions = Object.assign(Object.assign(Object.assign({}, fixedOptions), sqlFlagValues), sqlFlagValues);
126
183
  }
127
184
  else {
128
- // Map flag names to the properties defined for sql engines in:
129
- // https://github.com/steprz/generator-engines/blob/main/generator/src/shared/sql.ts
130
- // If/when the number of property-to-answer mappings increase, create a dictionary
131
- // { schema: { flag: field } } and build the below map based on this (a
132
- // dictionary also enables a generic solution to the warning about ignored flags).
133
- let preAnswered = {};
134
- if (schema === 'mysql' || schema === 'postgresql') {
135
- const asKeyValue = (key, flag) => flag === undefined ? {} : { [key]: flag };
136
- preAnswered = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, asKeyValue('host', flags['db-host'])), asKeyValue('user', flags['db-user'])), asKeyValue('password', flags['db-password'])), asKeyValue('database', flags['db-database'])), asKeyValue('linkTypes', flags['db-link-types'] ? 'Yes' : 'No')), asKeyValue('schema', flags['db-schema']));
185
+ // one or more required parameters are missing: start an interactive prompt
186
+ const interactiveOptions = await (0, sql2sdl_1.askSqlQuestions)(schema, sqlFlagValues);
187
+ sql2sdlOptions = Object.assign(Object.assign(Object.assign({}, fixedOptions), interactiveOptions), { include: sqlFlagValues.include });
188
+ }
189
+ core_1.CliUx.ux.action.start('Starting');
190
+ const resultOrError = await (0, sql2sdl_1.sql2sdl)(schema, sql2sdlOptions);
191
+ core_1.CliUx.ux.action.stop();
192
+ if ('error' in resultOrError) {
193
+ this.log('A problem occured while processing your import. ' +
194
+ 'Please check that the given database details are valid.');
195
+ this.log(resultOrError.error);
196
+ this.exit();
197
+ }
198
+ return resultOrError.outPath;
199
+ }
200
+ async importFromGeneratorEngines(schema, flags, fixedOptions) {
201
+ let preAnswered = {};
202
+ if (schema === 'mysql' || schema === 'postgresql') {
203
+ preAnswered = this.getSqlOptionsFromFlags(flags);
204
+ if (Object.prototype.hasOwnProperty.call(preAnswered, 'linkTypes')) {
205
+ preAnswered.linkTypes = preAnswered.linkTypes ? 'Yes' : 'No';
137
206
  }
138
- // Let's go!
139
- result = await generate_1.default({
140
- schema,
141
- name: flags.name,
142
- onConflict,
143
- source: workspace.schema,
144
- preAnswered,
145
- });
146
- // Validate
147
- await transpiler_1.validate(result, {
148
- extensions: await utils_1.getStepZenExtensions(),
149
- });
150
207
  }
151
- // Housekeeping
152
- fs.copySync(result, workspace.schema);
153
- fs.removeSync(result);
154
- // Nice message
155
- this.log(chalk.green(`Successfully imported schema ${chalk.bold(schema)} from StepZen`));
208
+ // Let's go!
209
+ const result = await (0, generate_1.default)(Object.assign(Object.assign({}, fixedOptions), { schema,
210
+ preAnswered }));
211
+ // Validate
212
+ await (0, transpiler_1.validate)(result, {
213
+ extensions: await (0, utils_1.getStepZenExtensions)(),
214
+ });
215
+ return result;
156
216
  }
157
217
  async ensureOnConflictBehavior(workspace, schema, flags) {
158
- const featureFlag = process.env.STEPZEN_DETECT_NAME_CONFLICTS;
159
- if (featureFlag === undefined || featureFlag.toLowerCase() === 'false') {
218
+ const detectNameConflicts = (0, utils_1.getFeatureFlag)(constants_1.DETECT_NAME_CONFLICTS);
219
+ if (!detectNameConflicts) {
160
220
  return 'append';
161
221
  }
162
222
  const name = flags.name || schema;
@@ -258,7 +318,7 @@ class Import extends zen_command_1.default {
258
318
  const headers = [];
259
319
  if (headerFlagValues) {
260
320
  headerFlagValues.forEach(value => {
261
- const headerOrError = header_1.parseHeader(value);
321
+ const headerOrError = (0, header_1.parseHeader)(value);
262
322
  if (headerOrError && 'error' in headerOrError) {
263
323
  throw new errors_1.CLIError(headerOrError.error);
264
324
  }
@@ -270,15 +330,37 @@ class Import extends zen_command_1.default {
270
330
  }
271
331
  });
272
332
  }
273
- const headersOrError = header_params_parser_1.makeHeaders(headers, headerParamFlagValues);
333
+ const headersOrError = (0, header_params_parser_1.makeHeaders)(headers, headerParamFlagValues);
274
334
  if ('error' in headersOrError) {
275
335
  throw new errors_1.CLIError(headersOrError.error);
276
336
  }
277
337
  return headersOrError;
278
338
  }
339
+ getSqlOptionsFromFlags(flags) {
340
+ const options = {
341
+ host: flags['db-host'],
342
+ user: flags['db-user'],
343
+ password: flags['db-password'],
344
+ database: flags['db-database'],
345
+ linkTypes: flags['db-link-types'],
346
+ schema: flags['db-schema'],
347
+ include: flags['db-include'],
348
+ };
349
+ if ((0, utils_1.getFeatureFlag)(constants_1.USE_GENERATOR_ENGINES)) {
350
+ // Explicitly delete all `undefined` properties to keep the
351
+ // `generator-engines` cloud function happy
352
+ Object.keys(options).forEach(key => {
353
+ const k = key;
354
+ if (options[k] === undefined) {
355
+ delete options[k];
356
+ }
357
+ });
358
+ }
359
+ return options;
360
+ }
279
361
  }
280
362
  exports.default = Import;
281
- Import.description = 'import a schema for an external data source or a API endpoint to your GraphQL API';
363
+ Import.description = 'import a schema for an external data source or an API endpoint to your GraphQL API';
282
364
  Import.commonIntrospectionFlags = {
283
365
  prefix: command_1.flags.string({
284
366
  description: '[curl, graphql] prefix to add every type in the generated schema.',
@@ -338,10 +420,16 @@ Import.sqlFlags = {
338
420
  description: '[mysql, postgresql] name of database to import',
339
421
  }),
340
422
  'db-link-types': command_1.flags.boolean({
341
- description: `[mysql, postgresql] Automatically link types with` +
342
- ` @materializer whenever there is database support` +
423
+ description: `[mysql, postgresql] Automatically link types based on` +
424
+ ` foreign key relationships using @materializer` +
343
425
  ` ${chalk.dim('(https://stepzen.com/docs/features/linking-types)')}`,
344
426
  }),
427
+ 'db-include': command_1.flags.enum({
428
+ options: ['tables-only', 'views-only', 'tables-and-views'],
429
+ description: `[mysql, postgresql] Should the generated GraphQL schema be based` +
430
+ ` only on database views, only on tables or on both.`,
431
+ hidden: (0, utils_1.getFeatureFlag)(constants_1.USE_GENERATOR_ENGINES),
432
+ }),
345
433
  };
346
434
  Import.postgresqlFlags = {
347
435
  'db-schema': command_1.flags.string({
@@ -7,7 +7,7 @@ const zen_command_1 = require("../shared/zen-command");
7
7
  class Init extends zen_command_1.default {
8
8
  async run() {
9
9
  const { args, flags } = this.parse(Init);
10
- const created = await workspace_1.initWorkspace({
10
+ const created = await (0, workspace_1.initWorkspace)({
11
11
  directory: args.directory,
12
12
  endpoint: flags.endpoint,
13
13
  yes: flags.yes,
@@ -17,7 +17,7 @@ class Init extends zen_command_1.default {
17
17
  }
18
18
  }
19
19
  exports.default = Init;
20
- Init.description = 'stepzen init';
20
+ Init.description = 'Initialize a StepZen workspace in the current directory';
21
21
  Init.hidden = true;
22
22
  Init.flags = Object.assign(Object.assign({}, zen_command_1.default.flags), { endpoint: command_1.flags.string({ hidden: true }), help: command_1.flags.help({ char: 'h' }), yes: command_1.flags.boolean({ default: false, hidden: true }) });
23
23
  Init.args = [
@@ -9,7 +9,7 @@ class Init extends zen_command_1.default {
9
9
  async run() {
10
10
  const { flags } = this.parse(Init);
11
11
  // Get the correct directory
12
- const directory = utils_1.getDirectory(flags.dir);
12
+ const directory = (0, utils_1.getDirectory)(flags.dir);
13
13
  this.log(directory);
14
14
  // Take over console.log
15
15
  console.log = (msg) => {
@@ -18,7 +18,7 @@ class Init extends zen_command_1.default {
18
18
  this.log(formatted);
19
19
  };
20
20
  // Lint
21
- await transpiler_1.lint(directory);
21
+ await (0, transpiler_1.lint)(directory);
22
22
  }
23
23
  }
24
24
  exports.default = Init;
@@ -14,7 +14,7 @@ class List extends zen_command_1.default {
14
14
  var _a;
15
15
  const { args } = this.parse(List);
16
16
  await this.ensureStepZenAccount();
17
- const response = await actions_1.list(args.type);
17
+ const response = await (0, actions_1.list)(args.type);
18
18
  if (response.success) {
19
19
  if (((_a = response.results) === null || _a === void 0 ? void 0 : _a.length) === 0) {
20
20
  // Success, but no results
@@ -15,7 +15,7 @@ class Login extends zen_command_1.default {
15
15
  const { flags } = this.parse(Login);
16
16
  let configuration;
17
17
  if (flags.public) {
18
- const { uuid } = await configuration_1.readConfiguration();
18
+ const { uuid } = await (0, configuration_1.readConfiguration)();
19
19
  configuration = await stepzen_sdk_1.default.createAnonymousAccount(uuid);
20
20
  }
21
21
  else {
@@ -23,7 +23,7 @@ class Login extends zen_command_1.default {
23
23
  let adminkey;
24
24
  // If the --config flag is provided, try and log in using the details in the file
25
25
  if (flags.config) {
26
- const config = await configuration_1.importConfiguration(flags.config);
26
+ const config = await (0, configuration_1.importConfiguration)(flags.config);
27
27
  account = config.account;
28
28
  adminkey = config.adminkey;
29
29
  }
@@ -49,7 +49,7 @@ class Login extends zen_command_1.default {
49
49
  configuration = await stepzen_sdk_1.default.login(adminkey, account);
50
50
  }
51
51
  // Change the default account.
52
- configuration_1.writeCredentialsToConfigFile(configuration);
52
+ (0, configuration_1.writeCredentialsToConfigFile)(configuration);
53
53
  this.log(`You have successfully logged in as ${chalk.bold(configuration.account)}.`);
54
54
  }
55
55
  }
@@ -9,7 +9,7 @@ const zen_command_1 = require("../shared/zen-command");
9
9
  class Logout extends zen_command_1.default {
10
10
  async run() {
11
11
  // Remove the configuration from the login file.
12
- configuration_1.removeCredentialsFromConfigFile();
12
+ (0, configuration_1.removeCredentialsFromConfigFile)();
13
13
  this.log('You have been logged out.');
14
14
  }
15
15
  }