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,5 +1,5 @@
|
|
|
1
1
|
const colors = require('colors/safe');
|
|
2
|
-
const {
|
|
2
|
+
const { Flags } = require('@oclif/core');
|
|
3
3
|
|
|
4
4
|
const BaseCommand = require('../ZapierBaseCommand');
|
|
5
5
|
const { buildFlags } = require('../buildFlags');
|
|
@@ -29,7 +29,7 @@ class ValidateCommand extends BaseCommand {
|
|
|
29
29
|
|
|
30
30
|
if (newErrors.length) {
|
|
31
31
|
this.log(
|
|
32
|
-
'Your integration is structurally invalid. Address concerns and run this command again.'
|
|
32
|
+
'Your integration is structurally invalid. Address concerns and run this command again.',
|
|
33
33
|
);
|
|
34
34
|
process.exitCode = 1;
|
|
35
35
|
} else {
|
|
@@ -41,8 +41,8 @@ class ValidateCommand extends BaseCommand {
|
|
|
41
41
|
if (process.exitCode === 1) {
|
|
42
42
|
this.log(
|
|
43
43
|
colors.grey(
|
|
44
|
-
'\nSkipping integration checks because schema did not validate.'
|
|
45
|
-
)
|
|
44
|
+
'\nSkipping integration checks because schema did not validate.',
|
|
45
|
+
),
|
|
46
46
|
);
|
|
47
47
|
}
|
|
48
48
|
return;
|
|
@@ -85,24 +85,32 @@ class ValidateCommand extends BaseCommand {
|
|
|
85
85
|
const suggestionDisplay = checkResult.suggestions.display_label;
|
|
86
86
|
|
|
87
87
|
if (checkIssues.length) {
|
|
88
|
-
this.
|
|
89
|
-
[
|
|
90
|
-
|
|
91
|
-
'
|
|
92
|
-
'properly. They block you from pushing.',
|
|
88
|
+
this.logTable({
|
|
89
|
+
headers: [
|
|
90
|
+
['', 'type'],
|
|
91
|
+
['', 'description'],
|
|
93
92
|
],
|
|
94
|
-
[
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
93
|
+
rows: [
|
|
94
|
+
{
|
|
95
|
+
type: `- ${colors.bold(errorDisplay)}`,
|
|
96
|
+
description:
|
|
97
|
+
'Issues that will prevent your integration from functioning properly. They block you from pushing.',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
type: `- ${colors.bold(warningDisplay)}`,
|
|
101
|
+
description:
|
|
102
|
+
'To-dos that must be addressed before your integration can be included in the App Directory. They block you from promoting and publishing.',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
type: `- ${colors.bold(suggestionDisplay)}`,
|
|
106
|
+
description:
|
|
107
|
+
"Issues and recommendations that need human reviews by Zapier before publishing your integration. They don't block.",
|
|
108
|
+
},
|
|
99
109
|
],
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
],
|
|
105
|
-
]);
|
|
110
|
+
hasBorder: false,
|
|
111
|
+
showHeaders: false,
|
|
112
|
+
style: { head: [], 'padding-left': 0, 'padding-right': 0 },
|
|
113
|
+
});
|
|
106
114
|
}
|
|
107
115
|
this.log();
|
|
108
116
|
}
|
|
@@ -110,7 +118,7 @@ class ValidateCommand extends BaseCommand {
|
|
|
110
118
|
|
|
111
119
|
ValidateCommand.flags = buildFlags({
|
|
112
120
|
commandFlags: {
|
|
113
|
-
'without-style':
|
|
121
|
+
'without-style': Flags.boolean({
|
|
114
122
|
description: 'Forgo pinging the Zapier server to run further checks.',
|
|
115
123
|
}),
|
|
116
124
|
},
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const colors = require('colors/safe');
|
|
2
|
+
|
|
1
3
|
const BaseCommand = require('../ZapierBaseCommand');
|
|
2
4
|
const { buildFlags } = require('../buildFlags');
|
|
3
5
|
|
|
@@ -23,9 +25,32 @@ class VersionCommand extends BaseCommand {
|
|
|
23
25
|
'No versions to show. Try adding one with the `zapier push` command',
|
|
24
26
|
});
|
|
25
27
|
|
|
28
|
+
this.logTable({
|
|
29
|
+
headers: [],
|
|
30
|
+
rows: [
|
|
31
|
+
{
|
|
32
|
+
version: `- ${colors.bold('Errors')}`,
|
|
33
|
+
platform_version:
|
|
34
|
+
'Issues that will prevent your integration from functioning properly. They block you from pushing.',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
version: `- ${colors.bold('Publishing Tasks')}`,
|
|
38
|
+
platform_version:
|
|
39
|
+
'To-dos that must be addressed before your integration can be included in the App Directory. They block you from promoting and publishing.',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
version: `- ${colors.bold('Warnings')}`,
|
|
43
|
+
platform_version:
|
|
44
|
+
"Issues and recommendations that need human reviews by Zapier before publishing your integration. They don't block.",
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
hasBorder: false,
|
|
48
|
+
style: { head: [], 'padding-left': 0, 'padding-right': 0 },
|
|
49
|
+
});
|
|
50
|
+
|
|
26
51
|
if (versions.map((v) => v.user_count).filter((c) => c === null).length) {
|
|
27
52
|
this.warn(
|
|
28
|
-
'Some user counts are still being calculated - run this command again in ~10 seconds (or longer if your integration has lots of users).'
|
|
53
|
+
'Some user counts are still being calculated - run this command again in ~10 seconds (or longer if your integration has lots of users).',
|
|
29
54
|
);
|
|
30
55
|
}
|
|
31
56
|
}
|
|
@@ -5,7 +5,7 @@ const { LAMBDA_VERSION } = require('../../constants');
|
|
|
5
5
|
module.exports = function () {
|
|
6
6
|
if (!isValidNodeVersion()) {
|
|
7
7
|
this.error(
|
|
8
|
-
`Requires node version >= ${LAMBDA_VERSION}, found ${process.versions.node}. Please upgrade Node.js
|
|
8
|
+
`Requires node version >= ${LAMBDA_VERSION}, found ${process.versions.node}. Please upgrade Node.js.`,
|
|
9
9
|
);
|
|
10
10
|
}
|
|
11
11
|
};
|
|
@@ -13,7 +13,7 @@ module.exports = async function (options) {
|
|
|
13
13
|
formFields = await callAPI('/apps/fields-choices', { skipDeployKey: true });
|
|
14
14
|
} catch (e) {
|
|
15
15
|
this.error(
|
|
16
|
-
`Unable to connect to Zapier API. Please check your connection and try again. ${e}
|
|
16
|
+
`Unable to connect to Zapier API. Please check your connection and try again. ${e}`,
|
|
17
17
|
);
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -28,17 +28,17 @@ module.exports = async function (options) {
|
|
|
28
28
|
if (cmd && cmd.flags) {
|
|
29
29
|
if (cmd.flags.audience) {
|
|
30
30
|
cmd.flags.audience.options = formFields.intention.map(
|
|
31
|
-
(audienceOption) => audienceOption.value
|
|
31
|
+
(audienceOption) => audienceOption.value,
|
|
32
32
|
);
|
|
33
33
|
}
|
|
34
34
|
if (cmd.flags.role) {
|
|
35
35
|
cmd.flags.role.options = formFields.role.map(
|
|
36
|
-
(roleOption) => roleOption.value
|
|
36
|
+
(roleOption) => roleOption.value,
|
|
37
37
|
);
|
|
38
38
|
}
|
|
39
39
|
if (cmd.flags.category) {
|
|
40
40
|
cmd.flags.category.options = formFields.app_category.map(
|
|
41
|
-
(categoryOption) => categoryOption.value
|
|
41
|
+
(categoryOption) => categoryOption.value,
|
|
42
42
|
);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
const chalk = require('chalk');
|
|
2
2
|
const { marked } = require('marked');
|
|
3
3
|
const TerminalRenderer = require('marked-terminal');
|
|
4
|
-
const { stdtermwidth } = require('@oclif/help/lib/screen');
|
|
5
4
|
|
|
6
5
|
marked.setOptions({
|
|
7
6
|
renderer: new TerminalRenderer({
|
|
8
7
|
tab: 2,
|
|
9
|
-
width:
|
|
8
|
+
width: process.stdout.getWindowSize()[0] - 2,
|
|
10
9
|
reflowText: true,
|
|
11
10
|
codespan: chalk.underline.bold,
|
|
12
11
|
}),
|
|
@@ -18,7 +18,7 @@ module.exports = (options) => {
|
|
|
18
18
|
`* CLI version: ${options.config.version}`,
|
|
19
19
|
`* Node.js version: ${process.version}`,
|
|
20
20
|
`* OS info: ${options.config.platform}-${options.config.arch}`,
|
|
21
|
-
].join('\n')
|
|
21
|
+
].join('\n'),
|
|
22
22
|
);
|
|
23
23
|
|
|
24
24
|
try {
|
|
@@ -28,7 +28,7 @@ module.exports = (options) => {
|
|
|
28
28
|
const maybeCoreDepVersion = get(pJson, ['dependencies', PLATFORM_PACKAGE]);
|
|
29
29
|
if (maybeCoreDepVersion) {
|
|
30
30
|
console.log(
|
|
31
|
-
`* \`${PLATFORM_PACKAGE}\` dependency: ${maybeCoreDepVersion}
|
|
31
|
+
`* \`${PLATFORM_PACKAGE}\` dependency: ${maybeCoreDepVersion}`,
|
|
32
32
|
);
|
|
33
33
|
}
|
|
34
34
|
} catch {}
|
package/src/utils/analytics.js
CHANGED
|
@@ -20,7 +20,7 @@ const shouldSkipAnalytics = (mode) =>
|
|
|
20
20
|
process.env.DISABLE_ZAPIER_ANALYTICS ||
|
|
21
21
|
mode === ANALYTICS_MODES.disabled;
|
|
22
22
|
|
|
23
|
-
const recordAnalytics = async (command, isValidCommand,
|
|
23
|
+
const recordAnalytics = async (command, isValidCommand, argNames, flags) => {
|
|
24
24
|
const analyticsMode = await currentAnalyticsMode();
|
|
25
25
|
|
|
26
26
|
if (shouldSkipAnalytics(analyticsMode)) {
|
|
@@ -34,10 +34,10 @@ const recordAnalytics = async (command, isValidCommand, args, flags) => {
|
|
|
34
34
|
const analyticsBody = {
|
|
35
35
|
command,
|
|
36
36
|
isValidCommand,
|
|
37
|
-
numArgs:
|
|
37
|
+
numArgs: argNames.length,
|
|
38
38
|
flags: {
|
|
39
39
|
...flags,
|
|
40
|
-
...(command === 'help' ? { helpCommand:
|
|
40
|
+
...(command === 'help' ? { helpCommand: argNames[0] } : {}), // include the beginning of args so we know what they want help on
|
|
41
41
|
},
|
|
42
42
|
cliVersion: pkg.version,
|
|
43
43
|
os: shouldRecordAnonymously ? undefined : process.platform,
|
|
@@ -54,7 +54,7 @@ const recordAnalytics = async (command, isValidCommand, args, flags) => {
|
|
|
54
54
|
skipDeployKey: shouldRecordAnonymously,
|
|
55
55
|
},
|
|
56
56
|
true,
|
|
57
|
-
false
|
|
57
|
+
false,
|
|
58
58
|
)
|
|
59
59
|
.then(({ success }) => debug('success:', success))
|
|
60
60
|
.catch(({ errText }) => debug('err:', errText));
|
package/src/utils/api.js
CHANGED
|
@@ -32,7 +32,7 @@ const readCredentials = (explodeIfMissing = true) => {
|
|
|
32
32
|
return Promise.resolve(
|
|
33
33
|
readFile(
|
|
34
34
|
constants.AUTH_LOCATION,
|
|
35
|
-
`Please run \`${colors.cyan('zapier login')}
|
|
35
|
+
`Please run \`${colors.cyan('zapier login')}\`.`,
|
|
36
36
|
)
|
|
37
37
|
.then((buf) => {
|
|
38
38
|
return JSON.parse(buf.toString());
|
|
@@ -43,7 +43,7 @@ const readCredentials = (explodeIfMissing = true) => {
|
|
|
43
43
|
} else {
|
|
44
44
|
return {};
|
|
45
45
|
}
|
|
46
|
-
})
|
|
46
|
+
}),
|
|
47
47
|
);
|
|
48
48
|
}
|
|
49
49
|
};
|
|
@@ -54,7 +54,7 @@ const callAPI = async (
|
|
|
54
54
|
options,
|
|
55
55
|
rawError = false,
|
|
56
56
|
credentialsRequired = true,
|
|
57
|
-
returnStreamBody = false
|
|
57
|
+
returnStreamBody = false,
|
|
58
58
|
) => {
|
|
59
59
|
// temp manual enable while we're not all the way moved over
|
|
60
60
|
if (_.get(global, ['argOpts', 'debug'])) {
|
|
@@ -149,7 +149,7 @@ const createCredentials = (username, password, totpCode) => {
|
|
|
149
149
|
},
|
|
150
150
|
},
|
|
151
151
|
// if totp is empty, we want a raw request so we can supress an error. If it's here, we want it to be "non-raw"
|
|
152
|
-
!totpCode
|
|
152
|
+
!totpCode,
|
|
153
153
|
);
|
|
154
154
|
};
|
|
155
155
|
|
|
@@ -162,22 +162,19 @@ const createCanary = async (versionFrom, versionTo, percent, duration) => {
|
|
|
162
162
|
method: 'POST',
|
|
163
163
|
body: {
|
|
164
164
|
percent,
|
|
165
|
-
duration
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
)
|
|
169
|
-
}
|
|
165
|
+
duration,
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
);
|
|
169
|
+
};
|
|
170
170
|
|
|
171
171
|
const listCanaries = async () => {
|
|
172
172
|
const linkedAppId = (await getLinkedAppConfig(undefined, true))?.id;
|
|
173
173
|
|
|
174
|
-
return callAPI(
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
)
|
|
180
|
-
}
|
|
174
|
+
return callAPI(`/apps/${linkedAppId}/canaries`, {
|
|
175
|
+
method: 'GET',
|
|
176
|
+
});
|
|
177
|
+
};
|
|
181
178
|
|
|
182
179
|
const deleteCanary = async (versionFrom, versionTo) => {
|
|
183
180
|
const linkedAppId = (await getLinkedAppConfig(undefined, true))?.id;
|
|
@@ -186,9 +183,9 @@ const deleteCanary = async (versionFrom, versionTo) => {
|
|
|
186
183
|
`/apps/${linkedAppId}/versions/${versionFrom}/canary-to/${versionTo}`,
|
|
187
184
|
{
|
|
188
185
|
method: 'DELETE',
|
|
189
|
-
}
|
|
190
|
-
)
|
|
191
|
-
}
|
|
186
|
+
},
|
|
187
|
+
);
|
|
188
|
+
};
|
|
192
189
|
|
|
193
190
|
/**
|
|
194
191
|
* read local `apprc` file
|
|
@@ -242,10 +239,10 @@ const getWritableApp = async () => {
|
|
|
242
239
|
if (!linkedAppConfig.id) {
|
|
243
240
|
throw new Error(
|
|
244
241
|
`This project hasn't yet been associated with an existing Zapier integration.\n\nIf it's a brand new integration, run \`${colors.cyan(
|
|
245
|
-
'zapier register'
|
|
242
|
+
'zapier register',
|
|
246
243
|
)}\`.\n\nIf this project already exists in your Zapier account, run \`${colors.cyan(
|
|
247
|
-
'zapier link'
|
|
248
|
-
)}\` instead
|
|
244
|
+
'zapier link',
|
|
245
|
+
)}\` instead.`,
|
|
249
246
|
);
|
|
250
247
|
}
|
|
251
248
|
|
|
@@ -261,7 +258,7 @@ const getWritableApp = async () => {
|
|
|
261
258
|
throw new Error(
|
|
262
259
|
`Your credentials are present, but invalid${
|
|
263
260
|
process.env.ZAPIER_BASE_ENDPOINT ? ' in this environment' : ''
|
|
264
|
-
}. Please run \`${colors.cyan('zapier login')}\` to resolve
|
|
261
|
+
}. Please run \`${colors.cyan('zapier login')}\` to resolve.`,
|
|
265
262
|
);
|
|
266
263
|
} else if (errOrRejectedResponse.status === 404) {
|
|
267
264
|
// if this fails, we know the issue is they can't see this app
|
|
@@ -272,9 +269,9 @@ const getWritableApp = async () => {
|
|
|
272
269
|
}). Try running \`${colors.cyan('zapier link')}\` to correct that.${
|
|
273
270
|
process.env.ZAPIER_BASE_ENDPOINT
|
|
274
271
|
? `\n\nFor local dev: make sure you've run \`${colors.cyan(
|
|
275
|
-
'zapier login'
|
|
272
|
+
'zapier login',
|
|
276
273
|
)}\` and \`${colors.cyan(
|
|
277
|
-
'zapier register'
|
|
274
|
+
'zapier register',
|
|
278
275
|
)}\` while providing ZAPIER_BASE_ENDPOINT.`
|
|
279
276
|
: ''
|
|
280
277
|
}`;
|
|
@@ -399,10 +396,10 @@ const downloadSourceZip = async (dst) => {
|
|
|
399
396
|
if (!linkedAppConfig.id) {
|
|
400
397
|
throw new Error(
|
|
401
398
|
`This project hasn't yet been associated with an existing Zapier integration.\n\nIf it's a brand new integration, run \`${colors.cyan(
|
|
402
|
-
'zapier register'
|
|
399
|
+
'zapier register',
|
|
403
400
|
)}\`.\n\nIf this project already exists in your Zapier account, run \`${colors.cyan(
|
|
404
|
-
'zapier link'
|
|
405
|
-
)}\` instead
|
|
401
|
+
'zapier link',
|
|
402
|
+
)}\` instead.`,
|
|
406
403
|
);
|
|
407
404
|
}
|
|
408
405
|
|
|
@@ -434,7 +431,7 @@ const upload = async (app, { skipValidation = false } = {}) => {
|
|
|
434
431
|
|
|
435
432
|
if (!fs.existsSync(fullZipPath)) {
|
|
436
433
|
throw new Error(
|
|
437
|
-
'Missing a built integration. Try running `zapier build` first.\nAlternatively, run `zapier push`, which will build and upload in one command.'
|
|
434
|
+
'Missing a built integration. Try running `zapier build` first.\nAlternatively, run `zapier push`, which will build and upload in one command.',
|
|
438
435
|
);
|
|
439
436
|
}
|
|
440
437
|
|
package/src/utils/ast.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
//
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
// tools for modifying an AST
|
|
2
4
|
|
|
3
5
|
const j = require('jscodeshift');
|
|
6
|
+
const ts = j.withParser('ts');
|
|
4
7
|
|
|
5
8
|
// simple helper functions used for searching for nodes
|
|
6
9
|
// can't use j.identifier(name) because it has extra properties and we have to have no extras to find nodes
|
|
@@ -21,7 +24,7 @@ const typeHelpers = {
|
|
|
21
24
|
/**
|
|
22
25
|
* adds a `const verName = require(path)` to the root of a codeStr
|
|
23
26
|
*/
|
|
24
|
-
const
|
|
27
|
+
const importActionInJsApp = (codeStr, varName, path) => {
|
|
25
28
|
if (codeStr.match(new RegExp(`${varName} ?= ?require`))) {
|
|
26
29
|
// duplicate identifier, no need to re-add
|
|
27
30
|
// this would fail if they used this variable name for something else; we'd keep going and double-declare that variable
|
|
@@ -42,7 +45,7 @@ const createRootRequire = (codeStr, varName, path) => {
|
|
|
42
45
|
const newRequireStatement = j.variableDeclaration('const', [
|
|
43
46
|
j.variableDeclarator(
|
|
44
47
|
j.identifier(varName),
|
|
45
|
-
j.callExpression(j.identifier('require'), [j.literal(path)])
|
|
48
|
+
j.callExpression(j.identifier('require'), [j.literal(path)]),
|
|
46
49
|
),
|
|
47
50
|
]);
|
|
48
51
|
|
|
@@ -61,7 +64,7 @@ const createRootRequire = (codeStr, varName, path) => {
|
|
|
61
64
|
return root.toSource();
|
|
62
65
|
};
|
|
63
66
|
|
|
64
|
-
const
|
|
67
|
+
const registerActionInJsApp = (codeStr, property, varName) => {
|
|
65
68
|
// to play with this, use https://astexplorer.net/#/gist/cb4986b3f1c6eb975339608109a48e7d/0fbf2fabbcf27d0b6ebd8910f979bd5d97dd9404
|
|
66
69
|
|
|
67
70
|
const root = j(codeStr);
|
|
@@ -77,13 +80,13 @@ const addKeyToPropertyOnApp = (codeStr, property, varName) => {
|
|
|
77
80
|
const exportAssignment = root.find(j.AssignmentExpression, {
|
|
78
81
|
left: typeHelpers.memberExpression(
|
|
79
82
|
typeHelpers.identifier('module'),
|
|
80
|
-
typeHelpers.identifier('exports')
|
|
83
|
+
typeHelpers.identifier('exports'),
|
|
81
84
|
),
|
|
82
85
|
});
|
|
83
86
|
|
|
84
87
|
if (!exportAssignment.length) {
|
|
85
88
|
throw new Error(
|
|
86
|
-
'Nothing is exported from this file; unable to find an object to modify'
|
|
89
|
+
'Nothing is exported from this file; unable to find an object to modify',
|
|
87
90
|
);
|
|
88
91
|
}
|
|
89
92
|
|
|
@@ -112,14 +115,14 @@ const addKeyToPropertyOnApp = (codeStr, property, varName) => {
|
|
|
112
115
|
|
|
113
116
|
// check if this object already has the property at the top level
|
|
114
117
|
const existingProp = objToModify.properties.find(
|
|
115
|
-
(props) => props.key.name === property
|
|
118
|
+
(props) => props.key.name === property,
|
|
116
119
|
);
|
|
117
120
|
if (existingProp) {
|
|
118
121
|
// `triggers: myTriggers` means we shouldn't bother
|
|
119
122
|
const value = existingProp.value;
|
|
120
123
|
if (value.type !== 'ObjectExpression') {
|
|
121
124
|
throw new Error(
|
|
122
|
-
`Tried to edit the ${property} key, but the value wasn't an object
|
|
125
|
+
`Tried to edit the ${property} key, but the value wasn't an object`,
|
|
123
126
|
);
|
|
124
127
|
}
|
|
125
128
|
value.properties.push(newProperty);
|
|
@@ -128,12 +131,110 @@ const addKeyToPropertyOnApp = (codeStr, property, varName) => {
|
|
|
128
131
|
j.property(
|
|
129
132
|
'init',
|
|
130
133
|
j.identifier(property),
|
|
131
|
-
j.objectExpression([newProperty])
|
|
132
|
-
)
|
|
134
|
+
j.objectExpression([newProperty]),
|
|
135
|
+
),
|
|
133
136
|
);
|
|
134
137
|
}
|
|
135
138
|
|
|
136
139
|
return root.toSource();
|
|
137
140
|
};
|
|
138
141
|
|
|
139
|
-
|
|
142
|
+
/**
|
|
143
|
+
* Adds an import statement to the top of an index.ts file to import a
|
|
144
|
+
* new action, such as `import some_trigger from './triggers/some_trigger';`
|
|
145
|
+
*
|
|
146
|
+
* @param {string} codeStr - The code of the index.ts file to modify.
|
|
147
|
+
* @param {string} identifierName - The name of imported action used as a variable in the code.
|
|
148
|
+
* @param {string} actionRelativeImportPath - The relative path to import the action from
|
|
149
|
+
* @returns {string}
|
|
150
|
+
*/
|
|
151
|
+
const importActionInTsApp = (
|
|
152
|
+
codeStr,
|
|
153
|
+
identifierName,
|
|
154
|
+
actionRelativeImportPath,
|
|
155
|
+
) => {
|
|
156
|
+
const root = ts(codeStr);
|
|
157
|
+
|
|
158
|
+
const imports = root.find(ts.ImportDeclaration);
|
|
159
|
+
|
|
160
|
+
const newImportStatement = j.importDeclaration(
|
|
161
|
+
[j.importDefaultSpecifier(j.identifier(identifierName))],
|
|
162
|
+
j.literal(actionRelativeImportPath),
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
if (imports.length) {
|
|
166
|
+
imports.at(-1).insertAfter(newImportStatement);
|
|
167
|
+
} else {
|
|
168
|
+
const body = root.find(ts.Program).get().node.body;
|
|
169
|
+
body.unshift(newImportStatement);
|
|
170
|
+
// Add newline after import?
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return root.toSource({ quote: 'single' });
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
*
|
|
178
|
+
* @param {string} codeStr
|
|
179
|
+
* @param {'creates' | 'searches' | 'triggers'} actionTypePlural - The type of action to register within the app
|
|
180
|
+
* @param {string} identifierName - Name of the action imported to be registered
|
|
181
|
+
* @returns {string}
|
|
182
|
+
*/
|
|
183
|
+
const registerActionInTsApp = (codeStr, actionTypePlural, identifierName) => {
|
|
184
|
+
const root = ts(codeStr);
|
|
185
|
+
|
|
186
|
+
// the `[thing.key]: thing` entry we'd like to insert.
|
|
187
|
+
const newProperty = ts.property.from({
|
|
188
|
+
kind: 'init',
|
|
189
|
+
key: j.memberExpression(j.identifier(identifierName), j.identifier('key')),
|
|
190
|
+
value: j.identifier(identifierName),
|
|
191
|
+
computed: true,
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// Find the top level app Object; the one with the `platformVersion`
|
|
195
|
+
// key. This is where we'll insert our new property.
|
|
196
|
+
const appObjectCandidates = root
|
|
197
|
+
.find(ts.ObjectExpression)
|
|
198
|
+
.filter((path) =>
|
|
199
|
+
path.value.properties.some(
|
|
200
|
+
(prop) => prop.key && prop.key.name === 'platformVersion',
|
|
201
|
+
),
|
|
202
|
+
);
|
|
203
|
+
if (appObjectCandidates.length !== 1) {
|
|
204
|
+
throw new Error('Unable to find the app definition to modify');
|
|
205
|
+
}
|
|
206
|
+
const appObj = appObjectCandidates.get().node;
|
|
207
|
+
|
|
208
|
+
// Now we have an app object to modify.
|
|
209
|
+
|
|
210
|
+
// Check if this object already has the actionType group inside it.
|
|
211
|
+
const existingProp = appObj.properties.find(
|
|
212
|
+
(props) => props.key.name === actionTypePlural,
|
|
213
|
+
);
|
|
214
|
+
if (existingProp) {
|
|
215
|
+
const value = existingProp.value;
|
|
216
|
+
if (value.type !== 'ObjectExpression') {
|
|
217
|
+
throw new Error(
|
|
218
|
+
`Tried to edit the ${actionTypePlural} key, but the value wasn't an object`,
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
value.properties.push(newProperty);
|
|
222
|
+
} else {
|
|
223
|
+
appObj.properties.push(
|
|
224
|
+
j.property(
|
|
225
|
+
'init',
|
|
226
|
+
j.identifier(actionTypePlural),
|
|
227
|
+
j.objectExpression([newProperty]),
|
|
228
|
+
),
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return root.toSource({ quote: 'single' });
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
module.exports = {
|
|
236
|
+
importActionInJsApp,
|
|
237
|
+
registerActionInJsApp,
|
|
238
|
+
importActionInTsApp,
|
|
239
|
+
registerActionInTsApp,
|
|
240
|
+
};
|