zapier-platform-cli 15.18.1 → 16.0.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/oclif.manifest.json +2316 -1
- package/package.json +43 -33
- package/scaffold/create.template.ts +64 -0
- package/scaffold/resource.template.ts +119 -0
- package/scaffold/search.template.ts +63 -0
- package/scaffold/test.template.ts +18 -0
- package/scaffold/trigger.template.ts +58 -0
- package/src/bin/run +4 -4
- package/src/bin/run.cmd +0 -3
- package/src/generators/index.js +11 -11
- package/src/index.js +1 -1
- package/src/oclif/ZapierBaseCommand.js +51 -44
- package/src/oclif/buildFlags.js +14 -16
- package/src/oclif/commands/analytics.js +6 -6
- package/src/oclif/commands/build.js +6 -6
- package/src/oclif/commands/cache/clear.js +13 -13
- package/src/oclif/commands/canary/create.js +27 -20
- package/src/oclif/commands/canary/delete.js +26 -16
- package/src/oclif/commands/canary/list.js +5 -7
- package/src/oclif/commands/convert.js +16 -16
- package/src/oclif/commands/delete/version.js +6 -6
- package/src/oclif/commands/deprecate.js +10 -11
- package/src/oclif/commands/describe.js +5 -5
- package/src/oclif/commands/env/get.js +5 -5
- package/src/oclif/commands/env/set.js +11 -12
- package/src/oclif/commands/env/unset.js +9 -10
- package/src/oclif/commands/init.js +12 -13
- package/src/oclif/commands/invoke.js +67 -69
- package/src/oclif/commands/jobs.js +1 -1
- package/src/oclif/commands/link.js +2 -2
- package/src/oclif/commands/login.js +15 -15
- package/src/oclif/commands/logout.js +1 -1
- package/src/oclif/commands/logs.js +9 -9
- package/src/oclif/commands/migrate.js +19 -22
- package/src/oclif/commands/promote.js +25 -27
- package/src/oclif/commands/push.js +2 -2
- package/src/oclif/commands/register.js +31 -32
- package/src/oclif/commands/scaffold.js +112 -106
- package/src/oclif/commands/team/add.js +12 -15
- package/src/oclif/commands/team/get.js +2 -2
- package/src/oclif/commands/team/remove.js +6 -6
- package/src/oclif/commands/test.js +8 -8
- package/src/oclif/commands/upload.js +1 -1
- package/src/oclif/commands/users/add.js +9 -11
- package/src/oclif/commands/users/get.js +7 -7
- package/src/oclif/commands/users/links.js +4 -4
- package/src/oclif/commands/users/remove.js +8 -9
- package/src/oclif/commands/validate.js +29 -21
- package/src/oclif/commands/versions.js +26 -1
- package/src/oclif/hooks/checkValidNodeVersion.js +1 -1
- package/src/oclif/hooks/deprecated.js +1 -1
- package/src/oclif/hooks/getAppRegistrationFieldChoices.js +4 -4
- package/src/oclif/hooks/renderMarkdownHelp.js +1 -2
- package/src/oclif/hooks/versionInfo.js +2 -2
- package/src/utils/analytics.js +4 -4
- package/src/utils/api.js +26 -29
- package/src/utils/ast.js +112 -11
- package/src/utils/auth-files-codegen.js +102 -99
- package/src/utils/build.js +27 -28
- package/src/utils/changelog.js +1 -1
- package/src/utils/check-missing-app-info.js +2 -2
- package/src/utils/convert.js +26 -20
- package/src/utils/credentials.js +1 -1
- package/src/utils/display.js +31 -8
- package/src/utils/files.js +3 -3
- package/src/utils/ignore.js +2 -2
- package/src/utils/local.js +1 -1
- package/src/utils/metadata.js +1 -1
- package/src/utils/misc.js +21 -22
- package/src/utils/promisify.js +1 -1
- package/src/utils/scaffold.js +293 -40
- package/src/utils/team.js +3 -3
- package/src/utils/xdg.js +3 -3
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
/* eslint-disable camelcase */
|
|
2
|
+
// @ts-check
|
|
3
|
+
|
|
1
4
|
const path = require('path');
|
|
5
|
+
const fs = require('fs');
|
|
2
6
|
|
|
3
|
-
const {
|
|
7
|
+
const { Args, Flags } = require('@oclif/core');
|
|
4
8
|
|
|
5
9
|
const BaseCommand = require('../ZapierBaseCommand');
|
|
6
10
|
const { buildFlags } = require('../buildFlags');
|
|
7
11
|
|
|
8
12
|
const {
|
|
9
|
-
|
|
10
|
-
getRelativeRequirePath,
|
|
13
|
+
createScaffoldingContext,
|
|
11
14
|
plural,
|
|
12
15
|
updateEntryFile,
|
|
13
16
|
isValidEntryFileUpdate,
|
|
@@ -18,127 +21,90 @@ const { isValidAppInstall } = require('../../utils/misc');
|
|
|
18
21
|
const { writeFile } = require('../../utils/files');
|
|
19
22
|
const { ISSUES_URL } = require('../../constants');
|
|
20
23
|
|
|
21
|
-
const getNewFileDirectory = (action, test = false) =>
|
|
22
|
-
path.join(test ? 'test/' : '', plural(action));
|
|
23
|
-
|
|
24
|
-
const getLocalFilePath = (directory, actionKey) =>
|
|
25
|
-
path.join(directory, actionKey);
|
|
26
|
-
/**
|
|
27
|
-
* both the string to `require` and later, the filepath to write to
|
|
28
|
-
*/
|
|
29
|
-
const getFullActionFilePath = (directory, actionKey) =>
|
|
30
|
-
path.join(process.cwd(), getLocalFilePath(directory, actionKey));
|
|
31
|
-
|
|
32
|
-
const getFullActionFilePathWithExtension = (directory, actionKey, isTest) =>
|
|
33
|
-
`${getFullActionFilePath(directory, actionKey)}${isTest ? '.test' : ''}.js`;
|
|
34
|
-
|
|
35
24
|
class ScaffoldCommand extends BaseCommand {
|
|
36
25
|
async perform() {
|
|
37
26
|
const { actionType, noun } = this.args;
|
|
38
|
-
|
|
39
|
-
// TODO: interactive portion here?
|
|
27
|
+
const indexFileLocal = this.flags.entry ?? this.defaultIndexFileLocal();
|
|
40
28
|
const {
|
|
41
|
-
dest:
|
|
42
|
-
|
|
43
|
-
entry = 'index.js',
|
|
29
|
+
dest: actionDirLocal = this.defaultActionDirLocal(indexFileLocal),
|
|
30
|
+
'test-dest': testDirLocal = this.defaultTestDirLocal(indexFileLocal),
|
|
44
31
|
force,
|
|
45
32
|
} = this.flags;
|
|
46
33
|
|
|
47
|
-
|
|
48
|
-
// const tsParser = j.withParser('ts')
|
|
49
|
-
// tsParser(codeStr)
|
|
50
|
-
// will have to change logic probably though
|
|
51
|
-
if (entry.endsWith('ts')) {
|
|
52
|
-
this.error(
|
|
53
|
-
`Typescript isn't supported for scaffolding yet. Instead, try copying the example code at https://github.com/zapier/zapier-platform/blob/b8224ec9855be91c66c924b731199a068b1e913a/example-apps/typescript/src/resources/recipe.ts`
|
|
54
|
-
);
|
|
55
|
-
}
|
|
34
|
+
const language = indexFileLocal.endsWith('.ts') ? 'ts' : 'js';
|
|
56
35
|
|
|
57
|
-
const
|
|
58
|
-
const templateContext = createTemplateContext(
|
|
36
|
+
const context = createScaffoldingContext({
|
|
59
37
|
actionType,
|
|
60
38
|
noun,
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
39
|
+
language,
|
|
40
|
+
indexFileLocal,
|
|
41
|
+
actionDirLocal,
|
|
42
|
+
testDirLocal,
|
|
43
|
+
includeIntroComments: !this.flags['no-help'],
|
|
44
|
+
preventOverwrite: !force,
|
|
45
|
+
});
|
|
65
46
|
|
|
66
|
-
const preventOverwrite = !force;
|
|
67
47
|
// TODO: read from config file?
|
|
68
48
|
|
|
69
|
-
this.startSpinner(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
actionType,
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
);
|
|
49
|
+
this.startSpinner(`Creating new file: ${context.actionFileLocal}`);
|
|
50
|
+
|
|
51
|
+
await writeTemplateFile({
|
|
52
|
+
destinationPath: context.actionFileResolved,
|
|
53
|
+
templateType: context.actionType,
|
|
54
|
+
language: context.language,
|
|
55
|
+
preventOverwrite: context.preventOverwrite,
|
|
56
|
+
templateContext: context.templateContext,
|
|
57
|
+
});
|
|
78
58
|
this.stopSpinner();
|
|
79
59
|
|
|
80
|
-
this.startSpinner(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
templateContext,
|
|
89
|
-
getFullActionFilePathWithExtension(newTestActionDir, actionKey, true),
|
|
90
|
-
preventOverwrite
|
|
91
|
-
);
|
|
60
|
+
this.startSpinner(`Creating new test file: ${context.testFileLocal}`);
|
|
61
|
+
await writeTemplateFile({
|
|
62
|
+
destinationPath: context.testFileResolved,
|
|
63
|
+
templateType: 'test',
|
|
64
|
+
language: context.language,
|
|
65
|
+
preventOverwrite: context.preventOverwrite,
|
|
66
|
+
templateContext: context.templateContext,
|
|
67
|
+
});
|
|
92
68
|
this.stopSpinner();
|
|
93
69
|
|
|
94
70
|
// * rewire the index.js to point to the new file
|
|
95
|
-
this.startSpinner(`Rewriting your ${
|
|
96
|
-
|
|
97
|
-
const entryFilePath = path.join(process.cwd(), entry);
|
|
71
|
+
this.startSpinner(`Rewriting your ${context.indexFileLocal}`);
|
|
98
72
|
|
|
99
|
-
const originalContents = await updateEntryFile(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
);
|
|
73
|
+
const originalContents = await updateEntryFile({
|
|
74
|
+
language: context.language,
|
|
75
|
+
indexFileResolved: context.indexFileResolved,
|
|
76
|
+
actionRelativeImportPath: context.actionRelativeImportPath,
|
|
77
|
+
actionImportName: context.templateContext.VARIABLE,
|
|
78
|
+
actionType: context.actionType,
|
|
79
|
+
});
|
|
106
80
|
|
|
107
81
|
if (isValidAppInstall().valid) {
|
|
108
82
|
const success = isValidEntryFileUpdate(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
83
|
+
context.language,
|
|
84
|
+
context.indexFileResolved,
|
|
85
|
+
context.actionType,
|
|
86
|
+
context.templateContext.KEY,
|
|
112
87
|
);
|
|
113
88
|
|
|
114
89
|
this.stopSpinner({ success });
|
|
115
90
|
|
|
116
91
|
if (!success) {
|
|
117
|
-
const entryName = splitFileFromPath(
|
|
92
|
+
const entryName = splitFileFromPath(context.indexFileResolved)[1];
|
|
118
93
|
|
|
119
94
|
this.startSpinner(
|
|
120
|
-
`Unable to successfully rewrite your ${entryName}. Rolling back
|
|
95
|
+
`Unable to successfully rewrite your ${entryName}. Rolling back...`,
|
|
121
96
|
);
|
|
122
|
-
await writeFile(
|
|
97
|
+
await writeFile(context.indexFileResolved, originalContents);
|
|
123
98
|
this.stopSpinner();
|
|
124
99
|
|
|
125
100
|
this.error(
|
|
126
101
|
[
|
|
127
|
-
`\nPlease add the following lines to ${
|
|
128
|
-
` * \`const ${
|
|
129
|
-
|
|
130
|
-
} = require('./${getRelativeRequirePath(
|
|
131
|
-
entryFilePath,
|
|
132
|
-
getFullActionFilePath(newActionDir, actionKey)
|
|
133
|
-
)}');\` at the top-level`,
|
|
134
|
-
` * \`[${templateContext.VARIABLE}.key]: ${
|
|
135
|
-
templateContext.VARIABLE
|
|
136
|
-
}\` in the "${plural(
|
|
137
|
-
actionType
|
|
138
|
-
)}" object in your exported integration definition.`,
|
|
102
|
+
`\nPlease add the following lines to ${context.indexFileResolved}:`,
|
|
103
|
+
` * \`const ${context.templateContext.VARIABLE} = require('./${context.actionRelativeImportPath}');\` at the top-level`,
|
|
104
|
+
` * \`[${context.templateContext.VARIABLE}.key]: ${context.templateContext.VARIABLE}\` in the "${context.actionTypePlural}" object in your exported integration definition.`,
|
|
139
105
|
'',
|
|
140
|
-
`Also, please file an issue at ${ISSUES_URL} with the contents of your ${
|
|
141
|
-
].join('\n')
|
|
106
|
+
`Also, please file an issue at ${ISSUES_URL} with the contents of your ${context.indexFileResolved}.`,
|
|
107
|
+
].join('\n'),
|
|
142
108
|
);
|
|
143
109
|
}
|
|
144
110
|
}
|
|
@@ -146,49 +112,89 @@ class ScaffoldCommand extends BaseCommand {
|
|
|
146
112
|
this.stopSpinner();
|
|
147
113
|
|
|
148
114
|
if (!this.flags.invokedFromAnotherCommand) {
|
|
149
|
-
this.log(`\nAll done! Your new ${actionType} is ready to use.`);
|
|
115
|
+
this.log(`\nAll done! Your new ${context.actionType} is ready to use.`);
|
|
150
116
|
}
|
|
151
117
|
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* If `--entry` is not provided, this will determine the path to the
|
|
121
|
+
* root index file. Notably, we'll look for tsconfig.json and
|
|
122
|
+
* src/index.ts first, because even TS apps have a root level plain
|
|
123
|
+
* index.js that we should ignore.
|
|
124
|
+
*
|
|
125
|
+
* @returns {string}
|
|
126
|
+
*/
|
|
127
|
+
defaultIndexFileLocal() {
|
|
128
|
+
const tsConfigPath = path.join(process.cwd(), 'tsconfig.json');
|
|
129
|
+
const srcIndexTsPath = path.join(process.cwd(), 'src', 'index.ts');
|
|
130
|
+
if (fs.existsSync(tsConfigPath) && fs.existsSync(srcIndexTsPath)) {
|
|
131
|
+
this.log('Automatically detected TypeScript project');
|
|
132
|
+
return 'src/index.ts';
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return 'index.js';
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* If `--dest` is not provided, this will determine the directory for
|
|
140
|
+
* the new action file to be created in.
|
|
141
|
+
*
|
|
142
|
+
* @param {string} indexFileLocal - The path to the index file
|
|
143
|
+
* @returns {string}
|
|
144
|
+
*/
|
|
145
|
+
defaultActionDirLocal(indexFileLocal) {
|
|
146
|
+
const parent = path.dirname(indexFileLocal);
|
|
147
|
+
return path.join(parent, plural(this.args.actionType));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* If `--test-dest` is not provided, this will determine the directory
|
|
152
|
+
* for the new test file to be created in.
|
|
153
|
+
*
|
|
154
|
+
* @param {string} indexFileLocal - The path to the index file
|
|
155
|
+
* @returns {string}
|
|
156
|
+
*/
|
|
157
|
+
defaultTestDirLocal(indexFileLocal) {
|
|
158
|
+
const parent = path.dirname(indexFileLocal);
|
|
159
|
+
return path.join(parent, 'test', plural(this.args.actionType));
|
|
160
|
+
}
|
|
152
161
|
}
|
|
153
162
|
|
|
154
|
-
ScaffoldCommand.args =
|
|
155
|
-
{
|
|
156
|
-
name: 'actionType',
|
|
163
|
+
ScaffoldCommand.args = {
|
|
164
|
+
actionType: Args.string({
|
|
157
165
|
help: 'What type of step type are you creating?',
|
|
158
166
|
required: true,
|
|
159
167
|
options: ['trigger', 'search', 'create', 'resource'],
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
name: 'noun',
|
|
168
|
+
}),
|
|
169
|
+
noun: Args.string({
|
|
163
170
|
help: 'What sort of object this action acts on. For example, the name of the new thing to create',
|
|
164
171
|
required: true,
|
|
165
|
-
},
|
|
166
|
-
|
|
172
|
+
}),
|
|
173
|
+
};
|
|
167
174
|
|
|
168
175
|
ScaffoldCommand.flags = buildFlags({
|
|
169
176
|
commandFlags: {
|
|
170
|
-
dest:
|
|
177
|
+
dest: Flags.string({
|
|
171
178
|
char: 'd',
|
|
172
179
|
description:
|
|
173
180
|
"Specify the new file's directory. Use this flag when you want to create a different folder structure such as `src/triggers` instead of the default `triggers`. Defaults to `[triggers|searches|creates]/{noun}`.",
|
|
174
181
|
}),
|
|
175
|
-
'test-dest':
|
|
182
|
+
'test-dest': Flags.string({
|
|
176
183
|
description:
|
|
177
184
|
"Specify the new test file's directory. Use this flag when you want to create a different folder structure such as `src/triggers` instead of the default `triggers`. Defaults to `test/[triggers|searches|creates]/{noun}`.",
|
|
178
185
|
}),
|
|
179
|
-
entry:
|
|
186
|
+
entry: Flags.string({
|
|
180
187
|
char: 'e',
|
|
181
188
|
description:
|
|
182
|
-
"Supply the path to your integration's
|
|
183
|
-
default: 'index.js',
|
|
189
|
+
"Supply the path to your integration's entry point (`index.js` or `src/index.ts`). This will try to automatically detect the correct file if not provided.",
|
|
184
190
|
}),
|
|
185
|
-
force:
|
|
191
|
+
force: Flags.boolean({
|
|
186
192
|
char: 'f',
|
|
187
193
|
description:
|
|
188
|
-
'Should we overwrite an
|
|
194
|
+
'Should we overwrite an existing trigger/search/create file?',
|
|
189
195
|
default: false,
|
|
190
196
|
}),
|
|
191
|
-
'no-help':
|
|
197
|
+
'no-help': Flags.boolean({
|
|
192
198
|
description:
|
|
193
199
|
"When scaffolding, should we skip adding helpful intro comments? Useful if this isn't your first rodeo.",
|
|
194
200
|
default: false,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const ZapierBaseCommand = require('../../ZapierBaseCommand');
|
|
2
|
-
|
|
2
|
+
const { Args } = require('@oclif/core');
|
|
3
3
|
const { cyan } = require('colors/safe');
|
|
4
4
|
const { buildFlags } = require('../../buildFlags');
|
|
5
5
|
const { callAPI } = require('../../../utils/api');
|
|
@@ -29,7 +29,7 @@ class TeamAddCommand extends ZapierBaseCommand {
|
|
|
29
29
|
`About to invite ${cyan(this.args.email)} to as a team member at the ${
|
|
30
30
|
this.args.role
|
|
31
31
|
} level. An email will be sent with the following message:\n\n"${message}"\n\nIs that ok?`,
|
|
32
|
-
true
|
|
32
|
+
true,
|
|
33
33
|
))
|
|
34
34
|
) {
|
|
35
35
|
this.log('\ncancelled');
|
|
@@ -42,8 +42,8 @@ class TeamAddCommand extends ZapierBaseCommand {
|
|
|
42
42
|
role === 'admin'
|
|
43
43
|
? `/apps/${id}/collaborators`
|
|
44
44
|
: role === 'subscriber'
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
? `${BASE_ENDPOINT}/api/platform/v3/integrations/${id}/subscribers`
|
|
46
|
+
: `/apps/${id}/limited_collaborators`;
|
|
47
47
|
|
|
48
48
|
await callAPI(url, {
|
|
49
49
|
url: url.startsWith('http') ? url : undefined,
|
|
@@ -54,26 +54,23 @@ class TeamAddCommand extends ZapierBaseCommand {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
TeamAddCommand.args =
|
|
58
|
-
{
|
|
59
|
-
name: 'email',
|
|
57
|
+
TeamAddCommand.args = {
|
|
58
|
+
email: Args.string({
|
|
60
59
|
description:
|
|
61
60
|
"The user to be invited. If they don't have a Zapier account, they'll be prompted to create one.",
|
|
62
61
|
required: true,
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
name: 'role',
|
|
62
|
+
}),
|
|
63
|
+
role: Args.string({
|
|
66
64
|
description:
|
|
67
65
|
'The level the invited team member should be at. Admins can edit everything and get email updates. Collaborators have read-access to the app and get email updates. Subscribers only get email updates.',
|
|
68
66
|
options: ['admin', 'collaborator', 'subscriber'],
|
|
69
67
|
required: true,
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
name: 'message',
|
|
68
|
+
}),
|
|
69
|
+
message: Args.string({
|
|
73
70
|
description:
|
|
74
71
|
'A message sent in the email to your team member, if you need to provide context. Wrap the message in quotes to ensure spaces get saved.',
|
|
75
|
-
},
|
|
76
|
-
|
|
72
|
+
}),
|
|
73
|
+
};
|
|
77
74
|
TeamAddCommand.flags = buildFlags();
|
|
78
75
|
TeamAddCommand.description = `Add a team member to your integration.
|
|
79
76
|
|
|
@@ -17,7 +17,7 @@ class TeamRemoveCommand extends ZapierBaseCommand {
|
|
|
17
17
|
value: { id, email, role: transformUserRole(role) },
|
|
18
18
|
name: `${email} (${transformUserRole(role)})`,
|
|
19
19
|
short: email,
|
|
20
|
-
})
|
|
20
|
+
}),
|
|
21
21
|
);
|
|
22
22
|
|
|
23
23
|
this.stopSpinner();
|
|
@@ -28,15 +28,15 @@ class TeamRemoveCommand extends ZapierBaseCommand {
|
|
|
28
28
|
id: invitationId,
|
|
29
29
|
} = await this.promptWithList(
|
|
30
30
|
'Which team member do you want to remove?',
|
|
31
|
-
choices
|
|
31
|
+
choices,
|
|
32
32
|
);
|
|
33
33
|
this.log();
|
|
34
34
|
if (
|
|
35
35
|
!(await this.confirm(
|
|
36
36
|
`About to revoke ${cyan(role)}-level access from ${cyan(
|
|
37
|
-
email
|
|
37
|
+
email,
|
|
38
38
|
)}. Are you sure?`,
|
|
39
|
-
true
|
|
39
|
+
true,
|
|
40
40
|
))
|
|
41
41
|
) {
|
|
42
42
|
this.log('\ncancelled');
|
|
@@ -49,8 +49,8 @@ class TeamRemoveCommand extends ZapierBaseCommand {
|
|
|
49
49
|
role === 'admin'
|
|
50
50
|
? `/apps/${appId}/collaborators/${invitationId}`
|
|
51
51
|
: role === 'subscriber'
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
? `${BASE_ENDPOINT}/api/platform/v3/integrations/${appId}/subscribers/${invitationId}`
|
|
53
|
+
: `/apps/${appId}/limited_collaborators`;
|
|
54
54
|
|
|
55
55
|
await callAPI(url, {
|
|
56
56
|
url: url.startsWith('http') ? url : undefined,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { Flags } = require('@oclif/core');
|
|
2
2
|
const chalk = require('chalk');
|
|
3
3
|
|
|
4
4
|
const BaseCommand = require('../ZapierBaseCommand');
|
|
@@ -27,7 +27,7 @@ class TestCommand extends BaseCommand {
|
|
|
27
27
|
const credentials = await readCredentials(false);
|
|
28
28
|
if (credentials.deployKey) {
|
|
29
29
|
this.log(
|
|
30
|
-
`Adding ${constants.AUTH_LOCATION} to environment as ZAPIER_DEPLOY_KEY
|
|
30
|
+
`Adding ${constants.AUTH_LOCATION} to environment as ZAPIER_DEPLOY_KEY...`,
|
|
31
31
|
);
|
|
32
32
|
extraEnv.ZAPIER_DEPLOY_KEY = credentials.deployKey;
|
|
33
33
|
}
|
|
@@ -53,10 +53,10 @@ class TestCommand extends BaseCommand {
|
|
|
53
53
|
// but the space-joined array made that unclear
|
|
54
54
|
this.log(
|
|
55
55
|
`\n ${chalk.cyanBright.bold(
|
|
56
|
-
packageManager.executable
|
|
56
|
+
packageManager.executable,
|
|
57
57
|
)} ${chalk.cyanBright(
|
|
58
|
-
argv.map((a) => (a.includes(' ') ? `"${a}"` : a)).join(' ')
|
|
59
|
-
)}\n
|
|
58
|
+
argv.map((a) => (a.includes(' ') ? `"${a}"` : a)).join(' '),
|
|
59
|
+
)}\n`,
|
|
60
60
|
);
|
|
61
61
|
|
|
62
62
|
const output = await runCommand(packageManager.executable, argv, {
|
|
@@ -71,15 +71,15 @@ class TestCommand extends BaseCommand {
|
|
|
71
71
|
|
|
72
72
|
TestCommand.flags = buildFlags({
|
|
73
73
|
commandFlags: {
|
|
74
|
-
'skip-validate':
|
|
74
|
+
'skip-validate': Flags.boolean({
|
|
75
75
|
description:
|
|
76
76
|
"Forgo running `zapier validate` before tests are run. This will speed up tests if you're modifying functionality of an existing integration rather than adding new actions.",
|
|
77
77
|
}),
|
|
78
|
-
yarn:
|
|
78
|
+
yarn: Flags.boolean({
|
|
79
79
|
description:
|
|
80
80
|
"Use `yarn` instead of `npm`. This happens automatically if there's a `yarn.lock` file, but you can manually force `yarn` if you run tests from a sub-directory.",
|
|
81
81
|
}),
|
|
82
|
-
pnpm:
|
|
82
|
+
pnpm: Flags.boolean({
|
|
83
83
|
description:
|
|
84
84
|
"Use `pnpm` instead of `npm`. This happens automatically if there's a `pnpm-lock.yaml` file, but you can manually force `pnpm` if you run tests from a sub-directory.",
|
|
85
85
|
}),
|
|
@@ -10,7 +10,7 @@ class UploadCommand extends BaseCommand {
|
|
|
10
10
|
// it would be cool if we differentiated between new/updated here
|
|
11
11
|
await buildAndOrUpload({ upload: true });
|
|
12
12
|
this.log(
|
|
13
|
-
`\nUpload complete! Uploaded ${BUILD_PATH} and ${SOURCE_PATH} to Zapier. If it's a new version, it should now be available in the Zap editor
|
|
13
|
+
`\nUpload complete! Uploaded ${BUILD_PATH} and ${SOURCE_PATH} to Zapier. If it's a new version, it should now be available in the Zap editor.`,
|
|
14
14
|
);
|
|
15
15
|
}
|
|
16
16
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const ZapierBaseCommand = require('../../ZapierBaseCommand');
|
|
2
|
-
const {
|
|
2
|
+
const { Args, Flags } = require('@oclif/core');
|
|
3
3
|
const { cyan } = require('colors/safe');
|
|
4
4
|
const { buildFlags } = require('../../buildFlags');
|
|
5
5
|
const { callAPI } = require('../../../utils/api');
|
|
@@ -12,7 +12,7 @@ class UsersAddCommand extends ZapierBaseCommand {
|
|
|
12
12
|
`About to invite ${cyan(this.args.email)} to ${
|
|
13
13
|
this.args.version ? `version ${this.args.version}` : 'all versions'
|
|
14
14
|
} of your integration. An invite email will be sent. Is that ok?`,
|
|
15
|
-
true
|
|
15
|
+
true,
|
|
16
16
|
))
|
|
17
17
|
) {
|
|
18
18
|
this.log('\ncancelled');
|
|
@@ -29,22 +29,20 @@ class UsersAddCommand extends ZapierBaseCommand {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
UsersAddCommand.args =
|
|
33
|
-
{
|
|
34
|
-
name: 'email',
|
|
32
|
+
UsersAddCommand.args = {
|
|
33
|
+
email: Args.string({
|
|
35
34
|
description:
|
|
36
35
|
"The user to be invited. If they don't have a Zapier account, they'll be prompted to create one.",
|
|
37
36
|
required: true,
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
name: 'version',
|
|
37
|
+
}),
|
|
38
|
+
version: Args.string({
|
|
41
39
|
description:
|
|
42
40
|
'A version string (like 1.2.3). Optional, used only if you want to invite a user to a specific version instead of all versions.',
|
|
43
|
-
},
|
|
44
|
-
|
|
41
|
+
}),
|
|
42
|
+
};
|
|
45
43
|
UsersAddCommand.flags = buildFlags({
|
|
46
44
|
commandFlags: {
|
|
47
|
-
force:
|
|
45
|
+
force: Flags.boolean({
|
|
48
46
|
char: 'f',
|
|
49
47
|
description: 'Skip confirmation. Useful for running programatically.',
|
|
50
48
|
}),
|
|
@@ -17,8 +17,8 @@ class UsersListCommand extends ZapierBaseCommand {
|
|
|
17
17
|
|
|
18
18
|
this.log(
|
|
19
19
|
`\n${yellow(
|
|
20
|
-
'Note'
|
|
21
|
-
)} that this list of users is NOT a comprehensive list of everyone who is using your integration. It only includes users who were invited directly by email (using the \`users:add EMAIL\` command or the web UI).\n
|
|
20
|
+
'Note',
|
|
21
|
+
)} that this list of users is NOT a comprehensive list of everyone who is using your integration. It only includes users who were invited directly by email (using the \`users:add EMAIL\` command or the web UI).\n`,
|
|
22
22
|
);
|
|
23
23
|
|
|
24
24
|
this.logTable({
|
|
@@ -33,10 +33,10 @@ class UsersListCommand extends ZapierBaseCommand {
|
|
|
33
33
|
|
|
34
34
|
this.log(
|
|
35
35
|
`\nTo invite users via a link, use the \`${cyan(
|
|
36
|
-
'zapier users:links'
|
|
36
|
+
'zapier users:links',
|
|
37
37
|
)}\` command. To invite a specific user by email, use the \`${cyan(
|
|
38
|
-
'zapier users:add'
|
|
39
|
-
)}\` command
|
|
38
|
+
'zapier users:add',
|
|
39
|
+
)}\` command.`,
|
|
40
40
|
);
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -45,9 +45,9 @@ UsersListCommand.flags = buildFlags({ opts: { format: true } });
|
|
|
45
45
|
UsersListCommand.description = `Get a list of users who have been invited to your integration.
|
|
46
46
|
|
|
47
47
|
Note that this list of users is NOT a comprehensive list of everyone who is using your integration. It only includes users who were invited directly by email (using the \`${cyan(
|
|
48
|
-
'zapier users:add'
|
|
48
|
+
'zapier users:add',
|
|
49
49
|
)}\` command or the web UI). Users who joined by clicking links generated using the \`${cyan(
|
|
50
|
-
'zapier user:links'
|
|
50
|
+
'zapier user:links',
|
|
51
51
|
)}\` command won't show up here.`;
|
|
52
52
|
UsersListCommand.aliases = ['users:list'];
|
|
53
53
|
UsersListCommand.skipValidInstallCheck = true;
|
|
@@ -13,13 +13,13 @@ class UsersLinksCommand extends ZapierBaseCommand {
|
|
|
13
13
|
|
|
14
14
|
this.log(
|
|
15
15
|
`\nYou can invite users to ${bold(
|
|
16
|
-
'all'
|
|
17
|
-
)} versions of your integration using the following link
|
|
16
|
+
'all',
|
|
17
|
+
)} versions of your integration using the following link:`,
|
|
18
18
|
);
|
|
19
19
|
this.log(`\n${cyan(inviteUrl)}\n`);
|
|
20
20
|
|
|
21
21
|
this.log(
|
|
22
|
-
'You can invite users to a specific integration version using the following links:'
|
|
22
|
+
'You can invite users to a specific integration version using the following links:',
|
|
23
23
|
);
|
|
24
24
|
this.logTable({
|
|
25
25
|
rows: Object.entries(versionInviteUrls).map(([version, url]) => ({
|
|
@@ -33,7 +33,7 @@ class UsersLinksCommand extends ZapierBaseCommand {
|
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
this.log(
|
|
36
|
-
'\nTo invite a specific user by email, use the `zapier users:add` command.'
|
|
36
|
+
'\nTo invite a specific user by email, use the `zapier users:add` command.',
|
|
37
37
|
);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const ZapierBaseCommand = require('../../ZapierBaseCommand');
|
|
2
|
-
const {
|
|
2
|
+
const { Args, Flags } = require('@oclif/core');
|
|
3
3
|
const { cyan } = require('colors/safe');
|
|
4
4
|
const { buildFlags } = require('../../buildFlags');
|
|
5
5
|
const { callAPI } = require('../../../utils/api');
|
|
@@ -10,9 +10,9 @@ class UsersRemoveCommand extends ZapierBaseCommand {
|
|
|
10
10
|
!this.flags.force &&
|
|
11
11
|
!(await this.confirm(
|
|
12
12
|
`About to revoke access to ${cyan(
|
|
13
|
-
this.args.email
|
|
13
|
+
this.args.email,
|
|
14
14
|
)}. They won't be able to see your app in the editor and their Zaps will stop working. Are you sure?`,
|
|
15
|
-
true
|
|
15
|
+
true,
|
|
16
16
|
))
|
|
17
17
|
) {
|
|
18
18
|
this.log('\ncancelled');
|
|
@@ -27,16 +27,15 @@ class UsersRemoveCommand extends ZapierBaseCommand {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
UsersRemoveCommand.args =
|
|
31
|
-
{
|
|
32
|
-
name: 'email',
|
|
30
|
+
UsersRemoveCommand.args = {
|
|
31
|
+
email: Args.string({
|
|
33
32
|
description: 'The user to be removed.',
|
|
34
33
|
required: true,
|
|
35
|
-
},
|
|
36
|
-
|
|
34
|
+
}),
|
|
35
|
+
};
|
|
37
36
|
UsersRemoveCommand.flags = buildFlags({
|
|
38
37
|
commandFlags: {
|
|
39
|
-
force:
|
|
38
|
+
force: Flags.boolean({
|
|
40
39
|
char: 'f',
|
|
41
40
|
description: 'Skips confirmation. Useful for running programatically.',
|
|
42
41
|
}),
|