@wraps.dev/cli 1.2.0 → 1.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/dist/cli.js +624 -55
- package/dist/cli.js.map +1 -1
- package/dist/lambda/event-processor/.bundled +1 -1
- package/package.json +5 -2
package/dist/cli.js
CHANGED
|
@@ -4,6 +4,9 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
|
4
4
|
var __esm = (fn, res) => function __init() {
|
|
5
5
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
6
|
};
|
|
7
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
+
};
|
|
7
10
|
var __export = (target, all3) => {
|
|
8
11
|
for (var name in all3)
|
|
9
12
|
__defProp(target, name, { get: all3[name], enumerable: true });
|
|
@@ -18,12 +21,456 @@ var init_esm_shims = __esm({
|
|
|
18
21
|
}
|
|
19
22
|
});
|
|
20
23
|
|
|
24
|
+
// src/utils/shared/ci-detection.ts
|
|
25
|
+
function isCI() {
|
|
26
|
+
if (process.env.CI === "true" || process.env.CI === "1") {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
const ciEnvVars = [
|
|
30
|
+
"GITHUB_ACTIONS",
|
|
31
|
+
// GitHub Actions
|
|
32
|
+
"GITLAB_CI",
|
|
33
|
+
// GitLab CI
|
|
34
|
+
"CIRCLECI",
|
|
35
|
+
// CircleCI
|
|
36
|
+
"TRAVIS",
|
|
37
|
+
// Travis CI
|
|
38
|
+
"JENKINS_URL",
|
|
39
|
+
// Jenkins
|
|
40
|
+
"BUILDKITE",
|
|
41
|
+
// Buildkite
|
|
42
|
+
"DRONE",
|
|
43
|
+
// Drone
|
|
44
|
+
"SEMAPHORE",
|
|
45
|
+
// Semaphore
|
|
46
|
+
"TEAMCITY_VERSION",
|
|
47
|
+
// TeamCity
|
|
48
|
+
"TF_BUILD",
|
|
49
|
+
// Azure Pipelines
|
|
50
|
+
"CODEBUILD_BUILD_ID",
|
|
51
|
+
// AWS CodeBuild
|
|
52
|
+
"NETLIFY",
|
|
53
|
+
// Netlify
|
|
54
|
+
"VERCEL",
|
|
55
|
+
// Vercel
|
|
56
|
+
"HEROKU_TEST_RUN_ID",
|
|
57
|
+
// Heroku CI
|
|
58
|
+
"BUDDY",
|
|
59
|
+
// Buddy
|
|
60
|
+
"BITBUCKET_BUILD_NUMBER"
|
|
61
|
+
// Bitbucket Pipelines
|
|
62
|
+
];
|
|
63
|
+
return ciEnvVars.some((envVar) => process.env[envVar] !== void 0);
|
|
64
|
+
}
|
|
65
|
+
var init_ci_detection = __esm({
|
|
66
|
+
"src/utils/shared/ci-detection.ts"() {
|
|
67
|
+
"use strict";
|
|
68
|
+
init_esm_shims();
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// src/telemetry/config.ts
|
|
73
|
+
import Conf from "conf";
|
|
74
|
+
import { v4 as uuidv4 } from "uuid";
|
|
75
|
+
var CONFIG_DEFAULTS, TelemetryConfigManager;
|
|
76
|
+
var init_config = __esm({
|
|
77
|
+
"src/telemetry/config.ts"() {
|
|
78
|
+
"use strict";
|
|
79
|
+
init_esm_shims();
|
|
80
|
+
CONFIG_DEFAULTS = {
|
|
81
|
+
enabled: true,
|
|
82
|
+
anonymousId: uuidv4(),
|
|
83
|
+
notificationShown: false
|
|
84
|
+
};
|
|
85
|
+
TelemetryConfigManager = class {
|
|
86
|
+
config;
|
|
87
|
+
constructor() {
|
|
88
|
+
this.config = new Conf({
|
|
89
|
+
projectName: "wraps",
|
|
90
|
+
configName: "telemetry",
|
|
91
|
+
defaults: CONFIG_DEFAULTS
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Check if telemetry is enabled
|
|
96
|
+
*/
|
|
97
|
+
isEnabled() {
|
|
98
|
+
return this.config.get("enabled");
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Enable or disable telemetry
|
|
102
|
+
*/
|
|
103
|
+
setEnabled(enabled) {
|
|
104
|
+
this.config.set("enabled", enabled);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get the anonymous user ID
|
|
108
|
+
*/
|
|
109
|
+
getAnonymousId() {
|
|
110
|
+
return this.config.get("anonymousId");
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Check if the first-run notification has been shown
|
|
114
|
+
*/
|
|
115
|
+
hasShownNotification() {
|
|
116
|
+
return this.config.get("notificationShown");
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Mark the first-run notification as shown
|
|
120
|
+
*/
|
|
121
|
+
markNotificationShown() {
|
|
122
|
+
this.config.set("notificationShown", true);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get the full path to the configuration file
|
|
126
|
+
*/
|
|
127
|
+
getConfigPath() {
|
|
128
|
+
return this.config.path;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Reset configuration to defaults
|
|
132
|
+
*/
|
|
133
|
+
reset() {
|
|
134
|
+
this.config.clear();
|
|
135
|
+
this.config.set({
|
|
136
|
+
...CONFIG_DEFAULTS,
|
|
137
|
+
anonymousId: uuidv4()
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// package.json
|
|
145
|
+
var require_package = __commonJS({
|
|
146
|
+
"package.json"(exports, module) {
|
|
147
|
+
module.exports = {
|
|
148
|
+
name: "@wraps.dev/cli",
|
|
149
|
+
version: "1.3.0",
|
|
150
|
+
description: "CLI for deploying Wraps email infrastructure to your AWS account",
|
|
151
|
+
type: "module",
|
|
152
|
+
main: "./dist/cli.js",
|
|
153
|
+
bin: {
|
|
154
|
+
wraps: "./dist/cli.js"
|
|
155
|
+
},
|
|
156
|
+
files: [
|
|
157
|
+
"dist",
|
|
158
|
+
"README.md",
|
|
159
|
+
"LICENSE"
|
|
160
|
+
],
|
|
161
|
+
repository: {
|
|
162
|
+
type: "git",
|
|
163
|
+
url: "https://github.com/wraps-team/wraps.git",
|
|
164
|
+
directory: "packages/cli"
|
|
165
|
+
},
|
|
166
|
+
homepage: "https://wraps.dev",
|
|
167
|
+
bugs: {
|
|
168
|
+
url: "https://github.com/wraps-team/wraps/issues"
|
|
169
|
+
},
|
|
170
|
+
publishConfig: {
|
|
171
|
+
access: "public"
|
|
172
|
+
},
|
|
173
|
+
scripts: {
|
|
174
|
+
dev: "tsup --watch",
|
|
175
|
+
build: "pnpm build:console && pnpm build:lambda && tsup",
|
|
176
|
+
"build:lambda": "tsx scripts/build-lambda.ts",
|
|
177
|
+
"build:console": "pnpm --filter @wraps/console build",
|
|
178
|
+
test: "vitest run",
|
|
179
|
+
"test:watch": "vitest --watch",
|
|
180
|
+
"test:ui": "vitest --ui",
|
|
181
|
+
"test:coverage": "vitest run --coverage",
|
|
182
|
+
typecheck: "tsc --noEmit",
|
|
183
|
+
lint: "eslint src",
|
|
184
|
+
prepublishOnly: "pnpm build"
|
|
185
|
+
},
|
|
186
|
+
keywords: [
|
|
187
|
+
"aws",
|
|
188
|
+
"ses",
|
|
189
|
+
"email",
|
|
190
|
+
"infrastructure",
|
|
191
|
+
"cli"
|
|
192
|
+
],
|
|
193
|
+
author: "Wraps",
|
|
194
|
+
license: "MIT",
|
|
195
|
+
dependencies: {
|
|
196
|
+
"@aws-sdk/client-acm": "3.933.0",
|
|
197
|
+
"@aws-sdk/client-cloudformation": "^3.490.0",
|
|
198
|
+
"@aws-sdk/client-cloudfront": "3.933.0",
|
|
199
|
+
"@aws-sdk/client-cloudwatch": "^3.490.0",
|
|
200
|
+
"@aws-sdk/client-dynamodb": "^3.490.0",
|
|
201
|
+
"@aws-sdk/client-iam": "3.932.0",
|
|
202
|
+
"@aws-sdk/client-lambda": "3.925.0",
|
|
203
|
+
"@aws-sdk/client-mailmanager": "3.925.0",
|
|
204
|
+
"@aws-sdk/client-route-53": "3.925.0",
|
|
205
|
+
"@aws-sdk/client-ses": "^3.490.0",
|
|
206
|
+
"@aws-sdk/client-sesv2": "3.925.0",
|
|
207
|
+
"@aws-sdk/client-sns": "^3.490.0",
|
|
208
|
+
"@aws-sdk/client-sts": "^3.490.0",
|
|
209
|
+
"@aws-sdk/util-dynamodb": "3.927.0",
|
|
210
|
+
"@clack/prompts": "^0.11.0",
|
|
211
|
+
"@pulumi/aws": "^7.11.1",
|
|
212
|
+
"@pulumi/pulumi": "^3.207.0",
|
|
213
|
+
args: "^5.0.3",
|
|
214
|
+
conf: "^13.0.1",
|
|
215
|
+
cosmiconfig: "^9.0.0",
|
|
216
|
+
esbuild: "^0.25.12",
|
|
217
|
+
express: "^4.21.2",
|
|
218
|
+
"get-port": "^7.1.0",
|
|
219
|
+
"http-terminator": "^3.2.0",
|
|
220
|
+
"isomorphic-dompurify": "2.32.0",
|
|
221
|
+
mailparser: "3.9.0",
|
|
222
|
+
open: "^10.1.0",
|
|
223
|
+
picocolors: "^1.1.1",
|
|
224
|
+
tabtab: "^3.0.2",
|
|
225
|
+
uuid: "^11.0.3"
|
|
226
|
+
},
|
|
227
|
+
devDependencies: {
|
|
228
|
+
"@types/args": "5.0.4",
|
|
229
|
+
"@types/express": "^5.0.0",
|
|
230
|
+
"@types/mailparser": "3.4.6",
|
|
231
|
+
"@types/node": "^20.11.0",
|
|
232
|
+
"@types/uuid": "^10.0.0",
|
|
233
|
+
"@vitest/coverage-v8": "4.0.7",
|
|
234
|
+
"aws-sdk-client-mock": "4.1.0",
|
|
235
|
+
"aws-sdk-client-mock-vitest": "7.0.1",
|
|
236
|
+
eslint: "^8.56.0",
|
|
237
|
+
tsup: "^8.0.1",
|
|
238
|
+
tsx: "4.20.6",
|
|
239
|
+
typescript: "catalog:",
|
|
240
|
+
vitest: "^4.0.7"
|
|
241
|
+
},
|
|
242
|
+
engines: {
|
|
243
|
+
node: ">=20.0.0"
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// src/telemetry/client.ts
|
|
250
|
+
function getTelemetryClient() {
|
|
251
|
+
if (!telemetryInstance) {
|
|
252
|
+
telemetryInstance = new TelemetryClient();
|
|
253
|
+
}
|
|
254
|
+
return telemetryInstance;
|
|
255
|
+
}
|
|
256
|
+
var DEFAULT_ENDPOINT, DEFAULT_TIMEOUT, TelemetryClient, telemetryInstance;
|
|
257
|
+
var init_client = __esm({
|
|
258
|
+
"src/telemetry/client.ts"() {
|
|
259
|
+
"use strict";
|
|
260
|
+
init_esm_shims();
|
|
261
|
+
init_ci_detection();
|
|
262
|
+
init_config();
|
|
263
|
+
DEFAULT_ENDPOINT = "https://wraps.dev/api/telemetry";
|
|
264
|
+
DEFAULT_TIMEOUT = 2e3;
|
|
265
|
+
TelemetryClient = class {
|
|
266
|
+
config;
|
|
267
|
+
endpoint;
|
|
268
|
+
timeout;
|
|
269
|
+
debug;
|
|
270
|
+
enabled;
|
|
271
|
+
eventQueue = [];
|
|
272
|
+
flushTimer;
|
|
273
|
+
constructor(options = {}) {
|
|
274
|
+
this.config = new TelemetryConfigManager();
|
|
275
|
+
this.endpoint = options.endpoint || DEFAULT_ENDPOINT;
|
|
276
|
+
this.timeout = options.timeout || DEFAULT_TIMEOUT;
|
|
277
|
+
this.debug = options.debug || process.env.WRAPS_TELEMETRY_DEBUG === "1";
|
|
278
|
+
this.enabled = this.shouldBeEnabled();
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Determine if telemetry should be enabled based on environment and config
|
|
282
|
+
*/
|
|
283
|
+
shouldBeEnabled() {
|
|
284
|
+
if (process.env.DO_NOT_TRACK === "1") {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
if (process.env.WRAPS_TELEMETRY_DISABLED === "1") {
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
if (isCI()) {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
if (!this.config.isEnabled()) {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Track an event
|
|
300
|
+
*
|
|
301
|
+
* @param event - Event name in format "category:action" (e.g., "command:init")
|
|
302
|
+
* @param properties - Additional event properties (no PII)
|
|
303
|
+
*/
|
|
304
|
+
track(event, properties) {
|
|
305
|
+
const telemetryEvent = {
|
|
306
|
+
event,
|
|
307
|
+
properties: {
|
|
308
|
+
...properties,
|
|
309
|
+
cli_version: this.getCLIVersion(),
|
|
310
|
+
os: process.platform,
|
|
311
|
+
node_version: process.version,
|
|
312
|
+
ci: isCI()
|
|
313
|
+
},
|
|
314
|
+
anonymousId: this.config.getAnonymousId(),
|
|
315
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
316
|
+
};
|
|
317
|
+
if (this.debug) {
|
|
318
|
+
console.log(
|
|
319
|
+
"[Telemetry Debug] Event:",
|
|
320
|
+
JSON.stringify(telemetryEvent, null, 2)
|
|
321
|
+
);
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
if (!this.enabled) {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
this.eventQueue.push(telemetryEvent);
|
|
328
|
+
if (this.flushTimer) {
|
|
329
|
+
clearTimeout(this.flushTimer);
|
|
330
|
+
}
|
|
331
|
+
this.flushTimer = setTimeout(() => this.flush(), 100);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Flush queued events to server
|
|
335
|
+
*/
|
|
336
|
+
async flush() {
|
|
337
|
+
if (this.eventQueue.length === 0) {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
const eventsToSend = [...this.eventQueue];
|
|
341
|
+
this.eventQueue = [];
|
|
342
|
+
try {
|
|
343
|
+
const controller = new AbortController();
|
|
344
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
345
|
+
const requestBody = {
|
|
346
|
+
events: eventsToSend,
|
|
347
|
+
batch: true
|
|
348
|
+
};
|
|
349
|
+
await fetch(this.endpoint, {
|
|
350
|
+
method: "POST",
|
|
351
|
+
headers: {
|
|
352
|
+
"Content-Type": "application/json"
|
|
353
|
+
},
|
|
354
|
+
body: JSON.stringify(requestBody),
|
|
355
|
+
signal: controller.signal
|
|
356
|
+
});
|
|
357
|
+
clearTimeout(timeoutId);
|
|
358
|
+
} catch (error) {
|
|
359
|
+
if (this.debug) {
|
|
360
|
+
console.error("[Telemetry Debug] Failed to send events:", error);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Flush and wait for all events to be sent
|
|
366
|
+
* Should be called before CLI exits
|
|
367
|
+
*/
|
|
368
|
+
async shutdown() {
|
|
369
|
+
if (this.flushTimer) {
|
|
370
|
+
clearTimeout(this.flushTimer);
|
|
371
|
+
}
|
|
372
|
+
await this.flush();
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Enable telemetry
|
|
376
|
+
* Note: Won't override environment variable opt-outs (DO_NOT_TRACK, CI, etc.)
|
|
377
|
+
*/
|
|
378
|
+
enable() {
|
|
379
|
+
this.config.setEnabled(true);
|
|
380
|
+
if (process.env.DO_NOT_TRACK === "1" || process.env.DO_NOT_TRACK === "true") {
|
|
381
|
+
this.enabled = false;
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
if (process.env.WRAPS_TELEMETRY_DISABLED === "1") {
|
|
385
|
+
this.enabled = false;
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
if (isCI()) {
|
|
389
|
+
this.enabled = false;
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
this.enabled = true;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Disable telemetry
|
|
396
|
+
*/
|
|
397
|
+
disable() {
|
|
398
|
+
this.config.setEnabled(false);
|
|
399
|
+
this.enabled = false;
|
|
400
|
+
this.eventQueue = [];
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Check if telemetry is enabled
|
|
404
|
+
*/
|
|
405
|
+
isEnabled() {
|
|
406
|
+
return this.enabled;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Get config file path
|
|
410
|
+
*/
|
|
411
|
+
getConfigPath() {
|
|
412
|
+
return this.config.getConfigPath();
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Show first-run notification
|
|
416
|
+
*/
|
|
417
|
+
shouldShowNotification() {
|
|
418
|
+
return this.enabled && !this.config.hasShownNotification();
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Mark notification as shown
|
|
422
|
+
*/
|
|
423
|
+
markNotificationShown() {
|
|
424
|
+
this.config.markNotificationShown();
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Get CLI version from package.json
|
|
428
|
+
*/
|
|
429
|
+
getCLIVersion() {
|
|
430
|
+
try {
|
|
431
|
+
const packageJson2 = require_package();
|
|
432
|
+
return packageJson2.version;
|
|
433
|
+
} catch {
|
|
434
|
+
return "unknown";
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
telemetryInstance = null;
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
// src/telemetry/events.ts
|
|
443
|
+
function trackCommand(command, metadata) {
|
|
444
|
+
const client = getTelemetryClient();
|
|
445
|
+
const sanitized = metadata ? { ...metadata } : {};
|
|
446
|
+
sanitized.domain = void 0;
|
|
447
|
+
sanitized.accountId = void 0;
|
|
448
|
+
sanitized.email = void 0;
|
|
449
|
+
client.track(`command:${command}`, sanitized);
|
|
450
|
+
}
|
|
451
|
+
function trackError(errorCode, command, metadata) {
|
|
452
|
+
const client = getTelemetryClient();
|
|
453
|
+
client.track("error:occurred", {
|
|
454
|
+
error_code: errorCode,
|
|
455
|
+
command,
|
|
456
|
+
...metadata
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
var init_events = __esm({
|
|
460
|
+
"src/telemetry/events.ts"() {
|
|
461
|
+
"use strict";
|
|
462
|
+
init_esm_shims();
|
|
463
|
+
init_client();
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
|
|
21
467
|
// src/utils/shared/errors.ts
|
|
22
468
|
import * as clack from "@clack/prompts";
|
|
23
469
|
import pc from "picocolors";
|
|
24
470
|
function handleCLIError(error) {
|
|
25
471
|
console.error("");
|
|
26
472
|
if (error instanceof WrapsError) {
|
|
473
|
+
trackError(error.code, "unknown");
|
|
27
474
|
clack.log.error(error.message);
|
|
28
475
|
if (error.suggestion) {
|
|
29
476
|
console.log(`
|
|
@@ -38,6 +485,7 @@ ${pc.yellow("Suggestion:")}`);
|
|
|
38
485
|
}
|
|
39
486
|
process.exit(1);
|
|
40
487
|
}
|
|
488
|
+
trackError("UNKNOWN_ERROR", "unknown");
|
|
41
489
|
clack.log.error("An unexpected error occurred");
|
|
42
490
|
console.error(error);
|
|
43
491
|
console.log(`
|
|
@@ -51,6 +499,7 @@ var init_errors = __esm({
|
|
|
51
499
|
"src/utils/shared/errors.ts"() {
|
|
52
500
|
"use strict";
|
|
53
501
|
init_esm_shims();
|
|
502
|
+
init_events();
|
|
54
503
|
WrapsError = class extends Error {
|
|
55
504
|
constructor(message, code, suggestion, docsUrl) {
|
|
56
505
|
super(message);
|
|
@@ -2206,9 +2655,9 @@ init_esm_shims();
|
|
|
2206
2655
|
import { readFileSync } from "fs";
|
|
2207
2656
|
import { dirname as dirname2, join as join4 } from "path";
|
|
2208
2657
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
2209
|
-
import * as
|
|
2658
|
+
import * as clack14 from "@clack/prompts";
|
|
2210
2659
|
import args from "args";
|
|
2211
|
-
import
|
|
2660
|
+
import pc15 from "picocolors";
|
|
2212
2661
|
|
|
2213
2662
|
// src/commands/dashboard/update-role.ts
|
|
2214
2663
|
init_esm_shims();
|
|
@@ -7548,6 +7997,67 @@ Run ${pc13.cyan("wraps email init")} to deploy infrastructure.
|
|
|
7548
7997
|
});
|
|
7549
7998
|
}
|
|
7550
7999
|
|
|
8000
|
+
// src/commands/telemetry.ts
|
|
8001
|
+
init_esm_shims();
|
|
8002
|
+
init_client();
|
|
8003
|
+
import * as clack13 from "@clack/prompts";
|
|
8004
|
+
import pc14 from "picocolors";
|
|
8005
|
+
async function telemetryEnable() {
|
|
8006
|
+
const client = getTelemetryClient();
|
|
8007
|
+
client.enable();
|
|
8008
|
+
clack13.log.success(pc14.green("Telemetry enabled"));
|
|
8009
|
+
console.log(` Config: ${pc14.dim(client.getConfigPath())}`);
|
|
8010
|
+
console.log(`
|
|
8011
|
+
${pc14.dim("Thank you for helping improve Wraps!")}
|
|
8012
|
+
`);
|
|
8013
|
+
}
|
|
8014
|
+
async function telemetryDisable() {
|
|
8015
|
+
const client = getTelemetryClient();
|
|
8016
|
+
client.disable();
|
|
8017
|
+
clack13.log.success(pc14.green("Telemetry disabled"));
|
|
8018
|
+
console.log(` Config: ${pc14.dim(client.getConfigPath())}`);
|
|
8019
|
+
console.log(
|
|
8020
|
+
`
|
|
8021
|
+
${pc14.dim("You can re-enable with:")} wraps telemetry enable
|
|
8022
|
+
`
|
|
8023
|
+
);
|
|
8024
|
+
}
|
|
8025
|
+
async function telemetryStatus() {
|
|
8026
|
+
const client = getTelemetryClient();
|
|
8027
|
+
clack13.intro(pc14.bold("Telemetry Status"));
|
|
8028
|
+
const status2 = client.isEnabled() ? pc14.green("Enabled") : pc14.red("Disabled");
|
|
8029
|
+
console.log();
|
|
8030
|
+
console.log(` ${pc14.bold("Status:")} ${status2}`);
|
|
8031
|
+
console.log(` ${pc14.bold("Config file:")} ${pc14.dim(client.getConfigPath())}`);
|
|
8032
|
+
if (client.isEnabled()) {
|
|
8033
|
+
console.log();
|
|
8034
|
+
console.log(pc14.bold(" How to opt-out:"));
|
|
8035
|
+
console.log(` ${pc14.cyan("wraps telemetry disable")}`);
|
|
8036
|
+
console.log(
|
|
8037
|
+
` ${pc14.dim("Or set:")} ${pc14.cyan("WRAPS_TELEMETRY_DISABLED=1")}`
|
|
8038
|
+
);
|
|
8039
|
+
console.log(` ${pc14.dim("Or set:")} ${pc14.cyan("DO_NOT_TRACK=1")}`);
|
|
8040
|
+
} else {
|
|
8041
|
+
console.log();
|
|
8042
|
+
console.log(pc14.bold(" How to opt-in:"));
|
|
8043
|
+
console.log(` ${pc14.cyan("wraps telemetry enable")}`);
|
|
8044
|
+
}
|
|
8045
|
+
console.log();
|
|
8046
|
+
console.log(pc14.bold(" Debug mode:"));
|
|
8047
|
+
console.log(
|
|
8048
|
+
` ${pc14.dim("See what would be sent:")} ${pc14.cyan("WRAPS_TELEMETRY_DEBUG=1 wraps <command>")}`
|
|
8049
|
+
);
|
|
8050
|
+
console.log();
|
|
8051
|
+
console.log(
|
|
8052
|
+
` ${pc14.dim("Learn more:")} ${pc14.cyan("https://wraps.dev/docs/telemetry")}`
|
|
8053
|
+
);
|
|
8054
|
+
console.log();
|
|
8055
|
+
}
|
|
8056
|
+
|
|
8057
|
+
// src/cli.ts
|
|
8058
|
+
init_client();
|
|
8059
|
+
init_events();
|
|
8060
|
+
|
|
7551
8061
|
// src/utils/shared/completion.ts
|
|
7552
8062
|
init_esm_shims();
|
|
7553
8063
|
function setupTabCompletion() {
|
|
@@ -7586,56 +8096,57 @@ function showVersion() {
|
|
|
7586
8096
|
process.exit(0);
|
|
7587
8097
|
}
|
|
7588
8098
|
function showHelp() {
|
|
7589
|
-
|
|
8099
|
+
clack14.intro(pc15.bold(`WRAPS CLI v${VERSION}`));
|
|
7590
8100
|
console.log("Deploy AWS infrastructure to your account\n");
|
|
7591
8101
|
console.log("Usage: wraps [service] <command> [options]\n");
|
|
7592
8102
|
console.log("Services:");
|
|
7593
|
-
console.log(` ${
|
|
8103
|
+
console.log(` ${pc15.cyan("email")} Email infrastructure (AWS SES)`);
|
|
7594
8104
|
console.log(
|
|
7595
|
-
` ${
|
|
8105
|
+
` ${pc15.cyan("sms")} SMS infrastructure (AWS End User Messaging) ${pc15.dim("[coming soon]")}
|
|
7596
8106
|
`
|
|
7597
8107
|
);
|
|
7598
8108
|
console.log("Email Commands:");
|
|
7599
8109
|
console.log(
|
|
7600
|
-
` ${
|
|
8110
|
+
` ${pc15.cyan("email init")} Deploy new email infrastructure`
|
|
7601
8111
|
);
|
|
7602
8112
|
console.log(
|
|
7603
|
-
` ${
|
|
8113
|
+
` ${pc15.cyan("email connect")} Connect to existing AWS SES`
|
|
7604
8114
|
);
|
|
7605
|
-
console.log(` ${
|
|
7606
|
-
console.log(` ${
|
|
7607
|
-
console.log(` ${
|
|
8115
|
+
console.log(` ${pc15.cyan("email domains verify")} Verify domain DNS records`);
|
|
8116
|
+
console.log(` ${pc15.cyan("email config")} Update infrastructure`);
|
|
8117
|
+
console.log(` ${pc15.cyan("email upgrade")} Add features`);
|
|
7608
8118
|
console.log(
|
|
7609
|
-
` ${
|
|
8119
|
+
` ${pc15.cyan("email restore")} Restore original configuration
|
|
7610
8120
|
`
|
|
7611
8121
|
);
|
|
7612
8122
|
console.log("Console & Dashboard:");
|
|
7613
|
-
console.log(` ${
|
|
8123
|
+
console.log(` ${pc15.cyan("console")} Start local web console`);
|
|
7614
8124
|
console.log(
|
|
7615
|
-
` ${
|
|
8125
|
+
` ${pc15.cyan("dashboard update-role")} Update hosted dashboard IAM permissions
|
|
7616
8126
|
`
|
|
7617
8127
|
);
|
|
7618
8128
|
console.log("Global Commands:");
|
|
7619
|
-
console.log(` ${
|
|
7620
|
-
console.log(` ${
|
|
8129
|
+
console.log(` ${pc15.cyan("status")} Show all infrastructure status`);
|
|
8130
|
+
console.log(` ${pc15.cyan("destroy")} Remove deployed infrastructure`);
|
|
8131
|
+
console.log(` ${pc15.cyan("completion")} Generate shell completion script`);
|
|
7621
8132
|
console.log(
|
|
7622
|
-
` ${
|
|
8133
|
+
` ${pc15.cyan("telemetry")} Manage anonymous telemetry settings
|
|
7623
8134
|
`
|
|
7624
8135
|
);
|
|
7625
8136
|
console.log("Options:");
|
|
7626
8137
|
console.log(
|
|
7627
|
-
` ${
|
|
8138
|
+
` ${pc15.dim("-p, --provider")} Hosting provider (vercel, aws, railway, other)`
|
|
7628
8139
|
);
|
|
7629
|
-
console.log(` ${
|
|
7630
|
-
console.log(` ${
|
|
7631
|
-
console.log(` ${
|
|
7632
|
-
console.log(` ${
|
|
7633
|
-
console.log(` ${
|
|
7634
|
-
console.log(` ${
|
|
7635
|
-
console.log(` ${
|
|
8140
|
+
console.log(` ${pc15.dim("-r, --region")} AWS region`);
|
|
8141
|
+
console.log(` ${pc15.dim("-d, --domain")} Domain name`);
|
|
8142
|
+
console.log(` ${pc15.dim("--account")} AWS account ID or alias`);
|
|
8143
|
+
console.log(` ${pc15.dim("--preset")} Configuration preset`);
|
|
8144
|
+
console.log(` ${pc15.dim("-y, --yes")} Skip confirmation prompts`);
|
|
8145
|
+
console.log(` ${pc15.dim("-f, --force")} Force destructive operations`);
|
|
8146
|
+
console.log(` ${pc15.dim("-v, --version")} Show version number
|
|
7636
8147
|
`);
|
|
7637
8148
|
console.log(
|
|
7638
|
-
`Run ${
|
|
8149
|
+
`Run ${pc15.cyan("wraps <service> <command> --help")} for more information.
|
|
7639
8150
|
`
|
|
7640
8151
|
);
|
|
7641
8152
|
process.exit(0);
|
|
@@ -7697,9 +8208,9 @@ var flags = args.parse(process.argv);
|
|
|
7697
8208
|
var [primaryCommand, subCommand] = args.sub;
|
|
7698
8209
|
if (!primaryCommand) {
|
|
7699
8210
|
async function selectService() {
|
|
7700
|
-
|
|
8211
|
+
clack14.intro(pc15.bold(`WRAPS CLI v${VERSION}`));
|
|
7701
8212
|
console.log("Welcome! Let's get started deploying your infrastructure.\n");
|
|
7702
|
-
const service = await
|
|
8213
|
+
const service = await clack14.select({
|
|
7703
8214
|
message: "Which service would you like to set up?",
|
|
7704
8215
|
options: [
|
|
7705
8216
|
{
|
|
@@ -7714,20 +8225,20 @@ if (!primaryCommand) {
|
|
|
7714
8225
|
}
|
|
7715
8226
|
]
|
|
7716
8227
|
});
|
|
7717
|
-
if (
|
|
7718
|
-
|
|
8228
|
+
if (clack14.isCancel(service)) {
|
|
8229
|
+
clack14.cancel("Operation cancelled.");
|
|
7719
8230
|
process.exit(0);
|
|
7720
8231
|
}
|
|
7721
8232
|
if (service === "sms") {
|
|
7722
|
-
|
|
8233
|
+
clack14.log.warn("SMS infrastructure is coming soon!");
|
|
7723
8234
|
console.log(
|
|
7724
8235
|
`
|
|
7725
|
-
Check back soon or follow our progress at ${
|
|
8236
|
+
Check back soon or follow our progress at ${pc15.cyan("https://github.com/wraps-team/wraps")}
|
|
7726
8237
|
`
|
|
7727
8238
|
);
|
|
7728
8239
|
process.exit(0);
|
|
7729
8240
|
}
|
|
7730
|
-
const action = await
|
|
8241
|
+
const action = await clack14.select({
|
|
7731
8242
|
message: "What would you like to do?",
|
|
7732
8243
|
options: [
|
|
7733
8244
|
{
|
|
@@ -7742,8 +8253,8 @@ Check back soon or follow our progress at ${pc14.cyan("https://github.com/wraps-
|
|
|
7742
8253
|
}
|
|
7743
8254
|
]
|
|
7744
8255
|
});
|
|
7745
|
-
if (
|
|
7746
|
-
|
|
8256
|
+
if (clack14.isCancel(action)) {
|
|
8257
|
+
clack14.cancel("Operation cancelled.");
|
|
7747
8258
|
process.exit(0);
|
|
7748
8259
|
}
|
|
7749
8260
|
if (action === "init") {
|
|
@@ -7766,6 +8277,27 @@ Check back soon or follow our progress at ${pc14.cyan("https://github.com/wraps-
|
|
|
7766
8277
|
process.exit(0);
|
|
7767
8278
|
}
|
|
7768
8279
|
async function run() {
|
|
8280
|
+
const startTime = Date.now();
|
|
8281
|
+
const telemetry = getTelemetryClient();
|
|
8282
|
+
if (telemetry.shouldShowNotification()) {
|
|
8283
|
+
console.log();
|
|
8284
|
+
clack14.log.info(pc15.bold("Anonymous Telemetry"));
|
|
8285
|
+
console.log(
|
|
8286
|
+
` Wraps collects ${pc15.cyan("anonymous usage data")} to improve the CLI.`
|
|
8287
|
+
);
|
|
8288
|
+
console.log(
|
|
8289
|
+
` We ${pc15.bold("never")} collect: domains, AWS credentials, email content, or PII.`
|
|
8290
|
+
);
|
|
8291
|
+
console.log(
|
|
8292
|
+
` We ${pc15.bold("only")} collect: command names, success/failure, CLI version, OS.`
|
|
8293
|
+
);
|
|
8294
|
+
console.log();
|
|
8295
|
+
console.log(` Opt-out anytime: ${pc15.cyan("wraps telemetry disable")}`);
|
|
8296
|
+
console.log(` Or set: ${pc15.cyan("WRAPS_TELEMETRY_DISABLED=1")}`);
|
|
8297
|
+
console.log(` Learn more: ${pc15.cyan("https://wraps.dev/docs/telemetry")}`);
|
|
8298
|
+
console.log();
|
|
8299
|
+
telemetry.markNotificationShown();
|
|
8300
|
+
}
|
|
7769
8301
|
try {
|
|
7770
8302
|
if (primaryCommand === "email" && subCommand) {
|
|
7771
8303
|
switch (subCommand) {
|
|
@@ -7808,10 +8340,10 @@ async function run() {
|
|
|
7808
8340
|
switch (domainsSubCommand) {
|
|
7809
8341
|
case "add": {
|
|
7810
8342
|
if (!flags.domain) {
|
|
7811
|
-
|
|
8343
|
+
clack14.log.error("--domain flag is required");
|
|
7812
8344
|
console.log(
|
|
7813
8345
|
`
|
|
7814
|
-
Usage: ${
|
|
8346
|
+
Usage: ${pc15.cyan("wraps email domains add --domain yourapp.com")}
|
|
7815
8347
|
`
|
|
7816
8348
|
);
|
|
7817
8349
|
process.exit(1);
|
|
@@ -7824,10 +8356,10 @@ Usage: ${pc14.cyan("wraps email domains add --domain yourapp.com")}
|
|
|
7824
8356
|
break;
|
|
7825
8357
|
case "verify": {
|
|
7826
8358
|
if (!flags.domain) {
|
|
7827
|
-
|
|
8359
|
+
clack14.log.error("--domain flag is required");
|
|
7828
8360
|
console.log(
|
|
7829
8361
|
`
|
|
7830
|
-
Usage: ${
|
|
8362
|
+
Usage: ${pc15.cyan("wraps email domains verify --domain yourapp.com")}
|
|
7831
8363
|
`
|
|
7832
8364
|
);
|
|
7833
8365
|
process.exit(1);
|
|
@@ -7837,10 +8369,10 @@ Usage: ${pc14.cyan("wraps email domains verify --domain yourapp.com")}
|
|
|
7837
8369
|
}
|
|
7838
8370
|
case "get-dkim": {
|
|
7839
8371
|
if (!flags.domain) {
|
|
7840
|
-
|
|
8372
|
+
clack14.log.error("--domain flag is required");
|
|
7841
8373
|
console.log(
|
|
7842
8374
|
`
|
|
7843
|
-
Usage: ${
|
|
8375
|
+
Usage: ${pc15.cyan("wraps email domains get-dkim --domain yourapp.com")}
|
|
7844
8376
|
`
|
|
7845
8377
|
);
|
|
7846
8378
|
process.exit(1);
|
|
@@ -7850,10 +8382,10 @@ Usage: ${pc14.cyan("wraps email domains get-dkim --domain yourapp.com")}
|
|
|
7850
8382
|
}
|
|
7851
8383
|
case "remove": {
|
|
7852
8384
|
if (!flags.domain) {
|
|
7853
|
-
|
|
8385
|
+
clack14.log.error("--domain flag is required");
|
|
7854
8386
|
console.log(
|
|
7855
8387
|
`
|
|
7856
|
-
Usage: ${
|
|
8388
|
+
Usage: ${pc15.cyan("wraps email domains remove --domain yourapp.com --force")}
|
|
7857
8389
|
`
|
|
7858
8390
|
);
|
|
7859
8391
|
process.exit(1);
|
|
@@ -7865,12 +8397,12 @@ Usage: ${pc14.cyan("wraps email domains remove --domain yourapp.com --force")}
|
|
|
7865
8397
|
break;
|
|
7866
8398
|
}
|
|
7867
8399
|
default:
|
|
7868
|
-
|
|
8400
|
+
clack14.log.error(
|
|
7869
8401
|
`Unknown domains command: ${domainsSubCommand || "(none)"}`
|
|
7870
8402
|
);
|
|
7871
8403
|
console.log(
|
|
7872
8404
|
`
|
|
7873
|
-
Available commands: ${
|
|
8405
|
+
Available commands: ${pc15.cyan("add")}, ${pc15.cyan("list")}, ${pc15.cyan("verify")}, ${pc15.cyan("get-dkim")}, ${pc15.cyan("remove")}
|
|
7874
8406
|
`
|
|
7875
8407
|
);
|
|
7876
8408
|
process.exit(1);
|
|
@@ -7878,10 +8410,10 @@ Available commands: ${pc14.cyan("add")}, ${pc14.cyan("list")}, ${pc14.cyan("veri
|
|
|
7878
8410
|
break;
|
|
7879
8411
|
}
|
|
7880
8412
|
default:
|
|
7881
|
-
|
|
8413
|
+
clack14.log.error(`Unknown email command: ${subCommand}`);
|
|
7882
8414
|
console.log(
|
|
7883
8415
|
`
|
|
7884
|
-
Run ${
|
|
8416
|
+
Run ${pc15.cyan("wraps --help")} for available commands.
|
|
7885
8417
|
`
|
|
7886
8418
|
);
|
|
7887
8419
|
process.exit(1);
|
|
@@ -7897,21 +8429,21 @@ Run ${pc14.cyan("wraps --help")} for available commands.
|
|
|
7897
8429
|
});
|
|
7898
8430
|
break;
|
|
7899
8431
|
default:
|
|
7900
|
-
|
|
8432
|
+
clack14.log.error(`Unknown dashboard command: ${subCommand}`);
|
|
7901
8433
|
console.log(`
|
|
7902
|
-
Available commands: ${
|
|
8434
|
+
Available commands: ${pc15.cyan("update-role")}
|
|
7903
8435
|
`);
|
|
7904
|
-
console.log(`Run ${
|
|
8436
|
+
console.log(`Run ${pc15.cyan("wraps --help")} for more information.
|
|
7905
8437
|
`);
|
|
7906
8438
|
process.exit(1);
|
|
7907
8439
|
}
|
|
7908
8440
|
return;
|
|
7909
8441
|
}
|
|
7910
8442
|
if (primaryCommand === "sms" && subCommand) {
|
|
7911
|
-
|
|
8443
|
+
clack14.log.warn("SMS infrastructure is coming soon!");
|
|
7912
8444
|
console.log(
|
|
7913
8445
|
`
|
|
7914
|
-
Check back soon or follow our progress at ${
|
|
8446
|
+
Check back soon or follow our progress at ${pc15.cyan("https://github.com/wraps-team/wraps")}
|
|
7915
8447
|
`
|
|
7916
8448
|
);
|
|
7917
8449
|
process.exit(0);
|
|
@@ -7931,8 +8463,8 @@ Check back soon or follow our progress at ${pc14.cyan("https://github.com/wraps-
|
|
|
7931
8463
|
break;
|
|
7932
8464
|
case "dashboard":
|
|
7933
8465
|
if (!subCommand) {
|
|
7934
|
-
|
|
7935
|
-
`'wraps dashboard' is deprecated. Use ${
|
|
8466
|
+
clack14.log.warn(
|
|
8467
|
+
`'wraps dashboard' is deprecated. Use ${pc15.cyan("wraps console")} instead.`
|
|
7936
8468
|
);
|
|
7937
8469
|
await dashboard({
|
|
7938
8470
|
port: flags.port,
|
|
@@ -7948,6 +8480,29 @@ Check back soon or follow our progress at ${pc14.cyan("https://github.com/wraps-
|
|
|
7948
8480
|
case "completion":
|
|
7949
8481
|
printCompletionScript();
|
|
7950
8482
|
break;
|
|
8483
|
+
case "telemetry": {
|
|
8484
|
+
switch (subCommand) {
|
|
8485
|
+
case "enable":
|
|
8486
|
+
await telemetryEnable();
|
|
8487
|
+
break;
|
|
8488
|
+
case "disable":
|
|
8489
|
+
await telemetryDisable();
|
|
8490
|
+
break;
|
|
8491
|
+
case "status":
|
|
8492
|
+
case void 0:
|
|
8493
|
+
await telemetryStatus();
|
|
8494
|
+
break;
|
|
8495
|
+
default:
|
|
8496
|
+
clack14.log.error(`Unknown telemetry command: ${subCommand}`);
|
|
8497
|
+
console.log(
|
|
8498
|
+
`
|
|
8499
|
+
Available commands: ${pc15.cyan("enable")}, ${pc15.cyan("disable")}, ${pc15.cyan("status")}
|
|
8500
|
+
`
|
|
8501
|
+
);
|
|
8502
|
+
process.exit(1);
|
|
8503
|
+
}
|
|
8504
|
+
break;
|
|
8505
|
+
}
|
|
7951
8506
|
// Show help for service without subcommand
|
|
7952
8507
|
case "email":
|
|
7953
8508
|
case "sms":
|
|
@@ -7959,16 +8514,30 @@ Please specify a command for ${primaryCommand} service.
|
|
|
7959
8514
|
showHelp();
|
|
7960
8515
|
break;
|
|
7961
8516
|
default:
|
|
7962
|
-
|
|
8517
|
+
clack14.log.error(`Unknown command: ${primaryCommand}`);
|
|
7963
8518
|
console.log(
|
|
7964
8519
|
`
|
|
7965
|
-
Run ${
|
|
8520
|
+
Run ${pc15.cyan("wraps --help")} for available commands.
|
|
7966
8521
|
`
|
|
7967
8522
|
);
|
|
7968
8523
|
process.exit(1);
|
|
7969
8524
|
}
|
|
8525
|
+
const duration = Date.now() - startTime;
|
|
8526
|
+
const commandName = subCommand ? `${primaryCommand}:${subCommand}` : primaryCommand;
|
|
8527
|
+
trackCommand(commandName, {
|
|
8528
|
+
success: true,
|
|
8529
|
+
duration_ms: duration
|
|
8530
|
+
});
|
|
7970
8531
|
} catch (error) {
|
|
8532
|
+
const duration = Date.now() - startTime;
|
|
8533
|
+
const commandName = subCommand ? `${primaryCommand}:${subCommand}` : primaryCommand;
|
|
8534
|
+
trackCommand(commandName, {
|
|
8535
|
+
success: false,
|
|
8536
|
+
duration_ms: duration
|
|
8537
|
+
});
|
|
7971
8538
|
handleCLIError(error);
|
|
8539
|
+
} finally {
|
|
8540
|
+
await telemetry.shutdown();
|
|
7972
8541
|
}
|
|
7973
8542
|
}
|
|
7974
8543
|
run();
|