stepzen 0.19.0-beta.0 → 0.19.0

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 (49) hide show
  1. package/README.md +13 -3
  2. package/lib/commands/deploy.js +1 -1
  3. package/lib/commands/import.d.ts +19 -6
  4. package/lib/commands/import.js +124 -74
  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 +2 -2
  16. package/lib/generate/curl2sdl.js +24 -15
  17. package/lib/generate/graphql2sdl.d.ts +3 -3
  18. package/lib/generate/graphql2sdl.js +19 -5
  19. package/lib/generate/helpers.d.ts +7 -1
  20. package/lib/generate/helpers.js +39 -21
  21. package/lib/generate/index.js +6 -6
  22. package/lib/generate/sql2sdl.d.ts +6 -5
  23. package/lib/generate/sql2sdl.js +37 -10
  24. package/lib/hooks/prerun/check-upgrade.js +13 -10
  25. package/lib/hooks/prerun/ensure-config-file.js +3 -3
  26. package/lib/index.js +1 -0
  27. package/lib/shared/actions.js +9 -6
  28. package/lib/shared/configuration.js +20 -14
  29. package/lib/shared/constants.d.ts +3 -0
  30. package/lib/shared/constants.js +17 -5
  31. package/lib/shared/curl-parser.js +3 -2
  32. package/lib/shared/errors.js +2 -1
  33. package/lib/shared/header-params-parser.js +6 -4
  34. package/lib/shared/header.js +2 -1
  35. package/lib/shared/moniker.js +5 -3
  36. package/lib/shared/path-params-parser.d.ts +1 -1
  37. package/lib/shared/path-params-parser.js +5 -3
  38. package/lib/shared/stepzen-sdk.d.ts +1 -1
  39. package/lib/shared/stepzen-sdk.js +1 -1
  40. package/lib/shared/utils.d.ts +1 -0
  41. package/lib/shared/utils.js +22 -8
  42. package/lib/shared/validation.js +4 -2
  43. package/lib/shared/workspace.js +21 -16
  44. package/lib/shared/zen-command.js +7 -7
  45. package/lib/start/console.d.ts +1 -1
  46. package/lib/start/console.js +16 -9
  47. package/lib/start/index.js +1 -0
  48. package/oclif.manifest.json +1 -1
  49. package/package.json +3 -3
@@ -37,7 +37,7 @@ class Upload extends zen_command_1.default {
37
37
  if (!flags.silent) {
38
38
  this.log('Uploading...');
39
39
  }
40
- const response = await actions_1.upload(args.type, args.destination, source);
40
+ const response = await (0, actions_1.upload)(args.type, args.destination, source);
41
41
  if (response.success) {
42
42
  if (!flags.silent) {
43
43
  this.log(response.message);
@@ -7,17 +7,19 @@ const errors_1 = require("@oclif/errors");
7
7
  const transpiler_1 = require("@stepzen/transpiler");
8
8
  const utils_1 = require("../shared/utils");
9
9
  const zen_command_1 = require("../shared/zen-command");
10
+ const core_1 = require("@oclif/core");
10
11
  class Validate extends zen_command_1.default {
11
12
  async run() {
12
13
  const { args } = this.parse(Validate);
13
- const folder = utils_1.getDirectory(args.folder);
14
+ const folder = (0, utils_1.getDirectory)(args.folder);
14
15
  try {
15
- const schema = transpiler_1.stitch(folder);
16
- transpiler_1.validate(schema, {
17
- extensions: await utils_1.getStepZenExtensions(),
16
+ const schema = (0, transpiler_1.stitch)(folder);
17
+ (0, transpiler_1.validate)(schema, {
18
+ extensions: await (0, utils_1.getStepZenExtensions)(),
18
19
  });
19
20
  }
20
21
  catch (error) {
22
+ core_1.CliUx.ux.action.stop(chalk.red('fail'));
21
23
  throw new errors_1.CLIError(chalk.red(error));
22
24
  }
23
25
  }
@@ -9,7 +9,7 @@ const zen_command_1 = require("../shared/zen-command");
9
9
  class WhoAmI extends zen_command_1.default {
10
10
  async run() {
11
11
  const { flags } = this.parse(WhoAmI);
12
- const configuration = await configuration_1.readConfiguration();
12
+ const configuration = await (0, configuration_1.readConfiguration)();
13
13
  if (!('account' in configuration)) {
14
14
  this.log('You are not logged in.');
15
15
  return;
@@ -36,7 +36,7 @@ class WhoAmI extends zen_command_1.default {
36
36
  details.adminkey = configuration.adminkey;
37
37
  }
38
38
  else {
39
- details.adminkey = utils_1.maskStepZenKey(configuration.adminkey);
39
+ details.adminkey = (0, utils_1.maskStepZenKey)(configuration.adminkey);
40
40
  }
41
41
  }
42
42
  if (configuration.apikey) {
@@ -44,7 +44,7 @@ class WhoAmI extends zen_command_1.default {
44
44
  details.apikey = configuration.apikey;
45
45
  }
46
46
  else {
47
- details.apikey = utils_1.maskStepZenKey(configuration.apikey);
47
+ details.apikey = (0, utils_1.maskStepZenKey)(configuration.apikey);
48
48
  }
49
49
  }
50
50
  this.log();
@@ -10,7 +10,7 @@ export declare type Curl2SdlOptions = CommonImportOptions & {
10
10
  pathParams: readonly PathParam[];
11
11
  headers: readonly HeaderInput[];
12
12
  };
13
- export declare type EditableCurl2SdlOptions = Pick<Curl2SdlOptions, 'curlArgs' | 'queryName' | 'rootType' | 'typePrefix' | 'pathParams'>;
13
+ export declare type InteractiveCurl2SdlOptions = Pick<Curl2SdlOptions, 'curlArgs' | 'queryName' | 'rootType' | 'typePrefix' | 'pathParams'>;
14
14
  export declare type CurlAnswers = {
15
15
  url: string;
16
16
  queryName: string;
@@ -45,7 +45,7 @@ export declare const compileParameterList: (headers: HeaderInput[], pathParams:
45
45
  * there are no duplicates
46
46
  */
47
47
  export declare const makeDuplicateParamsMessage: (headers: HeaderInput[], pathParams: PathParam[], url: string) => string | null;
48
- export declare const askCurlQuestions: (defaultAnswers?: Partial<CurlAnswers>) => Promise<EditableCurl2SdlOptions>;
48
+ export declare const askCurlQuestions: (defaultAnswers?: Partial<CurlAnswers>) => Promise<InteractiveCurl2SdlOptions>;
49
49
  export declare const curl2sdl: ({ curlArgs, name, source, queryName, rootType, typePrefix, pathParams, headers, onConflict, }: Curl2SdlOptions) => Promise<{
50
50
  error: string;
51
51
  } | {
@@ -19,12 +19,12 @@ const constants_1 = require("../shared/constants");
19
19
  * @param {*} pathname full pathname of the REST endpoint
20
20
  * @returns {*} combined list of query parameters in a uniform format
21
21
  */
22
- exports.compileParameterList = (headers, pathParams, pathname) => {
22
+ const compileParameterList = (headers, pathParams, pathname) => {
23
23
  // Drop empty segments, including empty string before the leading slash
24
24
  const pathSegments = pathname.split('/').filter(Boolean);
25
25
  // For each header, make a list of the parameters it contains.
26
26
  // `flatMap()` concatenates each header's param lists into a single list.
27
- return lodash_1.flatMap(headers, header => {
27
+ return (0, lodash_1.flatMap)(headers, header => {
28
28
  // skip headers that don't contain parameters
29
29
  if (!('parts' in header)) {
30
30
  return [];
@@ -53,6 +53,7 @@ exports.compileParameterList = (headers, pathParams, pathname) => {
53
53
  context: `pathname ${chalk.dim(`(${pathname})`)}`,
54
54
  })));
55
55
  };
56
+ exports.compileParameterList = compileParameterList;
56
57
  /**
57
58
  * Check the header and path parameters for duplicates, and construct a
58
59
  * user-friendly error message describing identified problems (if any).
@@ -64,15 +65,15 @@ exports.compileParameterList = (headers, pathParams, pathname) => {
64
65
  * @returns {*} a message describing duplicate query parameters, or null if
65
66
  * there are no duplicates
66
67
  */
67
- exports.makeDuplicateParamsMessage = (headers, pathParams, url) => {
68
+ const makeDuplicateParamsMessage = (headers, pathParams, url) => {
68
69
  // Create a uniform list of query parameters from the headers and path
69
- const parameters = exports.compileParameterList(headers, pathParams, new URL(url).pathname);
70
- const errors = Object.entries(lodash_1.groupBy(parameters, 'name'))
70
+ const parameters = (0, exports.compileParameterList)(headers, pathParams, new URL(url).pathname);
71
+ const errors = Object.entries((0, lodash_1.groupBy)(parameters, 'name'))
71
72
  // Create groups for each unique parameter name,
72
73
  // and then sub-groups for each unique [name, value] tuple.
73
74
  .map(([name, group]) => ({
74
75
  name,
75
- values: Object.entries(lodash_1.groupBy(group, 'value')),
76
+ values: Object.entries((0, lodash_1.groupBy)(group, 'value')),
76
77
  }))
77
78
  // ignore the [name, value] tuples that occur only once
78
79
  .filter(({ values }) => values.length > 1)
@@ -88,7 +89,8 @@ exports.makeDuplicateParamsMessage = (headers, pathParams, url) => {
88
89
  }
89
90
  return null;
90
91
  };
91
- exports.askCurlQuestions = async (defaultAnswers = {}) => {
92
+ exports.makeDuplicateParamsMessage = makeDuplicateParamsMessage;
93
+ const askCurlQuestions = async (defaultAnswers = {}) => {
92
94
  const questions = [
93
95
  {
94
96
  name: 'url',
@@ -111,15 +113,15 @@ exports.askCurlQuestions = async (defaultAnswers = {}) => {
111
113
  message: 'Prefix to add to all generated type names (leave blank to use defaults)',
112
114
  },
113
115
  ];
114
- const answers = await inquirer.prompt(helpers_1.overrideDefaults(questions, defaultAnswers));
115
- const curlArgs = curl_parser_1.parseCurlArgv(string_argv_1.default(answers.url));
116
+ const answers = await inquirer.prompt((0, helpers_1.overrideDefaults)(questions, defaultAnswers));
117
+ const curlArgs = (0, curl_parser_1.parseCurlArgv)((0, string_argv_1.default)(answers.url));
116
118
  if ('error' in curlArgs) {
117
119
  console.log();
118
120
  console.log(chalk.red('A problem occurred while parsing the curl command:\n', curlArgs.error), '\nPlease enter a URL or a supported curl command.');
119
121
  console.log();
120
- return exports.askCurlQuestions(answers);
122
+ return (0, exports.askCurlQuestions)(answers);
121
123
  }
122
- const parsedPathParamsOrError = path_params_parser_1.parsePathParamsPattern(curlArgs.url, answers.pathParams);
124
+ const parsedPathParamsOrError = (0, path_params_parser_1.parsePathParamsPattern)(curlArgs.url, answers.pathParams);
123
125
  if ('error' in parsedPathParamsOrError) {
124
126
  console.log();
125
127
  console.log(chalk.red('A problem occurred while parsing path parameters pattern:\n', parsedPathParamsOrError.error));
@@ -132,7 +134,7 @@ exports.askCurlQuestions = async (defaultAnswers = {}) => {
132
134
  `\tendpoint URL: https://example.com/users/jane/posts/12\n ` +
133
135
  `\tpath parameters: /users/${chalk.bold('$userId')}/posts/${chalk.bold('$postId')}`);
134
136
  console.log();
135
- return exports.askCurlQuestions(answers);
137
+ return (0, exports.askCurlQuestions)(answers);
136
138
  }
137
139
  return {
138
140
  curlArgs,
@@ -142,8 +144,9 @@ exports.askCurlQuestions = async (defaultAnswers = {}) => {
142
144
  pathParams: parsedPathParamsOrError,
143
145
  };
144
146
  };
145
- exports.curl2sdl = async ({ curlArgs, name, source, queryName, rootType, typePrefix, pathParams, headers, onConflict, }) => {
146
- const response = await helpers_1.queryIntrospectionService(constants_1.STEPZEN_JSON2SDL_SERVER_URL, {
147
+ exports.askCurlQuestions = askCurlQuestions;
148
+ const curl2sdl = async ({ curlArgs, name, source, queryName, rootType, typePrefix, pathParams, headers, onConflict, }) => {
149
+ const response = await (0, helpers_1.queryIntrospectionService)(constants_1.STEPZEN_JSON2SDL_SERVER_URL, {
147
150
  operation: 'getSDLFromCurl',
148
151
  variables: {
149
152
  command: {
@@ -183,5 +186,11 @@ exports.curl2sdl = async ({ curlArgs, name, source, queryName, rootType, typePre
183
186
  if (response.error) {
184
187
  return { error: response.error };
185
188
  }
186
- return helpers_1.writeSdlAndConfig(name || 'curl', source, onConflict, response);
189
+ return (0, helpers_1.writeSdlAndConfig)({
190
+ name: name || 'curl',
191
+ source,
192
+ onConflict,
193
+ response,
194
+ });
187
195
  };
196
+ exports.curl2sdl = curl2sdl;
@@ -6,14 +6,14 @@ export declare type GraphQL2SdlOptions = CommonImportOptions & {
6
6
  includeRootOperations?: boolean;
7
7
  headers: readonly HeaderInput[];
8
8
  };
9
- export declare type EditableGraphQL2SdlOptions = Pick<GraphQL2SdlOptions, 'endpoint' | 'typePrefix' | 'includeRootOperations' | 'headers'>;
9
+ export declare type InteractiveGraphQL2SdlOptions = Pick<GraphQL2SdlOptions, 'endpoint' | 'typePrefix' | 'includeRootOperations' | 'headers'>;
10
10
  export declare type GraphQLAnswers = {
11
11
  endpoint: string;
12
12
  typePrefix: string;
13
13
  includeRootOperations: boolean;
14
- headers: readonly HeaderInput[];
14
+ header: string;
15
15
  };
16
- export declare const askGraphQLQuestions: (defaultAnswers?: Partial<GraphQLAnswers>) => Promise<EditableGraphQL2SdlOptions>;
16
+ export declare const askGraphQLQuestions: (defaultAnswers?: Partial<GraphQLAnswers>) => Promise<InteractiveGraphQL2SdlOptions>;
17
17
  export declare const graphql2sdl: ({ name, source, endpoint, typePrefix, includeRootOperations, headers, onConflict, }: GraphQL2SdlOptions) => Promise<{
18
18
  error: string;
19
19
  } | {
@@ -6,7 +6,7 @@ const inquirer = require("inquirer");
6
6
  const header_1 = require("../shared/header");
7
7
  const helpers_1 = require("./helpers");
8
8
  const constants_1 = require("../shared/constants");
9
- exports.askGraphQLQuestions = async (defaultAnswers = {}) => {
9
+ const askGraphQLQuestions = async (defaultAnswers = {}) => {
10
10
  const questions = [
11
11
  {
12
12
  name: 'endpoint',
@@ -30,10 +30,18 @@ exports.askGraphQLQuestions = async (defaultAnswers = {}) => {
30
30
  validate: input => input === '' || header_1.HEADER_REGEX.test(input.trim()) || 'invalid header',
31
31
  },
32
32
  ];
33
- return inquirer.prompt(helpers_1.overrideDefaults(questions, defaultAnswers));
33
+ const answers = await inquirer.prompt((0, helpers_1.overrideDefaults)(questions, defaultAnswers));
34
+ const header = (0, header_1.parseHeader)(answers.header);
35
+ return {
36
+ endpoint: answers.endpoint,
37
+ typePrefix: answers.typePrefix.trim() === '' ? undefined : answers.typePrefix.trim(),
38
+ includeRootOperations: answers.includeRootOperations,
39
+ headers: header && !('error' in header) ? [header] : [],
40
+ };
34
41
  };
35
- exports.graphql2sdl = async ({ name, source, endpoint, typePrefix, includeRootOperations, headers, onConflict, }) => {
36
- const response = await helpers_1.queryIntrospectionService(constants_1.STEPZEN_JSON2SDL_SERVER_URL, {
42
+ exports.askGraphQLQuestions = askGraphQLQuestions;
43
+ const graphql2sdl = async ({ name, source, endpoint, typePrefix, includeRootOperations, headers, onConflict, }) => {
44
+ const response = await (0, helpers_1.queryIntrospectionService)(constants_1.STEPZEN_JSON2SDL_SERVER_URL, {
37
45
  operation: 'getSDLFromGraphQL',
38
46
  variables: {
39
47
  endpoint: {
@@ -57,5 +65,11 @@ exports.graphql2sdl = async ({ name, source, endpoint, typePrefix, includeRootOp
57
65
  if (response.error) {
58
66
  return { error: response.error };
59
67
  }
60
- return helpers_1.writeSdlAndConfig(name || 'graphql', source, onConflict, response);
68
+ return (0, helpers_1.writeSdlAndConfig)({
69
+ name: name || 'graphql',
70
+ source,
71
+ onConflict,
72
+ response,
73
+ });
61
74
  };
75
+ exports.graphql2sdl = graphql2sdl;
@@ -27,7 +27,13 @@ export declare type IntrospectionServiceResponse = {
27
27
  error?: string;
28
28
  };
29
29
  export declare const queryIntrospectionService: (serverUrl: string, query: IntrospectionServiceQuery) => Promise<IntrospectionServiceResponse>;
30
- export declare const writeSdlAndConfig: (name: string, source: string, onConflict: 'overwrite' | 'append', { config, sdl }: IntrospectionServiceResponse) => Promise<{
30
+ export declare const writeSdlAndConfig: ({ name, source, mergeTypes, onConflict, response, }: {
31
+ name: string;
32
+ source: string;
33
+ mergeTypes?: boolean | undefined;
34
+ onConflict: 'overwrite' | 'append';
35
+ response: IntrospectionServiceResponse;
36
+ }) => Promise<{
31
37
  outPath: string;
32
38
  }>;
33
39
  export declare const overrideDefaults: <Options>(questions: inquirer.DistinctQuestion<Options>[], defaultAnswers: Partial<Options>) => inquirer.DistinctQuestion<Options>[];
@@ -17,12 +17,12 @@ const prettier = require("prettier");
17
17
  const constants_1 = require("../shared/constants");
18
18
  const errors_2 = require("../shared/errors");
19
19
  const { version } = require('../../package.json');
20
- exports.createGeneratorFiles = async (id, details) => {
20
+ const createGeneratorFiles = async (id, details) => {
21
21
  const url = `${constants_1.STEPZEN_DIRECT_GENERATOR_ENGINES_URL}/create`;
22
22
  debug('stepzen:generate')(`calling the generator engine ${id} via ${url}`);
23
23
  const engineErrorMessageWrap = (msg) => `An error has occurred when creating the schema: ${msg}. Please check your parameters and try again.`;
24
24
  try {
25
- const response = await node_fetch_1.default(url, {
25
+ const response = await (0, node_fetch_1.default)(url, {
26
26
  body: JSON.stringify({
27
27
  id,
28
28
  details: JSON.stringify(details.answers),
@@ -62,11 +62,12 @@ exports.createGeneratorFiles = async (id, details) => {
62
62
  : new errors_1.CLIError(errors_2.PERMANENT_STEPZEN_ERROR);
63
63
  }
64
64
  };
65
- exports.getConfiguration = async (id, details = {}) => {
65
+ exports.createGeneratorFiles = createGeneratorFiles;
66
+ const getConfiguration = async (id, details = {}) => {
66
67
  const url = `${constants_1.STEPZEN_DIRECT_GENERATOR_ENGINES_URL}/configure`;
67
68
  debug('stepzen:generate')(`calling the generator engine ${id} via ${url}`);
68
69
  try {
69
- const response = await node_fetch_1.default(url, {
70
+ const response = await (0, node_fetch_1.default)(url, {
70
71
  body: JSON.stringify({
71
72
  id,
72
73
  details: JSON.stringify(details),
@@ -90,7 +91,8 @@ exports.getConfiguration = async (id, details = {}) => {
90
91
  throw new errors_1.CLIError(errors_2.PERMANENT_STEPZEN_ERROR);
91
92
  }
92
93
  };
93
- exports.getSchema = (arg) => {
94
+ exports.getConfiguration = getConfiguration;
95
+ const getSchema = (arg) => {
94
96
  const schema = arg.trim();
95
97
  // Now supports importing only one schema at a time:
96
98
  // https://github.com/steprz/stepzen-cli/issues/628
@@ -104,7 +106,8 @@ exports.getSchema = (arg) => {
104
106
  }
105
107
  return schema;
106
108
  };
107
- exports.getTemplates = async () => {
109
+ exports.getSchema = getSchema;
110
+ const getTemplates = async () => {
108
111
  const tmp = path.join(os.tmpdir(), `stepzen-api-templates-${Date.now()}`);
109
112
  fs.ensureDirSync(tmp);
110
113
  const repository = constants_1.STEPZEN_API_TEMPLATES_REPOSITORY;
@@ -115,7 +118,8 @@ exports.getTemplates = async () => {
115
118
  }
116
119
  return tmp;
117
120
  };
118
- exports.askGeneratorQuestions = async (id, settings, state) => {
121
+ exports.getTemplates = getTemplates;
122
+ const askGeneratorQuestions = async (id, settings, state) => {
119
123
  var _a, _b;
120
124
  let status = -1;
121
125
  do {
@@ -123,14 +127,14 @@ exports.askGeneratorQuestions = async (id, settings, state) => {
123
127
  return Object.assign(Object.assign({ type: 'password' }, question), {
124
128
  // set the previous iteration's answer as the default value, except for password fields
125
129
  default: question.type && question.type !== 'password'
126
- ? lodash_1.get(state, question.name)
130
+ ? (0, lodash_1.get)(state, question.name)
127
131
  : undefined });
128
132
  });
129
133
  // eslint-disable-next-line no-await-in-loop
130
134
  const answers = await inquirer.prompt(questions);
131
- state = lodash_1.merge(state, answers);
135
+ state = (0, lodash_1.merge)(state, answers);
132
136
  // eslint-disable-next-line no-await-in-loop
133
- const result = await exports.getConfiguration(id, state);
137
+ const result = await (0, exports.getConfiguration)(id, state);
134
138
  if (!result) {
135
139
  // at this point the generator ${id} should have been validated
136
140
  throw new errors_1.CLIError(errors_2.PERMANENT_STEPZEN_ERROR);
@@ -150,18 +154,20 @@ exports.askGeneratorQuestions = async (id, settings, state) => {
150
154
  questions: result.questions,
151
155
  };
152
156
  // eslint-disable-next-line require-atomic-updates
153
- state = lodash_1.merge(state, result.answers);
157
+ state = (0, lodash_1.merge)(state, result.answers);
154
158
  }
155
159
  status = result.status;
156
160
  } while (status === -1);
157
161
  return state;
158
162
  };
159
- exports.askTemplateQuestions = async (id, settings, state) => {
163
+ exports.askGeneratorQuestions = askGeneratorQuestions;
164
+ const askTemplateQuestions = async (id, settings, state) => {
160
165
  const questions = settings.questions.map((question) => (Object.assign({ type: 'password' }, question)));
161
166
  const answers = await inquirer.prompt(questions);
162
167
  return Object.assign(Object.assign({}, state), answers);
163
168
  };
164
- exports.queryIntrospectionService = async (serverUrl, query) => {
169
+ exports.askTemplateQuestions = askTemplateQuestions;
170
+ const queryIntrospectionService = async (serverUrl, query) => {
165
171
  let json;
166
172
  try {
167
173
  debug('stepzen:introspection')(serverUrl);
@@ -177,10 +183,10 @@ exports.queryIntrospectionService = async (serverUrl, query) => {
177
183
  debug('stepzen:introspection')(query.variables);
178
184
  const payload = JSON.stringify({
179
185
  query: queryString,
180
- variables: lodash_1.mapValues(query.variables, ({ value }) => value),
186
+ variables: (0, lodash_1.mapValues)(query.variables, ({ value }) => value),
181
187
  });
182
188
  debug('stepzen:introspection')(payload);
183
- const response = await node_fetch_1.default(serverUrl, {
189
+ const response = await (0, node_fetch_1.default)(serverUrl, {
184
190
  method: 'POST',
185
191
  headers: { 'Content-Type': 'application/json' },
186
192
  body: payload,
@@ -200,9 +206,17 @@ exports.queryIntrospectionService = async (serverUrl, query) => {
200
206
  }
201
207
  if (json.errors) {
202
208
  const compileError = (error) => {
203
- var _a;
209
+ var _a, _b, _c;
204
210
  return error.message +
205
- (((_a = error.extensions) === null || _a === void 0 ? void 0 : _a.details) ? `: ${JSON.stringify(error.extensions.details)}`
211
+ // error.extensions.Message: DB introspection API (e.g. wrong password)
212
+ (((_a = error.extensions) === null || _a === void 0 ? void 0 : _a.Message) ? `: ${error.extensions.Message}` : '') +
213
+ // error.extensions.details: REST instrospection API (e.g. 401 / unauthorized)
214
+ (((_b = error.extensions) === null || _b === void 0 ? void 0 : _b.details)
215
+ ? `: ${JSON.stringify(error.extensions.details)}`
216
+ : '') +
217
+ // error.extensions.cause: DB introspection API (e.g. --db-include=views-only and there are no views)
218
+ (((_c = error.extensions) === null || _c === void 0 ? void 0 : _c.cause)
219
+ ? `: ${JSON.stringify(error.extensions.cause)}`
206
220
  : '');
207
221
  };
208
222
  return { error: json.errors.map(compileError).join('\n') };
@@ -221,7 +235,9 @@ exports.queryIntrospectionService = async (serverUrl, query) => {
221
235
  }
222
236
  return { config, sdl };
223
237
  };
224
- exports.writeSdlAndConfig = async (name, source, onConflict, { config, sdl }) => {
238
+ exports.queryIntrospectionService = queryIntrospectionService;
239
+ const writeSdlAndConfig = async ({ name, source, mergeTypes = false, onConflict, response, }) => {
240
+ const { config, sdl } = response;
225
241
  // write out the generated config and schema files
226
242
  const tmp = path.join(os.tmpdir(), `stepzen-introspection-${Date.now()}`);
227
243
  fs.ensureDirSync(tmp);
@@ -239,14 +255,16 @@ exports.writeSdlAndConfig = async (name, source, onConflict, { config, sdl }) =>
239
255
  answers: {},
240
256
  output: null,
241
257
  silent: true,
242
- mergeTypes: false,
258
+ mergeTypes,
243
259
  onConflict,
244
260
  });
245
261
  return { outPath: result };
246
262
  };
247
- exports.overrideDefaults = (questions, defaultAnswers) => {
263
+ exports.writeSdlAndConfig = writeSdlAndConfig;
264
+ const overrideDefaults = (questions, defaultAnswers) => {
248
265
  return questions.map(question => {
249
- const def = lodash_1.get(defaultAnswers, question.name);
266
+ const def = (0, lodash_1.get)(defaultAnswers, question.name);
250
267
  return def === undefined ? question : Object.assign(Object.assign({}, question), { default: def });
251
268
  });
252
269
  };
270
+ exports.overrideDefaults = overrideDefaults;
@@ -19,7 +19,7 @@ exports.default = async ({ schema, name, onConflict, source, preAnswered = {}, }
19
19
  // Start downloading
20
20
  core_1.CliUx.ux.action.start('Downloading from StepZen...');
21
21
  // Get the generator configuration
22
- const configure = await helpers_1.getConfiguration(schema, answers);
22
+ const configure = await (0, helpers_1.getConfiguration)(schema, answers);
23
23
  if (((_a = configure === null || configure === void 0 ? void 0 : configure.questions) === null || _a === void 0 ? void 0 : _a.length) ||
24
24
  ((configure === null || configure === void 0 ? void 0 : configure.status) && configure.status >= 0)) {
25
25
  generator = {
@@ -44,7 +44,7 @@ exports.default = async ({ schema, name, onConflict, source, preAnswered = {}, }
44
44
  // Get the API templates repository
45
45
  let templates;
46
46
  if (generator === undefined) {
47
- templates = await helpers_1.getTemplates();
47
+ templates = await (0, helpers_1.getTemplates)();
48
48
  if (fs.existsSync(`${templates}/${schema}`)) {
49
49
  const file = path.join(templates, schema, 'stepzen.config.json');
50
50
  const config = fs.readFileSync(file, 'utf8');
@@ -67,19 +67,19 @@ exports.default = async ({ schema, name, onConflict, source, preAnswered = {}, }
67
67
  throw new errors_1.CLIError(`Cannot find the schema ${schema}`);
68
68
  }
69
69
  else if (generator.type === 'generator') {
70
- result = await helpers_1.askGeneratorQuestions(schema, generator, answers);
70
+ result = await (0, helpers_1.askGeneratorQuestions)(schema, generator, answers);
71
71
  }
72
72
  else if (generator.type === 'template') {
73
- result = await helpers_1.askTemplateQuestions(schema, generator, answers);
73
+ result = await (0, helpers_1.askTemplateQuestions)(schema, generator, answers);
74
74
  }
75
75
  generator.answers = result;
76
- answers = lodash_1.merge(answers, result);
76
+ answers = (0, lodash_1.merge)(answers, result);
77
77
  // We now have all the answers! Generate schemas
78
78
  console.log();
79
79
  core_1.CliUx.ux.action.start('Generating schemas...');
80
80
  let files;
81
81
  if (generator.type === 'generator') {
82
- files = await helpers_1.createGeneratorFiles(schema, generator);
82
+ files = await (0, helpers_1.createGeneratorFiles)(schema, generator);
83
83
  tempFiles.push(files);
84
84
  }
85
85
  else {
@@ -1,21 +1,22 @@
1
1
  import type { CommonImportOptions } from '.';
2
2
  export declare type DBType = 'mysql' | 'postgresql';
3
- export declare type SQLOptions = CommonImportOptions & {
3
+ export declare type Sql2SdlOptions = CommonImportOptions & {
4
4
  host: string;
5
5
  database: string;
6
6
  user: string;
7
7
  password: string;
8
8
  linkTypes?: boolean;
9
9
  schema?: string;
10
+ include?: 'tables-only' | 'views-only' | 'tables-and-views';
10
11
  };
11
- export declare type EditableSQLOptions = Pick<SQLOptions, 'host' | 'database' | 'user' | 'password' | 'linkTypes' | 'schema'>;
12
- export declare const parseHost: (host?: string | undefined) => {
12
+ export declare type InteractiveSql2SdlOptions = Pick<Sql2SdlOptions, 'host' | 'database' | 'user' | 'password' | 'linkTypes' | 'schema'>;
13
+ export declare const parseHost: (host?: string) => {
13
14
  host?: string | undefined;
14
15
  port?: string | undefined;
15
16
  isValid: boolean;
16
17
  };
17
- export declare const askSqlQuestions: (dbType: DBType, defaultAnswers?: Partial<SQLOptions>) => Promise<EditableSQLOptions>;
18
- export declare const sql2sdl: (dbType: DBType, { name, source, host, database, user, password, linkTypes, schema, onConflict, }: SQLOptions) => Promise<{
18
+ export declare const askSqlQuestions: (dbType: DBType, defaultAnswers?: Partial<Sql2SdlOptions>) => Promise<InteractiveSql2SdlOptions>;
19
+ export declare const sql2sdl: (dbType: DBType, { name, source, host, database, user, password, linkTypes, include, schema, onConflict, }: Sql2SdlOptions) => Promise<{
19
20
  error: string;
20
21
  } | {
21
22
  outPath: string;
@@ -6,7 +6,7 @@ const chalk = require("chalk");
6
6
  const inquirer = require("inquirer");
7
7
  const helpers_1 = require("./helpers");
8
8
  const constants_1 = require("../shared/constants");
9
- exports.parseHost = (host) => {
9
+ const parseHost = (host) => {
10
10
  if (!host) {
11
11
  return { host: undefined, port: undefined, isValid: false };
12
12
  }
@@ -35,12 +35,13 @@ exports.parseHost = (host) => {
35
35
  isValid: true,
36
36
  };
37
37
  };
38
- exports.askSqlQuestions = async (dbType, defaultAnswers = {}) => {
38
+ exports.parseHost = parseHost;
39
+ const askSqlQuestions = async (dbType, defaultAnswers = {}) => {
39
40
  let questions = [
40
41
  {
41
42
  name: 'host',
42
43
  message: 'What is your host?',
43
- validate: input => exports.parseHost(input).isValid || `Could not parse "${input}" as a hostname.`,
44
+ validate: input => (0, exports.parseHost)(input).isValid || `Could not parse "${input}" as a hostname.`,
44
45
  },
45
46
  {
46
47
  name: 'database',
@@ -59,8 +60,8 @@ exports.askSqlQuestions = async (dbType, defaultAnswers = {}) => {
59
60
  },
60
61
  {
61
62
  name: 'linkTypes',
62
- message: 'Automatically link types with @materializer whenever there is database support' +
63
- `\n ${chalk.dim('(https://stepzen.com/docs/features/linking-types)')}`,
63
+ message: `Automatically link types based on foreign key relationships using @materializer` +
64
+ `\n ${chalk.dim('(https://stepzen.com/docs/features/linking-types)')}`,
64
65
  type: 'confirm',
65
66
  default: false,
66
67
  },
@@ -73,12 +74,27 @@ exports.askSqlQuestions = async (dbType, defaultAnswers = {}) => {
73
74
  },
74
75
  ]);
75
76
  }
76
- return inquirer.prompt(helpers_1.overrideDefaults(questions, defaultAnswers));
77
+ return inquirer.prompt((0, helpers_1.overrideDefaults)(questions, defaultAnswers));
77
78
  };
78
- exports.sql2sdl = async (dbType, { name, source, host, database, user, password, linkTypes, schema, onConflict, }) => {
79
+ exports.askSqlQuestions = askSqlQuestions;
80
+ const sql2sdl = async (dbType, { name, source, host, database, user, password, linkTypes, include, schema, onConflict, }) => {
81
+ let inludeAsTableOptions;
82
+ switch (include) {
83
+ case 'tables-only':
84
+ inludeAsTableOptions = 'ONLYTABLES';
85
+ break;
86
+ case 'views-only':
87
+ inludeAsTableOptions = 'ONLYVIEWS';
88
+ break;
89
+ case 'tables-and-views':
90
+ inludeAsTableOptions = 'TABLESANDVIEWS';
91
+ break;
92
+ default:
93
+ inludeAsTableOptions = null;
94
+ }
79
95
  const effectiveName = name || dbType;
80
- const hostDetails = exports.parseHost(host);
81
- const response = await helpers_1.queryIntrospectionService(constants_1.STEPZEN_DBINTROSPECTION_SERVER_URL, {
96
+ const hostDetails = (0, exports.parseHost)(host);
97
+ const response = await (0, helpers_1.queryIntrospectionService)(constants_1.STEPZEN_DBINTROSPECTION_SERVER_URL, {
82
98
  operation: 'generateSDL',
83
99
  variables: {
84
100
  driver: {
@@ -111,6 +127,10 @@ exports.sql2sdl = async (dbType, { name, source, host, database, user, password,
111
127
  type: 'Boolean',
112
128
  value: !linkTypes,
113
129
  },
130
+ include: {
131
+ type: 'TableOptions',
132
+ value: inludeAsTableOptions,
133
+ },
114
134
  schema: {
115
135
  type: 'String',
116
136
  value: schema,
@@ -124,5 +144,12 @@ exports.sql2sdl = async (dbType, { name, source, host, database, user, password,
124
144
  if (response.error) {
125
145
  return { error: response.error };
126
146
  }
127
- return helpers_1.writeSdlAndConfig(effectiveName, source, onConflict, response);
147
+ return (0, helpers_1.writeSdlAndConfig)({
148
+ name: effectiveName,
149
+ source,
150
+ mergeTypes: true,
151
+ onConflict,
152
+ response,
153
+ });
128
154
  };
155
+ exports.sql2sdl = sql2sdl;