@vivoa/plugin-sdk 0.6.5 → 0.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-DGJZW46B.mjs +37 -0
- package/dist/host-api-yX49e7zE.d.mts +1533 -0
- package/dist/host-api-yX49e7zE.d.ts +1533 -0
- package/dist/index.d.mts +5 -1382
- package/dist/index.d.ts +5 -1382
- package/dist/index.js +155 -14
- package/dist/index.mjs +166 -44
- package/dist/testing/index.d.mts +54 -0
- package/dist/testing/index.d.ts +54 -0
- package/dist/testing/index.js +169 -0
- package/dist/testing/index.mjs +113 -0
- package/package.json +15 -9
package/dist/index.js
CHANGED
|
@@ -21,12 +21,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
ANALYTICS_PLUGIN_TOKEN: () => ANALYTICS_PLUGIN_TOKEN,
|
|
24
|
+
AUTHOR_HANDLE_RE: () => AUTHOR_HANDLE_RE,
|
|
24
25
|
ActionVariant: () => ActionVariant,
|
|
25
26
|
AnalyticsFeature: () => AnalyticsFeature,
|
|
26
27
|
BlockType: () => BlockType,
|
|
27
28
|
CapabilityKind: () => CapabilityKind,
|
|
28
29
|
CodFeeType: () => CodFeeType,
|
|
29
30
|
ConfigScope: () => ConfigScope,
|
|
31
|
+
ContentActionVariant: () => ContentActionVariant,
|
|
32
|
+
ContentBlockType: () => ContentBlockType,
|
|
30
33
|
FieldType: () => FieldType,
|
|
31
34
|
FieldVariant: () => FieldVariant,
|
|
32
35
|
GatewayEnvironment: () => GatewayEnvironment,
|
|
@@ -37,7 +40,6 @@ __export(index_exports, {
|
|
|
37
40
|
LayoutMode: () => LayoutMode,
|
|
38
41
|
MessageVariant: () => MessageVariant,
|
|
39
42
|
PAYMENT_PLUGIN_TOKEN: () => PAYMENT_PLUGIN_TOKEN,
|
|
40
|
-
PluginType: () => PluginType,
|
|
41
43
|
RepeaterSource: () => RepeaterSource,
|
|
42
44
|
SDK_VERSION: () => SDK_VERSION,
|
|
43
45
|
SHIPPING_PLUGIN_TOKEN: () => SHIPPING_PLUGIN_TOKEN,
|
|
@@ -62,7 +64,10 @@ __export(index_exports, {
|
|
|
62
64
|
paymentCapability: () => paymentCapability,
|
|
63
65
|
shippingCapability: () => shippingCapability,
|
|
64
66
|
suppliersCapability: () => suppliersCapability,
|
|
65
|
-
|
|
67
|
+
uiCapability: () => uiCapability,
|
|
68
|
+
validatePluginAuthor: () => validatePluginAuthor,
|
|
69
|
+
validateSetupLayout: () => validateSetupLayout,
|
|
70
|
+
validateUiContributions: () => validateUiContributions
|
|
66
71
|
});
|
|
67
72
|
module.exports = __toCommonJS(index_exports);
|
|
68
73
|
|
|
@@ -74,14 +79,6 @@ var ANALYTICS_PLUGIN_TOKEN = "ANALYTICS_PLUGINS";
|
|
|
74
79
|
var INVOICING_PLUGIN_TOKEN = "INVOICING_PLUGINS";
|
|
75
80
|
|
|
76
81
|
// src/plugin.ts
|
|
77
|
-
var PluginType = /* @__PURE__ */ ((PluginType2) => {
|
|
78
|
-
PluginType2["Payment"] = "payment";
|
|
79
|
-
PluginType2["Shipping"] = "shipping";
|
|
80
|
-
PluginType2["Analytics"] = "analytics";
|
|
81
|
-
PluginType2["Invoicing"] = "invoicing";
|
|
82
|
-
PluginType2["Generic"] = "generic";
|
|
83
|
-
return PluginType2;
|
|
84
|
-
})(PluginType || {});
|
|
85
82
|
var MessageVariant = /* @__PURE__ */ ((MessageVariant2) => {
|
|
86
83
|
MessageVariant2["Info"] = "info";
|
|
87
84
|
MessageVariant2["Warning"] = "warning";
|
|
@@ -244,6 +241,30 @@ var InvoiceStatus = /* @__PURE__ */ ((InvoiceStatus2) => {
|
|
|
244
241
|
return InvoiceStatus2;
|
|
245
242
|
})(InvoiceStatus || {});
|
|
246
243
|
|
|
244
|
+
// src/author.ts
|
|
245
|
+
var AUTHOR_HANDLE_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
246
|
+
function validatePluginAuthor(value) {
|
|
247
|
+
const errors = [];
|
|
248
|
+
if (typeof value !== "object" || value === null) {
|
|
249
|
+
return { ok: false, errors: ["author is required and must be an object"] };
|
|
250
|
+
}
|
|
251
|
+
const a = value;
|
|
252
|
+
if (typeof a.handle !== "string" || a.handle.length === 0) {
|
|
253
|
+
errors.push("author.handle is required");
|
|
254
|
+
} else if (!AUTHOR_HANDLE_RE.test(a.handle)) {
|
|
255
|
+
errors.push(
|
|
256
|
+
`author.handle "${a.handle}" must be a lowercase slug (a-z, 0-9, dash; start alphanumeric)`
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
if (typeof a.displayName !== "string" || a.displayName.trim().length === 0) {
|
|
260
|
+
errors.push("author.displayName is required");
|
|
261
|
+
}
|
|
262
|
+
if (a.url !== void 0 && typeof a.url !== "string") {
|
|
263
|
+
errors.push("author.url must be a string when present");
|
|
264
|
+
}
|
|
265
|
+
return { ok: errors.length === 0, errors };
|
|
266
|
+
}
|
|
267
|
+
|
|
247
268
|
// src/setup-layout.ts
|
|
248
269
|
var import_superstruct2 = require("superstruct");
|
|
249
270
|
var FieldVariant = /* @__PURE__ */ ((FieldVariant2) => {
|
|
@@ -314,6 +335,7 @@ var sGroupBlock = (0, import_superstruct2.object)({
|
|
|
314
335
|
type: (0, import_superstruct2.literal)("group" /* Group */),
|
|
315
336
|
title: (0, import_superstruct2.string)(),
|
|
316
337
|
description: (0, import_superstruct2.optional)((0, import_superstruct2.string)()),
|
|
338
|
+
helpUrl: (0, import_superstruct2.optional)((0, import_superstruct2.string)()),
|
|
317
339
|
fields: (0, import_superstruct2.array)((0, import_superstruct2.string)()),
|
|
318
340
|
collapsible: (0, import_superstruct2.optional)((0, import_superstruct2.boolean)()),
|
|
319
341
|
defaultOpen: (0, import_superstruct2.optional)((0, import_superstruct2.boolean)()),
|
|
@@ -510,13 +532,124 @@ function crossValidateSetupLayout(layout, configSchema) {
|
|
|
510
532
|
return errors;
|
|
511
533
|
}
|
|
512
534
|
|
|
535
|
+
// src/ui.ts
|
|
536
|
+
var import_superstruct3 = require("superstruct");
|
|
537
|
+
var ContentBlockType = /* @__PURE__ */ ((ContentBlockType2) => {
|
|
538
|
+
ContentBlockType2["Text"] = "text";
|
|
539
|
+
ContentBlockType2["Banner"] = "banner";
|
|
540
|
+
ContentBlockType2["Badge"] = "badge";
|
|
541
|
+
ContentBlockType2["KeyValue"] = "keyValue";
|
|
542
|
+
ContentBlockType2["CopyField"] = "copyField";
|
|
543
|
+
ContentBlockType2["Link"] = "link";
|
|
544
|
+
ContentBlockType2["Divider"] = "divider";
|
|
545
|
+
ContentBlockType2["Action"] = "action";
|
|
546
|
+
ContentBlockType2["Card"] = "card";
|
|
547
|
+
return ContentBlockType2;
|
|
548
|
+
})(ContentBlockType || {});
|
|
549
|
+
var ContentActionVariant = /* @__PURE__ */ ((ContentActionVariant2) => {
|
|
550
|
+
ContentActionVariant2["Primary"] = "primary";
|
|
551
|
+
ContentActionVariant2["Secondary"] = "secondary";
|
|
552
|
+
ContentActionVariant2["Danger"] = "danger";
|
|
553
|
+
return ContentActionVariant2;
|
|
554
|
+
})(ContentActionVariant || {});
|
|
555
|
+
var sMessageVariant2 = (0, import_superstruct3.enums)(Object.values(MessageVariant));
|
|
556
|
+
var sContentActionVariant = (0, import_superstruct3.enums)(Object.values(ContentActionVariant));
|
|
557
|
+
var sTextBlock = (0, import_superstruct3.object)({
|
|
558
|
+
type: (0, import_superstruct3.literal)("text" /* Text */),
|
|
559
|
+
content: (0, import_superstruct3.optional)((0, import_superstruct3.string)()),
|
|
560
|
+
computedKey: (0, import_superstruct3.optional)((0, import_superstruct3.string)())
|
|
561
|
+
});
|
|
562
|
+
var sBannerBlock2 = (0, import_superstruct3.object)({
|
|
563
|
+
type: (0, import_superstruct3.literal)("banner" /* Banner */),
|
|
564
|
+
variant: sMessageVariant2,
|
|
565
|
+
title: (0, import_superstruct3.optional)((0, import_superstruct3.string)()),
|
|
566
|
+
text: (0, import_superstruct3.string)()
|
|
567
|
+
});
|
|
568
|
+
var sBadgeBlock = (0, import_superstruct3.object)({
|
|
569
|
+
type: (0, import_superstruct3.literal)("badge" /* Badge */),
|
|
570
|
+
variant: sMessageVariant2,
|
|
571
|
+
text: (0, import_superstruct3.optional)((0, import_superstruct3.string)()),
|
|
572
|
+
computedKey: (0, import_superstruct3.optional)((0, import_superstruct3.string)())
|
|
573
|
+
});
|
|
574
|
+
var sKeyValueBlock2 = (0, import_superstruct3.object)({
|
|
575
|
+
type: (0, import_superstruct3.literal)("keyValue" /* KeyValue */),
|
|
576
|
+
rows: (0, import_superstruct3.array)(
|
|
577
|
+
(0, import_superstruct3.object)({
|
|
578
|
+
label: (0, import_superstruct3.string)(),
|
|
579
|
+
value: (0, import_superstruct3.optional)((0, import_superstruct3.string)()),
|
|
580
|
+
computedKey: (0, import_superstruct3.optional)((0, import_superstruct3.string)())
|
|
581
|
+
})
|
|
582
|
+
)
|
|
583
|
+
});
|
|
584
|
+
var sCopyFieldBlock2 = (0, import_superstruct3.object)({
|
|
585
|
+
type: (0, import_superstruct3.literal)("copyField" /* CopyField */),
|
|
586
|
+
label: (0, import_superstruct3.string)(),
|
|
587
|
+
value: (0, import_superstruct3.optional)((0, import_superstruct3.string)()),
|
|
588
|
+
computedKey: (0, import_superstruct3.optional)((0, import_superstruct3.string)())
|
|
589
|
+
});
|
|
590
|
+
var sLinkBlock = (0, import_superstruct3.object)({
|
|
591
|
+
type: (0, import_superstruct3.literal)("link" /* Link */),
|
|
592
|
+
label: (0, import_superstruct3.string)(),
|
|
593
|
+
href: (0, import_superstruct3.optional)((0, import_superstruct3.string)()),
|
|
594
|
+
computedKey: (0, import_superstruct3.optional)((0, import_superstruct3.string)()),
|
|
595
|
+
external: (0, import_superstruct3.optional)((0, import_superstruct3.boolean)())
|
|
596
|
+
});
|
|
597
|
+
var sDividerBlock2 = (0, import_superstruct3.object)({ type: (0, import_superstruct3.literal)("divider" /* Divider */) });
|
|
598
|
+
var sActionBlock2 = (0, import_superstruct3.object)({
|
|
599
|
+
type: (0, import_superstruct3.literal)("action" /* Action */),
|
|
600
|
+
id: (0, import_superstruct3.string)(),
|
|
601
|
+
label: (0, import_superstruct3.string)(),
|
|
602
|
+
variant: (0, import_superstruct3.optional)(sContentActionVariant)
|
|
603
|
+
});
|
|
604
|
+
var sCardBlock2 = (0, import_superstruct3.object)({
|
|
605
|
+
type: (0, import_superstruct3.literal)("card" /* Card */),
|
|
606
|
+
title: (0, import_superstruct3.optional)((0, import_superstruct3.string)()),
|
|
607
|
+
description: (0, import_superstruct3.optional)((0, import_superstruct3.string)()),
|
|
608
|
+
blocks: (0, import_superstruct3.array)((0, import_superstruct3.lazy)(() => sContentBlock))
|
|
609
|
+
});
|
|
610
|
+
var sContentBlock = (0, import_superstruct3.union)([
|
|
611
|
+
sTextBlock,
|
|
612
|
+
sBannerBlock2,
|
|
613
|
+
sBadgeBlock,
|
|
614
|
+
sKeyValueBlock2,
|
|
615
|
+
sCopyFieldBlock2,
|
|
616
|
+
sLinkBlock,
|
|
617
|
+
sDividerBlock2,
|
|
618
|
+
sActionBlock2,
|
|
619
|
+
sCardBlock2
|
|
620
|
+
]);
|
|
621
|
+
var sUiContribution = (0, import_superstruct3.object)({
|
|
622
|
+
slot: (0, import_superstruct3.string)(),
|
|
623
|
+
blocks: (0, import_superstruct3.array)(sContentBlock),
|
|
624
|
+
order: (0, import_superstruct3.optional)((0, import_superstruct3.number)())
|
|
625
|
+
});
|
|
626
|
+
function validateUiContributions(input) {
|
|
627
|
+
const [error, result] = (0, import_superstruct3.validate)(input, (0, import_superstruct3.array)(sUiContribution));
|
|
628
|
+
if (error) {
|
|
629
|
+
return {
|
|
630
|
+
success: false,
|
|
631
|
+
errors: error.failures().map((f) => {
|
|
632
|
+
const path = f.path.join(".");
|
|
633
|
+
return path ? `${path}: ${f.message}` : f.message;
|
|
634
|
+
})
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
return { success: true, data: result };
|
|
638
|
+
}
|
|
639
|
+
|
|
513
640
|
// src/capability.ts
|
|
514
641
|
var CapabilityKind = {
|
|
515
642
|
Payment: "payment",
|
|
516
643
|
Shipping: "shipping",
|
|
517
644
|
Suppliers: "suppliers",
|
|
518
645
|
Analytics: "analytics",
|
|
519
|
-
Invoicing: "invoicing"
|
|
646
|
+
Invoicing: "invoicing",
|
|
647
|
+
/**
|
|
648
|
+
* Cross-cutting DISPLAY capability: a plugin of ANY surface may ALSO expose
|
|
649
|
+
* `ui` to contribute declarative blocks into host slots. Not a catalog
|
|
650
|
+
* "surface" — the host's AppSurface derivation excludes it on purpose.
|
|
651
|
+
*/
|
|
652
|
+
Ui: "ui"
|
|
520
653
|
};
|
|
521
654
|
function capability(kind, impl) {
|
|
522
655
|
return { kind, impl };
|
|
@@ -536,6 +669,9 @@ function analyticsCapability(impl) {
|
|
|
536
669
|
function invoicingCapability(impl) {
|
|
537
670
|
return { kind: CapabilityKind.Invoicing, impl };
|
|
538
671
|
}
|
|
672
|
+
function uiCapability(impl) {
|
|
673
|
+
return { kind: CapabilityKind.Ui, impl };
|
|
674
|
+
}
|
|
539
675
|
var PLUGIN_FACTORY_BRAND = /* @__PURE__ */ Symbol.for("vivoa.plugin.factory");
|
|
540
676
|
function definePlugin(factory) {
|
|
541
677
|
Object.defineProperty(factory, PLUGIN_FACTORY_BRAND, {
|
|
@@ -581,7 +717,7 @@ function checkPermissions(required, grantedRaw) {
|
|
|
581
717
|
}
|
|
582
718
|
|
|
583
719
|
// src/version.ts
|
|
584
|
-
var SDK_VERSION = "0.6.
|
|
720
|
+
var SDK_VERSION = "0.6.7";
|
|
585
721
|
function isSdkCompatible(pluginSdkVersion, hostSdkVersion) {
|
|
586
722
|
const parse = (v) => {
|
|
587
723
|
const m = /^(\d+)\.(\d+)\.(\d+)/.exec(v);
|
|
@@ -599,12 +735,15 @@ function isSdkCompatible(pluginSdkVersion, hostSdkVersion) {
|
|
|
599
735
|
// Annotate the CommonJS export names for ESM import in node:
|
|
600
736
|
0 && (module.exports = {
|
|
601
737
|
ANALYTICS_PLUGIN_TOKEN,
|
|
738
|
+
AUTHOR_HANDLE_RE,
|
|
602
739
|
ActionVariant,
|
|
603
740
|
AnalyticsFeature,
|
|
604
741
|
BlockType,
|
|
605
742
|
CapabilityKind,
|
|
606
743
|
CodFeeType,
|
|
607
744
|
ConfigScope,
|
|
745
|
+
ContentActionVariant,
|
|
746
|
+
ContentBlockType,
|
|
608
747
|
FieldType,
|
|
609
748
|
FieldVariant,
|
|
610
749
|
GatewayEnvironment,
|
|
@@ -615,7 +754,6 @@ function isSdkCompatible(pluginSdkVersion, hostSdkVersion) {
|
|
|
615
754
|
LayoutMode,
|
|
616
755
|
MessageVariant,
|
|
617
756
|
PAYMENT_PLUGIN_TOKEN,
|
|
618
|
-
PluginType,
|
|
619
757
|
RepeaterSource,
|
|
620
758
|
SDK_VERSION,
|
|
621
759
|
SHIPPING_PLUGIN_TOKEN,
|
|
@@ -640,5 +778,8 @@ function isSdkCompatible(pluginSdkVersion, hostSdkVersion) {
|
|
|
640
778
|
paymentCapability,
|
|
641
779
|
shippingCapability,
|
|
642
780
|
suppliersCapability,
|
|
643
|
-
|
|
781
|
+
uiCapability,
|
|
782
|
+
validatePluginAuthor,
|
|
783
|
+
validateSetupLayout,
|
|
784
|
+
validateUiContributions
|
|
644
785
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
checkPermissions,
|
|
3
|
+
isPermissionGranted,
|
|
4
|
+
parsePermission
|
|
5
|
+
} from "./chunk-DGJZW46B.mjs";
|
|
6
|
+
|
|
1
7
|
// src/tokens.ts
|
|
2
8
|
var PAYMENT_PLUGIN_TOKEN = "PAYMENT_PLUGINS";
|
|
3
9
|
var SHIPPING_PLUGIN_TOKEN = "SHIPPING_PLUGINS";
|
|
@@ -6,14 +12,6 @@ var ANALYTICS_PLUGIN_TOKEN = "ANALYTICS_PLUGINS";
|
|
|
6
12
|
var INVOICING_PLUGIN_TOKEN = "INVOICING_PLUGINS";
|
|
7
13
|
|
|
8
14
|
// src/plugin.ts
|
|
9
|
-
var PluginType = /* @__PURE__ */ ((PluginType2) => {
|
|
10
|
-
PluginType2["Payment"] = "payment";
|
|
11
|
-
PluginType2["Shipping"] = "shipping";
|
|
12
|
-
PluginType2["Analytics"] = "analytics";
|
|
13
|
-
PluginType2["Invoicing"] = "invoicing";
|
|
14
|
-
PluginType2["Generic"] = "generic";
|
|
15
|
-
return PluginType2;
|
|
16
|
-
})(PluginType || {});
|
|
17
15
|
var MessageVariant = /* @__PURE__ */ ((MessageVariant2) => {
|
|
18
16
|
MessageVariant2["Info"] = "info";
|
|
19
17
|
MessageVariant2["Warning"] = "warning";
|
|
@@ -184,6 +182,30 @@ var InvoiceStatus = /* @__PURE__ */ ((InvoiceStatus2) => {
|
|
|
184
182
|
return InvoiceStatus2;
|
|
185
183
|
})(InvoiceStatus || {});
|
|
186
184
|
|
|
185
|
+
// src/author.ts
|
|
186
|
+
var AUTHOR_HANDLE_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
187
|
+
function validatePluginAuthor(value) {
|
|
188
|
+
const errors = [];
|
|
189
|
+
if (typeof value !== "object" || value === null) {
|
|
190
|
+
return { ok: false, errors: ["author is required and must be an object"] };
|
|
191
|
+
}
|
|
192
|
+
const a = value;
|
|
193
|
+
if (typeof a.handle !== "string" || a.handle.length === 0) {
|
|
194
|
+
errors.push("author.handle is required");
|
|
195
|
+
} else if (!AUTHOR_HANDLE_RE.test(a.handle)) {
|
|
196
|
+
errors.push(
|
|
197
|
+
`author.handle "${a.handle}" must be a lowercase slug (a-z, 0-9, dash; start alphanumeric)`
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
if (typeof a.displayName !== "string" || a.displayName.trim().length === 0) {
|
|
201
|
+
errors.push("author.displayName is required");
|
|
202
|
+
}
|
|
203
|
+
if (a.url !== void 0 && typeof a.url !== "string") {
|
|
204
|
+
errors.push("author.url must be a string when present");
|
|
205
|
+
}
|
|
206
|
+
return { ok: errors.length === 0, errors };
|
|
207
|
+
}
|
|
208
|
+
|
|
187
209
|
// src/setup-layout.ts
|
|
188
210
|
import {
|
|
189
211
|
array,
|
|
@@ -267,6 +289,7 @@ var sGroupBlock = object({
|
|
|
267
289
|
type: literal("group" /* Group */),
|
|
268
290
|
title: string2(),
|
|
269
291
|
description: optional2(string2()),
|
|
292
|
+
helpUrl: optional2(string2()),
|
|
270
293
|
fields: array(string2()),
|
|
271
294
|
collapsible: optional2(boolean2()),
|
|
272
295
|
defaultOpen: optional2(boolean2()),
|
|
@@ -463,13 +486,136 @@ function crossValidateSetupLayout(layout, configSchema) {
|
|
|
463
486
|
return errors;
|
|
464
487
|
}
|
|
465
488
|
|
|
489
|
+
// src/ui.ts
|
|
490
|
+
import {
|
|
491
|
+
array as array2,
|
|
492
|
+
boolean as boolean3,
|
|
493
|
+
enums as enums3,
|
|
494
|
+
lazy as lazy2,
|
|
495
|
+
literal as literal2,
|
|
496
|
+
number as number3,
|
|
497
|
+
object as object2,
|
|
498
|
+
optional as optional3,
|
|
499
|
+
string as string3,
|
|
500
|
+
union as union2,
|
|
501
|
+
validate as validate3
|
|
502
|
+
} from "superstruct";
|
|
503
|
+
var ContentBlockType = /* @__PURE__ */ ((ContentBlockType2) => {
|
|
504
|
+
ContentBlockType2["Text"] = "text";
|
|
505
|
+
ContentBlockType2["Banner"] = "banner";
|
|
506
|
+
ContentBlockType2["Badge"] = "badge";
|
|
507
|
+
ContentBlockType2["KeyValue"] = "keyValue";
|
|
508
|
+
ContentBlockType2["CopyField"] = "copyField";
|
|
509
|
+
ContentBlockType2["Link"] = "link";
|
|
510
|
+
ContentBlockType2["Divider"] = "divider";
|
|
511
|
+
ContentBlockType2["Action"] = "action";
|
|
512
|
+
ContentBlockType2["Card"] = "card";
|
|
513
|
+
return ContentBlockType2;
|
|
514
|
+
})(ContentBlockType || {});
|
|
515
|
+
var ContentActionVariant = /* @__PURE__ */ ((ContentActionVariant2) => {
|
|
516
|
+
ContentActionVariant2["Primary"] = "primary";
|
|
517
|
+
ContentActionVariant2["Secondary"] = "secondary";
|
|
518
|
+
ContentActionVariant2["Danger"] = "danger";
|
|
519
|
+
return ContentActionVariant2;
|
|
520
|
+
})(ContentActionVariant || {});
|
|
521
|
+
var sMessageVariant2 = enums3(Object.values(MessageVariant));
|
|
522
|
+
var sContentActionVariant = enums3(Object.values(ContentActionVariant));
|
|
523
|
+
var sTextBlock = object2({
|
|
524
|
+
type: literal2("text" /* Text */),
|
|
525
|
+
content: optional3(string3()),
|
|
526
|
+
computedKey: optional3(string3())
|
|
527
|
+
});
|
|
528
|
+
var sBannerBlock2 = object2({
|
|
529
|
+
type: literal2("banner" /* Banner */),
|
|
530
|
+
variant: sMessageVariant2,
|
|
531
|
+
title: optional3(string3()),
|
|
532
|
+
text: string3()
|
|
533
|
+
});
|
|
534
|
+
var sBadgeBlock = object2({
|
|
535
|
+
type: literal2("badge" /* Badge */),
|
|
536
|
+
variant: sMessageVariant2,
|
|
537
|
+
text: optional3(string3()),
|
|
538
|
+
computedKey: optional3(string3())
|
|
539
|
+
});
|
|
540
|
+
var sKeyValueBlock2 = object2({
|
|
541
|
+
type: literal2("keyValue" /* KeyValue */),
|
|
542
|
+
rows: array2(
|
|
543
|
+
object2({
|
|
544
|
+
label: string3(),
|
|
545
|
+
value: optional3(string3()),
|
|
546
|
+
computedKey: optional3(string3())
|
|
547
|
+
})
|
|
548
|
+
)
|
|
549
|
+
});
|
|
550
|
+
var sCopyFieldBlock2 = object2({
|
|
551
|
+
type: literal2("copyField" /* CopyField */),
|
|
552
|
+
label: string3(),
|
|
553
|
+
value: optional3(string3()),
|
|
554
|
+
computedKey: optional3(string3())
|
|
555
|
+
});
|
|
556
|
+
var sLinkBlock = object2({
|
|
557
|
+
type: literal2("link" /* Link */),
|
|
558
|
+
label: string3(),
|
|
559
|
+
href: optional3(string3()),
|
|
560
|
+
computedKey: optional3(string3()),
|
|
561
|
+
external: optional3(boolean3())
|
|
562
|
+
});
|
|
563
|
+
var sDividerBlock2 = object2({ type: literal2("divider" /* Divider */) });
|
|
564
|
+
var sActionBlock2 = object2({
|
|
565
|
+
type: literal2("action" /* Action */),
|
|
566
|
+
id: string3(),
|
|
567
|
+
label: string3(),
|
|
568
|
+
variant: optional3(sContentActionVariant)
|
|
569
|
+
});
|
|
570
|
+
var sCardBlock2 = object2({
|
|
571
|
+
type: literal2("card" /* Card */),
|
|
572
|
+
title: optional3(string3()),
|
|
573
|
+
description: optional3(string3()),
|
|
574
|
+
blocks: array2(lazy2(() => sContentBlock))
|
|
575
|
+
});
|
|
576
|
+
var sContentBlock = union2([
|
|
577
|
+
sTextBlock,
|
|
578
|
+
sBannerBlock2,
|
|
579
|
+
sBadgeBlock,
|
|
580
|
+
sKeyValueBlock2,
|
|
581
|
+
sCopyFieldBlock2,
|
|
582
|
+
sLinkBlock,
|
|
583
|
+
sDividerBlock2,
|
|
584
|
+
sActionBlock2,
|
|
585
|
+
sCardBlock2
|
|
586
|
+
]);
|
|
587
|
+
var sUiContribution = object2({
|
|
588
|
+
slot: string3(),
|
|
589
|
+
blocks: array2(sContentBlock),
|
|
590
|
+
order: optional3(number3())
|
|
591
|
+
});
|
|
592
|
+
function validateUiContributions(input) {
|
|
593
|
+
const [error, result] = validate3(input, array2(sUiContribution));
|
|
594
|
+
if (error) {
|
|
595
|
+
return {
|
|
596
|
+
success: false,
|
|
597
|
+
errors: error.failures().map((f) => {
|
|
598
|
+
const path = f.path.join(".");
|
|
599
|
+
return path ? `${path}: ${f.message}` : f.message;
|
|
600
|
+
})
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
return { success: true, data: result };
|
|
604
|
+
}
|
|
605
|
+
|
|
466
606
|
// src/capability.ts
|
|
467
607
|
var CapabilityKind = {
|
|
468
608
|
Payment: "payment",
|
|
469
609
|
Shipping: "shipping",
|
|
470
610
|
Suppliers: "suppliers",
|
|
471
611
|
Analytics: "analytics",
|
|
472
|
-
Invoicing: "invoicing"
|
|
612
|
+
Invoicing: "invoicing",
|
|
613
|
+
/**
|
|
614
|
+
* Cross-cutting DISPLAY capability: a plugin of ANY surface may ALSO expose
|
|
615
|
+
* `ui` to contribute declarative blocks into host slots. Not a catalog
|
|
616
|
+
* "surface" — the host's AppSurface derivation excludes it on purpose.
|
|
617
|
+
*/
|
|
618
|
+
Ui: "ui"
|
|
473
619
|
};
|
|
474
620
|
function capability(kind, impl) {
|
|
475
621
|
return { kind, impl };
|
|
@@ -489,6 +635,9 @@ function analyticsCapability(impl) {
|
|
|
489
635
|
function invoicingCapability(impl) {
|
|
490
636
|
return { kind: CapabilityKind.Invoicing, impl };
|
|
491
637
|
}
|
|
638
|
+
function uiCapability(impl) {
|
|
639
|
+
return { kind: CapabilityKind.Ui, impl };
|
|
640
|
+
}
|
|
492
641
|
var PLUGIN_FACTORY_BRAND = /* @__PURE__ */ Symbol.for("vivoa.plugin.factory");
|
|
493
642
|
function definePlugin(factory) {
|
|
494
643
|
Object.defineProperty(factory, PLUGIN_FACTORY_BRAND, {
|
|
@@ -501,40 +650,8 @@ function isPluginFactory(value) {
|
|
|
501
650
|
return typeof value === "function" && value[PLUGIN_FACTORY_BRAND] === true;
|
|
502
651
|
}
|
|
503
652
|
|
|
504
|
-
// src/permissions.ts
|
|
505
|
-
var PERMISSION_RE = /^([a-z0-9]+)\.([a-z0-9]+)(?::(.+))?$/i;
|
|
506
|
-
function parsePermission(raw) {
|
|
507
|
-
const m = PERMISSION_RE.exec(raw);
|
|
508
|
-
if (!m) return null;
|
|
509
|
-
const [, domain, action, resource] = m;
|
|
510
|
-
return resource === void 0 ? { domain, action } : { domain, action, resource };
|
|
511
|
-
}
|
|
512
|
-
function isPermissionGranted(required, granted) {
|
|
513
|
-
return granted.some((g) => {
|
|
514
|
-
if (g.domain !== required.domain || g.action !== required.action) {
|
|
515
|
-
return false;
|
|
516
|
-
}
|
|
517
|
-
if (required.resource === void 0) return true;
|
|
518
|
-
return g.resource === "*" || g.resource === required.resource;
|
|
519
|
-
});
|
|
520
|
-
}
|
|
521
|
-
function checkPermissions(required, grantedRaw) {
|
|
522
|
-
const grantedParsed = grantedRaw.map(parsePermission).filter((p) => p !== null);
|
|
523
|
-
const granted = [];
|
|
524
|
-
const missing = [];
|
|
525
|
-
for (const raw of required) {
|
|
526
|
-
const parsed = parsePermission(raw);
|
|
527
|
-
if (parsed && isPermissionGranted(parsed, grantedParsed)) {
|
|
528
|
-
granted.push(raw);
|
|
529
|
-
} else {
|
|
530
|
-
missing.push(raw);
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
return { ok: missing.length === 0, granted, missing };
|
|
534
|
-
}
|
|
535
|
-
|
|
536
653
|
// src/version.ts
|
|
537
|
-
var SDK_VERSION = "0.6.
|
|
654
|
+
var SDK_VERSION = "0.6.7";
|
|
538
655
|
function isSdkCompatible(pluginSdkVersion, hostSdkVersion) {
|
|
539
656
|
const parse = (v) => {
|
|
540
657
|
const m = /^(\d+)\.(\d+)\.(\d+)/.exec(v);
|
|
@@ -551,12 +668,15 @@ function isSdkCompatible(pluginSdkVersion, hostSdkVersion) {
|
|
|
551
668
|
}
|
|
552
669
|
export {
|
|
553
670
|
ANALYTICS_PLUGIN_TOKEN,
|
|
671
|
+
AUTHOR_HANDLE_RE,
|
|
554
672
|
ActionVariant,
|
|
555
673
|
AnalyticsFeature,
|
|
556
674
|
BlockType,
|
|
557
675
|
CapabilityKind,
|
|
558
676
|
CodFeeType,
|
|
559
677
|
ConfigScope,
|
|
678
|
+
ContentActionVariant,
|
|
679
|
+
ContentBlockType,
|
|
560
680
|
FieldType,
|
|
561
681
|
FieldVariant,
|
|
562
682
|
GatewayEnvironment,
|
|
@@ -567,7 +687,6 @@ export {
|
|
|
567
687
|
LayoutMode,
|
|
568
688
|
MessageVariant,
|
|
569
689
|
PAYMENT_PLUGIN_TOKEN,
|
|
570
|
-
PluginType,
|
|
571
690
|
RepeaterSource,
|
|
572
691
|
SDK_VERSION,
|
|
573
692
|
SHIPPING_PLUGIN_TOKEN,
|
|
@@ -592,5 +711,8 @@ export {
|
|
|
592
711
|
paymentCapability,
|
|
593
712
|
shippingCapability,
|
|
594
713
|
suppliersCapability,
|
|
595
|
-
|
|
714
|
+
uiCapability,
|
|
715
|
+
validatePluginAuthor,
|
|
716
|
+
validateSetupLayout,
|
|
717
|
+
validateUiContributions
|
|
596
718
|
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { _ as HostApi, a0 as HttpRequest, R as DomainEventName, u as Capability, Q as DomainEventHandler, a1 as HttpResponse, N as DispatchContext } from '../host-api-yX49e7zE.mjs';
|
|
2
|
+
|
|
3
|
+
/** Every recorded interaction, keyed by `"port.method"`. */
|
|
4
|
+
interface MockHostCalls {
|
|
5
|
+
'http.request': HttpRequest[];
|
|
6
|
+
'secrets.get': string[];
|
|
7
|
+
'storage.getUrl': string[];
|
|
8
|
+
'storage.put': Array<{
|
|
9
|
+
key: string;
|
|
10
|
+
body: Uint8Array | string;
|
|
11
|
+
}>;
|
|
12
|
+
'sequence.next': string[];
|
|
13
|
+
'host.on': DomainEventName[];
|
|
14
|
+
}
|
|
15
|
+
interface MockHostOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Permissions the mock "grants". When set, the mock enforces them exactly as
|
|
18
|
+
* the real host is specified to: an un-granted `http.outbound:<host>` or
|
|
19
|
+
* `secrets.read:<key>` THROWS. Omit to grant everything (pure recorder mode).
|
|
20
|
+
*/
|
|
21
|
+
grantedPermissions?: string[];
|
|
22
|
+
/** Canned secret values returned by `secrets.get`. */
|
|
23
|
+
secrets?: Record<string, string>;
|
|
24
|
+
/**
|
|
25
|
+
* Canned HTTP responses. Resolved against the request URL — exact match
|
|
26
|
+
* first, then the first entry whose key is a substring of the URL. Defaults
|
|
27
|
+
* to `{ status: 200, headers: {}, body: {} }`.
|
|
28
|
+
*/
|
|
29
|
+
httpResponses?: Record<string, HttpResponse>;
|
|
30
|
+
/** Seed values for named sequence scopes (monotonic from here). */
|
|
31
|
+
sequences?: Record<string, number>;
|
|
32
|
+
}
|
|
33
|
+
interface MockHostApi extends HostApi {
|
|
34
|
+
/** Every port call recorded in order. */
|
|
35
|
+
readonly calls: MockHostCalls;
|
|
36
|
+
/** Capabilities the plugin registered via `registerCapability`. */
|
|
37
|
+
readonly registered: Capability[];
|
|
38
|
+
/** Event handlers the plugin subscribed via `host.on`. */
|
|
39
|
+
readonly handlers: Map<DomainEventName, DomainEventHandler[]>;
|
|
40
|
+
/** Drives a subscribed handler as if the host emitted the event. */
|
|
41
|
+
emit(event: DomainEventName, payload: unknown): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Builds a {@link MockHostApi}. Pass `grantedPermissions` to assert your plugin
|
|
45
|
+
* declared what it actually uses; leave it out to just record calls.
|
|
46
|
+
*/
|
|
47
|
+
declare function createMockHostApi(opts?: MockHostOptions): MockHostApi;
|
|
48
|
+
/**
|
|
49
|
+
* Minimal {@link DispatchContext} for dispatch-method tests. Pass the merged
|
|
50
|
+
* config your plugin expects; the country fields mirror the host's resolution.
|
|
51
|
+
*/
|
|
52
|
+
declare function createDispatchContext(config?: Record<string, unknown>, overrides?: Partial<DispatchContext>): DispatchContext;
|
|
53
|
+
|
|
54
|
+
export { type MockHostApi, type MockHostCalls, type MockHostOptions, createDispatchContext, createMockHostApi };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { _ as HostApi, a0 as HttpRequest, R as DomainEventName, u as Capability, Q as DomainEventHandler, a1 as HttpResponse, N as DispatchContext } from '../host-api-yX49e7zE.js';
|
|
2
|
+
|
|
3
|
+
/** Every recorded interaction, keyed by `"port.method"`. */
|
|
4
|
+
interface MockHostCalls {
|
|
5
|
+
'http.request': HttpRequest[];
|
|
6
|
+
'secrets.get': string[];
|
|
7
|
+
'storage.getUrl': string[];
|
|
8
|
+
'storage.put': Array<{
|
|
9
|
+
key: string;
|
|
10
|
+
body: Uint8Array | string;
|
|
11
|
+
}>;
|
|
12
|
+
'sequence.next': string[];
|
|
13
|
+
'host.on': DomainEventName[];
|
|
14
|
+
}
|
|
15
|
+
interface MockHostOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Permissions the mock "grants". When set, the mock enforces them exactly as
|
|
18
|
+
* the real host is specified to: an un-granted `http.outbound:<host>` or
|
|
19
|
+
* `secrets.read:<key>` THROWS. Omit to grant everything (pure recorder mode).
|
|
20
|
+
*/
|
|
21
|
+
grantedPermissions?: string[];
|
|
22
|
+
/** Canned secret values returned by `secrets.get`. */
|
|
23
|
+
secrets?: Record<string, string>;
|
|
24
|
+
/**
|
|
25
|
+
* Canned HTTP responses. Resolved against the request URL — exact match
|
|
26
|
+
* first, then the first entry whose key is a substring of the URL. Defaults
|
|
27
|
+
* to `{ status: 200, headers: {}, body: {} }`.
|
|
28
|
+
*/
|
|
29
|
+
httpResponses?: Record<string, HttpResponse>;
|
|
30
|
+
/** Seed values for named sequence scopes (monotonic from here). */
|
|
31
|
+
sequences?: Record<string, number>;
|
|
32
|
+
}
|
|
33
|
+
interface MockHostApi extends HostApi {
|
|
34
|
+
/** Every port call recorded in order. */
|
|
35
|
+
readonly calls: MockHostCalls;
|
|
36
|
+
/** Capabilities the plugin registered via `registerCapability`. */
|
|
37
|
+
readonly registered: Capability[];
|
|
38
|
+
/** Event handlers the plugin subscribed via `host.on`. */
|
|
39
|
+
readonly handlers: Map<DomainEventName, DomainEventHandler[]>;
|
|
40
|
+
/** Drives a subscribed handler as if the host emitted the event. */
|
|
41
|
+
emit(event: DomainEventName, payload: unknown): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Builds a {@link MockHostApi}. Pass `grantedPermissions` to assert your plugin
|
|
45
|
+
* declared what it actually uses; leave it out to just record calls.
|
|
46
|
+
*/
|
|
47
|
+
declare function createMockHostApi(opts?: MockHostOptions): MockHostApi;
|
|
48
|
+
/**
|
|
49
|
+
* Minimal {@link DispatchContext} for dispatch-method tests. Pass the merged
|
|
50
|
+
* config your plugin expects; the country fields mirror the host's resolution.
|
|
51
|
+
*/
|
|
52
|
+
declare function createDispatchContext(config?: Record<string, unknown>, overrides?: Partial<DispatchContext>): DispatchContext;
|
|
53
|
+
|
|
54
|
+
export { type MockHostApi, type MockHostCalls, type MockHostOptions, createDispatchContext, createMockHostApi };
|