@samva/cli 0.21.0 → 0.22.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +14 -4
- package/dist/bin.mjs +847 -260
- package/package.json +9 -9
package/dist/bin.mjs
CHANGED
|
@@ -677,6 +677,7 @@ var identity = (a) => a;
|
|
|
677
677
|
var constant = (value) => () => value;
|
|
678
678
|
var constTrue = /* @__PURE__ */ constant(true);
|
|
679
679
|
var constFalse = /* @__PURE__ */ constant(false);
|
|
680
|
+
var constNull = /* @__PURE__ */ constant(null);
|
|
680
681
|
var constUndefined = /* @__PURE__ */ constant(undefined);
|
|
681
682
|
var constVoid = constUndefined;
|
|
682
683
|
function pipe(a, ...args) {
|
|
@@ -2012,6 +2013,7 @@ var getOrElse = /* @__PURE__ */ dual(2, (self, onNone) => isNone2(self) ? onNone
|
|
|
2012
2013
|
var orElse = /* @__PURE__ */ dual(2, (self, that) => isNone2(self) ? that() : self);
|
|
2013
2014
|
var fromNullishOr = (a) => a == null ? none2() : some2(a);
|
|
2014
2015
|
var fromUndefinedOr = (a) => a === undefined ? none2() : some2(a);
|
|
2016
|
+
var getOrNull = /* @__PURE__ */ getOrElse(constNull);
|
|
2015
2017
|
var getOrUndefined = /* @__PURE__ */ getOrElse(constUndefined);
|
|
2016
2018
|
var liftThrowable = (f) => (...a) => {
|
|
2017
2019
|
try {
|
|
@@ -4139,10 +4141,6 @@ var ignore = /* @__PURE__ */ dual((args) => isEffect(args[0]), (self, options) =
|
|
|
4139
4141
|
onSuccess: (_) => void_
|
|
4140
4142
|
});
|
|
4141
4143
|
});
|
|
4142
|
-
var option = (self) => match5(self, {
|
|
4143
|
-
onFailure: none2,
|
|
4144
|
-
onSuccess: some2
|
|
4145
|
-
});
|
|
4146
4144
|
var result = (self) => matchEager(self, {
|
|
4147
4145
|
onFailure: fail2,
|
|
4148
4146
|
onSuccess: succeed2
|
|
@@ -5744,10 +5742,10 @@ var flatMap3 = flatMap2;
|
|
|
5744
5742
|
var andThen2 = andThen;
|
|
5745
5743
|
var tap2 = tap;
|
|
5746
5744
|
var result2 = result;
|
|
5747
|
-
var option2 = option;
|
|
5748
5745
|
var exit2 = exit;
|
|
5749
5746
|
var map7 = map5;
|
|
5750
5747
|
var as2 = as;
|
|
5748
|
+
var asSome2 = asSome;
|
|
5751
5749
|
var asVoid2 = asVoid;
|
|
5752
5750
|
var catch_2 = catch_;
|
|
5753
5751
|
var catchTag2 = catchTag;
|
|
@@ -14278,7 +14276,7 @@ var layer12 = /* @__PURE__ */ layer.pipe(/* @__PURE__ */ provideMerge(/* @__PURE
|
|
|
14278
14276
|
// package.json
|
|
14279
14277
|
var package_default = {
|
|
14280
14278
|
name: "@samva/cli",
|
|
14281
|
-
version: "0.
|
|
14279
|
+
version: "0.22.1",
|
|
14282
14280
|
description: "Samva CLI \u2014 email and platform operations from your terminal",
|
|
14283
14281
|
keywords: [
|
|
14284
14282
|
"cli",
|
|
@@ -14321,7 +14319,7 @@ var package_default = {
|
|
|
14321
14319
|
"build:release-artifacts": "bun run scripts/build-release-artifacts.ts",
|
|
14322
14320
|
test: "vitest run --root ../.. --project cli",
|
|
14323
14321
|
"test:package": "vitest run --root ../.. --project cli packages/cli/tests/package-install.e2e.test.ts",
|
|
14324
|
-
typecheck: "tsc --noEmit && tsc --noEmit -p tests/consumer/tsconfig.json"
|
|
14322
|
+
typecheck: "tsc-rs --noEmit && tsc-rs --noEmit -p tests/consumer/tsconfig.json && tsc-rs --noEmit -p tests/consumer/tsconfig.default.json"
|
|
14325
14323
|
},
|
|
14326
14324
|
devDependencies: {
|
|
14327
14325
|
"@effect/platform-bun": "catalog:effect",
|
|
@@ -14334,16 +14332,16 @@ var package_default = {
|
|
|
14334
14332
|
"@types/node": "catalog:",
|
|
14335
14333
|
"better-auth": "catalog:",
|
|
14336
14334
|
effect: "catalog:effect",
|
|
14337
|
-
samva: "workspace:0.23.
|
|
14338
|
-
|
|
14335
|
+
samva: "workspace:0.23.1",
|
|
14336
|
+
"tsc-rs": "catalog:",
|
|
14339
14337
|
vite: "~8.3.0",
|
|
14340
14338
|
vitest: "catalog:"
|
|
14341
14339
|
},
|
|
14342
14340
|
optionalDependencies: {
|
|
14343
|
-
"@samva/cli-darwin-arm64": "workspace:0.
|
|
14344
|
-
"@samva/cli-darwin-x64": "workspace:0.
|
|
14345
|
-
"@samva/cli-linux-arm64": "workspace:0.
|
|
14346
|
-
"@samva/cli-linux-x64": "workspace:0.
|
|
14341
|
+
"@samva/cli-darwin-arm64": "workspace:0.22.1",
|
|
14342
|
+
"@samva/cli-darwin-x64": "workspace:0.22.1",
|
|
14343
|
+
"@samva/cli-linux-arm64": "workspace:0.22.1",
|
|
14344
|
+
"@samva/cli-linux-x64": "workspace:0.22.1"
|
|
14347
14345
|
},
|
|
14348
14346
|
engines: {
|
|
14349
14347
|
node: ">=18"
|
|
@@ -15841,7 +15839,7 @@ var map10 = /* @__PURE__ */ dual(2, (self, f) => {
|
|
|
15841
15839
|
var withDefault3 = /* @__PURE__ */ dual(2, (self, defaultValue) => {
|
|
15842
15840
|
return make28((provider, pathPrefix) => mapEager2(evaluateAt(self, provider, pathPrefix), (resolution) => isFailure2(resolution) ? succeed2(defaultValue) : resolution));
|
|
15843
15841
|
});
|
|
15844
|
-
var
|
|
15842
|
+
var option2 = (self) => self.pipe(map10(some2), withDefault3(none2()));
|
|
15845
15843
|
var isSourceError = (u) => isTagged(u, "SourceError");
|
|
15846
15844
|
var cursorToString = () => "<configuration>";
|
|
15847
15845
|
var mapReasons = (f) => (self) => catchCause2(self, (cause) => failCause3(fromReasons(cause.reasons.map(f))));
|
|
@@ -25566,7 +25564,7 @@ var __exportAll = (all, no_symbols) => {
|
|
|
25566
25564
|
};
|
|
25567
25565
|
|
|
25568
25566
|
// ../sdk/dist/package.js
|
|
25569
|
-
var version = "0.23.
|
|
25567
|
+
var version = "0.23.1";
|
|
25570
25568
|
|
|
25571
25569
|
// ../sdk/dist/client-attribution.js
|
|
25572
25570
|
var SDK_VERSION = version;
|
|
@@ -25909,7 +25907,7 @@ var commandTree = {
|
|
|
25909
25907
|
update: {},
|
|
25910
25908
|
remove: {}
|
|
25911
25909
|
},
|
|
25912
|
-
brands: { list: {}, get: {}, pull: {}, push: {} },
|
|
25910
|
+
brands: { list: {}, get: {}, pull: {}, push: {}, default: {}, remove: {} },
|
|
25913
25911
|
mailboxes: {
|
|
25914
25912
|
events: {},
|
|
25915
25913
|
list: {},
|
|
@@ -54599,6 +54597,8 @@ var make41 = /* @__PURE__ */ forGroup(BrandsGroup);
|
|
|
54599
54597
|
var list3 = /* @__PURE__ */ make41("brandsList");
|
|
54600
54598
|
var get9 = /* @__PURE__ */ make41("brandsGet");
|
|
54601
54599
|
var update4 = /* @__PURE__ */ make41("brandsUpdate");
|
|
54600
|
+
var remove4 = /* @__PURE__ */ make41("brandsRemove");
|
|
54601
|
+
var setDefault = /* @__PURE__ */ make41("brandsSetDefault");
|
|
54602
54602
|
|
|
54603
54603
|
// src/commands/brands.ts
|
|
54604
54604
|
var SNAPSHOT_DIR = [".samva", "brands"];
|
|
@@ -54755,11 +54755,62 @@ var push = make29("push", {
|
|
|
54755
54755
|
yield* log(`Updated brand ${updated.slug} from ${file}.`);
|
|
54756
54756
|
yield* logInfo("Published templates keep the brand they were built against until they are republished.");
|
|
54757
54757
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
54758
|
-
var
|
|
54758
|
+
var requiredSlugArgument = String10("slug").pipe(withDescription4("Brand slug"));
|
|
54759
|
+
var dryRunFlag2 = Boolean6("dry-run").pipe(withDescription2("Print the request without sending it"), withDefault5(false));
|
|
54760
|
+
var yesFlag2 = Boolean6("yes").pipe(withDescription2("Confirm without prompting (required outside a terminal)"), withDefault5(false));
|
|
54761
|
+
var makeDefault = make29("default", {
|
|
54762
|
+
slug: requiredSlugArgument,
|
|
54763
|
+
dryRun: dryRunFlag2,
|
|
54764
|
+
json: jsonFlag
|
|
54765
|
+
}).pipe(withDescription3("Make a brand the organization's default: bare samva:brand and domains without a brand resolve to it"), withExamples([
|
|
54766
|
+
{ command: "samva brands default acme" },
|
|
54767
|
+
{ command: "samva brands default acme --dry-run --json" }
|
|
54768
|
+
]), withHandler(({ slug, dryRun, json }) => gen2(function* () {
|
|
54769
|
+
if (dryRun)
|
|
54770
|
+
return yield* json ? printJson({ dryRun: true, action: "brands.default", slug }) : log(`[dry-run] Would make brand ${slug} the default.`);
|
|
54771
|
+
const client = yield* getClientProvider;
|
|
54772
|
+
const brand = yield* setDefault({ slug }).pipe(client.provide, mapError2(apiFailure(`Could not make brand ${slug} the default`)));
|
|
54773
|
+
const result = {
|
|
54774
|
+
action: "brands.default",
|
|
54775
|
+
slug: brand.slug,
|
|
54776
|
+
name: brand.name,
|
|
54777
|
+
isDefault: brand.isDefault
|
|
54778
|
+
};
|
|
54779
|
+
if (json)
|
|
54780
|
+
return yield* printJson(result);
|
|
54781
|
+
yield* log(`Brand ${brand.slug} (${brand.name}) is now the default.`);
|
|
54782
|
+
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
54783
|
+
var remove5 = make29("remove", {
|
|
54784
|
+
slug: requiredSlugArgument,
|
|
54785
|
+
dryRun: dryRunFlag2,
|
|
54786
|
+
yes: yesFlag2,
|
|
54787
|
+
json: jsonFlag
|
|
54788
|
+
}).pipe(withDescription3("Permanently delete a brand. The default brand cannot be deleted; make another brand the default first. Domains that used it fall back to the default."), withExamples([
|
|
54789
|
+
{ command: "samva brands remove promo --dry-run" },
|
|
54790
|
+
{ command: "samva brands remove promo --yes" }
|
|
54791
|
+
]), withHandler(({ slug, dryRun, yes, json }) => gen2(function* () {
|
|
54792
|
+
if (dryRun)
|
|
54793
|
+
return yield* json ? printJson({ dryRun: true, action: "brands.remove", slug }) : log(`[dry-run] Would permanently remove brand ${slug}.`);
|
|
54794
|
+
yield* confirmDestructive({
|
|
54795
|
+
yes,
|
|
54796
|
+
json,
|
|
54797
|
+
message: `Permanently remove brand ${slug}?`,
|
|
54798
|
+
nonInteractiveMessage: "Permanent brand deletion requires --yes in non-interactive mode. Preview with --dry-run."
|
|
54799
|
+
});
|
|
54800
|
+
const client = yield* getClientProvider;
|
|
54801
|
+
yield* remove4({ slug }).pipe(client.provide, mapError2(apiFailure(`Could not remove brand ${slug}`)));
|
|
54802
|
+
const result = { action: "brands.remove", slug, removed: true };
|
|
54803
|
+
if (json)
|
|
54804
|
+
return yield* printJson(result);
|
|
54805
|
+
yield* log(`Removed brand ${slug}.`);
|
|
54806
|
+
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
54807
|
+
var brandsCommand = make29("brands").pipe(withDescription3("List, snapshot, update, and delete the organization's brands (what samva:brand resolves to)"), withExamples([
|
|
54759
54808
|
{ command: "samva brands list" },
|
|
54760
54809
|
{ command: "samva brands pull", description: "Snapshot the default brand for offline builds" },
|
|
54761
|
-
{ command: "samva brands push brand.css --brand acme" }
|
|
54762
|
-
|
|
54810
|
+
{ command: "samva brands push brand.css --brand acme" },
|
|
54811
|
+
{ command: "samva brands default acme", description: "Make acme the default brand" },
|
|
54812
|
+
{ command: "samva brands remove promo --yes" }
|
|
54813
|
+
]), withSubcommands([list4, get10, pull, push, makeDefault, remove5]));
|
|
54763
54814
|
|
|
54764
54815
|
// ../sdk/dist/effect/generated/campaigns.js
|
|
54765
54816
|
var CampaignId2 = /* @__PURE__ */ String4.check(isPattern2(/* @__PURE__ */ new RegExp("^camp_[0-9a-hjkmnp-tv-z]{16,24}$", "u")).annotate({
|
|
@@ -55387,7 +55438,7 @@ var excludeTagsFlag = String9("exclude-tags").pipe(withDescription2("Contact tag
|
|
|
55387
55438
|
var contactIdsFlag = String9("contact-ids").pipe(withDescription2("Explicit contact ids to target (comma-separated or repeated)"), atLeast2(0));
|
|
55388
55439
|
var unsubscribeGroupIdFlag = String9("unsubscribe-group-id").pipe(withDescription2("Unsubscribe group id applied to every send; overrides the organization's default group"), optional4);
|
|
55389
55440
|
var pageSizeFlag = Int5("page-size").pipe(withDescription2("Recipients dispatched per batch"), optional4);
|
|
55390
|
-
var
|
|
55441
|
+
var dryRunFlag3 = Boolean6("dry-run").pipe(withDescription2("Validate inputs and print the request payload without calling the API"), withDefault5(false));
|
|
55391
55442
|
var trackOpensFlag = Literals3("track-opens", ["on", "off"]).pipe(withDescription2("Override open tracking for campaign sends; recipient opt-out wins"), optional4);
|
|
55392
55443
|
var trackClicksFlag = Literals3("track-clicks", ["on", "off"]).pipe(withDescription2("Override click tracking for campaign sends; recipient opt-out wins"), optional4);
|
|
55393
55444
|
var atFlag = String9("at").pipe(withDescription2("Absolute run start instant as ISO 8601 (defaults to now)"), optional4);
|
|
@@ -55415,7 +55466,7 @@ var create4 = make29("create", {
|
|
|
55415
55466
|
pageSize: pageSizeFlag,
|
|
55416
55467
|
trackOpens: trackOpensFlag,
|
|
55417
55468
|
trackClicks: trackClicksFlag,
|
|
55418
|
-
dryRun:
|
|
55469
|
+
dryRun: dryRunFlag3,
|
|
55419
55470
|
json: jsonFlag
|
|
55420
55471
|
}).pipe(withDescription3("Create an email campaign targeting tags or explicit contacts"), withExamples([
|
|
55421
55472
|
{
|
|
@@ -55794,7 +55845,7 @@ var runCreate = make29("create", {
|
|
|
55794
55845
|
campaignId: String10("campaignId"),
|
|
55795
55846
|
at: atFlag,
|
|
55796
55847
|
idempotencyKey: idempotencyKeyFlag,
|
|
55797
|
-
dryRun:
|
|
55848
|
+
dryRun: dryRunFlag3,
|
|
55798
55849
|
json: jsonFlag
|
|
55799
55850
|
}).pipe(withDescription3("Create a run for a campaign (starts immediately without --at)"), withExamples([
|
|
55800
55851
|
{ command: "samva campaigns runs create camp_abc123", description: "Start now" },
|
|
@@ -55907,7 +55958,7 @@ var runGet = make29("get", {
|
|
|
55907
55958
|
var runPause = make29("pause", {
|
|
55908
55959
|
campaignId: String10("campaignId"),
|
|
55909
55960
|
runId: String10("runId"),
|
|
55910
|
-
dryRun:
|
|
55961
|
+
dryRun: dryRunFlag3,
|
|
55911
55962
|
json: jsonFlag
|
|
55912
55963
|
}).pipe(withDescription3("Pause a running campaign run"), withExamples([{ command: "samva campaigns runs pause camp_abc123 crun_def456" }]), withHandler(({ campaignId, runId, dryRun, json }) => gen2(function* () {
|
|
55913
55964
|
if (dryRun)
|
|
@@ -55923,7 +55974,7 @@ var runPause = make29("pause", {
|
|
|
55923
55974
|
var runResume = make29("resume", {
|
|
55924
55975
|
campaignId: String10("campaignId"),
|
|
55925
55976
|
runId: String10("runId"),
|
|
55926
|
-
dryRun:
|
|
55977
|
+
dryRun: dryRunFlag3,
|
|
55927
55978
|
json: jsonFlag
|
|
55928
55979
|
}).pipe(withDescription3("Resume a paused campaign run"), withExamples([{ command: "samva campaigns runs resume camp_abc123 crun_def456" }]), withHandler(({ campaignId, runId, dryRun, json }) => gen2(function* () {
|
|
55929
55980
|
if (dryRun)
|
|
@@ -61003,7 +61054,7 @@ var rotateDkim = make29("rotate-dkim", {
|
|
|
61003
61054
|
yield* log("The minimum retention date does not authorize deletion. Retirement requires separate approval and verification that at least two actual former-record TTLs have elapsed.");
|
|
61004
61055
|
yield* log(`After DNS publication, advance verification: samva email domains check ${id}`);
|
|
61005
61056
|
})));
|
|
61006
|
-
var
|
|
61057
|
+
var remove6 = make29("remove", {
|
|
61007
61058
|
id: String10("id").pipe(withDescription4("Domain id to permanently remove")),
|
|
61008
61059
|
dryRun: Boolean6("dry-run").pipe(withDescription2("Print the deletion plan without calling the API"), withDefault5(false)),
|
|
61009
61060
|
yes: Boolean6("yes").pipe(withDescription2("Confirm permanent deletion (required for non-interactive use)"), withDefault5(false)),
|
|
@@ -61026,7 +61077,7 @@ var remove4 = make29("remove", {
|
|
|
61026
61077
|
return yield* printJson(data);
|
|
61027
61078
|
yield* log(`Removed domain ${id}.`);
|
|
61028
61079
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
61029
|
-
var
|
|
61080
|
+
var setDefault2 = make29("set-default", {
|
|
61030
61081
|
id: String10("id").pipe(withDescription4("Domain id to make the default")),
|
|
61031
61082
|
dryRun: Boolean6("dry-run").pipe(withDescription2("Print the planned change without calling the API"), withDefault5(false)),
|
|
61032
61083
|
json: jsonFlag
|
|
@@ -61144,7 +61195,7 @@ var customDisable = make29("disable", {
|
|
|
61144
61195
|
var customTracking = make29("custom-tracking").pipe(withDescription3("Manage a domain's custom tracking (custom open/click subdomain)"), withExamples([{ command: "samva email domains custom-tracking enable dom_abc123" }]), withSubcommands([customEnable, customStatus, customRecheck, customDisable]));
|
|
61145
61196
|
var domainsCommand = make29("domains").pipe(withDescription3("Manage email sending domains"), withExamples([
|
|
61146
61197
|
{ command: "samva email domains list", description: "List configured domains" }
|
|
61147
|
-
]), withSubcommands([list9, add2, check2, rotateDkim,
|
|
61198
|
+
]), withSubcommands([list9, add2, check2, rotateDkim, setDefault2, remove6, customTracking]));
|
|
61148
61199
|
|
|
61149
61200
|
// src/commands/email/receiving.ts
|
|
61150
61201
|
var destinationLabel = (destination) => {
|
|
@@ -61683,7 +61734,7 @@ var idempotencyKeyFlag2 = String9("idempotency-key").pipe(withDescription2("Key
|
|
|
61683
61734
|
var trackOpensFlag2 = Literals3("track-opens", ["on", "off"]).pipe(withDescription2("Override open tracking for this send; recipient opt-out still wins"), optional4);
|
|
61684
61735
|
var trackClicksFlag2 = Literals3("track-clicks", ["on", "off"]).pipe(withDescription2("Override click tracking for this send; recipient opt-out still wins"), optional4);
|
|
61685
61736
|
var attachFlag = String9("attach").pipe(withDescription2("File to attach (repeatable); small files travel inline, larger ones upload through media first"), atLeast2(0));
|
|
61686
|
-
var
|
|
61737
|
+
var dryRunFlag4 = Boolean6("dry-run").pipe(withDescription2("Validate inputs and print the request payload without calling the API"), withDefault5(false));
|
|
61687
61738
|
var bodySourceName = (input) => {
|
|
61688
61739
|
if (input.templateRefValue)
|
|
61689
61740
|
return "template";
|
|
@@ -61720,7 +61771,7 @@ var send3 = make29("send", {
|
|
|
61720
61771
|
trackOpens: trackOpensFlag2,
|
|
61721
61772
|
trackClicks: trackClicksFlag2,
|
|
61722
61773
|
attach: attachFlag,
|
|
61723
|
-
dryRun:
|
|
61774
|
+
dryRun: dryRunFlag4,
|
|
61724
61775
|
wait: Boolean6("wait").pipe(withDescription2("Wait for delivered/read or a terminal delivery failure"), withDefault5(false)),
|
|
61725
61776
|
timeout: timeoutFlag,
|
|
61726
61777
|
json: jsonFlag
|
|
@@ -62130,7 +62181,7 @@ var check3 = make29("check", {
|
|
|
62130
62181
|
["Verified at", data.verifiedAt ?? null]
|
|
62131
62182
|
]);
|
|
62132
62183
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
62133
|
-
var
|
|
62184
|
+
var setDefault3 = make29("set-default", {
|
|
62134
62185
|
id: String10("id").pipe(withDescription4("Sender id to make the default")),
|
|
62135
62186
|
dryRun: Boolean6("dry-run").pipe(withDescription2("Print the planned change without calling the API"), withDefault5(false)),
|
|
62136
62187
|
json: jsonFlag
|
|
@@ -62146,7 +62197,7 @@ var setDefault2 = make29("set-default", {
|
|
|
62146
62197
|
return yield* printJson(data);
|
|
62147
62198
|
yield* log(`Sender ${id} is now the default sender.`);
|
|
62148
62199
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
62149
|
-
var
|
|
62200
|
+
var remove7 = make29("remove", {
|
|
62150
62201
|
id: String10("id").pipe(withDescription4("Sender id to permanently remove")),
|
|
62151
62202
|
dryRun: Boolean6("dry-run").pipe(withDescription2("Print the deletion plan without calling the API"), withDefault5(false)),
|
|
62152
62203
|
yes: Boolean6("yes").pipe(withDescription2("Confirm permanent deletion (required for non-interactive use)"), withDefault5(false)),
|
|
@@ -62171,7 +62222,7 @@ var remove5 = make29("remove", {
|
|
|
62171
62222
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
62172
62223
|
var sendersCommand = make29("senders").pipe(withDescription3("Manage sender addresses"), withExamples([
|
|
62173
62224
|
{ command: "samva email senders list", description: "List sender addresses" }
|
|
62174
|
-
]), withSubcommands([list12, add3, check3,
|
|
62225
|
+
]), withSubcommands([list12, add3, check3, setDefault3, remove7]));
|
|
62175
62226
|
|
|
62176
62227
|
// src/commands/email/tracking.ts
|
|
62177
62228
|
var toggle = (name, description) => Literals3(name, ["on", "off"]).pipe(withDescription2(description), optional4);
|
|
@@ -64012,7 +64063,7 @@ __export(exports_mailboxes, {
|
|
|
64012
64063
|
mailboxes_exports: () => mailboxes_exports2,
|
|
64013
64064
|
pause: () => pause,
|
|
64014
64065
|
releaseMessage: () => releaseMessage,
|
|
64015
|
-
remove: () =>
|
|
64066
|
+
remove: () => remove8,
|
|
64016
64067
|
removeEndpoint: () => removeEndpoint,
|
|
64017
64068
|
removeThreadLabels: () => removeThreadLabels,
|
|
64018
64069
|
reply: () => reply,
|
|
@@ -67061,7 +67112,7 @@ var mailboxes_exports2 = /* @__PURE__ */ __exportAll({
|
|
|
67061
67112
|
listThreads: () => listThreads,
|
|
67062
67113
|
pause: () => pause,
|
|
67063
67114
|
releaseMessage: () => releaseMessage,
|
|
67064
|
-
remove: () =>
|
|
67115
|
+
remove: () => remove8,
|
|
67065
67116
|
removeEndpoint: () => removeEndpoint,
|
|
67066
67117
|
removeThreadLabels: () => removeThreadLabels,
|
|
67067
67118
|
reply: () => reply,
|
|
@@ -67085,7 +67136,7 @@ var list16 = /* @__PURE__ */ make50("mailboxesList");
|
|
|
67085
67136
|
var create6 = /* @__PURE__ */ make50("mailboxesCreate");
|
|
67086
67137
|
var get19 = /* @__PURE__ */ make50("mailboxesGet");
|
|
67087
67138
|
var update8 = /* @__PURE__ */ make50("mailboxesUpdate");
|
|
67088
|
-
var
|
|
67139
|
+
var remove8 = /* @__PURE__ */ make50("mailboxesRemove");
|
|
67089
67140
|
var createEndpoint = /* @__PURE__ */ make50("mailboxesCreateEndpoint");
|
|
67090
67141
|
var updateEndpoint = /* @__PURE__ */ make50("mailboxesUpdateEndpoint");
|
|
67091
67142
|
var removeEndpoint = /* @__PURE__ */ make50("mailboxesRemoveEndpoint");
|
|
@@ -67253,7 +67304,7 @@ var reconnectNotice = (output, reconnect) => {
|
|
|
67253
67304
|
};
|
|
67254
67305
|
var tailEvents = (options) => gen2(function* () {
|
|
67255
67306
|
const provider = yield* getClientProvider;
|
|
67256
|
-
const override = yield*
|
|
67307
|
+
const override = yield* option2(String5("SAMVA_EVENTS_URL"));
|
|
67257
67308
|
const eventsUrl = getOrUndefined(override);
|
|
67258
67309
|
yield* untilInterrupted((interrupted) => provider.provide(events3({
|
|
67259
67310
|
cursor: options.cursor,
|
|
@@ -68747,7 +68798,7 @@ var list17 = /* @__PURE__ */ make51("journeysList");
|
|
|
68747
68798
|
var create7 = /* @__PURE__ */ make51("journeysCreate");
|
|
68748
68799
|
var get20 = /* @__PURE__ */ make51("journeysGet");
|
|
68749
68800
|
var update9 = /* @__PURE__ */ make51("journeysUpdate");
|
|
68750
|
-
var
|
|
68801
|
+
var remove9 = /* @__PURE__ */ make51("journeysRemove");
|
|
68751
68802
|
var replaceDraft = /* @__PURE__ */ make51("journeysReplaceDraft");
|
|
68752
68803
|
var publish3 = /* @__PURE__ */ make51("journeysPublish");
|
|
68753
68804
|
var pause2 = /* @__PURE__ */ make51("journeysPause");
|
|
@@ -68974,7 +69025,7 @@ var destructive = (name, description, warning, run, failure) => make29(name, {
|
|
|
68974
69025
|
]);
|
|
68975
69026
|
}).pipe(quietWhenJson(json))));
|
|
68976
69027
|
var archive4 = destructive("archive", "Archive a journey and exit its active runs", "Archive and exit every active run of", (id) => archive3({ id }), "Could not archive journey");
|
|
68977
|
-
var
|
|
69028
|
+
var remove10 = destructive("delete", "Delete a never-published or archived journey with its versions and runs", "Permanently delete", (id) => remove9({ id }), "Could not delete journey");
|
|
68978
69029
|
var getVersion3 = make29("version", {
|
|
68979
69030
|
id: idArgument2,
|
|
68980
69031
|
version: Int6("version").pipe(withDescription4("Published version number")),
|
|
@@ -69101,7 +69152,7 @@ var journeysCommand = make29("journeys").pipe(withDescription3("Create, publish,
|
|
|
69101
69152
|
pause3,
|
|
69102
69153
|
resume3,
|
|
69103
69154
|
archive4,
|
|
69104
|
-
|
|
69155
|
+
remove10,
|
|
69105
69156
|
getVersion3,
|
|
69106
69157
|
stats2,
|
|
69107
69158
|
runs2
|
|
@@ -72743,7 +72794,7 @@ var actionDecision = (verb) => make29(verb, {
|
|
|
72743
72794
|
})).pipe(client.provide, mapError2((e) => mailboxApiError(`Could not ${verb} action`, e, { personOnly: verb })));
|
|
72744
72795
|
yield* json ? printJson(result) : printAction(result);
|
|
72745
72796
|
})));
|
|
72746
|
-
var
|
|
72797
|
+
var remove11 = make29("remove", {
|
|
72747
72798
|
id: String10("mailbox-id").pipe(withSchema3(MailboxId)),
|
|
72748
72799
|
dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
|
|
72749
72800
|
yes: Boolean6("yes").pipe(withDefault5(false)),
|
|
@@ -72761,7 +72812,7 @@ var remove9 = make29("remove", {
|
|
|
72761
72812
|
nonInteractiveMessage: "Permanent mailbox deletion requires --yes in non-interactive mode. Preview with --dry-run."
|
|
72762
72813
|
});
|
|
72763
72814
|
const client = yield* getClientProvider;
|
|
72764
|
-
const result = yield*
|
|
72815
|
+
const result = yield* remove8({ id }).pipe(client.provide, mapError2((e) => mailboxApiError("Could not remove mailbox", e)));
|
|
72765
72816
|
if (json)
|
|
72766
72817
|
return yield* printJson(result);
|
|
72767
72818
|
yield* log(`Removed mailbox ${id}. The messages it received stay with the organization.`);
|
|
@@ -73052,7 +73103,7 @@ var mailboxesCommand = make29("mailboxes").pipe(withDescription3("Mailbox readin
|
|
|
73052
73103
|
actionCancel,
|
|
73053
73104
|
actionRetry
|
|
73054
73105
|
])),
|
|
73055
|
-
|
|
73106
|
+
remove11,
|
|
73056
73107
|
threads,
|
|
73057
73108
|
read2,
|
|
73058
73109
|
send7,
|
|
@@ -73283,7 +73334,7 @@ var list20 = /* @__PURE__ */ make52("namespacesList");
|
|
|
73283
73334
|
var create10 = /* @__PURE__ */ make52("namespacesCreate");
|
|
73284
73335
|
var get23 = /* @__PURE__ */ make52("namespacesGet");
|
|
73285
73336
|
var update11 = /* @__PURE__ */ make52("namespacesUpdate");
|
|
73286
|
-
var
|
|
73337
|
+
var remove12 = /* @__PURE__ */ make52("namespacesRemove");
|
|
73287
73338
|
var assignResource = /* @__PURE__ */ make52("namespacesAssignResource");
|
|
73288
73339
|
var removeResource = /* @__PURE__ */ make52("namespacesRemoveResource");
|
|
73289
73340
|
var getUsage2 = /* @__PURE__ */ make52("namespacesGetUsage");
|
|
@@ -73291,7 +73342,7 @@ var getUsage2 = /* @__PURE__ */ make52("namespacesGetUsage");
|
|
|
73291
73342
|
// src/commands/namespaces.ts
|
|
73292
73343
|
var idArgument3 = String10("id").pipe(withDescription4("Namespace id (ns_...)"));
|
|
73293
73344
|
var optionalString2 = (name, description) => String9(name).pipe(withDescription2(description), optional4);
|
|
73294
|
-
var
|
|
73345
|
+
var dryRunFlag5 = Boolean6("dry-run").pipe(withDescription2("Print the planned change without calling the API"), withDefault5(false));
|
|
73295
73346
|
var RESOURCE_FLAGS = ["domain", "sender", "contact", "template"];
|
|
73296
73347
|
var resourceFlags = {
|
|
73297
73348
|
domain: optionalString2("domain", "Domain id (dom_...)"),
|
|
@@ -73381,7 +73432,7 @@ var list21 = make29("list", {
|
|
|
73381
73432
|
var create11 = make29("create", {
|
|
73382
73433
|
name: String10("name").pipe(withDescription4("Namespace name")),
|
|
73383
73434
|
metadata: String9("metadata").pipe(withDescription2("Your own label, key=value (repeatable); Samva stores and never reads it"), atLeast2(0)),
|
|
73384
|
-
dryRun:
|
|
73435
|
+
dryRun: dryRunFlag5,
|
|
73385
73436
|
json: jsonFlag
|
|
73386
73437
|
}).pipe(withDescription3("Create a namespace, a sub-tenant for one of your customers"), withExamples([
|
|
73387
73438
|
{ command: "samva namespaces create Acme --metadata customerId=cus_123" },
|
|
@@ -73420,7 +73471,7 @@ var update12 = make29("update", {
|
|
|
73420
73471
|
name: optionalString2("name", "New name"),
|
|
73421
73472
|
metadata: String9("metadata").pipe(withDescription2("Set a metadata label, key=value (repeatable); other keys are kept"), atLeast2(0)),
|
|
73422
73473
|
unsetMetadata: String9("unset-metadata").pipe(withDescription2("Delete a metadata key (repeatable)"), atLeast2(0)),
|
|
73423
|
-
dryRun:
|
|
73474
|
+
dryRun: dryRunFlag5,
|
|
73424
73475
|
json: jsonFlag
|
|
73425
73476
|
}).pipe(withDescription3("Rename a namespace or change its metadata"), withExamples([
|
|
73426
73477
|
{ command: "samva namespaces update ns_7q2xk9mvt4znw8rh --name Acme --metadata plan=pro" },
|
|
@@ -73467,9 +73518,9 @@ var update12 = make29("update", {
|
|
|
73467
73518
|
["Updated", updated.updatedAt]
|
|
73468
73519
|
]);
|
|
73469
73520
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
73470
|
-
var
|
|
73521
|
+
var remove13 = make29("delete", {
|
|
73471
73522
|
id: idArgument3,
|
|
73472
|
-
dryRun:
|
|
73523
|
+
dryRun: dryRunFlag5,
|
|
73473
73524
|
yes: Boolean6("yes").pipe(withDefault5(false)),
|
|
73474
73525
|
json: jsonFlag
|
|
73475
73526
|
}).pipe(withDescription3("Delete an empty namespace; one that still holds anything is refused with a count of what remains"), withExamples([
|
|
@@ -73485,7 +73536,7 @@ var remove11 = make29("delete", {
|
|
|
73485
73536
|
nonInteractiveMessage: "Namespace deletion requires --yes in non-interactive mode. Preview with --dry-run."
|
|
73486
73537
|
});
|
|
73487
73538
|
const client = yield* getClientProvider;
|
|
73488
|
-
const result = yield*
|
|
73539
|
+
const result = yield* remove12({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not delete namespace", error)));
|
|
73489
73540
|
if (json)
|
|
73490
73541
|
return yield* printJson(result);
|
|
73491
73542
|
yield* log(`Deleted namespace ${id}.`);
|
|
@@ -73493,7 +73544,7 @@ var remove11 = make29("delete", {
|
|
|
73493
73544
|
var assign2 = make29("assign", {
|
|
73494
73545
|
id: idArgument3,
|
|
73495
73546
|
...resourceFlags,
|
|
73496
|
-
dryRun:
|
|
73547
|
+
dryRun: dryRunFlag5,
|
|
73497
73548
|
json: jsonFlag
|
|
73498
73549
|
}).pipe(withDescription3("Move a domain, sender, contact, or template into a namespace; pass exactly one resource flag"), withExamples([
|
|
73499
73550
|
{ command: "samva namespaces assign ns_7q2xk9mvt4znw8rh --domain dom_xyz789" },
|
|
@@ -73523,7 +73574,7 @@ var assign2 = make29("assign", {
|
|
|
73523
73574
|
var unassign = make29("unassign", {
|
|
73524
73575
|
id: idArgument3,
|
|
73525
73576
|
...resourceFlags,
|
|
73526
|
-
dryRun:
|
|
73577
|
+
dryRun: dryRunFlag5,
|
|
73527
73578
|
json: jsonFlag
|
|
73528
73579
|
}).pipe(withDescription3("Return a domain, sender, contact, or template to organization level; pass exactly one resource flag"), withExamples([
|
|
73529
73580
|
{ command: "samva namespaces unassign ns_7q2xk9mvt4znw8rh --domain dom_xyz789" }
|
|
@@ -73571,7 +73622,7 @@ var usage3 = make29("usage", {
|
|
|
73571
73622
|
["Total", data.totalMessages]
|
|
73572
73623
|
]);
|
|
73573
73624
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
73574
|
-
var namespacesCommand = make29("namespaces").pipe(withDescription3("Manage namespaces, the sub-tenants of your organization"), withExamples([{ command: "samva namespaces list --json" }]), withSubcommands([list21, create11, get24, update12,
|
|
73625
|
+
var namespacesCommand = make29("namespaces").pipe(withDescription3("Manage namespaces, the sub-tenants of your organization"), withExamples([{ command: "samva namespaces list --json" }]), withSubcommands([list21, create11, get24, update12, remove13, assign2, unassign, usage3]));
|
|
73575
73626
|
|
|
73576
73627
|
// ../sdk/dist/effect/generated/whoami.js
|
|
73577
73628
|
var WhoamiUser = /* @__PURE__ */ Struct({
|
|
@@ -73912,7 +73963,7 @@ var use2 = make29("use", { name: String10("name") }).pipe(withDescription3("Sele
|
|
|
73912
73963
|
yield* writeConfig({ ...config, activeProfile: name });
|
|
73913
73964
|
yield* printResult({ action: "profile.use", name }, `Active profile set to ${name}.`);
|
|
73914
73965
|
})));
|
|
73915
|
-
var
|
|
73966
|
+
var remove14 = make29("delete", {
|
|
73916
73967
|
name: String10("name"),
|
|
73917
73968
|
yes: Boolean6("yes").pipe(withDefault5(false))
|
|
73918
73969
|
}).pipe(withDescription3("Delete a profile and its OS-keyring credential"), withHandler(fnUntraced2(function* ({ name, yes }) {
|
|
@@ -73937,7 +73988,7 @@ var remove12 = make29("delete", {
|
|
|
73937
73988
|
yield* (yield* Service4).clear(name);
|
|
73938
73989
|
yield* printResult({ action: "profile.delete", name }, `Deleted profile ${name}.`);
|
|
73939
73990
|
})));
|
|
73940
|
-
var profileCommand = make29("profile").pipe(withDescription3("Manage user-level credential identity and organization contexts"), withSubcommands([list23, show, create12, use2,
|
|
73991
|
+
var profileCommand = make29("profile").pipe(withDescription3("Manage user-level credential identity and organization contexts"), withSubcommands([list23, show, create12, use2, remove14]));
|
|
73941
73992
|
|
|
73942
73993
|
// ../sdk/dist/effect/generated/scheduled-messages.js
|
|
73943
73994
|
var ScheduledMessageId2 = /* @__PURE__ */ String4.check(isPattern2(/* @__PURE__ */ new RegExp("^sched_[0-9a-hjkmnp-tv-z]{16,24}$", "u")).annotate({
|
|
@@ -74194,7 +74245,7 @@ var atFlag2 = String9("at").pipe(withDescription2("Absolute send instant as an I
|
|
|
74194
74245
|
var timezoneFlag = String9("timezone").pipe(withDescription2("IANA timezone for the schedule, e.g. America/New_York"), optional4);
|
|
74195
74246
|
var idempotencyKeyFlag3 = String9("idempotency-key").pipe(withDescription2("Idempotency key so retries do not schedule duplicates"), optional4);
|
|
74196
74247
|
var referenceIdFlag = String9("reference-id").pipe(withDescription2("Your own reference id to correlate this schedule"), optional4);
|
|
74197
|
-
var
|
|
74248
|
+
var dryRunFlag6 = Boolean6("dry-run").pipe(withDescription2("Validate inputs and print the request payload without calling the API"), withDefault5(false));
|
|
74198
74249
|
var trackOpensFlag3 = Literals3("track-opens", ["on", "off"]).pipe(withDescription2("Override open tracking for this scheduled send; recipient opt-out wins"), optional4);
|
|
74199
74250
|
var trackClicksFlag3 = Literals3("track-clicks", ["on", "off"]).pipe(withDescription2("Override click tracking for this scheduled send; recipient opt-out wins"), optional4);
|
|
74200
74251
|
var statusFlag2 = Literals3("status", SCHEDULED_STATUSES).pipe(withDescription2("Filter by status"), optional4);
|
|
@@ -74219,7 +74270,7 @@ var create14 = make29("create", {
|
|
|
74219
74270
|
referenceId: referenceIdFlag,
|
|
74220
74271
|
trackOpens: trackOpensFlag3,
|
|
74221
74272
|
trackClicks: trackClicksFlag3,
|
|
74222
|
-
dryRun:
|
|
74273
|
+
dryRun: dryRunFlag6,
|
|
74223
74274
|
json: jsonFlag
|
|
74224
74275
|
}).pipe(withDescription3("Schedule an email to send at a future time"), withExamples([
|
|
74225
74276
|
{
|
|
@@ -74598,7 +74649,7 @@ var subscriptionsCommand = make29("subscriptions").pipe(withDescription3("Reques
|
|
|
74598
74649
|
// src/commands/templates.ts
|
|
74599
74650
|
import { constants as constants2 } from "fs";
|
|
74600
74651
|
import { access as access3, stat as stat5 } from "fs/promises";
|
|
74601
|
-
import { dirname as dirname5, resolve as
|
|
74652
|
+
import { basename as basename3, dirname as dirname5, resolve as resolve17 } from "path";
|
|
74602
74653
|
import { pathToFileURL as pathToFileURL5 } from "url";
|
|
74603
74654
|
|
|
74604
74655
|
// ../sdk/dist/effect/generated/templates.js
|
|
@@ -76862,7 +76913,7 @@ var create15 = /* @__PURE__ */ make54("templatesCreate");
|
|
|
76862
76913
|
var createFromWebsite = /* @__PURE__ */ make54("templatesCreateFromWebsite");
|
|
76863
76914
|
var addEntry = /* @__PURE__ */ make54("templatesAddEntry");
|
|
76864
76915
|
var getById = /* @__PURE__ */ make54("templatesGetById");
|
|
76865
|
-
var
|
|
76916
|
+
var remove15 = /* @__PURE__ */ make54("templatesRemove");
|
|
76866
76917
|
var update13 = /* @__PURE__ */ make54("templatesUpdate");
|
|
76867
76918
|
var openWorkspace = /* @__PURE__ */ make54("templatesOpenWorkspace");
|
|
76868
76919
|
var getGitRepository = /* @__PURE__ */ make54("templatesGetGitRepository");
|
|
@@ -76886,6 +76937,146 @@ var offlineFlag = Boolean6("offline").pipe(withDescription2("Use the cached bran
|
|
|
76886
76937
|
|
|
76887
76938
|
// src/commands/templates/toolchain.ts
|
|
76888
76939
|
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
76940
|
+
// ../../node_modules/.bun/@samva+markup@0.17.3+a19bcd7db259aaf7/node_modules/@samva/markup/package.json
|
|
76941
|
+
var package_default2 = {
|
|
76942
|
+
name: "@samva/markup",
|
|
76943
|
+
version: "0.17.3",
|
|
76944
|
+
description: "Type-safe authoring and compilation primitives for Samva templates",
|
|
76945
|
+
keywords: [
|
|
76946
|
+
"email",
|
|
76947
|
+
"jsx",
|
|
76948
|
+
"samva",
|
|
76949
|
+
"sml",
|
|
76950
|
+
"sms",
|
|
76951
|
+
"templates",
|
|
76952
|
+
"tsx",
|
|
76953
|
+
"whatsapp"
|
|
76954
|
+
],
|
|
76955
|
+
homepage: "https://samva.dev",
|
|
76956
|
+
bugs: {
|
|
76957
|
+
url: "https://github.com/SamvaHQ/SML/issues"
|
|
76958
|
+
},
|
|
76959
|
+
license: "MIT",
|
|
76960
|
+
author: "Arya Labs, Inc.",
|
|
76961
|
+
repository: {
|
|
76962
|
+
type: "git",
|
|
76963
|
+
url: "https://github.com/SamvaHQ/SML.git",
|
|
76964
|
+
directory: "packages/markup"
|
|
76965
|
+
},
|
|
76966
|
+
files: [
|
|
76967
|
+
"dist",
|
|
76968
|
+
"samva-brand.d.ts",
|
|
76969
|
+
"generated",
|
|
76970
|
+
"skills",
|
|
76971
|
+
"package.json",
|
|
76972
|
+
"README.md",
|
|
76973
|
+
"CHANGELOG.md",
|
|
76974
|
+
"AGENTS.md",
|
|
76975
|
+
"LICENSE"
|
|
76976
|
+
],
|
|
76977
|
+
type: "module",
|
|
76978
|
+
sideEffects: false,
|
|
76979
|
+
exports: {
|
|
76980
|
+
".": {
|
|
76981
|
+
types: "./dist/index.d.ts",
|
|
76982
|
+
import: "./dist/index.js"
|
|
76983
|
+
},
|
|
76984
|
+
"./email": {
|
|
76985
|
+
types: "./dist/email.d.ts",
|
|
76986
|
+
import: "./dist/email.js"
|
|
76987
|
+
},
|
|
76988
|
+
"./email/jsx-runtime": {
|
|
76989
|
+
types: "./dist/email/jsx-runtime.d.ts",
|
|
76990
|
+
import: "./dist/email/jsx-runtime.js"
|
|
76991
|
+
},
|
|
76992
|
+
"./email/jsx-dev-runtime": {
|
|
76993
|
+
types: "./dist/email/jsx-dev-runtime.d.ts",
|
|
76994
|
+
import: "./dist/email/jsx-dev-runtime.js"
|
|
76995
|
+
},
|
|
76996
|
+
"./fmt": {
|
|
76997
|
+
types: "./dist/fmt.d.ts",
|
|
76998
|
+
import: "./dist/fmt.js"
|
|
76999
|
+
},
|
|
77000
|
+
"./sms": {
|
|
77001
|
+
types: "./dist/sms.d.ts",
|
|
77002
|
+
import: "./dist/sms.js"
|
|
77003
|
+
},
|
|
77004
|
+
"./whatsapp": {
|
|
77005
|
+
types: "./dist/whatsapp.d.ts",
|
|
77006
|
+
import: "./dist/whatsapp.js"
|
|
77007
|
+
},
|
|
77008
|
+
"./input-schema": {
|
|
77009
|
+
types: "./dist/input-schema.d.ts",
|
|
77010
|
+
import: "./dist/input-schema.js"
|
|
77011
|
+
},
|
|
77012
|
+
"./compiler": {
|
|
77013
|
+
types: "./dist/compiler.d.ts",
|
|
77014
|
+
import: "./dist/compiler.js"
|
|
77015
|
+
},
|
|
77016
|
+
"./compatibility": {
|
|
77017
|
+
types: "./dist/compatibility.d.ts",
|
|
77018
|
+
import: "./dist/compatibility.js"
|
|
77019
|
+
},
|
|
77020
|
+
"./diagnostics": {
|
|
77021
|
+
types: "./dist/diagnostics.d.ts",
|
|
77022
|
+
import: "./dist/diagnostics.js"
|
|
77023
|
+
},
|
|
77024
|
+
"./render": {
|
|
77025
|
+
types: "./dist/render.d.ts",
|
|
77026
|
+
import: "./dist/render.js"
|
|
77027
|
+
},
|
|
77028
|
+
"./edit": {
|
|
77029
|
+
types: "./dist/edit.d.ts",
|
|
77030
|
+
import: "./dist/edit.js"
|
|
77031
|
+
},
|
|
77032
|
+
"./brand": {
|
|
77033
|
+
types: "./dist/brand.d.ts",
|
|
77034
|
+
import: "./dist/brand.js"
|
|
77035
|
+
},
|
|
77036
|
+
"./samva-brand": {
|
|
77037
|
+
types: "./samva-brand.d.ts"
|
|
77038
|
+
},
|
|
77039
|
+
"./contract.json": "./generated/contract.json",
|
|
77040
|
+
"./reference.md": "./generated/reference.md",
|
|
77041
|
+
"./package.json": "./package.json"
|
|
77042
|
+
},
|
|
77043
|
+
publishConfig: {
|
|
77044
|
+
access: "public"
|
|
77045
|
+
},
|
|
77046
|
+
scripts: {
|
|
77047
|
+
build: "tsdown",
|
|
77048
|
+
prepack: "bun run build",
|
|
77049
|
+
"corpus:render": "bun run scripts/render-compatibility-corpus.ts",
|
|
77050
|
+
"codegen:tailwind": "bun run scripts/codegen-tailwind.ts && oxfmt src/email/tailwind-stylesheets.gen.ts",
|
|
77051
|
+
"codegen:contract": "bun run scripts/generate-contract.ts",
|
|
77052
|
+
test: "vitest run",
|
|
77053
|
+
typecheck: "tsc --noEmit && tsc --noEmit -p tests/consumer/tsconfig.json"
|
|
77054
|
+
},
|
|
77055
|
+
dependencies: {
|
|
77056
|
+
"@babel/parser": "^8.0.4",
|
|
77057
|
+
"@cfworker/json-schema": "4.1.1",
|
|
77058
|
+
"@standard-schema/spec": "1.1.0",
|
|
77059
|
+
"better-result": "3.0.1",
|
|
77060
|
+
caniemail: "2.0.2",
|
|
77061
|
+
"css-tree": "3.2.1",
|
|
77062
|
+
tailwindcss: "^4.3.3"
|
|
77063
|
+
},
|
|
77064
|
+
devDependencies: {
|
|
77065
|
+
"@css-inline/css-inline-wasm": "0.15.0",
|
|
77066
|
+
"@effect/vitest": "4.0.0",
|
|
77067
|
+
"@types/css-tree": "3.2.0",
|
|
77068
|
+
"@types/node": "^26.6.2",
|
|
77069
|
+
effect: "4.0.0",
|
|
77070
|
+
tsdown: "^0.22.13",
|
|
77071
|
+
typescript: "^7.0.2",
|
|
77072
|
+
vitest: "^5.0.3",
|
|
77073
|
+
zod: "4.6.5"
|
|
77074
|
+
}
|
|
77075
|
+
};
|
|
77076
|
+
|
|
77077
|
+
// src/lib/authoring-release.ts
|
|
77078
|
+
var minorOf = (version) => version.split(".").slice(0, 2).join(".");
|
|
77079
|
+
var AUTHORING_MINOR = minorOf(package_default2.version);
|
|
76889
77080
|
|
|
76890
77081
|
// src/commands/templates/brand-resolver.ts
|
|
76891
77082
|
var brand_resolver_default = `import { execFile } from "node:child_process";
|
|
@@ -77316,6 +77507,30 @@ export const createBrandResolver = (options: {
|
|
|
77316
77507
|
|
|
77317
77508
|
// src/commands/templates/toolchain.ts
|
|
77318
77509
|
var TOOLCHAIN_INSTALL = "npm install --save-dev @samva/markup @samva/vite vite";
|
|
77510
|
+
var AUTHORING_PACKAGES = ["@samva/markup", "@samva/vite"];
|
|
77511
|
+
var toolchainSkew = (installed, action) => {
|
|
77512
|
+
for (const name of AUTHORING_PACKAGES) {
|
|
77513
|
+
const version = installed[name];
|
|
77514
|
+
if (version === undefined || minorOf(version) === AUTHORING_MINOR)
|
|
77515
|
+
continue;
|
|
77516
|
+
const behind = Number(minorOf(version).split(".")[1]) < Number(AUTHORING_MINOR.split(".")[1]);
|
|
77517
|
+
return behind ? `${action}: this project has ${name} ${version}, but this CLI drives ${AUTHORING_MINOR}.x. Update the project with \`npm install --save-dev @samva/markup@~${AUTHORING_MINOR}.0 @samva/vite@~${AUTHORING_MINOR}.0\`.` : `${action}: this project has ${name} ${version}, which is newer than the ${AUTHORING_MINOR}.x this CLI drives. Update the CLI with \`npm install -g @samva/cli@latest\`.`;
|
|
77518
|
+
}
|
|
77519
|
+
return;
|
|
77520
|
+
};
|
|
77521
|
+
var installedAuthoring = async (root) => Object.fromEntries(await Promise.all(AUTHORING_PACKAGES.map(async (name) => {
|
|
77522
|
+
const manifest = await Promise.resolve().then(async () => await Bun.file(Bun.resolveSync(`${name}/package.json`, root)).json()).catch(() => {
|
|
77523
|
+
return;
|
|
77524
|
+
});
|
|
77525
|
+
return [name, manifest?.version];
|
|
77526
|
+
})));
|
|
77527
|
+
var requireCompatibleToolchain = (action) => tryPromise2({
|
|
77528
|
+
try: () => installedAuthoring(process.cwd()),
|
|
77529
|
+
catch: () => new SamvaCliError({ message: `${action}: could not read the project's installed packages.` })
|
|
77530
|
+
}).pipe(flatMap3((installed) => {
|
|
77531
|
+
const skew = toolchainSkew(installed, action);
|
|
77532
|
+
return skew === undefined ? void_3 : fail6(new SamvaCliError({ message: skew }));
|
|
77533
|
+
}));
|
|
77319
77534
|
var MISSING_MODULE = /Cannot find (?:package|module) '([^']+)'/;
|
|
77320
77535
|
var toolchainFailure = (stderr, action) => {
|
|
77321
77536
|
const missing = MISSING_MODULE.exec(stderr)?.[1];
|
|
@@ -77327,28 +77542,42 @@ var toolchainFailure = (stderr, action) => {
|
|
|
77327
77542
|
}
|
|
77328
77543
|
return `${action}: ${stderr.trim() || "the toolchain process failed."}`;
|
|
77329
77544
|
};
|
|
77545
|
+
var invocationEnv = gen2(function* () {
|
|
77546
|
+
const profile = getOrUndefined(yield* Profile);
|
|
77547
|
+
const org = getOrUndefined(yield* Org);
|
|
77548
|
+
const apiUrl = getOrUndefined(yield* ApiUrl);
|
|
77549
|
+
return {
|
|
77550
|
+
...profile === undefined ? {} : { SAMVA_PROFILE: profile },
|
|
77551
|
+
...org === undefined ? {} : { SAMVA_ORG: org },
|
|
77552
|
+
...apiUrl === undefined ? {} : { SAMVA_API_URL: apiUrl }
|
|
77553
|
+
};
|
|
77554
|
+
});
|
|
77330
77555
|
var NODE_MISSING = "Install Node.js 22+ to run template authoring commands.";
|
|
77331
|
-
var runToolchain = (input) =>
|
|
77332
|
-
|
|
77333
|
-
|
|
77334
|
-
|
|
77335
|
-
|
|
77336
|
-
|
|
77337
|
-
|
|
77338
|
-
|
|
77339
|
-
|
|
77340
|
-
|
|
77341
|
-
|
|
77342
|
-
|
|
77343
|
-
|
|
77344
|
-
|
|
77345
|
-
|
|
77346
|
-
|
|
77347
|
-
|
|
77348
|
-
|
|
77349
|
-
|
|
77350
|
-
|
|
77351
|
-
|
|
77556
|
+
var runToolchain = (input) => gen2(function* () {
|
|
77557
|
+
yield* requireCompatibleToolchain(input.action);
|
|
77558
|
+
const selection = yield* invocationEnv;
|
|
77559
|
+
return yield* tryPromise2({
|
|
77560
|
+
try: async () => {
|
|
77561
|
+
const child = Bun.spawn(["node", "--input-type=module", "--eval", input.script], {
|
|
77562
|
+
cwd: process.cwd(),
|
|
77563
|
+
env: { ...Bun.env, ...selection, SAMVA_TOOLCHAIN_INPUT: JSON.stringify(input.options) },
|
|
77564
|
+
stdout: "pipe",
|
|
77565
|
+
stderr: "pipe"
|
|
77566
|
+
});
|
|
77567
|
+
const [stdout, stderr, exitCode] = await Promise.all([
|
|
77568
|
+
new Response(child.stdout).text(),
|
|
77569
|
+
new Response(child.stderr).text(),
|
|
77570
|
+
child.exited
|
|
77571
|
+
]);
|
|
77572
|
+
if (exitCode !== 0) {
|
|
77573
|
+
return Promise.reject(new SamvaCliError({ message: toolchainFailure(stderr, input.action) }));
|
|
77574
|
+
}
|
|
77575
|
+
return JSON.parse(stdout);
|
|
77576
|
+
},
|
|
77577
|
+
catch: (cause) => cause instanceof SamvaCliError ? cause : new SamvaCliError({
|
|
77578
|
+
message: `${input.action}: ${NODE_MISSING} ${String(cause)}`
|
|
77579
|
+
})
|
|
77580
|
+
});
|
|
77352
77581
|
});
|
|
77353
77582
|
var OPTIONS_PRELUDE = "const options = JSON.parse(process.env.SAMVA_TOOLCHAIN_INPUT);";
|
|
77354
77583
|
var brandResolverPrelude = () => `${new Bun.Transpiler({ loader: "ts" }).transformSync(brand_resolver_default)}
|
|
@@ -77539,8 +77768,24 @@ var buildDir = (dir, assetBase) => runToolchain({
|
|
|
77539
77768
|
${brandResolverPrelude()} process.stdout.write(JSON.stringify(await buildTemplates(options)));`
|
|
77540
77769
|
});
|
|
77541
77770
|
|
|
77542
|
-
// src/commands/templates/
|
|
77771
|
+
// src/commands/templates/local-export.ts
|
|
77543
77772
|
import { resolve as resolve10 } from "path";
|
|
77773
|
+
var exportProject = (input) => runToolchain({
|
|
77774
|
+
action: `Could not export templates${input.dir === undefined ? "" : ` in ${input.dir}`}`,
|
|
77775
|
+
options: {
|
|
77776
|
+
root: process.cwd(),
|
|
77777
|
+
out: resolve10(input.out),
|
|
77778
|
+
...input.dir === undefined ? {} : { dir: resolve10(input.dir) },
|
|
77779
|
+
...input.assetBase === undefined ? {} : { assetBase: input.assetBase },
|
|
77780
|
+
...input.offline === true ? { offline: true } : {}
|
|
77781
|
+
},
|
|
77782
|
+
script: `import { exportProject } from "@samva/vite/project"; ${OPTIONS_PRELUDE}
|
|
77783
|
+
${brandResolverPrelude()}
|
|
77784
|
+
process.stdout.write(JSON.stringify(await exportProject(options)));`
|
|
77785
|
+
});
|
|
77786
|
+
|
|
77787
|
+
// src/commands/templates/project.ts
|
|
77788
|
+
import { resolve as resolve11 } from "path";
|
|
77544
77789
|
var templateId = String10("id").pipe(withDescription4("Template id"));
|
|
77545
77790
|
var projectOrTemplateId = String10("id").pipe(withDescription4("Template project id (tproj_...) or the id of any template in it"));
|
|
77546
77791
|
var runGit = (args, options = {}) => tryPromise2({
|
|
@@ -77627,7 +77872,7 @@ var cloneProject = fn2("Templates.cloneProject")(function* (input) {
|
|
|
77627
77872
|
getById({ id: cloneTemplateId }).pipe(client.provide),
|
|
77628
77873
|
getGitRepository({ id: cloneTemplateId }).pipe(client.provide)
|
|
77629
77874
|
], { concurrency: 2 }).pipe(mapError2((error) => toCliApiError("Could not resolve template project", error)));
|
|
77630
|
-
const root =
|
|
77875
|
+
const root = resolve11(input.dir);
|
|
77631
77876
|
const helper = yield* helperCommand(template.id, "read");
|
|
77632
77877
|
yield* runGit([
|
|
77633
77878
|
"-c",
|
|
@@ -77725,7 +77970,7 @@ var init2 = make29("init", {
|
|
|
77725
77970
|
description: "Create deterministically for CI or a coding agent"
|
|
77726
77971
|
}
|
|
77727
77972
|
]), withHandler(({ name, projectName, slug, dir, starter, idempotencyKey, dryRun, json }) => gen2(function* () {
|
|
77728
|
-
const root =
|
|
77973
|
+
const root = resolve11(getOrElse(dir, () => projectDirectory(name)));
|
|
77729
77974
|
const key = getOrUndefined(idempotencyKey);
|
|
77730
77975
|
const request = {
|
|
77731
77976
|
name,
|
|
@@ -78080,10 +78325,12 @@ ${lines.join(`
|
|
|
78080
78325
|
|
|
78081
78326
|
// src/commands/templates/render-command.ts
|
|
78082
78327
|
import { mkdir as mkdir3, writeFile as writeFile4 } from "fs/promises";
|
|
78083
|
-
import { dirname as dirname3, resolve as
|
|
78328
|
+
import { dirname as dirname3, resolve as resolve13 } from "path";
|
|
78084
78329
|
|
|
78085
78330
|
// src/commands/templates/local-render.ts
|
|
78086
|
-
import {
|
|
78331
|
+
import { mkdtemp as mkdtemp2, readFile as readFile5, rm as rm2 } from "fs/promises";
|
|
78332
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
78333
|
+
import { join as join4, resolve as resolve12 } from "path";
|
|
78087
78334
|
var renderLocal = (input) => runToolchain({
|
|
78088
78335
|
action: `Could not render ${input.template}`,
|
|
78089
78336
|
options: {
|
|
@@ -78091,7 +78338,7 @@ var renderLocal = (input) => runToolchain({
|
|
|
78091
78338
|
template: input.template,
|
|
78092
78339
|
fixture: input.fixture,
|
|
78093
78340
|
channel: input.channel,
|
|
78094
|
-
...input.dir === undefined ? {} : { dir:
|
|
78341
|
+
...input.dir === undefined ? {} : { dir: resolve12(input.dir) },
|
|
78095
78342
|
...input.locale === undefined ? {} : { locale: input.locale },
|
|
78096
78343
|
...input.timeZone === undefined ? {} : { timeZone: input.timeZone },
|
|
78097
78344
|
...input.assetBase === undefined ? {} : { assetBase: input.assetBase },
|
|
@@ -78100,6 +78347,55 @@ var renderLocal = (input) => runToolchain({
|
|
|
78100
78347
|
script: `import { renderChannel, renderTemplate } from "@samva/vite/render"; ${OPTIONS_PRELUDE}
|
|
78101
78348
|
${brandResolverPrelude()} const { channel, ...rest } = options; const result = channel === "email" ? await renderTemplate(rest) : await renderChannel({ ...rest, channel }); process.stdout.write(JSON.stringify(result));`
|
|
78102
78349
|
});
|
|
78350
|
+
var finding = (code, message) => ({
|
|
78351
|
+
code,
|
|
78352
|
+
severity: "error",
|
|
78353
|
+
message,
|
|
78354
|
+
origins: []
|
|
78355
|
+
});
|
|
78356
|
+
var renderWithProjectAssets = (input) => gen2(function* () {
|
|
78357
|
+
const scratch = yield* acquireRelease2(tryPromise2({
|
|
78358
|
+
try: () => mkdtemp2(join4(tmpdir2(), "samva-snapshot-export-")),
|
|
78359
|
+
catch: (cause) => new SamvaCliError({ message: `Could not create a scratch directory: ${String(cause)}` })
|
|
78360
|
+
}), (path) => promise2(() => rm2(path, { recursive: true, force: true })));
|
|
78361
|
+
const receipt = yield* exportProject({
|
|
78362
|
+
dir: input.dir,
|
|
78363
|
+
out: scratch,
|
|
78364
|
+
assetBase: join4(scratch, "assets"),
|
|
78365
|
+
offline: input.offline
|
|
78366
|
+
});
|
|
78367
|
+
const entry = input.template.replace(/^\.\//, "");
|
|
78368
|
+
const template = receipt.templates.find((candidate) => candidate.id === entry || candidate.entryPath === entry);
|
|
78369
|
+
const others = receipt.templates.filter((candidate) => candidate !== template).map((candidate) => candidate.entryPath);
|
|
78370
|
+
const diagnostics = receipt.diagnostics.filter((diagnostic) => {
|
|
78371
|
+
const file = diagnostic.origins[0]?.fileName ?? "";
|
|
78372
|
+
return !others.some((path) => file === path || file.endsWith(`/${path}`));
|
|
78373
|
+
});
|
|
78374
|
+
if (template === undefined)
|
|
78375
|
+
return {
|
|
78376
|
+
ok: false,
|
|
78377
|
+
diagnostics: [
|
|
78378
|
+
...diagnostics,
|
|
78379
|
+
finding("template-not-found", `No template ${JSON.stringify(input.template)} in the project. Known templates: ${receipt.templates.map((candidate) => candidate.id).join(", ") || "none"}.`)
|
|
78380
|
+
]
|
|
78381
|
+
};
|
|
78382
|
+
if (diagnostics.some((diagnostic) => diagnostic.severity === "error"))
|
|
78383
|
+
return { ok: false, diagnostics };
|
|
78384
|
+
const page = template.fixtures.find((candidate) => candidate.fixture === input.fixture)?.html;
|
|
78385
|
+
if (page === undefined)
|
|
78386
|
+
return {
|
|
78387
|
+
ok: false,
|
|
78388
|
+
diagnostics: [
|
|
78389
|
+
...diagnostics,
|
|
78390
|
+
finding("unknown-fixture", `Template ${template.id} has no email fixture ${JSON.stringify(input.fixture)}. Known fixtures: ${template.fixtures.map((candidate) => candidate.fixture).join(", ") || "none"}.`)
|
|
78391
|
+
]
|
|
78392
|
+
};
|
|
78393
|
+
const html = yield* tryPromise2({
|
|
78394
|
+
try: () => readFile5(join4(scratch, page), "utf8"),
|
|
78395
|
+
catch: (cause) => new SamvaCliError({ message: `Could not read the exported page: ${String(cause)}` })
|
|
78396
|
+
});
|
|
78397
|
+
return { ok: true, template: template.id, html, diagnostics };
|
|
78398
|
+
});
|
|
78103
78399
|
|
|
78104
78400
|
// src/commands/templates/render-command.ts
|
|
78105
78401
|
var renderPayload = (result, out) => ({
|
|
@@ -78175,7 +78471,7 @@ var renderCommand = make29("render", {
|
|
|
78175
78471
|
json
|
|
78176
78472
|
}) => gen2(function* () {
|
|
78177
78473
|
const machine = json || format === "json";
|
|
78178
|
-
const outPath = map(out, (value) =>
|
|
78474
|
+
const outPath = map(out, (value) => resolve13(value)).pipe(getOrUndefined);
|
|
78179
78475
|
const result = yield* renderLocal({
|
|
78180
78476
|
template,
|
|
78181
78477
|
fixture,
|
|
@@ -78225,13 +78521,13 @@ var renderCommand = make29("render", {
|
|
|
78225
78521
|
}).pipe(json || format === "json" ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
78226
78522
|
|
|
78227
78523
|
// src/commands/templates/snapshot-command.ts
|
|
78228
|
-
import { resolve as
|
|
78524
|
+
import { resolve as resolve14 } from "path";
|
|
78229
78525
|
|
|
78230
78526
|
// src/commands/templates/snapshot-browser.ts
|
|
78231
78527
|
import { existsSync } from "fs";
|
|
78232
|
-
import { copyFile as copyFile3, mkdir as mkdir4, mkdtemp as
|
|
78233
|
-
import { tmpdir as
|
|
78234
|
-
import { join as
|
|
78528
|
+
import { copyFile as copyFile3, mkdir as mkdir4, mkdtemp as mkdtemp3, readFile as readFile6, rm as rm3, stat as stat4, writeFile as writeFile5 } from "fs/promises";
|
|
78529
|
+
import { tmpdir as tmpdir3 } from "os";
|
|
78530
|
+
import { join as join5 } from "path";
|
|
78235
78531
|
import { pathToFileURL as pathToFileURL4 } from "url";
|
|
78236
78532
|
var VIEWPORTS = {
|
|
78237
78533
|
desktop: { width: 1280, height: 800 },
|
|
@@ -78242,8 +78538,8 @@ var BROWSER_REMEDY = "Install a browser to screenshot with: add `playwright` to
|
|
|
78242
78538
|
var snapshotFileName = (template, fixture, viewport, scheme) => `${template}-${fixture}-${viewport}-${scheme}.png`;
|
|
78243
78539
|
var takeSnapshots = async (input) => {
|
|
78244
78540
|
await mkdir4(input.outDir, { recursive: true });
|
|
78245
|
-
const scratch = await
|
|
78246
|
-
const htmlPath =
|
|
78541
|
+
const scratch = await mkdtemp3(join5(tmpdir3(), "samva-snapshot-"));
|
|
78542
|
+
const htmlPath = join5(scratch, "page.html");
|
|
78247
78543
|
await writeFile5(htmlPath, input.html);
|
|
78248
78544
|
const requests = input.viewports.flatMap((viewport) => input.schemes.map((scheme) => ({
|
|
78249
78545
|
htmlPath,
|
|
@@ -78251,7 +78547,7 @@ var takeSnapshots = async (input) => {
|
|
|
78251
78547
|
width: VIEWPORTS[viewport].width,
|
|
78252
78548
|
height: VIEWPORTS[viewport].height,
|
|
78253
78549
|
scheme,
|
|
78254
|
-
outFile:
|
|
78550
|
+
outFile: join5(input.outDir, snapshotFileName(input.template, input.fixture, viewport, scheme))
|
|
78255
78551
|
})));
|
|
78256
78552
|
const reasons = [];
|
|
78257
78553
|
try {
|
|
@@ -78272,7 +78568,7 @@ var takeSnapshots = async (input) => {
|
|
|
78272
78568
|
}
|
|
78273
78569
|
return { ok: false, reasons };
|
|
78274
78570
|
} finally {
|
|
78275
|
-
await
|
|
78571
|
+
await rm3(scratch, { recursive: true, force: true });
|
|
78276
78572
|
}
|
|
78277
78573
|
};
|
|
78278
78574
|
var CHROME_PATHS = [
|
|
@@ -78366,10 +78662,10 @@ var chromeLauncher = (binary, run = runProcess) => ({
|
|
|
78366
78662
|
status: "unavailable",
|
|
78367
78663
|
reason: "no Chrome or Chromium found in the usual locations and SAMVA_CHROME is not set"
|
|
78368
78664
|
};
|
|
78369
|
-
const profile = await
|
|
78665
|
+
const profile = await mkdtemp3(join5(tmpdir3(), "samva-chrome-"));
|
|
78370
78666
|
try {
|
|
78371
78667
|
for (const request of requests) {
|
|
78372
|
-
const source = await
|
|
78668
|
+
const source = await readFile6(request.htmlPath, "utf8");
|
|
78373
78669
|
const measured = request.htmlPath.replace(/\.html$/, `.${request.viewport}.${request.scheme}.html`);
|
|
78374
78670
|
await writeFile5(measured, withMeasurement(source));
|
|
78375
78671
|
const measure = await run(binary, chromeMeasureArgs({
|
|
@@ -78380,7 +78676,7 @@ var chromeLauncher = (binary, run = runProcess) => ({
|
|
|
78380
78676
|
url: pathToFileURL4(measured).href
|
|
78381
78677
|
}), { stdoutIncludes: "</html>" });
|
|
78382
78678
|
const height = Math.max(request.height, parseMeasuredHeight(measure.stdout) ?? request.height);
|
|
78383
|
-
const staged =
|
|
78679
|
+
const staged = join5(profile, `shot-${request.viewport}-${request.scheme}.png`);
|
|
78384
78680
|
const shot = await run(binary, chromeScreenshotArgs({
|
|
78385
78681
|
profile,
|
|
78386
78682
|
width: request.width,
|
|
@@ -78399,7 +78695,7 @@ var chromeLauncher = (binary, run = runProcess) => ({
|
|
|
78399
78695
|
}
|
|
78400
78696
|
return { status: "done" };
|
|
78401
78697
|
} finally {
|
|
78402
|
-
await
|
|
78698
|
+
await rm3(profile, { recursive: true, force: true });
|
|
78403
78699
|
}
|
|
78404
78700
|
}
|
|
78405
78701
|
});
|
|
@@ -78491,7 +78787,7 @@ var snapshotCommand = make29("snapshot", {
|
|
|
78491
78787
|
out: Directory2("out").pipe(withDescription2("Directory to write the PNGs into"), withDefault5(".samva/snapshots")),
|
|
78492
78788
|
viewport: String9("viewport").pipe(withDescription2(`Comma-separated viewports: ${Object.entries(VIEWPORTS).map(([name, size]) => `${name} (${size.width}px)`).join(", ")}`), withDefault5("desktop,mobile")),
|
|
78493
78789
|
scheme: String9("scheme").pipe(withDescription2("Comma-separated color schemes: light, dark"), withDefault5("light,dark")),
|
|
78494
|
-
assetBase:
|
|
78790
|
+
assetBase: String9("asset-base").pipe(withDescription2("HTTPS origin the template's imported assets are served from; omit to use the project's own asset files"), optional4),
|
|
78495
78791
|
offline: offlineFlag,
|
|
78496
78792
|
json: jsonFlag
|
|
78497
78793
|
}).pipe(withDescription3("Screenshot one fixture in a headless browser at desktop and mobile widths, light and dark"), withExamples([
|
|
@@ -78503,17 +78799,18 @@ var snapshotCommand = make29("snapshot", {
|
|
|
78503
78799
|
command: "samva templates snapshot welcome --fixture default --viewport mobile --scheme dark --out shots",
|
|
78504
78800
|
description: "One screenshot: mobile, dark"
|
|
78505
78801
|
}
|
|
78506
|
-
]), withHandler(({ template, fixture, dir, out, viewport, scheme, assetBase, offline, json }) => gen2(function* () {
|
|
78802
|
+
]), withHandler(({ template, fixture, dir, out, viewport, scheme, assetBase, offline, json }) => scoped2(gen2(function* () {
|
|
78507
78803
|
const viewports = yield* parseChoices("viewport", viewport, Object.keys(VIEWPORTS));
|
|
78508
78804
|
const schemes = yield* parseChoices("scheme", scheme, SCHEMES);
|
|
78509
|
-
const
|
|
78510
|
-
|
|
78511
|
-
|
|
78512
|
-
|
|
78513
|
-
|
|
78514
|
-
|
|
78515
|
-
|
|
78516
|
-
}
|
|
78805
|
+
const base = getOrUndefined(assetBase);
|
|
78806
|
+
if (base !== undefined && !/^https:\/\//i.test(base)) {
|
|
78807
|
+
return yield* new CliUsageError({
|
|
78808
|
+
code: "invalid_asset_base",
|
|
78809
|
+
message: `--asset-base must be an HTTPS origin; got ${base}. Omit it to screenshot with the project's own asset files.`
|
|
78810
|
+
});
|
|
78811
|
+
}
|
|
78812
|
+
const input = { template, fixture, dir: getOrUndefined(dir) };
|
|
78813
|
+
const rendered = base === undefined ? yield* renderWithProjectAssets({ ...input, channel: "email", offline }) : yield* renderLocal({ ...input, channel: "email", assetBase: base, offline });
|
|
78517
78814
|
if (!rendered.ok || !("html" in rendered)) {
|
|
78518
78815
|
const message = `Could not render ${template} (${fixture}) to screenshot it.`;
|
|
78519
78816
|
const diagnostics = rendered.diagnostics.map((diagnostic) => reportDiagnostic(diagnostic, { file: "." }));
|
|
@@ -78530,7 +78827,7 @@ var snapshotCommand = make29("snapshot", {
|
|
|
78530
78827
|
}
|
|
78531
78828
|
return yield* new SamvaCliError({ message });
|
|
78532
78829
|
}
|
|
78533
|
-
const outDir =
|
|
78830
|
+
const outDir = resolve14(out);
|
|
78534
78831
|
const shots = yield* promise2(() => takeSnapshots({
|
|
78535
78832
|
html: rendered.html,
|
|
78536
78833
|
template: rendered.template,
|
|
@@ -78558,10 +78855,10 @@ var snapshotCommand = make29("snapshot", {
|
|
|
78558
78855
|
return yield* printJson(result);
|
|
78559
78856
|
for (const file of shots.files)
|
|
78560
78857
|
yield* log(file.path);
|
|
78561
|
-
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
78858
|
+
})).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
78562
78859
|
|
|
78563
78860
|
// src/commands/templates/types-command.ts
|
|
78564
|
-
import { dirname as dirname4, resolve as
|
|
78861
|
+
import { dirname as dirname4, resolve as resolve15 } from "path";
|
|
78565
78862
|
|
|
78566
78863
|
// src/commands/templates/schema-types.ts
|
|
78567
78864
|
var RESERVED = new Set([
|
|
@@ -78609,6 +78906,93 @@ var pascalCase = (value, fallback) => {
|
|
|
78609
78906
|
const joined = parts.map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`).join("").replace(/^[0-9]+/, "");
|
|
78610
78907
|
return joined.length === 0 || RESERVED.has(joined.toLowerCase()) ? fallback : joined;
|
|
78611
78908
|
};
|
|
78909
|
+
var text2 = (value) => ({ kind: "text", text: value });
|
|
78910
|
+
var NEVER = text2("never");
|
|
78911
|
+
var union2 = (members) => members.length === 1 ? members[0] ?? NEVER : { kind: "union", members: members.flatMap((m) => m.kind === "union" ? m.members : [m]) };
|
|
78912
|
+
var PRINT_WIDTH = 100;
|
|
78913
|
+
var pad2 = (indent) => " ".repeat(indent);
|
|
78914
|
+
var isFlat = (doc) => {
|
|
78915
|
+
switch (doc.kind) {
|
|
78916
|
+
case "text":
|
|
78917
|
+
return true;
|
|
78918
|
+
case "object":
|
|
78919
|
+
return false;
|
|
78920
|
+
case "union":
|
|
78921
|
+
case "intersection":
|
|
78922
|
+
return doc.members.every(isFlat);
|
|
78923
|
+
case "array":
|
|
78924
|
+
return isFlat(doc.element);
|
|
78925
|
+
case "tuple":
|
|
78926
|
+
return doc.members.every(isFlat) && (doc.rest === undefined || isFlat(doc.rest));
|
|
78927
|
+
case "record":
|
|
78928
|
+
return isFlat(doc.value);
|
|
78929
|
+
}
|
|
78930
|
+
};
|
|
78931
|
+
var flat = (doc) => {
|
|
78932
|
+
switch (doc.kind) {
|
|
78933
|
+
case "text":
|
|
78934
|
+
return doc.text;
|
|
78935
|
+
case "object":
|
|
78936
|
+
return `{ ${doc.members.map(({ name, optional, type }) => `readonly ${name}${optional ? "?" : ""}: ${flat(type)}`).join("; ")} }`;
|
|
78937
|
+
case "union":
|
|
78938
|
+
return doc.members.map(flat).join(" | ");
|
|
78939
|
+
case "intersection":
|
|
78940
|
+
return doc.members.map(operand).join(" & ");
|
|
78941
|
+
case "array":
|
|
78942
|
+
return `readonly ${wrapped(doc.element)}[]`;
|
|
78943
|
+
case "tuple":
|
|
78944
|
+
return `readonly [${[...doc.members.map(flat), ...doc.rest === undefined ? [] : [`...${flat(doc.rest)}[]`]].join(", ")}]`;
|
|
78945
|
+
case "record":
|
|
78946
|
+
return `Record<string, ${flat(doc.value)}>`;
|
|
78947
|
+
}
|
|
78948
|
+
};
|
|
78949
|
+
var needsParentheses = (doc) => doc.kind === "union" || doc.kind === "intersection" || doc.kind === "array" || doc.kind === "tuple";
|
|
78950
|
+
var operand = (doc) => doc.kind === "union" ? `(${flat(doc)})` : flat(doc);
|
|
78951
|
+
var wrapped = (doc) => needsParentheses(doc) ? `(${flat(doc)})` : flat(doc);
|
|
78952
|
+
var printType = (doc, indent, column, suffix = 1) => {
|
|
78953
|
+
switch (doc.kind) {
|
|
78954
|
+
case "object":
|
|
78955
|
+
return `{
|
|
78956
|
+
${doc.members.map(({ name, optional, type }) => {
|
|
78957
|
+
const head = `${pad2(indent + 2)}readonly ${name}${optional ? "?" : ""}:`;
|
|
78958
|
+
const body = printType(type, indent + 2, head.length + 1);
|
|
78959
|
+
return `${head}${body.startsWith(`
|
|
78960
|
+
`) ? "" : " "}${body};`;
|
|
78961
|
+
}).join(`
|
|
78962
|
+
`)}
|
|
78963
|
+
${pad2(indent)}}`;
|
|
78964
|
+
case "union": {
|
|
78965
|
+
if (isFlat(doc) && column + flat(doc).length + suffix <= PRINT_WIDTH)
|
|
78966
|
+
return flat(doc);
|
|
78967
|
+
return doc.members.map((member) => `
|
|
78968
|
+
${pad2(indent + 2)}| ${printType(member, indent + 4, indent + 4, 0)}`).join("");
|
|
78969
|
+
}
|
|
78970
|
+
case "intersection":
|
|
78971
|
+
return doc.members.map((member) => {
|
|
78972
|
+
const body = printType(member, indent, column, suffix);
|
|
78973
|
+
if (member.kind !== "union")
|
|
78974
|
+
return body;
|
|
78975
|
+
return body.startsWith(`
|
|
78976
|
+
`) ? `(${body}
|
|
78977
|
+
${pad2(indent)})` : `(${body})`;
|
|
78978
|
+
}).join(" & ");
|
|
78979
|
+
case "array": {
|
|
78980
|
+
const element = doc.element;
|
|
78981
|
+
if (isFlat(doc) && column + flat(doc).length + suffix <= PRINT_WIDTH)
|
|
78982
|
+
return flat(doc);
|
|
78983
|
+
if (element.kind === "object")
|
|
78984
|
+
return `readonly ${printType(element, indent, column + 9, 0)}[]`;
|
|
78985
|
+
if (!needsParentheses(element))
|
|
78986
|
+
return flat(doc);
|
|
78987
|
+
const body = printType(element, indent, column + 10, 0);
|
|
78988
|
+
return body.startsWith(`
|
|
78989
|
+
`) ? `readonly (${body}
|
|
78990
|
+
${pad2(indent)})[]` : `readonly (${body})[]`;
|
|
78991
|
+
}
|
|
78992
|
+
default:
|
|
78993
|
+
return flat(doc);
|
|
78994
|
+
}
|
|
78995
|
+
};
|
|
78612
78996
|
var UNSUPPORTED_KEYWORDS = [
|
|
78613
78997
|
"not",
|
|
78614
78998
|
"if",
|
|
@@ -78625,31 +79009,31 @@ var UNSUPPORTED_KEYWORDS = [
|
|
|
78625
79009
|
];
|
|
78626
79010
|
var literal = (value, pointer, state) => {
|
|
78627
79011
|
if (value === null)
|
|
78628
|
-
return "null";
|
|
79012
|
+
return text2("null");
|
|
78629
79013
|
if (typeof value === "string")
|
|
78630
|
-
return JSON.stringify(value);
|
|
79014
|
+
return text2(JSON.stringify(value));
|
|
78631
79015
|
if (typeof value === "number" || typeof value === "boolean")
|
|
78632
|
-
return String(value);
|
|
79016
|
+
return text2(String(value));
|
|
78633
79017
|
state.problems.push({
|
|
78634
79018
|
pointer,
|
|
78635
79019
|
message: "Only string, number, boolean and null literals become generated types."
|
|
78636
79020
|
});
|
|
78637
|
-
return
|
|
79021
|
+
return NEVER;
|
|
78638
79022
|
};
|
|
78639
79023
|
var scalar = (type, pointer, state) => {
|
|
78640
79024
|
switch (type) {
|
|
78641
79025
|
case "string":
|
|
78642
|
-
return "string";
|
|
79026
|
+
return text2("string");
|
|
78643
79027
|
case "number":
|
|
78644
79028
|
case "integer":
|
|
78645
|
-
return "number";
|
|
79029
|
+
return text2("number");
|
|
78646
79030
|
case "boolean":
|
|
78647
|
-
return "boolean";
|
|
79031
|
+
return text2("boolean");
|
|
78648
79032
|
case "null":
|
|
78649
|
-
return "null";
|
|
79033
|
+
return text2("null");
|
|
78650
79034
|
default:
|
|
78651
79035
|
state.problems.push({ pointer, message: `Unsupported JSON Schema type ${type}.` });
|
|
78652
|
-
return
|
|
79036
|
+
return NEVER;
|
|
78653
79037
|
}
|
|
78654
79038
|
};
|
|
78655
79039
|
var definitionName = (state, key, index, pointer) => {
|
|
@@ -78671,13 +79055,13 @@ var emit = (schema, pointer, root, state) => {
|
|
|
78671
79055
|
pointer,
|
|
78672
79056
|
message: "An unconstrained schema cannot produce a type that checks anything."
|
|
78673
79057
|
});
|
|
78674
|
-
return
|
|
79058
|
+
return NEVER;
|
|
78675
79059
|
}
|
|
78676
79060
|
if (schema === false)
|
|
78677
|
-
return
|
|
79061
|
+
return NEVER;
|
|
78678
79062
|
if (!isObject2(schema)) {
|
|
78679
79063
|
state.problems.push({ pointer, message: "Expected a JSON Schema object." });
|
|
78680
|
-
return
|
|
79064
|
+
return NEVER;
|
|
78681
79065
|
}
|
|
78682
79066
|
for (const keyword of UNSUPPORTED_KEYWORDS) {
|
|
78683
79067
|
if (schema[keyword] !== undefined) {
|
|
@@ -78685,7 +79069,7 @@ var emit = (schema, pointer, root, state) => {
|
|
|
78685
79069
|
pointer,
|
|
78686
79070
|
message: `Generated types do not support the ${keyword} keyword.`
|
|
78687
79071
|
});
|
|
78688
|
-
return
|
|
79072
|
+
return NEVER;
|
|
78689
79073
|
}
|
|
78690
79074
|
}
|
|
78691
79075
|
const reference = schema.$ref;
|
|
@@ -78697,48 +79081,51 @@ var emit = (schema, pointer, root, state) => {
|
|
|
78697
79081
|
pointer,
|
|
78698
79082
|
message: `Only local #/$defs references are generated; found ${reference}.`
|
|
78699
79083
|
});
|
|
78700
|
-
return
|
|
79084
|
+
return NEVER;
|
|
78701
79085
|
}
|
|
78702
79086
|
const name = definitionName(state, key, Object.keys(defs).indexOf(key), pointer);
|
|
78703
79087
|
if (name === undefined)
|
|
78704
|
-
return
|
|
79088
|
+
return NEVER;
|
|
78705
79089
|
if (!state.defs.has(name) && !state.emitting.has(name)) {
|
|
78706
79090
|
state.emitting.add(name);
|
|
78707
79091
|
state.defs.set(name, emit(defs[key], `#/$defs/${key}`, root, state));
|
|
78708
79092
|
}
|
|
78709
|
-
return name;
|
|
79093
|
+
return text2(name);
|
|
78710
79094
|
}
|
|
78711
79095
|
if (schema.const !== undefined)
|
|
78712
79096
|
return literal(schema.const, pointer, state);
|
|
78713
79097
|
if (Array.isArray(schema.enum)) {
|
|
78714
|
-
return schema.enum.length === 0 ?
|
|
79098
|
+
return schema.enum.length === 0 ? NEVER : union2(schema.enum.map((value) => literal(value, pointer, state)));
|
|
78715
79099
|
}
|
|
78716
79100
|
if (Array.isArray(schema.allOf)) {
|
|
78717
|
-
return
|
|
79101
|
+
return {
|
|
79102
|
+
kind: "intersection",
|
|
79103
|
+
members: schema.allOf.map((member, index) => emit(member, `${pointer}/allOf/${index}`, root, state))
|
|
79104
|
+
};
|
|
78718
79105
|
}
|
|
78719
79106
|
for (const key of ["anyOf", "oneOf"]) {
|
|
78720
79107
|
const members = schema[key];
|
|
78721
79108
|
if (!Array.isArray(members))
|
|
78722
79109
|
continue;
|
|
78723
|
-
return members.length === 0 ?
|
|
79110
|
+
return members.length === 0 ? NEVER : union2(members.map((member, index) => emit(member, `${pointer}/${key}/${index}`, root, state)));
|
|
78724
79111
|
}
|
|
78725
79112
|
const type = schema.type;
|
|
78726
79113
|
if (Array.isArray(type)) {
|
|
78727
|
-
return type.map((member) => scalarOrStructured(schema, member, pointer, root, state))
|
|
79114
|
+
return union2(type.map((member) => scalarOrStructured(schema, member, pointer, root, state)));
|
|
78728
79115
|
}
|
|
78729
79116
|
if (typeof type !== "string") {
|
|
78730
79117
|
state.problems.push({
|
|
78731
79118
|
pointer,
|
|
78732
79119
|
message: "A generated type needs an explicit type, enum, const, $ref or composition."
|
|
78733
79120
|
});
|
|
78734
|
-
return
|
|
79121
|
+
return NEVER;
|
|
78735
79122
|
}
|
|
78736
79123
|
return scalarOrStructured(schema, type, pointer, root, state);
|
|
78737
79124
|
};
|
|
78738
79125
|
var scalarOrStructured = (schema, type, pointer, root, state) => {
|
|
78739
79126
|
if (typeof type !== "string") {
|
|
78740
79127
|
state.problems.push({ pointer, message: "Expected a JSON Schema type name." });
|
|
78741
|
-
return
|
|
79128
|
+
return NEVER;
|
|
78742
79129
|
}
|
|
78743
79130
|
if (type === "object") {
|
|
78744
79131
|
const properties = isObject2(schema.properties) ? schema.properties : {};
|
|
@@ -78751,40 +79138,52 @@ var scalarOrStructured = (schema, type, pointer, root, state) => {
|
|
|
78751
79138
|
pointer,
|
|
78752
79139
|
message: "An object with no declared properties cannot produce a type that checks input."
|
|
78753
79140
|
});
|
|
78754
|
-
return
|
|
79141
|
+
return NEVER;
|
|
78755
79142
|
}
|
|
78756
|
-
return additional === false ? "
|
|
79143
|
+
return additional === false ? { kind: "record", value: NEVER } : {
|
|
79144
|
+
kind: "record",
|
|
79145
|
+
value: emit(additional, `${pointer}/additionalProperties`, root, state)
|
|
79146
|
+
};
|
|
78757
79147
|
}
|
|
78758
79148
|
const declared = keys.map((key) => ({
|
|
78759
79149
|
name: SAFE_PROPERTY.test(key) ? key : JSON.stringify(key),
|
|
78760
|
-
optional: required.has(key)
|
|
79150
|
+
optional: !required.has(key),
|
|
78761
79151
|
type: emit(properties[key], `${pointer}/properties/${key}`, root, state)
|
|
78762
79152
|
}));
|
|
78763
|
-
const shape =
|
|
78764
|
-
${declared.map(({ name, optional, type: member }) => ` readonly ${name}${optional}: ${member};`).join(`
|
|
78765
|
-
`)}
|
|
78766
|
-
}`;
|
|
79153
|
+
const shape = { kind: "object", members: declared };
|
|
78767
79154
|
if (additional === undefined || additional === false || additional === true)
|
|
78768
79155
|
return shape;
|
|
78769
79156
|
const extra = emit(additional, `${pointer}/additionalProperties`, root, state);
|
|
78770
|
-
const
|
|
78771
|
-
|
|
79157
|
+
const seen = new Set;
|
|
79158
|
+
const open = [...declared.map((member) => member.type), extra].filter((member) => {
|
|
79159
|
+
const key = flat(member);
|
|
79160
|
+
if (key === "never" || seen.has(key))
|
|
79161
|
+
return false;
|
|
79162
|
+
seen.add(key);
|
|
79163
|
+
return true;
|
|
79164
|
+
});
|
|
79165
|
+
return {
|
|
79166
|
+
kind: "intersection",
|
|
79167
|
+
members: [shape, { kind: "record", value: open.length === 0 ? NEVER : union2(open) }]
|
|
79168
|
+
};
|
|
78772
79169
|
}
|
|
78773
79170
|
if (type === "array") {
|
|
78774
79171
|
if (Array.isArray(schema.prefixItems)) {
|
|
78775
79172
|
const tuple = schema.prefixItems.map((member, index) => emit(member, `${pointer}/prefixItems/${index}`, root, state));
|
|
78776
|
-
|
|
78777
|
-
|
|
79173
|
+
return {
|
|
79174
|
+
kind: "tuple",
|
|
79175
|
+
members: tuple,
|
|
79176
|
+
...schema.items === undefined || schema.items === false ? {} : { rest: emit(schema.items, `${pointer}/items`, root, state) }
|
|
79177
|
+
};
|
|
78778
79178
|
}
|
|
78779
79179
|
if (schema.items === undefined) {
|
|
78780
79180
|
state.problems.push({
|
|
78781
79181
|
pointer,
|
|
78782
79182
|
message: "An array without declared items cannot produce a type that checks input."
|
|
78783
79183
|
});
|
|
78784
|
-
return
|
|
79184
|
+
return NEVER;
|
|
78785
79185
|
}
|
|
78786
|
-
|
|
78787
|
-
return SAFE_PROPERTY.test(member) ? `readonly ${member}[]` : `readonly (${member})[]`;
|
|
79186
|
+
return { kind: "array", element: emit(schema.items, `${pointer}/items`, root, state) };
|
|
78788
79187
|
}
|
|
78789
79188
|
return scalar(type, pointer, state);
|
|
78790
79189
|
};
|
|
@@ -78808,31 +79207,54 @@ var schemaToTypeScript = (schema, prefix) => {
|
|
|
78808
79207
|
var TEMPLATE_TYPES_MANIFEST_PREFIX = "// samva:catalog ";
|
|
78809
79208
|
var ManifestSchema = Struct({
|
|
78810
79209
|
version: Literal2(1),
|
|
78811
|
-
|
|
79210
|
+
by: optionalKey2(Literals(["id", "slug"])),
|
|
79211
|
+
reference: optionalKey2(Literals(["exact", "contract-latest"])),
|
|
78812
79212
|
templates: ArraySchema(Struct({
|
|
78813
79213
|
key: String4,
|
|
78814
79214
|
templateId: String4,
|
|
78815
|
-
reference: String4
|
|
79215
|
+
reference: optionalKey2(String4),
|
|
79216
|
+
inputContractId: optionalKey2(String4)
|
|
78816
79217
|
}))
|
|
78817
79218
|
});
|
|
78818
79219
|
var decodeManifest = decodeUnknownOption2(fromJsonString2(ManifestSchema));
|
|
79220
|
+
var withKeying = (manifest) => ({ ...manifest, by: manifest.by ?? "id" });
|
|
78819
79221
|
var readTemplateTypesManifest = (source) => {
|
|
78820
79222
|
const line = source.split(`
|
|
78821
79223
|
`).find((candidate) => candidate.startsWith(TEMPLATE_TYPES_MANIFEST_PREFIX));
|
|
78822
|
-
return line === undefined ? undefined : getOrUndefined(decodeManifest(line.slice(TEMPLATE_TYPES_MANIFEST_PREFIX.length)));
|
|
79224
|
+
return line === undefined ? undefined : getOrUndefined(map(decodeManifest(line.slice(TEMPLATE_TYPES_MANIFEST_PREFIX.length)), withKeying));
|
|
79225
|
+
};
|
|
79226
|
+
var MODULE_TYPE_NAMES = [
|
|
79227
|
+
"SamvaTemplateInputs",
|
|
79228
|
+
"TemplateContent",
|
|
79229
|
+
"TemplateSlug",
|
|
79230
|
+
"TemplateValue",
|
|
79231
|
+
"TemplateValues"
|
|
79232
|
+
];
|
|
79233
|
+
var memberKey = (value) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(value) ? value : JSON.stringify(value);
|
|
79234
|
+
var declaration = (head, type) => {
|
|
79235
|
+
const body = printType(type, 0, head.length + 1);
|
|
79236
|
+
return `${head}${body.startsWith(`
|
|
79237
|
+
`) ? "" : " "}${body};`;
|
|
79238
|
+
};
|
|
79239
|
+
var mapEntry = (key, fields) => {
|
|
79240
|
+
const flat = ` ${key}: { ${fields.map(([name, value]) => `${name}: ${value}`).join(", ")} },`;
|
|
79241
|
+
return flat.length <= PRINT_WIDTH ? flat : [` ${key}: {`, ...fields.map(([name, value]) => ` ${name}: ${value},`), " },"].join(`
|
|
79242
|
+
`);
|
|
78823
79243
|
};
|
|
78824
79244
|
var renderTemplateTypes = (input) => {
|
|
79245
|
+
const bySlug = input.by === "slug";
|
|
79246
|
+
const referenceKind = bySlug ? "contract-latest" : input.reference;
|
|
78825
79247
|
const skipped = [];
|
|
78826
79248
|
const problems = [];
|
|
78827
79249
|
const entries = [...input.entries].sort((left, right) => left.key < right.key ? -1 : left.key > right.key ? 1 : 0);
|
|
78828
79250
|
const generated = [];
|
|
78829
|
-
const
|
|
79251
|
+
const declared = new Set(MODULE_TYPE_NAMES);
|
|
78830
79252
|
for (const [index, entry] of entries.entries()) {
|
|
78831
|
-
const reference =
|
|
79253
|
+
const reference = referenceKind === "exact" ? entry.publicationId : entry.inputContractId;
|
|
78832
79254
|
if (reference === undefined) {
|
|
78833
79255
|
skipped.push({
|
|
78834
79256
|
key: entry.key,
|
|
78835
|
-
reason:
|
|
79257
|
+
reason: referenceKind === "exact" ? "no publication yet; publish the template before generating an exact reference" : bySlug ? "no input contract yet; publish the template before generating types by slug" : "no input contract yet; publish the template before adopting its contract"
|
|
78836
79258
|
});
|
|
78837
79259
|
continue;
|
|
78838
79260
|
}
|
|
@@ -78841,10 +79263,17 @@ var renderTemplateTypes = (input) => {
|
|
|
78841
79263
|
continue;
|
|
78842
79264
|
}
|
|
78843
79265
|
let name = pascalCase(entry.key, `Template${index + 1}`);
|
|
78844
|
-
|
|
79266
|
+
let rendered = schemaToTypeScript(entry.inputSchema, name);
|
|
79267
|
+
const typeNames = () => [
|
|
79268
|
+
`${name}Input`,
|
|
79269
|
+
...rendered.definitions.map((definition) => definition.name)
|
|
79270
|
+
];
|
|
79271
|
+
while (typeNames().some((typeName) => declared.has(typeName))) {
|
|
78845
79272
|
name = `${name}_`;
|
|
78846
|
-
|
|
78847
|
-
|
|
79273
|
+
rendered = schemaToTypeScript(entry.inputSchema, name);
|
|
79274
|
+
}
|
|
79275
|
+
for (const typeName of typeNames())
|
|
79276
|
+
declared.add(typeName);
|
|
78848
79277
|
for (const problem of rendered.problems)
|
|
78849
79278
|
problems.push({ ...problem, key: entry.key });
|
|
78850
79279
|
generated.push({
|
|
@@ -78857,19 +79286,60 @@ var renderTemplateTypes = (input) => {
|
|
|
78857
79286
|
}
|
|
78858
79287
|
const manifest = {
|
|
78859
79288
|
version: 1,
|
|
78860
|
-
|
|
79289
|
+
by: input.by,
|
|
79290
|
+
...bySlug ? {} : { reference: referenceKind },
|
|
78861
79291
|
templates: generated.map(({ entry, reference }) => ({
|
|
78862
79292
|
key: entry.key,
|
|
78863
79293
|
templateId: entry.templateId,
|
|
78864
|
-
reference
|
|
79294
|
+
...bySlug ? { inputContractId: reference } : { reference }
|
|
78865
79295
|
}))
|
|
78866
79296
|
};
|
|
78867
|
-
const referenceField =
|
|
78868
|
-
const referenceNote = input.
|
|
78869
|
-
const definitions = generated.flatMap(({ definitions: members }) => members.map(({ name, type }) => `type ${name}
|
|
78870
|
-
const inputs = generated.map(({ entry, name, type }) => [
|
|
79297
|
+
const referenceField = referenceKind === "exact" ? "publicationId" : "inputContractId";
|
|
79298
|
+
const referenceNote = bySlug ? "Each helper names a template by slug, so a send from this file renders the template's current publication; its input is typed from the input contract current when you generated." : referenceKind === "exact" ? "Each reference pins one exact publication, so a send from this file renders the same message until you regenerate." : "Each reference names an input contract, so a send from this file follows the newest publication that still validates input identically.";
|
|
79299
|
+
const definitions = generated.flatMap(({ definitions: members }) => members.map(({ name, type }) => declaration(`type ${name} =`, type)));
|
|
79300
|
+
const inputs = generated.map(({ entry, name, type }) => [
|
|
79301
|
+
`/** Input for the \`${entry.key}\` template. */`,
|
|
79302
|
+
declaration(`export type ${name}Input =`, type)
|
|
79303
|
+
].join(`
|
|
78871
79304
|
`));
|
|
78872
|
-
const
|
|
79305
|
+
const keying = bySlug ? [
|
|
79306
|
+
"/**",
|
|
79307
|
+
" * Email content for one template, named by slug. TypeScript rejects input the template's",
|
|
79308
|
+
" * input contract would reject; spread the result into `email.send`.",
|
|
79309
|
+
" */",
|
|
79310
|
+
"export const templateContent = <Slug extends TemplateSlug>(",
|
|
79311
|
+
" slug: Slug,",
|
|
79312
|
+
" templateData: SamvaTemplateInputs[Slug],",
|
|
79313
|
+
") => ({ templateSlug: slug, templateData: asTemplateData(templateData) });"
|
|
79314
|
+
] : [
|
|
79315
|
+
`/** ${referenceNote} */`,
|
|
79316
|
+
generated.length === 0 ? "export const samvaTemplates = {} as const;" : `export const samvaTemplates = {
|
|
79317
|
+
${generated.map(({ entry, reference }) => mapEntry(memberKey(entry.key), [
|
|
79318
|
+
["templateId", JSON.stringify(entry.templateId)],
|
|
79319
|
+
[referenceField, JSON.stringify(reference)]
|
|
79320
|
+
])).join(`
|
|
79321
|
+
`)}
|
|
79322
|
+
} as const;`,
|
|
79323
|
+
"",
|
|
79324
|
+
"/** What a send spreads in: the template's reference and its input as JSON. */",
|
|
79325
|
+
"export type TemplateContent = {",
|
|
79326
|
+
" readonly templateId: string;",
|
|
79327
|
+
` readonly ${referenceField}: string;`,
|
|
79328
|
+
" readonly templateData: TemplateValues;",
|
|
79329
|
+
"};",
|
|
79330
|
+
"",
|
|
79331
|
+
"/**",
|
|
79332
|
+
" * Email content for one template. TypeScript rejects input the published",
|
|
79333
|
+
" * schema would reject, and the reference travels with it. Spread it into `email.send`.",
|
|
79334
|
+
" */",
|
|
79335
|
+
"export const templateContent = <Slug extends TemplateSlug>(",
|
|
79336
|
+
" slug: Slug,",
|
|
79337
|
+
" templateData: SamvaTemplateInputs[Slug],",
|
|
79338
|
+
"): TemplateContent => ({",
|
|
79339
|
+
" ...samvaTemplates[slug],",
|
|
79340
|
+
" templateData: asTemplateData(templateData),",
|
|
79341
|
+
"});"
|
|
79342
|
+
];
|
|
78873
79343
|
const source = `${[
|
|
78874
79344
|
"// Generated by `samva templates types`. Do not edit.",
|
|
78875
79345
|
`//`,
|
|
@@ -78886,24 +79356,43 @@ var renderTemplateTypes = (input) => {
|
|
|
78886
79356
|
`), ""],
|
|
78887
79357
|
"/** What each published template accepts, keyed by slug. */",
|
|
78888
79358
|
generated.length === 0 ? "export interface SamvaTemplateInputs {}" : `export interface SamvaTemplateInputs {
|
|
78889
|
-
${generated.map(({ entry, name }) => ` readonly ${
|
|
79359
|
+
${generated.map(({ entry, name }) => ` readonly ${memberKey(entry.key)}: ${name}Input;`).join(`
|
|
78890
79360
|
`)}
|
|
78891
79361
|
}`,
|
|
78892
79362
|
"",
|
|
78893
|
-
|
|
78894
|
-
|
|
78895
|
-
${generated.map(({ entry, reference }) => ` ${key(entry.key)}: { templateId: ${JSON.stringify(entry.templateId)}, ${referenceField}: ${JSON.stringify(reference)} },`).join(`
|
|
78896
|
-
`)}
|
|
78897
|
-
} as const;`,
|
|
79363
|
+
"/** The slug of every template in this file. */",
|
|
79364
|
+
"export type TemplateSlug = keyof SamvaTemplateInputs;",
|
|
78898
79365
|
"",
|
|
78899
|
-
"
|
|
78900
|
-
"
|
|
78901
|
-
"
|
|
78902
|
-
"
|
|
78903
|
-
"
|
|
78904
|
-
"
|
|
78905
|
-
"
|
|
78906
|
-
"
|
|
79366
|
+
"// What the API accepts as template data. A generated input is made of these values, but its",
|
|
79367
|
+
"// readonly lists and optional properties are not always assignable to them, so the helper",
|
|
79368
|
+
"// rebuilds the input as JSON values, leaving out a property that is undefined.",
|
|
79369
|
+
"type TemplateValue =",
|
|
79370
|
+
" | string",
|
|
79371
|
+
" | number",
|
|
79372
|
+
" | boolean",
|
|
79373
|
+
" | null",
|
|
79374
|
+
" | TemplateValue[]",
|
|
79375
|
+
" | { [key: string]: TemplateValue };",
|
|
79376
|
+
"type TemplateValues = { [key: string]: TemplateValue };",
|
|
79377
|
+
"const toTemplateValue = (value: unknown): TemplateValue => {",
|
|
79378
|
+
' if (value === null || typeof value === "string") return value;',
|
|
79379
|
+
' if (typeof value === "number" || typeof value === "boolean") return value;',
|
|
79380
|
+
" if (Array.isArray(value)) return value.map(toTemplateValue);",
|
|
79381
|
+
' if (typeof value !== "object") return null;',
|
|
79382
|
+
" return Object.fromEntries(",
|
|
79383
|
+
" Object.entries(value)",
|
|
79384
|
+
" .filter(([, member]) => member !== undefined)",
|
|
79385
|
+
" .map(([key, member]) => [key, toTemplateValue(member)]),",
|
|
79386
|
+
" );",
|
|
79387
|
+
"};",
|
|
79388
|
+
"const asTemplateData = (input: SamvaTemplateInputs[TemplateSlug]): TemplateValues =>",
|
|
79389
|
+
" Object.fromEntries(",
|
|
79390
|
+
" Object.entries(input)",
|
|
79391
|
+
" .filter(([, member]) => member !== undefined)",
|
|
79392
|
+
" .map(([key, member]) => [key, toTemplateValue(member)]),",
|
|
79393
|
+
" );",
|
|
79394
|
+
"",
|
|
79395
|
+
...keying
|
|
78907
79396
|
].join(`
|
|
78908
79397
|
`)}
|
|
78909
79398
|
`;
|
|
@@ -78920,6 +79409,13 @@ var templateTypesDrift = (existing, generated) => {
|
|
|
78920
79409
|
detail: "The file carries no samva:catalog manifest; it was not written by this command."
|
|
78921
79410
|
}
|
|
78922
79411
|
];
|
|
79412
|
+
if (manifest.by !== generated.manifest.by)
|
|
79413
|
+
return [
|
|
79414
|
+
{
|
|
79415
|
+
kind: "keying",
|
|
79416
|
+
detail: `Generated by ${manifest.by}; asked for ${generated.manifest.by}.`
|
|
79417
|
+
}
|
|
79418
|
+
];
|
|
78923
79419
|
if (manifest.reference !== generated.manifest.reference)
|
|
78924
79420
|
return [
|
|
78925
79421
|
{
|
|
@@ -78936,7 +79432,14 @@ var templateTypesDrift = (existing, generated) => {
|
|
|
78936
79432
|
drift.push({ kind: "added", key, detail: `${key} is published and not in the file.` });
|
|
78937
79433
|
continue;
|
|
78938
79434
|
}
|
|
78939
|
-
if (
|
|
79435
|
+
if (generated.manifest.by === "slug") {
|
|
79436
|
+
if (previous.inputContractId !== entry.inputContractId)
|
|
79437
|
+
drift.push({
|
|
79438
|
+
kind: "contract",
|
|
79439
|
+
key,
|
|
79440
|
+
detail: `${key} was typed from input contract ${previous.inputContractId}; the catalog now has ${entry.inputContractId}.`
|
|
79441
|
+
});
|
|
79442
|
+
} else if (previous.reference !== entry.reference)
|
|
78940
79443
|
drift.push({
|
|
78941
79444
|
kind: "reference",
|
|
78942
79445
|
key,
|
|
@@ -78982,13 +79485,22 @@ var readCatalog = fn2("templates.types.readCatalog")(function* () {
|
|
|
78982
79485
|
...item.inputSchema === null ? {} : { inputSchema: item.inputSchema }
|
|
78983
79486
|
}))), { concurrency: CATALOG_READ_CONCURRENCY });
|
|
78984
79487
|
});
|
|
79488
|
+
var keyingRows = (by, reference) => by === "slug" ? [
|
|
79489
|
+
["By", "slug"],
|
|
79490
|
+
["Publication", "current"],
|
|
79491
|
+
["Drift", "input contract"]
|
|
79492
|
+
] : [
|
|
79493
|
+
["By", "id"],
|
|
79494
|
+
["Reference", reference ?? "exact"]
|
|
79495
|
+
];
|
|
78985
79496
|
var readExisting = (path) => gen2(function* () {
|
|
78986
79497
|
const fs = yield* FileSystem;
|
|
78987
79498
|
return (yield* fs.exists(path)) ? yield* fs.readFileString(path) : undefined;
|
|
78988
79499
|
}).pipe(catch_2(() => succeed6(undefined)));
|
|
78989
79500
|
var typesCommand = make29("types", {
|
|
78990
79501
|
out: String9("out").pipe(withDescription2("TypeScript file to write the generated template inputs into"), withDefault5("samva-templates.ts")),
|
|
78991
|
-
|
|
79502
|
+
by: Literals3("by", ["id", "slug"]).pipe(withDescription2("id keys each send by template id with a reference; slug keys it by template slug and follows the template's current publication"), withDefault5("id")),
|
|
79503
|
+
reference: String9("reference").pipe(withDescription2("With --by id (default exact): exact pins one publication per template; contract-latest follows the newest publication that validates input identically"), optional4),
|
|
78992
79504
|
check: Boolean6("check").pipe(withDescription2("Report drift without writing; exits 1 when the file is out of date"), withDefault5(false)),
|
|
78993
79505
|
json: jsonFlag
|
|
78994
79506
|
}).pipe(withDescription3("Generate typed template inputs from the authenticated catalog"), withExamples([
|
|
@@ -78996,21 +79508,32 @@ var typesCommand = make29("types", {
|
|
|
78996
79508
|
command: "samva templates types --out src/samva-templates.ts",
|
|
78997
79509
|
description: "Pin each template's current publication and type its input"
|
|
78998
79510
|
},
|
|
79511
|
+
{
|
|
79512
|
+
command: "samva templates types --by slug --out src/samva-templates.ts",
|
|
79513
|
+
description: "Type a send that names the template by slug: { templateSlug, templateData }"
|
|
79514
|
+
},
|
|
78999
79515
|
{
|
|
79000
79516
|
command: "samva templates types --check",
|
|
79001
79517
|
description: "Fail CI when the generated file no longer matches the catalog"
|
|
79002
79518
|
}
|
|
79003
|
-
]), withHandler(fnUntraced2(function* ({ out, reference, check, json }) {
|
|
79519
|
+
]), withHandler(fnUntraced2(function* ({ out, by, reference: requested, check, json }) {
|
|
79520
|
+
const reference = getOrElse(requested, () => "exact");
|
|
79004
79521
|
if (reference !== "exact" && reference !== "contract-latest") {
|
|
79005
79522
|
return yield* new SamvaCliError({
|
|
79006
79523
|
message: `Unknown --reference ${reference}. Use exact or contract-latest.`
|
|
79007
79524
|
});
|
|
79008
79525
|
}
|
|
79526
|
+
if (by === "slug" && isSome2(requested)) {
|
|
79527
|
+
return yield* new SamvaCliError({
|
|
79528
|
+
message: "--reference does not apply with --by slug: a send by slug renders the template's current publication, and the types follow its input contract."
|
|
79529
|
+
});
|
|
79530
|
+
}
|
|
79009
79531
|
const context = yield* resolveExecutionContext;
|
|
79010
|
-
const path =
|
|
79532
|
+
const path = resolve15(out);
|
|
79011
79533
|
const entries = yield* readCatalog();
|
|
79012
79534
|
const generated = renderTemplateTypes({
|
|
79013
79535
|
entries,
|
|
79536
|
+
by,
|
|
79014
79537
|
reference,
|
|
79015
79538
|
origin: context.apiUrl
|
|
79016
79539
|
});
|
|
@@ -79023,7 +79546,8 @@ var typesCommand = make29("types", {
|
|
|
79023
79546
|
action: "templates.types",
|
|
79024
79547
|
ok: false,
|
|
79025
79548
|
out: path,
|
|
79026
|
-
|
|
79549
|
+
by,
|
|
79550
|
+
...generated.manifest.reference === undefined ? {} : { reference: generated.manifest.reference },
|
|
79027
79551
|
problems: generated.problems
|
|
79028
79552
|
},
|
|
79029
79553
|
human: [
|
|
@@ -79039,7 +79563,8 @@ var typesCommand = make29("types", {
|
|
|
79039
79563
|
action: "templates.types",
|
|
79040
79564
|
ok: check ? drift.length === 0 : true,
|
|
79041
79565
|
out: path,
|
|
79042
|
-
|
|
79566
|
+
by,
|
|
79567
|
+
...generated.manifest.reference === undefined ? {} : { reference: generated.manifest.reference },
|
|
79043
79568
|
templates: generated.manifest.templates,
|
|
79044
79569
|
skipped: generated.skipped,
|
|
79045
79570
|
drift,
|
|
@@ -79051,7 +79576,7 @@ var typesCommand = make29("types", {
|
|
|
79051
79576
|
return yield* printJson(result);
|
|
79052
79577
|
return yield* printFields([
|
|
79053
79578
|
["File", path],
|
|
79054
|
-
|
|
79579
|
+
...keyingRows(by, generated.manifest.reference),
|
|
79055
79580
|
["Templates", generated.manifest.templates.length],
|
|
79056
79581
|
["Status", "up to date"]
|
|
79057
79582
|
]);
|
|
@@ -79078,7 +79603,7 @@ var typesCommand = make29("types", {
|
|
|
79078
79603
|
return yield* printJson(written);
|
|
79079
79604
|
yield* printFields([
|
|
79080
79605
|
["File", path],
|
|
79081
|
-
|
|
79606
|
+
...keyingRows(by, generated.manifest.reference),
|
|
79082
79607
|
["Templates", generated.manifest.templates.length],
|
|
79083
79608
|
["Skipped", generated.skipped.length]
|
|
79084
79609
|
]);
|
|
@@ -79087,9 +79612,22 @@ var typesCommand = make29("types", {
|
|
|
79087
79612
|
})));
|
|
79088
79613
|
|
|
79089
79614
|
// src/commands/templates/workspace.ts
|
|
79090
|
-
import { basename as basename2, resolve as
|
|
79615
|
+
import { basename as basename2, resolve as resolve16 } from "path";
|
|
79091
79616
|
var templateIdArgument = String10("template-id").pipe(withDescription4("Template whose project workspace to act on"));
|
|
79092
79617
|
var revisionFlag2 = String9("revision").pipe(withDescription2("Workspace revision this call is fenced to; a workspace that moved refuses the call"));
|
|
79618
|
+
var readRevisionFlag = String9("revision").pipe(withDescription2("Workspace revision this call is fenced to; a workspace that moved refuses the call (default: the workspace's current revision)"), optional4);
|
|
79619
|
+
var currentRevision = (id, revision) => isSome2(revision) ? succeed6(revision.value) : gen2(function* () {
|
|
79620
|
+
const client = yield* getClientProvider;
|
|
79621
|
+
const view = yield* openWorkspace({ id }).pipe(client.provide, mapError2((error) => {
|
|
79622
|
+
const failure = toCliApiError("Could not read the template workspace revision", error);
|
|
79623
|
+
return new SamvaCliError({
|
|
79624
|
+
message: `${failure.message} The current revision is read by opening the workspace, which needs templates:create; pass --revision to skip that.`,
|
|
79625
|
+
api: failure.api,
|
|
79626
|
+
details: failure.details
|
|
79627
|
+
});
|
|
79628
|
+
}));
|
|
79629
|
+
return view.workspace.revision;
|
|
79630
|
+
});
|
|
79093
79631
|
var idempotencyKeyFlag4 = String9("idempotency-key").pipe(withDescription2("Key so an identical retry returns the original result rather than repeating it"));
|
|
79094
79632
|
var apiFailure2 = (what) => (error) => toCliApiError(`Could not ${what}`, error);
|
|
79095
79633
|
var emit2 = (value) => printJsonDocument(value);
|
|
@@ -79105,11 +79643,12 @@ var open3 = make29("open", { id: templateIdArgument, json: jsonFlag }).pipe(with
|
|
|
79105
79643
|
})));
|
|
79106
79644
|
var diff = make29("diff", {
|
|
79107
79645
|
id: templateIdArgument,
|
|
79108
|
-
revision:
|
|
79646
|
+
revision: readRevisionFlag,
|
|
79109
79647
|
json: jsonFlag
|
|
79110
79648
|
}).pipe(withDescription3("Show every unsaved change against the workspace Git base"), withHandler(fnUntraced2(function* ({ id, revision, json }) {
|
|
79649
|
+
const expectedRevision = yield* currentRevision(id, revision);
|
|
79111
79650
|
const client = yield* getClientProvider;
|
|
79112
|
-
const result = yield* diffWorkspace({ id, expectedRevision
|
|
79651
|
+
const result = yield* diffWorkspace({ id, expectedRevision }).pipe(client.provide, mapError2(apiFailure2("diff the template workspace")));
|
|
79113
79652
|
yield* emit2(result);
|
|
79114
79653
|
})));
|
|
79115
79654
|
var patch2 = make29("patch", {
|
|
@@ -79140,7 +79679,7 @@ var patch2 = make29("patch", {
|
|
|
79140
79679
|
message: `--set must be <project-path>=<local-file>; got ${entry}.`
|
|
79141
79680
|
});
|
|
79142
79681
|
const path = entry.slice(0, separator);
|
|
79143
|
-
const source =
|
|
79682
|
+
const source = resolve16(entry.slice(separator + 1));
|
|
79144
79683
|
const content = yield* fs.readFileString(source).pipe(mapError2((cause) => new SamvaCliError({ message: `Could not read ${source}: ${String(cause)}` })));
|
|
79145
79684
|
written.push({ path, content });
|
|
79146
79685
|
}
|
|
@@ -79174,7 +79713,7 @@ var addAsset = make29("add-asset", {
|
|
|
79174
79713
|
}
|
|
79175
79714
|
]), withHandler(fnUntraced2(function* ({ id, file, revision, path, replace, idempotencyKey, json }) {
|
|
79176
79715
|
const fs = yield* FileSystem;
|
|
79177
|
-
const source =
|
|
79716
|
+
const source = resolve16(file);
|
|
79178
79717
|
const bytes = yield* fs.readFile(source).pipe(mapError2((cause) => new SamvaCliError({ message: `Could not read ${source}: ${String(cause)}` })));
|
|
79179
79718
|
const client = yield* getClientProvider;
|
|
79180
79719
|
const view = yield* putWorkspaceAsset({
|
|
@@ -79189,28 +79728,30 @@ var addAsset = make29("add-asset", {
|
|
|
79189
79728
|
})));
|
|
79190
79729
|
var check4 = make29("check", {
|
|
79191
79730
|
id: templateIdArgument,
|
|
79192
|
-
revision:
|
|
79731
|
+
revision: readRevisionFlag,
|
|
79193
79732
|
json: jsonFlag
|
|
79194
79733
|
}).pipe(withDescription3("Build the effective workspace tree and report what it declares plus every finding"), withExamples([
|
|
79195
79734
|
{
|
|
79196
|
-
command: "samva templates workspace check tmpl_abc123
|
|
79197
|
-
description: "Read the template id, input schema, fixture names, and located diagnostics without rendering or writing"
|
|
79735
|
+
command: "samva templates workspace check tmpl_abc123",
|
|
79736
|
+
description: "Read the template id, input schema, fixture names, and located diagnostics without rendering or writing; --revision 5 fences the call to a revision you inspected"
|
|
79198
79737
|
}
|
|
79199
79738
|
]), withHandler(fnUntraced2(function* ({ id, revision, json }) {
|
|
79739
|
+
const expectedRevision = yield* currentRevision(id, revision);
|
|
79200
79740
|
const client = yield* getClientProvider;
|
|
79201
|
-
const result = yield* checkWorkspace({ id, expectedRevision
|
|
79741
|
+
const result = yield* checkWorkspace({ id, expectedRevision }).pipe(client.provide, mapError2(apiFailure2("check the template workspace")));
|
|
79202
79742
|
yield* emit2(result);
|
|
79203
79743
|
})));
|
|
79204
79744
|
var fixture = make29("fixture", {
|
|
79205
79745
|
id: templateIdArgument,
|
|
79206
|
-
revision:
|
|
79746
|
+
revision: readRevisionFlag,
|
|
79207
79747
|
name: String9("name").pipe(withDescription2("One of the fixture names `workspace check` reported")),
|
|
79208
79748
|
json: jsonFlag
|
|
79209
79749
|
}).pipe(withDescription3("Render one input the template declares, as the recipient receives it"), withHandler(fnUntraced2(function* ({ id, revision, name, json }) {
|
|
79750
|
+
const expectedRevision = yield* currentRevision(id, revision);
|
|
79210
79751
|
const client = yield* getClientProvider;
|
|
79211
79752
|
const result = yield* renderWorkspaceFixture({
|
|
79212
79753
|
id,
|
|
79213
|
-
expectedRevision
|
|
79754
|
+
expectedRevision,
|
|
79214
79755
|
fixture: name
|
|
79215
79756
|
}).pipe(client.provide, mapError2(apiFailure2("render the template fixture")));
|
|
79216
79757
|
yield* emit2(result);
|
|
@@ -79287,42 +79828,52 @@ var workspaceCommand = make29("workspace").pipe(withDescription3("Author a templ
|
|
|
79287
79828
|
|
|
79288
79829
|
// src/commands/templates.ts
|
|
79289
79830
|
var tsconfigFlag = String9("tsconfig").pipe(withDescription2("TypeScript project used to check authored templates"), withDefault5("tsconfig.json"));
|
|
79290
|
-
var
|
|
79831
|
+
var dryRunFlag7 = Boolean6("dry-run").pipe(withDescription2("Show the request without calling the API"), withDefault5(false));
|
|
79291
79832
|
var templateIdArgument2 = String10("id").pipe(withDescription4("Remote template id"));
|
|
79292
79833
|
var parseObject = (raw, flag) => try_3({
|
|
79293
79834
|
try: () => JSON.parse(raw),
|
|
79294
79835
|
catch: () => new SamvaCliError({ message: `${flag} must be a valid JSON object.` })
|
|
79295
79836
|
}).pipe(filterOrFail2((value) => isObject(value) && !Array.isArray(value), () => new SamvaCliError({ message: `${flag} must be a non-null JSON object.` })));
|
|
79296
79837
|
var decodePayload = (raw, flag, schema) => parseObject(raw, flag).pipe(flatMap3(decodeUnknownEffect2(schema)), mapError2((error) => error instanceof SamvaCliError ? error : new SamvaCliError({ message: `${flag} does not match the API schema: ${String(error)}` })));
|
|
79297
|
-
var createProjectBuildSession = (dir, assetBase) =>
|
|
79298
|
-
|
|
79299
|
-
|
|
79300
|
-
|
|
79301
|
-
|
|
79302
|
-
|
|
79303
|
-
|
|
79304
|
-
|
|
79838
|
+
var createProjectBuildSession = (dir, assetBase) => gen2(function* () {
|
|
79839
|
+
yield* requireCompatibleToolchain(`Could not start template watch${dir === undefined ? "" : ` in ${dir}`}`);
|
|
79840
|
+
const selection = yield* invocationEnv;
|
|
79841
|
+
return yield* tryPromise2({
|
|
79842
|
+
try: async () => {
|
|
79843
|
+
const entry = Bun.resolveSync("@samva/vite/build", process.cwd());
|
|
79844
|
+
const projectBuild = await import(pathToFileURL5(entry).href);
|
|
79845
|
+
const { createBrandResolver, loadBrandEnv } = await loadSamvaBrandResolver(process.cwd());
|
|
79846
|
+
const projectBrand = await import(pathToFileURL5(Bun.resolveSync("@samva/markup/brand", process.cwd())).href);
|
|
79847
|
+
return projectBuild.createTemplateBuildSession({
|
|
79848
|
+
brandResolver: createBrandResolver({
|
|
79849
|
+
root: process.cwd(),
|
|
79850
|
+
env: { ...await loadBrandEnv(process.cwd()), ...selection }
|
|
79851
|
+
}),
|
|
79852
|
+
brandPlugin: projectBrand.samvaBrandPlugin,
|
|
79305
79853
|
root: process.cwd(),
|
|
79306
|
-
|
|
79307
|
-
|
|
79308
|
-
|
|
79309
|
-
|
|
79310
|
-
|
|
79311
|
-
|
|
79312
|
-
})
|
|
79313
|
-
}
|
|
79314
|
-
catch: (cause) => new SamvaCliError({
|
|
79315
|
-
message: toolchainFailure(String(cause), `Could not start template watch${dir === undefined ? "" : ` in ${dir}`}`)
|
|
79316
|
-
})
|
|
79854
|
+
...dir === undefined ? {} : { dir: resolve17(dir) },
|
|
79855
|
+
...assetBase === undefined ? {} : { assetBase }
|
|
79856
|
+
});
|
|
79857
|
+
},
|
|
79858
|
+
catch: (cause) => new SamvaCliError({
|
|
79859
|
+
message: toolchainFailure(String(cause), `Could not start template watch${dir === undefined ? "" : ` in ${dir}`}`)
|
|
79860
|
+
})
|
|
79861
|
+
});
|
|
79317
79862
|
});
|
|
79318
79863
|
var TSC_DIAGNOSTIC_LINE = /^(?:(.*?)(?:\((\d+),(\d+)\))?: )?(?:error )?(TS\d+): (.*)$/;
|
|
79864
|
+
var BRAND_MODULE_NOT_FOUND = /^Cannot find module 'samva:brand(?:\/[^']*)?'/;
|
|
79865
|
+
var ASSET_MODULE_NOT_FOUND = /^Cannot find module '[^']+\.(?:png|jpe?g|gif|webp|woff2)'/;
|
|
79866
|
+
var withTypesHint = (message, tsconfig) => {
|
|
79867
|
+
const types = BRAND_MODULE_NOT_FOUND.test(message) ? "@samva/markup/samva-brand" : ASSET_MODULE_NOT_FOUND.test(message) ? "vite/client" : undefined;
|
|
79868
|
+
return types === undefined ? message : `${message} Add "${types}" to compilerOptions.types in ${basename3(tsconfig)}.`;
|
|
79869
|
+
};
|
|
79319
79870
|
var parseTypeScriptDiagnostics = (output, tsconfig) => output.split(`
|
|
79320
79871
|
`).filter((line) => line.length > 0).map((line) => {
|
|
79321
79872
|
const match = TSC_DIAGNOSTIC_LINE.exec(line);
|
|
79322
79873
|
return match === null ? { file: tsconfig, code: "TSC", message: line } : {
|
|
79323
79874
|
file: match[1] ?? tsconfig,
|
|
79324
79875
|
code: match[4] ?? "TSC",
|
|
79325
|
-
message: match[5] ?? line,
|
|
79876
|
+
message: withTypesHint(match[5] ?? line, tsconfig),
|
|
79326
79877
|
...match[2] === undefined ? {} : { line: Number(match[2]) },
|
|
79327
79878
|
...match[3] === undefined ? {} : { column: Number(match[3]) }
|
|
79328
79879
|
};
|
|
@@ -79330,16 +79881,16 @@ var parseTypeScriptDiagnostics = (output, tsconfig) => output.split(`
|
|
|
79330
79881
|
var typecheckProject = (tsconfig) => tryPromise2({
|
|
79331
79882
|
try: async () => {
|
|
79332
79883
|
const typescriptPackage = Bun.resolveSync("typescript/package.json", process.cwd());
|
|
79333
|
-
const tsc =
|
|
79884
|
+
const tsc = resolve17(dirname5(typescriptPackage), "bin/tsc");
|
|
79334
79885
|
const typescriptManifest = await Bun.file(typescriptPackage).json();
|
|
79335
|
-
const child = Bun.spawn(["node", tsc, "--noEmit", "--pretty", "false", "--project",
|
|
79886
|
+
const child = Bun.spawn(["node", tsc, "--noEmit", "--pretty", "false", "--project", resolve17(tsconfig)], { cwd: process.cwd(), stdout: "pipe", stderr: "pipe" });
|
|
79336
79887
|
const [stdout, stderr, exitCode] = await Promise.all([
|
|
79337
79888
|
new Response(child.stdout).text(),
|
|
79338
79889
|
new Response(child.stderr).text(),
|
|
79339
79890
|
child.exited
|
|
79340
79891
|
]);
|
|
79341
79892
|
const output = `${stdout}${stderr}`.trim();
|
|
79342
|
-
const diagnostics = parseTypeScriptDiagnostics(output,
|
|
79893
|
+
const diagnostics = parseTypeScriptDiagnostics(output, resolve17(tsconfig));
|
|
79343
79894
|
if (exitCode !== 0 && diagnostics.length === 0) {
|
|
79344
79895
|
return Promise.reject(new SamvaCliError({
|
|
79345
79896
|
message: output || `Could not run TypeScript from this project. Install typescript and check ${tsconfig}.`
|
|
@@ -79421,7 +79972,7 @@ var observeTemplateCheck = (dir, tsconfig, build) => gen2(function* () {
|
|
|
79421
79972
|
problems: typeProblems
|
|
79422
79973
|
}
|
|
79423
79974
|
});
|
|
79424
|
-
const attempted = typeProblems.length > 0 ? yield*
|
|
79975
|
+
const attempted = typeProblems.length > 0 ? yield* build().pipe(asSome2, catchTag2("SamvaCliError", () => succeed6(none2()))) : some2(yield* build());
|
|
79425
79976
|
if (isNone2(attempted))
|
|
79426
79977
|
return typeFailure();
|
|
79427
79978
|
const built = attempted.value;
|
|
@@ -79433,7 +79984,15 @@ var observeTemplateCheck = (dir, tsconfig, build) => gen2(function* () {
|
|
|
79433
79984
|
const ok = typeProblems.length === 0 && isSuccessfulBuild(built);
|
|
79434
79985
|
const compilerVersion = built.compilerVersion;
|
|
79435
79986
|
const warnings = compatibilityFindings(built, "warning");
|
|
79436
|
-
const
|
|
79987
|
+
const failureMessage = () => {
|
|
79988
|
+
if (typeProblems.length > 0) {
|
|
79989
|
+
return `TypeScript check failed (${typeProblems.length} problem(s)); template check found ${problems.length - typeProblems.length} more.`;
|
|
79990
|
+
}
|
|
79991
|
+
if (built.files.length === 0)
|
|
79992
|
+
return NO_TEMPLATES(dir);
|
|
79993
|
+
return `Template check failed (${problems.length} problem(s)).`;
|
|
79994
|
+
};
|
|
79995
|
+
const message = ok ? `TypeScript v${typecheck.version} \xB7 compiler ${compilerVersion} \xB7 ${built.files.length} template(s) compiled \xB7 ${warnings.length} compatibility warning(s)` : failureMessage();
|
|
79437
79996
|
return {
|
|
79438
79997
|
ok,
|
|
79439
79998
|
message,
|
|
@@ -79634,7 +80193,7 @@ var build3 = make29("build", {
|
|
|
79634
80193
|
}
|
|
79635
80194
|
return yield* new SamvaCliError({ message });
|
|
79636
80195
|
}
|
|
79637
|
-
const target =
|
|
80196
|
+
const target = resolve17(out);
|
|
79638
80197
|
const artifact = toTemplateBuildArtifact(built);
|
|
79639
80198
|
yield* writeJsonFile(target, artifact);
|
|
79640
80199
|
const result = {
|
|
@@ -79718,7 +80277,7 @@ var createRemote = make29("create", {
|
|
|
79718
80277
|
data: String9("data").pipe(withDescription2("Complete template JSON payload")),
|
|
79719
80278
|
namespace: namespaceFlag("create"),
|
|
79720
80279
|
shared: Boolean6("shared").pipe(withDescription2("Share the new organization-level project with every namespace; namespace-scoped keys read and send it but cannot change it"), withDefault5(false)),
|
|
79721
|
-
dryRun:
|
|
80280
|
+
dryRun: dryRunFlag7,
|
|
79722
80281
|
json: jsonFlag
|
|
79723
80282
|
}).pipe(withDescription3("Create a remote template from JSON"), withExamples([
|
|
79724
80283
|
{
|
|
@@ -79761,7 +80320,7 @@ var updateRemote = make29("update", {
|
|
|
79761
80320
|
id: templateIdArgument2,
|
|
79762
80321
|
data: String9("data").pipe(withDescription2("JSON object of template fields to update")),
|
|
79763
80322
|
shared: Literals3("shared", ["true", "false"]).pipe(withDescription2("Share the template's organization-level project with every namespace (true) or stop sharing it (false); applies to every entry in the project"), optional4),
|
|
79764
|
-
dryRun:
|
|
80323
|
+
dryRun: dryRunFlag7,
|
|
79765
80324
|
json: jsonFlag
|
|
79766
80325
|
}).pipe(withDescription3("Update a remote template from JSON"), withExamples([
|
|
79767
80326
|
{
|
|
@@ -79791,7 +80350,7 @@ var updateRemote = make29("update", {
|
|
|
79791
80350
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
79792
80351
|
var removeRemote = make29("remove", {
|
|
79793
80352
|
id: templateIdArgument2,
|
|
79794
|
-
dryRun:
|
|
80353
|
+
dryRun: dryRunFlag7,
|
|
79795
80354
|
yes: Boolean6("yes").pipe(withDescription2("Confirm destructive state change"), withDefault5(false)),
|
|
79796
80355
|
json: jsonFlag
|
|
79797
80356
|
}).pipe(withDescription3("Deactivate a remote template; its project file and publications remain"), withExamples([{ command: "samva templates remove tmpl_abc123 --dry-run" }]), withHandler(({ id, dryRun, yes, json }) => gen2(function* () {
|
|
@@ -79804,7 +80363,7 @@ var removeRemote = make29("remove", {
|
|
|
79804
80363
|
nonInteractiveMessage: "remove requires --yes in non-interactive mode. Preview with --dry-run."
|
|
79805
80364
|
});
|
|
79806
80365
|
const client = yield* getClientProvider;
|
|
79807
|
-
const result = yield*
|
|
80366
|
+
const result = yield* remove15({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not remove template", error)));
|
|
79808
80367
|
if (json)
|
|
79809
80368
|
return yield* printJson(result);
|
|
79810
80369
|
yield* printFields([
|
|
@@ -79812,18 +80371,6 @@ var removeRemote = make29("remove", {
|
|
|
79812
80371
|
["Removed", result.success]
|
|
79813
80372
|
]);
|
|
79814
80373
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
79815
|
-
var exportProject = (input) => runToolchain({
|
|
79816
|
-
action: `Could not export templates${input.dir === undefined ? "" : ` in ${input.dir}`}`,
|
|
79817
|
-
options: {
|
|
79818
|
-
root: process.cwd(),
|
|
79819
|
-
out: resolve16(input.out),
|
|
79820
|
-
...input.dir === undefined ? {} : { dir: resolve16(input.dir) },
|
|
79821
|
-
...input.assetBase === undefined ? {} : { assetBase: input.assetBase }
|
|
79822
|
-
},
|
|
79823
|
-
script: `import { exportProject } from "@samva/vite/project"; ${OPTIONS_PRELUDE}
|
|
79824
|
-
${brandResolverPrelude()}
|
|
79825
|
-
process.stdout.write(JSON.stringify(await exportProject(options)));`
|
|
79826
|
-
});
|
|
79827
80374
|
var exportCommand = make29("export", {
|
|
79828
80375
|
dir: dirFlag,
|
|
79829
80376
|
out: Directory2("out").pipe(withDescription2("Directory to write rendered fixtures, assets, and the catalog into")),
|
|
@@ -79844,7 +80391,7 @@ var exportCommand = make29("export", {
|
|
|
79844
80391
|
const result = {
|
|
79845
80392
|
action: "templates.export",
|
|
79846
80393
|
ok: errors.length === 0,
|
|
79847
|
-
out:
|
|
80394
|
+
out: resolve17(out),
|
|
79848
80395
|
assetBase: receipt.assets.base,
|
|
79849
80396
|
templates: receipt.templates.map((template) => ({
|
|
79850
80397
|
id: template.id,
|
|
@@ -80486,7 +81033,7 @@ var list27 = /* @__PURE__ */ make55("webhooksList");
|
|
|
80486
81033
|
var create16 = /* @__PURE__ */ make55("webhooksCreate");
|
|
80487
81034
|
var getSecret = /* @__PURE__ */ make55("webhooksGetSecret");
|
|
80488
81035
|
var get28 = /* @__PURE__ */ make55("webhooksGet");
|
|
80489
|
-
var
|
|
81036
|
+
var remove16 = /* @__PURE__ */ make55("webhooksRemove");
|
|
80490
81037
|
var update14 = /* @__PURE__ */ make55("webhooksUpdate");
|
|
80491
81038
|
var test = /* @__PURE__ */ make55("webhooksTest");
|
|
80492
81039
|
var getLogs = /* @__PURE__ */ make55("webhooksGetLogs");
|
|
@@ -80749,11 +81296,11 @@ var rotate3 = make29("rotate-secret", {
|
|
|
80749
81296
|
const client = yield* getClientProvider;
|
|
80750
81297
|
const data = yield* regenerateSecret({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not rotate webhook secret", error)));
|
|
80751
81298
|
const warning = `Read this signing secret again with samva webhooks secret ${id}. The previous secret remains valid for 24 hours.`;
|
|
80752
|
-
const
|
|
81299
|
+
const signingSecret = value2(data.secret);
|
|
80753
81300
|
if (json)
|
|
80754
|
-
return yield* printJson({ secret, warning });
|
|
81301
|
+
return yield* printJson({ secret: signingSecret, warning });
|
|
80755
81302
|
yield* error(`WARNING: ${warning}`);
|
|
80756
|
-
yield* log(
|
|
81303
|
+
yield* log(signingSecret);
|
|
80757
81304
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
80758
81305
|
var create17 = make29("create", {
|
|
80759
81306
|
data: String9("data").pipe(withDescription2("Webhook JSON: name, url, eventTypes, and optional retry settings")),
|
|
@@ -80773,16 +81320,17 @@ var create17 = make29("create", {
|
|
|
80773
81320
|
const client = yield* getClientProvider;
|
|
80774
81321
|
const result = yield* create16(payload).pipe(client.provide, mapError2((error) => toCliApiError("Could not create webhook", error)));
|
|
80775
81322
|
const warning = `Read this signing secret again with samva webhooks secret ${result.endpoint.id}.`;
|
|
80776
|
-
const
|
|
80777
|
-
if (json)
|
|
80778
|
-
return yield* printJson({ endpoint: result.endpoint, secret, warning });
|
|
81323
|
+
const signingSecret = value2(result.secret);
|
|
81324
|
+
if (json) {
|
|
81325
|
+
return yield* printJson({ endpoint: result.endpoint, secret: signingSecret, warning });
|
|
81326
|
+
}
|
|
80779
81327
|
yield* error(`WARNING: ${warning}`);
|
|
80780
81328
|
yield* printFields([
|
|
80781
81329
|
["ID", result.endpoint.id],
|
|
80782
81330
|
["Name", result.endpoint.name],
|
|
80783
81331
|
["Status", result.endpoint.status],
|
|
80784
81332
|
["URL", result.endpoint.url],
|
|
80785
|
-
["Signing secret",
|
|
81333
|
+
["Signing secret", signingSecret]
|
|
80786
81334
|
]);
|
|
80787
81335
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
80788
81336
|
var update15 = make29("update", {
|
|
@@ -80808,7 +81356,7 @@ var update15 = make29("update", {
|
|
|
80808
81356
|
return yield* printJson(result);
|
|
80809
81357
|
yield* printFields(objectRows(result));
|
|
80810
81358
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
80811
|
-
var
|
|
81359
|
+
var remove17 = make29("remove", {
|
|
80812
81360
|
id: idArgument4,
|
|
80813
81361
|
dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
|
|
80814
81362
|
yes: Boolean6("yes").pipe(withDefault5(false)),
|
|
@@ -80826,7 +81374,7 @@ var remove15 = make29("remove", {
|
|
|
80826
81374
|
nonInteractiveMessage: "Permanent webhook deletion requires --yes in non-interactive mode. Preview with --dry-run."
|
|
80827
81375
|
});
|
|
80828
81376
|
const client = yield* getClientProvider;
|
|
80829
|
-
const result = yield*
|
|
81377
|
+
const result = yield* remove16({ id }).pipe(client.provide, mapError2((error) => toCliApiError("Could not remove webhook", error)));
|
|
80830
81378
|
if (json)
|
|
80831
81379
|
return yield* printJson(result);
|
|
80832
81380
|
yield* log(`Removed webhook ${id}.`);
|
|
@@ -80842,7 +81390,7 @@ var webhooksCommand = make29("webhooks").pipe(withDescription3("Inspect, test, a
|
|
|
80842
81390
|
stats3,
|
|
80843
81391
|
retry4,
|
|
80844
81392
|
rotate3,
|
|
80845
|
-
|
|
81393
|
+
remove17
|
|
80846
81394
|
]));
|
|
80847
81395
|
|
|
80848
81396
|
// src/lib/root-commands.ts
|
|
@@ -80913,6 +81461,40 @@ var cli = make29("samva").pipe(withDescription3(`Samva \u2014 email and platform
|
|
|
80913
81461
|
}
|
|
80914
81462
|
]), withSubcommands([...rootCommands, helpCommand]), withGlobalFlags(globalFlags));
|
|
80915
81463
|
|
|
81464
|
+
// src/lib/help-json.ts
|
|
81465
|
+
var description = (value) => getOrNull(value);
|
|
81466
|
+
var flag = (doc) => ({
|
|
81467
|
+
name: doc.name,
|
|
81468
|
+
aliases: doc.aliases,
|
|
81469
|
+
type: doc.type,
|
|
81470
|
+
description: description(doc.description),
|
|
81471
|
+
required: doc.required
|
|
81472
|
+
});
|
|
81473
|
+
var helpDocJson = (doc) => ({
|
|
81474
|
+
schemaVersion: 1,
|
|
81475
|
+
description: doc.description,
|
|
81476
|
+
usage: doc.usage,
|
|
81477
|
+
flags: doc.flags.map(flag),
|
|
81478
|
+
globalFlags: (doc.globalFlags ?? []).map(flag),
|
|
81479
|
+
args: (doc.args ?? []).map((arg) => ({
|
|
81480
|
+
name: arg.name,
|
|
81481
|
+
type: arg.type,
|
|
81482
|
+
description: description(arg.description),
|
|
81483
|
+
required: arg.required,
|
|
81484
|
+
variadic: arg.variadic
|
|
81485
|
+
})),
|
|
81486
|
+
subcommands: (doc.subcommands ?? []).flatMap((group) => group.commands.map((command) => ({
|
|
81487
|
+
name: command.name,
|
|
81488
|
+
alias: command.alias ?? null,
|
|
81489
|
+
description: command.shortDescription ?? command.description,
|
|
81490
|
+
group: group.group ?? null
|
|
81491
|
+
}))),
|
|
81492
|
+
examples: (doc.examples ?? []).map((example) => ({
|
|
81493
|
+
command: example.command,
|
|
81494
|
+
description: example.description ?? null
|
|
81495
|
+
}))
|
|
81496
|
+
});
|
|
81497
|
+
|
|
80916
81498
|
// src/bin.ts
|
|
80917
81499
|
var argv = process.argv.slice(2);
|
|
80918
81500
|
var outputMode = outputModeFromArgv(argv);
|
|
@@ -80938,7 +81520,7 @@ var rootMachineHelp = (() => {
|
|
|
80938
81520
|
}
|
|
80939
81521
|
return { requested, command: undefined };
|
|
80940
81522
|
})();
|
|
80941
|
-
var
|
|
81523
|
+
var helpRequested = processArgs.some((token) => token === "--help" || token === "-h");
|
|
80942
81524
|
var isUnknownRootMachineHelp = machineMode && rootMachineHelp.requested && rootMachineHelp.command !== undefined && !isKnownRootCommand(rootMachineHelp.command);
|
|
80943
81525
|
var cliLogger = make30(({ logLevel, message }) => {
|
|
80944
81526
|
const text = (Array.isArray(message) ? message : [message]).map(String).join(" ");
|
|
@@ -80964,11 +81546,21 @@ var isBareHelp = (error) => error instanceof ShowHelp && error.errors.length ===
|
|
|
80964
81546
|
var formatter = {
|
|
80965
81547
|
...defaultFormatter2(),
|
|
80966
81548
|
formatError: () => "",
|
|
80967
|
-
formatErrors: () => ""
|
|
81549
|
+
formatErrors: () => "",
|
|
81550
|
+
...machineMode && helpRequested ? {
|
|
81551
|
+
formatHelpDoc: (doc) => JSON.stringify(helpDocJson(doc))
|
|
81552
|
+
} : {}
|
|
80968
81553
|
};
|
|
80969
81554
|
var flushSuccessfulResults = (state, partial = false) => gen2(function* () {
|
|
80970
|
-
if (outputMode === "quiet"
|
|
81555
|
+
if (outputMode === "quiet")
|
|
80971
81556
|
return;
|
|
81557
|
+
if (outputMode === "jsonl") {
|
|
81558
|
+
if (helpRequested && state.lines.length === 1) {
|
|
81559
|
+
yield* writeOutput(process.stdout, `${JSON.stringify(resultEnvelope(commandNameFromArgv(argv), JSON.parse(state.lines[0])))}
|
|
81560
|
+
`);
|
|
81561
|
+
}
|
|
81562
|
+
return;
|
|
81563
|
+
}
|
|
80972
81564
|
if (outputMode === "human") {
|
|
80973
81565
|
if (state.lines.length > 0) {
|
|
80974
81566
|
yield* writeOutput(process.stdout, `${state.lines.join(`
|
|
@@ -81070,12 +81662,7 @@ Try: ${next}`}`);
|
|
|
81070
81662
|
}
|
|
81071
81663
|
yield* printJsonError(error2, message);
|
|
81072
81664
|
});
|
|
81073
|
-
var
|
|
81074
|
-
const payload = resultEnvelope(commandNameFromArgv(argv), helpManifest);
|
|
81075
|
-
yield* writeOutput(process.stdout, `${JSON.stringify(payload, null, outputMode === "jsonl" ? undefined : 2)}
|
|
81076
|
-
`);
|
|
81077
|
-
});
|
|
81078
|
-
var program = (isRootMachineHelp ? validateProcessArgs(argv).pipe(flatMap3(() => runMachineHelp)) : isUnknownRootMachineHelp ? validateProcessArgs(argv).pipe(flatMap3(() => new CliUsageError({
|
|
81665
|
+
var program = (isUnknownRootMachineHelp ? validateProcessArgs(argv).pipe(flatMap3(() => new CliUsageError({
|
|
81079
81666
|
code: "unknown_subcommand",
|
|
81080
81667
|
message: `Unknown subcommand ${JSON.stringify(rootMachineHelp.command)} for samva.`
|
|
81081
81668
|
}))) : withStdoutBuffer(validateProcessArgs(argv).pipe(flatMap3(() => run5(cli, { version: package_default.version }))))).pipe(provide4(mergeAll2(layer14([cliLogger]), layer12, layer13(formatter), layer17)), matchEffect3({
|