@samva/cli 0.4.0 → 0.5.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 +12 -2
- package/README.md +79 -32
- package/dist/bin.mjs +1024 -361
- package/package.json +8 -9
package/dist/bin.mjs
CHANGED
|
@@ -13567,7 +13567,7 @@ var layer12 = /* @__PURE__ */ layer.pipe(/* @__PURE__ */ provideMerge(/* @__PURE
|
|
|
13567
13567
|
// package.json
|
|
13568
13568
|
var package_default = {
|
|
13569
13569
|
name: "@samva/cli",
|
|
13570
|
-
version: "0.
|
|
13570
|
+
version: "0.5.0",
|
|
13571
13571
|
description: "Samva CLI \u2014 email and platform operations from your terminal",
|
|
13572
13572
|
keywords: [
|
|
13573
13573
|
"cli",
|
|
@@ -13615,21 +13615,20 @@ var package_default = {
|
|
|
13615
13615
|
devDependencies: {
|
|
13616
13616
|
"@effect/platform-bun": "catalog:effect",
|
|
13617
13617
|
"@effect/vitest": "catalog:effect",
|
|
13618
|
-
"@samva/markup": "workspace:0.
|
|
13619
|
-
"@samva/vite": "workspace:0.
|
|
13618
|
+
"@samva/markup": "workspace:0.9.0",
|
|
13619
|
+
"@samva/vite": "workspace:0.9.0",
|
|
13620
13620
|
"@types/node": "catalog:",
|
|
13621
13621
|
"better-auth": "catalog:",
|
|
13622
|
-
"better-result": "catalog:",
|
|
13623
13622
|
effect: "catalog:effect",
|
|
13624
|
-
samva: "workspace:0.
|
|
13623
|
+
samva: "workspace:0.8.0",
|
|
13625
13624
|
typescript: "catalog:",
|
|
13626
13625
|
vitest: "catalog:"
|
|
13627
13626
|
},
|
|
13628
13627
|
optionalDependencies: {
|
|
13629
|
-
"@samva/cli-darwin-arm64": "workspace:0.
|
|
13630
|
-
"@samva/cli-darwin-x64": "workspace:0.
|
|
13631
|
-
"@samva/cli-linux-arm64": "workspace:0.
|
|
13632
|
-
"@samva/cli-linux-x64": "workspace:0.
|
|
13628
|
+
"@samva/cli-darwin-arm64": "workspace:0.5.0",
|
|
13629
|
+
"@samva/cli-darwin-x64": "workspace:0.5.0",
|
|
13630
|
+
"@samva/cli-linux-arm64": "workspace:0.5.0",
|
|
13631
|
+
"@samva/cli-linux-x64": "workspace:0.5.0"
|
|
13633
13632
|
},
|
|
13634
13633
|
engines: {
|
|
13635
13634
|
node: ">=18"
|
|
@@ -18534,6 +18533,32 @@ var AGENT_AUTH_HINT = "For CI and agents, set SAMVA_API_KEY instead of samva log
|
|
|
18534
18533
|
// src/commands/brands.ts
|
|
18535
18534
|
import { join as join3, relative, resolve as resolve5 } from "path";
|
|
18536
18535
|
|
|
18536
|
+
// ../markup/dist/diagnostics.js
|
|
18537
|
+
var buildLineMap = (source) => {
|
|
18538
|
+
const lineStarts = [0];
|
|
18539
|
+
for (let index = 0;index < source.length; index++) {
|
|
18540
|
+
const code = source.charCodeAt(index);
|
|
18541
|
+
if (code === 10 || code === 13 && source.charCodeAt(index + 1) !== 10 || code === 8232 || code === 8233)
|
|
18542
|
+
lineStarts.push(index + 1);
|
|
18543
|
+
}
|
|
18544
|
+
return lineStarts;
|
|
18545
|
+
};
|
|
18546
|
+
var lineColumn = (lineMap, offset) => {
|
|
18547
|
+
let low = 0;
|
|
18548
|
+
let high = lineMap.length - 1;
|
|
18549
|
+
while (low < high) {
|
|
18550
|
+
const middle = low + high + 1 >> 1;
|
|
18551
|
+
if (lineMap[middle] <= offset)
|
|
18552
|
+
low = middle;
|
|
18553
|
+
else
|
|
18554
|
+
high = middle - 1;
|
|
18555
|
+
}
|
|
18556
|
+
return {
|
|
18557
|
+
line: low + 1,
|
|
18558
|
+
column: offset - lineMap[low] + 1
|
|
18559
|
+
};
|
|
18560
|
+
};
|
|
18561
|
+
|
|
18537
18562
|
// ../../node_modules/.bun/better-result@3.0.1/node_modules/better-result/dist/index.mjs
|
|
18538
18563
|
function e(e, t) {
|
|
18539
18564
|
return e === 2 ? (...e) => e.length >= 2 ? t(e[0], e[1]) : (n) => t(n, e[0]) : e === 3 ? (...e) => e.length >= 3 ? t(e[0], e[1], e[2]) : (n) => t(n, e[0], e[1]) : e === 4 ? (...e) => e.length >= 4 ? t(e[0], e[1], e[2], e[3]) : (n) => t(n, e[0], e[1], e[2]) : (...n) => n.length >= e ? t(...n) : (e) => t(e, ...n);
|
|
@@ -18973,50 +18998,6 @@ var $ = (e) => {
|
|
|
18973
18998
|
};
|
|
18974
18999
|
var ae = { ok: l, isOk: u, err: d, isError: f, try: T, tryPromise: E, map: D, mapError: O, tryRecover: k, andThen: A, tryRecoverAsync: ee, andThenAsync: te, match: ne, tap: j, tapAsync: M, tapError: N, tapErrorAsync: P, tapBoth: F, tapBothAsync: I, unwrap: L, unwrapOr: z, gen: B, await: V, codec: re, all: Q, allAsync: ie, partition: $, partitionAsync: async (e) => $(await Z(e, `Result.partitionAsync input promise rejected`)), flatten: (e) => e.status === `ok` ? e.value : e };
|
|
18975
19000
|
|
|
18976
|
-
// ../markup/dist/diagnostics.js
|
|
18977
|
-
var diagnosticsMessage = (diagnostics) => diagnostics.map((diagnostic) => diagnostic.message).join(`
|
|
18978
|
-
`);
|
|
18979
|
-
var SmlParseError = class extends h("SmlParseError") {
|
|
18980
|
-
constructor(args) {
|
|
18981
|
-
super({
|
|
18982
|
-
diagnostics: args.diagnostics,
|
|
18983
|
-
message: diagnosticsMessage(args.diagnostics)
|
|
18984
|
-
});
|
|
18985
|
-
}
|
|
18986
|
-
};
|
|
18987
|
-
var SmlCompileError = class extends h("SmlCompileError") {
|
|
18988
|
-
constructor(args) {
|
|
18989
|
-
super({
|
|
18990
|
-
diagnostics: args.diagnostics,
|
|
18991
|
-
message: diagnosticsMessage(args.diagnostics)
|
|
18992
|
-
});
|
|
18993
|
-
}
|
|
18994
|
-
};
|
|
18995
|
-
var buildLineMap = (source) => {
|
|
18996
|
-
const lineStarts = [0];
|
|
18997
|
-
for (let index = 0;index < source.length; index++) {
|
|
18998
|
-
const code = source.charCodeAt(index);
|
|
18999
|
-
if (code === 10 || code === 13 && source.charCodeAt(index + 1) !== 10 || code === 8232 || code === 8233)
|
|
19000
|
-
lineStarts.push(index + 1);
|
|
19001
|
-
}
|
|
19002
|
-
return lineStarts;
|
|
19003
|
-
};
|
|
19004
|
-
var lineColumn = (lineMap, offset) => {
|
|
19005
|
-
let low = 0;
|
|
19006
|
-
let high = lineMap.length - 1;
|
|
19007
|
-
while (low < high) {
|
|
19008
|
-
const middle = low + high + 1 >> 1;
|
|
19009
|
-
if (lineMap[middle] <= offset)
|
|
19010
|
-
low = middle;
|
|
19011
|
-
else
|
|
19012
|
-
high = middle - 1;
|
|
19013
|
-
}
|
|
19014
|
-
return {
|
|
19015
|
-
line: low + 1,
|
|
19016
|
-
column: offset - lineMap[low] + 1
|
|
19017
|
-
};
|
|
19018
|
-
};
|
|
19019
|
-
|
|
19020
19001
|
// ../../node_modules/.bun/css-tree@3.2.1/node_modules/css-tree/lib/tokenizer/types.js
|
|
19021
19002
|
var EOF = 0;
|
|
19022
19003
|
var Ident = 1;
|
|
@@ -42613,8 +42594,8 @@ function buildMessagesSendPayload(input) {
|
|
|
42613
42594
|
};
|
|
42614
42595
|
}
|
|
42615
42596
|
|
|
42616
|
-
// ../sdk/dist/client-attribution-
|
|
42617
|
-
var SDK_VERSION = "0.
|
|
42597
|
+
// ../sdk/dist/client-attribution-N5A784Zo.js
|
|
42598
|
+
var SDK_VERSION = "0.8.0";
|
|
42618
42599
|
var CLIENT_ATTRIBUTION_HEADER = "x-samva-client";
|
|
42619
42600
|
var clientAttribution = (surface) => `${surface}/${SDK_VERSION}`;
|
|
42620
42601
|
// ../../node_modules/.bun/effect@4.0.0-rc.117/node_modules/effect/dist/ChannelSchema.js
|
|
@@ -44938,7 +44919,7 @@ var fetch2 = /* @__PURE__ */ make32((request, url, signal, fiber) => {
|
|
|
44938
44919
|
});
|
|
44939
44920
|
var layer15 = /* @__PURE__ */ layerMergedContext(/* @__PURE__ */ succeed6(fetch2));
|
|
44940
44921
|
|
|
44941
|
-
// ../sdk/dist/client-
|
|
44922
|
+
// ../sdk/dist/client-ByJHYp7r.js
|
|
44942
44923
|
var Sensitive = (schema) => RedactedFromValue(schema);
|
|
44943
44924
|
var SensitiveString = Sensitive(String4);
|
|
44944
44925
|
var ABSOLUTE_ISO_INSTANT_PATTERN = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?(Z|([+-])(\d{2}):(\d{2}))$/;
|
|
@@ -45083,6 +45064,14 @@ var TemplateId = String4.pipe(brand2("TemplateId")).check(isPattern2(/* @__PURE_
|
|
|
45083
45064
|
identifier: "TemplateId"
|
|
45084
45065
|
}));
|
|
45085
45066
|
var JsonObject = Record(String4, JsonValue).annotate({ identifier: "JsonObject" });
|
|
45067
|
+
var RenderLocale = String4.check(isMaxLength(64).annotate({
|
|
45068
|
+
expected: "a value with a length of at most 64",
|
|
45069
|
+
identifier: "RenderLocale"
|
|
45070
|
+
}));
|
|
45071
|
+
var RenderTimeZone = String4.check(isMaxLength(64).annotate({
|
|
45072
|
+
expected: "a value with a length of at most 64",
|
|
45073
|
+
identifier: "RenderTimeZone"
|
|
45074
|
+
}));
|
|
45086
45075
|
var ReplyToAddresses = Union2([Union2([ArraySchema(String4), Null2]), Null2]).annotate({ identifier: "ReplyToAddresses" });
|
|
45087
45076
|
var UnsubscribeId = String4.pipe(brand2("UnsubscribeId")).check(isPattern2(/* @__PURE__ */ new RegExp("^unsub_[0-9a-hjkmnp-tv-z]{16,24}$")).annotate({
|
|
45088
45077
|
expected: "a string matching the RegExp ^unsub_[0-9a-hjkmnp-tv-z]{16,24}$",
|
|
@@ -45477,6 +45466,29 @@ var OperationResource = Struct({
|
|
|
45477
45466
|
type: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxLength(80).annotate({ expected: "a value with a length of at most 80" })),
|
|
45478
45467
|
id: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxLength(255).annotate({ expected: "a value with a length of at most 255" }))
|
|
45479
45468
|
}).annotate({ identifier: "OperationResource" });
|
|
45469
|
+
var Organization = Struct({
|
|
45470
|
+
id: String4,
|
|
45471
|
+
billingAccountId: String4,
|
|
45472
|
+
name: String4,
|
|
45473
|
+
slug: String4,
|
|
45474
|
+
countryCode: String4,
|
|
45475
|
+
timezone: String4,
|
|
45476
|
+
plan: String4,
|
|
45477
|
+
isActive: Boolean3,
|
|
45478
|
+
createdAt: String4,
|
|
45479
|
+
updatedAt: String4,
|
|
45480
|
+
metadata: Union2([Record(String4, JsonValue), Null2]),
|
|
45481
|
+
replyToDefault: Union2([ArraySchema(String4), Null2]),
|
|
45482
|
+
emailFooterEnabledDefault: Union2([Boolean3, Null2]),
|
|
45483
|
+
messagesUsed: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
45484
|
+
messagesUsedThisMonth: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
45485
|
+
emailUsed: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
45486
|
+
emailUsedThisMonth: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
45487
|
+
contactsUsed: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
45488
|
+
conversationsUsed: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
45489
|
+
teamMembersUsed: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
45490
|
+
messagesResetAt: Union2([String4, Null2])
|
|
45491
|
+
}).annotate({ identifier: "Organization" });
|
|
45480
45492
|
var TemplateProjectId = String4.pipe(brand2("TemplateProjectId")).check(isPattern2(/* @__PURE__ */ new RegExp("^tproj_[0-9a-hjkmnp-tv-z]{16,24}$")).annotate({
|
|
45481
45493
|
expected: "a string matching the RegExp ^tproj_[0-9a-hjkmnp-tv-z]{16,24}$",
|
|
45482
45494
|
identifier: "TemplateProjectId"
|
|
@@ -45494,6 +45506,10 @@ var TemplatePublicationBrand = Struct({
|
|
|
45494
45506
|
digest: String4.annotate({ description: "The brand's digest when the publication was built." }),
|
|
45495
45507
|
stale: Boolean3.annotate({ description: "Whether the brand has changed since this publication was built. Publishing the same commit again picks up the change." })
|
|
45496
45508
|
}).annotate({ identifier: "TemplatePublicationBrand" });
|
|
45509
|
+
var BrandFooterBlock = Struct({
|
|
45510
|
+
html: String4,
|
|
45511
|
+
text: String4
|
|
45512
|
+
}).annotate({ identifier: "BrandFooterBlock" });
|
|
45497
45513
|
var WebhookDeliveryCounts = Struct({
|
|
45498
45514
|
total: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })),
|
|
45499
45515
|
pending: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })),
|
|
@@ -45521,7 +45537,7 @@ var WebhookDailyDeliveries = Struct({
|
|
|
45521
45537
|
cancelled: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" }))
|
|
45522
45538
|
}).annotate({ identifier: "WebhookDailyDeliveries" });
|
|
45523
45539
|
Struct({
|
|
45524
|
-
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$" })),
|
|
45540
|
+
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })),
|
|
45525
45541
|
name: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxLength(200).annotate({ expected: "a value with a length of at most 200" })),
|
|
45526
45542
|
slug: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^(?=.{1,100}$)[a-z0-9]+(?:-[a-z0-9]+)*$")).annotate({ expected: "a string matching the RegExp ^(?=.{1,100}$)[a-z0-9]+(?:-[a-z0-9]+)*$" })),
|
|
45527
45543
|
description: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
|
|
@@ -45586,9 +45602,13 @@ var CreateWebhookPayload = Struct({
|
|
|
45586
45602
|
"message.bounced",
|
|
45587
45603
|
"message.complained",
|
|
45588
45604
|
"message.received",
|
|
45605
|
+
"message.opened",
|
|
45606
|
+
"message.clicked",
|
|
45589
45607
|
"contact.created",
|
|
45590
45608
|
"contact.updated",
|
|
45591
45609
|
"contact.deleted",
|
|
45610
|
+
"contact.unsubscribed",
|
|
45611
|
+
"contact.resubscribed",
|
|
45592
45612
|
"conversation.created",
|
|
45593
45613
|
"conversation.updated",
|
|
45594
45614
|
"conversation.archived",
|
|
@@ -45623,9 +45643,13 @@ var UpdateWebhookPayload = Struct({
|
|
|
45623
45643
|
"message.bounced",
|
|
45624
45644
|
"message.complained",
|
|
45625
45645
|
"message.received",
|
|
45646
|
+
"message.opened",
|
|
45647
|
+
"message.clicked",
|
|
45626
45648
|
"contact.created",
|
|
45627
45649
|
"contact.updated",
|
|
45628
45650
|
"contact.deleted",
|
|
45651
|
+
"contact.unsubscribed",
|
|
45652
|
+
"contact.resubscribed",
|
|
45629
45653
|
"conversation.created",
|
|
45630
45654
|
"conversation.updated",
|
|
45631
45655
|
"conversation.archived",
|
|
@@ -45704,30 +45728,6 @@ var CampaignPolicy = Struct({
|
|
|
45704
45728
|
unsubscribeGroupId: optionalKey2(Union2([UnsubscribeId, Null2])),
|
|
45705
45729
|
pageSize: optionalKey2(Union2([Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(100).annotate({ expected: "a value greater than or equal to 100" })).check(isLessThanOrEqualTo3(1000).annotate({ expected: "a value less than or equal to 1000" })), Null2]))
|
|
45706
45730
|
}).annotate({ identifier: "CampaignPolicy" });
|
|
45707
|
-
var Organization = Struct({
|
|
45708
|
-
id: String4,
|
|
45709
|
-
billingAccountId: String4,
|
|
45710
|
-
name: String4,
|
|
45711
|
-
slug: String4,
|
|
45712
|
-
countryCode: String4,
|
|
45713
|
-
timezone: String4,
|
|
45714
|
-
plan: String4,
|
|
45715
|
-
isActive: Boolean3,
|
|
45716
|
-
createdAt: String4,
|
|
45717
|
-
updatedAt: String4,
|
|
45718
|
-
metadata: Union2([Record(String4, JsonValue), Null2]),
|
|
45719
|
-
replyToDefault: Union2([ArraySchema(String4), Null2]),
|
|
45720
|
-
defaultUnsubscribeGroupId: Union2([UnsubscribeId, Null2]),
|
|
45721
|
-
emailFooterEnabledDefault: Union2([Boolean3, Null2]),
|
|
45722
|
-
messagesUsed: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
45723
|
-
messagesUsedThisMonth: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
45724
|
-
emailUsed: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
45725
|
-
emailUsedThisMonth: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
45726
|
-
contactsUsed: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
45727
|
-
conversationsUsed: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
45728
|
-
teamMembersUsed: Finite.check(isFinite4().annotate({ expected: "a finite number" })),
|
|
45729
|
-
messagesResetAt: Union2([String4, Null2])
|
|
45730
|
-
}).annotate({ identifier: "Organization" });
|
|
45731
45731
|
var MessageContent = Struct({
|
|
45732
45732
|
text: optionalKey2(Union2([String4, Null2])),
|
|
45733
45733
|
html: optionalKey2(Union2([String4, Null2])),
|
|
@@ -45888,7 +45888,7 @@ var ActorTracking = Struct({
|
|
|
45888
45888
|
actorType: Literals([
|
|
45889
45889
|
"contact",
|
|
45890
45890
|
"system",
|
|
45891
|
-
"
|
|
45891
|
+
"sender",
|
|
45892
45892
|
"agent",
|
|
45893
45893
|
"user"
|
|
45894
45894
|
]),
|
|
@@ -45910,7 +45910,7 @@ var ConversationParticipant = Struct({
|
|
|
45910
45910
|
actorType: Literals([
|
|
45911
45911
|
"contact",
|
|
45912
45912
|
"system",
|
|
45913
|
-
"
|
|
45913
|
+
"sender",
|
|
45914
45914
|
"agent",
|
|
45915
45915
|
"user"
|
|
45916
45916
|
]),
|
|
@@ -45928,9 +45928,13 @@ var WebhookEndpoint = Struct({
|
|
|
45928
45928
|
"message.bounced",
|
|
45929
45929
|
"message.complained",
|
|
45930
45930
|
"message.received",
|
|
45931
|
+
"message.opened",
|
|
45932
|
+
"message.clicked",
|
|
45931
45933
|
"contact.created",
|
|
45932
45934
|
"contact.updated",
|
|
45933
45935
|
"contact.deleted",
|
|
45936
|
+
"contact.unsubscribed",
|
|
45937
|
+
"contact.resubscribed",
|
|
45934
45938
|
"conversation.created",
|
|
45935
45939
|
"conversation.updated",
|
|
45936
45940
|
"conversation.archived",
|
|
@@ -46259,7 +46263,7 @@ var TemplateFamily = Struct({
|
|
|
46259
46263
|
var UpdateTemplatePayload = Struct({ data: Struct({
|
|
46260
46264
|
name: optionalKey2(Union2([String4, Null2])),
|
|
46261
46265
|
slug: optionalKey2(Union2([String4.check(isPattern2(/* @__PURE__ */ new RegExp("^(?=.{1,100}$)[a-z0-9]+(?:-[a-z0-9]+)*$")).annotate({ expected: "a string matching the RegExp ^(?=.{1,100}$)[a-z0-9]+(?:-[a-z0-9]+)*$" })), Null2])),
|
|
46262
|
-
entryPath: optionalKey2(Union2([String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$" })), Null2])),
|
|
46266
|
+
entryPath: optionalKey2(Union2([String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })), Null2])),
|
|
46263
46267
|
description: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
|
|
46264
46268
|
category: optionalKey2(Union2([Union2([Literals([
|
|
46265
46269
|
"transactional",
|
|
@@ -46278,7 +46282,7 @@ var Template = Struct({
|
|
|
46278
46282
|
id: TemplateId,
|
|
46279
46283
|
organizationId: OrganizationId,
|
|
46280
46284
|
projectId: TemplateProjectId,
|
|
46281
|
-
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$" })),
|
|
46285
|
+
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })),
|
|
46282
46286
|
name: String4,
|
|
46283
46287
|
slug: String4,
|
|
46284
46288
|
familyId: Union2([TemplateFamilyId, Null2]),
|
|
@@ -46310,6 +46314,10 @@ var Template = Struct({
|
|
|
46310
46314
|
createdAt: String4,
|
|
46311
46315
|
updatedAt: String4
|
|
46312
46316
|
}).annotate({ identifier: "Template" });
|
|
46317
|
+
var BrandRenderedFooter = Struct({
|
|
46318
|
+
withUnsubscribe: BrandFooterBlock,
|
|
46319
|
+
withoutUnsubscribe: BrandFooterBlock
|
|
46320
|
+
}).annotate({ identifier: "BrandRenderedFooter" });
|
|
46313
46321
|
var WebhookEndpointListItem = Struct({
|
|
46314
46322
|
id: WebhookEndpointId,
|
|
46315
46323
|
name: String4,
|
|
@@ -46322,9 +46330,13 @@ var WebhookEndpointListItem = Struct({
|
|
|
46322
46330
|
"message.bounced",
|
|
46323
46331
|
"message.complained",
|
|
46324
46332
|
"message.received",
|
|
46333
|
+
"message.opened",
|
|
46334
|
+
"message.clicked",
|
|
46325
46335
|
"contact.created",
|
|
46326
46336
|
"contact.updated",
|
|
46327
46337
|
"contact.deleted",
|
|
46338
|
+
"contact.unsubscribed",
|
|
46339
|
+
"contact.resubscribed",
|
|
46328
46340
|
"conversation.created",
|
|
46329
46341
|
"conversation.updated",
|
|
46330
46342
|
"conversation.archived",
|
|
@@ -47014,6 +47026,8 @@ var EmailContent = Struct({
|
|
|
47014
47026
|
templateId: optionalKey2(Union2([TemplateId, Null2])),
|
|
47015
47027
|
templateSlug: optionalKey2(Union2([String4.check(isPattern2(/* @__PURE__ */ new RegExp("^(?=.{1,100}$)[a-z0-9]+(?:-[a-z0-9]+)*$")).annotate({ expected: "a string matching the RegExp ^(?=.{1,100}$)[a-z0-9]+(?:-[a-z0-9]+)*$" })), Null2])),
|
|
47016
47028
|
templateData: optionalKey2(TemplateData),
|
|
47029
|
+
locale: optionalKey2(RenderLocale),
|
|
47030
|
+
timeZone: optionalKey2(RenderTimeZone),
|
|
47017
47031
|
inReplyToMessageId: optionalKey2(Union2([MessageId, Null2])),
|
|
47018
47032
|
replyTo: optionalKey2(ReplyToAddresses),
|
|
47019
47033
|
unsubscribeGroupId: optionalKey2(Union2([UnsubscribeId, Null2])),
|
|
@@ -47030,6 +47044,8 @@ var EmailDispatchContent = Struct({
|
|
|
47030
47044
|
templateId: optionalKey2(Union2([TemplateId, Null2])),
|
|
47031
47045
|
templateSlug: optionalKey2(Union2([String4.check(isPattern2(/* @__PURE__ */ new RegExp("^(?=.{1,100}$)[a-z0-9]+(?:-[a-z0-9]+)*$")).annotate({ expected: "a string matching the RegExp ^(?=.{1,100}$)[a-z0-9]+(?:-[a-z0-9]+)*$" })), Null2])),
|
|
47032
47046
|
templateData: optionalKey2(TemplateData),
|
|
47047
|
+
locale: optionalKey2(RenderLocale),
|
|
47048
|
+
timeZone: optionalKey2(RenderTimeZone),
|
|
47033
47049
|
inReplyToMessageId: optionalKey2(Union2([MessageId, Null2])),
|
|
47034
47050
|
replyTo: optionalKey2(ReplyToAddresses),
|
|
47035
47051
|
unsubscribeGroupId: optionalKey2(Union2([UnsubscribeId, Null2])),
|
|
@@ -49940,7 +49956,6 @@ var OrganizationsUpdateRequestJson = Struct({
|
|
|
49940
49956
|
isActive: optionalKey2(Union2([Boolean3, Null2])),
|
|
49941
49957
|
metadata: optionalKey2(Union2([Record(String4, JsonValue), Null2])),
|
|
49942
49958
|
replyToDefault: optionalKey2(Union2([Union2([ArraySchema(String4), Null2]), Null2])),
|
|
49943
|
-
defaultUnsubscribeGroupId: optionalKey2(Union2([Union2([UnsubscribeId, Null2]), Null2])),
|
|
49944
49959
|
emailFooterEnabledDefault: optionalKey2(Union2([Union2([Boolean3, Null2]), Null2]))
|
|
49945
49960
|
});
|
|
49946
49961
|
var OrganizationsUpdate200 = Organization;
|
|
@@ -49950,6 +49965,15 @@ var OrganizationsUpdate404 = ResourceNotFoundError;
|
|
|
49950
49965
|
var OrganizationsUpdate422 = ValidationError;
|
|
49951
49966
|
var OrganizationsUpdate500 = InternalError;
|
|
49952
49967
|
var OrganizationsUpdate504 = GatewayTimeoutError;
|
|
49968
|
+
var OrganizationsGetProfile200 = Struct({
|
|
49969
|
+
id: String4.annotate({ description: "Opaque identity for your organization membership" }),
|
|
49970
|
+
name: String4.annotate({ description: "Your display name" }),
|
|
49971
|
+
nickname: String4.annotate({ description: "Your display name and organization name" })
|
|
49972
|
+
});
|
|
49973
|
+
var OrganizationsGetProfile401 = UnauthorizedError;
|
|
49974
|
+
var OrganizationsGetProfile403 = ForbiddenError;
|
|
49975
|
+
var OrganizationsGetProfile500 = InternalError;
|
|
49976
|
+
var OrganizationsGetProfile504 = GatewayTimeoutError;
|
|
49953
49977
|
var OrganizationsDeleteHeaders = Struct({ "idempotency-key": String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxLength(255).annotate({ expected: "a value with a length of at most 255" })) });
|
|
49954
49978
|
var OrganizationsDeleteRequestJson = Struct({ confirmationName: String4 });
|
|
49955
49979
|
var OrganizationsDelete202 = OperationAccepted;
|
|
@@ -50069,7 +50093,7 @@ var TemplatesUpdatePathParams = Struct({ id: TemplateId });
|
|
|
50069
50093
|
var TemplatesUpdateRequestJson = Struct({ data: Struct({
|
|
50070
50094
|
name: optionalKey2(Union2([String4, Null2])),
|
|
50071
50095
|
slug: optionalKey2(Union2([String4.check(isPattern2(/* @__PURE__ */ new RegExp("^(?=.{1,100}$)[a-z0-9]+(?:-[a-z0-9]+)*$")).annotate({ expected: "a string matching the RegExp ^(?=.{1,100}$)[a-z0-9]+(?:-[a-z0-9]+)*$" })), Null2])),
|
|
50072
|
-
entryPath: optionalKey2(Union2([String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$" })), Null2])),
|
|
50096
|
+
entryPath: optionalKey2(Union2([String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })), Null2])),
|
|
50073
50097
|
description: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
|
|
50074
50098
|
category: optionalKey2(Union2([Union2([Literals([
|
|
50075
50099
|
"transactional",
|
|
@@ -50129,7 +50153,7 @@ var TemplatesPublishPathParams = Struct({ id: TemplateId });
|
|
|
50129
50153
|
var TemplatesPublishRequestJson = Struct({
|
|
50130
50154
|
projectId: TemplateProjectId,
|
|
50131
50155
|
commitSha: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{40}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{40}$" })),
|
|
50132
|
-
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$" })),
|
|
50156
|
+
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })),
|
|
50133
50157
|
expectedWorkspaceRevision: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
|
|
50134
50158
|
ifCurrentPublicationId: optionalKey2(Union2([TemplatePublicationId, Null2]))
|
|
50135
50159
|
});
|
|
@@ -50141,30 +50165,20 @@ var TemplatesPublish201 = Struct({
|
|
|
50141
50165
|
inputContractId: TemplateInputContractId,
|
|
50142
50166
|
commitSha: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{40}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{40}$" })),
|
|
50143
50167
|
treeSha: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{40}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{40}$" })),
|
|
50144
|
-
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$" })),
|
|
50168
|
+
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })),
|
|
50145
50169
|
buildIdentity: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" })),
|
|
50146
50170
|
manifest: Struct({
|
|
50147
50171
|
templateKey: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
|
|
50148
|
-
|
|
50149
|
-
|
|
50172
|
+
ir: Struct({
|
|
50173
|
+
version: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(1).annotate({ expected: "a value greater than or equal to 1" })),
|
|
50174
|
+
digest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" })),
|
|
50150
50175
|
bytes: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" }))
|
|
50151
50176
|
}),
|
|
50177
|
+
compiler: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
|
|
50152
50178
|
input: Struct({
|
|
50153
50179
|
schemaDigest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" })),
|
|
50154
50180
|
contractDigest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" }))
|
|
50155
50181
|
}),
|
|
50156
|
-
environment: Struct({
|
|
50157
|
-
locale: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
|
|
50158
|
-
timeZone: Literal2("UTC"),
|
|
50159
|
-
now: optionalKey2(Finite.check(isInt().annotate({ expected: "an integer" }))),
|
|
50160
|
-
randomSeed: optionalKey2(Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })).check(isLessThanOrEqualTo3(4294967295).annotate({ expected: "a value less than or equal to 4294967295" }))),
|
|
50161
|
-
compiler: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
|
|
50162
|
-
runtime: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
|
|
50163
|
-
checker: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
|
|
50164
|
-
lockKind: Literals(["bun", "npm"]),
|
|
50165
|
-
lockDigest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" })),
|
|
50166
|
-
digest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" }))
|
|
50167
|
-
}),
|
|
50168
50182
|
assets: Struct({
|
|
50169
50183
|
base: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^https?:\\/\\/")).annotate({ expected: "a string matching the RegExp ^https?:\\/\\/" })),
|
|
50170
50184
|
entries: ArraySchema(Struct({
|
|
@@ -50179,7 +50193,7 @@ var TemplatesPublish201 = Struct({
|
|
|
50179
50193
|
source: Struct({
|
|
50180
50194
|
commitSha: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{40}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{40}$" })),
|
|
50181
50195
|
treeSha: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{40}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{40}$" })),
|
|
50182
|
-
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$" })),
|
|
50196
|
+
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })),
|
|
50183
50197
|
treeDigest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" }))
|
|
50184
50198
|
}),
|
|
50185
50199
|
brand: optionalKey2(Struct({
|
|
@@ -50187,6 +50201,7 @@ var TemplatesPublish201 = Struct({
|
|
|
50187
50201
|
css: String4,
|
|
50188
50202
|
assets: BrandAssets,
|
|
50189
50203
|
footer: BrandFooter,
|
|
50204
|
+
renderedFooter: BrandRenderedFooter,
|
|
50190
50205
|
digest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" })),
|
|
50191
50206
|
rendersFooter: Literals([
|
|
50192
50207
|
"every",
|
|
@@ -50195,7 +50210,7 @@ var TemplatesPublish201 = Struct({
|
|
|
50195
50210
|
])
|
|
50196
50211
|
}))
|
|
50197
50212
|
}),
|
|
50198
|
-
|
|
50213
|
+
ir: Struct({
|
|
50199
50214
|
key: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
|
|
50200
50215
|
digest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" }))
|
|
50201
50216
|
}),
|
|
@@ -50295,30 +50310,20 @@ var TemplatesGetPublication200 = Struct({
|
|
|
50295
50310
|
inputContractId: TemplateInputContractId,
|
|
50296
50311
|
commitSha: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{40}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{40}$" })),
|
|
50297
50312
|
treeSha: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{40}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{40}$" })),
|
|
50298
|
-
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$" })),
|
|
50313
|
+
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })),
|
|
50299
50314
|
buildIdentity: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" })),
|
|
50300
50315
|
manifest: Struct({
|
|
50301
50316
|
templateKey: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
|
|
50302
|
-
|
|
50303
|
-
|
|
50317
|
+
ir: Struct({
|
|
50318
|
+
version: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(1).annotate({ expected: "a value greater than or equal to 1" })),
|
|
50319
|
+
digest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" })),
|
|
50304
50320
|
bytes: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" }))
|
|
50305
50321
|
}),
|
|
50322
|
+
compiler: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
|
|
50306
50323
|
input: Struct({
|
|
50307
50324
|
schemaDigest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" })),
|
|
50308
50325
|
contractDigest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" }))
|
|
50309
50326
|
}),
|
|
50310
|
-
environment: Struct({
|
|
50311
|
-
locale: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
|
|
50312
|
-
timeZone: Literal2("UTC"),
|
|
50313
|
-
now: optionalKey2(Finite.check(isInt().annotate({ expected: "an integer" }))),
|
|
50314
|
-
randomSeed: optionalKey2(Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })).check(isLessThanOrEqualTo3(4294967295).annotate({ expected: "a value less than or equal to 4294967295" }))),
|
|
50315
|
-
compiler: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
|
|
50316
|
-
runtime: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
|
|
50317
|
-
checker: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
|
|
50318
|
-
lockKind: Literals(["bun", "npm"]),
|
|
50319
|
-
lockDigest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" })),
|
|
50320
|
-
digest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" }))
|
|
50321
|
-
}),
|
|
50322
50327
|
assets: Struct({
|
|
50323
50328
|
base: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^https?:\\/\\/")).annotate({ expected: "a string matching the RegExp ^https?:\\/\\/" })),
|
|
50324
50329
|
entries: ArraySchema(Struct({
|
|
@@ -50333,7 +50338,7 @@ var TemplatesGetPublication200 = Struct({
|
|
|
50333
50338
|
source: Struct({
|
|
50334
50339
|
commitSha: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{40}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{40}$" })),
|
|
50335
50340
|
treeSha: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{40}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{40}$" })),
|
|
50336
|
-
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$" })),
|
|
50341
|
+
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })),
|
|
50337
50342
|
treeDigest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" }))
|
|
50338
50343
|
}),
|
|
50339
50344
|
brand: optionalKey2(Struct({
|
|
@@ -50341,6 +50346,7 @@ var TemplatesGetPublication200 = Struct({
|
|
|
50341
50346
|
css: String4,
|
|
50342
50347
|
assets: BrandAssets,
|
|
50343
50348
|
footer: BrandFooter,
|
|
50349
|
+
renderedFooter: BrandRenderedFooter,
|
|
50344
50350
|
digest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" })),
|
|
50345
50351
|
rendersFooter: Literals([
|
|
50346
50352
|
"every",
|
|
@@ -50349,7 +50355,7 @@ var TemplatesGetPublication200 = Struct({
|
|
|
50349
50355
|
])
|
|
50350
50356
|
}))
|
|
50351
50357
|
}),
|
|
50352
|
-
|
|
50358
|
+
ir: Struct({
|
|
50353
50359
|
key: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })),
|
|
50354
50360
|
digest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" }))
|
|
50355
50361
|
}),
|
|
@@ -50778,7 +50784,7 @@ var TemplatesCheckWorkspaceRequestJson = Struct({ expectedRevision: String4 });
|
|
|
50778
50784
|
var TemplatesCheckWorkspace200 = Struct({
|
|
50779
50785
|
projectId: TemplateProjectId,
|
|
50780
50786
|
revision: String4,
|
|
50781
|
-
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$" })),
|
|
50787
|
+
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })),
|
|
50782
50788
|
declaration: Union2([Struct({
|
|
50783
50789
|
codeDigest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" })),
|
|
50784
50790
|
templateId: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxLength(128).annotate({ expected: "a value with a length of at most 128" })),
|
|
@@ -50787,10 +50793,6 @@ var TemplatesCheckWorkspace200 = Struct({
|
|
|
50787
50793
|
schemaDigest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" })),
|
|
50788
50794
|
contractDigest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" }))
|
|
50789
50795
|
}),
|
|
50790
|
-
runtime: Struct({
|
|
50791
|
-
now: optionalKey2(Finite.check(isInt().annotate({ expected: "an integer" }))),
|
|
50792
|
-
randomSeed: optionalKey2(Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })).check(isLessThanOrEqualTo3(4294967295).annotate({ expected: "a value less than or equal to 4294967295" })))
|
|
50793
|
-
}),
|
|
50794
50796
|
fixtures: ArraySchema(String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxLength(128).annotate({ expected: "a value with a length of at most 128" })))
|
|
50795
50797
|
}), Null2]),
|
|
50796
50798
|
diagnostics: ArraySchema(Struct({
|
|
@@ -51012,7 +51014,7 @@ var TemplatesRenderWorkspaceFixtureRequestJson = Struct({
|
|
|
51012
51014
|
var TemplatesRenderWorkspaceFixture200 = Struct({
|
|
51013
51015
|
projectId: TemplateProjectId,
|
|
51014
51016
|
revision: String4,
|
|
51015
|
-
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$" })),
|
|
51017
|
+
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })),
|
|
51016
51018
|
declaration: Union2([Struct({
|
|
51017
51019
|
codeDigest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" })),
|
|
51018
51020
|
templateId: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxLength(128).annotate({ expected: "a value with a length of at most 128" })),
|
|
@@ -51021,10 +51023,6 @@ var TemplatesRenderWorkspaceFixture200 = Struct({
|
|
|
51021
51023
|
schemaDigest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" })),
|
|
51022
51024
|
contractDigest: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^[a-f0-9]{64}$")).annotate({ expected: "a string matching the RegExp ^[a-f0-9]{64}$" }))
|
|
51023
51025
|
}),
|
|
51024
|
-
runtime: Struct({
|
|
51025
|
-
now: optionalKey2(Finite.check(isInt().annotate({ expected: "an integer" }))),
|
|
51026
|
-
randomSeed: optionalKey2(Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })).check(isLessThanOrEqualTo3(4294967295).annotate({ expected: "a value less than or equal to 4294967295" })))
|
|
51027
|
-
}),
|
|
51028
51026
|
fixtures: ArraySchema(String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxLength(128).annotate({ expected: "a value with a length of at most 128" })))
|
|
51029
51027
|
}), Null2]),
|
|
51030
51028
|
diagnostics: ArraySchema(Struct({
|
|
@@ -51733,7 +51731,7 @@ var TemplatesCreateFamilyFromTemplate500 = InternalError;
|
|
|
51733
51731
|
var TemplatesCreateFamilyFromTemplate504 = GatewayTimeoutError;
|
|
51734
51732
|
var TemplatesAddEntryPathParams = Struct({ projectId: TemplateProjectId });
|
|
51735
51733
|
var TemplatesAddEntryRequestJson = Struct({
|
|
51736
|
-
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))emails\\/.+\\.tsx$" })),
|
|
51734
|
+
entryPath: String4.check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })),
|
|
51737
51735
|
name: String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxLength(200).annotate({ expected: "a value with a length of at most 200" })),
|
|
51738
51736
|
slug: String4.check(isPattern2(/* @__PURE__ */ new RegExp("^(?=.{1,100}$)[a-z0-9]+(?:-[a-z0-9]+)*$")).annotate({ expected: "a string matching the RegExp ^(?=.{1,100}$)[a-z0-9]+(?:-[a-z0-9]+)*$" })),
|
|
51739
51737
|
description: optionalKey2(Union2([Union2([String4, Null2]), Null2])),
|
|
@@ -51765,6 +51763,7 @@ var UnsubscribeList200 = Struct({
|
|
|
51765
51763
|
organizationId: String4,
|
|
51766
51764
|
name: String4,
|
|
51767
51765
|
description: Union2([String4, Null2]),
|
|
51766
|
+
isDefault: Boolean3,
|
|
51768
51767
|
memberCount: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })),
|
|
51769
51768
|
createdAt: String4,
|
|
51770
51769
|
updatedAt: String4
|
|
@@ -51784,6 +51783,7 @@ var UnsubscribeCreate201 = Struct({
|
|
|
51784
51783
|
organizationId: String4,
|
|
51785
51784
|
name: String4,
|
|
51786
51785
|
description: Union2([String4, Null2]),
|
|
51786
|
+
isDefault: Boolean3,
|
|
51787
51787
|
memberCount: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })),
|
|
51788
51788
|
createdAt: String4,
|
|
51789
51789
|
updatedAt: String4
|
|
@@ -51850,6 +51850,7 @@ var UnsubscribeRemove200 = Struct({ success: Boolean3 });
|
|
|
51850
51850
|
var UnsubscribeRemove401 = UnauthorizedError;
|
|
51851
51851
|
var UnsubscribeRemove403 = ForbiddenError;
|
|
51852
51852
|
var UnsubscribeRemove404 = ResourceNotFoundError;
|
|
51853
|
+
var UnsubscribeRemove409 = ConflictError;
|
|
51853
51854
|
var UnsubscribeRemove500 = InternalError;
|
|
51854
51855
|
var UnsubscribeRemove504 = GatewayTimeoutError;
|
|
51855
51856
|
var UnsubscribeUpdatePathParams = Struct({ id: UnsubscribeId });
|
|
@@ -51862,6 +51863,7 @@ var UnsubscribeUpdate200 = Struct({
|
|
|
51862
51863
|
organizationId: String4,
|
|
51863
51864
|
name: String4,
|
|
51864
51865
|
description: Union2([String4, Null2]),
|
|
51866
|
+
isDefault: Boolean3,
|
|
51865
51867
|
memberCount: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })),
|
|
51866
51868
|
createdAt: String4,
|
|
51867
51869
|
updatedAt: String4
|
|
@@ -51871,6 +51873,22 @@ var UnsubscribeUpdate403 = ForbiddenError;
|
|
|
51871
51873
|
var UnsubscribeUpdate404 = ResourceNotFoundError;
|
|
51872
51874
|
var UnsubscribeUpdate500 = InternalError;
|
|
51873
51875
|
var UnsubscribeUpdate504 = GatewayTimeoutError;
|
|
51876
|
+
var UnsubscribeSetDefaultPathParams = Struct({ id: UnsubscribeId });
|
|
51877
|
+
var UnsubscribeSetDefault200 = Struct({
|
|
51878
|
+
id: UnsubscribeId,
|
|
51879
|
+
organizationId: String4,
|
|
51880
|
+
name: String4,
|
|
51881
|
+
description: Union2([String4, Null2]),
|
|
51882
|
+
isDefault: Boolean3,
|
|
51883
|
+
memberCount: Finite.check(isInt().annotate({ expected: "an integer" })).check(isGreaterThanOrEqualTo2(0).annotate({ expected: "a value greater than or equal to 0" })),
|
|
51884
|
+
createdAt: String4,
|
|
51885
|
+
updatedAt: String4
|
|
51886
|
+
});
|
|
51887
|
+
var UnsubscribeSetDefault401 = UnauthorizedError;
|
|
51888
|
+
var UnsubscribeSetDefault403 = ForbiddenError;
|
|
51889
|
+
var UnsubscribeSetDefault404 = ResourceNotFoundError;
|
|
51890
|
+
var UnsubscribeSetDefault500 = InternalError;
|
|
51891
|
+
var UnsubscribeSetDefault504 = GatewayTimeoutError;
|
|
51874
51892
|
var UnsubscribeCheckSubscriptionQuery = Struct({
|
|
51875
51893
|
email: String4,
|
|
51876
51894
|
groupIds: optionalKey2(Union2([String4, Null2]))
|
|
@@ -51913,9 +51931,13 @@ var WebhooksCreateRequestJson = Struct({
|
|
|
51913
51931
|
"message.bounced",
|
|
51914
51932
|
"message.complained",
|
|
51915
51933
|
"message.received",
|
|
51934
|
+
"message.opened",
|
|
51935
|
+
"message.clicked",
|
|
51916
51936
|
"contact.created",
|
|
51917
51937
|
"contact.updated",
|
|
51918
51938
|
"contact.deleted",
|
|
51939
|
+
"contact.unsubscribed",
|
|
51940
|
+
"contact.resubscribed",
|
|
51919
51941
|
"conversation.created",
|
|
51920
51942
|
"conversation.updated",
|
|
51921
51943
|
"conversation.archived",
|
|
@@ -51969,9 +51991,13 @@ var WebhooksUpdateRequestJson = Struct({
|
|
|
51969
51991
|
"message.bounced",
|
|
51970
51992
|
"message.complained",
|
|
51971
51993
|
"message.received",
|
|
51994
|
+
"message.opened",
|
|
51995
|
+
"message.clicked",
|
|
51972
51996
|
"contact.created",
|
|
51973
51997
|
"contact.updated",
|
|
51974
51998
|
"contact.deleted",
|
|
51999
|
+
"contact.unsubscribed",
|
|
52000
|
+
"contact.resubscribed",
|
|
51975
52001
|
"conversation.created",
|
|
51976
52002
|
"conversation.updated",
|
|
51977
52003
|
"conversation.archived",
|
|
@@ -53427,7 +53453,7 @@ var EmailGroup = class extends make36("Email").add(get5("emailListBlocks", "/v1/
|
|
|
53427
53453
|
EmailListSenders500,
|
|
53428
53454
|
EmailListSenders504.pipe(status(504))
|
|
53429
53455
|
]
|
|
53430
|
-
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.listSenders").annotate(Summary, "List
|
|
53456
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.listSenders").annotate(Summary, "List senders").annotate(Description, "Returns a paginated list of senders, optionally filtered by verification status, active state, or default flag. Each row carries `deliverability` (bounce and complaint rates over the last 24 hours) and `series`, the last 14 days of daily email sends from the address, oldest first."), post("emailAddSender", "/v1/email/senders", {
|
|
53431
53457
|
headers: EmailAddSenderHeaders,
|
|
53432
53458
|
payload: EmailAddSenderRequestJson,
|
|
53433
53459
|
success: EmailAddSender201.pipe(status(201)),
|
|
@@ -53441,7 +53467,7 @@ var EmailGroup = class extends make36("Email").add(get5("emailListBlocks", "/v1/
|
|
|
53441
53467
|
EmailAddSender502.pipe(status(502)),
|
|
53442
53468
|
EmailAddSender504.pipe(status(504))
|
|
53443
53469
|
]
|
|
53444
|
-
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.addSender").annotate(Summary, "Add a sender
|
|
53470
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.addSender").annotate(Summary, "Add a sender").annotate(Description, "Creates a sender. The required Idempotency-Key replays the original sender for an identical request and conflicts when reused with different input."), get5("emailGetSender", "/v1/email/senders/:id", {
|
|
53445
53471
|
params: EmailGetSenderPathParams,
|
|
53446
53472
|
success: EmailGetSender200,
|
|
53447
53473
|
error: [
|
|
@@ -53451,7 +53477,7 @@ var EmailGroup = class extends make36("Email").add(get5("emailListBlocks", "/v1/
|
|
|
53451
53477
|
EmailGetSender500,
|
|
53452
53478
|
EmailGetSender504.pipe(status(504))
|
|
53453
53479
|
]
|
|
53454
|
-
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.getSender").annotate(Summary, "Get a sender
|
|
53480
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.getSender").annotate(Summary, "Get a sender").annotate(Description, "Returns one sender owned by the authenticated organization. Other organizations' ids are reported as not found."), del("emailRemoveSender", "/v1/email/senders/:id", {
|
|
53455
53481
|
params: EmailRemoveSenderPathParams,
|
|
53456
53482
|
success: EmailRemoveSender200,
|
|
53457
53483
|
error: [
|
|
@@ -53462,7 +53488,7 @@ var EmailGroup = class extends make36("Email").add(get5("emailListBlocks", "/v1/
|
|
|
53462
53488
|
EmailRemoveSender500,
|
|
53463
53489
|
EmailRemoveSender504.pipe(status(504))
|
|
53464
53490
|
]
|
|
53465
|
-
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.removeSender").annotate(Summary, "Remove a sender
|
|
53491
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.removeSender").annotate(Summary, "Remove a sender").annotate(Description, "Accepts sender removal and marks the sender inactive. A default sender can be removed when no other active sender remains in the organization. It reports the `deleting` lifecycle until removal finishes."), post("emailSetDefaultSender", "/v1/email/senders/:id/default", {
|
|
53466
53492
|
params: EmailSetDefaultSenderPathParams,
|
|
53467
53493
|
success: EmailSetDefaultSender200,
|
|
53468
53494
|
error: [
|
|
@@ -53483,7 +53509,7 @@ var EmailGroup = class extends make36("Email").add(get5("emailListBlocks", "/v1/
|
|
|
53483
53509
|
EmailCheckSenderVerification502.pipe(status(502)),
|
|
53484
53510
|
EmailCheckSenderVerification504.pipe(status(504))
|
|
53485
53511
|
]
|
|
53486
|
-
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.checkSenderVerification").annotate(Summary, "Check sender verification status").annotate(Description, "Returns the current verification status of a sender
|
|
53512
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "email.checkSenderVerification").annotate(Summary, "Check sender verification status").annotate(Description, "Returns the current verification status of a sender."), get5("emailGetStats", "/v1/email/stats", {
|
|
53487
53513
|
query: EmailGetStatsQuery,
|
|
53488
53514
|
success: EmailGetStats200,
|
|
53489
53515
|
error: [
|
|
@@ -53821,7 +53847,15 @@ var OrganizationsGroup = class extends make36("Organizations").add(post("organiz
|
|
|
53821
53847
|
OrganizationsUpdate500,
|
|
53822
53848
|
OrganizationsUpdate504.pipe(status(504))
|
|
53823
53849
|
]
|
|
53824
|
-
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "organizations.update").annotate(Summary, "Update the current organization").annotate(Description, "Updates the current organization's profile, regional defaults, reply-to
|
|
53850
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "organizations.update").annotate(Summary, "Update the current organization").annotate(Description, "Updates the current organization's profile, regional defaults, and reply-to default and returns the saved organization. `metadata` is merged into the stored value; every other field is replaced."), get5("organizationsGetProfile", "/v1/organizations/current/profile", {
|
|
53851
|
+
success: OrganizationsGetProfile200,
|
|
53852
|
+
error: [
|
|
53853
|
+
OrganizationsGetProfile401.pipe(status(401)),
|
|
53854
|
+
OrganizationsGetProfile403.pipe(status(403)),
|
|
53855
|
+
OrganizationsGetProfile500,
|
|
53856
|
+
OrganizationsGetProfile504.pipe(status(504))
|
|
53857
|
+
]
|
|
53858
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "organizations.getProfile").annotate(Summary, "Get the current account profile").annotate(Description, "Returns your identity in the organization authorized by your credential. The ID remains stable across reconnects and display-name changes. Removing and re-adding your membership creates a new ID."), post("organizationsDelete", "/v1/organizations/deletion-operations", {
|
|
53825
53859
|
headers: OrganizationsDeleteHeaders,
|
|
53826
53860
|
payload: OrganizationsDeleteRequestJson,
|
|
53827
53861
|
success: OrganizationsDelete202.pipe(status(202)),
|
|
@@ -53930,7 +53964,7 @@ var TemplatesGroup = class extends make36("Templates").add(get5("templatesList",
|
|
|
53930
53964
|
TemplatesPublish500,
|
|
53931
53965
|
TemplatesPublish504.pipe(status(504))
|
|
53932
53966
|
]
|
|
53933
|
-
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "templates.publish").annotate(Summary, "Publish an exact template commit").annotate(Description, "Builds an exact Git commit and entry path, stores the immutable
|
|
53967
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "templates.publish").annotate(Summary, "Publish an exact template commit").annotate(Description, "Builds an exact Git commit and entry path, stores the immutable compiled IR and its assets, records the input contract it validates against, and makes that publication current."), get5("templatesGetPublication", "/v1/templates/:id/publications/:publicationId", {
|
|
53934
53968
|
params: TemplatesGetPublicationPathParams,
|
|
53935
53969
|
success: TemplatesGetPublication200,
|
|
53936
53970
|
error: [
|
|
@@ -54219,7 +54253,7 @@ var TemplatesGroup = class extends make36("Templates").add(get5("templatesList",
|
|
|
54219
54253
|
TemplatesAddEntry500,
|
|
54220
54254
|
TemplatesAddEntry504.pipe(status(504))
|
|
54221
54255
|
]
|
|
54222
|
-
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "templates.addEntry").annotate(Summary, "Add a template entry").annotate(Description, "Registers
|
|
54256
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "templates.addEntry").annotate(Summary, "Add a template entry").annotate(Description, "Registers a `.tsx` file under `templates/` or `emails/` in an existing template project as its own template and returns it with status 201. The file does not need to exist yet; publishing fails until a commit contains it. Repeating the call with the same entry path, name, and slug returns the existing template.")).annotate(Description, "Git-backed email template projects, workspace editing, immutable publications, and delivery defaults") {
|
|
54223
54257
|
};
|
|
54224
54258
|
var UnsubscribeGroupsGroup = class extends make36("Unsubscribe Groups").add(get5("unsubscribeList", "/v1/unsubscribe-groups", {
|
|
54225
54259
|
query: UnsubscribeListQuery,
|
|
@@ -54230,7 +54264,7 @@ var UnsubscribeGroupsGroup = class extends make36("Unsubscribe Groups").add(get5
|
|
|
54230
54264
|
UnsubscribeList500,
|
|
54231
54265
|
UnsubscribeList504.pipe(status(504))
|
|
54232
54266
|
]
|
|
54233
|
-
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "unsubscribe.list").annotate(Summary, "List unsubscribe groups").annotate(Description, "Returns a paginated list of the organization's unsubscribe groups."), post("unsubscribeCreate", "/v1/unsubscribe-groups", {
|
|
54267
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "unsubscribe.list").annotate(Summary, "List unsubscribe groups").annotate(Description, "Returns a paginated list of the organization's unsubscribe groups, the default group first."), post("unsubscribeCreate", "/v1/unsubscribe-groups", {
|
|
54234
54268
|
payload: UnsubscribeCreateRequestJson,
|
|
54235
54269
|
success: UnsubscribeCreate201.pipe(status(201)),
|
|
54236
54270
|
error: [
|
|
@@ -54279,10 +54313,11 @@ var UnsubscribeGroupsGroup = class extends make36("Unsubscribe Groups").add(get5
|
|
|
54279
54313
|
UnsubscribeRemove401.pipe(status(401)),
|
|
54280
54314
|
UnsubscribeRemove403.pipe(status(403)),
|
|
54281
54315
|
UnsubscribeRemove404.pipe(status(404)),
|
|
54316
|
+
UnsubscribeRemove409.pipe(status(409)),
|
|
54282
54317
|
UnsubscribeRemove500,
|
|
54283
54318
|
UnsubscribeRemove504.pipe(status(504))
|
|
54284
54319
|
]
|
|
54285
|
-
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "unsubscribe.remove").annotate(Summary, "Delete an unsubscribe group").annotate(Description, "Permanently deletes an unsubscribe group by its ID."), patch("unsubscribeUpdate", "/v1/unsubscribe-groups/:id", {
|
|
54320
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "unsubscribe.remove").annotate(Summary, "Delete an unsubscribe group").annotate(Description, "Permanently deletes an unsubscribe group by its ID. The default group cannot be deleted; make another group the default first. A group a scheduled or running campaign uses cannot be deleted until that run finishes or is cancelled."), patch("unsubscribeUpdate", "/v1/unsubscribe-groups/:id", {
|
|
54286
54321
|
params: UnsubscribeUpdatePathParams,
|
|
54287
54322
|
payload: UnsubscribeUpdateRequestJson,
|
|
54288
54323
|
success: UnsubscribeUpdate200,
|
|
@@ -54293,7 +54328,17 @@ var UnsubscribeGroupsGroup = class extends make36("Unsubscribe Groups").add(get5
|
|
|
54293
54328
|
UnsubscribeUpdate500,
|
|
54294
54329
|
UnsubscribeUpdate504.pipe(status(504))
|
|
54295
54330
|
]
|
|
54296
|
-
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "unsubscribe.update").annotate(Summary, "Update an unsubscribe group").annotate(Description, "Updates the name or description of an unsubscribe group."),
|
|
54331
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "unsubscribe.update").annotate(Summary, "Update an unsubscribe group").annotate(Description, "Updates the name or description of an unsubscribe group."), post("unsubscribeSetDefault", "/v1/unsubscribe-groups/:id/default", {
|
|
54332
|
+
params: UnsubscribeSetDefaultPathParams,
|
|
54333
|
+
success: UnsubscribeSetDefault200,
|
|
54334
|
+
error: [
|
|
54335
|
+
UnsubscribeSetDefault401.pipe(status(401)),
|
|
54336
|
+
UnsubscribeSetDefault403.pipe(status(403)),
|
|
54337
|
+
UnsubscribeSetDefault404.pipe(status(404)),
|
|
54338
|
+
UnsubscribeSetDefault500,
|
|
54339
|
+
UnsubscribeSetDefault504.pipe(status(504))
|
|
54340
|
+
]
|
|
54341
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "unsubscribe.setDefault").annotate(Summary, "Make an unsubscribe group the default").annotate(Description, "Makes this group the organization's default: campaigns that name no group, and whose template and sending domain name none, unsubscribe recipients from it."), get5("unsubscribeCheckSubscription", "/v1/unsubscribe-groups/check", {
|
|
54297
54342
|
query: UnsubscribeCheckSubscriptionQuery,
|
|
54298
54343
|
success: UnsubscribeCheckSubscription200,
|
|
54299
54344
|
error: [
|
|
@@ -54418,7 +54463,7 @@ var WebhooksGroup = class extends make36("Webhooks").add(get5("webhooksList", "/
|
|
|
54418
54463
|
]
|
|
54419
54464
|
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "webhooks.getStats").annotate(Summary, "Get webhook delivery statistics").annotate(Description, "Returns aggregate pending, delivered, exhausted, and cancelled delivery counts for a webhook endpoint, plus the same counts per organization-local calendar day over the selected period of 7, 30, or 90 days. Deliveries are retained for 90 days, so 90d is the whole history.")).annotate(Description, "Customer event webhook management, testing, and delivery logs") {
|
|
54420
54465
|
};
|
|
54421
|
-
var SamvaApi = class extends make34("SamvaApi").annotate(Title, "Samva API").annotate(Version2, "1.0.0").annotate(Description, "Samva is
|
|
54466
|
+
var SamvaApi = class extends make34("SamvaApi").annotate(Title, "Samva API").annotate(Version2, "1.0.0").annotate(Description, "Samva is the email API for your app. Send transactional email in one typed call. Delivery events and customer replies come back as signed webhooks, and replies thread to the email they answer.").annotate(Servers, [{ url: "https://api.samva.dev" }]).add(AnalyticsGroup, APIKeysGroup, AttachmentsGroup, BrandsGroup, CampaignsGroup, ContactGroupsGroup, ContactsGroup, ConversationsGroup, CustomFieldsGroup, EmailGroup, MediaGroup, MessagesGroup, ScheduledMessagesGroup, OperationsGroup, OrganizationsGroup, TemplatesGroup, UnsubscribeGroupsGroup, WebhooksGroup) {
|
|
54422
54467
|
};
|
|
54423
54468
|
var DEFAULT_BASE_URL = "https://api.samva.dev";
|
|
54424
54469
|
var Service3 = class extends Service()("samva/Client") {
|
|
@@ -54617,7 +54662,7 @@ var generateIdempotencyKey = gen2(function* () {
|
|
|
54617
54662
|
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
54618
54663
|
});
|
|
54619
54664
|
|
|
54620
|
-
// ../sdk/dist/operation-
|
|
54665
|
+
// ../sdk/dist/operation-D2nEeKBD.js
|
|
54621
54666
|
var SDK_OPERATION_CALLS = {
|
|
54622
54667
|
brandsList: { kind: "none" },
|
|
54623
54668
|
brandsCreate: { kind: "payload" },
|
|
@@ -55122,6 +55167,7 @@ var SDK_OPERATION_CALLS = {
|
|
|
55122
55167
|
},
|
|
55123
55168
|
organizationsCreate: { kind: "payload" },
|
|
55124
55169
|
organizationsGet: { kind: "none" },
|
|
55170
|
+
organizationsGetProfile: { kind: "none" },
|
|
55125
55171
|
organizationsUpdate: { kind: "payload" },
|
|
55126
55172
|
organizationsGetUsage: { kind: "params" },
|
|
55127
55173
|
organizationsDelete: { kind: "idempotentPayload" },
|
|
@@ -55219,6 +55265,10 @@ var SDK_OPERATION_CALLS = {
|
|
|
55219
55265
|
kind: "path",
|
|
55220
55266
|
paths: ["id"]
|
|
55221
55267
|
},
|
|
55268
|
+
unsubscribeSetDefault: {
|
|
55269
|
+
kind: "path",
|
|
55270
|
+
paths: ["id"]
|
|
55271
|
+
},
|
|
55222
55272
|
unsubscribeListMembers: {
|
|
55223
55273
|
kind: "pathParams",
|
|
55224
55274
|
paths: ["groupId"]
|
|
@@ -55581,6 +55631,7 @@ var retry4 = make38("operationsRetry");
|
|
|
55581
55631
|
// ../sdk/dist/effect/organizations.js
|
|
55582
55632
|
var create9 = make38("organizationsCreate");
|
|
55583
55633
|
var get13 = make38("organizationsGet");
|
|
55634
|
+
var getProfile = make38("organizationsGetProfile");
|
|
55584
55635
|
var update9 = make38("organizationsUpdate");
|
|
55585
55636
|
var getUsage = make38("organizationsGetUsage");
|
|
55586
55637
|
var deleteOrganization = make38("organizationsDelete");
|
|
@@ -55632,6 +55683,7 @@ var list13 = make38("unsubscribeList");
|
|
|
55632
55683
|
var create12 = make38("unsubscribeCreate");
|
|
55633
55684
|
var update11 = make38("unsubscribeUpdate");
|
|
55634
55685
|
var remove13 = make38("unsubscribeRemove");
|
|
55686
|
+
var setDefault2 = make38("unsubscribeSetDefault");
|
|
55635
55687
|
var listMembers = make38("unsubscribeListMembers");
|
|
55636
55688
|
var addEmails = make38("unsubscribeAddEmails");
|
|
55637
55689
|
var removeEmails = make38("unsubscribeRemoveEmails");
|
|
@@ -55815,7 +55867,10 @@ var commandTree = {
|
|
|
55815
55867
|
credential: {},
|
|
55816
55868
|
add: {},
|
|
55817
55869
|
move: {},
|
|
55870
|
+
dev: {},
|
|
55818
55871
|
check: {},
|
|
55872
|
+
render: {},
|
|
55873
|
+
snapshot: {},
|
|
55819
55874
|
build: {},
|
|
55820
55875
|
export: {},
|
|
55821
55876
|
types: {},
|
|
@@ -56169,18 +56224,6 @@ var decodeStoredCredentials = (profile, rawCredentials) => try_3({
|
|
|
56169
56224
|
})));
|
|
56170
56225
|
var resolveApiUrl = map7(resolveExecutionSelection, (selection) => selection.apiUrl);
|
|
56171
56226
|
var isCredentialExpired = (credentials, nowMillis) => credentials.expiresAt <= Math.floor(nowMillis / 1000);
|
|
56172
|
-
var resolveAuthToken = gen2(function* () {
|
|
56173
|
-
const context = yield* resolveExecutionContext;
|
|
56174
|
-
if (!context.credentials)
|
|
56175
|
-
return;
|
|
56176
|
-
if (isCredentialExpired(context.credentials, yield* currentTimeMillis2)) {
|
|
56177
|
-
return yield* new CliAuthError({
|
|
56178
|
-
code: "expired_credentials",
|
|
56179
|
-
message: "Your session has expired. Run `samva login` to sign in again."
|
|
56180
|
-
});
|
|
56181
|
-
}
|
|
56182
|
-
return context.credentials.accessToken;
|
|
56183
|
-
});
|
|
56184
56227
|
var writeCredentials = fn2("CliConfig.writeCredentials")(function* (credentials) {
|
|
56185
56228
|
const context = yield* resolveExecutionSelection;
|
|
56186
56229
|
const config = yield* readConfig;
|
|
@@ -56588,7 +56631,7 @@ var templateDataFlag = String8("template-data").pipe(withDescription2("JSON obje
|
|
|
56588
56631
|
var includeTagsFlag = String8("include-tags").pipe(withDescription2("Contact tags to include (comma-separated or repeated)"), atLeast2(0));
|
|
56589
56632
|
var excludeTagsFlag = String8("exclude-tags").pipe(withDescription2("Contact tags to exclude from the include set (comma-separated or repeated)"), atLeast2(0));
|
|
56590
56633
|
var contactIdsFlag = String8("contact-ids").pipe(withDescription2("Explicit contact ids to target (comma-separated or repeated)"), atLeast2(0));
|
|
56591
|
-
var unsubscribeGroupIdFlag = String8("unsubscribe-group-id").pipe(withDescription2("Unsubscribe group id applied to every send"), optional4);
|
|
56634
|
+
var unsubscribeGroupIdFlag = String8("unsubscribe-group-id").pipe(withDescription2("Unsubscribe group id applied to every send; overrides the organization's default group"), optional4);
|
|
56592
56635
|
var pageSizeFlag = Int5("page-size").pipe(withDescription2("Recipients dispatched per batch"), optional4);
|
|
56593
56636
|
var dryRunFlag = Boolean6("dry-run").pipe(withDescription2("Validate inputs and print the request payload without calling the API"), withDefault4(false));
|
|
56594
56637
|
var trackOpensFlag = Literals3("track-opens", ["on", "off"]).pipe(withDescription2("Override open tracking for campaign sends; recipient opt-out wins"), optional4);
|
|
@@ -57263,14 +57306,26 @@ var check = (name, run) => run.pipe(match6({
|
|
|
57263
57306
|
}));
|
|
57264
57307
|
var reachability = (apiUrl) => check("API reachability", getText(`${apiUrl.replace(/\/+$/, "")}/v1/health/ping`).pipe(flatMap3((response) => response.ok ? succeed6("Health endpoint responded") : fail6(new SamvaCliError({ message: `Health endpoint returned ${response.status}` })))));
|
|
57265
57308
|
var orgAccess = check("Organization permissions", getClientProvider.pipe(flatMap3((client) => get13().pipe(client.provide, map7((organization) => `${organization.name} (${organization.slug})`), mapError2((error) => new SamvaCliError({ message: formatApiError("Organization read failed", error) }))))));
|
|
57266
|
-
var
|
|
57267
|
-
|
|
57268
|
-
|
|
57269
|
-
}
|
|
57270
|
-
|
|
57271
|
-
|
|
57272
|
-
|
|
57273
|
-
|
|
57309
|
+
var sendReview = getClientProvider.pipe(flatMap3((client) => getOnboardingReview().pipe(client.provide, map7((review) => ({
|
|
57310
|
+
name: "Send review",
|
|
57311
|
+
status: review.canSend ? "passed" : review.code === "review_rejected" || review.code === "identity_review_rejected" ? "failed" : "unavailable",
|
|
57312
|
+
detail: review.canSend ? `${review.decision}; trust tier ${review.trustTier}` : `${review.code}; next action: ${review.nextAction}`
|
|
57313
|
+
})))), catch_2((error) => succeed6({
|
|
57314
|
+
name: "Send review",
|
|
57315
|
+
status: "failed",
|
|
57316
|
+
detail: formatApiError("Send review read failed", error)
|
|
57317
|
+
})));
|
|
57318
|
+
var identityCount = (name, noun, read) => getClientProvider.pipe(flatMap3((client) => client.provide(read)), map7(({ pagination }) => ({
|
|
57319
|
+
name,
|
|
57320
|
+
status: pagination.total > 0 ? "passed" : "unavailable",
|
|
57321
|
+
detail: `${pagination.total} ${noun}`
|
|
57322
|
+
})), catch_2((error) => succeed6({
|
|
57323
|
+
name,
|
|
57324
|
+
status: "failed",
|
|
57325
|
+
detail: formatApiError(`${name} read failed`, error)
|
|
57326
|
+
})));
|
|
57327
|
+
var domains = identityCount("Sending domains", "sendable", listDomains({ sendable: "true", limit: "1" }));
|
|
57328
|
+
var senders = identityCount("Senders", "verified and active", listSenders({ verificationStatus: "verified", isActive: "true", limit: "1" }));
|
|
57274
57329
|
var domainVerificationReadback = getClientProvider.pipe(flatMap3((client) => listDomains({ limit: "1" }).pipe(client.provide, mapError2((error) => new SamvaCliError({ message: formatApiError("Domain verification read failed", error) })), flatMap3((result) => {
|
|
57275
57330
|
const domain = result.items[0];
|
|
57276
57331
|
if (!domain) {
|
|
@@ -57298,19 +57353,29 @@ var domainVerificationReadback = getClientProvider.pipe(flatMap3((client) => lis
|
|
|
57298
57353
|
var doctorCommand = make28("doctor", { json: jsonFlag }).pipe(withDescription3("Read local configuration and remote email state"), withExamples([{ command: "samva email doctor --json" }]), withHandler(({ json }) => gen2(function* () {
|
|
57299
57354
|
const context = yield* resolveExecutionContext;
|
|
57300
57355
|
const authSource = context.apiKey ? "SAMVA_API_KEY" : context.credentials ? "stored OAuth credential" : "none";
|
|
57301
|
-
const
|
|
57356
|
+
const [reachable, org, review, domainCount, senderCount, verification] = yield* all2([
|
|
57302
57357
|
reachability(context.apiUrl),
|
|
57303
57358
|
orgAccess,
|
|
57359
|
+
sendReview,
|
|
57304
57360
|
domains,
|
|
57305
57361
|
senders,
|
|
57306
57362
|
domainVerificationReadback
|
|
57307
|
-
]);
|
|
57363
|
+
], { concurrency: "unbounded" });
|
|
57364
|
+
const checks = [
|
|
57365
|
+
reachable,
|
|
57366
|
+
org,
|
|
57367
|
+
review,
|
|
57368
|
+
domainCount,
|
|
57369
|
+
senderCount,
|
|
57370
|
+
verification
|
|
57371
|
+
];
|
|
57308
57372
|
const ok = checks.every((result) => result.status !== "failed");
|
|
57309
57373
|
const payload = {
|
|
57310
57374
|
schemaVersion: 1,
|
|
57311
57375
|
mode: "read-only",
|
|
57312
57376
|
ok,
|
|
57313
|
-
|
|
57377
|
+
readyToSend: review.status === "passed" && (domainCount.status === "passed" || senderCount.status === "passed"),
|
|
57378
|
+
limitations: "Reads the send fence and identity lists only. It does not send, mutate, replay fixtures, or check DNS itself.",
|
|
57314
57379
|
resolved: {
|
|
57315
57380
|
profile: context.profile,
|
|
57316
57381
|
apiUrl: context.apiUrl,
|
|
@@ -57327,7 +57392,8 @@ var doctorCommand = make28("doctor", { json: jsonFlag }).pipe(withDescription3("
|
|
|
57327
57392
|
["Profile", payload.resolved.profile],
|
|
57328
57393
|
["API", payload.resolved.apiUrl],
|
|
57329
57394
|
["Auth source", payload.resolved.authSource],
|
|
57330
|
-
["Organization", payload.resolved.organization]
|
|
57395
|
+
["Organization", payload.resolved.organization],
|
|
57396
|
+
["Ready to send", payload.readyToSend ? "yes" : "no"]
|
|
57331
57397
|
]);
|
|
57332
57398
|
yield* log(`
|
|
57333
57399
|
Read-only checks:`);
|
|
@@ -57727,7 +57793,7 @@ var readStatus = gen2(function* () {
|
|
|
57727
57793
|
message: formatApiError("Could not get email review status", error)
|
|
57728
57794
|
})));
|
|
57729
57795
|
});
|
|
57730
|
-
var status3 = make28("status", { json: jsonFlag }).pipe(withDescription3("Get
|
|
57796
|
+
var status3 = make28("status", { json: jsonFlag }).pipe(withDescription3("Get organization and sending-identity review status"), withExamples([{ command: "samva email review status --json" }]), withHandler(({ json }) => gen2(function* () {
|
|
57731
57797
|
const data = yield* readStatus;
|
|
57732
57798
|
if (json)
|
|
57733
57799
|
return yield* printJson(data);
|
|
@@ -57747,7 +57813,7 @@ Sending identities:`);
|
|
|
57747
57813
|
}
|
|
57748
57814
|
}
|
|
57749
57815
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
57750
|
-
var reapply = make28("reapply", { json: jsonFlag }).pipe(withDescription3("Resubmit a rejected
|
|
57816
|
+
var reapply = make28("reapply", { json: jsonFlag }).pipe(withDescription3("Resubmit a rejected organization for email review"), withExamples([{ command: "samva email review reapply --json" }]), withHandler(({ json }) => gen2(function* () {
|
|
57751
57817
|
const client = yield* getClientProvider;
|
|
57752
57818
|
const current = yield* readStatus;
|
|
57753
57819
|
const data = yield* reapplyOnboardingReview({
|
|
@@ -57788,6 +57854,7 @@ var projectMessage = (message) => ({
|
|
|
57788
57854
|
id: message.id,
|
|
57789
57855
|
channel: message.channel,
|
|
57790
57856
|
status: message.status,
|
|
57857
|
+
from: message.emailDeliveryDetails[0]?.fromEmail ?? null,
|
|
57791
57858
|
conversationId: message.conversationId,
|
|
57792
57859
|
createdAt: message.createdAt,
|
|
57793
57860
|
updatedAt: message.updatedAt,
|
|
@@ -57808,6 +57875,7 @@ var printMessage = (message) => printFields([
|
|
|
57808
57875
|
["Message ID", message.id],
|
|
57809
57876
|
["Channel", message.channel],
|
|
57810
57877
|
["Status", message.status],
|
|
57878
|
+
["From", message.from],
|
|
57811
57879
|
["Waiting", waitingLine(message)],
|
|
57812
57880
|
["Conversation", message.conversationId],
|
|
57813
57881
|
["Created", message.createdAt],
|
|
@@ -58040,6 +58108,8 @@ var textFlag2 = String8("text").pipe(withDescription2("Plain-text body (use `-`
|
|
|
58040
58108
|
var templateIdFlag2 = String8("template-id").pipe(withDescription2("Template id to render instead of inline body"), optional4);
|
|
58041
58109
|
var templateSlugFlag2 = String8("template-slug").pipe(withDescription2("Template handle to render instead of inline body, e.g. welcome-email"), optional4);
|
|
58042
58110
|
var templateDataFlag2 = String8("template-data").pipe(withDescription2("JSON object of variables for the template"), optional4);
|
|
58111
|
+
var localeFlag = String8("locale").pipe(withDescription2("BCP 47 language tag (for example en-US) for dates, numbers and money in a template send; defaults to the template's locale"), optional4);
|
|
58112
|
+
var timeZoneFlag = String8("time-zone").pipe(withDescription2("IANA time zone (for example America/New_York) that a template send renders dates in; defaults to UTC"), optional4);
|
|
58043
58113
|
var replyToMessageFlag = String8("reply-to-message-id").pipe(withDescription2("Message id this email replies to (threads the conversation)"), optional4);
|
|
58044
58114
|
var replyToAddressFlag = String8("reply-to").pipe(withDescription2("Reply-To header email address"), optional4);
|
|
58045
58115
|
var idempotencyKeyFlag2 = String8("idempotency-key").pipe(withDescription2("Key (1-255 characters) so identical retries return the original email"), optional4);
|
|
@@ -58074,6 +58144,8 @@ var send2 = make28("send", {
|
|
|
58074
58144
|
inputContractId: inputContractIdFlag,
|
|
58075
58145
|
templateSlug: templateSlugFlag2,
|
|
58076
58146
|
templateData: templateDataFlag2,
|
|
58147
|
+
locale: localeFlag,
|
|
58148
|
+
timeZone: timeZoneFlag,
|
|
58077
58149
|
replyTo: replyToMessageFlag,
|
|
58078
58150
|
replyToAddress: replyToAddressFlag,
|
|
58079
58151
|
idempotencyKey: idempotencyKeyFlag2,
|
|
@@ -58092,6 +58164,10 @@ var send2 = make28("send", {
|
|
|
58092
58164
|
command: `samva email send --to you@example.com --template-slug welcome-email --template-data '{"name":"Ada"}'`,
|
|
58093
58165
|
description: "Render a template by handle"
|
|
58094
58166
|
},
|
|
58167
|
+
{
|
|
58168
|
+
command: `samva email send --to you@example.com --template-slug order-receipt --template-data '{"total":42}' --locale de-DE --time-zone Europe/Berlin`,
|
|
58169
|
+
description: "Render a template's dates and money for a locale and time zone"
|
|
58170
|
+
},
|
|
58095
58171
|
{
|
|
58096
58172
|
command: 'echo "Hello" | samva email send --to you@example.com --subject Hi --text -',
|
|
58097
58173
|
description: "Pipe plain-text body from stdin"
|
|
@@ -58116,6 +58192,8 @@ var send2 = make28("send", {
|
|
|
58116
58192
|
inputContractId,
|
|
58117
58193
|
templateSlug,
|
|
58118
58194
|
templateData,
|
|
58195
|
+
locale,
|
|
58196
|
+
timeZone,
|
|
58119
58197
|
replyTo,
|
|
58120
58198
|
replyToAddress,
|
|
58121
58199
|
idempotencyKey,
|
|
@@ -58144,6 +58222,8 @@ var send2 = make28("send", {
|
|
|
58144
58222
|
const ccValue = getOrUndefined(cc);
|
|
58145
58223
|
const bccValue = getOrUndefined(bcc);
|
|
58146
58224
|
const templateDataValue = yield* parseTemplateData2(templateData);
|
|
58225
|
+
const localeValue = getOrUndefined(locale);
|
|
58226
|
+
const timeZoneValue = getOrUndefined(timeZone);
|
|
58147
58227
|
if (idempotencyKeyValue !== undefined && (idempotencyKeyValue.length < 1 || idempotencyKeyValue.length > 255)) {
|
|
58148
58228
|
return yield* new SamvaCliError({
|
|
58149
58229
|
message: "--idempotency-key must contain between 1 and 255 characters."
|
|
@@ -58155,6 +58235,11 @@ var send2 = make28("send", {
|
|
|
58155
58235
|
});
|
|
58156
58236
|
}
|
|
58157
58237
|
const templateRefValue = templateSlugValue ?? templateIdValue;
|
|
58238
|
+
if ((localeValue !== undefined || timeZoneValue !== undefined) && !templateIdValue && !templateSlugValue) {
|
|
58239
|
+
return yield* new SamvaCliError({
|
|
58240
|
+
message: "--locale and --time-zone apply to template sends."
|
|
58241
|
+
});
|
|
58242
|
+
}
|
|
58158
58243
|
if (templateRefValue && subjectValue) {
|
|
58159
58244
|
return yield* new SamvaCliError({
|
|
58160
58245
|
message: "Template sends derive their subject from the template. Omit --subject."
|
|
@@ -58196,6 +58281,8 @@ var send2 = make28("send", {
|
|
|
58196
58281
|
...reference,
|
|
58197
58282
|
...templateSlugValue === undefined ? {} : { templateSlug: templateSlugValue },
|
|
58198
58283
|
...templateDataValue === undefined ? {} : { templateData: templateDataValue },
|
|
58284
|
+
...localeValue === undefined ? {} : { locale: localeValue },
|
|
58285
|
+
...timeZoneValue === undefined ? {} : { timeZone: timeZoneValue },
|
|
58199
58286
|
...replyToValue === undefined ? {} : { inReplyToMessageId: replyToValue },
|
|
58200
58287
|
...replyToAddressValue === undefined ? {} : { replyTo: replyToAddressValue },
|
|
58201
58288
|
...trackOpensValue !== undefined || trackClicksValue !== undefined ? {
|
|
@@ -58453,7 +58540,7 @@ var remove16 = make28("remove", {
|
|
|
58453
58540
|
dryRun: Boolean6("dry-run").pipe(withDescription2("Print the deletion plan without calling the API"), withDefault4(false)),
|
|
58454
58541
|
yes: Boolean6("yes").pipe(withDescription2("Confirm permanent deletion (required for non-interactive use)"), withDefault4(false)),
|
|
58455
58542
|
json: jsonFlag
|
|
58456
|
-
}).pipe(withDescription3("Permanently remove a sender
|
|
58543
|
+
}).pipe(withDescription3("Permanently remove a sender"), withExamples([
|
|
58457
58544
|
{ command: "samva email senders remove sender_abc123 --dry-run" },
|
|
58458
58545
|
{ command: "samva email senders remove sender_abc123 --yes" }
|
|
58459
58546
|
]), withHandler(({ id, dryRun, yes, json }) => gen2(function* () {
|
|
@@ -58613,13 +58700,13 @@ var emailCommand = make28("email").pipe(withDescription3("Send, inspect, and con
|
|
|
58613
58700
|
trackingCommand
|
|
58614
58701
|
]));
|
|
58615
58702
|
|
|
58616
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
58703
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/package.mjs
|
|
58617
58704
|
var version2 = "1.7.5";
|
|
58618
58705
|
|
|
58619
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
58706
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/version.mjs
|
|
58620
58707
|
var PACKAGE_VERSION = version2;
|
|
58621
58708
|
|
|
58622
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
58709
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/client/broadcast-channel.mjs
|
|
58623
58710
|
var kBroadcastChannel = Symbol.for("better-auth:broadcast-channel");
|
|
58624
58711
|
var now = () => Math.floor(Date.now() / 1000);
|
|
58625
58712
|
var WindowBroadcastChannel = class {
|
|
@@ -58865,7 +58952,7 @@ var onMount = ($store, initialize) => {
|
|
|
58865
58952
|
};
|
|
58866
58953
|
});
|
|
58867
58954
|
};
|
|
58868
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
58955
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/client/equality.mjs
|
|
58869
58956
|
function isPlainObject(value) {
|
|
58870
58957
|
if (typeof value !== "object" || value === null)
|
|
58871
58958
|
return false;
|
|
@@ -58902,7 +58989,7 @@ function withEquality(store, isEqual) {
|
|
|
58902
58989
|
});
|
|
58903
58990
|
}
|
|
58904
58991
|
|
|
58905
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
58992
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/client/focus-manager.mjs
|
|
58906
58993
|
var kFocusManager = Symbol.for("better-auth:focus-manager");
|
|
58907
58994
|
var WindowFocusManager = class {
|
|
58908
58995
|
listeners = /* @__PURE__ */ new Set;
|
|
@@ -58934,7 +59021,7 @@ function getGlobalFocusManager() {
|
|
|
58934
59021
|
return globalThis[kFocusManager];
|
|
58935
59022
|
}
|
|
58936
59023
|
|
|
58937
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
59024
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/client/online-manager.mjs
|
|
58938
59025
|
var kOnlineManager = Symbol.for("better-auth:online-manager");
|
|
58939
59026
|
var WindowOnlineManager = class {
|
|
58940
59027
|
listeners = /* @__PURE__ */ new Set;
|
|
@@ -58968,7 +59055,7 @@ function getGlobalOnlineManager() {
|
|
|
58968
59055
|
return globalThis[kOnlineManager];
|
|
58969
59056
|
}
|
|
58970
59057
|
|
|
58971
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
59058
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/client/parser.mjs
|
|
58972
59059
|
var PROTO_POLLUTION_PATTERNS = {
|
|
58973
59060
|
proto: /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,
|
|
58974
59061
|
constructor: /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,
|
|
@@ -59046,7 +59133,7 @@ function parseJSON(value, options = { strict: true }) {
|
|
|
59046
59133
|
return betterJSONParse(value, options);
|
|
59047
59134
|
}
|
|
59048
59135
|
|
|
59049
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
59136
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/client/query.mjs
|
|
59050
59137
|
var isServer = () => typeof window === "undefined";
|
|
59051
59138
|
function isAuthQueryStateEqual(a, b) {
|
|
59052
59139
|
return isJsonEqual(a.data, b.data) && a.error === b.error && a.isPending === b.isPending && a.isRefetching === b.isRefetching && a.refetch === b.refetch;
|
|
@@ -59172,7 +59259,7 @@ var useAuthQuery = (initializedAtom, path, $fetch, options) => {
|
|
|
59172
59259
|
return value;
|
|
59173
59260
|
};
|
|
59174
59261
|
|
|
59175
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
59262
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/client/session-refresh.mjs
|
|
59176
59263
|
var now2 = () => Math.floor(Date.now() / 1000);
|
|
59177
59264
|
var FOCUS_REFETCH_RATE_LIMIT_SECONDS = 5;
|
|
59178
59265
|
function createSessionRefreshManager(opts) {
|
|
@@ -59501,7 +59588,7 @@ var BetterAuthError = class extends Error {
|
|
|
59501
59588
|
}
|
|
59502
59589
|
};
|
|
59503
59590
|
|
|
59504
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
59591
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/utils/url.mjs
|
|
59505
59592
|
var SLASH_CHAR_CODE = 47;
|
|
59506
59593
|
function trimTrailingSlashes(value) {
|
|
59507
59594
|
let end = value.length;
|
|
@@ -59608,7 +59695,7 @@ function isSafeUrlScheme(value) {
|
|
|
59608
59695
|
return !DANGEROUS_URL_SCHEMES.includes(parsed.protocol);
|
|
59609
59696
|
}
|
|
59610
59697
|
|
|
59611
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
59698
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/client/fetch-plugins.mjs
|
|
59612
59699
|
var redirectPlugin = {
|
|
59613
59700
|
id: "redirect",
|
|
59614
59701
|
name: "Redirect",
|
|
@@ -59624,7 +59711,7 @@ var redirectPlugin = {
|
|
|
59624
59711
|
} }
|
|
59625
59712
|
};
|
|
59626
59713
|
|
|
59627
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
59714
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/client/session-atom.mjs
|
|
59628
59715
|
var isServer2 = () => typeof window === "undefined";
|
|
59629
59716
|
var SESSION_MOUNT_DEDUPE_INTERVAL = STORE_UNMOUNT_DELAY;
|
|
59630
59717
|
function hydrateSessionAtom(sessionAtom, session) {
|
|
@@ -60488,7 +60575,7 @@ var createFetch = (config) => {
|
|
|
60488
60575
|
return $fetch;
|
|
60489
60576
|
};
|
|
60490
60577
|
|
|
60491
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
60578
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/client/config.mjs
|
|
60492
60579
|
var resolvePublicAuthUrl = (basePath) => {
|
|
60493
60580
|
if (typeof process === "undefined")
|
|
60494
60581
|
return;
|
|
@@ -60607,7 +60694,7 @@ var getClientConfig = (options, loadEnv) => {
|
|
|
60607
60694
|
};
|
|
60608
60695
|
};
|
|
60609
60696
|
|
|
60610
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
60697
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/utils/is-atom.mjs
|
|
60611
60698
|
function isAtom(value) {
|
|
60612
60699
|
return typeof value === "object" && value !== null && "get" in value && typeof value.get === "function" && "lc" in value && typeof value.lc === "number";
|
|
60613
60700
|
}
|
|
@@ -60625,7 +60712,7 @@ function toKebabCase(input) {
|
|
|
60625
60712
|
return splitWords(input).map((word) => word.toLowerCase()).join("-");
|
|
60626
60713
|
}
|
|
60627
60714
|
|
|
60628
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
60715
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/client/proxy.mjs
|
|
60629
60716
|
function getMethod2(path, knownPathMethods, args) {
|
|
60630
60717
|
const method = knownPathMethods[path];
|
|
60631
60718
|
const { fetchOptions, query: _query, ...body } = args || {};
|
|
@@ -60707,7 +60794,7 @@ function createDynamicPathProxy(routes, client, knownPathMethods, atoms, atomLis
|
|
|
60707
60794
|
return createProxy();
|
|
60708
60795
|
}
|
|
60709
60796
|
|
|
60710
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
60797
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/client/vanilla.mjs
|
|
60711
60798
|
function createAuthClient(options) {
|
|
60712
60799
|
const { pluginPathMethods, pluginsActions, pluginsAtoms, hydrateSession, $fetch, atomListeners, $store } = getClientConfig(options);
|
|
60713
60800
|
const resolvedHooks = {};
|
|
@@ -60721,7 +60808,7 @@ function createAuthClient(options) {
|
|
|
60721
60808
|
$store
|
|
60722
60809
|
}, $fetch, pluginPathMethods, pluginsAtoms, atomListeners);
|
|
60723
60810
|
}
|
|
60724
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
60811
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/plugins/device-authorization/client.mjs
|
|
60725
60812
|
var deviceAuthorizationClient = () => {
|
|
60726
60813
|
return {
|
|
60727
60814
|
id: "device-authorization",
|
|
@@ -60736,7 +60823,7 @@ var deviceAuthorizationClient = () => {
|
|
|
60736
60823
|
}
|
|
60737
60824
|
};
|
|
60738
60825
|
};
|
|
60739
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
60826
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/plugins/access/access.mjs
|
|
60740
60827
|
function unknownResourceResponse(requestedResource) {
|
|
60741
60828
|
return {
|
|
60742
60829
|
success: false,
|
|
@@ -60822,7 +60909,7 @@ function createAccessControl(s) {
|
|
|
60822
60909
|
};
|
|
60823
60910
|
}
|
|
60824
60911
|
|
|
60825
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
60912
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/plugins/organization/access/statement.mjs
|
|
60826
60913
|
var defaultStatements = {
|
|
60827
60914
|
organization: ["update", "delete"],
|
|
60828
60915
|
member: [
|
|
@@ -60897,7 +60984,7 @@ var defaultRoles = {
|
|
|
60897
60984
|
member: memberAc
|
|
60898
60985
|
};
|
|
60899
60986
|
|
|
60900
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
60987
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/plugins/organization/error-codes.mjs
|
|
60901
60988
|
var ORGANIZATION_ERROR_CODES = defineErrorCodes({
|
|
60902
60989
|
YOU_ARE_NOT_ALLOWED_TO_CREATE_A_NEW_ORGANIZATION: "You are not allowed to create a new organization",
|
|
60903
60990
|
YOU_HAVE_REACHED_THE_MAXIMUM_NUMBER_OF_ORGANIZATIONS: "You have reached the maximum number of organizations",
|
|
@@ -60960,7 +61047,7 @@ var ORGANIZATION_ERROR_CODES = defineErrorCodes({
|
|
|
60960
61047
|
INVALID_TEAM_ID: "Team id contains a reserved character"
|
|
60961
61048
|
});
|
|
60962
61049
|
|
|
60963
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
61050
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/plugins/organization/permission.mjs
|
|
60964
61051
|
var hasPermissionFn = (input, acRoles) => {
|
|
60965
61052
|
if (!input.permissions)
|
|
60966
61053
|
return false;
|
|
@@ -60976,7 +61063,7 @@ var hasPermissionFn = (input, acRoles) => {
|
|
|
60976
61063
|
return false;
|
|
60977
61064
|
};
|
|
60978
61065
|
|
|
60979
|
-
// ../../node_modules/.bun/better-auth@1.7.5+
|
|
61066
|
+
// ../../node_modules/.bun/better-auth@1.7.5+d84e686d419eddf2/node_modules/better-auth/dist/plugins/organization/client.mjs
|
|
60980
61067
|
var clientSideHasPermission = (input) => {
|
|
60981
61068
|
return hasPermissionFn(input, input.options.roles || defaultRoles);
|
|
60982
61069
|
};
|
|
@@ -61865,26 +61952,37 @@ var scheduledMessagesCommand = make28("scheduled-messages").pipe(withDescription
|
|
|
61865
61952
|
|
|
61866
61953
|
// src/commands/templates.ts
|
|
61867
61954
|
import { constants as constants2 } from "fs";
|
|
61868
|
-
import { access as access3, stat as
|
|
61869
|
-
import { dirname as
|
|
61870
|
-
import { pathToFileURL as
|
|
61955
|
+
import { access as access3, stat as stat4 } from "fs/promises";
|
|
61956
|
+
import { dirname as dirname4, resolve as resolve14 } from "path";
|
|
61957
|
+
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
61871
61958
|
|
|
61872
|
-
// src/commands/templates/
|
|
61959
|
+
// src/commands/templates/dev-command.ts
|
|
61873
61960
|
import { resolve as resolve6 } from "path";
|
|
61874
|
-
|
|
61961
|
+
|
|
61962
|
+
// src/commands/templates/flags.ts
|
|
61963
|
+
var dirFlag = Directory2("dir").pipe(withDescription2("Directory containing your .tsx templates (default: templates/ and emails/, whichever exist)"), optional4);
|
|
61964
|
+
var assetBaseFlag = String8("asset-base").pipe(withDescription2("Actual HTTPS serving base for imported email assets"), optional4);
|
|
61965
|
+
var offlineFlag = Boolean6("offline").pipe(withDescription2("Use the cached brand in .samva/brands instead of fetching it"), withDefault4(false));
|
|
61966
|
+
|
|
61967
|
+
// src/commands/templates/toolchain.ts
|
|
61968
|
+
var TOOLCHAIN_INSTALL = "npm install --save-dev @samva/markup @samva/vite vite";
|
|
61969
|
+
var MISSING_MODULE = /Cannot find (?:package|module) '([^']+)'/;
|
|
61970
|
+
var toolchainFailure = (stderr, action) => {
|
|
61971
|
+
const missing = MISSING_MODULE.exec(stderr)?.[1];
|
|
61972
|
+
if (stderr.includes("`vite` is required")) {
|
|
61973
|
+
return `${action}: vite is not installed in this project. Install the authoring toolchain with \`${TOOLCHAIN_INSTALL}\`.`;
|
|
61974
|
+
}
|
|
61975
|
+
if (missing !== undefined && /^(@samva\/|vite)/.test(missing)) {
|
|
61976
|
+
return `${action}: ${missing} is not installed in this project. Install the authoring toolchain with \`${TOOLCHAIN_INSTALL}\`.`;
|
|
61977
|
+
}
|
|
61978
|
+
return `${action}: ${stderr.trim() || "the toolchain process failed."}`;
|
|
61979
|
+
};
|
|
61980
|
+
var NODE_MISSING = "Install Node.js 22+ to run template authoring commands.";
|
|
61981
|
+
var runToolchain = (input) => tryPromise2({
|
|
61875
61982
|
try: async () => {
|
|
61876
|
-
const child = Bun.spawn([
|
|
61877
|
-
"node",
|
|
61878
|
-
"--input-type=module",
|
|
61879
|
-
"--eval",
|
|
61880
|
-
'import { buildTemplates } from "@samva/vite/build"; const dir = process.env.SAMVA_TEMPLATE_BUILD_DIR; if (dir === undefined) throw new Error("SAMVA_TEMPLATE_BUILD_DIR is required"); const result = await buildTemplates(dir, { root: process.cwd(), assetBase: process.env.SAMVA_TEMPLATE_ASSET_BASE }); process.stdout.write(JSON.stringify(result));'
|
|
61881
|
-
], {
|
|
61983
|
+
const child = Bun.spawn(["node", "--input-type=module", "--eval", input.script], {
|
|
61882
61984
|
cwd: process.cwd(),
|
|
61883
|
-
env: {
|
|
61884
|
-
...Bun.env,
|
|
61885
|
-
SAMVA_TEMPLATE_BUILD_DIR: resolve6(dir),
|
|
61886
|
-
SAMVA_TEMPLATE_ASSET_BASE: assetBase
|
|
61887
|
-
},
|
|
61985
|
+
env: { ...Bun.env, SAMVA_TOOLCHAIN_INPUT: JSON.stringify(input.options) },
|
|
61888
61986
|
stdout: "pipe",
|
|
61889
61987
|
stderr: "pipe"
|
|
61890
61988
|
});
|
|
@@ -61894,17 +61992,122 @@ var buildDir = (dir, assetBase) => tryPromise2({
|
|
|
61894
61992
|
child.exited
|
|
61895
61993
|
]);
|
|
61896
61994
|
if (exitCode !== 0) {
|
|
61897
|
-
return Promise.reject(new SamvaCliError({ message: stderr.
|
|
61995
|
+
return Promise.reject(new SamvaCliError({ message: toolchainFailure(stderr, input.action) }));
|
|
61898
61996
|
}
|
|
61899
61997
|
return JSON.parse(stdout);
|
|
61900
61998
|
},
|
|
61901
|
-
catch: (cause) => new SamvaCliError({
|
|
61902
|
-
message:
|
|
61999
|
+
catch: (cause) => cause instanceof SamvaCliError ? cause : new SamvaCliError({
|
|
62000
|
+
message: `${input.action}: ${NODE_MISSING} ${String(cause)}`
|
|
62001
|
+
})
|
|
62002
|
+
});
|
|
62003
|
+
var OPTIONS_PRELUDE = "const options = JSON.parse(process.env.SAMVA_TOOLCHAIN_INPUT);";
|
|
62004
|
+
|
|
62005
|
+
// src/commands/templates/dev-command.ts
|
|
62006
|
+
var DEV_SCRIPT = `import { startDevServer } from "@samva/vite/dev";
|
|
62007
|
+
${OPTIONS_PRELUDE}
|
|
62008
|
+
const server = await startDevServer(options);
|
|
62009
|
+
process.stdout.write("Samva template editor: " + server.url + "\\nPress Ctrl+C to stop.\\n");
|
|
62010
|
+
const stop = () => { server.close().finally(() => process.exit(0)); };
|
|
62011
|
+
process.on("SIGINT", stop);
|
|
62012
|
+
process.on("SIGTERM", stop);`;
|
|
62013
|
+
var runDevServer = (input) => tryPromise2({
|
|
62014
|
+
try: async () => {
|
|
62015
|
+
const child = Bun.spawn(["node", "--input-type=module", "--eval", DEV_SCRIPT], {
|
|
62016
|
+
cwd: process.cwd(),
|
|
62017
|
+
env: {
|
|
62018
|
+
...Bun.env,
|
|
62019
|
+
SAMVA_TOOLCHAIN_INPUT: JSON.stringify({
|
|
62020
|
+
root: process.cwd(),
|
|
62021
|
+
...input.dir === undefined ? {} : { dir: input.dir },
|
|
62022
|
+
...input.port === undefined ? {} : { port: input.port },
|
|
62023
|
+
...input.host === undefined ? {} : { host: input.host },
|
|
62024
|
+
open: input.open
|
|
62025
|
+
})
|
|
62026
|
+
},
|
|
62027
|
+
stdout: "inherit",
|
|
62028
|
+
stderr: "pipe"
|
|
62029
|
+
});
|
|
62030
|
+
const forward = (signal) => () => child.kill(signal);
|
|
62031
|
+
const onInterrupt = forward("SIGINT");
|
|
62032
|
+
const onTerminate = forward("SIGTERM");
|
|
62033
|
+
process.on("SIGINT", onInterrupt);
|
|
62034
|
+
process.on("SIGTERM", onTerminate);
|
|
62035
|
+
let stderr = "";
|
|
62036
|
+
const drain = (async () => {
|
|
62037
|
+
for await (const chunk of child.stderr) {
|
|
62038
|
+
stderr += Buffer.from(chunk).toString();
|
|
62039
|
+
process.stderr.write(chunk);
|
|
62040
|
+
}
|
|
62041
|
+
})();
|
|
62042
|
+
const exitCode = await child.exited;
|
|
62043
|
+
await drain;
|
|
62044
|
+
process.off("SIGINT", onInterrupt);
|
|
62045
|
+
process.off("SIGTERM", onTerminate);
|
|
62046
|
+
if (exitCode !== 0 && child.signalCode === null) {
|
|
62047
|
+
return Promise.reject(new SamvaCliError({
|
|
62048
|
+
message: toolchainFailure(stderr, "Could not start the template editor")
|
|
62049
|
+
}));
|
|
62050
|
+
}
|
|
62051
|
+
},
|
|
62052
|
+
catch: (cause) => cause instanceof SamvaCliError ? cause : new SamvaCliError({
|
|
62053
|
+
message: `Could not start the template editor. Install Node.js 22+: ${String(cause)}`
|
|
61903
62054
|
})
|
|
61904
62055
|
});
|
|
62056
|
+
var devCommand = make28("dev", {
|
|
62057
|
+
dir: dirFlag,
|
|
62058
|
+
port: Int5("port").pipe(withDescription2("Port to listen on (default: Vite's, 5173, or the next free one)"), optional4),
|
|
62059
|
+
host: String8("host").pipe(withDescription2("Interface to listen on (default: loopback only)"), optional4),
|
|
62060
|
+
open: Boolean6("open").pipe(withDescription2("Open the editor in a browser once it is listening"), withDefault4(false))
|
|
62061
|
+
}).pipe(withDescription3("Start the local visual editor for the templates in this project; no vite.config.ts needed"), withExamples([
|
|
62062
|
+
{ command: "samva templates dev", description: "Serve templates/ and emails/" },
|
|
62063
|
+
{
|
|
62064
|
+
command: "samva templates dev --dir templates --port 4000 --open",
|
|
62065
|
+
description: "Serve one directory on a fixed port and open the browser"
|
|
62066
|
+
}
|
|
62067
|
+
]), withHandler(({ dir, port, host, open }) => runDevServer({
|
|
62068
|
+
dir: map(dir, (value) => resolve6(value)).pipe(getOrUndefined),
|
|
62069
|
+
port: getOrUndefined(port),
|
|
62070
|
+
host: getOrUndefined(host),
|
|
62071
|
+
open
|
|
62072
|
+
})));
|
|
61905
62073
|
|
|
61906
|
-
// src/commands/templates/
|
|
62074
|
+
// src/commands/templates/diagnostics.ts
|
|
62075
|
+
var reportDiagnostic = (diagnostic, context) => {
|
|
62076
|
+
const origin = diagnostic.origins[0];
|
|
62077
|
+
const range = diagnostic.range ?? (origin === undefined ? undefined : { start: { line: origin.lineNumber, column: origin.columnNumber } });
|
|
62078
|
+
return {
|
|
62079
|
+
file: origin?.fileName ?? context.file,
|
|
62080
|
+
code: diagnostic.code,
|
|
62081
|
+
severity: diagnostic.severity,
|
|
62082
|
+
message: diagnostic.message,
|
|
62083
|
+
...origin === undefined ? {} : { line: origin.lineNumber, column: origin.columnNumber },
|
|
62084
|
+
...range === undefined ? {} : { range },
|
|
62085
|
+
...diagnostic.fix === undefined ? {} : { fix: diagnostic.fix },
|
|
62086
|
+
...diagnostic.edit === undefined ? {} : { edit: diagnostic.edit },
|
|
62087
|
+
...context.fixture === undefined ? {} : { fixture: context.fixture }
|
|
62088
|
+
};
|
|
62089
|
+
};
|
|
62090
|
+
var formatReportedDiagnostic = (diagnostic) => {
|
|
62091
|
+
const at = diagnostic.line === undefined ? diagnostic.file : `${diagnostic.file}:${diagnostic.line}${diagnostic.column === undefined ? "" : `:${diagnostic.column}`}`;
|
|
62092
|
+
const head = `${at} ${diagnostic.severity} ${diagnostic.code}: ${diagnostic.message}`;
|
|
62093
|
+
return diagnostic.fix === undefined ? head : `${head}
|
|
62094
|
+
Fix: ${diagnostic.fix}`;
|
|
62095
|
+
};
|
|
62096
|
+
|
|
62097
|
+
// src/commands/templates/local-build.ts
|
|
61907
62098
|
import { resolve as resolve7 } from "path";
|
|
62099
|
+
var buildDir = (dir, assetBase) => runToolchain({
|
|
62100
|
+
action: `Could not build templates${dir === undefined ? "" : ` in ${dir}`}`,
|
|
62101
|
+
options: {
|
|
62102
|
+
root: process.cwd(),
|
|
62103
|
+
...dir === undefined ? {} : { dir: resolve7(dir) },
|
|
62104
|
+
...assetBase === undefined ? {} : { assetBase }
|
|
62105
|
+
},
|
|
62106
|
+
script: `import { buildTemplates } from "@samva/vite/build"; ${OPTIONS_PRELUDE} process.stdout.write(JSON.stringify(await buildTemplates(options)));`
|
|
62107
|
+
});
|
|
62108
|
+
|
|
62109
|
+
// src/commands/templates/project.ts
|
|
62110
|
+
import { resolve as resolve8 } from "path";
|
|
61908
62111
|
var templateId = String9("id").pipe(withDescription4("Template id"));
|
|
61909
62112
|
var projectOrTemplateId = String9("id").pipe(withDescription4("Template project id (tproj_...) or the id of any template in it"));
|
|
61910
62113
|
var runGit = (args, options = {}) => tryPromise2({
|
|
@@ -61993,7 +62196,7 @@ var cloneProject = fn2("Templates.cloneProject")(function* (input) {
|
|
|
61993
62196
|
], { concurrency: 2 }).pipe(mapError2((error) => new SamvaCliError({
|
|
61994
62197
|
message: formatApiError("Could not resolve template project", error)
|
|
61995
62198
|
})));
|
|
61996
|
-
const root =
|
|
62199
|
+
const root = resolve8(input.dir);
|
|
61997
62200
|
const helper = yield* helperCommand(template.id, "read");
|
|
61998
62201
|
yield* runGit([
|
|
61999
62202
|
"-c",
|
|
@@ -62083,7 +62286,7 @@ var init = make28("init", {
|
|
|
62083
62286
|
description: "Create deterministically for CI or a coding agent"
|
|
62084
62287
|
}
|
|
62085
62288
|
]), withHandler(({ name, projectName, slug, dir, idempotencyKey, dryRun, json }) => gen2(function* () {
|
|
62086
|
-
const root =
|
|
62289
|
+
const root = resolve8(getOrElse(dir, () => projectDirectory(name)));
|
|
62087
62290
|
const key = getOrUndefined(idempotencyKey);
|
|
62088
62291
|
const request = {
|
|
62089
62292
|
name,
|
|
@@ -62179,37 +62382,36 @@ var resolveProjectId = fn2("Templates.resolveProjectId")(function* (flag) {
|
|
|
62179
62382
|
}
|
|
62180
62383
|
return projectId;
|
|
62181
62384
|
});
|
|
62182
|
-
var
|
|
62385
|
+
var ENTRY_ROOTS = ["templates", "emails"];
|
|
62386
|
+
var ENTRY_PATH = new RegExp(`^(?:${ENTRY_ROOTS.join("|")})/.+\\.tsx$`);
|
|
62387
|
+
var ENTRY_ROOTS_LABEL = ENTRY_ROOTS.map((root) => `${root}/*.tsx`).join(" or ");
|
|
62183
62388
|
var TEMPLATE_SLUG = /^(?=.{1,100}$)[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
62184
62389
|
var entryPathArgument = (name, description) => String9(name).pipe(withDescription4(description), filterMap3((value) => {
|
|
62185
62390
|
const normalized = value.replace(/^\.\//, "");
|
|
62186
62391
|
return ENTRY_PATH.test(normalized) ? some2(normalized) : none2();
|
|
62187
|
-
}, (value) => `${value} is not
|
|
62392
|
+
}, (value) => `${value} is not a ${ENTRY_ROOTS_LABEL} entry path`));
|
|
62188
62393
|
var humanize2 = (id) => {
|
|
62189
62394
|
const words = id.replace(/[-_.]+/g, " ").trim();
|
|
62190
62395
|
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
62191
62396
|
};
|
|
62192
62397
|
var declaredTemplateId = fn2("Templates.declaredTemplateId")(function* (entryPath) {
|
|
62193
|
-
const built = yield* buildDir(
|
|
62194
|
-
|
|
62195
|
-
if (file === undefined || file.preview.kind !== "email")
|
|
62196
|
-
return;
|
|
62197
|
-
return file.preview.templates[0]?.name;
|
|
62398
|
+
const built = yield* buildDir(undefined, undefined);
|
|
62399
|
+
return built.files.find(({ id }) => id === entryPath)?.template?.template;
|
|
62198
62400
|
});
|
|
62199
62401
|
var add4 = make28("add", {
|
|
62200
|
-
entry: entryPathArgument("entry", "Entry file to register, such as
|
|
62201
|
-
name: String8("name").pipe(withDescription2("Template name (defaults from the entry's
|
|
62202
|
-
slug: String8("slug").pipe(withDescription2("Template handle (defaults to the entry's
|
|
62402
|
+
entry: entryPathArgument("entry", "Entry file to register, such as templates/reset.tsx"),
|
|
62403
|
+
name: String8("name").pipe(withDescription2("Template name (defaults from the entry's defineTemplate id)"), optional4),
|
|
62404
|
+
slug: String8("slug").pipe(withDescription2("Template handle (defaults to the entry's defineTemplate id)"), optional4),
|
|
62203
62405
|
projectId: projectIdFlag,
|
|
62204
62406
|
dryRun: Boolean6("dry-run").pipe(withDescription2("Show the registration request without writing"), withDefault4(false)),
|
|
62205
62407
|
json: jsonFlag
|
|
62206
|
-
}).pipe(withDescription3("Register another
|
|
62408
|
+
}).pipe(withDescription3("Register another template entry in a template project"), withExamples([
|
|
62207
62409
|
{
|
|
62208
|
-
command: "samva templates add
|
|
62209
|
-
description: "Register a local entry under the handle its
|
|
62410
|
+
command: "samva templates add templates/reset.tsx",
|
|
62411
|
+
description: "Register a local entry under the handle its defineTemplate id declares"
|
|
62210
62412
|
},
|
|
62211
62413
|
{
|
|
62212
|
-
command: 'samva templates add
|
|
62414
|
+
command: 'samva templates add templates/reset.tsx --slug password-reset --name "Password reset"',
|
|
62213
62415
|
description: "Register an entry that is not written yet, or override the defaults"
|
|
62214
62416
|
}
|
|
62215
62417
|
]), withHandler(({ entry, name, slug, projectId, dryRun, json }) => gen2(function* () {
|
|
@@ -62220,12 +62422,12 @@ var add4 = make28("add", {
|
|
|
62220
62422
|
const resolvedSlug = explicitSlug ?? declared;
|
|
62221
62423
|
if (resolvedSlug === undefined) {
|
|
62222
62424
|
return yield* new SamvaCliError({
|
|
62223
|
-
message: `${entry} does not build to a
|
|
62425
|
+
message: `${entry} does not build to a defineTemplate template here. Pass --slug and --name to register it before it exists.`
|
|
62224
62426
|
});
|
|
62225
62427
|
}
|
|
62226
62428
|
if (!TEMPLATE_SLUG.test(resolvedSlug)) {
|
|
62227
62429
|
return yield* new SamvaCliError({
|
|
62228
|
-
message: `
|
|
62430
|
+
message: `defineTemplate id ${JSON.stringify(resolvedSlug)} is not a valid handle (lowercase kebab-case). Pass --slug.`
|
|
62229
62431
|
});
|
|
62230
62432
|
}
|
|
62231
62433
|
const request = {
|
|
@@ -62267,7 +62469,7 @@ var move = make28("move", {
|
|
|
62267
62469
|
json: jsonFlag
|
|
62268
62470
|
}).pipe(withDescription3("Point a template at another entry file in its project"), withExamples([
|
|
62269
62471
|
{
|
|
62270
|
-
command: "samva templates move
|
|
62472
|
+
command: "samva templates move templates/reset.tsx templates/account/reset.tsx",
|
|
62271
62473
|
description: "Keep the template's id, handle, and publications after `git mv`"
|
|
62272
62474
|
}
|
|
62273
62475
|
]), withHandler(({ from, to, projectId, json }) => gen2(function* () {
|
|
@@ -62291,7 +62493,14 @@ var move = make28("move", {
|
|
|
62291
62493
|
Publish fails until a pushed commit has ${to}; move the file with \`git mv\` if you have not.`);
|
|
62292
62494
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
62293
62495
|
var unregisteredEntries = fn2("Templates.unregisteredEntries")(function* (commit, templates) {
|
|
62294
|
-
const matches = yield* runGit([
|
|
62496
|
+
const matches = yield* runGit([
|
|
62497
|
+
"grep",
|
|
62498
|
+
"-l",
|
|
62499
|
+
"defineTemplate",
|
|
62500
|
+
commit,
|
|
62501
|
+
"--",
|
|
62502
|
+
...ENTRY_ROOTS.map((root) => `${root}/`)
|
|
62503
|
+
]).pipe(catch_2(() => succeed6("")));
|
|
62295
62504
|
const registered = new Set(templates.map(({ entryPath }) => entryPath));
|
|
62296
62505
|
return matches.split(`
|
|
62297
62506
|
`).map((line) => line.slice(line.indexOf(":") + 1)).filter((path) => ENTRY_PATH.test(path) && !registered.has(path));
|
|
@@ -62327,7 +62536,7 @@ var publish2 = make28("publish", {
|
|
|
62327
62536
|
json: jsonFlag
|
|
62328
62537
|
}).pipe(withDescription3("Publish template entries at an exact clean, pushed commit"), withExamples([
|
|
62329
62538
|
{
|
|
62330
|
-
command: "samva templates publish
|
|
62539
|
+
command: "samva templates publish templates/reset.tsx",
|
|
62331
62540
|
description: "Publish one entry at the current commit"
|
|
62332
62541
|
},
|
|
62333
62542
|
{
|
|
@@ -62420,8 +62629,489 @@ ${lines.join(`
|
|
|
62420
62629
|
`)}`);
|
|
62421
62630
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
62422
62631
|
|
|
62632
|
+
// src/commands/templates/render-command.ts
|
|
62633
|
+
import { mkdir as mkdir2, writeFile as writeFile3 } from "fs/promises";
|
|
62634
|
+
import { dirname as dirname2, resolve as resolve10 } from "path";
|
|
62635
|
+
|
|
62636
|
+
// src/commands/templates/local-render.ts
|
|
62637
|
+
import { resolve as resolve9 } from "path";
|
|
62638
|
+
var renderLocal = (input) => runToolchain({
|
|
62639
|
+
action: `Could not render ${input.template}`,
|
|
62640
|
+
options: {
|
|
62641
|
+
root: process.cwd(),
|
|
62642
|
+
template: input.template,
|
|
62643
|
+
fixture: input.fixture,
|
|
62644
|
+
channel: input.channel,
|
|
62645
|
+
...input.dir === undefined ? {} : { dir: resolve9(input.dir) },
|
|
62646
|
+
...input.locale === undefined ? {} : { locale: input.locale },
|
|
62647
|
+
...input.timeZone === undefined ? {} : { timeZone: input.timeZone },
|
|
62648
|
+
...input.assetBase === undefined ? {} : { assetBase: input.assetBase },
|
|
62649
|
+
...input.offline === true ? { offline: true } : {}
|
|
62650
|
+
},
|
|
62651
|
+
script: `import { renderChannel, renderTemplate } from "@samva/vite/render"; ${OPTIONS_PRELUDE} const { channel, ...rest } = options; const result = channel === "email" ? await renderTemplate(rest) : await renderChannel({ ...rest, channel }); process.stdout.write(JSON.stringify(result));`
|
|
62652
|
+
});
|
|
62653
|
+
|
|
62654
|
+
// src/commands/templates/render-command.ts
|
|
62655
|
+
var renderPayload = (result, out) => ({
|
|
62656
|
+
action: "templates.render",
|
|
62657
|
+
...result,
|
|
62658
|
+
diagnostics: result.diagnostics.map((diagnostic) => reportDiagnostic(diagnostic, { file: "." })),
|
|
62659
|
+
...out === undefined ? {} : { out }
|
|
62660
|
+
});
|
|
62661
|
+
var renderedBody = (result, format) => {
|
|
62662
|
+
if ("html" in result) {
|
|
62663
|
+
if (format === "html")
|
|
62664
|
+
return result.html;
|
|
62665
|
+
return [
|
|
62666
|
+
`Subject: ${result.subject}`,
|
|
62667
|
+
...result.preheader === undefined ? [] : [`Preheader: ${result.preheader}`],
|
|
62668
|
+
"",
|
|
62669
|
+
result.text
|
|
62670
|
+
].join(`
|
|
62671
|
+
`);
|
|
62672
|
+
}
|
|
62673
|
+
if ("message" in result) {
|
|
62674
|
+
const { header, body, footer, buttons } = result.message;
|
|
62675
|
+
return [
|
|
62676
|
+
...header === undefined ? [] : [`Header (${header.type}): ${header.text}`, ""],
|
|
62677
|
+
body,
|
|
62678
|
+
...footer === undefined ? [] : ["", footer],
|
|
62679
|
+
...buttons.length === 0 ? [] : ["", ...buttons.map((button) => `[${JSON.stringify(button)}]`)]
|
|
62680
|
+
].join(`
|
|
62681
|
+
`);
|
|
62682
|
+
}
|
|
62683
|
+
return result.text;
|
|
62684
|
+
};
|
|
62685
|
+
var renderCommand = make28("render", {
|
|
62686
|
+
template: String9("template").pipe(withDescription4("Template id, or the path of its .tsx entry")),
|
|
62687
|
+
fixture: String8("fixture").pipe(withDescription2("Fixture to render, such as no-tracking")),
|
|
62688
|
+
channel: Literals3("channel", ["email", "sms", "whatsapp"]).pipe(withDescription2("Channel to render"), withDefault4("email")),
|
|
62689
|
+
dir: dirFlag,
|
|
62690
|
+
locale: String8("locale").pipe(withDescription2("Locale for formatters (default: the template's)"), optional4),
|
|
62691
|
+
timeZone: String8("time-zone").pipe(withDescription2("IANA time zone for date and time formatters (default: UTC)"), optional4),
|
|
62692
|
+
assetBase: assetBaseFlag,
|
|
62693
|
+
offline: offlineFlag,
|
|
62694
|
+
format: Literals3("format", ["text", "html", "json"]).pipe(withDescription2("text: subject, preheader and plain-text body; html: the HTML; json: the full result"), withDefault4("text")),
|
|
62695
|
+
out: File3("out").pipe(withDescription2("Write the rendered output to a file instead of stdout"), optional4),
|
|
62696
|
+
json: jsonFlag
|
|
62697
|
+
}).pipe(withDescription3("Render one fixture of a local template and print the result"), withExamples([
|
|
62698
|
+
{
|
|
62699
|
+
command: "samva templates render welcome --fixture no-tracking",
|
|
62700
|
+
description: "Print the subject, preheader and plain-text body"
|
|
62701
|
+
},
|
|
62702
|
+
{
|
|
62703
|
+
command: "samva templates render welcome --fixture default --format html --out welcome.html",
|
|
62704
|
+
description: "Write the rendered HTML to a file"
|
|
62705
|
+
},
|
|
62706
|
+
{
|
|
62707
|
+
command: "samva templates render welcome --fixture default --json",
|
|
62708
|
+
description: "Print the full result with located findings, fixes and edits"
|
|
62709
|
+
},
|
|
62710
|
+
{
|
|
62711
|
+
command: "samva templates render order-shipped --fixture default --channel sms",
|
|
62712
|
+
description: "Render the SMS body of a multi-channel template"
|
|
62713
|
+
}
|
|
62714
|
+
]), withHandler(({
|
|
62715
|
+
template,
|
|
62716
|
+
fixture,
|
|
62717
|
+
channel,
|
|
62718
|
+
dir,
|
|
62719
|
+
locale,
|
|
62720
|
+
timeZone,
|
|
62721
|
+
assetBase,
|
|
62722
|
+
offline,
|
|
62723
|
+
format,
|
|
62724
|
+
out,
|
|
62725
|
+
json
|
|
62726
|
+
}) => gen2(function* () {
|
|
62727
|
+
const machine = json || format === "json";
|
|
62728
|
+
const outPath = map(out, (value) => resolve10(value)).pipe(getOrUndefined);
|
|
62729
|
+
const result = yield* renderLocal({
|
|
62730
|
+
template,
|
|
62731
|
+
fixture,
|
|
62732
|
+
channel,
|
|
62733
|
+
dir: getOrUndefined(dir),
|
|
62734
|
+
locale: getOrUndefined(locale),
|
|
62735
|
+
timeZone: getOrUndefined(timeZone),
|
|
62736
|
+
assetBase: getOrUndefined(assetBase),
|
|
62737
|
+
offline
|
|
62738
|
+
});
|
|
62739
|
+
if (!result.ok) {
|
|
62740
|
+
const message = `Could not render ${template} (${fixture}): ${result.diagnostics.length} finding(s).`;
|
|
62741
|
+
if (machine) {
|
|
62742
|
+
return yield* new CliResultError({
|
|
62743
|
+
code: "template_render_failed",
|
|
62744
|
+
message,
|
|
62745
|
+
result: renderPayload(result, undefined),
|
|
62746
|
+
human: message
|
|
62747
|
+
});
|
|
62748
|
+
}
|
|
62749
|
+
for (const diagnostic of result.diagnostics) {
|
|
62750
|
+
yield* error(formatReportedDiagnostic(reportDiagnostic(diagnostic, { file: "." })));
|
|
62751
|
+
}
|
|
62752
|
+
return yield* new SamvaCliError({ message });
|
|
62753
|
+
}
|
|
62754
|
+
const payload = renderPayload(result, outPath);
|
|
62755
|
+
if (outPath !== undefined) {
|
|
62756
|
+
const content = machine ? `${JSON.stringify(payload, null, 2)}
|
|
62757
|
+
` : `${renderedBody(result, format)}
|
|
62758
|
+
`;
|
|
62759
|
+
yield* tryPromise2({
|
|
62760
|
+
try: async () => {
|
|
62761
|
+
await mkdir2(dirname2(outPath), { recursive: true });
|
|
62762
|
+
await writeFile3(outPath, content);
|
|
62763
|
+
},
|
|
62764
|
+
catch: (cause) => new SamvaCliError({ message: `Could not write ${outPath}: ${String(cause)}` })
|
|
62765
|
+
});
|
|
62766
|
+
}
|
|
62767
|
+
if (machine)
|
|
62768
|
+
return yield* printJson(payload);
|
|
62769
|
+
for (const diagnostic of result.diagnostics) {
|
|
62770
|
+
yield* error(formatReportedDiagnostic(reportDiagnostic(diagnostic, { file: "." })));
|
|
62771
|
+
}
|
|
62772
|
+
if (outPath !== undefined)
|
|
62773
|
+
return yield* logInfo(`Wrote ${outPath}`);
|
|
62774
|
+
yield* log(renderedBody(result, format));
|
|
62775
|
+
}).pipe(json || format === "json" ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
62776
|
+
|
|
62777
|
+
// src/commands/templates/snapshot-command.ts
|
|
62778
|
+
import { resolve as resolve11 } from "path";
|
|
62779
|
+
|
|
62780
|
+
// src/commands/templates/snapshot-browser.ts
|
|
62781
|
+
import { existsSync } from "fs";
|
|
62782
|
+
import { copyFile as copyFile3, mkdir as mkdir3, mkdtemp as mkdtemp2, readFile as readFile4, rm as rm2, stat as stat3, writeFile as writeFile4 } from "fs/promises";
|
|
62783
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
62784
|
+
import { join as join4 } from "path";
|
|
62785
|
+
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
62786
|
+
var VIEWPORTS = {
|
|
62787
|
+
desktop: { width: 1280, height: 800 },
|
|
62788
|
+
mobile: { width: 390, height: 844 }
|
|
62789
|
+
};
|
|
62790
|
+
var SCHEMES = ["light", "dark"];
|
|
62791
|
+
var BROWSER_REMEDY = "Install a browser to screenshot with: add `playwright` to this project (`npm install --save-dev playwright && npx playwright install chromium`), or install Google Chrome or Chromium and set SAMVA_CHROME to its executable path if it is not in the usual location.";
|
|
62792
|
+
var snapshotFileName = (template, fixture, viewport, scheme) => `${template}-${fixture}-${viewport}-${scheme}.png`;
|
|
62793
|
+
var takeSnapshots = async (input) => {
|
|
62794
|
+
await mkdir3(input.outDir, { recursive: true });
|
|
62795
|
+
const scratch = await mkdtemp2(join4(tmpdir2(), "samva-snapshot-"));
|
|
62796
|
+
const htmlPath = join4(scratch, "page.html");
|
|
62797
|
+
await writeFile4(htmlPath, input.html);
|
|
62798
|
+
const requests = input.viewports.flatMap((viewport) => input.schemes.map((scheme) => ({
|
|
62799
|
+
htmlPath,
|
|
62800
|
+
viewport,
|
|
62801
|
+
width: VIEWPORTS[viewport].width,
|
|
62802
|
+
height: VIEWPORTS[viewport].height,
|
|
62803
|
+
scheme,
|
|
62804
|
+
outFile: join4(input.outDir, snapshotFileName(input.template, input.fixture, viewport, scheme))
|
|
62805
|
+
})));
|
|
62806
|
+
const reasons = [];
|
|
62807
|
+
try {
|
|
62808
|
+
for (const launcher of input.launchers) {
|
|
62809
|
+
const outcome = await launcher.capture(requests);
|
|
62810
|
+
if (outcome.status === "done")
|
|
62811
|
+
return {
|
|
62812
|
+
ok: true,
|
|
62813
|
+
browser: launcher.name,
|
|
62814
|
+
files: requests.map(({ viewport, scheme, width, outFile }) => ({
|
|
62815
|
+
viewport,
|
|
62816
|
+
scheme,
|
|
62817
|
+
width,
|
|
62818
|
+
path: outFile
|
|
62819
|
+
}))
|
|
62820
|
+
};
|
|
62821
|
+
reasons.push(`${launcher.name}: ${outcome.reason}`);
|
|
62822
|
+
}
|
|
62823
|
+
return { ok: false, reasons };
|
|
62824
|
+
} finally {
|
|
62825
|
+
await rm2(scratch, { recursive: true, force: true });
|
|
62826
|
+
}
|
|
62827
|
+
};
|
|
62828
|
+
var CHROME_PATHS = [
|
|
62829
|
+
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
62830
|
+
"/Applications/Chromium.app/Contents/MacOS/Chromium",
|
|
62831
|
+
"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
|
|
62832
|
+
"/usr/bin/google-chrome",
|
|
62833
|
+
"/usr/bin/google-chrome-stable",
|
|
62834
|
+
"/usr/bin/chromium",
|
|
62835
|
+
"/usr/bin/chromium-browser",
|
|
62836
|
+
"/snap/bin/chromium"
|
|
62837
|
+
];
|
|
62838
|
+
var CHROME_COMMANDS = ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"];
|
|
62839
|
+
var findChrome = (env, which = (command) => Bun.which(command), exists = existsSync) => {
|
|
62840
|
+
const override = env["SAMVA_CHROME"];
|
|
62841
|
+
if (override !== undefined && override !== "")
|
|
62842
|
+
return override;
|
|
62843
|
+
return CHROME_PATHS.find((path) => exists(path)) ?? CHROME_COMMANDS.map((command) => which(command)).find((path) => path !== null) ?? undefined;
|
|
62844
|
+
};
|
|
62845
|
+
var chromeScreenshotArgs = (input) => [
|
|
62846
|
+
"--headless=new",
|
|
62847
|
+
"--disable-gpu",
|
|
62848
|
+
"--hide-scrollbars",
|
|
62849
|
+
"--disable-background-networking",
|
|
62850
|
+
"--disable-component-update",
|
|
62851
|
+
"--no-first-run",
|
|
62852
|
+
"--no-default-browser-check",
|
|
62853
|
+
`--user-data-dir=${input.profile}`,
|
|
62854
|
+
`--window-size=${input.width},${input.height}`,
|
|
62855
|
+
`--blink-settings=preferredColorScheme=${input.scheme === "dark" ? 1 : 0}`,
|
|
62856
|
+
`--screenshot=${input.outFile}`,
|
|
62857
|
+
input.url
|
|
62858
|
+
];
|
|
62859
|
+
var chromeMeasureArgs = (input) => [
|
|
62860
|
+
"--headless=new",
|
|
62861
|
+
"--disable-gpu",
|
|
62862
|
+
"--hide-scrollbars",
|
|
62863
|
+
"--disable-background-networking",
|
|
62864
|
+
"--disable-component-update",
|
|
62865
|
+
"--no-first-run",
|
|
62866
|
+
"--no-default-browser-check",
|
|
62867
|
+
`--user-data-dir=${input.profile}`,
|
|
62868
|
+
`--window-size=${input.width},${input.height}`,
|
|
62869
|
+
`--blink-settings=preferredColorScheme=${input.scheme === "dark" ? 1 : 0}`,
|
|
62870
|
+
"--dump-dom",
|
|
62871
|
+
input.url
|
|
62872
|
+
];
|
|
62873
|
+
var MEASURE_SCRIPT = "<script>addEventListener('load',()=>{document.documentElement.setAttribute('data-samva-height',String(Math.ceil(Math.max(document.documentElement.scrollHeight,document.body?document.body.scrollHeight:0))))})</script>";
|
|
62874
|
+
var withMeasurement = (html) => /<\/body>/i.test(html) ? html.replace(/<\/body>/i, `${MEASURE_SCRIPT}</body>`) : `${html}${MEASURE_SCRIPT}`;
|
|
62875
|
+
var parseMeasuredHeight = (dom) => {
|
|
62876
|
+
const height = /data-samva-height="(\d+)"/.exec(dom)?.[1];
|
|
62877
|
+
return height === undefined ? undefined : Number(height);
|
|
62878
|
+
};
|
|
62879
|
+
var RUN_TIMEOUT_MS = 30000;
|
|
62880
|
+
var POLL_MS = 100;
|
|
62881
|
+
var runProcess = async (command, args, until) => {
|
|
62882
|
+
const child = Bun.spawn([command, ...args], { stdout: "pipe", stderr: "pipe" });
|
|
62883
|
+
let stdout = "";
|
|
62884
|
+
let stderr = "";
|
|
62885
|
+
const drain = async (stream, sink) => {
|
|
62886
|
+
for await (const chunk of stream)
|
|
62887
|
+
sink(Buffer.from(chunk).toString());
|
|
62888
|
+
};
|
|
62889
|
+
drain(child.stdout, (text) => {
|
|
62890
|
+
stdout += text;
|
|
62891
|
+
});
|
|
62892
|
+
drain(child.stderr, (text) => {
|
|
62893
|
+
stderr += text;
|
|
62894
|
+
});
|
|
62895
|
+
const deadline = Date.now() + RUN_TIMEOUT_MS;
|
|
62896
|
+
const produced = async () => until.stdoutIncludes !== undefined && stdout.includes(until.stdoutIncludes) || until.file !== undefined && existsSync(until.file) && (await stat3(until.file)).size > 0;
|
|
62897
|
+
const state = { exited: false };
|
|
62898
|
+
child.exited.then(() => {
|
|
62899
|
+
state.exited = true;
|
|
62900
|
+
});
|
|
62901
|
+
while (!state.exited && Date.now() < deadline && !await produced()) {
|
|
62902
|
+
await new Promise((done) => setTimeout(done, POLL_MS));
|
|
62903
|
+
}
|
|
62904
|
+
if (!state.exited) {
|
|
62905
|
+
await new Promise((done) => setTimeout(done, POLL_MS * 3));
|
|
62906
|
+
child.kill("SIGKILL");
|
|
62907
|
+
}
|
|
62908
|
+
await child.exited;
|
|
62909
|
+
return { code: state.exited ? child.exitCode : null, stdout, stderr };
|
|
62910
|
+
};
|
|
62911
|
+
var chromeLauncher = (binary, run = runProcess) => ({
|
|
62912
|
+
name: "Chrome",
|
|
62913
|
+
capture: async (requests) => {
|
|
62914
|
+
if (binary === undefined)
|
|
62915
|
+
return {
|
|
62916
|
+
status: "unavailable",
|
|
62917
|
+
reason: "no Chrome or Chromium found in the usual locations and SAMVA_CHROME is not set"
|
|
62918
|
+
};
|
|
62919
|
+
const profile = await mkdtemp2(join4(tmpdir2(), "samva-chrome-"));
|
|
62920
|
+
try {
|
|
62921
|
+
for (const request of requests) {
|
|
62922
|
+
const source = await readFile4(request.htmlPath, "utf8");
|
|
62923
|
+
const measured = request.htmlPath.replace(/\.html$/, `.${request.viewport}.${request.scheme}.html`);
|
|
62924
|
+
await writeFile4(measured, withMeasurement(source));
|
|
62925
|
+
const measure = await run(binary, chromeMeasureArgs({
|
|
62926
|
+
profile,
|
|
62927
|
+
width: request.width,
|
|
62928
|
+
height: request.height,
|
|
62929
|
+
scheme: request.scheme,
|
|
62930
|
+
url: pathToFileURL2(measured).href
|
|
62931
|
+
}), { stdoutIncludes: "</html>" });
|
|
62932
|
+
const height = Math.max(request.height, parseMeasuredHeight(measure.stdout) ?? request.height);
|
|
62933
|
+
const staged = join4(profile, `shot-${request.viewport}-${request.scheme}.png`);
|
|
62934
|
+
const shot = await run(binary, chromeScreenshotArgs({
|
|
62935
|
+
profile,
|
|
62936
|
+
width: request.width,
|
|
62937
|
+
height,
|
|
62938
|
+
scheme: request.scheme,
|
|
62939
|
+
outFile: staged,
|
|
62940
|
+
url: pathToFileURL2(request.htmlPath).href
|
|
62941
|
+
}), { file: staged });
|
|
62942
|
+
if (!existsSync(staged))
|
|
62943
|
+
return {
|
|
62944
|
+
status: "unavailable",
|
|
62945
|
+
reason: `${binary} did not produce a screenshot (exit ${shot.code ?? "killed"}): ${shot.stderr.trim().split(`
|
|
62946
|
+
`).slice(-3).join(" ")}`
|
|
62947
|
+
};
|
|
62948
|
+
await copyFile3(staged, request.outFile);
|
|
62949
|
+
}
|
|
62950
|
+
return { status: "done" };
|
|
62951
|
+
} finally {
|
|
62952
|
+
await rm2(profile, { recursive: true, force: true });
|
|
62953
|
+
}
|
|
62954
|
+
}
|
|
62955
|
+
});
|
|
62956
|
+
var PLAYWRIGHT_SCRIPT = `
|
|
62957
|
+
const options = JSON.parse(process.env.SAMVA_TOOLCHAIN_INPUT);
|
|
62958
|
+
const load = async () => {
|
|
62959
|
+
for (const name of ["playwright", "playwright-core"]) {
|
|
62960
|
+
try { return await import(name); } catch {}
|
|
62961
|
+
}
|
|
62962
|
+
return undefined;
|
|
62963
|
+
};
|
|
62964
|
+
const done = (value) => process.stdout.write(JSON.stringify(value));
|
|
62965
|
+
const playwright = await load();
|
|
62966
|
+
if (playwright === undefined) {
|
|
62967
|
+
done({ status: "unavailable", reason: "neither playwright nor playwright-core is installed in this project" });
|
|
62968
|
+
} else {
|
|
62969
|
+
const chromium = playwright.chromium ?? playwright.default?.chromium;
|
|
62970
|
+
let browser;
|
|
62971
|
+
let failure = "";
|
|
62972
|
+
for (const launch of [{}, { channel: "chrome" }]) {
|
|
62973
|
+
try { browser = await chromium.launch(launch); break; } catch (error) { failure = String(error?.message ?? error).split("\\n")[0]; }
|
|
62974
|
+
}
|
|
62975
|
+
if (browser === undefined) {
|
|
62976
|
+
done({ status: "unavailable", reason: "playwright could not launch a browser (" + failure + ")" });
|
|
62977
|
+
} else {
|
|
62978
|
+
try {
|
|
62979
|
+
for (const request of options.requests) {
|
|
62980
|
+
const context = await browser.newContext({
|
|
62981
|
+
viewport: { width: request.width, height: request.height },
|
|
62982
|
+
colorScheme: request.scheme,
|
|
62983
|
+
});
|
|
62984
|
+
const page = await context.newPage();
|
|
62985
|
+
await page.goto(options.urls[request.htmlPath]);
|
|
62986
|
+
await page.screenshot({ path: request.outFile, fullPage: true });
|
|
62987
|
+
await context.close();
|
|
62988
|
+
}
|
|
62989
|
+
done({ status: "done" });
|
|
62990
|
+
} finally {
|
|
62991
|
+
await browser.close();
|
|
62992
|
+
}
|
|
62993
|
+
}
|
|
62994
|
+
}
|
|
62995
|
+
`;
|
|
62996
|
+
var playwrightLauncher = () => ({
|
|
62997
|
+
name: "Playwright",
|
|
62998
|
+
capture: async (requests) => {
|
|
62999
|
+
const urls = Object.fromEntries([...new Set(requests.map((request) => request.htmlPath))].map((path) => [
|
|
63000
|
+
path,
|
|
63001
|
+
pathToFileURL2(path).href
|
|
63002
|
+
]));
|
|
63003
|
+
const child = Bun.spawn(["node", "--input-type=module", "--eval", PLAYWRIGHT_SCRIPT], {
|
|
63004
|
+
cwd: process.cwd(),
|
|
63005
|
+
env: { ...Bun.env, SAMVA_TOOLCHAIN_INPUT: JSON.stringify({ requests, urls }) },
|
|
63006
|
+
stdout: "pipe",
|
|
63007
|
+
stderr: "pipe"
|
|
63008
|
+
});
|
|
63009
|
+
const [stdout, stderr, code] = await Promise.all([
|
|
63010
|
+
new Response(child.stdout).text(),
|
|
63011
|
+
new Response(child.stderr).text(),
|
|
63012
|
+
child.exited
|
|
63013
|
+
]);
|
|
63014
|
+
if (code !== 0)
|
|
63015
|
+
return {
|
|
63016
|
+
status: "unavailable",
|
|
63017
|
+
reason: stderr.trim().split(`
|
|
63018
|
+
`).slice(-3).join(" ") || `node exited ${code}`
|
|
63019
|
+
};
|
|
63020
|
+
return JSON.parse(stdout);
|
|
63021
|
+
}
|
|
63022
|
+
});
|
|
63023
|
+
var defaultLaunchers = (env) => [
|
|
63024
|
+
playwrightLauncher(),
|
|
63025
|
+
chromeLauncher(findChrome(env))
|
|
63026
|
+
];
|
|
63027
|
+
|
|
63028
|
+
// src/commands/templates/snapshot-command.ts
|
|
63029
|
+
var parseChoices = (flag, raw, allowed) => {
|
|
63030
|
+
const chosen = raw.split(",").map((value) => value.trim()).filter((value) => value !== "");
|
|
63031
|
+
const unknown = chosen.filter((value) => !allowed.includes(value));
|
|
63032
|
+
return unknown.length > 0 || chosen.length === 0 ? fail6(new CliUsageError({
|
|
63033
|
+
code: "invalid_snapshot_choice",
|
|
63034
|
+
message: `--${flag} takes a comma-separated list of ${allowed.join(", ")}${unknown.length > 0 ? `; got ${unknown.join(", ")}` : ""}.`
|
|
63035
|
+
})) : succeed6([...new Set(chosen)]);
|
|
63036
|
+
};
|
|
63037
|
+
var snapshotCommand = make28("snapshot", {
|
|
63038
|
+
template: String9("template").pipe(withDescription4("Template id, or the path of its .tsx entry")),
|
|
63039
|
+
fixture: String8("fixture").pipe(withDescription2("Fixture to screenshot")),
|
|
63040
|
+
dir: dirFlag,
|
|
63041
|
+
out: Directory2("out").pipe(withDescription2("Directory to write the PNGs into"), withDefault4(".samva/snapshots")),
|
|
63042
|
+
viewport: String8("viewport").pipe(withDescription2(`Comma-separated viewports: ${Object.entries(VIEWPORTS).map(([name, size]) => `${name} (${size.width}px)`).join(", ")}`), withDefault4("desktop,mobile")),
|
|
63043
|
+
scheme: String8("scheme").pipe(withDescription2("Comma-separated color schemes: light, dark"), withDefault4("light,dark")),
|
|
63044
|
+
assetBase: assetBaseFlag,
|
|
63045
|
+
offline: offlineFlag,
|
|
63046
|
+
json: jsonFlag
|
|
63047
|
+
}).pipe(withDescription3("Screenshot one fixture in a headless browser at desktop and mobile widths, light and dark"), withExamples([
|
|
63048
|
+
{
|
|
63049
|
+
command: "samva templates snapshot welcome --fixture no-tracking",
|
|
63050
|
+
description: "Write four PNGs to .samva/snapshots"
|
|
63051
|
+
},
|
|
63052
|
+
{
|
|
63053
|
+
command: "samva templates snapshot welcome --fixture default --viewport mobile --scheme dark --out shots",
|
|
63054
|
+
description: "One screenshot: mobile, dark"
|
|
63055
|
+
}
|
|
63056
|
+
]), withHandler(({ template, fixture, dir, out, viewport, scheme, assetBase, offline, json }) => gen2(function* () {
|
|
63057
|
+
const viewports = yield* parseChoices("viewport", viewport, Object.keys(VIEWPORTS));
|
|
63058
|
+
const schemes = yield* parseChoices("scheme", scheme, SCHEMES);
|
|
63059
|
+
const rendered = yield* renderLocal({
|
|
63060
|
+
template,
|
|
63061
|
+
fixture,
|
|
63062
|
+
channel: "email",
|
|
63063
|
+
dir: getOrUndefined(dir),
|
|
63064
|
+
assetBase: getOrUndefined(assetBase),
|
|
63065
|
+
offline
|
|
63066
|
+
});
|
|
63067
|
+
if (!rendered.ok || !("html" in rendered)) {
|
|
63068
|
+
const message = `Could not render ${template} (${fixture}) to screenshot it.`;
|
|
63069
|
+
const diagnostics = rendered.diagnostics.map((diagnostic) => reportDiagnostic(diagnostic, { file: "." }));
|
|
63070
|
+
if (json) {
|
|
63071
|
+
return yield* new CliResultError({
|
|
63072
|
+
code: "template_render_failed",
|
|
63073
|
+
message,
|
|
63074
|
+
result: { action: "templates.snapshot", ok: false, diagnostics },
|
|
63075
|
+
human: message
|
|
63076
|
+
});
|
|
63077
|
+
}
|
|
63078
|
+
for (const diagnostic of diagnostics) {
|
|
63079
|
+
yield* error(formatReportedDiagnostic(diagnostic));
|
|
63080
|
+
}
|
|
63081
|
+
return yield* new SamvaCliError({ message });
|
|
63082
|
+
}
|
|
63083
|
+
const outDir = resolve11(out);
|
|
63084
|
+
const shots = yield* promise2(() => takeSnapshots({
|
|
63085
|
+
html: rendered.html,
|
|
63086
|
+
template: rendered.template,
|
|
63087
|
+
fixture,
|
|
63088
|
+
outDir,
|
|
63089
|
+
viewports,
|
|
63090
|
+
schemes,
|
|
63091
|
+
launchers: defaultLaunchers(Bun.env)
|
|
63092
|
+
}));
|
|
63093
|
+
if (!shots.ok) {
|
|
63094
|
+
return yield* new SamvaCliError({
|
|
63095
|
+
message: `No browser could take the screenshots (${shots.reasons.join("; ")}). ${BROWSER_REMEDY}`
|
|
63096
|
+
});
|
|
63097
|
+
}
|
|
63098
|
+
const result = {
|
|
63099
|
+
action: "templates.snapshot",
|
|
63100
|
+
ok: true,
|
|
63101
|
+
template: rendered.template,
|
|
63102
|
+
fixture,
|
|
63103
|
+
browser: shots.browser,
|
|
63104
|
+
out: outDir,
|
|
63105
|
+
files: shots.files
|
|
63106
|
+
};
|
|
63107
|
+
if (json)
|
|
63108
|
+
return yield* printJson(result);
|
|
63109
|
+
for (const file of shots.files)
|
|
63110
|
+
yield* log(file.path);
|
|
63111
|
+
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
63112
|
+
|
|
62423
63113
|
// src/commands/templates/types-command.ts
|
|
62424
|
-
import { dirname as
|
|
63114
|
+
import { dirname as dirname3, resolve as resolve12 } from "path";
|
|
62425
63115
|
|
|
62426
63116
|
// src/commands/templates/schema-types.ts
|
|
62427
63117
|
var RESERVED = new Set([
|
|
@@ -62866,7 +63556,7 @@ var typesCommand = make28("types", {
|
|
|
62866
63556
|
});
|
|
62867
63557
|
}
|
|
62868
63558
|
const context = yield* resolveExecutionContext;
|
|
62869
|
-
const path =
|
|
63559
|
+
const path = resolve12(out);
|
|
62870
63560
|
const entries = yield* readCatalog();
|
|
62871
63561
|
const generated = renderTemplateTypes({
|
|
62872
63562
|
entries,
|
|
@@ -62930,7 +63620,7 @@ var typesCommand = make28("types", {
|
|
|
62930
63620
|
});
|
|
62931
63621
|
}
|
|
62932
63622
|
const fs = yield* FileSystem;
|
|
62933
|
-
yield* fs.makeDirectory(
|
|
63623
|
+
yield* fs.makeDirectory(dirname3(path), { recursive: true }).pipe(catch_2(() => void_3));
|
|
62934
63624
|
yield* fs.writeFileString(path, generated.source).pipe(mapError2((cause) => new SamvaCliError({ message: `Could not write ${path}: ${String(cause)}` })));
|
|
62935
63625
|
const written = { ...result, written: true };
|
|
62936
63626
|
if (json)
|
|
@@ -62946,7 +63636,7 @@ var typesCommand = make28("types", {
|
|
|
62946
63636
|
})));
|
|
62947
63637
|
|
|
62948
63638
|
// src/commands/templates/workspace.ts
|
|
62949
|
-
import { basename, resolve as
|
|
63639
|
+
import { basename, resolve as resolve13 } from "path";
|
|
62950
63640
|
var templateIdArgument = String9("template-id").pipe(withDescription4("Template whose project workspace to act on"));
|
|
62951
63641
|
var revisionFlag = String8("revision").pipe(withDescription2("Workspace revision this call is fenced to; a workspace that moved refuses the call"));
|
|
62952
63642
|
var idempotencyKeyFlag4 = String8("idempotency-key").pipe(withDescription2("Key so an identical retry returns the original result rather than repeating it"));
|
|
@@ -62980,7 +63670,7 @@ var patch2 = make28("patch", {
|
|
|
62980
63670
|
json: jsonFlag
|
|
62981
63671
|
}).pipe(withDescription3("Apply file replacements and deletions to the shared workspace"), withExamples([
|
|
62982
63672
|
{
|
|
62983
|
-
command: "samva templates workspace patch tmpl_abc123 --revision 4 --set
|
|
63673
|
+
command: "samva templates workspace patch tmpl_abc123 --revision 4 --set templates/welcome.tsx=./welcome.tsx --idempotency-key edit-1",
|
|
62984
63674
|
description: "Write one file, fenced to the revision you inspected"
|
|
62985
63675
|
}
|
|
62986
63676
|
]), withHandler(fnUntraced2(function* ({ id, revision, set, remove, idempotencyKey, json }) {
|
|
@@ -62999,7 +63689,7 @@ var patch2 = make28("patch", {
|
|
|
62999
63689
|
message: `--set must be <project-path>=<local-file>; got ${entry}.`
|
|
63000
63690
|
});
|
|
63001
63691
|
const path = entry.slice(0, separator);
|
|
63002
|
-
const source =
|
|
63692
|
+
const source = resolve13(entry.slice(separator + 1));
|
|
63003
63693
|
const content = yield* fs.readFileString(source).pipe(mapError2((cause) => new SamvaCliError({ message: `Could not read ${source}: ${String(cause)}` })));
|
|
63004
63694
|
written.push({ path, content });
|
|
63005
63695
|
}
|
|
@@ -63033,7 +63723,7 @@ var addAsset = make28("add-asset", {
|
|
|
63033
63723
|
}
|
|
63034
63724
|
]), withHandler(fnUntraced2(function* ({ id, file, revision, path, replace, idempotencyKey, json }) {
|
|
63035
63725
|
const fs = yield* FileSystem;
|
|
63036
|
-
const source =
|
|
63726
|
+
const source = resolve13(file);
|
|
63037
63727
|
const bytes = yield* fs.readFile(source).pipe(mapError2((cause) => new SamvaCliError({ message: `Could not read ${source}: ${String(cause)}` })));
|
|
63038
63728
|
const client = yield* getClientProvider;
|
|
63039
63729
|
const view = yield* putWorkspaceAsset({
|
|
@@ -63119,7 +63809,7 @@ var publish3 = make28("publish", {
|
|
|
63119
63809
|
json: jsonFlag
|
|
63120
63810
|
}).pipe(withDescription3("Publish an exact saved commit without a local clone"), withExamples([
|
|
63121
63811
|
{
|
|
63122
|
-
command: "samva templates workspace publish tmpl_abc123 --revision 6 --commit 0a1b\u2026 --entry
|
|
63812
|
+
command: "samva templates workspace publish tmpl_abc123 --revision 6 --commit 0a1b\u2026 --entry templates/welcome.tsx --project-id tproj_abc123",
|
|
63123
63813
|
description: "Complete the workspace journey; `templates publish` is the Git-clone equivalent"
|
|
63124
63814
|
}
|
|
63125
63815
|
]), withHandler(fnUntraced2(function* ({ id, revision, commit, entry, projectId, json }) {
|
|
@@ -63145,9 +63835,7 @@ var workspaceCommand = make28("workspace").pipe(withDescription3("Author a templ
|
|
|
63145
63835
|
]), withSubcommands([open3, diff, patch2, addAsset, check4, fixture, save, history, publish3]));
|
|
63146
63836
|
|
|
63147
63837
|
// src/commands/templates.ts
|
|
63148
|
-
var dirFlag = Directory2("dir").pipe(withDescription2("Directory containing your .tsx templates"), withDefault4("emails"));
|
|
63149
63838
|
var tsconfigFlag = String8("tsconfig").pipe(withDescription2("TypeScript project used to check authored templates"), withDefault4("tsconfig.json"));
|
|
63150
|
-
var assetBaseFlag = String8("asset-base").pipe(withDescription2("Actual HTTPS serving base for imported email assets"), optional4);
|
|
63151
63839
|
var dryRunFlag4 = Boolean6("dry-run").pipe(withDescription2("Show the request without calling the API"), withDefault4(false));
|
|
63152
63840
|
var templateIdArgument2 = String9("id").pipe(withDescription4("Remote template id"));
|
|
63153
63841
|
var parseObject = (raw, flag) => try_3({
|
|
@@ -63158,14 +63846,15 @@ var decodePayload = (raw, flag, schema) => parseObject(raw, flag).pipe(flatMap3(
|
|
|
63158
63846
|
var createProjectBuildSession = (dir, assetBase) => tryPromise2({
|
|
63159
63847
|
try: async () => {
|
|
63160
63848
|
const entry = Bun.resolveSync("@samva/vite/build", process.cwd());
|
|
63161
|
-
const projectBuild = await import(
|
|
63162
|
-
return projectBuild.createTemplateBuildSession(
|
|
63849
|
+
const projectBuild = await import(pathToFileURL3(entry).href);
|
|
63850
|
+
return projectBuild.createTemplateBuildSession({
|
|
63163
63851
|
root: process.cwd(),
|
|
63164
|
-
|
|
63852
|
+
...dir === undefined ? {} : { dir: resolve14(dir) },
|
|
63853
|
+
...assetBase === undefined ? {} : { assetBase }
|
|
63165
63854
|
});
|
|
63166
63855
|
},
|
|
63167
63856
|
catch: (cause) => new SamvaCliError({
|
|
63168
|
-
message: `Could not start template watch
|
|
63857
|
+
message: toolchainFailure(String(cause), `Could not start template watch${dir === undefined ? "" : ` in ${dir}`}`)
|
|
63169
63858
|
})
|
|
63170
63859
|
});
|
|
63171
63860
|
var TSC_DIAGNOSTIC_LINE = /^(?:(.*?)(?:\((\d+),(\d+)\))?: )?(?:error )?(TS\d+): (.*)$/;
|
|
@@ -63183,16 +63872,16 @@ var parseTypeScriptDiagnostics = (output, tsconfig) => output.split(`
|
|
|
63183
63872
|
var typecheckProject = (tsconfig) => tryPromise2({
|
|
63184
63873
|
try: async () => {
|
|
63185
63874
|
const typescriptPackage = Bun.resolveSync("typescript/package.json", process.cwd());
|
|
63186
|
-
const tsc =
|
|
63875
|
+
const tsc = resolve14(dirname4(typescriptPackage), "bin/tsc");
|
|
63187
63876
|
const typescriptManifest = await Bun.file(typescriptPackage).json();
|
|
63188
|
-
const child = Bun.spawn(["node", tsc, "--noEmit", "--pretty", "false", "--project",
|
|
63877
|
+
const child = Bun.spawn(["node", tsc, "--noEmit", "--pretty", "false", "--project", resolve14(tsconfig)], { cwd: process.cwd(), stdout: "pipe", stderr: "pipe" });
|
|
63189
63878
|
const [stdout, stderr, exitCode] = await Promise.all([
|
|
63190
63879
|
new Response(child.stdout).text(),
|
|
63191
63880
|
new Response(child.stderr).text(),
|
|
63192
63881
|
child.exited
|
|
63193
63882
|
]);
|
|
63194
63883
|
const output = `${stdout}${stderr}`.trim();
|
|
63195
|
-
const diagnostics = parseTypeScriptDiagnostics(output,
|
|
63884
|
+
const diagnostics = parseTypeScriptDiagnostics(output, resolve14(tsconfig));
|
|
63196
63885
|
if (exitCode !== 0 && diagnostics.length === 0) {
|
|
63197
63886
|
return Promise.reject(new SamvaCliError({
|
|
63198
63887
|
message: output || `Could not run TypeScript from this project. Install typescript and check ${tsconfig}.`
|
|
@@ -63206,7 +63895,7 @@ var typecheckProject = (tsconfig) => tryPromise2({
|
|
|
63206
63895
|
});
|
|
63207
63896
|
var validateTemplatesDir = (dir) => tryPromise2({
|
|
63208
63897
|
try: async () => {
|
|
63209
|
-
const info = await
|
|
63898
|
+
const info = await stat4(dir);
|
|
63210
63899
|
if (!info.isDirectory()) {
|
|
63211
63900
|
return Promise.reject(new SamvaCliError({ message: `${dir} is not a directory.` }));
|
|
63212
63901
|
}
|
|
@@ -63227,69 +63916,28 @@ var validateTemplatesDir = (dir) => tryPromise2({
|
|
|
63227
63916
|
});
|
|
63228
63917
|
}
|
|
63229
63918
|
});
|
|
63230
|
-
var
|
|
63231
|
-
|
|
63232
|
-
file,
|
|
63919
|
+
var problemOf = (phase, diagnostic, context) => ({
|
|
63920
|
+
...reportDiagnostic(diagnostic, context),
|
|
63233
63921
|
phase,
|
|
63234
|
-
provenance
|
|
63235
|
-
|
|
63236
|
-
|
|
63237
|
-
|
|
63238
|
-
|
|
63239
|
-
|
|
63240
|
-
|
|
63241
|
-
|
|
63242
|
-
|
|
63243
|
-
|
|
63244
|
-
|
|
63245
|
-
|
|
63246
|
-
|
|
63247
|
-
code: diagnostic.code,
|
|
63248
|
-
message: diagnostic.message,
|
|
63249
|
-
...origin === undefined ? {} : { line: origin.lineNumber, column: origin.columnNumber },
|
|
63250
|
-
...fixture === undefined ? {} : { fixture }
|
|
63251
|
-
};
|
|
63252
|
-
};
|
|
63253
|
-
var compatibilityWarnings = (result) => result.files.flatMap((file) => {
|
|
63254
|
-
if (file.preview.kind !== "email")
|
|
63255
|
-
return [];
|
|
63256
|
-
return file.preview.templates.flatMap((template) => template.fixtures.flatMap((fixture) => fixture.diagnostics.filter((diagnostic) => diagnostic.severity === "warning").map((diagnostic) => emailProblem(file.id, diagnostic, fixture.name))));
|
|
63257
|
-
});
|
|
63258
|
-
var compilerVersionOf = (result) => result.files[0]?.preview.compilerVersion ?? "unknown";
|
|
63259
|
-
var collectBuildProblems = (result) => {
|
|
63260
|
-
const files = result.files.flatMap((file) => {
|
|
63261
|
-
if (file.preview.kind === "email")
|
|
63262
|
-
return [
|
|
63263
|
-
...file.preview.diagnostics.filter((finding) => finding.severity === "error").map((finding) => emailProblem(file.id, finding)),
|
|
63264
|
-
...file.preview.templates.flatMap((template) => template.fixtures.flatMap((fixture) => fixture.diagnostics.filter((finding) => finding.severity === "error").map((finding) => emailProblem(file.id, finding, fixture.name))))
|
|
63265
|
-
];
|
|
63266
|
-
const moduleDiagnostics = file.preview.diagnostics.map((diagnostic) => ({
|
|
63267
|
-
file: file.id,
|
|
63268
|
-
phase: "module",
|
|
63269
|
-
provenance: "tsx",
|
|
63270
|
-
code: diagnostic.code,
|
|
63271
|
-
message: diagnostic.message,
|
|
63272
|
-
span: diagnostic.span,
|
|
63273
|
-
repair: diagnostic.repair
|
|
63274
|
-
}));
|
|
63275
|
-
const templateDiagnostics = file.preview.templates.flatMap((template) => {
|
|
63276
|
-
const source = template.source;
|
|
63277
|
-
return [
|
|
63278
|
-
...template.diagnostics.map((diagnostic) => diagnosticProblem(file.id, "emit", "sml", diagnostic, source)),
|
|
63279
|
-
...(template.compiled.ok ? [] : template.compiled.diagnostics ?? []).map((diagnostic) => diagnosticProblem(file.id, "compile", "sml", diagnostic, source))
|
|
63280
|
-
];
|
|
63281
|
-
});
|
|
63282
|
-
return [...moduleDiagnostics, ...templateDiagnostics];
|
|
63283
|
-
});
|
|
63284
|
-
return files;
|
|
63285
|
-
};
|
|
63286
|
-
var isSuccessfulBuild = (result) => result.files.length > 0 && result.files.every((file) => file.preview.ok) && collectBuildProblems(result).length === 0;
|
|
63922
|
+
provenance: "tsx"
|
|
63923
|
+
});
|
|
63924
|
+
var compatibilityFindings = (result, severity) => result.files.flatMap((file) => (file.template?.compatibility ?? []).filter((diagnostic) => diagnostic.severity === severity).map((diagnostic) => problemOf("compatibility", diagnostic, { file: file.id })));
|
|
63925
|
+
var compileWarnings = (result) => result.files.flatMap((file) => file.diagnostics.filter((diagnostic) => diagnostic.severity === "warning").map((diagnostic) => problemOf("compile", diagnostic, { file: file.id })));
|
|
63926
|
+
var collectBuildProblems = (result) => [
|
|
63927
|
+
...result.diagnostics.filter((diagnostic) => diagnostic.severity === "error").map((diagnostic) => problemOf("project", diagnostic, { file: "." })),
|
|
63928
|
+
...result.files.flatMap((file) => [
|
|
63929
|
+
...file.diagnostics.filter((diagnostic) => diagnostic.severity === "error").map((diagnostic) => problemOf("compile", diagnostic, { file: file.id })),
|
|
63930
|
+
...(file.template?.fixtures ?? []).flatMap((fixture) => fixture.diagnostics.filter((diagnostic) => diagnostic.severity === "error").map((diagnostic) => problemOf("compile", diagnostic, { file: file.id, fixture: fixture.name })))
|
|
63931
|
+
]),
|
|
63932
|
+
...compatibilityFindings(result, "error")
|
|
63933
|
+
];
|
|
63934
|
+
var isSuccessfulBuild = (result) => result.files.length > 0 && result.ok && collectBuildProblems(result).length === 0;
|
|
63287
63935
|
var toTemplateBuildArtifact = (result) => ({
|
|
63288
|
-
schemaVersion:
|
|
63289
|
-
compilerVersion:
|
|
63936
|
+
schemaVersion: 3,
|
|
63937
|
+
compilerVersion: result.compilerVersion,
|
|
63290
63938
|
result
|
|
63291
63939
|
});
|
|
63292
|
-
var
|
|
63940
|
+
var NO_TEMPLATES = (dir) => `No templates found in ${dir ?? "templates/ or emails/"}. A template is a .tsx file that default-exports defineTemplate with an input schema, fixtures, and an email, sms, or whatsapp body.`;
|
|
63293
63941
|
var observeTemplateCheck = (dir, tsconfig, build) => gen2(function* () {
|
|
63294
63942
|
const typecheck = yield* typecheckProject(tsconfig);
|
|
63295
63943
|
const typeProblems = typecheck.diagnostics.map((diagnostic) => ({
|
|
@@ -63297,6 +63945,7 @@ var observeTemplateCheck = (dir, tsconfig, build) => gen2(function* () {
|
|
|
63297
63945
|
phase: "typescript",
|
|
63298
63946
|
provenance: "tsx",
|
|
63299
63947
|
code: diagnostic.code,
|
|
63948
|
+
severity: "error",
|
|
63300
63949
|
message: diagnostic.message,
|
|
63301
63950
|
line: diagnostic.line,
|
|
63302
63951
|
column: diagnostic.column
|
|
@@ -63320,9 +63969,9 @@ var observeTemplateCheck = (dir, tsconfig, build) => gen2(function* () {
|
|
|
63320
63969
|
const built = yield* build();
|
|
63321
63970
|
const problems = collectBuildProblems(built);
|
|
63322
63971
|
const ok = isSuccessfulBuild(built);
|
|
63323
|
-
const compilerVersion =
|
|
63324
|
-
const warnings =
|
|
63325
|
-
const message = ok ? `TypeScript v${typecheck.version} \xB7 compiler
|
|
63972
|
+
const compilerVersion = built.compilerVersion;
|
|
63973
|
+
const warnings = compatibilityFindings(built, "warning");
|
|
63974
|
+
const message = ok ? `TypeScript v${typecheck.version} \xB7 compiler ${compilerVersion} \xB7 ${built.files.length} template(s) compiled \xB7 ${warnings.length} compatibility warning(s)` : built.files.length === 0 ? NO_TEMPLATES(dir) : `Template check failed (${problems.length} problem(s)).`;
|
|
63326
63975
|
return {
|
|
63327
63976
|
ok,
|
|
63328
63977
|
message,
|
|
@@ -63334,9 +63983,10 @@ var observeTemplateCheck = (dir, tsconfig, build) => gen2(function* () {
|
|
|
63334
63983
|
tsconfig,
|
|
63335
63984
|
typescriptVersion: typecheck.version,
|
|
63336
63985
|
compilerVersion,
|
|
63337
|
-
buildSchemaVersion:
|
|
63986
|
+
buildSchemaVersion: 3,
|
|
63338
63987
|
files: built.files,
|
|
63339
63988
|
problems,
|
|
63989
|
+
warnings: compileWarnings(built),
|
|
63340
63990
|
compatibility: {
|
|
63341
63991
|
errors: problems.filter((problem) => problem.phase === "compatibility").length,
|
|
63342
63992
|
warnings: warnings.length,
|
|
@@ -63353,10 +64003,11 @@ var watchTemplateChecks = (dir, tsconfig, assetBase) => acquireUseRelease2(creat
|
|
|
63353
64003
|
});
|
|
63354
64004
|
const observe = () => observeTemplateCheck(dir, tsconfig, build).pipe(catch_2((error) => {
|
|
63355
64005
|
const problem = {
|
|
63356
|
-
file: dir,
|
|
63357
|
-
phase: "
|
|
64006
|
+
file: dir ?? ".",
|
|
64007
|
+
phase: "watch",
|
|
63358
64008
|
provenance: "tsx",
|
|
63359
64009
|
code: "watch-rebuild-error",
|
|
64010
|
+
severity: "error",
|
|
63360
64011
|
message: error.message
|
|
63361
64012
|
};
|
|
63362
64013
|
return succeed6({
|
|
@@ -63382,12 +64033,11 @@ var watchTemplateChecks = (dir, tsconfig, assetBase) => acquireUseRelease2(creat
|
|
|
63382
64033
|
files: files.map((file) => ({
|
|
63383
64034
|
id: file.id,
|
|
63384
64035
|
kind: file.kind,
|
|
63385
|
-
ok: file.
|
|
63386
|
-
|
|
63387
|
-
|
|
63388
|
-
|
|
63389
|
-
|
|
63390
|
-
}))
|
|
64036
|
+
ok: file.ok,
|
|
64037
|
+
...file.template === undefined ? {} : {
|
|
64038
|
+
template: file.template.template,
|
|
64039
|
+
channels: file.template.channels
|
|
64040
|
+
}
|
|
63391
64041
|
}))
|
|
63392
64042
|
},
|
|
63393
64043
|
observation: sequence,
|
|
@@ -63401,7 +64051,7 @@ var watchTemplateChecks = (dir, tsconfig, assetBase) => acquireUseRelease2(creat
|
|
|
63401
64051
|
process.stdout.write(`${status} ${observation.message}
|
|
63402
64052
|
`);
|
|
63403
64053
|
for (const problem of observation.problems) {
|
|
63404
|
-
process.stdout.write(` ${
|
|
64054
|
+
process.stdout.write(` ${formatReportedDiagnostic(problem)}
|
|
63405
64055
|
`);
|
|
63406
64056
|
}
|
|
63407
64057
|
});
|
|
@@ -63418,10 +64068,10 @@ var check5 = make28("check", {
|
|
|
63418
64068
|
tsconfig: tsconfigFlag,
|
|
63419
64069
|
assetBase: assetBaseFlag,
|
|
63420
64070
|
watch: Boolean6("watch").pipe(withDescription2("Continuously re-run checks as project files change"), withDefault4(false))
|
|
63421
|
-
}).pipe(withDescription3("
|
|
64071
|
+
}).pipe(withDescription3("Type-check and compile local TSX templates, render every fixture, and report located findings"), withExamples([
|
|
63422
64072
|
{
|
|
63423
|
-
command: "samva templates check
|
|
63424
|
-
description: "Check templates in emails/ without writing files"
|
|
64073
|
+
command: "samva templates check",
|
|
64074
|
+
description: "Check the templates in templates/ and emails/ without writing files"
|
|
63425
64075
|
},
|
|
63426
64076
|
{
|
|
63427
64077
|
command: "samva templates check --json",
|
|
@@ -63444,7 +64094,9 @@ var check5 = make28("check", {
|
|
|
63444
64094
|
description: "Stream one machine-readable result per observation"
|
|
63445
64095
|
}
|
|
63446
64096
|
]), withHandler(({ dir, json, tsconfig, watch, assetBase }) => gen2(function* () {
|
|
63447
|
-
|
|
64097
|
+
const dirValue = getOrUndefined(dir);
|
|
64098
|
+
if (dirValue !== undefined)
|
|
64099
|
+
yield* validateTemplatesDir(dirValue);
|
|
63448
64100
|
if (watch) {
|
|
63449
64101
|
if (json && !isJsonLinesRequested()) {
|
|
63450
64102
|
return yield* new CliUsageError({
|
|
@@ -63452,9 +64104,9 @@ var check5 = make28("check", {
|
|
|
63452
64104
|
message: "--watch uses --jsonl for machine output; --json remains one-shot."
|
|
63453
64105
|
});
|
|
63454
64106
|
}
|
|
63455
|
-
return yield* watchTemplateChecks(
|
|
64107
|
+
return yield* watchTemplateChecks(dirValue, tsconfig, getOrUndefined(assetBase));
|
|
63456
64108
|
}
|
|
63457
|
-
const observation = yield* observeTemplateCheck(
|
|
64109
|
+
const observation = yield* observeTemplateCheck(dirValue, tsconfig, () => buildDir(dirValue, getOrUndefined(assetBase)));
|
|
63458
64110
|
if (!observation.ok) {
|
|
63459
64111
|
if (json) {
|
|
63460
64112
|
return yield* new CliResultError({
|
|
@@ -63465,7 +64117,7 @@ var check5 = make28("check", {
|
|
|
63465
64117
|
});
|
|
63466
64118
|
}
|
|
63467
64119
|
for (const problem of observation.problems) {
|
|
63468
|
-
yield* error(
|
|
64120
|
+
yield* error(formatReportedDiagnostic(problem));
|
|
63469
64121
|
}
|
|
63470
64122
|
return yield* new SamvaCliError({ message: observation.message });
|
|
63471
64123
|
}
|
|
@@ -63477,7 +64129,7 @@ var check5 = make28("check", {
|
|
|
63477
64129
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
63478
64130
|
var writeJsonFile = (target, value) => gen2(function* () {
|
|
63479
64131
|
const fs = yield* FileSystem;
|
|
63480
|
-
yield* fs.makeDirectory(
|
|
64132
|
+
yield* fs.makeDirectory(dirname4(target), { recursive: true });
|
|
63481
64133
|
yield* fs.writeFileString(target, `${JSON.stringify(value, null, 2)}
|
|
63482
64134
|
`);
|
|
63483
64135
|
}).pipe(mapError2((cause) => new SamvaCliError({
|
|
@@ -63490,7 +64142,7 @@ var build2 = make28("build", {
|
|
|
63490
64142
|
json: jsonFlag
|
|
63491
64143
|
}).pipe(withDescription3("Build local TSX templates into a reusable JSON artifact"), withExamples([
|
|
63492
64144
|
{
|
|
63493
|
-
command: "samva templates build --
|
|
64145
|
+
command: "samva templates build --out dist/templates.json",
|
|
63494
64146
|
description: "Compile local templates for another package or deployment step"
|
|
63495
64147
|
},
|
|
63496
64148
|
{
|
|
@@ -63498,10 +64150,11 @@ var build2 = make28("build", {
|
|
|
63498
64150
|
description: "Build executable fixtures with their imported asset URLs"
|
|
63499
64151
|
}
|
|
63500
64152
|
]), withHandler(({ dir, out, json, assetBase }) => gen2(function* () {
|
|
63501
|
-
const
|
|
64153
|
+
const dirValue = getOrUndefined(dir);
|
|
64154
|
+
const built = yield* buildDir(dirValue, getOrUndefined(assetBase));
|
|
63502
64155
|
const problems = collectBuildProblems(built);
|
|
63503
64156
|
if (!isSuccessfulBuild(built)) {
|
|
63504
|
-
const message = built.files.length === 0 ?
|
|
64157
|
+
const message = built.files.length === 0 ? NO_TEMPLATES(dirValue) : `Template build failed (${problems.length} problem(s)).`;
|
|
63505
64158
|
if (json) {
|
|
63506
64159
|
return yield* new CliResultError({
|
|
63507
64160
|
code: "template_build_failed",
|
|
@@ -63515,11 +64168,11 @@ var build2 = make28("build", {
|
|
|
63515
64168
|
});
|
|
63516
64169
|
}
|
|
63517
64170
|
for (const problem of problems) {
|
|
63518
|
-
yield* error(
|
|
64171
|
+
yield* error(formatReportedDiagnostic(problem));
|
|
63519
64172
|
}
|
|
63520
64173
|
return yield* new SamvaCliError({ message });
|
|
63521
64174
|
}
|
|
63522
|
-
const target =
|
|
64175
|
+
const target = resolve14(out);
|
|
63523
64176
|
const artifact = toTemplateBuildArtifact(built);
|
|
63524
64177
|
yield* writeJsonFile(target, artifact);
|
|
63525
64178
|
const result = {
|
|
@@ -63532,7 +64185,7 @@ var build2 = make28("build", {
|
|
|
63532
64185
|
if (json) {
|
|
63533
64186
|
yield* printJson(result);
|
|
63534
64187
|
} else {
|
|
63535
|
-
yield* logInfo(`Built ${built.files.length} template file(s) with compiler
|
|
64188
|
+
yield* logInfo(`Built ${built.files.length} template file(s) with compiler ${artifact.compilerVersion} to ${target}`);
|
|
63536
64189
|
}
|
|
63537
64190
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
63538
64191
|
var listRemote = make28("list", {
|
|
@@ -63646,34 +64299,29 @@ var removeRemote = make28("remove", {
|
|
|
63646
64299
|
return yield* printJson(result);
|
|
63647
64300
|
yield* printJson(result);
|
|
63648
64301
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
63649
|
-
var exportProject = (input) =>
|
|
63650
|
-
|
|
63651
|
-
|
|
63652
|
-
|
|
63653
|
-
|
|
63654
|
-
|
|
63655
|
-
|
|
63656
|
-
out: resolve10(input.out),
|
|
63657
|
-
...input.assetBase === undefined ? {} : { assetBase: input.assetBase }
|
|
63658
|
-
});
|
|
64302
|
+
var exportProject = (input) => runToolchain({
|
|
64303
|
+
action: `Could not export templates${input.dir === undefined ? "" : ` in ${input.dir}`}`,
|
|
64304
|
+
options: {
|
|
64305
|
+
root: process.cwd(),
|
|
64306
|
+
out: resolve14(input.out),
|
|
64307
|
+
...input.dir === undefined ? {} : { dir: resolve14(input.dir) },
|
|
64308
|
+
...input.assetBase === undefined ? {} : { assetBase: input.assetBase }
|
|
63659
64309
|
},
|
|
63660
|
-
|
|
63661
|
-
message: `Could not export templates in ${input.dir}. Install @samva/markup, @samva/vite, and vite in this project: ${String(cause)}`
|
|
63662
|
-
})
|
|
64310
|
+
script: `import { exportProject } from "@samva/vite/project"; ${OPTIONS_PRELUDE} process.stdout.write(JSON.stringify(await exportProject(options)));`
|
|
63663
64311
|
});
|
|
63664
64312
|
var exportCommand = make28("export", {
|
|
63665
64313
|
dir: dirFlag,
|
|
63666
64314
|
out: Directory2("out").pipe(withDescription2("Directory to write rendered fixtures, assets, and the catalog into")),
|
|
63667
64315
|
assetBase: String8("asset-base").pipe(withDescription2("Origin the exported assets will be served from; omit to point each exported page at the export's own assets directory"), optional4),
|
|
63668
64316
|
json: jsonFlag
|
|
63669
|
-
}).pipe(withDescription3("Render every local template's fixtures to HTML, text, and assets"), withExamples([
|
|
64317
|
+
}).pipe(withDescription3("Render every local template's fixtures to HTML, text, SMS, WhatsApp files, and assets"), withExamples([
|
|
63670
64318
|
{
|
|
63671
|
-
command: "samva templates export --
|
|
64319
|
+
command: "samva templates export --out dist/email",
|
|
63672
64320
|
description: "Render fixtures for review, images resolving from the export's assets directory"
|
|
63673
64321
|
}
|
|
63674
64322
|
]), withHandler(fnUntraced2(function* ({ dir, out, assetBase, json }) {
|
|
63675
64323
|
const receipt = yield* exportProject({
|
|
63676
|
-
dir,
|
|
64324
|
+
dir: getOrUndefined(dir),
|
|
63677
64325
|
out,
|
|
63678
64326
|
assetBase: getOrUndefined(assetBase)
|
|
63679
64327
|
});
|
|
@@ -63681,7 +64329,7 @@ var exportCommand = make28("export", {
|
|
|
63681
64329
|
const result = {
|
|
63682
64330
|
action: "templates.export",
|
|
63683
64331
|
ok: errors.length === 0,
|
|
63684
|
-
out:
|
|
64332
|
+
out: resolve14(out),
|
|
63685
64333
|
assetBase: receipt.assets.base,
|
|
63686
64334
|
templates: receipt.templates.map((template) => ({
|
|
63687
64335
|
id: template.id,
|
|
@@ -63689,7 +64337,7 @@ var exportCommand = make28("export", {
|
|
|
63689
64337
|
fixtures: template.fixtures.map((fixture) => fixture.fixture)
|
|
63690
64338
|
})),
|
|
63691
64339
|
assets: receipt.assets.assets.length,
|
|
63692
|
-
diagnostics: receipt.diagnostics
|
|
64340
|
+
diagnostics: receipt.diagnostics.map((diagnostic) => reportDiagnostic(diagnostic, { file: "." }))
|
|
63693
64341
|
};
|
|
63694
64342
|
if (errors.length > 0) {
|
|
63695
64343
|
const message = `Template export found ${errors.length} error(s).`;
|
|
@@ -63714,15 +64362,27 @@ var templatesCommand = make28("templates").pipe(withDescription3("Create, author
|
|
|
63714
64362
|
description: "Clone an existing project with its repository credential helper"
|
|
63715
64363
|
},
|
|
63716
64364
|
{
|
|
63717
|
-
command: "samva templates
|
|
64365
|
+
command: "samva templates dev",
|
|
64366
|
+
description: "Start the local visual editor for templates/ and emails/"
|
|
64367
|
+
},
|
|
64368
|
+
{
|
|
64369
|
+
command: "samva templates check",
|
|
63718
64370
|
description: "Check local TSX templates without writing files"
|
|
63719
64371
|
},
|
|
64372
|
+
{
|
|
64373
|
+
command: "samva templates render welcome --fixture default",
|
|
64374
|
+
description: "Print one fixture's subject, preheader and plain-text body"
|
|
64375
|
+
},
|
|
64376
|
+
{
|
|
64377
|
+
command: "samva templates snapshot welcome --fixture default",
|
|
64378
|
+
description: "Screenshot one fixture at desktop and mobile widths, light and dark"
|
|
64379
|
+
},
|
|
63720
64380
|
{
|
|
63721
64381
|
command: "samva templates publish --commit HEAD",
|
|
63722
64382
|
description: "Publish the current clean commit, then continue with ordinary Git"
|
|
63723
64383
|
},
|
|
63724
64384
|
{
|
|
63725
|
-
command: "samva templates export --
|
|
64385
|
+
command: "samva templates export --out dist/email",
|
|
63726
64386
|
description: "Render every template's fixtures to HTML, text, and assets"
|
|
63727
64387
|
},
|
|
63728
64388
|
{
|
|
@@ -63741,7 +64401,10 @@ var templatesCommand = make28("templates").pipe(withDescription3("Create, author
|
|
|
63741
64401
|
createRemote,
|
|
63742
64402
|
updateRemote,
|
|
63743
64403
|
removeRemote,
|
|
64404
|
+
devCommand,
|
|
63744
64405
|
check5,
|
|
64406
|
+
renderCommand,
|
|
64407
|
+
snapshotCommand,
|
|
63745
64408
|
build2,
|
|
63746
64409
|
exportCommand,
|
|
63747
64410
|
typesCommand,
|