stepzen 0.18.0 → 0.19.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 +1 -1
- package/lib/commands/import.d.ts +8 -0
- package/lib/commands/import.js +146 -108
- package/lib/generate/curl2sdl.d.ts +2 -4
- package/lib/generate/curl2sdl.js +4 -4
- package/lib/generate/graphql2sdl.d.ts +2 -4
- package/lib/generate/graphql2sdl.js +4 -5
- package/lib/generate/helpers.d.ts +3 -1
- package/lib/generate/helpers.js +10 -5
- package/lib/generate/index.d.ts +5 -3
- package/lib/generate/sql2sdl.d.ts +22 -0
- package/lib/generate/sql2sdl.js +128 -0
- package/lib/shared/constants.d.ts +1 -0
- package/lib/shared/constants.js +5 -3
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
package/lib/commands/import.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { flags } from '@oclif/command';
|
|
2
|
+
import type { CommonImportOptions } from '../generate';
|
|
2
3
|
import ZenCommand from '../shared/zen-command';
|
|
3
4
|
import { HeaderInput } from '../shared/header';
|
|
4
5
|
import { Workspace } from '../shared/types';
|
|
@@ -79,6 +80,10 @@ export default class Import extends ZenCommand {
|
|
|
79
80
|
}[];
|
|
80
81
|
static strict: boolean;
|
|
81
82
|
run(): Promise<void>;
|
|
83
|
+
importCurl(argv: string[], flags: any, fixedOptions: CommonImportOptions): Promise<string>;
|
|
84
|
+
importGraphQL(argv: string[], flags: any, fixedOptions: CommonImportOptions): Promise<string>;
|
|
85
|
+
importSql(schema: string, argv: string[], flags: any, fixedOptions: CommonImportOptions): Promise<string>;
|
|
86
|
+
importFromGeneratorEngines(schema: string, argv: string[], flags: any, fixedOptions: CommonImportOptions): Promise<string>;
|
|
82
87
|
ensureOnConflictBehavior(workspace: Workspace, schema: string, flags: ReturnType<Import['parseWorkaround']>['flags']): Promise<"overwrite" | "append">;
|
|
83
88
|
warnAboutIgnoredFlags(schema: string, usedFlags: {
|
|
84
89
|
[key: string]: any;
|
|
@@ -106,4 +111,7 @@ export default class Import extends ZenCommand {
|
|
|
106
111
|
[name: string]: any;
|
|
107
112
|
}>;
|
|
108
113
|
parseHeaderFlags(headerFlagValues?: string[], headerParamFlagValues?: string[]): HeaderInput[];
|
|
114
|
+
getSqlOptionsFromFlags(flags: any): {
|
|
115
|
+
[x: string]: any;
|
|
116
|
+
};
|
|
109
117
|
}
|
package/lib/commands/import.js
CHANGED
|
@@ -16,6 +16,7 @@ const curl2sdl_1 = require("../generate/curl2sdl");
|
|
|
16
16
|
const curl_parser_1 = require("../shared/curl-parser");
|
|
17
17
|
const zen_command_1 = require("../shared/zen-command");
|
|
18
18
|
const graphql2sdl_1 = require("../generate/graphql2sdl");
|
|
19
|
+
const sql2sdl_1 = require("../generate/sql2sdl");
|
|
19
20
|
const constants_1 = require("../shared/constants");
|
|
20
21
|
const path_params_parser_1 = require("../shared/path-params-parser");
|
|
21
22
|
const header_params_parser_1 = require("../shared/header-params-parser");
|
|
@@ -30,123 +31,28 @@ class Import extends zen_command_1.default {
|
|
|
30
31
|
// Define a sane onConflict behaviour (possibly interactive)
|
|
31
32
|
const onConflict = await this.ensureOnConflictBehavior(workspace, schema, flags);
|
|
32
33
|
this.warnAboutIgnoredFlags(schema, flags);
|
|
33
|
-
|
|
34
|
+
// Common options for all import schemas
|
|
35
|
+
const fixedOptions = {
|
|
36
|
+
name: flags.name,
|
|
37
|
+
source: workspace.schema,
|
|
38
|
+
onConflict,
|
|
39
|
+
};
|
|
34
40
|
// Select an import execution flow:
|
|
35
41
|
// - v1 with `stepzen/engines` and cloud function
|
|
36
42
|
// - v2 with the graphqlize service
|
|
37
43
|
let result;
|
|
38
44
|
if (schema === 'curl') {
|
|
39
|
-
|
|
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);
|
|
79
|
-
}
|
|
80
|
-
const maybeDuplicateParamsMessage = curl2sdl_1.makeDuplicateParamsMessage(headers, parsedPathParamsOrError, argsOrError.url);
|
|
81
|
-
if (maybeDuplicateParamsMessage) {
|
|
82
|
-
throw new errors_1.CLIError(maybeDuplicateParamsMessage);
|
|
83
|
-
}
|
|
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;
|
|
45
|
+
result = await this.importCurl(argv, flags, fixedOptions);
|
|
96
46
|
}
|
|
97
47
|
else if (schema === 'graphql') {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
let answers;
|
|
103
|
-
if (argv.length === 1) {
|
|
104
|
-
// interactive
|
|
105
|
-
answers = await graphql2sdl_1.askGraphQLQuestions(editableOptions);
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
// non-interactive
|
|
109
|
-
answers = Object.assign(Object.assign({}, editableOptions), { endpoint: argv[1] });
|
|
110
|
-
}
|
|
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();
|
|
124
|
-
}
|
|
125
|
-
result = resultOrError.outPath;
|
|
48
|
+
result = await this.importGraphQL(argv, flags, fixedOptions);
|
|
49
|
+
}
|
|
50
|
+
else if (process.env.STEPZEN_BYPASS_GENERATOR_ENGINES) {
|
|
51
|
+
result = await this.importSql(schema, argv, flags, fixedOptions);
|
|
126
52
|
}
|
|
127
53
|
else {
|
|
128
|
-
//
|
|
129
|
-
|
|
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']));
|
|
137
|
-
}
|
|
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
|
-
});
|
|
54
|
+
// Delegate the schema to generator-engines function
|
|
55
|
+
result = await this.importFromGeneratorEngines(schema, argv, flags, fixedOptions);
|
|
150
56
|
}
|
|
151
57
|
// Housekeeping
|
|
152
58
|
fs.copySync(result, workspace.schema);
|
|
@@ -154,6 +60,134 @@ class Import extends zen_command_1.default {
|
|
|
154
60
|
// Nice message
|
|
155
61
|
this.log(chalk.green(`Successfully imported schema ${chalk.bold(schema)} from StepZen`));
|
|
156
62
|
}
|
|
63
|
+
async importCurl(argv, flags, fixedOptions) {
|
|
64
|
+
const headers = this.parseHeaderFlags(flags.header, flags['header-param']);
|
|
65
|
+
// LATER: offload the check to the graphqlize service or fetch
|
|
66
|
+
// the list of supported data sources and compare agains it.
|
|
67
|
+
this.log(chalk.yellow(`NOTE: ${chalk.bold('stepzen import curl')} is a ${chalk.bold('new')} feature.`));
|
|
68
|
+
this.log(chalk.yellow('If you have any issues, please check if they have been addressed ' +
|
|
69
|
+
'in the latest version, or reach out to StepZen on Discord: ' +
|
|
70
|
+
constants_1.STEPZEN_DISCORD_URL));
|
|
71
|
+
let curl2sdlOptions;
|
|
72
|
+
const editableOptions = {
|
|
73
|
+
queryName: flags['query-name'],
|
|
74
|
+
rootType: flags['query-type'],
|
|
75
|
+
typePrefix: flags.prefix,
|
|
76
|
+
pathParams: flags['path-params'],
|
|
77
|
+
};
|
|
78
|
+
if (argv.length === 1) {
|
|
79
|
+
// no parameters given: start an interactive prompt
|
|
80
|
+
console.log();
|
|
81
|
+
console.log('This command introspects the response of a REST endpoint and generates' +
|
|
82
|
+
' a GraphQL schema allowing you to access this endpoint through your ' +
|
|
83
|
+
'StepZen API. curl syntax is supported so that you copy and paste a ' +
|
|
84
|
+
'curl command instead of the URL.');
|
|
85
|
+
console.log();
|
|
86
|
+
const curlAnswers = await curl2sdl_1.askCurlQuestions(editableOptions);
|
|
87
|
+
curl2sdlOptions = Object.assign(Object.assign(Object.assign({}, fixedOptions), curlAnswers), {
|
|
88
|
+
// include boths headers passed via flags and headers entered interactively
|
|
89
|
+
headers: headers.concat(curlAnswers.curlArgs.headers) });
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// run non-interative
|
|
93
|
+
const argsOrError = curl_parser_1.parseCurlArgv(argv);
|
|
94
|
+
if ('error' in argsOrError) {
|
|
95
|
+
throw new errors_1.CLIError(argsOrError.error);
|
|
96
|
+
}
|
|
97
|
+
const parsedPathParamsOrError = path_params_parser_1.parsePathParamsPattern(argsOrError.url, flags['path-params']);
|
|
98
|
+
if ('error' in parsedPathParamsOrError) {
|
|
99
|
+
throw new errors_1.CLIError(parsedPathParamsOrError.error);
|
|
100
|
+
}
|
|
101
|
+
const maybeDuplicateParamsMessage = curl2sdl_1.makeDuplicateParamsMessage(headers, parsedPathParamsOrError, argsOrError.url);
|
|
102
|
+
if (maybeDuplicateParamsMessage) {
|
|
103
|
+
throw new errors_1.CLIError(maybeDuplicateParamsMessage);
|
|
104
|
+
}
|
|
105
|
+
curl2sdlOptions = Object.assign(Object.assign(Object.assign({}, fixedOptions), editableOptions), { pathParams: parsedPathParamsOrError, headers: headers, curlArgs: argsOrError });
|
|
106
|
+
}
|
|
107
|
+
core_1.CliUx.ux.action.start('Starting');
|
|
108
|
+
const resultOrError = await curl2sdl_1.curl2sdl(curl2sdlOptions);
|
|
109
|
+
core_1.CliUx.ux.action.stop();
|
|
110
|
+
if ('error' in resultOrError) {
|
|
111
|
+
this.log('A problem occured while processing your import. ' +
|
|
112
|
+
'Please check that the given cURL command is valid.');
|
|
113
|
+
this.log(resultOrError.error);
|
|
114
|
+
this.exit();
|
|
115
|
+
}
|
|
116
|
+
return resultOrError.outPath;
|
|
117
|
+
}
|
|
118
|
+
async importGraphQL(argv, flags, fixedOptions) {
|
|
119
|
+
const headers = this.parseHeaderFlags(flags.header, flags['header-param']);
|
|
120
|
+
const editableOptions = {
|
|
121
|
+
typePrefix: flags.prefix,
|
|
122
|
+
headers: headers,
|
|
123
|
+
};
|
|
124
|
+
let answers;
|
|
125
|
+
if (argv.length === 1) {
|
|
126
|
+
// interactive
|
|
127
|
+
answers = await graphql2sdl_1.askGraphQLQuestions(editableOptions);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
// non-interactive
|
|
131
|
+
answers = Object.assign(Object.assign({}, editableOptions), { endpoint: argv[1] });
|
|
132
|
+
}
|
|
133
|
+
const options = Object.assign(Object.assign({}, fixedOptions), answers);
|
|
134
|
+
core_1.CliUx.ux.action.start('Starting');
|
|
135
|
+
const resultOrError = await graphql2sdl_1.graphql2sdl(options);
|
|
136
|
+
core_1.CliUx.ux.action.stop();
|
|
137
|
+
if ('error' in resultOrError) {
|
|
138
|
+
this.log('A problem occured while processing your import.');
|
|
139
|
+
this.log(resultOrError.error);
|
|
140
|
+
this.exit();
|
|
141
|
+
}
|
|
142
|
+
return resultOrError.outPath;
|
|
143
|
+
}
|
|
144
|
+
async importSql(schema, argv, flags, fixedOptions) {
|
|
145
|
+
if (!(schema === 'mysql' || schema === 'postgresql')) {
|
|
146
|
+
throw new errors_1.CLIError(`Schema "${schema}" not supported when the STEPZEN_BYPASS_GENERATOR_ENGINES feature flag is enabled; ` +
|
|
147
|
+
`if this is a legacy import schema, please run the command without the feature flag`);
|
|
148
|
+
}
|
|
149
|
+
const editableOptions = this.getSqlOptionsFromFlags(flags);
|
|
150
|
+
let answers;
|
|
151
|
+
if (editableOptions.host !== undefined &&
|
|
152
|
+
editableOptions.database !== undefined &&
|
|
153
|
+
editableOptions.user !== undefined &&
|
|
154
|
+
editableOptions.password !== undefined) {
|
|
155
|
+
// non-interactive
|
|
156
|
+
answers = editableOptions;
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
// interactive
|
|
160
|
+
answers = await sql2sdl_1.askSqlQuestions(schema, editableOptions);
|
|
161
|
+
}
|
|
162
|
+
const options = Object.assign(Object.assign({}, fixedOptions), answers);
|
|
163
|
+
core_1.CliUx.ux.action.start('Starting');
|
|
164
|
+
const resultOrError = await sql2sdl_1.sql2sdl(schema, options);
|
|
165
|
+
core_1.CliUx.ux.action.stop();
|
|
166
|
+
if ('error' in resultOrError) {
|
|
167
|
+
this.log('A problem occured while processing your import. ' +
|
|
168
|
+
'Please check that the given database details are valid.');
|
|
169
|
+
this.log(resultOrError.error);
|
|
170
|
+
this.exit();
|
|
171
|
+
}
|
|
172
|
+
return resultOrError.outPath;
|
|
173
|
+
}
|
|
174
|
+
async importFromGeneratorEngines(schema, argv, flags, fixedOptions) {
|
|
175
|
+
const preAnswered = {};
|
|
176
|
+
if (schema === 'mysql' || schema === 'postgresql') {
|
|
177
|
+
const sqlPreAnswered = this.getSqlOptionsFromFlags(flags);
|
|
178
|
+
if (Object.prototype.hasOwnProperty.call(sqlPreAnswered, 'linkTypes')) {
|
|
179
|
+
sqlPreAnswered.linkTypes = sqlPreAnswered.linkTypes ? 'Yes' : 'No';
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Let's go!
|
|
183
|
+
const result = await generate_1.default(Object.assign(Object.assign({}, fixedOptions), { schema,
|
|
184
|
+
preAnswered }));
|
|
185
|
+
// Validate
|
|
186
|
+
await transpiler_1.validate(result, {
|
|
187
|
+
extensions: await utils_1.getStepZenExtensions(),
|
|
188
|
+
});
|
|
189
|
+
return result;
|
|
190
|
+
}
|
|
157
191
|
async ensureOnConflictBehavior(workspace, schema, flags) {
|
|
158
192
|
const featureFlag = process.env.STEPZEN_DETECT_NAME_CONFLICTS;
|
|
159
193
|
if (featureFlag === undefined || featureFlag.toLowerCase() === 'false') {
|
|
@@ -276,6 +310,10 @@ class Import extends zen_command_1.default {
|
|
|
276
310
|
}
|
|
277
311
|
return headersOrError;
|
|
278
312
|
}
|
|
313
|
+
getSqlOptionsFromFlags(flags) {
|
|
314
|
+
const asKeyValue = (key, flag) => flag === undefined ? {} : { [key]: flag };
|
|
315
|
+
return 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'])), asKeyValue('schema', flags['db-schema']));
|
|
316
|
+
}
|
|
279
317
|
}
|
|
280
318
|
exports.default = Import;
|
|
281
319
|
Import.description = 'import a schema for an external data source or a API endpoint to your GraphQL API';
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { CurlArguments } from '../shared/curl-parser';
|
|
2
2
|
import { PathParam } from '../shared/path-params-parser';
|
|
3
3
|
import { HeaderInput } from '../shared/header';
|
|
4
|
-
|
|
4
|
+
import type { CommonImportOptions } from '.';
|
|
5
|
+
export declare type Curl2SdlOptions = CommonImportOptions & {
|
|
5
6
|
curlArgs: CurlArguments;
|
|
6
|
-
name?: string;
|
|
7
|
-
source: string;
|
|
8
7
|
queryName?: string;
|
|
9
8
|
rootType?: string;
|
|
10
9
|
typePrefix?: string;
|
|
11
10
|
pathParams: readonly PathParam[];
|
|
12
11
|
headers: readonly HeaderInput[];
|
|
13
|
-
onConflict: 'overwrite' | 'append';
|
|
14
12
|
};
|
|
15
13
|
export declare type EditableCurl2SdlOptions = Pick<Curl2SdlOptions, 'curlArgs' | 'queryName' | 'rootType' | 'typePrefix' | 'pathParams'>;
|
|
16
14
|
export declare type CurlAnswers = {
|
package/lib/generate/curl2sdl.js
CHANGED
|
@@ -9,6 +9,7 @@ const string_argv_1 = require("string-argv");
|
|
|
9
9
|
const curl_parser_1 = require("../shared/curl-parser");
|
|
10
10
|
const path_params_parser_1 = require("../shared/path-params-parser");
|
|
11
11
|
const helpers_1 = require("./helpers");
|
|
12
|
+
const constants_1 = require("../shared/constants");
|
|
12
13
|
/**
|
|
13
14
|
* Collect together all query parameters from HTTP headers and from the
|
|
14
15
|
* pathname, and return them as a uniform list.
|
|
@@ -88,7 +89,7 @@ exports.makeDuplicateParamsMessage = (headers, pathParams, url) => {
|
|
|
88
89
|
return null;
|
|
89
90
|
};
|
|
90
91
|
exports.askCurlQuestions = async (defaultAnswers = {}) => {
|
|
91
|
-
|
|
92
|
+
const questions = [
|
|
92
93
|
{
|
|
93
94
|
name: 'url',
|
|
94
95
|
message: 'Endpoint URL or a full curl command',
|
|
@@ -110,8 +111,7 @@ exports.askCurlQuestions = async (defaultAnswers = {}) => {
|
|
|
110
111
|
message: 'Prefix to add to all generated type names (leave blank to use defaults)',
|
|
111
112
|
},
|
|
112
113
|
];
|
|
113
|
-
|
|
114
|
-
const answers = await inquirer.prompt(questions);
|
|
114
|
+
const answers = await inquirer.prompt(helpers_1.overrideDefaults(questions, defaultAnswers));
|
|
115
115
|
const curlArgs = curl_parser_1.parseCurlArgv(string_argv_1.default(answers.url));
|
|
116
116
|
if ('error' in curlArgs) {
|
|
117
117
|
console.log();
|
|
@@ -143,7 +143,7 @@ exports.askCurlQuestions = async (defaultAnswers = {}) => {
|
|
|
143
143
|
};
|
|
144
144
|
};
|
|
145
145
|
exports.curl2sdl = async ({ curlArgs, name, source, queryName, rootType, typePrefix, pathParams, headers, onConflict, }) => {
|
|
146
|
-
const response = await helpers_1.queryIntrospectionService({
|
|
146
|
+
const response = await helpers_1.queryIntrospectionService(constants_1.STEPZEN_JSON2SDL_SERVER_URL, {
|
|
147
147
|
operation: 'getSDLFromCurl',
|
|
148
148
|
variables: {
|
|
149
149
|
command: {
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { HeaderInput } from '../shared/header';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
source: string;
|
|
2
|
+
import type { CommonImportOptions } from '.';
|
|
3
|
+
export declare type GraphQL2SdlOptions = CommonImportOptions & {
|
|
5
4
|
endpoint: string;
|
|
6
5
|
typePrefix?: string;
|
|
7
6
|
includeRootOperations?: boolean;
|
|
8
7
|
headers: readonly HeaderInput[];
|
|
9
|
-
onConflict: 'overwrite' | 'append';
|
|
10
8
|
};
|
|
11
9
|
export declare type EditableGraphQL2SdlOptions = Pick<GraphQL2SdlOptions, 'endpoint' | 'typePrefix' | 'includeRootOperations' | 'headers'>;
|
|
12
10
|
export declare type GraphQLAnswers = {
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.graphql2sdl = exports.askGraphQLQuestions = void 0;
|
|
5
5
|
const inquirer = require("inquirer");
|
|
6
|
-
const lodash_1 = require("lodash");
|
|
7
6
|
const header_1 = require("../shared/header");
|
|
8
7
|
const helpers_1 = require("./helpers");
|
|
8
|
+
const constants_1 = require("../shared/constants");
|
|
9
9
|
exports.askGraphQLQuestions = async (defaultAnswers = {}) => {
|
|
10
|
-
|
|
10
|
+
const questions = [
|
|
11
11
|
{
|
|
12
12
|
name: 'endpoint',
|
|
13
13
|
message: 'What is the GraphQL endpoint URL?',
|
|
@@ -30,11 +30,10 @@ exports.askGraphQLQuestions = async (defaultAnswers = {}) => {
|
|
|
30
30
|
validate: input => input === '' || header_1.HEADER_REGEX.test(input.trim()) || 'invalid header',
|
|
31
31
|
},
|
|
32
32
|
];
|
|
33
|
-
|
|
34
|
-
return inquirer.prompt(questions);
|
|
33
|
+
return inquirer.prompt(helpers_1.overrideDefaults(questions, defaultAnswers));
|
|
35
34
|
};
|
|
36
35
|
exports.graphql2sdl = async ({ name, source, endpoint, typePrefix, includeRootOperations, headers, onConflict, }) => {
|
|
37
|
-
const response = await helpers_1.queryIntrospectionService({
|
|
36
|
+
const response = await helpers_1.queryIntrospectionService(constants_1.STEPZEN_JSON2SDL_SERVER_URL, {
|
|
38
37
|
operation: 'getSDLFromGraphQL',
|
|
39
38
|
variables: {
|
|
40
39
|
endpoint: {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as inquirer from 'inquirer';
|
|
1
2
|
import type { Answers, DistinctQuestion } from 'inquirer';
|
|
2
3
|
export declare const createGeneratorFiles: (id: string, details: any) => Promise<string>;
|
|
3
4
|
export declare type GeneratorConfiguration = {
|
|
@@ -25,7 +26,8 @@ export declare type IntrospectionServiceResponse = {
|
|
|
25
26
|
config?: string;
|
|
26
27
|
error?: string;
|
|
27
28
|
};
|
|
28
|
-
export declare const queryIntrospectionService: (query: IntrospectionServiceQuery) => Promise<IntrospectionServiceResponse>;
|
|
29
|
+
export declare const queryIntrospectionService: (serverUrl: string, query: IntrospectionServiceQuery) => Promise<IntrospectionServiceResponse>;
|
|
29
30
|
export declare const writeSdlAndConfig: (name: string, source: string, onConflict: 'overwrite' | 'append', { config, sdl }: IntrospectionServiceResponse) => Promise<{
|
|
30
31
|
outPath: string;
|
|
31
32
|
}>;
|
|
33
|
+
export declare const overrideDefaults: <Options>(questions: inquirer.DistinctQuestion<Options>[], defaultAnswers: Partial<Options>) => inquirer.DistinctQuestion<Options>[];
|
package/lib/generate/helpers.js
CHANGED
|
@@ -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.writeSdlAndConfig = exports.queryIntrospectionService = exports.askTemplateQuestions = exports.askGeneratorQuestions = exports.getTemplates = exports.getSchema = exports.getConfiguration = exports.createGeneratorFiles = void 0;
|
|
4
|
+
exports.overrideDefaults = exports.writeSdlAndConfig = exports.queryIntrospectionService = exports.askTemplateQuestions = exports.askGeneratorQuestions = exports.getTemplates = exports.getSchema = exports.getConfiguration = exports.createGeneratorFiles = void 0;
|
|
5
5
|
const errors_1 = require("@oclif/errors");
|
|
6
6
|
const chalk = require("chalk");
|
|
7
7
|
const debug = require("debug");
|
|
@@ -161,11 +161,10 @@ exports.askTemplateQuestions = async (id, settings, state) => {
|
|
|
161
161
|
const answers = await inquirer.prompt(questions);
|
|
162
162
|
return Object.assign(Object.assign({}, state), answers);
|
|
163
163
|
};
|
|
164
|
-
exports.queryIntrospectionService = async (query) => {
|
|
164
|
+
exports.queryIntrospectionService = async (serverUrl, query) => {
|
|
165
165
|
let json;
|
|
166
166
|
try {
|
|
167
|
-
|
|
168
|
-
debug('stepzen:introspection')(url);
|
|
167
|
+
debug('stepzen:introspection')(serverUrl);
|
|
169
168
|
const queryString = `query (
|
|
170
169
|
${Object.entries(query.variables).map(([id, { type }]) => `$${id}: ${type}`)}
|
|
171
170
|
) {
|
|
@@ -181,7 +180,7 @@ exports.queryIntrospectionService = async (query) => {
|
|
|
181
180
|
variables: lodash_1.mapValues(query.variables, ({ value }) => value),
|
|
182
181
|
});
|
|
183
182
|
debug('stepzen:introspection')(payload);
|
|
184
|
-
const response = await node_fetch_1.default(
|
|
183
|
+
const response = await node_fetch_1.default(serverUrl, {
|
|
185
184
|
method: 'POST',
|
|
186
185
|
headers: { 'Content-Type': 'application/json' },
|
|
187
186
|
body: payload,
|
|
@@ -245,3 +244,9 @@ exports.writeSdlAndConfig = async (name, source, onConflict, { config, sdl }) =>
|
|
|
245
244
|
});
|
|
246
245
|
return { outPath: result };
|
|
247
246
|
};
|
|
247
|
+
exports.overrideDefaults = (questions, defaultAnswers) => {
|
|
248
|
+
return questions.map(question => {
|
|
249
|
+
const def = lodash_1.get(defaultAnswers, question.name);
|
|
250
|
+
return def === undefined ? question : Object.assign(Object.assign({}, question), { default: def });
|
|
251
|
+
});
|
|
252
|
+
};
|
package/lib/generate/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
export declare type
|
|
2
|
-
schema: string;
|
|
1
|
+
export declare type CommonImportOptions = {
|
|
3
2
|
name?: string;
|
|
4
|
-
onConflict: 'overwrite' | 'append';
|
|
5
3
|
source: string;
|
|
4
|
+
onConflict: 'overwrite' | 'append';
|
|
5
|
+
};
|
|
6
|
+
export declare type GenerateOptions = CommonImportOptions & {
|
|
7
|
+
schema: string;
|
|
6
8
|
preAnswered?: {
|
|
7
9
|
[question: string]: string;
|
|
8
10
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CommonImportOptions } from '.';
|
|
2
|
+
export declare type DBType = 'mysql' | 'postgresql';
|
|
3
|
+
export declare type SQLOptions = CommonImportOptions & {
|
|
4
|
+
host: string;
|
|
5
|
+
database: string;
|
|
6
|
+
user: string;
|
|
7
|
+
password: string;
|
|
8
|
+
linkTypes?: boolean;
|
|
9
|
+
schema?: string;
|
|
10
|
+
};
|
|
11
|
+
export declare type EditableSQLOptions = Pick<SQLOptions, 'host' | 'database' | 'user' | 'password' | 'linkTypes' | 'schema'>;
|
|
12
|
+
export declare const parseHost: (host?: string | undefined) => {
|
|
13
|
+
host?: string | undefined;
|
|
14
|
+
port?: string | undefined;
|
|
15
|
+
isValid: boolean;
|
|
16
|
+
};
|
|
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<{
|
|
19
|
+
error: string;
|
|
20
|
+
} | {
|
|
21
|
+
outPath: string;
|
|
22
|
+
}>;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2020,2021,2022, StepZen, Inc.
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.sql2sdl = exports.askSqlQuestions = exports.parseHost = void 0;
|
|
5
|
+
const chalk = require("chalk");
|
|
6
|
+
const inquirer = require("inquirer");
|
|
7
|
+
const helpers_1 = require("./helpers");
|
|
8
|
+
const constants_1 = require("../shared/constants");
|
|
9
|
+
exports.parseHost = (host) => {
|
|
10
|
+
if (!host) {
|
|
11
|
+
return { host: undefined, port: undefined, isValid: false };
|
|
12
|
+
}
|
|
13
|
+
let url;
|
|
14
|
+
// Try parsing as a DNS name or an IPv4 address (possibly with a port)
|
|
15
|
+
// e.g. "example.com:5432" or "[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:5432"
|
|
16
|
+
try {
|
|
17
|
+
url = new URL(`http://${host}`);
|
|
18
|
+
}
|
|
19
|
+
catch (_a) {
|
|
20
|
+
// Try parsing as an IPv6 address (without a port)
|
|
21
|
+
// e.g. fedc:ba98:7654:3210:fedc:ba98:7654:3210
|
|
22
|
+
try {
|
|
23
|
+
url = new URL(`http://[${host}]`);
|
|
24
|
+
}
|
|
25
|
+
catch (_b) {
|
|
26
|
+
// ignore
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (!url) {
|
|
30
|
+
return { host, port: undefined, isValid: false };
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
host: url.hostname,
|
|
34
|
+
port: url.port || undefined,
|
|
35
|
+
isValid: true,
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
exports.askSqlQuestions = async (dbType, defaultAnswers = {}) => {
|
|
39
|
+
let questions = [
|
|
40
|
+
{
|
|
41
|
+
name: 'host',
|
|
42
|
+
message: 'What is your host?',
|
|
43
|
+
validate: input => exports.parseHost(input).isValid || `Could not parse "${input}" as a hostname.`,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'database',
|
|
47
|
+
message: 'What is your database name?',
|
|
48
|
+
validate: input => input.trim() !== '' || 'Database name must not be empty',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'user',
|
|
52
|
+
message: 'What is the username?',
|
|
53
|
+
validate: input => input.trim() !== '' || 'Username must not be empty',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: 'password',
|
|
57
|
+
message: 'What is the password?',
|
|
58
|
+
type: 'password',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
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)')}`,
|
|
64
|
+
type: 'confirm',
|
|
65
|
+
default: false,
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
if (dbType === 'postgresql') {
|
|
69
|
+
questions = questions.concat([
|
|
70
|
+
{
|
|
71
|
+
name: 'schema',
|
|
72
|
+
message: 'What is your database schema (leave blank to use defaults)?',
|
|
73
|
+
},
|
|
74
|
+
]);
|
|
75
|
+
}
|
|
76
|
+
return inquirer.prompt(helpers_1.overrideDefaults(questions, defaultAnswers));
|
|
77
|
+
};
|
|
78
|
+
exports.sql2sdl = async (dbType, { name, source, host, database, user, password, linkTypes, schema, onConflict, }) => {
|
|
79
|
+
const effectiveName = name || dbType;
|
|
80
|
+
const hostDetails = exports.parseHost(host);
|
|
81
|
+
const response = await helpers_1.queryIntrospectionService(constants_1.STEPZEN_DBINTROSPECTION_SERVER_URL, {
|
|
82
|
+
operation: 'generateSDL',
|
|
83
|
+
variables: {
|
|
84
|
+
driver: {
|
|
85
|
+
type: 'DBDriver!',
|
|
86
|
+
value: dbType === 'mysql' ? 'MYSQL' : 'POSTGRESQL',
|
|
87
|
+
},
|
|
88
|
+
host: {
|
|
89
|
+
type: 'String!',
|
|
90
|
+
value: hostDetails.host,
|
|
91
|
+
},
|
|
92
|
+
port: {
|
|
93
|
+
type: 'Int',
|
|
94
|
+
value: hostDetails.port === undefined
|
|
95
|
+
? null
|
|
96
|
+
: parseInt(hostDetails.port, 10),
|
|
97
|
+
},
|
|
98
|
+
database: {
|
|
99
|
+
type: 'String!',
|
|
100
|
+
value: database,
|
|
101
|
+
},
|
|
102
|
+
user: {
|
|
103
|
+
type: 'String!',
|
|
104
|
+
value: user,
|
|
105
|
+
},
|
|
106
|
+
password: {
|
|
107
|
+
type: 'String!',
|
|
108
|
+
value: password,
|
|
109
|
+
},
|
|
110
|
+
onlyTypes: {
|
|
111
|
+
type: 'Boolean',
|
|
112
|
+
value: !linkTypes,
|
|
113
|
+
},
|
|
114
|
+
schema: {
|
|
115
|
+
type: 'String',
|
|
116
|
+
value: schema,
|
|
117
|
+
},
|
|
118
|
+
configName: {
|
|
119
|
+
type: 'String!',
|
|
120
|
+
value: `${effectiveName}_config`,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
if (response.error) {
|
|
125
|
+
return { error: response.error };
|
|
126
|
+
}
|
|
127
|
+
return helpers_1.writeSdlAndConfig(effectiveName, source, onConflict, response);
|
|
128
|
+
};
|
|
@@ -10,4 +10,5 @@ export declare const ADMIN_LIST_URL = "/cli/admin/list";
|
|
|
10
10
|
export declare const ADMIN_UPLOAD_URL = "/cli/admin/upload";
|
|
11
11
|
export declare const ADMIN_ACCOUNT_URL = "/cli/admin/account";
|
|
12
12
|
export declare const STEPZEN_JSON2SDL_SERVER_URL: string;
|
|
13
|
+
export declare const STEPZEN_DBINTROSPECTION_SERVER_URL: string;
|
|
13
14
|
export declare const STEPZEN_DISCORD_URL = "https://discord.gg/9k2VdPn2FR";
|
package/lib/shared/constants.js
CHANGED
|
@@ -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.STEPZEN_DISCORD_URL = exports.STEPZEN_JSON2SDL_SERVER_URL = exports.ADMIN_ACCOUNT_URL = exports.ADMIN_UPLOAD_URL = exports.ADMIN_LIST_URL = exports.ADMIN_DEPLOY_URL = exports.STEPZEN_API_TEMPLATES_REPOSITORY = exports.STEPZEN_DIRECT_GENERATOR_ENGINES_URL = exports.STEPZEN_SERVER_URL = exports.STEPZEN_DOMAIN = exports.STEPZEN_CONFIG_FILE = exports.STEPZEN_LAST_UPDATE_CHECK_TIMESTAMP = exports.STEPZEN_CONFIG_DIRECTORY = void 0;
|
|
4
|
+
exports.STEPZEN_DISCORD_URL = exports.STEPZEN_DBINTROSPECTION_SERVER_URL = exports.STEPZEN_JSON2SDL_SERVER_URL = exports.ADMIN_ACCOUNT_URL = exports.ADMIN_UPLOAD_URL = exports.ADMIN_LIST_URL = exports.ADMIN_DEPLOY_URL = exports.STEPZEN_API_TEMPLATES_REPOSITORY = exports.STEPZEN_DIRECT_GENERATOR_ENGINES_URL = exports.STEPZEN_SERVER_URL = exports.STEPZEN_DOMAIN = exports.STEPZEN_CONFIG_FILE = exports.STEPZEN_LAST_UPDATE_CHECK_TIMESTAMP = exports.STEPZEN_CONFIG_DIRECTORY = void 0;
|
|
5
5
|
// This file contains constants and all magic strings
|
|
6
6
|
const dotenv = require("dotenv");
|
|
7
7
|
const os = require("os");
|
|
@@ -9,7 +9,7 @@ const path = require("path");
|
|
|
9
9
|
// This allows you to set environment variables in a `.env` file.
|
|
10
10
|
// This file needs to be in your working directory.
|
|
11
11
|
dotenv.config();
|
|
12
|
-
const { STEPZEN_CONFIG_FILE: ENV_VAR_STEPZEN_CONFIG_FILE, STEPZEN_DOMAIN: ENV_VAR_STEPZEN_DOMAIN, STEPZEN_SERVER_URL: ENV_VAR_STEPZEN_SERVER_URL, STEPZEN_JSON2SDL_SERVER_URL: ENV_VAR_STEPZEN_JSON2SDL_SERVER_URL, STEPZEN_DIRECT_GENERATOR_ENGINES_URL: ENV_VAR_STEPZEN_DIRECT_GENERATOR_ENGINES_URL, } = process.env;
|
|
12
|
+
const { STEPZEN_CONFIG_FILE: ENV_VAR_STEPZEN_CONFIG_FILE, STEPZEN_DOMAIN: ENV_VAR_STEPZEN_DOMAIN, STEPZEN_SERVER_URL: ENV_VAR_STEPZEN_SERVER_URL, STEPZEN_JSON2SDL_SERVER_URL: ENV_VAR_STEPZEN_JSON2SDL_SERVER_URL, STEPZEN_DBINTROSPECTION_SERVER_URL: ENV_VAR_DBINTROSPECTION_SERVER_URL, STEPZEN_DIRECT_GENERATOR_ENGINES_URL: ENV_VAR_STEPZEN_DIRECT_GENERATOR_ENGINES_URL, } = process.env;
|
|
13
13
|
// Where your authentication details are stored locally
|
|
14
14
|
exports.STEPZEN_CONFIG_DIRECTORY = path.join(os.homedir(), '.stepzen');
|
|
15
15
|
exports.STEPZEN_LAST_UPDATE_CHECK_TIMESTAMP = path.join(exports.STEPZEN_CONFIG_DIRECTORY, 'last_update_check.timestamp');
|
|
@@ -29,5 +29,7 @@ exports.ADMIN_LIST_URL = '/cli/admin/list';
|
|
|
29
29
|
exports.ADMIN_UPLOAD_URL = '/cli/admin/upload';
|
|
30
30
|
exports.ADMIN_ACCOUNT_URL = '/cli/admin/account';
|
|
31
31
|
exports.STEPZEN_JSON2SDL_SERVER_URL = ENV_VAR_STEPZEN_JSON2SDL_SERVER_URL ||
|
|
32
|
-
'https://jsonintrospection-ng-prod-xynkgeaaaa-uc.a.run.app';
|
|
32
|
+
'https://jsonintrospection-ng-prod-xynkgeaaaa-uc.a.run.app/api/graphql';
|
|
33
|
+
exports.STEPZEN_DBINTROSPECTION_SERVER_URL = ENV_VAR_DBINTROSPECTION_SERVER_URL ||
|
|
34
|
+
'https://dbintrospection-prod-xynkgeaaaa-uc.a.run.app/graphql';
|
|
33
35
|
exports.STEPZEN_DISCORD_URL = 'https://discord.gg/9k2VdPn2FR';
|
package/oclif.manifest.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"0.18.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 to. Defaults to the name of the imported schema."},"overwrite":{"name":"overwrite","type":"boolean","description":"Overwrite any existing schema with the same name. Cannot be used without also providing a --name flag.","hidden":true,"allowNo":false},"prefix":{"name":"prefix","type":"option","description":"[curl, graphql] prefix to add every type in the generated schema."},"header":{"name":"header","type":"option","char":"H","description":"[curl, graphql] specifies a request header to pass\n\nExample:\nstepzen import curl https://example.com/api/customers \\\n\t-H \u001b[1m\"Authorization: apikey SecretAPIKeyValue\"\u001b[22m"},"header-param":{"name":"header-param","type":"option","description":"[curl, graphql] specifies a parameter in a header value. Can be formed by taking a \u001b[1m-H, --header\u001b[22m flag and replacing the variable part of the header value with a \u001b[1m$paramName\u001b[22m 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 \u001b[1m$apikey\u001b[22m'"},"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 \u001b[1m--query-type\u001b[22m is not prefixed by \u001b[1m--prefix\u001b[22m 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 \u001b[1m$paramName\u001b[22m placeholders.\n\nExample:\nstepzen import curl https://example.com/users/jane/posts/12 --path-params '/users/\u001b[1m$userId\u001b[22m/posts/\u001b[1m$postId\u001b[22m'"},"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-link-types":{"name":"db-link-types","type":"boolean","description":"[mysql, postgresql] Automatically link types with @materializer whenever there is database support \u001b[2m(https://stepzen.com/docs/features/linking-types)\u001b[22m","allowNo":false},"db-schema":{"name":"db-schema","type":"option","description":"[postgresql] database schema"}},"args":[{"name":"schema","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","description":"StepZen account name (copy from https://stepzen.com/account). If not provided, the CLI prompts the users to enter one."},"adminkey":{"name":"adminkey","type":"option","char":"k","description":"Admin key (copy from https://stepzen.com/account) If not provided, the CLI prompts the users to enter one."},"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-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":"display your credentials with 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.19.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 to. Defaults to the name of the imported schema."},"overwrite":{"name":"overwrite","type":"boolean","description":"Overwrite any existing schema with the same name. Cannot be used without also providing a --name flag.","hidden":true,"allowNo":false},"prefix":{"name":"prefix","type":"option","description":"[curl, graphql] prefix to add every type in the generated schema."},"header":{"name":"header","type":"option","char":"H","description":"[curl, graphql] specifies a request header to pass\n\nExample:\nstepzen import curl https://example.com/api/customers \\\n\t-H \"Authorization: apikey SecretAPIKeyValue\""},"header-param":{"name":"header-param","type":"option","description":"[curl, graphql] 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'"},"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'"},"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-link-types":{"name":"db-link-types","type":"boolean","description":"[mysql, postgresql] Automatically link types with @materializer whenever there is database support (https://stepzen.com/docs/features/linking-types)","allowNo":false},"db-schema":{"name":"db-schema","type":"option","description":"[postgresql] database schema"}},"args":[{"name":"schema","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","description":"StepZen account name (copy from https://stepzen.com/account). If not provided, the CLI prompts the users to enter one."},"adminkey":{"name":"adminkey","type":"option","char":"k","description":"Admin key (copy from https://stepzen.com/account) If not provided, the CLI prompts the users to enter one."},"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-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":"display your credentials with 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":[]}}}
|