zapier-platform-cli 11.0.1 → 11.3.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/LICENSE +1 -2
- package/README-source.md +2002 -0
- package/README.md +137 -39
- package/oclif.manifest.json +1 -1
- package/package.json +6 -6
- package/src/generators/index.js +1 -1
- package/src/generators/templates/files/creates/uploadFile_v10.js +11 -5
- package/src/oclif/commands/describe.js +1 -1
- package/src/oclif/commands/jobs.js +98 -0
- package/src/oclif/commands/migrate.js +12 -4
- package/src/oclif/commands/promote.js +13 -8
- package/src/oclif/commands/test.js +11 -9
- package/src/oclif/hooks/renderMarkdownHelp.js +1 -1
- package/src/oclif/oCommands.js +1 -0
- package/src/utils/api.js +3 -0
- package/src/utils/auth-files-codegen.js +2 -2
- package/src/utils/convert.js +9 -8
- package/src/utils/npm.js +1 -3
- package/src/utils/package-manager.js +45 -0
|
@@ -6,19 +6,25 @@ const FormData = require('form-data');
|
|
|
6
6
|
// 9.x compatible code, see uploadFile_v9.js.
|
|
7
7
|
const makeDownloadStream = (url) =>
|
|
8
8
|
new Promise((resolve, reject) => {
|
|
9
|
-
http.request(url,
|
|
9
|
+
http.request(url, (res) => {
|
|
10
|
+
// We can risk missing the first n bytes if we don't pause!
|
|
11
|
+
res.pause();
|
|
12
|
+
resolve(res);
|
|
13
|
+
}).on('error', reject).end();
|
|
10
14
|
});
|
|
11
15
|
|
|
12
16
|
const perform = async (z, bundle) => {
|
|
13
|
-
const form = new FormData();
|
|
14
|
-
|
|
15
|
-
form.append('filename', bundle.inputData.filename);
|
|
16
|
-
|
|
17
17
|
// bundle.inputData.file will in fact be an URL where the file data can be
|
|
18
18
|
// downloaded from which we do via a stream
|
|
19
19
|
const stream = await makeDownloadStream(bundle.inputData.file, z);
|
|
20
|
+
|
|
21
|
+
const form = new FormData();
|
|
22
|
+
form.append('filename', bundle.inputData.filename);
|
|
20
23
|
form.append('file', stream);
|
|
21
24
|
|
|
25
|
+
// All set! Resume the stream
|
|
26
|
+
stream.resume();
|
|
27
|
+
|
|
22
28
|
const response = await z.request({
|
|
23
29
|
url: 'https://auth-json-server.zapier-staging.com/upload',
|
|
24
30
|
method: 'POST',
|
|
@@ -194,7 +194,7 @@ class DescribeCommand extends BaseCommand {
|
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
DescribeCommand.flags = buildFlags({ opts: { format: true } });
|
|
197
|
-
DescribeCommand.description = `Describe the current
|
|
197
|
+
DescribeCommand.description = `Describe the current integration.
|
|
198
198
|
|
|
199
199
|
This command prints a human readable enumeration of your integrations's
|
|
200
200
|
triggers, searches, and creates as seen by Zapier. Useful to understand how your
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const { chain } = require('lodash');
|
|
2
|
+
|
|
3
|
+
const BaseCommand = require('../ZapierBaseCommand');
|
|
4
|
+
const { listMigrations } = require('../../utils/api');
|
|
5
|
+
const { buildFlags } = require('../buildFlags');
|
|
6
|
+
|
|
7
|
+
const getVersion = (versionStr) => versionStr.split('@')[1];
|
|
8
|
+
const getIsoDate = (unixTs) => (unixTs ? new Date(unixTs).toISOString() : '-');
|
|
9
|
+
|
|
10
|
+
class JobsCommand extends BaseCommand {
|
|
11
|
+
async perform() {
|
|
12
|
+
/**
|
|
13
|
+
* Migrations and Jobs are used somewhat interchangeably here.
|
|
14
|
+
* Migrations represents the collection of promotion and migration
|
|
15
|
+
* background "jobs" that were recently executed on this app.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
this.startSpinner('Loading jobs');
|
|
19
|
+
const { migrations } = await listMigrations();
|
|
20
|
+
this.stopSpinner();
|
|
21
|
+
|
|
22
|
+
const jobs = chain(migrations)
|
|
23
|
+
.filter(
|
|
24
|
+
(migration) =>
|
|
25
|
+
migration.job_kind === 'migrate' || migration.job_kind === 'promote'
|
|
26
|
+
)
|
|
27
|
+
.map((migration) => {
|
|
28
|
+
const job = {
|
|
29
|
+
app_title: migration.app_title,
|
|
30
|
+
job_id: migration.job_id,
|
|
31
|
+
job_kind: migration.job_kind,
|
|
32
|
+
job_stage: migration.job_stage,
|
|
33
|
+
version_from: getVersion(migration.from_selected_api),
|
|
34
|
+
version_to: getVersion(migration.to_selected_api),
|
|
35
|
+
started_at: getIsoDate(migration.started_at),
|
|
36
|
+
updated_at: getIsoDate(migration.updated_at),
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
if (migration.progress) {
|
|
40
|
+
job.overall_progress =
|
|
41
|
+
parseFloat(migration.progress.overall_progress * 100).toFixed(2) +
|
|
42
|
+
'%';
|
|
43
|
+
|
|
44
|
+
if (migration.progress.current_step) {
|
|
45
|
+
job.current_step = migration.progress.current_step.name;
|
|
46
|
+
job.current_progress = `${migration.progress.current_step.finished_points} finished, ${migration.progress.current_step.skipped_points} skipped, ${migration.progress.current_step.estimated_points} estimated`;
|
|
47
|
+
job.current_step_status = migration.progress.current_step.status;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (migration.error) {
|
|
52
|
+
job.error_message = migration.error.message;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return job;
|
|
56
|
+
})
|
|
57
|
+
.sortBy((migration) => migration.started_at)
|
|
58
|
+
.value();
|
|
59
|
+
|
|
60
|
+
this.logTable({
|
|
61
|
+
rows: jobs,
|
|
62
|
+
headers: [
|
|
63
|
+
['App Title', 'app_title'],
|
|
64
|
+
['Job Id', 'job_id'],
|
|
65
|
+
['Job Kind', 'job_kind'],
|
|
66
|
+
['Job Stage', 'job_stage'],
|
|
67
|
+
['From', 'version_from'],
|
|
68
|
+
['To', 'version_to'],
|
|
69
|
+
['Current Step', 'current_step'],
|
|
70
|
+
['Current Progress', 'current_progress'],
|
|
71
|
+
['Current Step Status', 'current_step_status'],
|
|
72
|
+
['Progress', 'overall_progress'],
|
|
73
|
+
['Started At', 'started_at'],
|
|
74
|
+
['Updated At', 'updated_at'],
|
|
75
|
+
['Errors', 'error_message'],
|
|
76
|
+
],
|
|
77
|
+
emptyMessage:
|
|
78
|
+
'No recent migration or promotion jobs found. Try `zapier history` if you see older jobs.',
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
JobsCommand.examples = ['zapier jobs'];
|
|
84
|
+
JobsCommand.description = `Lists ongoing migration or promotion jobs for the current integration.
|
|
85
|
+
|
|
86
|
+
A job represents a background process that will be queued up when users execute a "migrate" or "promote" command for the current integration.
|
|
87
|
+
|
|
88
|
+
Each job will be added to the end of a queue of "promote" and "migration" jobs where the "Job Stage" will then be initialized with "requested".
|
|
89
|
+
|
|
90
|
+
Job stages will then move to "estimating", "in_progress" and finally one of four "end" stages: "complete", "aborted", "errored" or "paused".
|
|
91
|
+
|
|
92
|
+
Job times will vary as it depends on the size of the queue and how many users your integration has.
|
|
93
|
+
|
|
94
|
+
Jobs are returned from oldest to newest.
|
|
95
|
+
`;
|
|
96
|
+
|
|
97
|
+
JobsCommand.flags = buildFlags({ opts: { format: true } });
|
|
98
|
+
module.exports = JobsCommand;
|
|
@@ -46,10 +46,14 @@ class MigrateCommand extends BaseCommand {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
const body = {
|
|
49
|
-
|
|
49
|
+
job: {
|
|
50
|
+
name: 'migrate',
|
|
51
|
+
from_version: fromVersion,
|
|
52
|
+
to_version: toVersion,
|
|
53
|
+
email: user,
|
|
54
|
+
},
|
|
50
55
|
};
|
|
51
56
|
if (user) {
|
|
52
|
-
body.user = user;
|
|
53
57
|
this.startSpinner(
|
|
54
58
|
`Starting migration from ${fromVersion} to ${toVersion} for ${user}`
|
|
55
59
|
);
|
|
@@ -58,8 +62,12 @@ class MigrateCommand extends BaseCommand {
|
|
|
58
62
|
`Starting migration from ${fromVersion} to ${toVersion} for ${percent}%`
|
|
59
63
|
);
|
|
60
64
|
}
|
|
65
|
+
if (percent) {
|
|
66
|
+
body.job.percent_human = percent;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const url = `/apps/${app.id}/migrations`;
|
|
61
70
|
|
|
62
|
-
const url = `/apps/${app.id}/versions/${fromVersion}/migrate-to/${toVersion}`;
|
|
63
71
|
try {
|
|
64
72
|
await callAPI(url, { method: 'POST', body });
|
|
65
73
|
} finally {
|
|
@@ -110,7 +118,7 @@ Start a migration to move users between different versions of your integration.
|
|
|
110
118
|
|
|
111
119
|
Only use this command to migrate users between non-breaking versions, use \`zapier deprecate\` if you have breaking changes!
|
|
112
120
|
|
|
113
|
-
Migration time varies based on the number of affected Zaps. Be patient and check \`zapier
|
|
121
|
+
Migration time varies based on the number of affected Zaps. Be patient and check \`zapier jobs\` to track the status. Or use \`zapier history\` if you want to see older jobs.
|
|
114
122
|
|
|
115
123
|
Since a migration is only for non-breaking changes, users are not emailed about the update/migration. It will be a transparent process for them.
|
|
116
124
|
|
|
@@ -60,19 +60,22 @@ class PromoteCommand extends BaseCommand {
|
|
|
60
60
|
`Preparing to promote version ${version} of your integration "${app.title}".`
|
|
61
61
|
);
|
|
62
62
|
|
|
63
|
-
const body = {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
const body = {
|
|
64
|
+
job: {
|
|
65
|
+
name: 'promote',
|
|
66
|
+
to_version: version,
|
|
67
|
+
changelog,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
67
70
|
|
|
68
71
|
this.startSpinner(`Verifying and promoting ${version}`);
|
|
69
72
|
|
|
70
|
-
const url = `/apps/${app.id}/
|
|
73
|
+
const url = `/apps/${app.id}/migrations`;
|
|
71
74
|
try {
|
|
72
75
|
await callAPI(
|
|
73
76
|
url,
|
|
74
77
|
{
|
|
75
|
-
method: '
|
|
78
|
+
method: 'POST',
|
|
76
79
|
body,
|
|
77
80
|
},
|
|
78
81
|
true
|
|
@@ -120,7 +123,7 @@ PromoteCommand.args = [
|
|
|
120
123
|
{
|
|
121
124
|
name: 'version',
|
|
122
125
|
required: true,
|
|
123
|
-
description: 'The version you want promote.',
|
|
126
|
+
description: 'The version you want to promote.',
|
|
124
127
|
},
|
|
125
128
|
];
|
|
126
129
|
|
|
@@ -136,6 +139,8 @@ Promote an integration version into production (non-private) rotation, which mea
|
|
|
136
139
|
|
|
137
140
|
Promotes are an inherently safe operation for all existing users of your integration.
|
|
138
141
|
|
|
139
|
-
If your integration is private and passes our integration checks, this will give you a URL to a form where you can fill in additional information for your integration to go public. After reviewing, the Zapier team will approve to make it public if there are no issues or decline with feedback
|
|
142
|
+
If your integration is private and passes our integration checks, this will give you a URL to a form where you can fill in additional information for your integration to go public. After reviewing, the Zapier team will approve to make it public if there are no issues or decline with feedback.
|
|
143
|
+
|
|
144
|
+
Check \`zapier jobs\` to track the status of the promotion. Or use \`zapier history\` if you want to see older jobs.`;
|
|
140
145
|
|
|
141
146
|
module.exports = PromoteCommand;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const { pathExists } = require('fs-extra');
|
|
3
1
|
const { flags } = require('@oclif/command');
|
|
4
2
|
const chalk = require('chalk');
|
|
5
3
|
|
|
@@ -9,6 +7,7 @@ const constants = require('../../constants');
|
|
|
9
7
|
const { buildFlags } = require('../buildFlags');
|
|
10
8
|
const { readCredentials } = require('../../utils/api');
|
|
11
9
|
const { runCommand } = require('../../utils/misc');
|
|
10
|
+
const { getPackageManager } = require('../../utils/package-manager');
|
|
12
11
|
|
|
13
12
|
class TestCommand extends BaseCommand {
|
|
14
13
|
async perform() {
|
|
@@ -35,9 +34,7 @@ class TestCommand extends BaseCommand {
|
|
|
35
34
|
|
|
36
35
|
const env = Object.assign({}, process.env, extraEnv);
|
|
37
36
|
|
|
38
|
-
const
|
|
39
|
-
this.flags.yarn ||
|
|
40
|
-
(await pathExists(path.join(process.cwd(), 'yarn.lock')));
|
|
37
|
+
const packageManager = await getPackageManager(this.flags);
|
|
41
38
|
|
|
42
39
|
const passthroughArgs = this.argv.includes('--')
|
|
43
40
|
? this.argv.slice(this.argv.indexOf('--') + 1)
|
|
@@ -47,21 +44,22 @@ class TestCommand extends BaseCommand {
|
|
|
47
44
|
'run',
|
|
48
45
|
'--silent',
|
|
49
46
|
'test',
|
|
50
|
-
|
|
47
|
+
packageManager.useDoubleHyphenBeforeArgs ? '--' : '',
|
|
51
48
|
...passthroughArgs,
|
|
52
49
|
].filter(Boolean);
|
|
53
|
-
const packageManager = useYarn ? 'yarn' : 'npm';
|
|
54
50
|
|
|
55
51
|
this.log('Running test suite with the following command:');
|
|
56
52
|
// some extra formatting happen w/ quotes so it's clear when they're already like that in the array,
|
|
57
53
|
// but the space-joined array made that unclear
|
|
58
54
|
this.log(
|
|
59
|
-
`\n ${chalk.cyanBright.bold(
|
|
55
|
+
`\n ${chalk.cyanBright.bold(
|
|
56
|
+
packageManager.executable
|
|
57
|
+
)} ${chalk.cyanBright(
|
|
60
58
|
argv.map((a) => (a.includes(' ') ? `"${a}"` : a)).join(' ')
|
|
61
59
|
)}\n`
|
|
62
60
|
);
|
|
63
61
|
|
|
64
|
-
const output = await runCommand(packageManager, argv, {
|
|
62
|
+
const output = await runCommand(packageManager.executable, argv, {
|
|
65
63
|
stdio: 'inherit',
|
|
66
64
|
env,
|
|
67
65
|
});
|
|
@@ -81,6 +79,10 @@ TestCommand.flags = buildFlags({
|
|
|
81
79
|
description:
|
|
82
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.",
|
|
83
81
|
}),
|
|
82
|
+
pnpm: flags.boolean({
|
|
83
|
+
description:
|
|
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
|
+
}),
|
|
84
86
|
},
|
|
85
87
|
});
|
|
86
88
|
|
package/src/oclif/oCommands.js
CHANGED
|
@@ -15,6 +15,7 @@ module.exports = {
|
|
|
15
15
|
'env:set': require('./commands/env/set'),
|
|
16
16
|
'env:unset': require('./commands/env/unset'),
|
|
17
17
|
history: require('./commands/history'),
|
|
18
|
+
jobs: require('./commands/jobs'),
|
|
18
19
|
init: require('./commands/init'),
|
|
19
20
|
integrations: require('./commands/integrations'),
|
|
20
21
|
link: require('./commands/link'),
|
package/src/utils/api.js
CHANGED
|
@@ -327,6 +327,8 @@ const listLogs = (opts) => {
|
|
|
327
327
|
const listEnv = (version) =>
|
|
328
328
|
listEndpoint(`versions/${version}/environment`, 'env');
|
|
329
329
|
|
|
330
|
+
const listMigrations = () => listEndpoint('migrations');
|
|
331
|
+
|
|
330
332
|
// the goal of this is to call `/check` with as much info as possible
|
|
331
333
|
// if the app is registered and auth is available, then we can send app id
|
|
332
334
|
// otherwise, we should just send the definition and get back checks about that
|
|
@@ -411,6 +413,7 @@ module.exports = {
|
|
|
411
413
|
listInvitees,
|
|
412
414
|
listLogs,
|
|
413
415
|
listVersions,
|
|
416
|
+
listMigrations,
|
|
414
417
|
readCredentials,
|
|
415
418
|
upload,
|
|
416
419
|
validateApp,
|
|
@@ -404,13 +404,13 @@ const sessionAuthFile = () => {
|
|
|
404
404
|
obj(
|
|
405
405
|
objProperty('key', strLiteral('username')),
|
|
406
406
|
objProperty('label', strLiteral('Username')),
|
|
407
|
-
objProperty('required',
|
|
407
|
+
objProperty('required', 'true')
|
|
408
408
|
),
|
|
409
409
|
obj(
|
|
410
410
|
objProperty('key', strLiteral('password')),
|
|
411
411
|
objProperty('label', strLiteral('Password')),
|
|
412
412
|
objProperty('required', 'true'),
|
|
413
|
-
comment('this lets the user enter
|
|
413
|
+
comment('this lets the user enter masked data'),
|
|
414
414
|
objProperty('type', strLiteral('password'))
|
|
415
415
|
),
|
|
416
416
|
],
|
package/src/utils/convert.js
CHANGED
|
@@ -167,7 +167,9 @@ const renderStep = (type, definition) => {
|
|
|
167
167
|
if (func && func.source) {
|
|
168
168
|
const args = func.args || ['z', 'bundle'];
|
|
169
169
|
functionBlock.push(
|
|
170
|
-
`const ${funcName} = (${args.join(', ')}) => {\n${
|
|
170
|
+
`const ${funcName} = async (${args.join(', ')}) => {\n${
|
|
171
|
+
func.source
|
|
172
|
+
}\n};`
|
|
171
173
|
);
|
|
172
174
|
|
|
173
175
|
exportBlock.operation[funcName] = makePlaceholder(funcName);
|
|
@@ -188,7 +190,7 @@ const renderStep = (type, definition) => {
|
|
|
188
190
|
funcNum ? funcNum++ : ++funcNum && ''
|
|
189
191
|
}`;
|
|
190
192
|
functionBlock.push(
|
|
191
|
-
`const ${funcName} = (${args.join(', ')}) => {\n${
|
|
193
|
+
`const ${funcName} = async (${args.join(', ')}) => {\n${
|
|
192
194
|
maybeFunc.source
|
|
193
195
|
}\n};`
|
|
194
196
|
);
|
|
@@ -277,7 +279,7 @@ const renderAuth = async (appDefinition) => {
|
|
|
277
279
|
if (func && func.source) {
|
|
278
280
|
const args = func.args || ['z', 'bundle'];
|
|
279
281
|
functionBlock.push(
|
|
280
|
-
`const ${funcName} = (${args.join(', ')}) => {${func.source}};`
|
|
282
|
+
`const ${funcName} = async (${args.join(', ')}) => {${func.source}};`
|
|
281
283
|
);
|
|
282
284
|
|
|
283
285
|
exportBlock[key] = makePlaceholder(funcName);
|
|
@@ -302,7 +304,7 @@ const renderHydrators = async (appDefinition) => {
|
|
|
302
304
|
if (func && func.source) {
|
|
303
305
|
const args = func.args || ['z', 'bundle'];
|
|
304
306
|
functionBlock.push(
|
|
305
|
-
`const ${funcName} = (${args.join(', ')}) => {${func.source}};`
|
|
307
|
+
`const ${funcName} = async (${args.join(', ')}) => {${func.source}};`
|
|
306
308
|
);
|
|
307
309
|
exportBlock[funcName] = makePlaceholder(funcName);
|
|
308
310
|
}
|
|
@@ -347,9 +349,8 @@ const renderIndex = async (appDefinition) => {
|
|
|
347
349
|
importBlock.push(`const ${importName} = require('${filepath}');`);
|
|
348
350
|
|
|
349
351
|
delete exportBlock[stepType][key];
|
|
350
|
-
exportBlock[stepType][
|
|
351
|
-
makePlaceholder(
|
|
352
|
-
] = makePlaceholder(importName);
|
|
352
|
+
exportBlock[stepType][makePlaceholder(`[${importName}.key]`)] =
|
|
353
|
+
makePlaceholder(importName);
|
|
353
354
|
});
|
|
354
355
|
}
|
|
355
356
|
);
|
|
@@ -368,7 +369,7 @@ const renderIndex = async (appDefinition) => {
|
|
|
368
369
|
const args = func.args || ['z', 'bundle'];
|
|
369
370
|
const funcName = middlewareType;
|
|
370
371
|
functionBlock.push(
|
|
371
|
-
`const ${funcName} = (${args.join(', ')}) => {${func.source}};`
|
|
372
|
+
`const ${funcName} = async (${args.join(', ')}) => {${func.source}};`
|
|
372
373
|
);
|
|
373
374
|
|
|
374
375
|
exportBlock[middlewareType][0] = makePlaceholder(funcName);
|
package/src/utils/npm.js
CHANGED
|
@@ -11,9 +11,7 @@ const getPackageLatestVersion = async (name) => {
|
|
|
11
11
|
|
|
12
12
|
const getPackageSize = async (name, version) => {
|
|
13
13
|
const baseUrl = `${BASE_URL}/${name}`;
|
|
14
|
-
const res = await fetch(`${baseUrl}/-/${name}-${version}.tgz
|
|
15
|
-
method: 'HEAD',
|
|
16
|
-
});
|
|
14
|
+
const res = await fetch(`${baseUrl}/-/${name}-${version}.tgz`);
|
|
17
15
|
return res.headers.get('content-length');
|
|
18
16
|
};
|
|
19
17
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const { pathExists } = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const packageManagers = [
|
|
5
|
+
{
|
|
6
|
+
lockFile: 'package-lock.json',
|
|
7
|
+
forceFlag: undefined,
|
|
8
|
+
executable: 'npm',
|
|
9
|
+
useDoubleHyphenBeforeArgs: true,
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
lockFile: 'yarn.lock',
|
|
13
|
+
forceFlag: 'yarn',
|
|
14
|
+
executable: 'yarn',
|
|
15
|
+
useDoubleHyphenBeforeArgs: false, // yarn gives a warning if we include `--`
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
lockFile: 'pnpm-lock.yaml',
|
|
19
|
+
forceFlag: 'pnpm',
|
|
20
|
+
executable: 'pnpm',
|
|
21
|
+
useDoubleHyphenBeforeArgs: true,
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const defaultPackageManager = packageManagers[0];
|
|
26
|
+
|
|
27
|
+
const getPackageManager = async (flags) => {
|
|
28
|
+
for (const man of packageManagers) {
|
|
29
|
+
if (flags[man.forceFlag]) {
|
|
30
|
+
return man;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
for (const man of packageManagers) {
|
|
35
|
+
if (await pathExists(path.join(process.cwd(), man.lockFile))) {
|
|
36
|
+
return man;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return defaultPackageManager;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
module.exports = {
|
|
44
|
+
getPackageManager,
|
|
45
|
+
};
|