@samva/cli 0.17.0 → 0.18.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/AGENTS.md +6 -0
- package/dist/bin.mjs +145 -25
- package/package.json +7 -7
package/AGENTS.md
CHANGED
|
@@ -37,6 +37,12 @@ confirmation (`--yes` outside a terminal), and every mutation supports `--dry-ru
|
|
|
37
37
|
`SAMVA_API_KEY`, `samva org current` asks the API who the key is (`GET /v1/whoami`) and reports its
|
|
38
38
|
organization and key; with OAuth it reports the profile's selected organization.
|
|
39
39
|
|
|
40
|
+
`samva webhooks secret <id>` reads the current signing secret with `webhooks:update` permission.
|
|
41
|
+
Human output includes the secret, its creation time, and when the previous secret stops verifying
|
|
42
|
+
if one exists. `--json` returns `{secret, createdAt, previousExpiresAt}` inside the result envelope.
|
|
43
|
+
`create` and `rotate-secret` return readable secrets too; retrieve them again with `secret <id>`.
|
|
44
|
+
Their JSON results contain `secret` and `warning` (`create` also includes `endpoint`).
|
|
45
|
+
|
|
40
46
|
`samva templates export --out <dir>` renders every local template's fixtures to HTML
|
|
41
47
|
and text with the asset manifest, needing a Samva credential only to resolve a live `samva:brand`; `--asset-base <origin>` is for an
|
|
42
48
|
export that will be delivered, which cannot carry a relative reference.
|
package/dist/bin.mjs
CHANGED
|
@@ -14106,7 +14106,7 @@ var layer12 = /* @__PURE__ */ layer.pipe(/* @__PURE__ */ provideMerge(/* @__PURE
|
|
|
14106
14106
|
// package.json
|
|
14107
14107
|
var package_default = {
|
|
14108
14108
|
name: "@samva/cli",
|
|
14109
|
-
version: "0.
|
|
14109
|
+
version: "0.18.0",
|
|
14110
14110
|
description: "Samva CLI \u2014 email and platform operations from your terminal",
|
|
14111
14111
|
keywords: [
|
|
14112
14112
|
"cli",
|
|
@@ -14162,16 +14162,16 @@ var package_default = {
|
|
|
14162
14162
|
"@types/node": "catalog:",
|
|
14163
14163
|
"better-auth": "catalog:",
|
|
14164
14164
|
effect: "catalog:effect",
|
|
14165
|
-
samva: "workspace:0.
|
|
14165
|
+
samva: "workspace:0.21.0",
|
|
14166
14166
|
typescript: "catalog:",
|
|
14167
14167
|
vite: "~8.3.0",
|
|
14168
14168
|
vitest: "catalog:"
|
|
14169
14169
|
},
|
|
14170
14170
|
optionalDependencies: {
|
|
14171
|
-
"@samva/cli-darwin-arm64": "workspace:0.
|
|
14172
|
-
"@samva/cli-darwin-x64": "workspace:0.
|
|
14173
|
-
"@samva/cli-linux-arm64": "workspace:0.
|
|
14174
|
-
"@samva/cli-linux-x64": "workspace:0.
|
|
14171
|
+
"@samva/cli-darwin-arm64": "workspace:0.18.0",
|
|
14172
|
+
"@samva/cli-darwin-x64": "workspace:0.18.0",
|
|
14173
|
+
"@samva/cli-linux-arm64": "workspace:0.18.0",
|
|
14174
|
+
"@samva/cli-linux-x64": "workspace:0.18.0"
|
|
14175
14175
|
},
|
|
14176
14176
|
engines: {
|
|
14177
14177
|
node: ">=18"
|
|
@@ -19596,6 +19596,9 @@ var ENTITY_PREFIXES = {
|
|
|
19596
19596
|
waflow: "WhatsAppFlowId",
|
|
19597
19597
|
wafver: "WhatsAppFlowVersionId",
|
|
19598
19598
|
wafreg: "WhatsAppFlowRegistrationId",
|
|
19599
|
+
wafkey: "WhatsAppFlowEncryptionKeyId",
|
|
19600
|
+
wafx: "WhatsAppFlowExchangeId",
|
|
19601
|
+
wasl: "WhatsAppSetupLinkId",
|
|
19599
19602
|
mbx: "MailboxId",
|
|
19600
19603
|
mbxep: "MailboxEndpointId",
|
|
19601
19604
|
thread: "MailboxThreadId",
|
|
@@ -19691,6 +19694,9 @@ var WhatsAppBusinessAccountId = entityId("waba").pipe(brand(ENTITY_PREFIXES.waba
|
|
|
19691
19694
|
var WhatsAppFlowId = entityId("waflow").pipe(brand(ENTITY_PREFIXES.waflow));
|
|
19692
19695
|
var WhatsAppFlowVersionId = entityId("wafver").pipe(brand(ENTITY_PREFIXES.wafver));
|
|
19693
19696
|
var WhatsAppFlowRegistrationId = entityId("wafreg").pipe(brand(ENTITY_PREFIXES.wafreg));
|
|
19697
|
+
var WhatsAppFlowEncryptionKeyId = entityId("wafkey").pipe(brand(ENTITY_PREFIXES.wafkey));
|
|
19698
|
+
var WhatsAppFlowExchangeId = entityId("wafx").pipe(brand(ENTITY_PREFIXES.wafx));
|
|
19699
|
+
var WhatsAppSetupLinkId = entityId("wasl").pipe(brand(ENTITY_PREFIXES.wasl));
|
|
19694
19700
|
var WhatsAppServiceWindowId = entityId("wasw").pipe(brand(ENTITY_PREFIXES.wasw));
|
|
19695
19701
|
var WebhookEndpointId = entityId("wep").pipe(brand(ENTITY_PREFIXES.wep));
|
|
19696
19702
|
var WebhookCredentialId = entityId("whcred").pipe(brand(ENTITY_PREFIXES.whcred));
|
|
@@ -20398,6 +20404,7 @@ var DOMAIN_WEBHOOK_EVENT_TYPE_VALUES = [
|
|
|
20398
20404
|
var domainWebhookEventTypeSchema = Literals(DOMAIN_WEBHOOK_EVENT_TYPE_VALUES);
|
|
20399
20405
|
var TEMPLATE_WEBHOOK_EVENT_TYPE_VALUES = ["template.registration.updated"];
|
|
20400
20406
|
var FLOW_WEBHOOK_EVENT_TYPE_VALUES = ["flow.registration.updated"];
|
|
20407
|
+
var WHATSAPP_NUMBER_WEBHOOK_EVENT_TYPE_VALUES = ["whatsapp.number.connected"];
|
|
20401
20408
|
var MAILBOX_WEBHOOK_EVENT_TYPE_VALUES = [
|
|
20402
20409
|
"mailbox.message.received",
|
|
20403
20410
|
"mailbox.message.sent",
|
|
@@ -20422,6 +20429,7 @@ var WEBHOOK_EVENT_TYPE_VALUES = [
|
|
|
20422
20429
|
...DOMAIN_WEBHOOK_EVENT_TYPE_VALUES,
|
|
20423
20430
|
...TEMPLATE_WEBHOOK_EVENT_TYPE_VALUES,
|
|
20424
20431
|
...FLOW_WEBHOOK_EVENT_TYPE_VALUES,
|
|
20432
|
+
...WHATSAPP_NUMBER_WEBHOOK_EVENT_TYPE_VALUES,
|
|
20425
20433
|
...MAILBOX_WEBHOOK_EVENT_TYPE_VALUES,
|
|
20426
20434
|
...JOURNEY_WEBHOOK_EVENT_TYPE_VALUES
|
|
20427
20435
|
];
|
|
@@ -24149,6 +24157,7 @@ var CreateTemplatePayload = /* @__PURE__ */ Struct({
|
|
|
24149
24157
|
]), Null2]), Null2])),
|
|
24150
24158
|
isActive: optionalKey2(Union2([Boolean3, Null2])),
|
|
24151
24159
|
namespaceId: optionalKey2(Union2([NamespaceId2, Null2]).annotate({ description: "The namespace the new template project belongs to; the project and every entry added to it share it. Omit for organization level. A namespace-scoped key always creates in its own namespace." })),
|
|
24160
|
+
shared: optionalKey2(Union2([Boolean3, Null2]).annotate({ description: "Share the new organization-level project with every namespace: namespace-scoped keys read and send its entries but cannot change them. Defaults to false. Not with `namespaceId`, and not from a namespace-scoped key." })),
|
|
24152
24161
|
idempotencyKey: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(255).annotate({ expected: "a string with at most 255 code points" })).check(isMaxLength(255).annotate({ expected: "a value with a length of at most 255" }))
|
|
24153
24162
|
}).annotate({ identifier: "CreateTemplatePayload" });
|
|
24154
24163
|
var CreateWebhookPayload = /* @__PURE__ */ Struct({
|
|
@@ -24462,7 +24471,8 @@ var UpdateTemplatePayload = /* @__PURE__ */ Struct({ data: Struct({
|
|
|
24462
24471
|
]), Null2]), Null2])),
|
|
24463
24472
|
fromDefault: optionalKey2(Union2([Union2([TemplateFromDefault, Null2]), Null2])),
|
|
24464
24473
|
replyToDefault: optionalKey2(Union2([Union2([ArraySchema(String4), Null2]), Null2])),
|
|
24465
|
-
isActive: optionalKey2(Union2([Boolean3, Null2]))
|
|
24474
|
+
isActive: optionalKey2(Union2([Boolean3, Null2])),
|
|
24475
|
+
shared: optionalKey2(Union2([Boolean3, Null2]).annotate({ description: "Share the template's project with every namespace, or stop sharing it. Applies to every entry in the project. Only an organization-level project is shared." }))
|
|
24466
24476
|
}) }).annotate({ identifier: "UpdateTemplatePayload" });
|
|
24467
24477
|
var ApiKeyAccess = /* @__PURE__ */ Union2([Struct({ mode: Literal2("full") }), Struct({
|
|
24468
24478
|
mode: Literal2("restricted"),
|
|
@@ -24799,6 +24809,7 @@ var apiStatuses = {
|
|
|
24799
24809
|
MailboxSendConflictError: 409,
|
|
24800
24810
|
MailboxSendRefusedError: 403,
|
|
24801
24811
|
CursorExpiredError: 410,
|
|
24812
|
+
WhatsAppSetupLinkUnavailableError: 410,
|
|
24802
24813
|
MethodNotAllowedError: 405,
|
|
24803
24814
|
UpgradeRequiredError: 426,
|
|
24804
24815
|
RateLimitedError: 429,
|
|
@@ -25082,7 +25093,7 @@ var __exportAll = (all, no_symbols) => {
|
|
|
25082
25093
|
};
|
|
25083
25094
|
|
|
25084
25095
|
// ../sdk/dist/package.js
|
|
25085
|
-
var version = "0.
|
|
25096
|
+
var version = "0.21.0";
|
|
25086
25097
|
|
|
25087
25098
|
// ../sdk/dist/client-attribution.js
|
|
25088
25099
|
var SDK_VERSION = version;
|
|
@@ -25473,6 +25484,7 @@ var commandTree = {
|
|
|
25473
25484
|
webhooks: {
|
|
25474
25485
|
list: {},
|
|
25475
25486
|
get: {},
|
|
25487
|
+
secret: {},
|
|
25476
25488
|
create: {},
|
|
25477
25489
|
update: {},
|
|
25478
25490
|
test: {},
|
|
@@ -25903,7 +25915,12 @@ var getAuthenticatedJsonForContext = fn2("CliClient.getAuthenticatedJson")(funct
|
|
|
25903
25915
|
};
|
|
25904
25916
|
const url = `${config.baseUrl.replace(/\/$/, "")}${path}`;
|
|
25905
25917
|
const response = yield* tryPromise2({
|
|
25906
|
-
try: (signal) => fetch(url, request === undefined ? { headers, signal } : {
|
|
25918
|
+
try: (signal) => fetch(url, request === undefined ? { headers, signal } : {
|
|
25919
|
+
method: request.method ?? "POST",
|
|
25920
|
+
headers,
|
|
25921
|
+
body: JSON.stringify(request.body),
|
|
25922
|
+
signal
|
|
25923
|
+
}),
|
|
25907
25924
|
catch: (cause) => new SamvaCliError({ message: `Request to ${url} failed: ${String(cause)}` })
|
|
25908
25925
|
});
|
|
25909
25926
|
const body = yield* tryPromise2({
|
|
@@ -27166,6 +27183,10 @@ var SDK_OPERATION_CALLS = {
|
|
|
27166
27183
|
whoamiGet: { kind: "none" },
|
|
27167
27184
|
webhooksList: { kind: "params" },
|
|
27168
27185
|
webhooksCreate: { kind: "payload" },
|
|
27186
|
+
webhooksGetSecret: {
|
|
27187
|
+
kind: "path",
|
|
27188
|
+
paths: ["id"]
|
|
27189
|
+
},
|
|
27169
27190
|
webhooksGet: {
|
|
27170
27191
|
kind: "path",
|
|
27171
27192
|
paths: ["id"]
|
|
@@ -28558,6 +28579,7 @@ var SamvaOperations = {
|
|
|
28558
28579
|
webhooksRetryDelivery: operationMetadata96,
|
|
28559
28580
|
webhooksGetLogs: operationMetadata95,
|
|
28560
28581
|
webhooksRegenerateSecret: operationMetadata96,
|
|
28582
|
+
webhooksGetSecret: operationMetadata97,
|
|
28561
28583
|
webhooksGetStats: operationMetadata97,
|
|
28562
28584
|
webhooksTest: operationMetadata96,
|
|
28563
28585
|
whoamiGet: {
|
|
@@ -28804,6 +28826,7 @@ var ApiKey = /* @__PURE__ */ Struct({
|
|
|
28804
28826
|
name: String4,
|
|
28805
28827
|
key: optionalKey2(Union2([String4, Null2])),
|
|
28806
28828
|
start: Union2([String4, Null2]),
|
|
28829
|
+
end: Union2([String4, Null2]),
|
|
28807
28830
|
description: optionalKey2(Union2([String4, Null2])),
|
|
28808
28831
|
createdAt: String4,
|
|
28809
28832
|
expiresAt: Union2([String4, Null2]),
|
|
@@ -28817,6 +28840,7 @@ var ApiKeyWithSecret = /* @__PURE__ */ Struct({
|
|
|
28817
28840
|
name: String4,
|
|
28818
28841
|
key: SensitiveString,
|
|
28819
28842
|
start: Union2([String4, Null2]),
|
|
28843
|
+
end: Union2([String4, Null2]),
|
|
28820
28844
|
description: optionalKey2(Union2([String4, Null2])),
|
|
28821
28845
|
createdAt: String4,
|
|
28822
28846
|
expiresAt: Union2([String4, Null2]),
|
|
@@ -54206,6 +54230,7 @@ var CampaignLatestRun = /* @__PURE__ */ Struct({
|
|
|
54206
54230
|
dispatchedCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
54207
54231
|
failedCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
54208
54232
|
skippedCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
54233
|
+
pendingCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
54209
54234
|
estimatedCompletionAt: Union2([String4, Null2])
|
|
54210
54235
|
}).annotate({ identifier: "CampaignLatestRun" });
|
|
54211
54236
|
var CampaignRecipientPage = /* @__PURE__ */ Struct({
|
|
@@ -54304,11 +54329,14 @@ var CampaignRun = /* @__PURE__ */ Struct({
|
|
|
54304
54329
|
dispatchedCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
54305
54330
|
failedCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
54306
54331
|
skippedCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
54332
|
+
pendingCount: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
54307
54333
|
skippedReasons: ArraySchema(CampaignRunSkippedReason),
|
|
54308
54334
|
estimatedCompletionAt: Union2([String4, Null2]),
|
|
54309
54335
|
failureReason: Union2([String4, Null2]),
|
|
54310
54336
|
holdReason: Union2([String4, Null2]),
|
|
54311
54337
|
holdDomainId: Union2([EmailDomainId2, Null2]),
|
|
54338
|
+
holdUntil: Union2([String4, Null2]),
|
|
54339
|
+
capacityWarning: Union2([String4, Null2]),
|
|
54312
54340
|
lastContactId: Union2([String4, Null2]),
|
|
54313
54341
|
createdBy: Union2([String4, Null2]),
|
|
54314
54342
|
actorEmail: String4,
|
|
@@ -54659,6 +54687,23 @@ var resumeRun = /* @__PURE__ */ make42("campaignsResumeRun");
|
|
|
54659
54687
|
var cancelRun = /* @__PURE__ */ make42("campaignsCancelRun");
|
|
54660
54688
|
var listRecipients = /* @__PURE__ */ make42("campaignsListRecipients");
|
|
54661
54689
|
|
|
54690
|
+
// src/lib/run-hold.ts
|
|
54691
|
+
var WHATSAPP_MESSAGING_LIMIT_HOLD = "whatsapp_messaging_limit";
|
|
54692
|
+
var holdLabel = (reason) => reason === null || reason === undefined ? null : reason === WHATSAPP_MESSAGING_LIMIT_HOLD ? `${reason} (the number's messaging limit; the run resumes on its own)` : reason;
|
|
54693
|
+
var holdFields = (run) => [
|
|
54694
|
+
["Held", holdLabel(run.holdReason)],
|
|
54695
|
+
["Resumes at", run.holdUntil]
|
|
54696
|
+
];
|
|
54697
|
+
var campaignPacingFields = (run, options) => [
|
|
54698
|
+
...holdFields(run),
|
|
54699
|
+
[
|
|
54700
|
+
"Pending",
|
|
54701
|
+
run.pendingCount !== undefined && (run.pendingCount > 0 || run.holdReason != null) ? String(run.pendingCount) : null
|
|
54702
|
+
],
|
|
54703
|
+
["Est. completion", run.estimatedCompletionAt],
|
|
54704
|
+
...options.warning ? [["Capacity warning", run.capacityWarning]] : []
|
|
54705
|
+
];
|
|
54706
|
+
|
|
54662
54707
|
// src/lib/template-reference.ts
|
|
54663
54708
|
var publicationIdFlag = String9("publication-id").pipe(withDescription2("Pin one exact publication, so nothing published later changes what this renders"), optional4);
|
|
54664
54709
|
var inputContractIdFlag = String9("input-contract-id").pipe(withDescription2("Follow the newest publication that still validates input identically to this contract"), optional4);
|
|
@@ -55131,7 +55176,7 @@ var archive2 = make29("archive", {
|
|
|
55131
55176
|
["Definition", data.definition.state]
|
|
55132
55177
|
]);
|
|
55133
55178
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
55134
|
-
var printRun = (run) => printFields([
|
|
55179
|
+
var printRun = (run, options = { warning: true }) => printFields([
|
|
55135
55180
|
["Run ID", run.id],
|
|
55136
55181
|
["Campaign", run.campaignId],
|
|
55137
55182
|
["Status", run.status],
|
|
@@ -55146,8 +55191,10 @@ var printRun = (run) => printFields([
|
|
|
55146
55191
|
"Skipped by reason",
|
|
55147
55192
|
(run.skippedReasons ?? []).map(({ reason, count }) => `${reason} ${count}`).join(", ")
|
|
55148
55193
|
],
|
|
55149
|
-
["Failure", run.failureReason]
|
|
55194
|
+
["Failure", run.failureReason],
|
|
55195
|
+
...campaignPacingFields(run, options)
|
|
55150
55196
|
]);
|
|
55197
|
+
var warnCapacity = (run) => run.capacityWarning ? error(`Warning: ${run.capacityWarning}`) : void_3;
|
|
55151
55198
|
var runCreate = make29("create", {
|
|
55152
55199
|
campaignId: String10("campaignId"),
|
|
55153
55200
|
at: atFlag,
|
|
@@ -55186,7 +55233,8 @@ var runCreate = make29("create", {
|
|
|
55186
55233
|
return yield* printJson(data);
|
|
55187
55234
|
yield* logInfo(`Run scheduled.
|
|
55188
55235
|
`);
|
|
55189
|
-
yield* printRun(data);
|
|
55236
|
+
yield* printRun(data, { warning: false });
|
|
55237
|
+
yield* warnCapacity(data);
|
|
55190
55238
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
55191
55239
|
var runList = make29("list", {
|
|
55192
55240
|
campaignId: String10("campaignId"),
|
|
@@ -67136,6 +67184,18 @@ class WhatsAppTemplateIneligibleError extends TaggedError3()("WhatsAppTemplateIn
|
|
|
67136
67184
|
message: String4
|
|
67137
67185
|
}, { httpApiStatus: 422 }) {
|
|
67138
67186
|
}
|
|
67187
|
+
|
|
67188
|
+
class WhatsAppSetupLinkUnavailableError extends TaggedError3()("WhatsAppSetupLinkUnavailableError", {
|
|
67189
|
+
reason: Literals(["completed", "revoked", "expired"]),
|
|
67190
|
+
message: String4
|
|
67191
|
+
}, { httpApiStatus: 410 }) {
|
|
67192
|
+
static new(reason) {
|
|
67193
|
+
return new WhatsAppSetupLinkUnavailableError({
|
|
67194
|
+
reason,
|
|
67195
|
+
message: reason === "completed" ? "This setup link already connected a WhatsApp number. Ask for a new link to connect another." : reason === "revoked" ? "This setup link was revoked. Ask for a new link." : "This setup link expired. Ask for a new link."
|
|
67196
|
+
});
|
|
67197
|
+
}
|
|
67198
|
+
}
|
|
67139
67199
|
var EmailChannelErrorReason = Literals([
|
|
67140
67200
|
"transport",
|
|
67141
67201
|
"rejected",
|
|
@@ -67678,6 +67738,8 @@ var JourneyRun = /* @__PURE__ */ Struct({
|
|
|
67678
67738
|
exitReason: Union2([JourneyRunExitReason, Null2]),
|
|
67679
67739
|
failureReason: Union2([String4, Null2]),
|
|
67680
67740
|
currentNodeId: Union2([JourneyNodeId, Null2]),
|
|
67741
|
+
holdReason: Union2([String4, Null2]),
|
|
67742
|
+
holdUntil: Union2([String4, Null2]),
|
|
67681
67743
|
trigger: JourneyRunTrigger,
|
|
67682
67744
|
enteredAt: String4,
|
|
67683
67745
|
endedAt: Union2([String4, Null2])
|
|
@@ -67701,6 +67763,8 @@ var JourneyRunDetail = /* @__PURE__ */ Struct({
|
|
|
67701
67763
|
exitReason: Union2([JourneyRunExitReason, Null2]),
|
|
67702
67764
|
failureReason: Union2([String4, Null2]),
|
|
67703
67765
|
currentNodeId: Union2([JourneyNodeId, Null2]),
|
|
67766
|
+
holdReason: Union2([String4, Null2]),
|
|
67767
|
+
holdUntil: Union2([String4, Null2]),
|
|
67704
67768
|
trigger: JourneyRunTrigger,
|
|
67705
67769
|
enteredAt: String4,
|
|
67706
67770
|
endedAt: Union2([String4, Null2]),
|
|
@@ -68329,6 +68393,7 @@ var printRun2 = (run) => printFields([
|
|
|
68329
68393
|
["Exit reason", run.exitReason],
|
|
68330
68394
|
["Failure", run.failureReason],
|
|
68331
68395
|
["Current node", run.currentNodeId],
|
|
68396
|
+
...holdFields(run),
|
|
68332
68397
|
["Entered", run.enteredAt],
|
|
68333
68398
|
["Ended", run.endedAt]
|
|
68334
68399
|
]);
|
|
@@ -73851,7 +73916,8 @@ var TemplateFamilyId2 = /* @__PURE__ */ String4.check(isPattern2(/* @__PURE__ */
|
|
|
73851
73916
|
var VersionCursor2 = /* @__PURE__ */ String4.annotate({ identifier: "VersionCursor" });
|
|
73852
73917
|
var BrandFooterBlock = /* @__PURE__ */ Struct({
|
|
73853
73918
|
html: String4,
|
|
73854
|
-
text: String4
|
|
73919
|
+
text: String4,
|
|
73920
|
+
headCss: optionalKey2(Union2([String4, Null2]))
|
|
73855
73921
|
}).annotate({ identifier: "BrandFooterBlock" });
|
|
73856
73922
|
var TemplatePublicationRender = /* @__PURE__ */ Struct({
|
|
73857
73923
|
subject: String4,
|
|
@@ -73894,7 +73960,8 @@ var TemplateSummary = /* @__PURE__ */ Struct({
|
|
|
73894
73960
|
name: String4,
|
|
73895
73961
|
channel: Literal2("email"),
|
|
73896
73962
|
projectId: TemplateProjectId2,
|
|
73897
|
-
namespaceId: Union2([NamespaceId2, Null2]).annotate({ description: "The namespace the template's project belongs to; every entry in a project shares it. Null at organization level. A namespace-scoped key reaches only its own namespace's templates." }),
|
|
73963
|
+
namespaceId: Union2([NamespaceId2, Null2]).annotate({ description: "The namespace the template's project belongs to; every entry in a project shares it. Null at organization level. A namespace-scoped key reaches only its own namespace's templates and shared ones." }),
|
|
73964
|
+
shared: Boolean3.annotate({ description: "Whether the template's project is shared with every namespace. Every entry in a project shares it. A namespace-scoped key reads and sends a shared template in its own namespace but cannot change it. Only an organization-level project is shared." }),
|
|
73898
73965
|
entryPath: String4.check(isMaxCodePoints(1024).annotate({ expected: "a string with at most 1024 code points" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$", "u")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })).check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })),
|
|
73899
73966
|
status: Union2([
|
|
73900
73967
|
Literal2("draft"),
|
|
@@ -73919,7 +73986,8 @@ var Template = /* @__PURE__ */ Struct({
|
|
|
73919
73986
|
name: String4,
|
|
73920
73987
|
channel: Literal2("email"),
|
|
73921
73988
|
projectId: TemplateProjectId2,
|
|
73922
|
-
namespaceId: Union2([NamespaceId2, Null2]).annotate({ description: "The namespace the template's project belongs to; every entry in a project shares it. Null at organization level. A namespace-scoped key reaches only its own namespace's templates." }),
|
|
73989
|
+
namespaceId: Union2([NamespaceId2, Null2]).annotate({ description: "The namespace the template's project belongs to; every entry in a project shares it. Null at organization level. A namespace-scoped key reaches only its own namespace's templates and shared ones." }),
|
|
73990
|
+
shared: Boolean3.annotate({ description: "Whether the template's project is shared with every namespace. Every entry in a project shares it. A namespace-scoped key reads and sends a shared template in its own namespace but cannot change it. Only an organization-level project is shared." }),
|
|
73923
73991
|
entryPath: String4.check(isMaxCodePoints(1024).annotate({ expected: "a string with at most 1024 code points" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$", "u")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })).check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })),
|
|
73924
73992
|
status: Union2([
|
|
73925
73993
|
Literal2("draft"),
|
|
@@ -74004,7 +74072,8 @@ var TemplatesListQuery = /* @__PURE__ */ Struct({
|
|
|
74004
74072
|
]), Null2])),
|
|
74005
74073
|
search: optionalKey2(Union2([String4, Null2])),
|
|
74006
74074
|
projectId: optionalKey2(Union2([TemplateProjectId2, Null2])),
|
|
74007
|
-
namespaceId: optionalKey2(Union2([NamespaceId2, Null2]).annotate({ description: "Only templates
|
|
74075
|
+
namespaceId: optionalKey2(Union2([NamespaceId2, Null2]).annotate({ description: "Only the templates this namespace uses: its own and those shared with every namespace (add `shared=false` for its own only). A namespace-scoped key lists its own namespace's and shared templates." })),
|
|
74076
|
+
shared: optionalKey2(Union2([Union2([Literal2("true"), Literal2("false")]), Null2]).annotate({ description: "Only templates whose project is shared with every namespace (true), or only unshared ones (false)." }))
|
|
74008
74077
|
});
|
|
74009
74078
|
var TemplatesList200 = TemplatePage;
|
|
74010
74079
|
var TemplatesList401 = UnauthorizedError2;
|
|
@@ -74030,6 +74099,7 @@ var TemplatesCreateRequestJson = /* @__PURE__ */ Struct({
|
|
|
74030
74099
|
]), Null2]), Null2])),
|
|
74031
74100
|
isActive: optionalKey2(Union2([Boolean3, Null2])),
|
|
74032
74101
|
namespaceId: optionalKey2(Union2([NamespaceId2, Null2]).annotate({ description: "The namespace the new template project belongs to; the project and every entry added to it share it. Omit for organization level. A namespace-scoped key always creates in its own namespace." })),
|
|
74102
|
+
shared: optionalKey2(Union2([Boolean3, Null2]).annotate({ description: "Share the new organization-level project with every namespace: namespace-scoped keys read and send its entries but cannot change them. Defaults to false. Not with `namespaceId`, and not from a namespace-scoped key." })),
|
|
74033
74103
|
idempotencyKey: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(255).annotate({ expected: "a string with at most 255 code points" })).check(isMaxLength(255).annotate({ expected: "a value with a length of at most 255" }))
|
|
74034
74104
|
});
|
|
74035
74105
|
var TemplatesCreate201 = Template;
|
|
@@ -74073,7 +74143,8 @@ var TemplatesUpdateRequestJson = /* @__PURE__ */ Struct({ data: Struct({
|
|
|
74073
74143
|
]), Null2]), Null2])),
|
|
74074
74144
|
fromDefault: optionalKey2(Union2([Union2([TemplateFromDefault, Null2]), Null2])),
|
|
74075
74145
|
replyToDefault: optionalKey2(Union2([Union2([ArraySchema(String4), Null2]), Null2])),
|
|
74076
|
-
isActive: optionalKey2(Union2([Boolean3, Null2]))
|
|
74146
|
+
isActive: optionalKey2(Union2([Boolean3, Null2])),
|
|
74147
|
+
shared: optionalKey2(Union2([Boolean3, Null2]).annotate({ description: "Share the template's project with every namespace, or stop sharing it. Applies to every entry in the project. Only an organization-level project is shared." }))
|
|
74077
74148
|
}) });
|
|
74078
74149
|
var TemplatesUpdate200 = Template;
|
|
74079
74150
|
var TemplatesUpdate401 = UnauthorizedError2;
|
|
@@ -79060,6 +79131,11 @@ var WebhookDailyDeliveries = /* @__PURE__ */ Struct({
|
|
|
79060
79131
|
exhausted: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })),
|
|
79061
79132
|
cancelled: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" }))
|
|
79062
79133
|
}).annotate({ identifier: "WebhookDailyDeliveries" });
|
|
79134
|
+
var WebhookSigningSecret = /* @__PURE__ */ Struct({
|
|
79135
|
+
secret: SensitiveString,
|
|
79136
|
+
createdAt: String4,
|
|
79137
|
+
previousExpiresAt: Union2([String4, Null2])
|
|
79138
|
+
}).annotate({ identifier: "WebhookSigningSecret" });
|
|
79063
79139
|
var WebhookEndpoint = /* @__PURE__ */ Struct({
|
|
79064
79140
|
id: WebhookEndpointId2,
|
|
79065
79141
|
name: String4,
|
|
@@ -79388,6 +79464,14 @@ var WebhooksRegenerateSecret404 = ResourceNotFoundError2;
|
|
|
79388
79464
|
var WebhooksRegenerateSecret422 = ValidationError2;
|
|
79389
79465
|
var WebhooksRegenerateSecret500 = InternalError2;
|
|
79390
79466
|
var WebhooksRegenerateSecret504 = GatewayTimeoutError2;
|
|
79467
|
+
var WebhooksGetSecretPathParams = /* @__PURE__ */ Struct({ id: WebhookEndpointId2 });
|
|
79468
|
+
var WebhooksGetSecret200 = WebhookSigningSecret;
|
|
79469
|
+
var WebhooksGetSecret401 = UnauthorizedError2;
|
|
79470
|
+
var WebhooksGetSecret403 = ForbiddenError2;
|
|
79471
|
+
var WebhooksGetSecret404 = ResourceNotFoundError2;
|
|
79472
|
+
var WebhooksGetSecret422 = ValidationError2;
|
|
79473
|
+
var WebhooksGetSecret500 = InternalError2;
|
|
79474
|
+
var WebhooksGetSecret504 = GatewayTimeoutError2;
|
|
79391
79475
|
var WebhooksGetStatsPathParams = /* @__PURE__ */ Struct({ id: WebhookEndpointId2 });
|
|
79392
79476
|
var WebhooksGetStatsQuery = /* @__PURE__ */ Struct({
|
|
79393
79477
|
after: optionalKey2(Union2([String4, Null2])),
|
|
@@ -79437,7 +79521,7 @@ var WebhooksGroup = class extends make37("Webhooks").add(get5("webhooksList", "/
|
|
|
79437
79521
|
WebhooksCreate502.pipe(status(502)),
|
|
79438
79522
|
WebhooksCreate504.pipe(status(504))
|
|
79439
79523
|
]
|
|
79440
|
-
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "webhooks.create").annotate(Summary, "Create a webhook").annotate(Description, "Creates a signed webhook endpoint for Samva delivery and inbound events, stores subscriptions, and returns the endpoint and signing secret with a 201 response. `
|
|
79524
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "webhooks.create").annotate(Summary, "Create a webhook").annotate(Description, "Creates a signed webhook endpoint for Samva delivery and inbound events, stores subscriptions, and returns the endpoint and signing secret with a 201 response. `namespaceId` confines the endpoint to one namespace's events and `mailboxIds` to those mailboxes' events; when both are set, every mailbox must belong to the namespace."), get5("webhooksGet", "/v1/webhooks/:id", {
|
|
79441
79525
|
params: WebhooksGetPathParams,
|
|
79442
79526
|
success: WebhooksGet200,
|
|
79443
79527
|
error: [
|
|
@@ -79508,7 +79592,18 @@ var WebhooksGroup = class extends make37("Webhooks").add(get5("webhooksList", "/
|
|
|
79508
79592
|
WebhooksRegenerateSecret500,
|
|
79509
79593
|
WebhooksRegenerateSecret504.pipe(status(504))
|
|
79510
79594
|
]
|
|
79511
|
-
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "webhooks.regenerateSecret").annotate(Summary, "Rotate a webhook signing secret").annotate(Description, "Generates and returns a new signing secret. The previous secret remains valid for a 24-hour rotation overlap."), get5("
|
|
79595
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "webhooks.regenerateSecret").annotate(Summary, "Rotate a webhook signing secret").annotate(Description, "Generates and returns a new signing secret. The previous secret remains valid for a 24-hour rotation overlap."), get5("webhooksGetSecret", "/v1/webhooks/:id/secret", {
|
|
79596
|
+
params: WebhooksGetSecretPathParams,
|
|
79597
|
+
success: WebhooksGetSecret200,
|
|
79598
|
+
error: [
|
|
79599
|
+
WebhooksGetSecret401.pipe(status(401)),
|
|
79600
|
+
WebhooksGetSecret403.pipe(status(403)),
|
|
79601
|
+
WebhooksGetSecret404.pipe(status(404)),
|
|
79602
|
+
WebhooksGetSecret422.pipe(status(422)),
|
|
79603
|
+
WebhooksGetSecret500,
|
|
79604
|
+
WebhooksGetSecret504.pipe(status(504))
|
|
79605
|
+
]
|
|
79606
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "webhooks.getSecret").annotate(Summary, "Get a webhook signing secret").annotate(Description, "Returns the endpoint's current signing secret and when a rotated-out secret stops verifying. It needs the same permission as rotating the secret."), get5("webhooksGetStats", "/v1/webhooks/:id/stats", {
|
|
79512
79607
|
params: WebhooksGetStatsPathParams,
|
|
79513
79608
|
query: WebhooksGetStatsQuery,
|
|
79514
79609
|
success: WebhooksGetStats200,
|
|
@@ -79539,6 +79634,7 @@ var WebhooksGroup = class extends make37("Webhooks").add(get5("webhooksList", "/
|
|
|
79539
79634
|
var make55 = /* @__PURE__ */ forGroup(WebhooksGroup);
|
|
79540
79635
|
var list27 = /* @__PURE__ */ make55("webhooksList");
|
|
79541
79636
|
var create16 = /* @__PURE__ */ make55("webhooksCreate");
|
|
79637
|
+
var getSecret = /* @__PURE__ */ make55("webhooksGetSecret");
|
|
79542
79638
|
var get28 = /* @__PURE__ */ make55("webhooksGet");
|
|
79543
79639
|
var remove14 = /* @__PURE__ */ make55("webhooksRemove");
|
|
79544
79640
|
var update13 = /* @__PURE__ */ make55("webhooksUpdate");
|
|
@@ -79628,6 +79724,18 @@ var get29 = make29("get", { id: idArgument4, json: jsonFlag }).pipe(withDescript
|
|
|
79628
79724
|
["URL", data.url]
|
|
79629
79725
|
]);
|
|
79630
79726
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
79727
|
+
var secret = make29("secret", { id: idArgument4, json: jsonFlag }).pipe(withDescription3("Read the current webhook signing secret (requires webhooks:update)"), withExamples([{ command: "samva webhooks secret wep_abc123 --json" }]), withHandler(({ id, json }) => gen2(function* () {
|
|
79728
|
+
const client = yield* getClientProvider;
|
|
79729
|
+
const data = yield* getSecret({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not read webhook signing secret", error)));
|
|
79730
|
+
if (json)
|
|
79731
|
+
return yield* printJson({ ...data, secret: value2(data.secret) });
|
|
79732
|
+
yield* printFields([
|
|
79733
|
+
["Signing secret", value2(data.secret)],
|
|
79734
|
+
["Created at", data.createdAt]
|
|
79735
|
+
]);
|
|
79736
|
+
if (data.previousExpiresAt !== null)
|
|
79737
|
+
yield* log(`The previous secret keeps verifying until ${data.previousExpiresAt}.`);
|
|
79738
|
+
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
79631
79739
|
var logs = make29("logs", {
|
|
79632
79740
|
id: idArgument4,
|
|
79633
79741
|
limit: Int5("limit").pipe(optional4),
|
|
@@ -79785,15 +79893,15 @@ var rotate3 = make29("rotate-secret", {
|
|
|
79785
79893
|
yield* confirmDestructive({
|
|
79786
79894
|
yes,
|
|
79787
79895
|
json,
|
|
79788
|
-
message: `Rotate the signing secret for webhook ${id}? The
|
|
79896
|
+
message: `Rotate the signing secret for webhook ${id}? The previous secret keeps verifying for 24 hours.`,
|
|
79789
79897
|
nonInteractiveMessage: "Secret rotation requires --yes in non-interactive mode. Preview with --dry-run."
|
|
79790
79898
|
});
|
|
79791
79899
|
const client = yield* getClientProvider;
|
|
79792
79900
|
const data = yield* regenerateSecret({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not rotate webhook secret", error)));
|
|
79793
|
-
const warning =
|
|
79901
|
+
const warning = `Read this signing secret again with samva webhooks secret ${id}. The previous secret remains valid for 24 hours.`;
|
|
79794
79902
|
const secret = value2(data.secret);
|
|
79795
79903
|
if (json)
|
|
79796
|
-
return yield* printJson({ secret,
|
|
79904
|
+
return yield* printJson({ secret, warning });
|
|
79797
79905
|
yield* error(`WARNING: ${warning}`);
|
|
79798
79906
|
yield* log(secret);
|
|
79799
79907
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
@@ -79814,10 +79922,10 @@ var create17 = make29("create", {
|
|
|
79814
79922
|
]);
|
|
79815
79923
|
const client = yield* getClientProvider;
|
|
79816
79924
|
const result = yield* create16(payload).pipe(client.provide, mapError2((error) => toCliApiError("Could not create webhook", error)));
|
|
79817
|
-
const warning =
|
|
79925
|
+
const warning = `Read this signing secret again with samva webhooks secret ${result.endpoint.id}.`;
|
|
79818
79926
|
const secret = value2(result.secret);
|
|
79819
79927
|
if (json)
|
|
79820
|
-
return yield* printJson({ endpoint: result.endpoint, secret,
|
|
79928
|
+
return yield* printJson({ endpoint: result.endpoint, secret, warning });
|
|
79821
79929
|
yield* error(`WARNING: ${warning}`);
|
|
79822
79930
|
yield* printFields([
|
|
79823
79931
|
["ID", result.endpoint.id],
|
|
@@ -79873,7 +79981,19 @@ var remove15 = make29("remove", {
|
|
|
79873
79981
|
return yield* printJson(result);
|
|
79874
79982
|
yield* log(`Removed webhook ${id}.`);
|
|
79875
79983
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
79876
|
-
var webhooksCommand = make29("webhooks").pipe(withDescription3("Inspect, test, and recover customer webhooks"), withExamples([{ command: "samva webhooks list --json" }]), withSubcommands([
|
|
79984
|
+
var webhooksCommand = make29("webhooks").pipe(withDescription3("Inspect, test, and recover customer webhooks"), withExamples([{ command: "samva webhooks list --json" }]), withSubcommands([
|
|
79985
|
+
list28,
|
|
79986
|
+
get29,
|
|
79987
|
+
secret,
|
|
79988
|
+
create17,
|
|
79989
|
+
update14,
|
|
79990
|
+
test2,
|
|
79991
|
+
logs,
|
|
79992
|
+
stats3,
|
|
79993
|
+
retry4,
|
|
79994
|
+
rotate3,
|
|
79995
|
+
remove15
|
|
79996
|
+
]));
|
|
79877
79997
|
|
|
79878
79998
|
// src/lib/root-commands.ts
|
|
79879
79999
|
var rootCommands = [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@samva/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Samva CLI — email and platform operations from your terminal",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -50,22 +50,22 @@
|
|
|
50
50
|
"@effect/vitest": "4.0.0",
|
|
51
51
|
"@samva/contracts": "0.0.0",
|
|
52
52
|
"@samva/core": "0.0.0",
|
|
53
|
-
"@samva/mailbox": "0.5.
|
|
53
|
+
"@samva/mailbox": "0.5.1",
|
|
54
54
|
"@samva/markup": "^0.13.1",
|
|
55
55
|
"@samva/vite": "^0.13.1",
|
|
56
56
|
"@types/node": "^26.6.2",
|
|
57
57
|
"better-auth": "1.7.5",
|
|
58
58
|
"effect": "4.0.0",
|
|
59
|
-
"samva": "0.
|
|
59
|
+
"samva": "0.21.0",
|
|
60
60
|
"typescript": "^7.0.2",
|
|
61
61
|
"vite": "~8.3.0",
|
|
62
62
|
"vitest": "^5.0.3"
|
|
63
63
|
},
|
|
64
64
|
"optionalDependencies": {
|
|
65
|
-
"@samva/cli-darwin-arm64": "0.
|
|
66
|
-
"@samva/cli-darwin-x64": "0.
|
|
67
|
-
"@samva/cli-linux-arm64": "0.
|
|
68
|
-
"@samva/cli-linux-x64": "0.
|
|
65
|
+
"@samva/cli-darwin-arm64": "0.18.0",
|
|
66
|
+
"@samva/cli-darwin-x64": "0.18.0",
|
|
67
|
+
"@samva/cli-linux-arm64": "0.18.0",
|
|
68
|
+
"@samva/cli-linux-x64": "0.18.0"
|
|
69
69
|
},
|
|
70
70
|
"engines": {
|
|
71
71
|
"node": ">=18"
|