stepzen 0.15.0 → 0.16.0-beta.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.
package/README.md CHANGED
@@ -29,7 +29,7 @@ $ npm install -g stepzen
29
29
  $ stepzen COMMAND
30
30
  running command...
31
31
  $ stepzen (-v|--version|version)
32
- stepzen/0.15.0 darwin-x64 node-v14.19.1
32
+ stepzen/0.16.0-beta.0 darwin-x64 node-v14.19.1
33
33
  $ stepzen --help [COMMAND]
34
34
  USAGE
35
35
  $ stepzen COMMAND
@@ -94,9 +94,34 @@ OPTIONS
94
94
  -h, --help
95
95
  show CLI help
96
96
 
97
+ --db-database=db-database
98
+ [mysql, postgresql] name of database to import
99
+
100
+ --db-host=db-host
101
+ [mysql, postgresql] database host
102
+
103
+ --db-password=db-password
104
+ [mysql, postgresql] database password
105
+
106
+ --db-schema=db-schema
107
+ [postgresql] database schema
108
+
109
+ --db-user=db-user
110
+ [mysql, postgresql] database user name
111
+
97
112
  --dir=dir
98
113
  working directory
99
114
 
115
+ --header-param=header-param
116
+ [curl] specifies a parameter in a header value. Can be formed by taking a -H, --header flag and replacing the
117
+ variable part of the header value with a $paramName placeholder. Repeat this flag once for each header with a
118
+ parameter.
119
+
120
+ Example:
121
+ stepzen import curl https://example.com/api/customers \
122
+ -H "Authorization: apikey SecretAPIKeyValue" \
123
+ --header-param 'Authorization: apikey $apikey'
124
+
100
125
  --name=name
101
126
  subfolder inside the workspace folder to save the imported schema files, defaults to the imported schema name
102
127
 
@@ -2,15 +2,37 @@ import { flags } from '@oclif/command';
2
2
  import ZenCommand from '../shared/zen-command';
3
3
  export default class Import extends ZenCommand {
4
4
  static description: string;
5
+ static curlFlags: {
6
+ prefix: flags.IOptionFlag<string | undefined>;
7
+ 'query-name': flags.IOptionFlag<string | undefined>;
8
+ 'query-type': flags.IOptionFlag<string | undefined>;
9
+ 'path-params': flags.IOptionFlag<string | undefined>;
10
+ 'header-param': flags.IOptionFlag<string[]>;
11
+ };
12
+ static sqlFlags: {
13
+ 'db-host': flags.IOptionFlag<string | undefined>;
14
+ 'db-user': flags.IOptionFlag<string | undefined>;
15
+ 'db-password': flags.IOptionFlag<string | undefined>;
16
+ 'db-database': flags.IOptionFlag<string | undefined>;
17
+ };
18
+ static postgresqlFlags: {
19
+ 'db-schema': flags.IOptionFlag<string | undefined>;
20
+ };
5
21
  static flags: {
6
- dir: flags.IOptionFlag<string | undefined>;
7
- help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
8
- silent: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
9
- name: flags.IOptionFlag<string | undefined>;
22
+ 'db-schema': flags.IOptionFlag<string | undefined>;
23
+ 'db-host': flags.IOptionFlag<string | undefined>;
24
+ 'db-user': flags.IOptionFlag<string | undefined>;
25
+ 'db-password': flags.IOptionFlag<string | undefined>;
26
+ 'db-database': flags.IOptionFlag<string | undefined>;
10
27
  prefix: flags.IOptionFlag<string | undefined>;
11
28
  'query-name': flags.IOptionFlag<string | undefined>;
12
29
  'query-type': flags.IOptionFlag<string | undefined>;
13
30
  'path-params': flags.IOptionFlag<string | undefined>;
31
+ 'header-param': flags.IOptionFlag<string[]>;
32
+ dir: flags.IOptionFlag<string | undefined>;
33
+ help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
34
+ silent: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
35
+ name: flags.IOptionFlag<string | undefined>;
14
36
  'non-interactive': import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
15
37
  };
16
38
  static args: {
@@ -19,4 +41,5 @@ export default class Import extends ZenCommand {
19
41
  }[];
20
42
  static strict: boolean;
21
43
  run(): Promise<void>;
44
+ warnAboutIgnoredFlags: (schemas: string[], maybeIgnored: string[], relevantSchemas: string[]) => void;
22
45
  }
@@ -17,7 +17,24 @@ const zen_command_1 = require("../shared/zen-command");
17
17
  const init_1 = require("./init");
18
18
  const constants_1 = require("../shared/constants");
19
19
  const path_params_parser_1 = require("../shared/path-params-parser");
20
+ const header_params_parser_1 = require("../shared/header-params-parser");
20
21
  class Import extends zen_command_1.default {
22
+ constructor() {
23
+ super(...arguments);
24
+ // notify the user about any ignored flags
25
+ this.warnAboutIgnoredFlags = (schemas, maybeIgnored, relevantSchemas) => {
26
+ if (!schemas.some(schema => relevantSchemas.includes(schema))) {
27
+ maybeIgnored.forEach(flag => {
28
+ // eslint-disable-next-line no-prototype-builtins
29
+ if (command_1.flags.hasOwnProperty(flag)) {
30
+ this.log(chalk.gray(`The ${chalk.bold(`--${flag}`)} flag only applies when importing ${relevantSchemas
31
+ .map(schema => chalk.bold(schema))
32
+ .join(', ')}. It will be ignored now.`));
33
+ }
34
+ });
35
+ }
36
+ };
37
+ }
21
38
  async run() {
22
39
  const { args, argv, flags } = this.parse(Import);
23
40
  // Get a list of schemas you're asking for
@@ -41,6 +58,14 @@ class Import extends zen_command_1.default {
41
58
  throw new errors_1.CLIError(`Could not create a StepZen workspace in the ${flags.dir ? directory : 'current'} directory.\n` + error.message);
42
59
  }
43
60
  }
61
+ this.warnAboutIgnoredFlags(schemas, Object.keys(Import.curlFlags), ['curl']);
62
+ this.warnAboutIgnoredFlags(schemas, Object.keys(Import.sqlFlags), [
63
+ 'mysql',
64
+ 'postgresql',
65
+ ]);
66
+ this.warnAboutIgnoredFlags(schemas, Object.keys(Import.postgresqlFlags), [
67
+ 'postgresql',
68
+ ]);
44
69
  // Select an import execution flow:
45
70
  // - v1 with `stepzen/engines` and cloud function
46
71
  // - v2 with the graphqlize service
@@ -74,7 +99,8 @@ class Import extends zen_command_1.default {
74
99
  'StepZen API. curl syntax is supported so that you copy and paste a ' +
75
100
  'curl command instead of the URL.');
76
101
  console.log();
77
- curl2sdlOptions = Object.assign(Object.assign({}, fixedOptions), (await curl2sdl_1.askCurlQuestions(editableOptions)));
102
+ const curlAnswers = await curl2sdl_1.askCurlQuestions(editableOptions);
103
+ curl2sdlOptions = Object.assign(Object.assign(Object.assign({}, fixedOptions), curlAnswers), { headers: curlAnswers.curlArgs.headers });
78
104
  }
79
105
  else {
80
106
  // run non-interative
@@ -86,7 +112,15 @@ class Import extends zen_command_1.default {
86
112
  if ('error' in parsedPathParamsOrError) {
87
113
  throw new errors_1.CLIError(parsedPathParamsOrError.error);
88
114
  }
89
- curl2sdlOptions = Object.assign(Object.assign(Object.assign({}, fixedOptions), editableOptions), { pathParams: parsedPathParamsOrError, curlArgs: argsOrError });
115
+ const headersOrError = header_params_parser_1.makeHeaders(argsOrError.headers, flags['header-param']);
116
+ if ('error' in headersOrError) {
117
+ throw new errors_1.CLIError(headersOrError.error);
118
+ }
119
+ const maybeDuplicateParamsMessage = curl2sdl_1.makeDuplicateParamsMessage(headersOrError, parsedPathParamsOrError, argsOrError.url);
120
+ if (maybeDuplicateParamsMessage) {
121
+ throw new errors_1.CLIError(maybeDuplicateParamsMessage);
122
+ }
123
+ curl2sdlOptions = Object.assign(Object.assign(Object.assign({}, fixedOptions), editableOptions), { pathParams: parsedPathParamsOrError, headers: headersOrError, curlArgs: argsOrError });
90
124
  }
91
125
  core_1.CliUx.ux.action.start('Starting');
92
126
  const resultOrError = await curl2sdl_1.curl2sdl(curl2sdlOptions);
@@ -100,14 +134,24 @@ class Import extends zen_command_1.default {
100
134
  result = resultOrError.outPath;
101
135
  }
102
136
  else {
103
- ;
104
- ['prefix', 'query-type', 'query-name', 'path-params'].forEach(flag => {
105
- if (flag in flags) {
106
- this.log(chalk.gray(`The ${chalk.bold(`--${flag}`)} flag only applies when importing ${chalk.bold('curl')}. It will be ignored now.`));
107
- }
108
- });
137
+ // Map flag names to the properties defined for sql engines in:
138
+ // https://github.com/steprz/generator-engines/blob/main/generator/src/shared/sql.ts
139
+ // If/when the number of property-to-answer mappings increase, create a dictionary
140
+ // { schema: { flag: field } } and build the below map based on this (a
141
+ // dictionary also enables a generic solution to the warning about ignored flags).
142
+ const preAnsweredForDBs = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (flags['db-host'] === undefined ? {} : { host: flags['db-host'] })), (flags['db-user'] === undefined ? {} : { user: flags['db-user'] })), (flags['db-password'] === undefined
143
+ ? {}
144
+ : { password: flags['db-password'] })), (flags['db-database'] === undefined
145
+ ? {}
146
+ : { database: flags['db-database'] })), (flags['db-schema'] === undefined
147
+ ? {}
148
+ : { schema: flags['db-schema'] }));
149
+ const preAnswered = {
150
+ mysql: preAnsweredForDBs,
151
+ postgresql: preAnsweredForDBs,
152
+ };
109
153
  // Let's go!
110
- result = await generate_1.default(schemas, flags.name, workspace.schema);
154
+ result = await generate_1.default(schemas, flags.name, workspace.schema, preAnswered);
111
155
  // Validate
112
156
  await transpiler_1.validate(result, {
113
157
  extensions: await utils_1.getStepZenExtensions(),
@@ -123,18 +167,19 @@ class Import extends zen_command_1.default {
123
167
  }
124
168
  exports.default = Import;
125
169
  Import.description = 'Import a schema for an external data source or a API endpoint to your GraphQL API.';
126
- Import.flags = Object.assign(Object.assign({}, zen_command_1.default.flags), { dir: command_1.flags.string({ description: 'working directory' }), help: command_1.flags.help({ char: 'h' }), silent: command_1.flags.boolean({ hidden: true }), name: command_1.flags.string({
127
- description: 'subfolder inside the workspace folder to save the imported' +
128
- ' schema files, defaults to the imported schema name',
129
- }), prefix: command_1.flags.string({
170
+ Import.curlFlags = {
171
+ prefix: command_1.flags.string({
130
172
  description: '[curl] prefix to add every type in the generated schema.',
131
- }), 'query-name': command_1.flags.string({
173
+ }),
174
+ 'query-name': command_1.flags.string({
132
175
  description: '[curl] property name to add to the Query type as a way to' +
133
176
  ' access the imported cURL endpoint.',
134
- }), 'query-type': command_1.flags.string({
177
+ }),
178
+ 'query-type': command_1.flags.string({
135
179
  description: '[curl] name for the type returned by the cURL endpoint in the ' +
136
180
  `generated schema. The name specified by ${chalk.bold('--query-type')} is not prefixed by ${chalk.bold('--prefix')} if both flags are present.`,
137
- }), 'path-params': command_1.flags.string({
181
+ }),
182
+ 'path-params': command_1.flags.string({
138
183
  description: `[curl] specifies path parameters in the URL path.` +
139
184
  ` Can be formed by taking the original path and replacing the` +
140
185
  ` variable segments with ${chalk.bold('$paramName')} placeholders.` +
@@ -143,7 +188,42 @@ Import.flags = Object.assign(Object.assign({}, zen_command_1.default.flags), { d
143
188
  `\nstepzen import curl https://example.com/users/jane/posts/12` +
144
189
  ` --path-params` +
145
190
  ` '/users/${chalk.bold('$userId')}/posts/${chalk.bold('$postId')}'`,
146
- }) });
191
+ }),
192
+ 'header-param': command_1.flags.string({
193
+ description: `[curl] specifies a parameter in a header value.` +
194
+ ` Can be formed by taking a ${chalk.bold('-H, --header')} flag and replacing the` +
195
+ ` variable part of the header value with a ${chalk.bold('$paramName')} placeholder. Repeat this flag once for each header with a parameter.` +
196
+ `\n` +
197
+ `\nExample:` +
198
+ `\nstepzen import curl https://example.com/api/customers \\` +
199
+ `\n\t-H "Authorization: apikey SecretAPIKeyValue" \\` +
200
+ `\n\t--header-param 'Authorization: apikey ${chalk.bold('$apikey')}'`,
201
+ multiple: true,
202
+ }),
203
+ };
204
+ Import.sqlFlags = {
205
+ 'db-host': command_1.flags.string({
206
+ description: '[mysql, postgresql] database host',
207
+ }),
208
+ 'db-user': command_1.flags.string({
209
+ description: '[mysql, postgresql] database user name',
210
+ }),
211
+ 'db-password': command_1.flags.string({
212
+ description: '[mysql, postgresql] database password',
213
+ }),
214
+ 'db-database': command_1.flags.string({
215
+ description: '[mysql, postgresql] name of database to import',
216
+ }),
217
+ };
218
+ Import.postgresqlFlags = {
219
+ 'db-schema': command_1.flags.string({
220
+ description: '[postgresql] database schema',
221
+ }),
222
+ };
223
+ Import.flags = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, zen_command_1.default.flags), { dir: command_1.flags.string({ description: 'working directory' }), help: command_1.flags.help({ char: 'h' }), silent: command_1.flags.boolean({ hidden: true }), name: command_1.flags.string({
224
+ description: 'subfolder inside the workspace folder to save the imported' +
225
+ ' schema files, defaults to the imported schema name',
226
+ }) }), Import.curlFlags), Import.sqlFlags), Import.postgresqlFlags);
147
227
  Import.args = [
148
228
  {
149
229
  name: 'schemas',
@@ -1,5 +1,24 @@
1
1
  import { CurlArguments } from '../shared/curl-parser';
2
2
  import { PathParam } from '../shared/path-params-parser';
3
+ export declare type NameValueHeaderInput = {
4
+ name: string;
5
+ value: string;
6
+ };
7
+ export declare type NamePartsHeaderInput = {
8
+ name: string;
9
+ parts: HeaderInputValuePart[];
10
+ };
11
+ export declare type HeaderInput = NameValueHeaderInput | NamePartsHeaderInput;
12
+ export declare type HeaderInputConstantValuePart = {
13
+ kind: 'Constant';
14
+ value: string;
15
+ };
16
+ export declare type HeaderInputVariableValuePart = {
17
+ kind: 'Variable';
18
+ value: string;
19
+ name: string;
20
+ };
21
+ export declare type HeaderInputValuePart = HeaderInputConstantValuePart | HeaderInputVariableValuePart;
3
22
  export declare type Curl2SdlOptions = {
4
23
  curlArgs: CurlArguments;
5
24
  name?: string;
@@ -8,6 +27,7 @@ export declare type Curl2SdlOptions = {
8
27
  rootType?: string;
9
28
  typePrefix?: string;
10
29
  pathParams: readonly PathParam[];
30
+ headers: readonly HeaderInput[];
11
31
  };
12
32
  export declare type EditableCurl2SdlOptions = Pick<Curl2SdlOptions, 'curlArgs' | 'queryName' | 'rootType' | 'typePrefix' | 'pathParams'>;
13
33
  export declare type CurlAnswers = {
@@ -17,8 +37,35 @@ export declare type CurlAnswers = {
17
37
  typePrefix: string;
18
38
  pathParams: string;
19
39
  };
40
+ export declare type CurlQueryParameter = {
41
+ name: string;
42
+ value: string;
43
+ context: string;
44
+ };
45
+ /**
46
+ * Collect together all query parameters from HTTP headers and from the
47
+ * pathname, and return them as a uniform list.
48
+ *
49
+ * @param {*} headers list of curl headers, possibly with parameters
50
+ * @param {*} pathParams list of path parameters
51
+ * @param {*} pathname full pathname of the REST endpoint
52
+ * @returns {*} combined list of query parameters in a uniform format
53
+ */
54
+ export declare const compileParameterList: (headers: HeaderInput[], pathParams: PathParam[], pathname: string) => CurlQueryParameter[];
55
+ /**
56
+ * Check the header and path parameters for duplicates, and construct a
57
+ * user-friendly error message describing identified problems (if any).
58
+ * If no problems are found, return `null`.
59
+ *
60
+ * @param {*} headers list of curl headers, possibly with parameters
61
+ * @param {*} pathParams list of path parameters
62
+ * @param {*} url full URL of the REST endpoint
63
+ * @returns {*} a message describing duplicate query parameters, or null if
64
+ * there are no duplicates
65
+ */
66
+ export declare const makeDuplicateParamsMessage: (headers: HeaderInput[], pathParams: PathParam[], url: string) => string | null;
20
67
  export declare const askCurlQuestions: (defaultAnswers?: Partial<CurlAnswers>) => Promise<EditableCurl2SdlOptions>;
21
- export declare const curl2sdl: ({ curlArgs, name, source, queryName, rootType, typePrefix, pathParams, }: Curl2SdlOptions) => Promise<{
68
+ export declare const curl2sdl: ({ curlArgs, name, source, queryName, rootType, typePrefix, pathParams, headers, }: Curl2SdlOptions) => Promise<{
22
69
  error: string;
23
70
  } | {
24
71
  outPath: string;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // Copyright (c) 2020,2021,2022, StepZen, Inc.
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.curl2sdl = exports.askCurlQuestions = void 0;
4
+ exports.curl2sdl = exports.askCurlQuestions = exports.makeDuplicateParamsMessage = exports.compileParameterList = void 0;
5
5
  const errors_1 = require("@oclif/errors");
6
6
  const chalk = require("chalk");
7
7
  const fs = require("fs-extra");
@@ -18,6 +18,84 @@ const curl_parser_1 = require("../shared/curl-parser");
18
18
  const path_params_parser_1 = require("../shared/path-params-parser");
19
19
  const constants_1 = require("../shared/constants");
20
20
  const errors_2 = require("../shared/errors");
21
+ /**
22
+ * Collect together all query parameters from HTTP headers and from the
23
+ * pathname, and return them as a uniform list.
24
+ *
25
+ * @param {*} headers list of curl headers, possibly with parameters
26
+ * @param {*} pathParams list of path parameters
27
+ * @param {*} pathname full pathname of the REST endpoint
28
+ * @returns {*} combined list of query parameters in a uniform format
29
+ */
30
+ exports.compileParameterList = (headers, pathParams, pathname) => {
31
+ // Drop empty segments, including empty string before the leading slash
32
+ const pathSegments = pathname.split('/').filter(Boolean);
33
+ // For each header, make a list of the parameters it contains.
34
+ // `flatMap()` concatenates each header's param lists into a single list.
35
+ return lodash_1.flatMap(headers, header => {
36
+ // skip headers that don't contain parameters
37
+ if (!('parts' in header)) {
38
+ return [];
39
+ }
40
+ // Reconstruct the full header string (for the context).
41
+ const fullHeader = `${header.name}: ${header.parts
42
+ .map(part => part.value)
43
+ .join('')}`;
44
+ // Filter out the 'Variable' parts of the header value, and convert them
45
+ // to the `CurlyQueryParameter` structure.
46
+ return header.parts
47
+ .map(part => part.kind === 'Variable'
48
+ ? {
49
+ name: part.name,
50
+ value: part.value,
51
+ context: `'${header.name}' header ${chalk.dim(`(${fullHeader})`)}`,
52
+ }
53
+ : null)
54
+ .filter(Boolean); // remove nulls
55
+ }).concat(
56
+ // Append the path parameters to the list, converting them to
57
+ // the `CurlyQueryParameter` structure as well.
58
+ pathParams.map(param => ({
59
+ name: param.name,
60
+ value: pathSegments[param.index],
61
+ context: `pathname ${chalk.dim(`(${pathname})`)}`,
62
+ })));
63
+ };
64
+ /**
65
+ * Check the header and path parameters for duplicates, and construct a
66
+ * user-friendly error message describing identified problems (if any).
67
+ * If no problems are found, return `null`.
68
+ *
69
+ * @param {*} headers list of curl headers, possibly with parameters
70
+ * @param {*} pathParams list of path parameters
71
+ * @param {*} url full URL of the REST endpoint
72
+ * @returns {*} a message describing duplicate query parameters, or null if
73
+ * there are no duplicates
74
+ */
75
+ exports.makeDuplicateParamsMessage = (headers, pathParams, url) => {
76
+ // Create a uniform list of query parameters from the headers and path
77
+ const parameters = exports.compileParameterList(headers, pathParams, new URL(url).pathname);
78
+ const errors = Object.entries(lodash_1.groupBy(parameters, 'name'))
79
+ // Create groups for each unique parameter name,
80
+ // and then sub-groups for each unique [name, value] tuple.
81
+ .map(([name, group]) => ({
82
+ name,
83
+ values: Object.entries(lodash_1.groupBy(group, 'value')),
84
+ }))
85
+ // ignore the [name, value] tuples that occur only once
86
+ .filter(({ values }) => values.length > 1)
87
+ // for the rest, create a message describing the duplicates
88
+ .map(({ name, values }) => `The parameter ${chalk.bold(`$${name}`)} is used for ${values.length} different values:` +
89
+ `\n${values
90
+ .map(([value, params], i) => `\t${i + 1}: '${value}' in the ${params[0].context}`)
91
+ .join('\n')}`);
92
+ if (errors.length > 0) {
93
+ return ('Could not use the same name for different parameters.\n' +
94
+ errors.join('\n') +
95
+ '\nPlease give a different parameter name for each variable value.');
96
+ }
97
+ return null;
98
+ };
21
99
  exports.askCurlQuestions = async (defaultAnswers = {}) => {
22
100
  let questions = [
23
101
  {
@@ -73,7 +151,7 @@ exports.askCurlQuestions = async (defaultAnswers = {}) => {
73
151
  pathParams: parsedPathParamsOrError,
74
152
  };
75
153
  };
76
- exports.curl2sdl = async ({ curlArgs, name, source, queryName, rootType, typePrefix, pathParams, }) => {
154
+ exports.curl2sdl = async ({ curlArgs, name, source, queryName, rootType, typePrefix, pathParams, headers, }) => {
77
155
  let json;
78
156
  try {
79
157
  const url = `${constants_1.STEPZEN_JSON2SDL_SERVER_URL}/api/graphql`;
@@ -106,7 +184,7 @@ exports.curl2sdl = async ({ curlArgs, name, source, queryName, rootType, typePre
106
184
  queryName: queryName || null,
107
185
  rootType: rootType || null,
108
186
  typePrefix: typePrefix || null,
109
- headers: curlArgs.headers.length > 0 ? curlArgs.headers : null,
187
+ headers: headers.length > 0 ? headers : null,
110
188
  data: curlArgs.data || null,
111
189
  method: curlArgs.method,
112
190
  pathParams: pathParams.length > 0 ? pathParams : null,
@@ -121,15 +121,13 @@ exports.askGeneratorQuestions = async (id, settings, state) => {
121
121
  var _a, _b;
122
122
  let status = -1;
123
123
  do {
124
- if (settings.questions.length === 0) {
125
- // would cause a hot loop, so it's an error
126
- throw new errors_1.CLIError(errors_2.PERMANENT_STEPZEN_ERROR);
127
- }
128
- const questions = settings.questions.map((question) => (Object.assign(Object.assign({ type: 'password' }, question), {
129
- // set the previous iteration's answer as the default value, except for password fields
130
- default: question.type && question.type !== 'password'
131
- ? lodash_1.get(state, question.name)
132
- : undefined })));
124
+ const questions = settings.questions.map((question) => {
125
+ return Object.assign(Object.assign({ type: 'password' }, question), {
126
+ // set the previous iteration's answer as the default value, except for password fields
127
+ default: question.type && question.type !== 'password'
128
+ ? lodash_1.get(state, question.name)
129
+ : undefined });
130
+ });
133
131
  // eslint-disable-next-line no-await-in-loop
134
132
  const answers = await inquirer.prompt(questions);
135
133
  state = lodash_1.merge(state, answers);
@@ -142,7 +140,12 @@ exports.askGeneratorQuestions = async (id, settings, state) => {
142
140
  if (result.status === -1 && result.questions.length === 0) {
143
141
  console.log();
144
142
  console.log(chalk.red(`A problem occurred when running ${id} import${((_a = result.errors) === null || _a === void 0 ? void 0 : _a.error) ? `: "${(_b = result.errors) === null || _b === void 0 ? void 0 : _b.error}"` : '.'}`));
145
- console.log('Please try again');
143
+ console.log('Please try again and check command-line parameters');
144
+ if (questions.length === 0) {
145
+ // all questions are pre-answered, so there is no chance to save the
146
+ // situation interactively => don't loop
147
+ throw new errors_1.CLIError('Unable to import');
148
+ }
146
149
  }
147
150
  else {
148
151
  settings = {
@@ -1,2 +1,6 @@
1
- declare const _default: (schemas: any, name: string | undefined, source: string) => Promise<string>;
1
+ declare const _default: (schemas: any, name: string | undefined, source: string, preAnswered?: {
2
+ [schema: string]: {
3
+ [question: string]: string;
4
+ };
5
+ }) => Promise<string>;
2
6
  export default _default;
@@ -10,7 +10,7 @@ const os = require("os");
10
10
  const path = require("path");
11
11
  const transpiler_1 = require("@stepzen/transpiler");
12
12
  const helpers_1 = require("./helpers");
13
- exports.default = async (schemas, name, source) => {
13
+ exports.default = async (schemas, name, source, preAnswered = {}) => {
14
14
  var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
15
15
  var _e;
16
16
  // Store the generators
@@ -18,15 +18,19 @@ exports.default = async (schemas, name, source) => {
18
18
  for (const schema of schemas) {
19
19
  generators[schema] = null;
20
20
  }
21
- // Store the answers
22
- let answers = {};
21
+ // Initial answers from flags. Assumption: <schema> -> <schema>_config
22
+ const initialAnswers = {};
23
+ Object.keys(generators).forEach(id => {
24
+ initialAnswers[`${id}_config`] = preAnswered[id] || {};
25
+ });
26
+ let answers = initialAnswers;
23
27
  // Start downloading
24
28
  core_1.CliUx.ux.action.start('Downloading from StepZen...');
25
29
  try {
26
30
  // Get all generators from...Generators
27
31
  for (var _f = tslib_1.__asyncValues(Object.keys(generators)), _g; _g = await _f.next(), !_g.done;) {
28
32
  const id = _g.value;
29
- const configure = await helpers_1.getConfiguration(id, {});
33
+ const configure = await helpers_1.getConfiguration(id, answers);
30
34
  if (configure) {
31
35
  generators[id] = {
32
36
  questions: configure.questions,
@@ -1,30 +1,26 @@
1
- /**
2
- * Parse a header string according to https://curl.se/docs/manpage.html#-H
3
- * and https://datatracker.ietf.org/doc/html/rfc2616#section-4.2
4
- *
5
- * @param {*} header a curl header string, e.g. `"api-key: asfdasdfad"`
6
- * @returns {*} a name/value record or
7
- * `null` for the `Header:` notation that means "remove this header" in
8
- * the cURL spec or a error object if cannot parse the string.
9
- */
10
- export declare const parseCurlHeaderString: (header: string) => {
1
+ export interface CurlHeader {
11
2
  name: string;
12
3
  value: string;
13
- } | null | {
14
- error: string;
15
- };
4
+ }
16
5
  export interface CurlArguments {
17
6
  url: string;
18
7
  method: 'Get' | 'Post';
19
- headers: Array<{
20
- name: string;
21
- value: string;
22
- }>;
8
+ headers: CurlHeader[];
23
9
  data?: string;
24
10
  }
25
11
  export interface ParseError {
26
12
  error: string;
27
13
  }
14
+ /**
15
+ * Parse a header string according to https://curl.se/docs/manpage.html#-H
16
+ * and https://datatracker.ietf.org/doc/html/rfc2616#section-4.2
17
+ *
18
+ * @param {*} header a curl header string, e.g. `"api-key: asfdasdfad"`
19
+ * @returns {*} a name/value record or
20
+ * `null` for the `Header:` notation that means "remove this header" in
21
+ * the cURL spec or a error object if cannot parse the string.
22
+ */
23
+ export declare const parseCurlHeaderString: (header: string) => CurlHeader | null | ParseError;
28
24
  /**
29
25
  * Parse a curl command line arguments array to a JSON structure consumable by
30
26
  * the StepZen introspection service backend.
@@ -26,7 +26,8 @@ exports.parseCurlHeaderString = (header) => {
26
26
  return null;
27
27
  }
28
28
  // Check if it's a `Header;` case
29
- if (trimmed.indexOf(';') === trimmed.length - 1) {
29
+ if (trimmed.indexOf(':') === -1 &&
30
+ trimmed.indexOf(';') === trimmed.length - 1) {
30
31
  return {
31
32
  name: trimmed.substring(0, trimmed.length - 1).trim(),
32
33
  value: '',
@@ -0,0 +1,7 @@
1
+ import { HeaderInput } from '../generate/curl2sdl';
2
+ import { ParseError, CurlHeader } from './curl-parser';
3
+ export declare const parseHeaderParam: (headers: readonly CurlHeader[], headerParam: string) => {
4
+ header: HeaderInput;
5
+ remainingHeaders: CurlHeader[];
6
+ } | ParseError;
7
+ export declare const makeHeaders: (curlHeaders: readonly CurlHeader[], headerParams?: readonly string[]) => ParseError | HeaderInput[];
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ // Copyright (c) 2020,2021,2022, StepZen, Inc.
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.makeHeaders = exports.parseHeaderParam = void 0;
5
+ const chalk = require("chalk");
6
+ const debug = require("debug");
7
+ const curl_parser_1 = require("./curl-parser");
8
+ const headerParamRegex = /^(?<prefix>([^$]|\$\$)*)(?<param>\$[_A-Za-z]\w*);?(?<suffix>.*)$/;
9
+ exports.parseHeaderParam = (headers, headerParam) => {
10
+ const headerOrError = curl_parser_1.parseCurlHeaderString(headerParam);
11
+ if (!headerOrError || 'error' in headerOrError) {
12
+ if (headerOrError) {
13
+ debug('stepzen:curl2sdl')(`Failed to parse a header param ${headerParam}.` +
14
+ ` Error: ${headerOrError.error}`);
15
+ }
16
+ return {
17
+ error: `Could not find a header name in` +
18
+ ` ${chalk.bold(`--header-param '${headerParam}'`)}.`,
19
+ };
20
+ }
21
+ const { name, value } = headerOrError;
22
+ const paramValueMatches = value.match(headerParamRegex);
23
+ if (!paramValueMatches || !paramValueMatches.groups) {
24
+ return {
25
+ error: `Could not find a $-prefixed parameter name in` +
26
+ ` ${chalk.bold(`--header-param '${headerParam}'`)}.` +
27
+ ` Did you use single quotes to prevent shell variable expansion?`,
28
+ };
29
+ }
30
+ const prefix = paramValueMatches.groups.prefix.replace(/\$\$/g, '$');
31
+ const paramName = paramValueMatches.groups.param.substring(1);
32
+ const suffix = paramValueMatches.groups.suffix.replace(/\$\$/g, '$');
33
+ if (suffix.match(headerParamRegex)) {
34
+ return {
35
+ error: `StepZen CLI currently supports at max 1 parameter per header` +
36
+ ` ${chalk.bold(`--header-param '${headerParam}'`)} has several.`,
37
+ };
38
+ }
39
+ const candidates = headers.filter(h => h.name.toLowerCase() === name.toLowerCase());
40
+ if (candidates.length === 0) {
41
+ return {
42
+ error: `Could not find a matching '-H, --header' curl flag for` +
43
+ ` ${chalk.bold(`--header-param '${headerParam}'`)}.` +
44
+ ` No header matches the name ${name}.`,
45
+ };
46
+ }
47
+ const matches = candidates.filter(({ value }) => value.startsWith(prefix) &&
48
+ value.substring(prefix.length).endsWith(suffix));
49
+ if (matches.length === 0) {
50
+ return {
51
+ error: `Could not find a matching '-H, --header' curl flag for` +
52
+ ` ${chalk.bold(`--header-param '${headerParam}'`)}.` +
53
+ (candidates.length > 1
54
+ ? ` None of the ${name} headers matches the '${value}' pattern.`
55
+ : ` The ${name} header does not match the '${value}' pattern.`),
56
+ };
57
+ }
58
+ if (matches.length > 1) {
59
+ debug('stepzen:curl2sdl')(`Ambiguous --header-param '${headerParam}'. Matched headers:` +
60
+ `\n${matches
61
+ .map(header => `\t-H '${header.name}: ${header.value}'`)
62
+ .join('\n')}` +
63
+ `\nUsing the first match.`);
64
+ }
65
+ const asConstantHeaderValuePart = (value) => ({
66
+ kind: 'Constant',
67
+ value,
68
+ });
69
+ const asVariableHeaderValuePart = (value, name) => ({
70
+ kind: 'Variable',
71
+ value,
72
+ name,
73
+ });
74
+ return {
75
+ header: {
76
+ name: matches[0].name,
77
+ parts: [
78
+ ...(prefix
79
+ ? [asConstantHeaderValuePart(prefix)]
80
+ : [
81
+ /* spreading an empty array is a no-op */
82
+ ]),
83
+ asVariableHeaderValuePart(matches[0].value.substring(prefix.length, matches[0].value.length - suffix.length), paramName),
84
+ ...(suffix
85
+ ? [asConstantHeaderValuePart(suffix)]
86
+ : [
87
+ /* spreading an empty array is a no-op */
88
+ ]),
89
+ ],
90
+ },
91
+ // assume each --header is referenced by at most one --header-param
92
+ remainingHeaders: headers.filter(h => h !== matches[0]),
93
+ };
94
+ };
95
+ exports.makeHeaders = (curlHeaders, headerParams = []) => {
96
+ const headers = [];
97
+ let remainingCurlHeaders = curlHeaders;
98
+ for (const headerParam of headerParams) {
99
+ const resultOrError = exports.parseHeaderParam(remainingCurlHeaders, headerParam);
100
+ if ('error' in resultOrError) {
101
+ return resultOrError;
102
+ }
103
+ headers.push(resultOrError.header);
104
+ remainingCurlHeaders = resultOrError.remainingHeaders;
105
+ }
106
+ headers.push(...remainingCurlHeaders);
107
+ return headers;
108
+ };
@@ -1 +1 @@
1
- {"version":"0.15.0","commands":{"deploy":{"id":"deploy","description":"deploy to stepzen","pluginName":"stepzen","pluginType":"core","aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"configurationsets":{"name":"configurationsets","type":"option","description":"Configurationsets to use","default":""},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"schema":{"name":"schema","type":"option","description":"Schema to use","required":true},"silent":{"name":"silent","type":"boolean","allowNo":false}},"args":[{"name":"destination","description":"destination","required":true}]},"import":{"id":"import","description":"Import a schema for an external data source or a API endpoint to your GraphQL API.","pluginName":"stepzen","pluginType":"core","aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"dir":{"name":"dir","type":"option","description":"working directory"},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"silent":{"name":"silent","type":"boolean","hidden":true,"allowNo":false},"name":{"name":"name","type":"option","description":"subfolder inside the workspace folder to save the imported schema files, defaults to the imported schema name"},"prefix":{"name":"prefix","type":"option","description":"[curl] prefix to add every type in the generated schema."},"query-name":{"name":"query-name","type":"option","description":"[curl] property name to add to the Query type as a way to access the imported cURL endpoint."},"query-type":{"name":"query-type","type":"option","description":"[curl] name for the type returned by the cURL endpoint in the generated schema. The name specified by --query-type is not prefixed by --prefix if both flags are present."},"path-params":{"name":"path-params","type":"option","description":"[curl] specifies path parameters in the URL path. Can be formed by taking the original path and replacing the variable segments with $paramName placeholders.\n\nExample:\nstepzen import curl https://example.com/users/jane/posts/12 --path-params '/users/$userId/posts/$postId'"}},"args":[{"name":"schemas","required":true}]},"init":{"id":"init","description":"stepzen init","pluginName":"stepzen","pluginType":"core","hidden":true,"aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"endpoint":{"name":"endpoint","type":"option","hidden":true},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"yes":{"name":"yes","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"directory","hidden":true}]},"lint":{"id":"lint","description":"stepzen lint","pluginName":"stepzen","pluginType":"core","hidden":true,"aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"dir":{"name":"dir","type":"option","hidden":true},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"list":{"id":"list","description":"list your items","pluginName":"stepzen","pluginType":"core","aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"type","description":"type","required":true,"options":["configurationsets","schemas"]}]},"login":{"id":"login","description":"Log in to StepZen","pluginName":"stepzen","pluginType":"core","aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"account":{"name":"account","type":"option","char":"a","hidden":true},"adminkey":{"name":"adminkey","type":"option","char":"k","hidden":true},"public":{"name":"public","type":"boolean","description":"Create a public anonymous StepZen account and use it. This is handy for trying StepZen out, but it not suitable for handling private data as all endpoints created with a public account will be public.","allowNo":false},"config":{"name":"config","type":"option","hidden":true},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"logout":{"id":"logout","description":"log out of stepzen","pluginName":"stepzen","pluginType":"core","aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"start":{"id":"start","description":"upload and deploy your schema","pluginName":"stepzen","pluginType":"core","aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"dir":{"name":"dir","type":"option","description":"working directory"},"endpoint":{"name":"endpoint","type":"option","description":"Override workspace endpoint"},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"no-console":{"name":"no-console","type":"boolean","hidden":true,"allowNo":false},"no-dashboard":{"name":"no-dashboard","type":"boolean","hidden":true,"allowNo":false},"no-init":{"name":"no-init","type":"boolean","hidden":true,"allowNo":false},"no-server":{"name":"no-server","type":"boolean","hidden":true,"allowNo":false},"no-validate":{"name":"no-validate","type":"boolean","hidden":true,"allowNo":false},"no-watcher":{"name":"no-watcher","type":"boolean","hidden":true,"allowNo":false},"port":{"name":"port","type":"option","default":5001}},"args":[]},"transpile":{"id":"transpile","description":"transpile a graphql schema","pluginName":"stepzen","pluginType":"core","hidden":true,"aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"config":{"name":"config","type":"option","hidden":true},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"hide-output":{"name":"hide-output","type":"boolean","hidden":true,"allowNo":false},"inspect":{"name":"inspect","type":"boolean","char":"i","hidden":true,"allowNo":false},"inspect-after":{"name":"inspect-after","type":"boolean","hidden":true,"allowNo":false},"output-configuration":{"name":"output-configuration","type":"boolean","allowNo":false},"silent":{"name":"silent","type":"boolean","allowNo":false}},"args":[{"name":"folder","required":true}]},"upload":{"id":"upload","description":"upload to stepzen","pluginName":"stepzen","pluginType":"core","aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"dir":{"name":"dir","type":"option","description":"A directory to upload"},"file":{"name":"file","type":"option","description":"A file to upload"},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"silent":{"name":"silent","type":"boolean","allowNo":false}},"args":[{"name":"type","description":"type","required":true,"options":["configurationset","schema"]},{"name":"destination","description":"destination","required":true}]},"validate":{"id":"validate","description":"validate a graphql schema","pluginName":"stepzen","pluginType":"core","hidden":true,"aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"folder","required":true}]},"whoami":{"id":"whoami","description":"stepzen whoami","pluginName":"stepzen","pluginType":"core","hidden":true,"aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"showkeys":{"name":"showkeys","type":"boolean","allowNo":false},"apikey":{"name":"apikey","type":"boolean","allowNo":false},"adminkey":{"name":"adminkey","type":"boolean","allowNo":false}},"args":[]}}}
1
+ {"version":"0.16.0-beta.0","commands":{"deploy":{"id":"deploy","description":"deploy to stepzen","pluginName":"stepzen","pluginType":"core","aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"configurationsets":{"name":"configurationsets","type":"option","description":"Configurationsets to use","default":""},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"schema":{"name":"schema","type":"option","description":"Schema to use","required":true},"silent":{"name":"silent","type":"boolean","allowNo":false}},"args":[{"name":"destination","description":"destination","required":true}]},"import":{"id":"import","description":"Import a schema for an external data source or a API endpoint to your GraphQL API.","pluginName":"stepzen","pluginType":"core","aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"dir":{"name":"dir","type":"option","description":"working directory"},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"silent":{"name":"silent","type":"boolean","hidden":true,"allowNo":false},"name":{"name":"name","type":"option","description":"subfolder inside the workspace folder to save the imported schema files, defaults to the imported schema name"},"prefix":{"name":"prefix","type":"option","description":"[curl] prefix to add every type in the generated schema."},"query-name":{"name":"query-name","type":"option","description":"[curl] property name to add to the Query type as a way to access the imported cURL endpoint."},"query-type":{"name":"query-type","type":"option","description":"[curl] name for the type returned by the cURL endpoint in the generated schema. The name specified by --query-type is not prefixed by --prefix if both flags are present."},"path-params":{"name":"path-params","type":"option","description":"[curl] specifies path parameters in the URL path. Can be formed by taking the original path and replacing the variable segments with $paramName placeholders.\n\nExample:\nstepzen import curl https://example.com/users/jane/posts/12 --path-params '/users/$userId/posts/$postId'"},"header-param":{"name":"header-param","type":"option","description":"[curl] specifies a parameter in a header value. Can be formed by taking a -H, --header flag and replacing the variable part of the header value with a $paramName placeholder. Repeat this flag once for each header with a parameter.\n\nExample:\nstepzen import curl https://example.com/api/customers \\\n\t-H \"Authorization: apikey SecretAPIKeyValue\" \\\n\t--header-param 'Authorization: apikey $apikey'"},"db-host":{"name":"db-host","type":"option","description":"[mysql, postgresql] database host"},"db-user":{"name":"db-user","type":"option","description":"[mysql, postgresql] database user name"},"db-password":{"name":"db-password","type":"option","description":"[mysql, postgresql] database password"},"db-database":{"name":"db-database","type":"option","description":"[mysql, postgresql] name of database to import"},"db-schema":{"name":"db-schema","type":"option","description":"[postgresql] database schema"}},"args":[{"name":"schemas","required":true}]},"init":{"id":"init","description":"stepzen init","pluginName":"stepzen","pluginType":"core","hidden":true,"aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"endpoint":{"name":"endpoint","type":"option","hidden":true},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"yes":{"name":"yes","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"directory","hidden":true}]},"lint":{"id":"lint","description":"stepzen lint","pluginName":"stepzen","pluginType":"core","hidden":true,"aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"dir":{"name":"dir","type":"option","hidden":true},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"list":{"id":"list","description":"list your items","pluginName":"stepzen","pluginType":"core","aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"type","description":"type","required":true,"options":["configurationsets","schemas"]}]},"login":{"id":"login","description":"Log in to StepZen","pluginName":"stepzen","pluginType":"core","aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"account":{"name":"account","type":"option","char":"a","hidden":true},"adminkey":{"name":"adminkey","type":"option","char":"k","hidden":true},"public":{"name":"public","type":"boolean","description":"Create a public anonymous StepZen account and use it. This is handy for trying StepZen out, but it not suitable for handling private data as all endpoints created with a public account will be public.","allowNo":false},"config":{"name":"config","type":"option","hidden":true},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"logout":{"id":"logout","description":"log out of stepzen","pluginName":"stepzen","pluginType":"core","aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"start":{"id":"start","description":"upload and deploy your schema","pluginName":"stepzen","pluginType":"core","aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"dir":{"name":"dir","type":"option","description":"working directory"},"endpoint":{"name":"endpoint","type":"option","description":"Override workspace endpoint"},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"no-console":{"name":"no-console","type":"boolean","hidden":true,"allowNo":false},"no-dashboard":{"name":"no-dashboard","type":"boolean","hidden":true,"allowNo":false},"no-init":{"name":"no-init","type":"boolean","hidden":true,"allowNo":false},"no-server":{"name":"no-server","type":"boolean","hidden":true,"allowNo":false},"no-validate":{"name":"no-validate","type":"boolean","hidden":true,"allowNo":false},"no-watcher":{"name":"no-watcher","type":"boolean","hidden":true,"allowNo":false},"port":{"name":"port","type":"option","default":5001}},"args":[]},"transpile":{"id":"transpile","description":"transpile a graphql schema","pluginName":"stepzen","pluginType":"core","hidden":true,"aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"config":{"name":"config","type":"option","hidden":true},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"hide-output":{"name":"hide-output","type":"boolean","hidden":true,"allowNo":false},"inspect":{"name":"inspect","type":"boolean","char":"i","hidden":true,"allowNo":false},"inspect-after":{"name":"inspect-after","type":"boolean","hidden":true,"allowNo":false},"output-configuration":{"name":"output-configuration","type":"boolean","allowNo":false},"silent":{"name":"silent","type":"boolean","allowNo":false}},"args":[{"name":"folder","required":true}]},"upload":{"id":"upload","description":"upload to stepzen","pluginName":"stepzen","pluginType":"core","aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"dir":{"name":"dir","type":"option","description":"A directory to upload"},"file":{"name":"file","type":"option","description":"A file to upload"},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"silent":{"name":"silent","type":"boolean","allowNo":false}},"args":[{"name":"type","description":"type","required":true,"options":["configurationset","schema"]},{"name":"destination","description":"destination","required":true}]},"validate":{"id":"validate","description":"validate a graphql schema","pluginName":"stepzen","pluginType":"core","hidden":true,"aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"folder","required":true}]},"whoami":{"id":"whoami","description":"stepzen whoami","pluginName":"stepzen","pluginType":"core","hidden":true,"aliases":[],"flags":{"non-interactive":{"name":"non-interactive","type":"boolean","description":"disable all interactive prompts","hidden":true,"allowNo":false},"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"showkeys":{"name":"showkeys","type":"boolean","allowNo":false},"apikey":{"name":"apikey","type":"boolean","allowNo":false},"adminkey":{"name":"adminkey","type":"boolean","allowNo":false}},"args":[]}}}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "stepzen",
3
3
  "description": "The StepZen CLI",
4
- "version": "0.15.0",
4
+ "version": "0.16.0-beta.0",
5
5
  "license": "MIT",
6
6
  "author": "Darren Waddell <darren@stepzen.com>",
7
7
  "contributors": [
@@ -99,6 +99,7 @@
99
99
  "semver": "^7.3.7",
100
100
  "sinon": "13.0.1",
101
101
  "sinon-chai": "3.7.0",
102
+ "strip-ansi": "^6.0.1",
102
103
  "ts-node": "^8.10.2",
103
104
  "typescript": "^3.9.7"
104
105
  },