@zapier/zapier-sdk-cli 0.32.4 → 0.34.1
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/CHANGELOG.md +28 -0
- package/README.md +39 -2
- package/dist/cli.cjs +589 -110
- package/dist/cli.mjs +580 -102
- package/dist/index.cjs +531 -18
- package/dist/index.mjs +525 -15
- package/dist/package.json +3 -2
- package/dist/src/cli.js +11 -1
- package/dist/src/paths.d.ts +1 -0
- package/dist/src/paths.js +6 -0
- package/dist/src/plugins/index.d.ts +1 -0
- package/dist/src/plugins/index.js +1 -0
- package/dist/src/plugins/init/display.d.ts +9 -0
- package/dist/src/plugins/init/display.js +72 -0
- package/dist/src/plugins/init/index.d.ts +16 -0
- package/dist/src/plugins/init/index.js +61 -0
- package/dist/src/plugins/init/schemas.d.ts +8 -0
- package/dist/src/plugins/init/schemas.js +14 -0
- package/dist/src/plugins/init/steps.d.ts +39 -0
- package/dist/src/plugins/init/steps.js +141 -0
- package/dist/src/plugins/init/types.d.ts +31 -0
- package/dist/src/plugins/init/types.js +1 -0
- package/dist/src/plugins/init/utils.d.ts +48 -0
- package/dist/src/plugins/init/utils.js +135 -0
- package/dist/src/plugins/logout/index.js +1 -1
- package/dist/src/sdk.js +5 -2
- package/dist/src/utils/auth/login.js +33 -4
- package/dist/src/utils/package-manager-detector.d.ts +3 -1
- package/dist/src/utils/package-manager-detector.js +1 -0
- package/dist/src/utils/version-checker.js +1 -8
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -5
- package/templates/basic/AGENTS.md.hbs +15 -0
- package/templates/basic/README.md.hbs +21 -0
- package/templates/basic/package.json.hbs +17 -0
- package/templates/basic/src/index.ts +46 -0
- package/templates/basic/tsconfig.json +12 -0
package/dist/index.cjs
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var cliLogin = require('@zapier/zapier-sdk-cli-login');
|
|
3
4
|
var zapierSdk = require('@zapier/zapier-sdk');
|
|
4
5
|
var open = require('open');
|
|
5
6
|
var crypto = require('crypto');
|
|
6
7
|
var express = require('express');
|
|
7
8
|
var pkceChallenge = require('pkce-challenge');
|
|
8
|
-
var zapierSdkCliLogin = require('@zapier/zapier-sdk-cli-login');
|
|
9
9
|
var ora = require('ora');
|
|
10
|
-
var
|
|
10
|
+
var chalk3 = require('chalk');
|
|
11
|
+
var inquirer = require('inquirer');
|
|
11
12
|
var zod = require('zod');
|
|
12
13
|
var zapierSdkMcp = require('@zapier/zapier-sdk-mcp');
|
|
13
14
|
var esbuild = require('esbuild');
|
|
@@ -15,7 +16,12 @@ var fs = require('fs');
|
|
|
15
16
|
var path = require('path');
|
|
16
17
|
var promises = require('fs/promises');
|
|
17
18
|
var ts = require('typescript');
|
|
19
|
+
require('is-installed-globally');
|
|
20
|
+
var child_process = require('child_process');
|
|
21
|
+
var Handlebars = require('handlebars');
|
|
22
|
+
var url = require('url');
|
|
18
23
|
|
|
24
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
19
25
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
20
26
|
|
|
21
27
|
function _interopNamespace(e) {
|
|
@@ -36,15 +42,18 @@ function _interopNamespace(e) {
|
|
|
36
42
|
return Object.freeze(n);
|
|
37
43
|
}
|
|
38
44
|
|
|
45
|
+
var cliLogin__namespace = /*#__PURE__*/_interopNamespace(cliLogin);
|
|
39
46
|
var open__default = /*#__PURE__*/_interopDefault(open);
|
|
40
47
|
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
41
48
|
var express__default = /*#__PURE__*/_interopDefault(express);
|
|
42
49
|
var pkceChallenge__default = /*#__PURE__*/_interopDefault(pkceChallenge);
|
|
43
50
|
var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
44
|
-
var
|
|
51
|
+
var chalk3__default = /*#__PURE__*/_interopDefault(chalk3);
|
|
52
|
+
var inquirer__default = /*#__PURE__*/_interopDefault(inquirer);
|
|
45
53
|
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
46
54
|
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
47
55
|
var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
|
|
56
|
+
var Handlebars__default = /*#__PURE__*/_interopDefault(Handlebars);
|
|
48
57
|
|
|
49
58
|
// src/sdk.ts
|
|
50
59
|
var LOGIN_PORTS = [49505, 50575, 52804, 55981, 61010, 63851];
|
|
@@ -59,6 +68,14 @@ var ZapierCliUserCancellationError = class extends ZapierCliError {
|
|
|
59
68
|
this.exitCode = 0;
|
|
60
69
|
}
|
|
61
70
|
};
|
|
71
|
+
var ZapierCliExitError = class extends ZapierCliError {
|
|
72
|
+
constructor(message, exitCode = 1) {
|
|
73
|
+
super(message);
|
|
74
|
+
this.name = "ZapierCliExitError";
|
|
75
|
+
this.code = "ZAPIER_CLI_EXIT";
|
|
76
|
+
this.exitCode = exitCode;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
62
79
|
|
|
63
80
|
// src/utils/spinner.ts
|
|
64
81
|
var spinPromise = async (promise, text) => {
|
|
@@ -78,20 +95,20 @@ var spinPromise = async (promise, text) => {
|
|
|
78
95
|
};
|
|
79
96
|
var log = {
|
|
80
97
|
info: (message, ...args) => {
|
|
81
|
-
console.log(
|
|
98
|
+
console.log(chalk3__default.default.blue("\u2139"), message, ...args);
|
|
82
99
|
},
|
|
83
100
|
error: (message, ...args) => {
|
|
84
|
-
console.error(
|
|
101
|
+
console.error(chalk3__default.default.red("\u2716"), message, ...args);
|
|
85
102
|
},
|
|
86
103
|
success: (message, ...args) => {
|
|
87
|
-
console.log(
|
|
104
|
+
console.log(chalk3__default.default.green("\u2713"), message, ...args);
|
|
88
105
|
},
|
|
89
106
|
warn: (message, ...args) => {
|
|
90
|
-
console.log(
|
|
107
|
+
console.log(chalk3__default.default.yellow("\u26A0"), message, ...args);
|
|
91
108
|
},
|
|
92
109
|
debug: (message, ...args) => {
|
|
93
110
|
if (process.env.DEBUG === "true" || process.argv.includes("--debug")) {
|
|
94
|
-
console.log(
|
|
111
|
+
console.log(chalk3__default.default.gray("\u{1F41B}"), message, ...args);
|
|
95
112
|
}
|
|
96
113
|
}
|
|
97
114
|
};
|
|
@@ -192,13 +209,13 @@ var login = async ({
|
|
|
192
209
|
timeoutMs = LOGIN_TIMEOUT_MS,
|
|
193
210
|
credentials
|
|
194
211
|
}) => {
|
|
195
|
-
const { clientId, tokenUrl, authorizeUrl } =
|
|
212
|
+
const { clientId, tokenUrl, authorizeUrl } = cliLogin.getPkceLoginConfig({
|
|
196
213
|
credentials
|
|
197
214
|
});
|
|
198
215
|
const scope = ensureOfflineAccess(
|
|
199
216
|
credentials?.scope || "internal credentials"
|
|
200
217
|
);
|
|
201
|
-
|
|
218
|
+
await cliLogin.logout();
|
|
202
219
|
const availablePort = await findAvailablePort();
|
|
203
220
|
const redirectUri = `http://localhost:${availablePort}/oauth`;
|
|
204
221
|
log_default.info(`Using port ${availablePort} for OAuth callback`);
|
|
@@ -286,12 +303,37 @@ var login = async ({
|
|
|
286
303
|
},
|
|
287
304
|
{
|
|
288
305
|
headers: {
|
|
289
|
-
[
|
|
306
|
+
[cliLogin.AUTH_MODE_HEADER]: "no",
|
|
290
307
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
291
308
|
}
|
|
292
309
|
}
|
|
293
310
|
);
|
|
294
|
-
|
|
311
|
+
let targetStorage;
|
|
312
|
+
if (cliLogin.getLoginStorageMode() === "config") {
|
|
313
|
+
const { upgrade } = await inquirer__default.default.prompt([
|
|
314
|
+
{
|
|
315
|
+
type: "confirm",
|
|
316
|
+
name: "upgrade",
|
|
317
|
+
message: "Would you like to upgrade to system keychain storage? This is recommended to securely store your credentials. However, note that older SDK/CLI versions will NOT be able to read these credentials, so you will want to upgrade them to the latest version.",
|
|
318
|
+
default: true
|
|
319
|
+
}
|
|
320
|
+
]);
|
|
321
|
+
targetStorage = upgrade ? "keychain" : "config";
|
|
322
|
+
} else {
|
|
323
|
+
targetStorage = "keychain";
|
|
324
|
+
}
|
|
325
|
+
try {
|
|
326
|
+
await cliLogin.updateLogin(data, { storage: targetStorage });
|
|
327
|
+
} catch (err) {
|
|
328
|
+
if (targetStorage === "keychain") {
|
|
329
|
+
log_default.warn(
|
|
330
|
+
`Could not store credentials in system keychain. Storing in plaintext at ${cliLogin.getConfigPath()}.`
|
|
331
|
+
);
|
|
332
|
+
await cliLogin.updateLogin(data, { storage: "config" });
|
|
333
|
+
} else {
|
|
334
|
+
throw err;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
295
337
|
log_default.info("Token exchange completed successfully");
|
|
296
338
|
return data.access_token;
|
|
297
339
|
};
|
|
@@ -302,7 +344,7 @@ var LoginSchema = zod.z.object({
|
|
|
302
344
|
|
|
303
345
|
// package.json
|
|
304
346
|
var package_default = {
|
|
305
|
-
version: "0.
|
|
347
|
+
version: "0.34.1"};
|
|
306
348
|
|
|
307
349
|
// src/telemetry/builders.ts
|
|
308
350
|
function createCliBaseEvent(context = {}) {
|
|
@@ -388,7 +430,7 @@ var loginPlugin = ({ context }) => {
|
|
|
388
430
|
timeoutMs: timeoutSeconds * 1e3,
|
|
389
431
|
credentials: pkceCredentials
|
|
390
432
|
});
|
|
391
|
-
const user = await
|
|
433
|
+
const user = await cliLogin.getLoggedInUser();
|
|
392
434
|
accountId = user.accountId;
|
|
393
435
|
customUserId = user.customUserId;
|
|
394
436
|
console.log(`\u2705 Successfully logged in as ${user.email}`);
|
|
@@ -441,7 +483,7 @@ var LogoutSchema = zod.z.object({}).describe("Log out of your Zapier account");
|
|
|
441
483
|
|
|
442
484
|
// src/plugins/logout/index.ts
|
|
443
485
|
var logoutWithSdk = zapierSdk.createFunction(async function logoutWithSdk2(_options) {
|
|
444
|
-
|
|
486
|
+
await cliLogin.logout();
|
|
445
487
|
console.log("\u2705 Successfully logged out");
|
|
446
488
|
}, LogoutSchema);
|
|
447
489
|
var logoutPlugin = () => ({
|
|
@@ -575,7 +617,7 @@ var GetLoginConfigPathSchema = zod.z.object({}).describe("Show the path to the l
|
|
|
575
617
|
var getLoginConfigPathPlugin = () => {
|
|
576
618
|
const getLoginConfigPathWithSdk = zapierSdk.createFunction(
|
|
577
619
|
async function getLoginConfigPathWithSdk2(_options) {
|
|
578
|
-
return
|
|
620
|
+
return cliLogin.getConfigPath();
|
|
579
621
|
},
|
|
580
622
|
GetLoginConfigPathSchema
|
|
581
623
|
);
|
|
@@ -1610,7 +1652,7 @@ var feedbackPlugin = ({
|
|
|
1610
1652
|
}) => {
|
|
1611
1653
|
const debug = context.options.debug;
|
|
1612
1654
|
const feedbackWithSdk = zapierSdk.createFunction(async function feedback(options) {
|
|
1613
|
-
const user = await
|
|
1655
|
+
const user = await cliLogin.getLoggedInUser();
|
|
1614
1656
|
const body = JSON.stringify({
|
|
1615
1657
|
email: user.email,
|
|
1616
1658
|
customuser_id: user.customUserId,
|
|
@@ -2070,13 +2112,484 @@ var cliOverridesPlugin = ({ context }) => {
|
|
|
2070
2112
|
}
|
|
2071
2113
|
};
|
|
2072
2114
|
};
|
|
2115
|
+
var TEMPLATES = ["basic"];
|
|
2116
|
+
var InitSchema = zod.z.object({
|
|
2117
|
+
projectName: zod.z.string().min(1).describe("Name of the project directory to create"),
|
|
2118
|
+
skipPrompts: zod.z.boolean().optional().describe("Skip all interactive prompts and accept all defaults")
|
|
2119
|
+
}).describe(
|
|
2120
|
+
"Create a new Zapier SDK project in a new directory with starter files"
|
|
2121
|
+
);
|
|
2122
|
+
function detectPackageManager(cwd = process.cwd()) {
|
|
2123
|
+
const ua = process.env.npm_config_user_agent;
|
|
2124
|
+
if (ua) {
|
|
2125
|
+
if (ua.includes("yarn")) return { name: "yarn", source: "runtime" };
|
|
2126
|
+
if (ua.includes("pnpm")) return { name: "pnpm", source: "runtime" };
|
|
2127
|
+
if (ua.includes("bun")) return { name: "bun", source: "runtime" };
|
|
2128
|
+
if (ua.includes("npm")) return { name: "npm", source: "runtime" };
|
|
2129
|
+
}
|
|
2130
|
+
const files = [
|
|
2131
|
+
["pnpm-lock.yaml", "pnpm"],
|
|
2132
|
+
["yarn.lock", "yarn"],
|
|
2133
|
+
["bun.lockb", "bun"],
|
|
2134
|
+
["package-lock.json", "npm"]
|
|
2135
|
+
];
|
|
2136
|
+
for (const [file, name] of files) {
|
|
2137
|
+
if (fs.existsSync(path.join(cwd, file))) {
|
|
2138
|
+
return { name, source: "lockfile" };
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
return { name: "unknown", source: "fallback" };
|
|
2142
|
+
}
|
|
2143
|
+
function getDirentParentPath(entry) {
|
|
2144
|
+
const e = entry;
|
|
2145
|
+
const parent = e.parentPath ?? e.path;
|
|
2146
|
+
if (!parent)
|
|
2147
|
+
throw new Error(
|
|
2148
|
+
"readdirSync entry missing parentPath/path \u2014 unsupported Node version"
|
|
2149
|
+
);
|
|
2150
|
+
return parent;
|
|
2151
|
+
}
|
|
2152
|
+
function toProjectName(name) {
|
|
2153
|
+
return name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
2154
|
+
}
|
|
2155
|
+
function validateInitOptions({
|
|
2156
|
+
rawName,
|
|
2157
|
+
cwd
|
|
2158
|
+
}) {
|
|
2159
|
+
const projectName = toProjectName(rawName);
|
|
2160
|
+
if (!projectName) {
|
|
2161
|
+
throw new Error(
|
|
2162
|
+
`"${rawName}" results in an empty project name. Provide a name with at least one letter or number.`
|
|
2163
|
+
);
|
|
2164
|
+
}
|
|
2165
|
+
const projectDir = path.join(cwd, projectName);
|
|
2166
|
+
if (fs.existsSync(projectDir)) {
|
|
2167
|
+
const contents = fs.readdirSync(projectDir);
|
|
2168
|
+
if (contents.length > 0) {
|
|
2169
|
+
throw new Error(
|
|
2170
|
+
`Directory "${projectName}" already exists and is not empty. Choose a different name.`
|
|
2171
|
+
);
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
return { projectName, projectDir };
|
|
2175
|
+
}
|
|
2176
|
+
function createExec({ cwd }) {
|
|
2177
|
+
return (cmd) => child_process.execSync(cmd, {
|
|
2178
|
+
cwd,
|
|
2179
|
+
stdio: "inherit",
|
|
2180
|
+
shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh"
|
|
2181
|
+
});
|
|
2182
|
+
}
|
|
2183
|
+
async function promptYesNo({
|
|
2184
|
+
message,
|
|
2185
|
+
defaultValue,
|
|
2186
|
+
skipPrompts
|
|
2187
|
+
}) {
|
|
2188
|
+
if (skipPrompts) return defaultValue;
|
|
2189
|
+
const { answer } = await inquirer__default.default.prompt([
|
|
2190
|
+
{ type: "confirm", name: "answer", message, default: defaultValue }
|
|
2191
|
+
]);
|
|
2192
|
+
return answer;
|
|
2193
|
+
}
|
|
2194
|
+
function getPackageManagerCommands({
|
|
2195
|
+
packageManager
|
|
2196
|
+
}) {
|
|
2197
|
+
return {
|
|
2198
|
+
installCmd: `${packageManager} install`,
|
|
2199
|
+
devCmd: packageManager === "yarn" ? "yarn dev" : `${packageManager} run dev`,
|
|
2200
|
+
devScript: packageManager === "bun" ? "bun src/index.ts" : "tsx src/index.ts",
|
|
2201
|
+
execCmd: {
|
|
2202
|
+
npm: "npx",
|
|
2203
|
+
yarn: "yarn dlx",
|
|
2204
|
+
pnpm: "pnpm dlx",
|
|
2205
|
+
bun: "bunx"
|
|
2206
|
+
}[packageManager]
|
|
2207
|
+
};
|
|
2208
|
+
}
|
|
2209
|
+
function isTemplateFile(name) {
|
|
2210
|
+
return path.extname(name) === ".hbs";
|
|
2211
|
+
}
|
|
2212
|
+
function getDestRelPath(relPath, isTemplate) {
|
|
2213
|
+
return isTemplate ? relPath.slice(0, -path.extname(relPath).length) : relPath;
|
|
2214
|
+
}
|
|
2215
|
+
function renderTemplate(srcPath, variables) {
|
|
2216
|
+
const source = fs.readFileSync(srcPath, "utf-8");
|
|
2217
|
+
const template = Handlebars__default.default.compile(source, { noEscape: true });
|
|
2218
|
+
return template(variables);
|
|
2219
|
+
}
|
|
2220
|
+
function buildTemplateVariables({
|
|
2221
|
+
projectName,
|
|
2222
|
+
packageManager
|
|
2223
|
+
}) {
|
|
2224
|
+
const { execCmd, devScript, devCmd } = getPackageManagerCommands({
|
|
2225
|
+
packageManager
|
|
2226
|
+
});
|
|
2227
|
+
return {
|
|
2228
|
+
projectName,
|
|
2229
|
+
execCmd,
|
|
2230
|
+
devScript,
|
|
2231
|
+
devCmd,
|
|
2232
|
+
includeTsx: packageManager !== "bun"
|
|
2233
|
+
};
|
|
2234
|
+
}
|
|
2235
|
+
function cleanupProject({ projectDir }) {
|
|
2236
|
+
console.log("\n" + chalk3__default.default.yellow("!") + " Cleaning up...");
|
|
2237
|
+
fs.rmSync(projectDir, { recursive: true, force: true });
|
|
2238
|
+
}
|
|
2239
|
+
async function withInterruptCleanup(cleanup, fn) {
|
|
2240
|
+
if (!cleanup) return fn();
|
|
2241
|
+
const handler = () => {
|
|
2242
|
+
cleanup();
|
|
2243
|
+
process.removeListener("SIGINT", handler);
|
|
2244
|
+
process.kill(process.pid, "SIGINT");
|
|
2245
|
+
};
|
|
2246
|
+
process.on("SIGINT", handler);
|
|
2247
|
+
try {
|
|
2248
|
+
return await fn();
|
|
2249
|
+
} finally {
|
|
2250
|
+
process.removeListener("SIGINT", handler);
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
function createProjectDir({
|
|
2254
|
+
projectDir,
|
|
2255
|
+
projectName
|
|
2256
|
+
}) {
|
|
2257
|
+
try {
|
|
2258
|
+
fs.mkdirSync(projectDir, { recursive: true });
|
|
2259
|
+
} catch (err) {
|
|
2260
|
+
if (err instanceof Error) {
|
|
2261
|
+
const code = err.code;
|
|
2262
|
+
if (code === "EACCES") {
|
|
2263
|
+
throw new Error(
|
|
2264
|
+
`Permission denied creating "${projectName}". Check directory permissions.`
|
|
2265
|
+
);
|
|
2266
|
+
}
|
|
2267
|
+
if (code === "ENOSPC") {
|
|
2268
|
+
throw new Error("No space left on device.");
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
throw err;
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
var TEMPLATES_DIR = url.fileURLToPath(
|
|
2275
|
+
new URL("../templates", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))
|
|
2276
|
+
);
|
|
2277
|
+
|
|
2278
|
+
// src/plugins/init/steps.ts
|
|
2279
|
+
var DEFAULT_TEMPLATE = "basic";
|
|
2280
|
+
function getTemplateDir({
|
|
2281
|
+
template = DEFAULT_TEMPLATE
|
|
2282
|
+
} = {}) {
|
|
2283
|
+
const dirPath = path.join(TEMPLATES_DIR, template);
|
|
2284
|
+
if (!fs.existsSync(dirPath)) {
|
|
2285
|
+
throw new Error(
|
|
2286
|
+
`Template "${template}" not found at ${dirPath}. Available templates: ${TEMPLATES.join(", ")}`
|
|
2287
|
+
);
|
|
2288
|
+
}
|
|
2289
|
+
return dirPath;
|
|
2290
|
+
}
|
|
2291
|
+
function scaffoldFiles({
|
|
2292
|
+
projectDir,
|
|
2293
|
+
templatesDir,
|
|
2294
|
+
variables = {},
|
|
2295
|
+
displayHooks
|
|
2296
|
+
}) {
|
|
2297
|
+
const entries = fs.readdirSync(templatesDir, {
|
|
2298
|
+
withFileTypes: true,
|
|
2299
|
+
recursive: true
|
|
2300
|
+
});
|
|
2301
|
+
const files = entries.filter((e) => e.isFile());
|
|
2302
|
+
if (files.length === 0) {
|
|
2303
|
+
throw new Error(`Template directory "${templatesDir}" contains no files.`);
|
|
2304
|
+
}
|
|
2305
|
+
for (const entry of files) {
|
|
2306
|
+
const srcPath = path.join(getDirentParentPath(entry), entry.name);
|
|
2307
|
+
const relPath = path.relative(templatesDir, srcPath);
|
|
2308
|
+
const isTemplate = isTemplateFile(entry.name);
|
|
2309
|
+
const destRelPath = getDestRelPath(relPath, isTemplate);
|
|
2310
|
+
const destPath = path.join(projectDir, destRelPath);
|
|
2311
|
+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
2312
|
+
if (isTemplate) {
|
|
2313
|
+
fs.writeFileSync(destPath, renderTemplate(srcPath, variables));
|
|
2314
|
+
} else {
|
|
2315
|
+
fs.copyFileSync(srcPath, destPath);
|
|
2316
|
+
}
|
|
2317
|
+
displayHooks?.onItemComplete?.(destRelPath);
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
function scaffoldProject({
|
|
2321
|
+
projectDir,
|
|
2322
|
+
projectName,
|
|
2323
|
+
packageManager,
|
|
2324
|
+
template,
|
|
2325
|
+
displayHooks
|
|
2326
|
+
}) {
|
|
2327
|
+
const variables = buildTemplateVariables({ projectName, packageManager });
|
|
2328
|
+
const templatesDir = getTemplateDir({ template });
|
|
2329
|
+
createProjectDir({ projectDir, projectName });
|
|
2330
|
+
scaffoldFiles({ projectDir, templatesDir, variables, displayHooks });
|
|
2331
|
+
}
|
|
2332
|
+
async function runStep({
|
|
2333
|
+
step,
|
|
2334
|
+
stepNumber,
|
|
2335
|
+
totalSteps,
|
|
2336
|
+
skipPrompts,
|
|
2337
|
+
displayHooks
|
|
2338
|
+
}) {
|
|
2339
|
+
if (step.askConfirmation) {
|
|
2340
|
+
const should = await promptYesNo({
|
|
2341
|
+
message: step.description,
|
|
2342
|
+
defaultValue: true,
|
|
2343
|
+
skipPrompts
|
|
2344
|
+
});
|
|
2345
|
+
if (!should) return false;
|
|
2346
|
+
}
|
|
2347
|
+
displayHooks?.onStepStart({
|
|
2348
|
+
description: step.description,
|
|
2349
|
+
stepNumber,
|
|
2350
|
+
totalSteps,
|
|
2351
|
+
command: step.command,
|
|
2352
|
+
skipPrompts
|
|
2353
|
+
});
|
|
2354
|
+
try {
|
|
2355
|
+
await step.run();
|
|
2356
|
+
displayHooks?.onStepSuccess({ stepNumber, totalSteps });
|
|
2357
|
+
return true;
|
|
2358
|
+
} catch (err) {
|
|
2359
|
+
step.cleanup?.();
|
|
2360
|
+
displayHooks?.onStepError({
|
|
2361
|
+
description: step.description,
|
|
2362
|
+
command: step.command,
|
|
2363
|
+
err
|
|
2364
|
+
});
|
|
2365
|
+
return false;
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
function getInitSteps({
|
|
2369
|
+
projectDir,
|
|
2370
|
+
projectName,
|
|
2371
|
+
packageManager,
|
|
2372
|
+
template,
|
|
2373
|
+
displayHooks
|
|
2374
|
+
}) {
|
|
2375
|
+
if (template !== void 0 && !TEMPLATES.includes(template)) {
|
|
2376
|
+
throw new Error(
|
|
2377
|
+
`Unknown template "${template}". Available templates: ${TEMPLATES.join(", ")}`
|
|
2378
|
+
);
|
|
2379
|
+
}
|
|
2380
|
+
const { installCmd, execCmd, devCmd } = getPackageManagerCommands({
|
|
2381
|
+
packageManager
|
|
2382
|
+
});
|
|
2383
|
+
const exec = createExec({ cwd: projectDir });
|
|
2384
|
+
return [
|
|
2385
|
+
{
|
|
2386
|
+
id: "scaffold",
|
|
2387
|
+
description: "Scaffold project files",
|
|
2388
|
+
cleanup: () => cleanupProject({ projectDir }),
|
|
2389
|
+
run: () => scaffoldProject({
|
|
2390
|
+
projectDir,
|
|
2391
|
+
projectName,
|
|
2392
|
+
packageManager,
|
|
2393
|
+
template,
|
|
2394
|
+
displayHooks
|
|
2395
|
+
})
|
|
2396
|
+
},
|
|
2397
|
+
{
|
|
2398
|
+
id: "install-deps",
|
|
2399
|
+
description: "Install dependencies",
|
|
2400
|
+
askConfirmation: true,
|
|
2401
|
+
command: installCmd,
|
|
2402
|
+
run: () => exec(installCmd)
|
|
2403
|
+
},
|
|
2404
|
+
{
|
|
2405
|
+
id: "login",
|
|
2406
|
+
description: "Log in to Zapier",
|
|
2407
|
+
askConfirmation: true,
|
|
2408
|
+
command: `${execCmd} zapier-sdk login`,
|
|
2409
|
+
run: () => exec(`${execCmd} zapier-sdk login`)
|
|
2410
|
+
},
|
|
2411
|
+
{
|
|
2412
|
+
id: "run",
|
|
2413
|
+
description: "Run your app",
|
|
2414
|
+
askConfirmation: true,
|
|
2415
|
+
command: devCmd,
|
|
2416
|
+
run: () => exec(devCmd)
|
|
2417
|
+
}
|
|
2418
|
+
];
|
|
2419
|
+
}
|
|
2420
|
+
function buildNextSteps({
|
|
2421
|
+
projectName,
|
|
2422
|
+
leftoverSteps,
|
|
2423
|
+
execCmd
|
|
2424
|
+
}) {
|
|
2425
|
+
return [
|
|
2426
|
+
{
|
|
2427
|
+
description: "Change into your project directory",
|
|
2428
|
+
command: `cd ${projectName}`
|
|
2429
|
+
},
|
|
2430
|
+
...leftoverSteps.map(({ description, command }) => ({
|
|
2431
|
+
description,
|
|
2432
|
+
command
|
|
2433
|
+
})),
|
|
2434
|
+
{
|
|
2435
|
+
description: "Search for an app to integrate",
|
|
2436
|
+
command: `${execCmd} zapier-sdk list-apps --search "<app name>"`
|
|
2437
|
+
},
|
|
2438
|
+
{
|
|
2439
|
+
description: "Add an app and generate TypeScript types",
|
|
2440
|
+
command: `${execCmd} zapier-sdk add <app-key>`
|
|
2441
|
+
}
|
|
2442
|
+
];
|
|
2443
|
+
}
|
|
2444
|
+
function createConsoleDisplayHooks() {
|
|
2445
|
+
return {
|
|
2446
|
+
onItemComplete: (message) => console.log(" " + chalk3__default.default.green("\u2713") + " " + chalk3__default.default.dim(message)),
|
|
2447
|
+
onWarn: (message) => console.warn(chalk3__default.default.yellow("!") + " " + message),
|
|
2448
|
+
onStepStart: ({
|
|
2449
|
+
description,
|
|
2450
|
+
stepNumber,
|
|
2451
|
+
totalSteps,
|
|
2452
|
+
command,
|
|
2453
|
+
skipPrompts
|
|
2454
|
+
}) => {
|
|
2455
|
+
const progressMessage = `${description}...`;
|
|
2456
|
+
const stepCounter = chalk3__default.default.dim(`${stepNumber}/${totalSteps}`);
|
|
2457
|
+
if (skipPrompts) {
|
|
2458
|
+
console.log(
|
|
2459
|
+
"\n" + chalk3__default.default.bold(`\u276F ${progressMessage}`) + " " + stepCounter + "\n"
|
|
2460
|
+
);
|
|
2461
|
+
} else {
|
|
2462
|
+
console.log(
|
|
2463
|
+
chalk3__default.default.dim("\u2192") + " " + progressMessage + " " + stepCounter
|
|
2464
|
+
);
|
|
2465
|
+
}
|
|
2466
|
+
if (command) {
|
|
2467
|
+
console.log(" " + chalk3__default.default.cyan(`$ ${command}`));
|
|
2468
|
+
}
|
|
2469
|
+
},
|
|
2470
|
+
onStepSuccess: ({ stepNumber, totalSteps }) => console.log(
|
|
2471
|
+
"\n" + chalk3__default.default.green("\u2713") + " " + chalk3__default.default.dim(`Step ${stepNumber}/${totalSteps} complete`) + "\n"
|
|
2472
|
+
),
|
|
2473
|
+
onStepError: ({ description, command, err }) => {
|
|
2474
|
+
const detail = err instanceof Error && err.message ? `
|
|
2475
|
+
${chalk3__default.default.dim(err.message)}` : "";
|
|
2476
|
+
const hint = command ? `
|
|
2477
|
+
${chalk3__default.default.dim("run manually:")} ${chalk3__default.default.cyan(`$ ${command}`)}` : "";
|
|
2478
|
+
console.error(
|
|
2479
|
+
`
|
|
2480
|
+
${chalk3__default.default.red("\u2716")} ${chalk3__default.default.bold(description)}${chalk3__default.default.dim(" failed")}${detail}${hint}`
|
|
2481
|
+
);
|
|
2482
|
+
}
|
|
2483
|
+
};
|
|
2484
|
+
}
|
|
2485
|
+
function displaySummaryAndNextSteps({
|
|
2486
|
+
projectName,
|
|
2487
|
+
steps,
|
|
2488
|
+
completedSetupStepIds,
|
|
2489
|
+
packageManager
|
|
2490
|
+
}) {
|
|
2491
|
+
const formatStatus = (complete) => ({
|
|
2492
|
+
icon: complete ? chalk3__default.default.green("\u2713") : chalk3__default.default.yellow("!"),
|
|
2493
|
+
text: complete ? chalk3__default.default.green("Setup complete") : chalk3__default.default.yellow("Setup interrupted")
|
|
2494
|
+
});
|
|
2495
|
+
const formatNextStep = (step, i) => " " + chalk3__default.default.dim(`${i + 1}.`) + " " + chalk3__default.default.bold(step.description);
|
|
2496
|
+
const formatCommand = (cmd) => " " + chalk3__default.default.cyan(`$ ${cmd}`);
|
|
2497
|
+
const formatCompletedStep = (step) => " " + chalk3__default.default.green("\u2713") + " " + step.description;
|
|
2498
|
+
const { execCmd } = getPackageManagerCommands({ packageManager });
|
|
2499
|
+
const leftoverSteps = steps.filter(
|
|
2500
|
+
(s) => !completedSetupStepIds.includes(s.id)
|
|
2501
|
+
);
|
|
2502
|
+
const isComplete = leftoverSteps.length === 0;
|
|
2503
|
+
const status = formatStatus(isComplete);
|
|
2504
|
+
console.log("\n" + chalk3__default.default.bold("\u276F Summary") + "\n");
|
|
2505
|
+
console.log(" " + chalk3__default.default.dim("Project") + " " + chalk3__default.default.bold(projectName));
|
|
2506
|
+
console.log(
|
|
2507
|
+
" " + chalk3__default.default.dim("Status") + " " + status.icon + " " + status.text
|
|
2508
|
+
);
|
|
2509
|
+
const completedSteps = steps.filter(
|
|
2510
|
+
(s) => completedSetupStepIds.includes(s.id)
|
|
2511
|
+
);
|
|
2512
|
+
if (completedSteps.length > 0) {
|
|
2513
|
+
console.log();
|
|
2514
|
+
for (const step of completedSteps) console.log(formatCompletedStep(step));
|
|
2515
|
+
}
|
|
2516
|
+
const nextSteps = buildNextSteps({ projectName, leftoverSteps, execCmd });
|
|
2517
|
+
console.log("\n" + chalk3__default.default.bold("\u276F Next Steps") + "\n");
|
|
2518
|
+
nextSteps.forEach((step, i) => {
|
|
2519
|
+
console.log(formatNextStep(step, i));
|
|
2520
|
+
if (step.command) console.log(formatCommand(step.command));
|
|
2521
|
+
console.log();
|
|
2522
|
+
});
|
|
2523
|
+
}
|
|
2524
|
+
|
|
2525
|
+
// src/plugins/init/index.ts
|
|
2526
|
+
var initPlugin = () => {
|
|
2527
|
+
const init = zapierSdk.createFunction(async function init2(options) {
|
|
2528
|
+
const { projectName: rawName, skipPrompts = false } = options;
|
|
2529
|
+
const cwd = process.cwd();
|
|
2530
|
+
const { projectName, projectDir } = validateInitOptions({ rawName, cwd });
|
|
2531
|
+
const displayHooks = createConsoleDisplayHooks();
|
|
2532
|
+
const packageManagerInfo = detectPackageManager(cwd);
|
|
2533
|
+
if (packageManagerInfo.name === "unknown") {
|
|
2534
|
+
displayHooks.onWarn(
|
|
2535
|
+
"Could not detect package manager, defaulting to npm."
|
|
2536
|
+
);
|
|
2537
|
+
}
|
|
2538
|
+
const packageManager = packageManagerInfo.name === "unknown" ? "npm" : packageManagerInfo.name;
|
|
2539
|
+
const steps = getInitSteps({
|
|
2540
|
+
projectDir,
|
|
2541
|
+
projectName,
|
|
2542
|
+
packageManager,
|
|
2543
|
+
displayHooks
|
|
2544
|
+
});
|
|
2545
|
+
const completedSetupStepIds = [];
|
|
2546
|
+
for (let i = 0; i < steps.length; i++) {
|
|
2547
|
+
const step = steps[i];
|
|
2548
|
+
const succeeded = await withInterruptCleanup(
|
|
2549
|
+
step.cleanup,
|
|
2550
|
+
() => runStep({
|
|
2551
|
+
step,
|
|
2552
|
+
stepNumber: i + 1,
|
|
2553
|
+
totalSteps: steps.length,
|
|
2554
|
+
skipPrompts,
|
|
2555
|
+
displayHooks
|
|
2556
|
+
})
|
|
2557
|
+
);
|
|
2558
|
+
if (!succeeded) break;
|
|
2559
|
+
completedSetupStepIds.push(step.id);
|
|
2560
|
+
}
|
|
2561
|
+
if (completedSetupStepIds.length === 0) {
|
|
2562
|
+
throw new ZapierCliExitError(
|
|
2563
|
+
"Project setup failed \u2014 no steps completed."
|
|
2564
|
+
);
|
|
2565
|
+
}
|
|
2566
|
+
displaySummaryAndNextSteps({
|
|
2567
|
+
projectName,
|
|
2568
|
+
steps,
|
|
2569
|
+
completedSetupStepIds,
|
|
2570
|
+
packageManager
|
|
2571
|
+
});
|
|
2572
|
+
}, InitSchema);
|
|
2573
|
+
return {
|
|
2574
|
+
init,
|
|
2575
|
+
context: {
|
|
2576
|
+
meta: {
|
|
2577
|
+
init: {
|
|
2578
|
+
categories: ["utility"],
|
|
2579
|
+
inputSchema: InitSchema
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
}
|
|
2583
|
+
};
|
|
2584
|
+
};
|
|
2073
2585
|
|
|
2074
2586
|
// src/sdk.ts
|
|
2587
|
+
zapierSdk.injectCliLogin(cliLogin__namespace);
|
|
2075
2588
|
function createZapierCliSdk(options = {}) {
|
|
2076
2589
|
return zapierSdk.createZapierSdkWithoutRegistry({
|
|
2077
2590
|
...options,
|
|
2078
2591
|
eventEmission: { ...options.eventEmission, callContext: "cli" }
|
|
2079
|
-
}).addPlugin(generateAppTypesPlugin).addPlugin(buildManifestPlugin).addPlugin(bundleCodePlugin).addPlugin(getLoginConfigPathPlugin).addPlugin(addPlugin).addPlugin(feedbackPlugin).addPlugin(curlPlugin).addPlugin(mcpPlugin).addPlugin(loginPlugin).addPlugin(logoutPlugin).addPlugin(cliOverridesPlugin).addPlugin(zapierSdk.registryPlugin);
|
|
2592
|
+
}).addPlugin(generateAppTypesPlugin).addPlugin(buildManifestPlugin).addPlugin(bundleCodePlugin).addPlugin(getLoginConfigPathPlugin).addPlugin(addPlugin).addPlugin(feedbackPlugin).addPlugin(curlPlugin).addPlugin(initPlugin).addPlugin(mcpPlugin).addPlugin(loginPlugin).addPlugin(logoutPlugin).addPlugin(cliOverridesPlugin).addPlugin(zapierSdk.registryPlugin);
|
|
2080
2593
|
}
|
|
2081
2594
|
|
|
2082
2595
|
// src/utils/cli-options.ts
|