@vivoa/plugin-sdk 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +71 -0
- package/dist/index.d.mts +788 -0
- package/dist/index.d.ts +788 -0
- package/dist/index.js +563 -0
- package/dist/index.mjs +526 -0
- package/package.json +59 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
// src/tokens.ts
|
|
2
|
+
var PAYMENT_PLUGIN_TOKEN = "PAYMENT_PLUGINS";
|
|
3
|
+
var SHIPPING_PLUGIN_TOKEN = "SHIPPING_PLUGINS";
|
|
4
|
+
|
|
5
|
+
// src/plugin.ts
|
|
6
|
+
var PluginType = /* @__PURE__ */ ((PluginType2) => {
|
|
7
|
+
PluginType2["Payment"] = "payment";
|
|
8
|
+
PluginType2["Shipping"] = "shipping";
|
|
9
|
+
PluginType2["Analytics"] = "analytics";
|
|
10
|
+
PluginType2["Generic"] = "generic";
|
|
11
|
+
return PluginType2;
|
|
12
|
+
})(PluginType || {});
|
|
13
|
+
var MessageVariant = /* @__PURE__ */ ((MessageVariant2) => {
|
|
14
|
+
MessageVariant2["Info"] = "info";
|
|
15
|
+
MessageVariant2["Warning"] = "warning";
|
|
16
|
+
MessageVariant2["Success"] = "success";
|
|
17
|
+
MessageVariant2["Danger"] = "danger";
|
|
18
|
+
return MessageVariant2;
|
|
19
|
+
})(MessageVariant || {});
|
|
20
|
+
function isConfigurablePlugin(plugin) {
|
|
21
|
+
return typeof plugin === "object" && plugin !== null && "loadConfig" in plugin && typeof plugin.loadConfig === "function";
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// src/config.ts
|
|
25
|
+
var FieldType = /* @__PURE__ */ ((FieldType2) => {
|
|
26
|
+
FieldType2["String"] = "string";
|
|
27
|
+
FieldType2["Password"] = "password";
|
|
28
|
+
FieldType2["Url"] = "url";
|
|
29
|
+
FieldType2["Number"] = "number";
|
|
30
|
+
FieldType2["Boolean"] = "boolean";
|
|
31
|
+
FieldType2["Select"] = "select";
|
|
32
|
+
return FieldType2;
|
|
33
|
+
})(FieldType || {});
|
|
34
|
+
var ConfigScope = /* @__PURE__ */ ((ConfigScope2) => {
|
|
35
|
+
ConfigScope2["Global"] = "global";
|
|
36
|
+
ConfigScope2["Country"] = "country";
|
|
37
|
+
return ConfigScope2;
|
|
38
|
+
})(ConfigScope || {});
|
|
39
|
+
|
|
40
|
+
// src/config-schema.ts
|
|
41
|
+
import {
|
|
42
|
+
string,
|
|
43
|
+
number,
|
|
44
|
+
boolean,
|
|
45
|
+
optional,
|
|
46
|
+
enums,
|
|
47
|
+
type as structType,
|
|
48
|
+
validate
|
|
49
|
+
} from "superstruct";
|
|
50
|
+
function field(def) {
|
|
51
|
+
return { required: true, ...def };
|
|
52
|
+
}
|
|
53
|
+
function normalizeDependsOn(dep) {
|
|
54
|
+
if (!dep) return void 0;
|
|
55
|
+
return {
|
|
56
|
+
field: dep.field,
|
|
57
|
+
value: Array.isArray(dep.value) ? dep.value : [dep.value]
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function buildStructForField(def) {
|
|
61
|
+
let base;
|
|
62
|
+
if (def.options) {
|
|
63
|
+
base = enums(def.options.map((o) => o.value));
|
|
64
|
+
} else if (def.type === "boolean" /* Boolean */) {
|
|
65
|
+
base = boolean();
|
|
66
|
+
} else if (def.type === "number" /* Number */) {
|
|
67
|
+
base = number();
|
|
68
|
+
} else {
|
|
69
|
+
base = string();
|
|
70
|
+
}
|
|
71
|
+
return def.required ? base : optional(base);
|
|
72
|
+
}
|
|
73
|
+
function createPluginConfig(fields) {
|
|
74
|
+
const shape = {};
|
|
75
|
+
const configFields = [];
|
|
76
|
+
for (const [key, def] of Object.entries(fields)) {
|
|
77
|
+
shape[key] = buildStructForField(def);
|
|
78
|
+
configFields.push({
|
|
79
|
+
key,
|
|
80
|
+
label: def.label,
|
|
81
|
+
type: def.type,
|
|
82
|
+
required: def.required ?? true,
|
|
83
|
+
scopedTo: def.scopedTo,
|
|
84
|
+
dependsOn: normalizeDependsOn(def.dependsOn),
|
|
85
|
+
placeholder: def.placeholder,
|
|
86
|
+
description: def.description,
|
|
87
|
+
options: def.options,
|
|
88
|
+
internal: def.internal,
|
|
89
|
+
group: def.group
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const schema = structType(shape);
|
|
93
|
+
return {
|
|
94
|
+
configFields,
|
|
95
|
+
validate: (data) => {
|
|
96
|
+
const [error, result] = validate(data, schema);
|
|
97
|
+
if (error) {
|
|
98
|
+
const messages = error.failures().map((f) => {
|
|
99
|
+
const path = f.path.join(".");
|
|
100
|
+
return path ? `${path}: ${f.message}` : f.message;
|
|
101
|
+
});
|
|
102
|
+
return { success: false, errors: messages };
|
|
103
|
+
}
|
|
104
|
+
return { success: true, data: result };
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// src/payment.ts
|
|
110
|
+
var TransactionStatus = /* @__PURE__ */ ((TransactionStatus2) => {
|
|
111
|
+
TransactionStatus2["Pending"] = "Pending";
|
|
112
|
+
TransactionStatus2["PendingRedirect"] = "Pending_Redirect";
|
|
113
|
+
TransactionStatus2["Approved"] = "Approved";
|
|
114
|
+
TransactionStatus2["Declined"] = "Declined";
|
|
115
|
+
TransactionStatus2["Failed"] = "Failed";
|
|
116
|
+
TransactionStatus2["Error"] = "Error";
|
|
117
|
+
return TransactionStatus2;
|
|
118
|
+
})(TransactionStatus || {});
|
|
119
|
+
var GatewayEnvironment = /* @__PURE__ */ ((GatewayEnvironment2) => {
|
|
120
|
+
GatewayEnvironment2["Sandbox"] = "sandbox";
|
|
121
|
+
GatewayEnvironment2["Production"] = "production";
|
|
122
|
+
return GatewayEnvironment2;
|
|
123
|
+
})(GatewayEnvironment || {});
|
|
124
|
+
|
|
125
|
+
// src/shipping.ts
|
|
126
|
+
var ShippingFeature = /* @__PURE__ */ ((ShippingFeature2) => {
|
|
127
|
+
ShippingFeature2["Tracking"] = "tracking";
|
|
128
|
+
ShippingFeature2["Cod"] = "cod";
|
|
129
|
+
ShippingFeature2["Quotes"] = "quotes";
|
|
130
|
+
ShippingFeature2["Labels"] = "labels";
|
|
131
|
+
return ShippingFeature2;
|
|
132
|
+
})(ShippingFeature || {});
|
|
133
|
+
var CodFeeType = /* @__PURE__ */ ((CodFeeType2) => {
|
|
134
|
+
CodFeeType2["Percentage"] = "percentage";
|
|
135
|
+
CodFeeType2["Fixed"] = "fixed";
|
|
136
|
+
return CodFeeType2;
|
|
137
|
+
})(CodFeeType || {});
|
|
138
|
+
|
|
139
|
+
// src/setup-layout.ts
|
|
140
|
+
import {
|
|
141
|
+
array,
|
|
142
|
+
boolean as boolean2,
|
|
143
|
+
enums as enums2,
|
|
144
|
+
lazy,
|
|
145
|
+
literal,
|
|
146
|
+
number as number2,
|
|
147
|
+
object,
|
|
148
|
+
optional as optional2,
|
|
149
|
+
string as string2,
|
|
150
|
+
union,
|
|
151
|
+
unknown,
|
|
152
|
+
validate as validate2
|
|
153
|
+
} from "superstruct";
|
|
154
|
+
var FieldVariant = /* @__PURE__ */ ((FieldVariant2) => {
|
|
155
|
+
FieldVariant2["Text"] = "text";
|
|
156
|
+
FieldVariant2["Secret"] = "secret";
|
|
157
|
+
FieldVariant2["Url"] = "url";
|
|
158
|
+
FieldVariant2["Number"] = "number";
|
|
159
|
+
FieldVariant2["Select"] = "select";
|
|
160
|
+
FieldVariant2["Textarea"] = "textarea";
|
|
161
|
+
FieldVariant2["Segmented"] = "segmented";
|
|
162
|
+
return FieldVariant2;
|
|
163
|
+
})(FieldVariant || {});
|
|
164
|
+
var ActionVariant = /* @__PURE__ */ ((ActionVariant2) => {
|
|
165
|
+
ActionVariant2["Primary"] = "primary";
|
|
166
|
+
ActionVariant2["Secondary"] = "secondary";
|
|
167
|
+
ActionVariant2["Danger"] = "danger";
|
|
168
|
+
return ActionVariant2;
|
|
169
|
+
})(ActionVariant || {});
|
|
170
|
+
var RepeaterSource = /* @__PURE__ */ ((RepeaterSource2) => {
|
|
171
|
+
RepeaterSource2["SupportedCountries"] = "supportedCountries";
|
|
172
|
+
return RepeaterSource2;
|
|
173
|
+
})(RepeaterSource || {});
|
|
174
|
+
var LayoutMode = /* @__PURE__ */ ((LayoutMode2) => {
|
|
175
|
+
LayoutMode2["Wizard"] = "wizard";
|
|
176
|
+
LayoutMode2["Stacked"] = "stacked";
|
|
177
|
+
LayoutMode2["Tabs"] = "tabs";
|
|
178
|
+
LayoutMode2["Sections"] = "sections";
|
|
179
|
+
return LayoutMode2;
|
|
180
|
+
})(LayoutMode || {});
|
|
181
|
+
var BlockType = /* @__PURE__ */ ((BlockType2) => {
|
|
182
|
+
BlockType2["Field"] = "field";
|
|
183
|
+
BlockType2["Group"] = "group";
|
|
184
|
+
BlockType2["Toggle"] = "toggle";
|
|
185
|
+
BlockType2["Action"] = "action";
|
|
186
|
+
BlockType2["Callout"] = "callout";
|
|
187
|
+
BlockType2["Markdown"] = "markdown";
|
|
188
|
+
BlockType2["Divider"] = "divider";
|
|
189
|
+
BlockType2["Conditional"] = "conditional";
|
|
190
|
+
BlockType2["Repeater"] = "repeater";
|
|
191
|
+
BlockType2["Card"] = "card";
|
|
192
|
+
BlockType2["Banner"] = "banner";
|
|
193
|
+
BlockType2["CopyField"] = "copyField";
|
|
194
|
+
BlockType2["InlineRow"] = "inlineRow";
|
|
195
|
+
BlockType2["Tabs"] = "tabs";
|
|
196
|
+
BlockType2["Accordion"] = "accordion";
|
|
197
|
+
BlockType2["KeyValue"] = "keyValue";
|
|
198
|
+
return BlockType2;
|
|
199
|
+
})(BlockType || {});
|
|
200
|
+
var StepStatusFrom = /* @__PURE__ */ ((StepStatusFrom2) => {
|
|
201
|
+
StepStatusFrom2["Fields"] = "fields";
|
|
202
|
+
StepStatusFrom2["Action"] = "action";
|
|
203
|
+
return StepStatusFrom2;
|
|
204
|
+
})(StepStatusFrom || {});
|
|
205
|
+
var sFieldVariant = enums2(Object.values(FieldVariant));
|
|
206
|
+
var sActionVariant = enums2(Object.values(ActionVariant));
|
|
207
|
+
var sRepeaterSource = enums2(Object.values(RepeaterSource));
|
|
208
|
+
var sMessageVariant = enums2(Object.values(MessageVariant));
|
|
209
|
+
var sSpan = optional2(number2());
|
|
210
|
+
var sFieldBlock = object({
|
|
211
|
+
type: literal("field" /* Field */),
|
|
212
|
+
key: string2(),
|
|
213
|
+
variant: optional2(sFieldVariant),
|
|
214
|
+
labelOverride: optional2(string2()),
|
|
215
|
+
optionsFrom: optional2(string2()),
|
|
216
|
+
span: sSpan
|
|
217
|
+
});
|
|
218
|
+
var sGroupBlock = object({
|
|
219
|
+
type: literal("group" /* Group */),
|
|
220
|
+
title: string2(),
|
|
221
|
+
description: optional2(string2()),
|
|
222
|
+
fields: array(string2()),
|
|
223
|
+
collapsible: optional2(boolean2()),
|
|
224
|
+
defaultOpen: optional2(boolean2()),
|
|
225
|
+
span: sSpan
|
|
226
|
+
});
|
|
227
|
+
var sToggleBlock = object({
|
|
228
|
+
type: literal("toggle" /* Toggle */),
|
|
229
|
+
key: string2(),
|
|
230
|
+
label: string2(),
|
|
231
|
+
description: optional2(string2()),
|
|
232
|
+
span: sSpan
|
|
233
|
+
});
|
|
234
|
+
var sActionBlock = object({
|
|
235
|
+
type: literal("action" /* Action */),
|
|
236
|
+
id: string2(),
|
|
237
|
+
label: string2(),
|
|
238
|
+
variant: optional2(sActionVariant),
|
|
239
|
+
resultSlot: optional2(string2()),
|
|
240
|
+
span: sSpan
|
|
241
|
+
});
|
|
242
|
+
var sCalloutBlock = object({
|
|
243
|
+
type: literal("callout" /* Callout */),
|
|
244
|
+
variant: sMessageVariant,
|
|
245
|
+
text: string2(),
|
|
246
|
+
slot: optional2(string2()),
|
|
247
|
+
span: sSpan
|
|
248
|
+
});
|
|
249
|
+
var sMarkdownBlock = object({
|
|
250
|
+
type: literal("markdown" /* Markdown */),
|
|
251
|
+
content: string2(),
|
|
252
|
+
span: sSpan
|
|
253
|
+
});
|
|
254
|
+
var sDividerBlock = object({ type: literal("divider" /* Divider */), span: sSpan });
|
|
255
|
+
var sConditionalBlock = object({
|
|
256
|
+
type: literal("conditional" /* Conditional */),
|
|
257
|
+
when: object({ key: string2(), equals: unknown() }),
|
|
258
|
+
blocks: array(lazy(() => sBlock)),
|
|
259
|
+
span: sSpan
|
|
260
|
+
});
|
|
261
|
+
var sRepeaterBlock = object({
|
|
262
|
+
type: literal("repeater" /* Repeater */),
|
|
263
|
+
source: sRepeaterSource,
|
|
264
|
+
blocks: array(lazy(() => sBlock)),
|
|
265
|
+
span: sSpan
|
|
266
|
+
});
|
|
267
|
+
var sCardBlock = object({
|
|
268
|
+
type: literal("card" /* Card */),
|
|
269
|
+
title: optional2(string2()),
|
|
270
|
+
description: optional2(string2()),
|
|
271
|
+
blocks: array(lazy(() => sBlock)),
|
|
272
|
+
span: sSpan
|
|
273
|
+
});
|
|
274
|
+
var sBannerBlock = object({
|
|
275
|
+
type: literal("banner" /* Banner */),
|
|
276
|
+
variant: sMessageVariant,
|
|
277
|
+
title: optional2(string2()),
|
|
278
|
+
text: string2(),
|
|
279
|
+
span: sSpan
|
|
280
|
+
});
|
|
281
|
+
var sCopyFieldBlock = object({
|
|
282
|
+
type: literal("copyField" /* CopyField */),
|
|
283
|
+
label: string2(),
|
|
284
|
+
value: optional2(string2()),
|
|
285
|
+
computedKey: optional2(string2()),
|
|
286
|
+
fieldKey: optional2(string2()),
|
|
287
|
+
span: sSpan
|
|
288
|
+
});
|
|
289
|
+
var sInlineRowBlock = object({
|
|
290
|
+
type: literal("inlineRow" /* InlineRow */),
|
|
291
|
+
blocks: array(lazy(() => sBlock)),
|
|
292
|
+
span: sSpan
|
|
293
|
+
});
|
|
294
|
+
var sTabsBlock = object({
|
|
295
|
+
type: literal("tabs" /* Tabs */),
|
|
296
|
+
tabs: array(
|
|
297
|
+
object({
|
|
298
|
+
id: string2(),
|
|
299
|
+
label: string2(),
|
|
300
|
+
blocks: array(lazy(() => sBlock))
|
|
301
|
+
})
|
|
302
|
+
),
|
|
303
|
+
span: sSpan
|
|
304
|
+
});
|
|
305
|
+
var sAccordionBlock = object({
|
|
306
|
+
type: literal("accordion" /* Accordion */),
|
|
307
|
+
sections: array(
|
|
308
|
+
object({
|
|
309
|
+
id: string2(),
|
|
310
|
+
title: string2(),
|
|
311
|
+
defaultOpen: optional2(boolean2()),
|
|
312
|
+
blocks: array(lazy(() => sBlock))
|
|
313
|
+
})
|
|
314
|
+
),
|
|
315
|
+
span: sSpan
|
|
316
|
+
});
|
|
317
|
+
var sKeyValueBlock = object({
|
|
318
|
+
type: literal("keyValue" /* KeyValue */),
|
|
319
|
+
rows: array(
|
|
320
|
+
object({
|
|
321
|
+
label: string2(),
|
|
322
|
+
value: optional2(string2()),
|
|
323
|
+
computedKey: optional2(string2())
|
|
324
|
+
})
|
|
325
|
+
),
|
|
326
|
+
span: sSpan
|
|
327
|
+
});
|
|
328
|
+
var sBlock = union([
|
|
329
|
+
sFieldBlock,
|
|
330
|
+
sGroupBlock,
|
|
331
|
+
sToggleBlock,
|
|
332
|
+
sActionBlock,
|
|
333
|
+
sCalloutBlock,
|
|
334
|
+
sMarkdownBlock,
|
|
335
|
+
sDividerBlock,
|
|
336
|
+
sConditionalBlock,
|
|
337
|
+
sRepeaterBlock,
|
|
338
|
+
sCardBlock,
|
|
339
|
+
sBannerBlock,
|
|
340
|
+
sCopyFieldBlock,
|
|
341
|
+
sInlineRowBlock,
|
|
342
|
+
sTabsBlock,
|
|
343
|
+
sAccordionBlock,
|
|
344
|
+
sKeyValueBlock
|
|
345
|
+
]);
|
|
346
|
+
var sStep = object({
|
|
347
|
+
id: string2(),
|
|
348
|
+
title: string2(),
|
|
349
|
+
intro: optional2(string2()),
|
|
350
|
+
blocks: array(sBlock),
|
|
351
|
+
repeatFor: optional2(sRepeaterSource),
|
|
352
|
+
status: optional2(
|
|
353
|
+
union([
|
|
354
|
+
object({ from: literal("fields" /* Fields */) }),
|
|
355
|
+
object({ from: literal("action" /* Action */), actionId: string2() })
|
|
356
|
+
])
|
|
357
|
+
)
|
|
358
|
+
});
|
|
359
|
+
var sAction = object({
|
|
360
|
+
id: string2(),
|
|
361
|
+
label: optional2(string2()),
|
|
362
|
+
perCountry: optional2(boolean2())
|
|
363
|
+
});
|
|
364
|
+
var sSetupLayout = object({
|
|
365
|
+
customScreen: optional2(string2()),
|
|
366
|
+
mode: optional2(enums2(Object.values(LayoutMode))),
|
|
367
|
+
intro: optional2(string2()),
|
|
368
|
+
steps: array(sStep),
|
|
369
|
+
actions: optional2(array(sAction))
|
|
370
|
+
});
|
|
371
|
+
function validateSetupLayout(input) {
|
|
372
|
+
const [error, result] = validate2(input, sSetupLayout);
|
|
373
|
+
if (error) {
|
|
374
|
+
return {
|
|
375
|
+
success: false,
|
|
376
|
+
errors: error.failures().map((f) => {
|
|
377
|
+
const path = f.path.join(".");
|
|
378
|
+
return path ? `${path}: ${f.message}` : f.message;
|
|
379
|
+
})
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
return { success: true, data: result };
|
|
383
|
+
}
|
|
384
|
+
function crossValidateSetupLayout(layout, configSchema) {
|
|
385
|
+
const errors = [];
|
|
386
|
+
const knownKeys = new Set(configSchema.map((f) => f.key));
|
|
387
|
+
const knownActions = new Set((layout.actions ?? []).map((a) => a.id));
|
|
388
|
+
const walk = (blocks, path) => {
|
|
389
|
+
blocks.forEach((b, i) => {
|
|
390
|
+
const here = `${path}[${i}]`;
|
|
391
|
+
if (b.type === "field" /* Field */ && !knownKeys.has(b.key)) {
|
|
392
|
+
errors.push(`${here}.key: "${b.key}" not in configSchema`);
|
|
393
|
+
} else if (b.type === "group" /* Group */) {
|
|
394
|
+
b.fields.forEach((k, j) => {
|
|
395
|
+
if (!knownKeys.has(k)) {
|
|
396
|
+
errors.push(`${here}.fields[${j}]: "${k}" not in configSchema`);
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
} else if (b.type === "action" /* Action */ && knownActions.size > 0) {
|
|
400
|
+
if (!knownActions.has(b.id)) {
|
|
401
|
+
errors.push(`${here}.id: action "${b.id}" not declared`);
|
|
402
|
+
}
|
|
403
|
+
} else if (b.type === "conditional" /* Conditional */ || b.type === "repeater" /* Repeater */ || b.type === "card" /* Card */ || b.type === "inlineRow" /* InlineRow */) {
|
|
404
|
+
walk(b.blocks, `${here}.blocks`);
|
|
405
|
+
} else if (b.type === "tabs" /* Tabs */) {
|
|
406
|
+
b.tabs.forEach((t, j) => walk(t.blocks, `${here}.tabs[${j}].blocks`));
|
|
407
|
+
} else if (b.type === "accordion" /* Accordion */) {
|
|
408
|
+
b.sections.forEach(
|
|
409
|
+
(s, j) => walk(s.blocks, `${here}.sections[${j}].blocks`)
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
};
|
|
414
|
+
layout.steps.forEach((s, i) => walk(s.blocks, `steps[${i}].blocks`));
|
|
415
|
+
return errors;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// src/capability.ts
|
|
419
|
+
var CapabilityKind = {
|
|
420
|
+
Payment: "payment",
|
|
421
|
+
Shipping: "shipping",
|
|
422
|
+
Analytics: "analytics"
|
|
423
|
+
};
|
|
424
|
+
function capability(kind, impl) {
|
|
425
|
+
return { kind, impl };
|
|
426
|
+
}
|
|
427
|
+
function paymentCapability(impl) {
|
|
428
|
+
return { kind: CapabilityKind.Payment, impl };
|
|
429
|
+
}
|
|
430
|
+
function shippingCapability(impl) {
|
|
431
|
+
return { kind: CapabilityKind.Shipping, impl };
|
|
432
|
+
}
|
|
433
|
+
var PLUGIN_FACTORY_BRAND = /* @__PURE__ */ Symbol.for("vivoa.plugin.factory");
|
|
434
|
+
function definePlugin(factory) {
|
|
435
|
+
Object.defineProperty(factory, PLUGIN_FACTORY_BRAND, {
|
|
436
|
+
value: true,
|
|
437
|
+
enumerable: false
|
|
438
|
+
});
|
|
439
|
+
return factory;
|
|
440
|
+
}
|
|
441
|
+
function isPluginFactory(value) {
|
|
442
|
+
return typeof value === "function" && value[PLUGIN_FACTORY_BRAND] === true;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// src/permissions.ts
|
|
446
|
+
var PERMISSION_RE = /^([a-z0-9]+)\.([a-z0-9]+)(?::(.+))?$/i;
|
|
447
|
+
function parsePermission(raw) {
|
|
448
|
+
const m = PERMISSION_RE.exec(raw);
|
|
449
|
+
if (!m) return null;
|
|
450
|
+
const [, domain, action, resource] = m;
|
|
451
|
+
return resource === void 0 ? { domain, action } : { domain, action, resource };
|
|
452
|
+
}
|
|
453
|
+
function isPermissionGranted(required, granted) {
|
|
454
|
+
return granted.some((g) => {
|
|
455
|
+
if (g.domain !== required.domain || g.action !== required.action) {
|
|
456
|
+
return false;
|
|
457
|
+
}
|
|
458
|
+
if (required.resource === void 0) return true;
|
|
459
|
+
return g.resource === "*" || g.resource === required.resource;
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
function checkPermissions(required, grantedRaw) {
|
|
463
|
+
const grantedParsed = grantedRaw.map(parsePermission).filter((p) => p !== null);
|
|
464
|
+
const granted = [];
|
|
465
|
+
const missing = [];
|
|
466
|
+
for (const raw of required) {
|
|
467
|
+
const parsed = parsePermission(raw);
|
|
468
|
+
if (parsed && isPermissionGranted(parsed, grantedParsed)) {
|
|
469
|
+
granted.push(raw);
|
|
470
|
+
} else {
|
|
471
|
+
missing.push(raw);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return { ok: missing.length === 0, granted, missing };
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// src/version.ts
|
|
478
|
+
var SDK_VERSION = "0.5.0";
|
|
479
|
+
function isSdkCompatible(pluginSdkVersion, hostSdkVersion) {
|
|
480
|
+
const parse = (v) => {
|
|
481
|
+
const m = /^(\d+)\.(\d+)\.(\d+)/.exec(v);
|
|
482
|
+
return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;
|
|
483
|
+
};
|
|
484
|
+
const p = parse(pluginSdkVersion);
|
|
485
|
+
const h = parse(hostSdkVersion);
|
|
486
|
+
if (!p || !h) return false;
|
|
487
|
+
if (p[0] !== h[0]) return false;
|
|
488
|
+
if (p[0] === 0) {
|
|
489
|
+
return p[1] === h[1] && h[2] >= p[2];
|
|
490
|
+
}
|
|
491
|
+
return h[1] > p[1] || h[1] === p[1] && h[2] >= p[2];
|
|
492
|
+
}
|
|
493
|
+
export {
|
|
494
|
+
ActionVariant,
|
|
495
|
+
BlockType,
|
|
496
|
+
CapabilityKind,
|
|
497
|
+
CodFeeType,
|
|
498
|
+
ConfigScope,
|
|
499
|
+
FieldType,
|
|
500
|
+
FieldVariant,
|
|
501
|
+
GatewayEnvironment,
|
|
502
|
+
LayoutMode,
|
|
503
|
+
MessageVariant,
|
|
504
|
+
PAYMENT_PLUGIN_TOKEN,
|
|
505
|
+
PluginType,
|
|
506
|
+
RepeaterSource,
|
|
507
|
+
SDK_VERSION,
|
|
508
|
+
SHIPPING_PLUGIN_TOKEN,
|
|
509
|
+
ShippingFeature,
|
|
510
|
+
StepStatusFrom,
|
|
511
|
+
TransactionStatus,
|
|
512
|
+
capability,
|
|
513
|
+
checkPermissions,
|
|
514
|
+
createPluginConfig,
|
|
515
|
+
crossValidateSetupLayout,
|
|
516
|
+
definePlugin,
|
|
517
|
+
field,
|
|
518
|
+
isConfigurablePlugin,
|
|
519
|
+
isPermissionGranted,
|
|
520
|
+
isPluginFactory,
|
|
521
|
+
isSdkCompatible,
|
|
522
|
+
parsePermission,
|
|
523
|
+
paymentCapability,
|
|
524
|
+
shippingCapability,
|
|
525
|
+
validateSetupLayout
|
|
526
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vivoa/plugin-sdk",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Public contracts for Vivoa plugins (types, DI tokens, config + setup-layout validators)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Vivoa",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/VivoaPlatform/vivoa-plugin-sdk.git"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"vivoa",
|
|
13
|
+
"plugin",
|
|
14
|
+
"sdk",
|
|
15
|
+
"ecommerce",
|
|
16
|
+
"payment",
|
|
17
|
+
"shipping"
|
|
18
|
+
],
|
|
19
|
+
"main": "dist/index.js",
|
|
20
|
+
"module": "dist/index.mjs",
|
|
21
|
+
"types": "dist/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"import": "./dist/index.mjs",
|
|
26
|
+
"require": "./dist/index.js"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"sideEffects": false,
|
|
30
|
+
"files": [
|
|
31
|
+
"dist"
|
|
32
|
+
],
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"registry": "https://registry.npmjs.org",
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean --target node18",
|
|
39
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch --target node18",
|
|
40
|
+
"test": "vitest run",
|
|
41
|
+
"test:watch": "vitest",
|
|
42
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
43
|
+
"prepublishOnly": "pnpm run typecheck && pnpm run test && pnpm run build"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"superstruct": "^2.0.2"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/node": "^22.10.7",
|
|
50
|
+
"tsup": "^8.3.5",
|
|
51
|
+
"typescript": "^5.7.3",
|
|
52
|
+
"vitest": "^2.1.8"
|
|
53
|
+
},
|
|
54
|
+
"pnpm": {
|
|
55
|
+
"onlyBuiltDependencies": [
|
|
56
|
+
"esbuild"
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
}
|