@promptscript/cli 1.4.0 → 1.4.2

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/index.js CHANGED
@@ -1,12 +1,1584 @@
1
+ var __create = Object.create;
1
2
  var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
2
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
3
7
  var __esm = (fn, res) => function __init() {
4
8
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
9
  };
10
+ var __commonJS = (cb, mod) => function __require() {
11
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
12
+ };
6
13
  var __export = (target, all) => {
7
14
  for (var name in all)
8
15
  __defProp(target, name, { get: all[name], enumerable: true });
9
16
  };
17
+ var __copyProps = (to, from, except, desc) => {
18
+ if (from && typeof from === "object" || typeof from === "function") {
19
+ for (let key of __getOwnPropNames(from))
20
+ if (!__hasOwnProp.call(to, key) && key !== except)
21
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
22
+ }
23
+ return to;
24
+ };
25
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
26
+ // If the importer is in node compatibility mode or this is not an ESM
27
+ // file that has been converted to a CommonJS file using a Babel-
28
+ // compatible transform (i.e. "__esModule" has not been set), then set
29
+ // "default" to the CommonJS "module.exports" for node compatibility.
30
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
31
+ mod
32
+ ));
33
+
34
+ // node_modules/.pnpm/fastify-plugin@5.1.0/node_modules/fastify-plugin/lib/getPluginName.js
35
+ var require_getPluginName = __commonJS({
36
+ "node_modules/.pnpm/fastify-plugin@5.1.0/node_modules/fastify-plugin/lib/getPluginName.js"(exports2, module2) {
37
+ "use strict";
38
+ var fpStackTracePattern = /at\s(?:.*\.)?plugin\s.*\n\s*(.*)/;
39
+ var fileNamePattern = /(\w*(\.\w*)*)\..*/;
40
+ module2.exports = function getPluginName(fn) {
41
+ if (fn.name.length > 0) return fn.name;
42
+ const stackTraceLimit = Error.stackTraceLimit;
43
+ Error.stackTraceLimit = 10;
44
+ try {
45
+ throw new Error("anonymous function");
46
+ } catch (e) {
47
+ Error.stackTraceLimit = stackTraceLimit;
48
+ return extractPluginName(e.stack);
49
+ }
50
+ };
51
+ function extractPluginName(stack) {
52
+ const m = stack.match(fpStackTracePattern);
53
+ return m ? m[1].split(/[/\\]/).slice(-1)[0].match(fileNamePattern)[1] : "anonymous";
54
+ }
55
+ module2.exports.extractPluginName = extractPluginName;
56
+ }
57
+ });
58
+
59
+ // node_modules/.pnpm/fastify-plugin@5.1.0/node_modules/fastify-plugin/lib/toCamelCase.js
60
+ var require_toCamelCase = __commonJS({
61
+ "node_modules/.pnpm/fastify-plugin@5.1.0/node_modules/fastify-plugin/lib/toCamelCase.js"(exports2, module2) {
62
+ "use strict";
63
+ module2.exports = function toCamelCase(name) {
64
+ if (name[0] === "@") {
65
+ name = name.slice(1).replace("/", "-");
66
+ }
67
+ return name.replace(/-(.)/g, function(match, g1) {
68
+ return g1.toUpperCase();
69
+ });
70
+ };
71
+ }
72
+ });
73
+
74
+ // node_modules/.pnpm/fastify-plugin@5.1.0/node_modules/fastify-plugin/plugin.js
75
+ var require_plugin = __commonJS({
76
+ "node_modules/.pnpm/fastify-plugin@5.1.0/node_modules/fastify-plugin/plugin.js"(exports2, module2) {
77
+ "use strict";
78
+ var getPluginName = require_getPluginName();
79
+ var toCamelCase = require_toCamelCase();
80
+ var count = 0;
81
+ function plugin(fn, options = {}) {
82
+ let autoName = false;
83
+ if (fn.default !== void 0) {
84
+ fn = fn.default;
85
+ }
86
+ if (typeof fn !== "function") {
87
+ throw new TypeError(
88
+ `fastify-plugin expects a function, instead got a '${typeof fn}'`
89
+ );
90
+ }
91
+ if (typeof options === "string") {
92
+ options = {
93
+ fastify: options
94
+ };
95
+ }
96
+ if (typeof options !== "object" || Array.isArray(options) || options === null) {
97
+ throw new TypeError("The options object should be an object");
98
+ }
99
+ if (options.fastify !== void 0 && typeof options.fastify !== "string") {
100
+ throw new TypeError(`fastify-plugin expects a version string, instead got '${typeof options.fastify}'`);
101
+ }
102
+ if (!options.name) {
103
+ autoName = true;
104
+ options.name = getPluginName(fn) + "-auto-" + count++;
105
+ }
106
+ fn[/* @__PURE__ */ Symbol.for("skip-override")] = options.encapsulate !== true;
107
+ fn[/* @__PURE__ */ Symbol.for("fastify.display-name")] = options.name;
108
+ fn[/* @__PURE__ */ Symbol.for("plugin-meta")] = options;
109
+ if (!fn.default) {
110
+ fn.default = fn;
111
+ }
112
+ const camelCase = toCamelCase(options.name);
113
+ if (!autoName && !fn[camelCase]) {
114
+ fn[camelCase] = fn;
115
+ }
116
+ return fn;
117
+ }
118
+ module2.exports = plugin;
119
+ module2.exports.default = plugin;
120
+ module2.exports.fastifyPlugin = plugin;
121
+ }
122
+ });
123
+
124
+ // node_modules/.pnpm/@lukeed+ms@2.0.2/node_modules/@lukeed/ms/dist/index.js
125
+ var require_dist = __commonJS({
126
+ "node_modules/.pnpm/@lukeed+ms@2.0.2/node_modules/@lukeed/ms/dist/index.js"(exports2) {
127
+ "use strict";
128
+ var RGX = /^(-?(?:\d+)?\.?\d+) *(m(?:illiseconds?|s(?:ecs?)?))?(s(?:ec(?:onds?|s)?)?)?(m(?:in(?:utes?|s)?)?)?(h(?:ours?|rs?)?)?(d(?:ays?)?)?(w(?:eeks?|ks?)?)?(y(?:ears?|rs?)?)?$/;
129
+ var SEC = 1e3;
130
+ var MIN = SEC * 60;
131
+ var HOUR = MIN * 60;
132
+ var DAY = HOUR * 24;
133
+ var YEAR = DAY * 365.25;
134
+ function parse2(val) {
135
+ var num, arr = val.toLowerCase().match(RGX);
136
+ if (arr != null && (num = parseFloat(arr[1]))) {
137
+ if (arr[3] != null) return num * SEC;
138
+ if (arr[4] != null) return num * MIN;
139
+ if (arr[5] != null) return num * HOUR;
140
+ if (arr[6] != null) return num * DAY;
141
+ if (arr[7] != null) return num * DAY * 7;
142
+ if (arr[8] != null) return num * YEAR;
143
+ return num;
144
+ }
145
+ }
146
+ function fmt(val, pfx, str, long) {
147
+ var num = (val | 0) === val ? val : ~~(val + 0.5);
148
+ return pfx + num + (long ? " " + str + (num != 1 ? "s" : "") : str[0]);
149
+ }
150
+ function format2(num, long) {
151
+ var pfx = num < 0 ? "-" : "", abs = num < 0 ? -num : num;
152
+ if (abs < SEC) return num + (long ? " ms" : "ms");
153
+ if (abs < MIN) return fmt(abs / SEC, pfx, "second", long);
154
+ if (abs < HOUR) return fmt(abs / MIN, pfx, "minute", long);
155
+ if (abs < DAY) return fmt(abs / HOUR, pfx, "hour", long);
156
+ if (abs < YEAR) return fmt(abs / DAY, pfx, "day", long);
157
+ return fmt(abs / YEAR, pfx, "year", long);
158
+ }
159
+ exports2.format = format2;
160
+ exports2.parse = parse2;
161
+ }
162
+ });
163
+
164
+ // node_modules/.pnpm/toad-cache@3.7.0/node_modules/toad-cache/dist/toad-cache.cjs
165
+ var require_toad_cache = __commonJS({
166
+ "node_modules/.pnpm/toad-cache@3.7.0/node_modules/toad-cache/dist/toad-cache.cjs"(exports2) {
167
+ "use strict";
168
+ var FifoMap = class {
169
+ constructor(max = 1e3, ttlInMsecs = 0) {
170
+ if (isNaN(max) || max < 0) {
171
+ throw new Error("Invalid max value");
172
+ }
173
+ if (isNaN(ttlInMsecs) || ttlInMsecs < 0) {
174
+ throw new Error("Invalid ttl value");
175
+ }
176
+ this.first = null;
177
+ this.items = /* @__PURE__ */ new Map();
178
+ this.last = null;
179
+ this.max = max;
180
+ this.ttl = ttlInMsecs;
181
+ }
182
+ get size() {
183
+ return this.items.size;
184
+ }
185
+ clear() {
186
+ this.items = /* @__PURE__ */ new Map();
187
+ this.first = null;
188
+ this.last = null;
189
+ }
190
+ delete(key) {
191
+ if (this.items.has(key)) {
192
+ const deletedItem = this.items.get(key);
193
+ this.items.delete(key);
194
+ if (deletedItem.prev !== null) {
195
+ deletedItem.prev.next = deletedItem.next;
196
+ }
197
+ if (deletedItem.next !== null) {
198
+ deletedItem.next.prev = deletedItem.prev;
199
+ }
200
+ if (this.first === deletedItem) {
201
+ this.first = deletedItem.next;
202
+ }
203
+ if (this.last === deletedItem) {
204
+ this.last = deletedItem.prev;
205
+ }
206
+ }
207
+ }
208
+ deleteMany(keys2) {
209
+ for (var i = 0; i < keys2.length; i++) {
210
+ this.delete(keys2[i]);
211
+ }
212
+ }
213
+ evict() {
214
+ if (this.size > 0) {
215
+ const item = this.first;
216
+ this.items.delete(item.key);
217
+ if (this.size === 0) {
218
+ this.first = null;
219
+ this.last = null;
220
+ } else {
221
+ this.first = item.next;
222
+ this.first.prev = null;
223
+ }
224
+ }
225
+ }
226
+ expiresAt(key) {
227
+ if (this.items.has(key)) {
228
+ return this.items.get(key).expiry;
229
+ }
230
+ }
231
+ get(key) {
232
+ if (this.items.has(key)) {
233
+ const item = this.items.get(key);
234
+ if (this.ttl > 0 && item.expiry <= Date.now()) {
235
+ this.delete(key);
236
+ return;
237
+ }
238
+ return item.value;
239
+ }
240
+ }
241
+ getMany(keys2) {
242
+ const result = [];
243
+ for (var i = 0; i < keys2.length; i++) {
244
+ result.push(this.get(keys2[i]));
245
+ }
246
+ return result;
247
+ }
248
+ keys() {
249
+ return this.items.keys();
250
+ }
251
+ set(key, value) {
252
+ if (this.items.has(key)) {
253
+ const item2 = this.items.get(key);
254
+ item2.value = value;
255
+ item2.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
256
+ return;
257
+ }
258
+ if (this.max > 0 && this.size === this.max) {
259
+ this.evict();
260
+ }
261
+ const item = {
262
+ expiry: this.ttl > 0 ? Date.now() + this.ttl : this.ttl,
263
+ key,
264
+ prev: this.last,
265
+ next: null,
266
+ value
267
+ };
268
+ this.items.set(key, item);
269
+ if (this.size === 1) {
270
+ this.first = item;
271
+ } else {
272
+ this.last.next = item;
273
+ }
274
+ this.last = item;
275
+ }
276
+ };
277
+ var LruMap = class {
278
+ constructor(max = 1e3, ttlInMsecs = 0) {
279
+ if (isNaN(max) || max < 0) {
280
+ throw new Error("Invalid max value");
281
+ }
282
+ if (isNaN(ttlInMsecs) || ttlInMsecs < 0) {
283
+ throw new Error("Invalid ttl value");
284
+ }
285
+ this.first = null;
286
+ this.items = /* @__PURE__ */ new Map();
287
+ this.last = null;
288
+ this.max = max;
289
+ this.ttl = ttlInMsecs;
290
+ }
291
+ get size() {
292
+ return this.items.size;
293
+ }
294
+ bumpLru(item) {
295
+ if (this.last === item) {
296
+ return;
297
+ }
298
+ const last2 = this.last;
299
+ const next = item.next;
300
+ const prev = item.prev;
301
+ if (this.first === item) {
302
+ this.first = next;
303
+ }
304
+ item.next = null;
305
+ item.prev = last2;
306
+ last2.next = item;
307
+ if (prev !== null) {
308
+ prev.next = next;
309
+ }
310
+ if (next !== null) {
311
+ next.prev = prev;
312
+ }
313
+ this.last = item;
314
+ }
315
+ clear() {
316
+ this.items = /* @__PURE__ */ new Map();
317
+ this.first = null;
318
+ this.last = null;
319
+ }
320
+ delete(key) {
321
+ if (this.items.has(key)) {
322
+ const item = this.items.get(key);
323
+ this.items.delete(key);
324
+ if (item.prev !== null) {
325
+ item.prev.next = item.next;
326
+ }
327
+ if (item.next !== null) {
328
+ item.next.prev = item.prev;
329
+ }
330
+ if (this.first === item) {
331
+ this.first = item.next;
332
+ }
333
+ if (this.last === item) {
334
+ this.last = item.prev;
335
+ }
336
+ }
337
+ }
338
+ deleteMany(keys2) {
339
+ for (var i = 0; i < keys2.length; i++) {
340
+ this.delete(keys2[i]);
341
+ }
342
+ }
343
+ evict() {
344
+ if (this.size > 0) {
345
+ const item = this.first;
346
+ this.items.delete(item.key);
347
+ if (this.size === 0) {
348
+ this.first = null;
349
+ this.last = null;
350
+ } else {
351
+ this.first = item.next;
352
+ this.first.prev = null;
353
+ }
354
+ }
355
+ }
356
+ expiresAt(key) {
357
+ if (this.items.has(key)) {
358
+ return this.items.get(key).expiry;
359
+ }
360
+ }
361
+ get(key) {
362
+ if (this.items.has(key)) {
363
+ const item = this.items.get(key);
364
+ if (this.ttl > 0 && item.expiry <= Date.now()) {
365
+ this.delete(key);
366
+ return;
367
+ }
368
+ this.bumpLru(item);
369
+ return item.value;
370
+ }
371
+ }
372
+ getMany(keys2) {
373
+ const result = [];
374
+ for (var i = 0; i < keys2.length; i++) {
375
+ result.push(this.get(keys2[i]));
376
+ }
377
+ return result;
378
+ }
379
+ keys() {
380
+ return this.items.keys();
381
+ }
382
+ set(key, value) {
383
+ if (this.items.has(key)) {
384
+ const item2 = this.items.get(key);
385
+ item2.value = value;
386
+ item2.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
387
+ if (this.last !== item2) {
388
+ this.bumpLru(item2);
389
+ }
390
+ return;
391
+ }
392
+ if (this.max > 0 && this.size === this.max) {
393
+ this.evict();
394
+ }
395
+ const item = {
396
+ expiry: this.ttl > 0 ? Date.now() + this.ttl : this.ttl,
397
+ key,
398
+ prev: this.last,
399
+ next: null,
400
+ value
401
+ };
402
+ this.items.set(key, item);
403
+ if (this.size === 1) {
404
+ this.first = item;
405
+ } else {
406
+ this.last.next = item;
407
+ }
408
+ this.last = item;
409
+ }
410
+ };
411
+ var LruObject = class {
412
+ constructor(max = 1e3, ttlInMsecs = 0) {
413
+ if (isNaN(max) || max < 0) {
414
+ throw new Error("Invalid max value");
415
+ }
416
+ if (isNaN(ttlInMsecs) || ttlInMsecs < 0) {
417
+ throw new Error("Invalid ttl value");
418
+ }
419
+ this.first = null;
420
+ this.items = /* @__PURE__ */ Object.create(null);
421
+ this.last = null;
422
+ this.size = 0;
423
+ this.max = max;
424
+ this.ttl = ttlInMsecs;
425
+ }
426
+ bumpLru(item) {
427
+ if (this.last === item) {
428
+ return;
429
+ }
430
+ const last2 = this.last;
431
+ const next = item.next;
432
+ const prev = item.prev;
433
+ if (this.first === item) {
434
+ this.first = next;
435
+ }
436
+ item.next = null;
437
+ item.prev = last2;
438
+ last2.next = item;
439
+ if (prev !== null) {
440
+ prev.next = next;
441
+ }
442
+ if (next !== null) {
443
+ next.prev = prev;
444
+ }
445
+ this.last = item;
446
+ }
447
+ clear() {
448
+ this.items = /* @__PURE__ */ Object.create(null);
449
+ this.first = null;
450
+ this.last = null;
451
+ this.size = 0;
452
+ }
453
+ delete(key) {
454
+ if (Object.prototype.hasOwnProperty.call(this.items, key)) {
455
+ const item = this.items[key];
456
+ delete this.items[key];
457
+ this.size--;
458
+ if (item.prev !== null) {
459
+ item.prev.next = item.next;
460
+ }
461
+ if (item.next !== null) {
462
+ item.next.prev = item.prev;
463
+ }
464
+ if (this.first === item) {
465
+ this.first = item.next;
466
+ }
467
+ if (this.last === item) {
468
+ this.last = item.prev;
469
+ }
470
+ }
471
+ }
472
+ deleteMany(keys2) {
473
+ for (var i = 0; i < keys2.length; i++) {
474
+ this.delete(keys2[i]);
475
+ }
476
+ }
477
+ evict() {
478
+ if (this.size > 0) {
479
+ const item = this.first;
480
+ delete this.items[item.key];
481
+ if (--this.size === 0) {
482
+ this.first = null;
483
+ this.last = null;
484
+ } else {
485
+ this.first = item.next;
486
+ this.first.prev = null;
487
+ }
488
+ }
489
+ }
490
+ expiresAt(key) {
491
+ if (Object.prototype.hasOwnProperty.call(this.items, key)) {
492
+ return this.items[key].expiry;
493
+ }
494
+ }
495
+ get(key) {
496
+ if (Object.prototype.hasOwnProperty.call(this.items, key)) {
497
+ const item = this.items[key];
498
+ if (this.ttl > 0 && item.expiry <= Date.now()) {
499
+ this.delete(key);
500
+ return;
501
+ }
502
+ this.bumpLru(item);
503
+ return item.value;
504
+ }
505
+ }
506
+ getMany(keys2) {
507
+ const result = [];
508
+ for (var i = 0; i < keys2.length; i++) {
509
+ result.push(this.get(keys2[i]));
510
+ }
511
+ return result;
512
+ }
513
+ keys() {
514
+ return Object.keys(this.items);
515
+ }
516
+ set(key, value) {
517
+ if (Object.prototype.hasOwnProperty.call(this.items, key)) {
518
+ const item2 = this.items[key];
519
+ item2.value = value;
520
+ item2.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
521
+ if (this.last !== item2) {
522
+ this.bumpLru(item2);
523
+ }
524
+ return;
525
+ }
526
+ if (this.max > 0 && this.size === this.max) {
527
+ this.evict();
528
+ }
529
+ const item = {
530
+ expiry: this.ttl > 0 ? Date.now() + this.ttl : this.ttl,
531
+ key,
532
+ prev: this.last,
533
+ next: null,
534
+ value
535
+ };
536
+ this.items[key] = item;
537
+ if (++this.size === 1) {
538
+ this.first = item;
539
+ } else {
540
+ this.last.next = item;
541
+ }
542
+ this.last = item;
543
+ }
544
+ };
545
+ var HitStatisticsRecord = class {
546
+ constructor() {
547
+ this.records = {};
548
+ }
549
+ initForCache(cacheId, currentTimeStamp) {
550
+ this.records[cacheId] = {
551
+ [currentTimeStamp]: {
552
+ cacheSize: 0,
553
+ hits: 0,
554
+ falsyHits: 0,
555
+ emptyHits: 0,
556
+ misses: 0,
557
+ expirations: 0,
558
+ evictions: 0,
559
+ invalidateOne: 0,
560
+ invalidateAll: 0,
561
+ sets: 0
562
+ }
563
+ };
564
+ }
565
+ resetForCache(cacheId) {
566
+ for (let key of Object.keys(this.records[cacheId])) {
567
+ this.records[cacheId][key] = {
568
+ cacheSize: 0,
569
+ hits: 0,
570
+ falsyHits: 0,
571
+ emptyHits: 0,
572
+ misses: 0,
573
+ expirations: 0,
574
+ evictions: 0,
575
+ invalidateOne: 0,
576
+ invalidateAll: 0,
577
+ sets: 0
578
+ };
579
+ }
580
+ }
581
+ getStatistics() {
582
+ return this.records;
583
+ }
584
+ };
585
+ function getTimestamp(date) {
586
+ return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}`;
587
+ }
588
+ var HitStatistics = class {
589
+ constructor(cacheId, statisticTtlInHours, globalStatisticsRecord) {
590
+ this.cacheId = cacheId;
591
+ this.statisticTtlInHours = statisticTtlInHours;
592
+ this.collectionStart = /* @__PURE__ */ new Date();
593
+ this.currentTimeStamp = getTimestamp(this.collectionStart);
594
+ this.records = globalStatisticsRecord || new HitStatisticsRecord();
595
+ this.records.initForCache(this.cacheId, this.currentTimeStamp);
596
+ }
597
+ get currentRecord() {
598
+ if (!this.records.records[this.cacheId][this.currentTimeStamp]) {
599
+ this.records.records[this.cacheId][this.currentTimeStamp] = {
600
+ cacheSize: 0,
601
+ hits: 0,
602
+ falsyHits: 0,
603
+ emptyHits: 0,
604
+ misses: 0,
605
+ expirations: 0,
606
+ evictions: 0,
607
+ sets: 0,
608
+ invalidateOne: 0,
609
+ invalidateAll: 0
610
+ };
611
+ }
612
+ return this.records.records[this.cacheId][this.currentTimeStamp];
613
+ }
614
+ hoursPassed() {
615
+ return (Date.now() - this.collectionStart) / 1e3 / 60 / 60;
616
+ }
617
+ addHit() {
618
+ this.archiveIfNeeded();
619
+ this.currentRecord.hits++;
620
+ }
621
+ addFalsyHit() {
622
+ this.archiveIfNeeded();
623
+ this.currentRecord.falsyHits++;
624
+ }
625
+ addEmptyHit() {
626
+ this.archiveIfNeeded();
627
+ this.currentRecord.emptyHits++;
628
+ }
629
+ addMiss() {
630
+ this.archiveIfNeeded();
631
+ this.currentRecord.misses++;
632
+ }
633
+ addEviction() {
634
+ this.archiveIfNeeded();
635
+ this.currentRecord.evictions++;
636
+ }
637
+ setCacheSize(currentSize) {
638
+ this.archiveIfNeeded();
639
+ this.currentRecord.cacheSize = currentSize;
640
+ }
641
+ addExpiration() {
642
+ this.archiveIfNeeded();
643
+ this.currentRecord.expirations++;
644
+ }
645
+ addSet() {
646
+ this.archiveIfNeeded();
647
+ this.currentRecord.sets++;
648
+ }
649
+ addInvalidateOne() {
650
+ this.archiveIfNeeded();
651
+ this.currentRecord.invalidateOne++;
652
+ }
653
+ addInvalidateAll() {
654
+ this.archiveIfNeeded();
655
+ this.currentRecord.invalidateAll++;
656
+ }
657
+ getStatistics() {
658
+ return this.records.getStatistics();
659
+ }
660
+ archiveIfNeeded() {
661
+ if (this.hoursPassed() >= this.statisticTtlInHours) {
662
+ this.collectionStart = /* @__PURE__ */ new Date();
663
+ this.currentTimeStamp = getTimestamp(this.collectionStart);
664
+ this.records.initForCache(this.cacheId, this.currentTimeStamp);
665
+ }
666
+ }
667
+ };
668
+ var LruObjectHitStatistics = class extends LruObject {
669
+ constructor(max, ttlInMsecs, cacheId, globalStatisticsRecord, statisticTtlInHours) {
670
+ super(max || 1e3, ttlInMsecs || 0);
671
+ if (!cacheId) {
672
+ throw new Error("Cache id is mandatory");
673
+ }
674
+ this.hitStatistics = new HitStatistics(
675
+ cacheId,
676
+ statisticTtlInHours !== void 0 ? statisticTtlInHours : 24,
677
+ globalStatisticsRecord
678
+ );
679
+ }
680
+ getStatistics() {
681
+ return this.hitStatistics.getStatistics();
682
+ }
683
+ set(key, value) {
684
+ super.set(key, value);
685
+ this.hitStatistics.addSet();
686
+ this.hitStatistics.setCacheSize(this.size);
687
+ }
688
+ evict() {
689
+ super.evict();
690
+ this.hitStatistics.addEviction();
691
+ this.hitStatistics.setCacheSize(this.size);
692
+ }
693
+ delete(key, isExpiration = false) {
694
+ super.delete(key);
695
+ if (!isExpiration) {
696
+ this.hitStatistics.addInvalidateOne();
697
+ }
698
+ this.hitStatistics.setCacheSize(this.size);
699
+ }
700
+ clear() {
701
+ super.clear();
702
+ this.hitStatistics.addInvalidateAll();
703
+ this.hitStatistics.setCacheSize(this.size);
704
+ }
705
+ get(key) {
706
+ if (Object.prototype.hasOwnProperty.call(this.items, key)) {
707
+ const item = this.items[key];
708
+ if (this.ttl > 0 && item.expiry <= Date.now()) {
709
+ this.delete(key, true);
710
+ this.hitStatistics.addExpiration();
711
+ return;
712
+ }
713
+ this.bumpLru(item);
714
+ if (!item.value) {
715
+ this.hitStatistics.addFalsyHit();
716
+ }
717
+ if (item.value === void 0 || item.value === null || item.value === "") {
718
+ this.hitStatistics.addEmptyHit();
719
+ }
720
+ this.hitStatistics.addHit();
721
+ return item.value;
722
+ }
723
+ this.hitStatistics.addMiss();
724
+ }
725
+ };
726
+ var FifoObject = class {
727
+ constructor(max = 1e3, ttlInMsecs = 0) {
728
+ if (isNaN(max) || max < 0) {
729
+ throw new Error("Invalid max value");
730
+ }
731
+ if (isNaN(ttlInMsecs) || ttlInMsecs < 0) {
732
+ throw new Error("Invalid ttl value");
733
+ }
734
+ this.first = null;
735
+ this.items = /* @__PURE__ */ Object.create(null);
736
+ this.last = null;
737
+ this.size = 0;
738
+ this.max = max;
739
+ this.ttl = ttlInMsecs;
740
+ }
741
+ clear() {
742
+ this.items = /* @__PURE__ */ Object.create(null);
743
+ this.first = null;
744
+ this.last = null;
745
+ this.size = 0;
746
+ }
747
+ delete(key) {
748
+ if (Object.prototype.hasOwnProperty.call(this.items, key)) {
749
+ const deletedItem = this.items[key];
750
+ delete this.items[key];
751
+ this.size--;
752
+ if (deletedItem.prev !== null) {
753
+ deletedItem.prev.next = deletedItem.next;
754
+ }
755
+ if (deletedItem.next !== null) {
756
+ deletedItem.next.prev = deletedItem.prev;
757
+ }
758
+ if (this.first === deletedItem) {
759
+ this.first = deletedItem.next;
760
+ }
761
+ if (this.last === deletedItem) {
762
+ this.last = deletedItem.prev;
763
+ }
764
+ }
765
+ }
766
+ deleteMany(keys2) {
767
+ for (var i = 0; i < keys2.length; i++) {
768
+ this.delete(keys2[i]);
769
+ }
770
+ }
771
+ evict() {
772
+ if (this.size > 0) {
773
+ const item = this.first;
774
+ delete this.items[item.key];
775
+ if (--this.size === 0) {
776
+ this.first = null;
777
+ this.last = null;
778
+ } else {
779
+ this.first = item.next;
780
+ this.first.prev = null;
781
+ }
782
+ }
783
+ }
784
+ expiresAt(key) {
785
+ if (Object.prototype.hasOwnProperty.call(this.items, key)) {
786
+ return this.items[key].expiry;
787
+ }
788
+ }
789
+ get(key) {
790
+ if (Object.prototype.hasOwnProperty.call(this.items, key)) {
791
+ const item = this.items[key];
792
+ if (this.ttl > 0 && item.expiry <= Date.now()) {
793
+ this.delete(key);
794
+ return;
795
+ }
796
+ return item.value;
797
+ }
798
+ }
799
+ getMany(keys2) {
800
+ const result = [];
801
+ for (var i = 0; i < keys2.length; i++) {
802
+ result.push(this.get(keys2[i]));
803
+ }
804
+ return result;
805
+ }
806
+ keys() {
807
+ return Object.keys(this.items);
808
+ }
809
+ set(key, value) {
810
+ if (Object.prototype.hasOwnProperty.call(this.items, key)) {
811
+ const item2 = this.items[key];
812
+ item2.value = value;
813
+ item2.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
814
+ return;
815
+ }
816
+ if (this.max > 0 && this.size === this.max) {
817
+ this.evict();
818
+ }
819
+ const item = {
820
+ expiry: this.ttl > 0 ? Date.now() + this.ttl : this.ttl,
821
+ key,
822
+ prev: this.last,
823
+ next: null,
824
+ value
825
+ };
826
+ this.items[key] = item;
827
+ if (++this.size === 1) {
828
+ this.first = item;
829
+ } else {
830
+ this.last.next = item;
831
+ }
832
+ this.last = item;
833
+ }
834
+ };
835
+ exports2.Fifo = FifoObject;
836
+ exports2.FifoMap = FifoMap;
837
+ exports2.FifoObject = FifoObject;
838
+ exports2.HitStatisticsRecord = HitStatisticsRecord;
839
+ exports2.Lru = LruObject;
840
+ exports2.LruHitStatistics = LruObjectHitStatistics;
841
+ exports2.LruMap = LruMap;
842
+ exports2.LruObject = LruObject;
843
+ exports2.LruObjectHitStatistics = LruObjectHitStatistics;
844
+ }
845
+ });
846
+
847
+ // node_modules/.pnpm/@fastify+rate-limit@10.3.0/node_modules/@fastify/rate-limit/store/LocalStore.js
848
+ var require_LocalStore = __commonJS({
849
+ "node_modules/.pnpm/@fastify+rate-limit@10.3.0/node_modules/@fastify/rate-limit/store/LocalStore.js"(exports2, module2) {
850
+ "use strict";
851
+ var { LruMap: Lru } = require_toad_cache();
852
+ function LocalStore(continueExceeding, exponentialBackoff, cache = 5e3) {
853
+ this.continueExceeding = continueExceeding;
854
+ this.exponentialBackoff = exponentialBackoff;
855
+ this.lru = new Lru(cache);
856
+ }
857
+ LocalStore.prototype.incr = function(ip, cb, timeWindow, max) {
858
+ const nowInMs = Date.now();
859
+ let current = this.lru.get(ip);
860
+ if (!current) {
861
+ current = { current: 1, ttl: timeWindow, iterationStartMs: nowInMs };
862
+ } else if (current.iterationStartMs + timeWindow <= nowInMs) {
863
+ current.current = 1;
864
+ current.ttl = timeWindow;
865
+ current.iterationStartMs = nowInMs;
866
+ } else {
867
+ ++current.current;
868
+ if (this.continueExceeding && current.current > max) {
869
+ current.ttl = timeWindow;
870
+ current.iterationStartMs = nowInMs;
871
+ } else if (this.exponentialBackoff && current.current > max) {
872
+ const backoffExponent = current.current - max - 1;
873
+ const ttl = timeWindow * 2 ** backoffExponent;
874
+ current.ttl = Number.isSafeInteger(ttl) ? ttl : Number.MAX_SAFE_INTEGER;
875
+ current.iterationStartMs = nowInMs;
876
+ } else {
877
+ current.ttl = timeWindow - (nowInMs - current.iterationStartMs);
878
+ }
879
+ }
880
+ this.lru.set(ip, current);
881
+ cb(null, current);
882
+ };
883
+ LocalStore.prototype.child = function(routeOptions) {
884
+ return new LocalStore(routeOptions.continueExceeding, routeOptions.exponentialBackoff, routeOptions.cache);
885
+ };
886
+ module2.exports = LocalStore;
887
+ }
888
+ });
889
+
890
+ // node_modules/.pnpm/@fastify+rate-limit@10.3.0/node_modules/@fastify/rate-limit/store/RedisStore.js
891
+ var require_RedisStore = __commonJS({
892
+ "node_modules/.pnpm/@fastify+rate-limit@10.3.0/node_modules/@fastify/rate-limit/store/RedisStore.js"(exports2, module2) {
893
+ "use strict";
894
+ var lua = `
895
+ -- Key to operate on
896
+ local key = KEYS[1]
897
+ -- Time window for the TTL
898
+ local timeWindow = tonumber(ARGV[1])
899
+ -- Max requests
900
+ local max = tonumber(ARGV[2])
901
+ -- Flag to determine if TTL should be reset after exceeding
902
+ local continueExceeding = ARGV[3] == 'true'
903
+ --Flag to determine if exponential backoff should be applied
904
+ local exponentialBackoff = ARGV[4] == 'true'
905
+
906
+ --Max safe integer
907
+ local MAX_SAFE_INTEGER = (2^53) - 1
908
+
909
+ -- Increment the key's value
910
+ local current = redis.call('INCR', key)
911
+
912
+ if current == 1 or (continueExceeding and current > max) then
913
+ redis.call('PEXPIRE', key, timeWindow)
914
+ elseif exponentialBackoff and current > max then
915
+ local backoffExponent = current - max - 1
916
+ timeWindow = math.min(timeWindow * (2 ^ backoffExponent), MAX_SAFE_INTEGER)
917
+ redis.call('PEXPIRE', key, timeWindow)
918
+ else
919
+ timeWindow = redis.call('PTTL', key)
920
+ end
921
+
922
+ return {current, timeWindow}
923
+ `;
924
+ function RedisStore(continueExceeding, exponentialBackoff, redis, key = "fastify-rate-limit-") {
925
+ this.continueExceeding = continueExceeding;
926
+ this.exponentialBackoff = exponentialBackoff;
927
+ this.redis = redis;
928
+ this.key = key;
929
+ if (!this.redis.rateLimit) {
930
+ this.redis.defineCommand("rateLimit", {
931
+ numberOfKeys: 1,
932
+ lua
933
+ });
934
+ }
935
+ }
936
+ RedisStore.prototype.incr = function(ip, cb, timeWindow, max) {
937
+ this.redis.rateLimit(this.key + ip, timeWindow, max, this.continueExceeding, this.exponentialBackoff, (err, result) => {
938
+ err ? cb(err, null) : cb(null, { current: result[0], ttl: result[1] });
939
+ });
940
+ };
941
+ RedisStore.prototype.child = function(routeOptions) {
942
+ return new RedisStore(routeOptions.continueExceeding, routeOptions.exponentialBackoff, this.redis, `${this.key}${routeOptions.routeInfo.method}${routeOptions.routeInfo.url}-`);
943
+ };
944
+ module2.exports = RedisStore;
945
+ }
946
+ });
947
+
948
+ // node_modules/.pnpm/@fastify+rate-limit@10.3.0/node_modules/@fastify/rate-limit/index.js
949
+ var require_rate_limit = __commonJS({
950
+ "node_modules/.pnpm/@fastify+rate-limit@10.3.0/node_modules/@fastify/rate-limit/index.js"(exports2, module2) {
951
+ "use strict";
952
+ var fp = require_plugin();
953
+ var { parse: parse2, format: format2 } = require_dist();
954
+ var LocalStore = require_LocalStore();
955
+ var RedisStore = require_RedisStore();
956
+ var defaultMax = 1e3;
957
+ var defaultTimeWindow = 6e4;
958
+ var defaultHook = "onRequest";
959
+ var defaultHeaders = {
960
+ rateLimit: "x-ratelimit-limit",
961
+ rateRemaining: "x-ratelimit-remaining",
962
+ rateReset: "x-ratelimit-reset",
963
+ retryAfter: "retry-after"
964
+ };
965
+ var draftSpecHeaders = {
966
+ rateLimit: "ratelimit-limit",
967
+ rateRemaining: "ratelimit-remaining",
968
+ rateReset: "ratelimit-reset",
969
+ retryAfter: "retry-after"
970
+ };
971
+ var defaultOnFn = () => {
972
+ };
973
+ var defaultKeyGenerator = (req) => req.ip;
974
+ var defaultErrorResponse = (_req, context) => {
975
+ const err = new Error(`Rate limit exceeded, retry in ${context.after}`);
976
+ err.statusCode = context.statusCode;
977
+ return err;
978
+ };
979
+ async function fastifyRateLimit2(fastify, settings) {
980
+ const globalParams = {
981
+ global: typeof settings.global === "boolean" ? settings.global : true
982
+ };
983
+ if (typeof settings.enableDraftSpec === "boolean" && settings.enableDraftSpec) {
984
+ globalParams.enableDraftSpec = true;
985
+ globalParams.labels = draftSpecHeaders;
986
+ } else {
987
+ globalParams.enableDraftSpec = false;
988
+ globalParams.labels = defaultHeaders;
989
+ }
990
+ globalParams.addHeaders = Object.assign({
991
+ [globalParams.labels.rateLimit]: true,
992
+ [globalParams.labels.rateRemaining]: true,
993
+ [globalParams.labels.rateReset]: true,
994
+ [globalParams.labels.retryAfter]: true
995
+ }, settings.addHeaders);
996
+ globalParams.addHeadersOnExceeding = Object.assign({
997
+ [globalParams.labels.rateLimit]: true,
998
+ [globalParams.labels.rateRemaining]: true,
999
+ [globalParams.labels.rateReset]: true
1000
+ }, settings.addHeadersOnExceeding);
1001
+ if (Number.isFinite(settings.max) && settings.max >= 0) {
1002
+ globalParams.max = Math.trunc(settings.max);
1003
+ } else if (typeof settings.max === "function") {
1004
+ globalParams.max = settings.max;
1005
+ } else {
1006
+ globalParams.max = defaultMax;
1007
+ }
1008
+ if (Number.isFinite(settings.timeWindow) && settings.timeWindow >= 0) {
1009
+ globalParams.timeWindow = Math.trunc(settings.timeWindow);
1010
+ } else if (typeof settings.timeWindow === "string") {
1011
+ globalParams.timeWindow = parse2(settings.timeWindow);
1012
+ } else if (typeof settings.timeWindow === "function") {
1013
+ globalParams.timeWindow = settings.timeWindow;
1014
+ } else {
1015
+ globalParams.timeWindow = defaultTimeWindow;
1016
+ }
1017
+ globalParams.hook = settings.hook || defaultHook;
1018
+ globalParams.allowList = settings.allowList || settings.whitelist || null;
1019
+ globalParams.ban = Number.isFinite(settings.ban) && settings.ban >= 0 ? Math.trunc(settings.ban) : -1;
1020
+ globalParams.onBanReach = typeof settings.onBanReach === "function" ? settings.onBanReach : defaultOnFn;
1021
+ globalParams.onExceeding = typeof settings.onExceeding === "function" ? settings.onExceeding : defaultOnFn;
1022
+ globalParams.onExceeded = typeof settings.onExceeded === "function" ? settings.onExceeded : defaultOnFn;
1023
+ globalParams.continueExceeding = typeof settings.continueExceeding === "boolean" ? settings.continueExceeding : false;
1024
+ globalParams.exponentialBackoff = typeof settings.exponentialBackoff === "boolean" ? settings.exponentialBackoff : false;
1025
+ globalParams.keyGenerator = typeof settings.keyGenerator === "function" ? settings.keyGenerator : defaultKeyGenerator;
1026
+ if (typeof settings.errorResponseBuilder === "function") {
1027
+ globalParams.errorResponseBuilder = settings.errorResponseBuilder;
1028
+ globalParams.isCustomErrorMessage = true;
1029
+ } else {
1030
+ globalParams.errorResponseBuilder = defaultErrorResponse;
1031
+ globalParams.isCustomErrorMessage = false;
1032
+ }
1033
+ globalParams.skipOnError = typeof settings.skipOnError === "boolean" ? settings.skipOnError : false;
1034
+ const pluginComponent = {
1035
+ rateLimitRan: /* @__PURE__ */ Symbol("fastify.request.rateLimitRan"),
1036
+ store: null
1037
+ };
1038
+ if (settings.store) {
1039
+ const Store = settings.store;
1040
+ pluginComponent.store = new Store(globalParams);
1041
+ } else {
1042
+ if (settings.redis) {
1043
+ pluginComponent.store = new RedisStore(globalParams.continueExceeding, globalParams.exponentialBackoff, settings.redis, settings.nameSpace);
1044
+ } else {
1045
+ pluginComponent.store = new LocalStore(globalParams.continueExceeding, globalParams.exponentialBackoff, settings.cache);
1046
+ }
1047
+ }
1048
+ fastify.decorateRequest(pluginComponent.rateLimitRan, false);
1049
+ if (!fastify.hasDecorator("createRateLimit")) {
1050
+ fastify.decorate("createRateLimit", (options) => {
1051
+ const args = createLimiterArgs(pluginComponent, globalParams, options);
1052
+ return (req) => applyRateLimit.apply(this, args.concat(req));
1053
+ });
1054
+ }
1055
+ if (!fastify.hasDecorator("rateLimit")) {
1056
+ fastify.decorate("rateLimit", (options) => {
1057
+ const args = createLimiterArgs(pluginComponent, globalParams, options);
1058
+ return rateLimitRequestHandler(...args);
1059
+ });
1060
+ }
1061
+ fastify.addHook("onRoute", (routeOptions) => {
1062
+ if (routeOptions.config?.rateLimit != null) {
1063
+ if (typeof routeOptions.config.rateLimit === "object") {
1064
+ const newPluginComponent = Object.create(pluginComponent);
1065
+ const mergedRateLimitParams = mergeParams(globalParams, routeOptions.config.rateLimit, { routeInfo: routeOptions });
1066
+ newPluginComponent.store = pluginComponent.store.child(mergedRateLimitParams);
1067
+ addRouteRateHook(newPluginComponent, mergedRateLimitParams, routeOptions);
1068
+ } else if (routeOptions.config.rateLimit !== false) {
1069
+ throw new Error("Unknown value for route rate-limit configuration");
1070
+ }
1071
+ } else if (globalParams.global) {
1072
+ addRouteRateHook(pluginComponent, globalParams, routeOptions);
1073
+ }
1074
+ });
1075
+ }
1076
+ function mergeParams(...params) {
1077
+ const result = Object.assign({}, ...params);
1078
+ if (Number.isFinite(result.timeWindow) && result.timeWindow >= 0) {
1079
+ result.timeWindow = Math.trunc(result.timeWindow);
1080
+ } else if (typeof result.timeWindow === "string") {
1081
+ result.timeWindow = parse2(result.timeWindow);
1082
+ } else if (typeof result.timeWindow !== "function") {
1083
+ result.timeWindow = defaultTimeWindow;
1084
+ }
1085
+ if (Number.isFinite(result.max) && result.max >= 0) {
1086
+ result.max = Math.trunc(result.max);
1087
+ } else if (typeof result.max !== "function") {
1088
+ result.max = defaultMax;
1089
+ }
1090
+ if (Number.isFinite(result.ban) && result.ban >= 0) {
1091
+ result.ban = Math.trunc(result.ban);
1092
+ } else {
1093
+ result.ban = -1;
1094
+ }
1095
+ if (result.groupId !== void 0 && typeof result.groupId !== "string") {
1096
+ throw new Error("groupId must be a string");
1097
+ }
1098
+ return result;
1099
+ }
1100
+ function createLimiterArgs(pluginComponent, globalParams, options) {
1101
+ if (typeof options === "object") {
1102
+ const newPluginComponent = Object.create(pluginComponent);
1103
+ const mergedRateLimitParams = mergeParams(globalParams, options, { routeInfo: {} });
1104
+ newPluginComponent.store = newPluginComponent.store.child(mergedRateLimitParams);
1105
+ return [newPluginComponent, mergedRateLimitParams];
1106
+ }
1107
+ return [pluginComponent, globalParams];
1108
+ }
1109
+ function addRouteRateHook(pluginComponent, params, routeOptions) {
1110
+ const hook = params.hook;
1111
+ const hookHandler = rateLimitRequestHandler(pluginComponent, params);
1112
+ if (Array.isArray(routeOptions[hook])) {
1113
+ routeOptions[hook].push(hookHandler);
1114
+ } else if (typeof routeOptions[hook] === "function") {
1115
+ routeOptions[hook] = [routeOptions[hook], hookHandler];
1116
+ } else {
1117
+ routeOptions[hook] = [hookHandler];
1118
+ }
1119
+ }
1120
+ async function applyRateLimit(pluginComponent, params, req) {
1121
+ const { store } = pluginComponent;
1122
+ let key = await params.keyGenerator(req);
1123
+ const groupId = req.routeOptions.config?.rateLimit?.groupId;
1124
+ if (groupId) {
1125
+ key += groupId;
1126
+ }
1127
+ if (params.allowList) {
1128
+ if (typeof params.allowList === "function") {
1129
+ if (await params.allowList(req, key)) {
1130
+ return {
1131
+ isAllowed: true,
1132
+ key
1133
+ };
1134
+ }
1135
+ } else if (params.allowList.indexOf(key) !== -1) {
1136
+ return {
1137
+ isAllowed: true,
1138
+ key
1139
+ };
1140
+ }
1141
+ }
1142
+ const max = typeof params.max === "number" ? params.max : await params.max(req, key);
1143
+ const timeWindow = typeof params.timeWindow === "number" ? params.timeWindow : await params.timeWindow(req, key);
1144
+ let current = 0;
1145
+ let ttl = 0;
1146
+ let ttlInSeconds = 0;
1147
+ try {
1148
+ const res = await new Promise((resolve15, reject2) => {
1149
+ store.incr(key, (err, res2) => {
1150
+ err ? reject2(err) : resolve15(res2);
1151
+ }, timeWindow, max);
1152
+ });
1153
+ current = res.current;
1154
+ ttl = res.ttl;
1155
+ ttlInSeconds = Math.ceil(res.ttl / 1e3);
1156
+ } catch (err) {
1157
+ if (!params.skipOnError) {
1158
+ throw err;
1159
+ }
1160
+ }
1161
+ return {
1162
+ isAllowed: false,
1163
+ key,
1164
+ max,
1165
+ timeWindow,
1166
+ remaining: Math.max(0, max - current),
1167
+ ttl,
1168
+ ttlInSeconds,
1169
+ isExceeded: current > max,
1170
+ isBanned: params.ban !== -1 && current - max > params.ban
1171
+ };
1172
+ }
1173
+ function rateLimitRequestHandler(pluginComponent, params) {
1174
+ const { rateLimitRan } = pluginComponent;
1175
+ return async (req, res) => {
1176
+ if (req[rateLimitRan]) {
1177
+ return;
1178
+ }
1179
+ req[rateLimitRan] = true;
1180
+ const rateLimit = await applyRateLimit(pluginComponent, params, req);
1181
+ if (rateLimit.isAllowed) {
1182
+ return;
1183
+ }
1184
+ const {
1185
+ key,
1186
+ max,
1187
+ remaining,
1188
+ ttl,
1189
+ ttlInSeconds,
1190
+ isExceeded,
1191
+ isBanned
1192
+ } = rateLimit;
1193
+ if (!isExceeded) {
1194
+ if (params.addHeadersOnExceeding[params.labels.rateLimit]) {
1195
+ res.header(params.labels.rateLimit, max);
1196
+ }
1197
+ if (params.addHeadersOnExceeding[params.labels.rateRemaining]) {
1198
+ res.header(params.labels.rateRemaining, remaining);
1199
+ }
1200
+ if (params.addHeadersOnExceeding[params.labels.rateReset]) {
1201
+ res.header(params.labels.rateReset, ttlInSeconds);
1202
+ }
1203
+ params.onExceeding(req, key);
1204
+ return;
1205
+ }
1206
+ params.onExceeded(req, key);
1207
+ if (params.addHeaders[params.labels.rateLimit]) {
1208
+ res.header(params.labels.rateLimit, max);
1209
+ }
1210
+ if (params.addHeaders[params.labels.rateRemaining]) {
1211
+ res.header(params.labels.rateRemaining, 0);
1212
+ }
1213
+ if (params.addHeaders[params.labels.rateReset]) {
1214
+ res.header(params.labels.rateReset, ttlInSeconds);
1215
+ }
1216
+ if (params.addHeaders[params.labels.retryAfter]) {
1217
+ res.header(params.labels.retryAfter, ttlInSeconds);
1218
+ }
1219
+ const respCtx = {
1220
+ statusCode: 429,
1221
+ ban: false,
1222
+ max,
1223
+ ttl,
1224
+ after: format2(ttlInSeconds * 1e3, true)
1225
+ };
1226
+ if (isBanned) {
1227
+ respCtx.statusCode = 403;
1228
+ respCtx.ban = true;
1229
+ params.onBanReach(req, key);
1230
+ }
1231
+ throw params.errorResponseBuilder(req, respCtx);
1232
+ };
1233
+ }
1234
+ module2.exports = fp(fastifyRateLimit2, {
1235
+ fastify: "5.x",
1236
+ name: "@fastify/rate-limit"
1237
+ });
1238
+ module2.exports.default = fastifyRateLimit2;
1239
+ module2.exports.fastifyRateLimit = fastifyRateLimit2;
1240
+ }
1241
+ });
1242
+
1243
+ // packages/server/src/routes/health.ts
1244
+ function registerHealthRoute(app) {
1245
+ app.get("/api/health", async () => {
1246
+ return { status: "ok" };
1247
+ });
1248
+ }
1249
+ var init_health = __esm({
1250
+ "packages/server/src/routes/health.ts"() {
1251
+ "use strict";
1252
+ }
1253
+ });
1254
+
1255
+ // packages/server/src/source-dirs.ts
1256
+ import { readFile as readFile11 } from "fs/promises";
1257
+ import { join as join14, dirname as dirname9 } from "path";
1258
+ import { parse as parseYaml6 } from "yaml";
1259
+ async function readProjectConfig(workspace) {
1260
+ for (const filename of CONFIG_FILENAMES) {
1261
+ try {
1262
+ const raw = await readFile11(join14(workspace, filename), "utf-8");
1263
+ const config = parseYaml6(raw);
1264
+ if (config) return config;
1265
+ } catch {
1266
+ }
1267
+ }
1268
+ return null;
1269
+ }
1270
+ async function resolveSourceDir(workspace) {
1271
+ for (const filename of CONFIG_FILENAMES) {
1272
+ try {
1273
+ const raw = await readFile11(join14(workspace, filename), "utf-8");
1274
+ const config = parseYaml6(raw);
1275
+ if (config?.input?.entry) {
1276
+ return dirname9(config.input.entry);
1277
+ }
1278
+ } catch {
1279
+ }
1280
+ }
1281
+ return DEFAULT_SOURCE_DIR;
1282
+ }
1283
+ async function resolveFileGlobs(workspace) {
1284
+ const sourceDir = await resolveSourceDir(workspace);
1285
+ return [`${sourceDir}/**/*.prs`, "promptscript.yaml", "promptscript.yml"];
1286
+ }
1287
+ async function resolveWatchPaths(workspace) {
1288
+ const sourceDir = await resolveSourceDir(workspace);
1289
+ return [
1290
+ join14(workspace, sourceDir),
1291
+ join14(workspace, "promptscript.yaml"),
1292
+ join14(workspace, "promptscript.yml")
1293
+ ];
1294
+ }
1295
+ var DEFAULT_SOURCE_DIR, CONFIG_FILENAMES;
1296
+ var init_source_dirs = __esm({
1297
+ "packages/server/src/source-dirs.ts"() {
1298
+ "use strict";
1299
+ DEFAULT_SOURCE_DIR = ".promptscript";
1300
+ CONFIG_FILENAMES = ["promptscript.yaml", "promptscript.yml"];
1301
+ }
1302
+ });
1303
+
1304
+ // packages/server/src/routes/config.ts
1305
+ function registerConfigRoute(app, config, workspace) {
1306
+ app.get("/api/config", async () => {
1307
+ const projectConfig = await readProjectConfig(workspace);
1308
+ return { ...config, project: projectConfig };
1309
+ });
1310
+ }
1311
+ var init_config = __esm({
1312
+ "packages/server/src/routes/config.ts"() {
1313
+ "use strict";
1314
+ init_source_dirs();
1315
+ }
1316
+ });
1317
+
1318
+ // packages/server/src/path-guard.ts
1319
+ import { resolve as resolve14, relative as relative2, isAbsolute as isAbsolute4 } from "path";
1320
+ function resolveSafePath(workspace, requestedPath) {
1321
+ const decoded = decodeURIComponent(requestedPath);
1322
+ if (isAbsolute4(decoded)) {
1323
+ throw new PathTraversalError(requestedPath);
1324
+ }
1325
+ const resolved = resolve14(workspace, decoded);
1326
+ const rel = relative2(workspace, resolved);
1327
+ if (rel.startsWith("..") || isAbsolute4(rel)) {
1328
+ throw new PathTraversalError(requestedPath);
1329
+ }
1330
+ return resolved;
1331
+ }
1332
+ var PathTraversalError;
1333
+ var init_path_guard = __esm({
1334
+ "packages/server/src/path-guard.ts"() {
1335
+ "use strict";
1336
+ PathTraversalError = class extends Error {
1337
+ constructor(requestedPath) {
1338
+ super(`Path traversal rejected: ${requestedPath}`);
1339
+ this.name = "PathTraversalError";
1340
+ }
1341
+ };
1342
+ }
1343
+ });
1344
+
1345
+ // packages/server/src/routes/files.ts
1346
+ import { readFile as readFile12, writeFile as writeFile5, unlink, stat, mkdir as mkdir5 } from "fs/promises";
1347
+ import { dirname as dirname10 } from "path";
1348
+ import fg from "fast-glob";
1349
+ function registerRoutes(app, workspace, readOnly) {
1350
+ app.get("/api/files", async () => {
1351
+ const globs = await resolveFileGlobs(workspace);
1352
+ const entries = await fg(globs, {
1353
+ cwd: workspace,
1354
+ stats: true
1355
+ });
1356
+ const files = entries.map((entry) => ({
1357
+ path: entry.path,
1358
+ size: entry.stats?.size ?? 0,
1359
+ modified: entry.stats?.mtime?.toISOString() ?? (/* @__PURE__ */ new Date()).toISOString()
1360
+ }));
1361
+ return { files };
1362
+ });
1363
+ app.get("/api/files/*", async (request, reply) => {
1364
+ const filePath = request.params["*"];
1365
+ try {
1366
+ const resolved = resolveSafePath(workspace, filePath);
1367
+ const content = await readFile12(resolved, "utf-8");
1368
+ return { path: filePath, content };
1369
+ } catch (err) {
1370
+ if (err instanceof PathTraversalError) {
1371
+ return reply.status(403).send({ error: "Forbidden" });
1372
+ }
1373
+ return reply.status(404).send({ error: "File not found" });
1374
+ }
1375
+ });
1376
+ app.put(
1377
+ "/api/files/*",
1378
+ { bodyLimit: MAX_BODY_SIZE },
1379
+ async (request, reply) => {
1380
+ if (readOnly) return reply.status(403).send({ error: "Read-only mode" });
1381
+ const filePath = request.params["*"];
1382
+ try {
1383
+ const resolved = resolveSafePath(workspace, filePath);
1384
+ await writeFile5(resolved, request.body.content, "utf-8");
1385
+ return { path: filePath, status: "updated" };
1386
+ } catch (err) {
1387
+ if (err instanceof PathTraversalError) {
1388
+ return reply.status(403).send({ error: "Forbidden" });
1389
+ }
1390
+ return reply.status(500).send({ error: "Write failed" });
1391
+ }
1392
+ }
1393
+ );
1394
+ app.post(
1395
+ "/api/files/*",
1396
+ { bodyLimit: MAX_BODY_SIZE },
1397
+ async (request, reply) => {
1398
+ if (readOnly) return reply.status(403).send({ error: "Read-only mode" });
1399
+ const filePath = request.params["*"];
1400
+ try {
1401
+ const resolved = resolveSafePath(workspace, filePath);
1402
+ try {
1403
+ await stat(resolved);
1404
+ return reply.status(409).send({ error: "File already exists" });
1405
+ } catch {
1406
+ }
1407
+ await mkdir5(dirname10(resolved), { recursive: true });
1408
+ await writeFile5(resolved, request.body.content, "utf-8");
1409
+ return reply.status(201).send({ path: filePath, status: "created" });
1410
+ } catch (err) {
1411
+ if (err instanceof PathTraversalError) {
1412
+ return reply.status(403).send({ error: "Forbidden" });
1413
+ }
1414
+ return reply.status(500).send({ error: "Create failed" });
1415
+ }
1416
+ }
1417
+ );
1418
+ app.delete("/api/files/*", async (request, reply) => {
1419
+ if (readOnly) return reply.status(403).send({ error: "Read-only mode" });
1420
+ const filePath = request.params["*"];
1421
+ try {
1422
+ const resolved = resolveSafePath(workspace, filePath);
1423
+ await unlink(resolved);
1424
+ return { path: filePath, status: "deleted" };
1425
+ } catch (err) {
1426
+ if (err instanceof PathTraversalError) {
1427
+ return reply.status(403).send({ error: "Forbidden" });
1428
+ }
1429
+ return reply.status(404).send({ error: "File not found" });
1430
+ }
1431
+ });
1432
+ }
1433
+ var MAX_BODY_SIZE;
1434
+ var init_files = __esm({
1435
+ "packages/server/src/routes/files.ts"() {
1436
+ "use strict";
1437
+ init_path_guard();
1438
+ init_source_dirs();
1439
+ MAX_BODY_SIZE = 1048576;
1440
+ }
1441
+ });
1442
+
1443
+ // packages/server/src/watcher.ts
1444
+ import { watch } from "chokidar";
1445
+ import { relative as relative3 } from "path";
1446
+ function isWatchedFile(filePath) {
1447
+ const base = filePath.split("/").pop() ?? "";
1448
+ if (CONFIG_FILENAMES2.has(base)) return true;
1449
+ return base.endsWith(".prs");
1450
+ }
1451
+ function createFileWatcher(workspace, watchPaths, onEvent) {
1452
+ let ready = false;
1453
+ const watcher = watch(watchPaths, { ignoreInitial: true });
1454
+ watcher.on("ready", () => {
1455
+ setTimeout(() => {
1456
+ ready = true;
1457
+ }, 100);
1458
+ });
1459
+ watcher.on("add", (filePath) => {
1460
+ if (!ready || !isWatchedFile(filePath)) return;
1461
+ onEvent({ type: "file:created", path: relative3(workspace, filePath) });
1462
+ });
1463
+ watcher.on("change", (filePath) => {
1464
+ if (!ready || !isWatchedFile(filePath)) return;
1465
+ onEvent({ type: "file:changed", path: relative3(workspace, filePath) });
1466
+ });
1467
+ watcher.on("unlink", (filePath) => {
1468
+ if (!ready || !isWatchedFile(filePath)) return;
1469
+ onEvent({ type: "file:deleted", path: relative3(workspace, filePath) });
1470
+ });
1471
+ return watcher;
1472
+ }
1473
+ var CONFIG_FILENAMES2;
1474
+ var init_watcher = __esm({
1475
+ "packages/server/src/watcher.ts"() {
1476
+ "use strict";
1477
+ CONFIG_FILENAMES2 = /* @__PURE__ */ new Set(["promptscript.yaml", "promptscript.yml"]);
1478
+ }
1479
+ });
1480
+
1481
+ // packages/server/src/server.ts
1482
+ import Fastify from "fastify";
1483
+ import fastifyCors from "@fastify/cors";
1484
+ import fastifyWebsocket from "@fastify/websocket";
1485
+ async function createServer(options) {
1486
+ const app = Fastify({ bodyLimit: 1048576 });
1487
+ await app.register(fastifyCors, {
1488
+ origin: options.corsOrigin
1489
+ });
1490
+ await app.register(import_rate_limit.default, { max: 1e3, timeWindow: "1 minute" });
1491
+ await app.register(fastifyWebsocket);
1492
+ registerHealthRoute(app);
1493
+ registerConfigRoute(
1494
+ app,
1495
+ {
1496
+ mode: options.readOnly ? "readonly" : "readwrite",
1497
+ workspace: options.workspace
1498
+ },
1499
+ options.workspace
1500
+ );
1501
+ registerRoutes(app, options.workspace, options.readOnly);
1502
+ const clients = /* @__PURE__ */ new Set();
1503
+ app.get("/ws", { websocket: true }, (socket) => {
1504
+ clients.add(socket);
1505
+ socket.on("close", () => clients.delete(socket));
1506
+ });
1507
+ const watchPaths = await resolveWatchPaths(options.workspace);
1508
+ const watcher = createFileWatcher(options.workspace, watchPaths, (event) => {
1509
+ const message = JSON.stringify(event);
1510
+ for (const client of clients) {
1511
+ if (client.readyState === 1) {
1512
+ client.send(message);
1513
+ }
1514
+ }
1515
+ });
1516
+ app.addHook("onClose", async () => {
1517
+ await watcher.close();
1518
+ for (const client of clients) {
1519
+ client.close();
1520
+ }
1521
+ });
1522
+ return app;
1523
+ }
1524
+ async function startServer(options) {
1525
+ const app = await createServer(options);
1526
+ const shutdown = () => {
1527
+ const forceTimer = setTimeout(() => process.exit(0), 3e3);
1528
+ forceTimer.unref();
1529
+ app.close().then(
1530
+ () => process.exit(0),
1531
+ () => process.exit(1)
1532
+ );
1533
+ };
1534
+ process.on("SIGINT", shutdown);
1535
+ process.on("SIGTERM", shutdown);
1536
+ try {
1537
+ await app.listen({ port: options.port, host: options.host });
1538
+ } catch (err) {
1539
+ if (err instanceof Error && "code" in err && err.code === "EADDRINUSE") {
1540
+ console.error(`Port ${options.port} is already in use. Try --port <alternative>`);
1541
+ process.exit(1);
1542
+ }
1543
+ throw err;
1544
+ }
1545
+ const displayHost = options.host === "0.0.0.0" ? "localhost" : options.host;
1546
+ const playgroundUrl = `https://getpromptscript.dev/playground/?server=${displayHost}:${options.port}`;
1547
+ console.log(`
1548
+ PromptScript server running at http://${displayHost}:${options.port}`);
1549
+ console.log(`Open playground: ${playgroundUrl}`);
1550
+ console.log(
1551
+ `
1552
+ All compilation happens locally in your browser \u2014 no data is sent to any external server.`
1553
+ );
1554
+ }
1555
+ var import_rate_limit;
1556
+ var init_server = __esm({
1557
+ "packages/server/src/server.ts"() {
1558
+ "use strict";
1559
+ import_rate_limit = __toESM(require_rate_limit(), 1);
1560
+ init_health();
1561
+ init_config();
1562
+ init_files();
1563
+ init_watcher();
1564
+ init_source_dirs();
1565
+ }
1566
+ });
1567
+
1568
+ // packages/server/src/index.ts
1569
+ var src_exports = {};
1570
+ __export(src_exports, {
1571
+ createFileWatcher: () => createFileWatcher,
1572
+ createServer: () => createServer,
1573
+ startServer: () => startServer
1574
+ });
1575
+ var init_src = __esm({
1576
+ "packages/server/src/index.ts"() {
1577
+ "use strict";
1578
+ init_server();
1579
+ init_watcher();
1580
+ }
1581
+ });
10
1582
 
11
1583
  // packages/cli/src/commands/serve.ts
12
1584
  var serve_exports = {};
@@ -14,8 +1586,8 @@ __export(serve_exports, {
14
1586
  serveCommand: () => serveCommand
15
1587
  });
16
1588
  async function serveCommand(options) {
17
- const { startServer } = await import("@promptscript/server");
18
- await startServer({
1589
+ const { startServer: startServer2 } = await Promise.resolve().then(() => (init_src(), src_exports));
1590
+ await startServer2({
19
1591
  port: options.port ? parseInt(options.port, 10) : 3e3,
20
1592
  host: options.host ?? "127.0.0.1",
21
1593
  workspace: process.cwd(),
@@ -32,7 +1604,7 @@ var init_serve = __esm({
32
1604
  // packages/cli/src/cli.ts
33
1605
  import { Command } from "commander";
34
1606
  import { fileURLToPath as fileURLToPath4 } from "url";
35
- import { dirname as dirname9 } from "path";
1607
+ import { dirname as dirname11 } from "path";
36
1608
 
37
1609
  // packages/core/src/types/constants.ts
38
1610
  var BLOCK_TYPES = [
@@ -19961,7 +21533,7 @@ var HttpRegistry = class {
19961
21533
  * Sleep for specified milliseconds.
19962
21534
  */
19963
21535
  sleep(ms) {
19964
- return new Promise((resolve14) => setTimeout(resolve14, ms));
21536
+ return new Promise((resolve15) => setTimeout(resolve15, ms));
19965
21537
  }
19966
21538
  /**
19967
21539
  * Fetch with timeout.
@@ -20394,8 +21966,8 @@ var GitCacheManager = class {
20394
21966
  if (entry.isDirectory()) {
20395
21967
  size += await this.calculateDirSize(fullPath);
20396
21968
  } else {
20397
- const stat = await fs2.stat(fullPath);
20398
- size += stat.size;
21969
+ const stat2 = await fs2.stat(fullPath);
21970
+ size += stat2.size;
20399
21971
  }
20400
21972
  }
20401
21973
  return size;
@@ -23276,12 +24848,12 @@ var Compiler = class _Compiler {
23276
24848
  */
23277
24849
  async watch(entryPath, options = {}) {
23278
24850
  const { default: chokidar2 } = await import("chokidar");
23279
- const { dirname: dirname10, resolve: resolve14 } = await import("path");
23280
- const baseDir = dirname10(resolve14(entryPath));
24851
+ const { dirname: dirname12, resolve: resolve15 } = await import("path");
24852
+ const baseDir = dirname12(resolve15(entryPath));
23281
24853
  const includePatterns = options.include ?? ["**/*.prs"];
23282
24854
  const excludePatterns = options.exclude ?? ["**/node_modules/**"];
23283
24855
  const debounceMs = options.debounce ?? 300;
23284
- const watchPatterns = includePatterns.map((p) => resolve14(baseDir, p));
24856
+ const watchPatterns = includePatterns.map((p) => resolve15(baseDir, p));
23285
24857
  let debounceTimer = null;
23286
24858
  let pendingChanges = [];
23287
24859
  const handleChange = async (changedFiles) => {
@@ -23455,7 +25027,7 @@ var Pager = class {
23455
25027
  }
23456
25028
  return;
23457
25029
  }
23458
- return new Promise((resolve14) => {
25030
+ return new Promise((resolve15) => {
23459
25031
  const pagerCmd = getPagerCommand();
23460
25032
  const [cmd, ...args] = pagerCmd.split(" ");
23461
25033
  if (cmd === "less" && !args.includes("-R")) {
@@ -23463,7 +25035,7 @@ var Pager = class {
23463
25035
  }
23464
25036
  if (!cmd) {
23465
25037
  console.log(content);
23466
- resolve14();
25038
+ resolve15();
23467
25039
  return;
23468
25040
  }
23469
25041
  const pager = spawn(cmd, args, {
@@ -23476,17 +25048,17 @@ var Pager = class {
23476
25048
  });
23477
25049
  pager.on("error", (_err) => {
23478
25050
  console.log(content);
23479
- resolve14();
25051
+ resolve15();
23480
25052
  });
23481
25053
  pager.on("close", () => {
23482
- resolve14();
25054
+ resolve15();
23483
25055
  });
23484
25056
  if (pager.stdin) {
23485
25057
  pager.stdin.write(content);
23486
25058
  pager.stdin.end();
23487
25059
  } else {
23488
25060
  console.log(content);
23489
- resolve14();
25061
+ resolve15();
23490
25062
  }
23491
25063
  });
23492
25064
  }
@@ -23634,7 +25206,7 @@ function parseTargets(targets) {
23634
25206
  async function isPromptScriptGenerated2(filePath) {
23635
25207
  try {
23636
25208
  const content = await readFile7(filePath, "utf-8");
23637
- const lines = content.split("\n").slice(0, 20);
25209
+ const lines = content.split("\n").slice(0, 50);
23638
25210
  return lines.some((line) => PROMPTSCRIPT_MARKERS.some((marker) => line.includes(marker)));
23639
25211
  } catch {
23640
25212
  return false;
@@ -25726,7 +27298,7 @@ async function importCommand(file, options) {
25726
27298
 
25727
27299
  // packages/cli/src/cli.ts
25728
27300
  var __filename4 = fileURLToPath4(import.meta.url);
25729
- var __dirname4 = dirname9(__filename4);
27301
+ var __dirname4 = dirname11(__filename4);
25730
27302
  var program = new Command();
25731
27303
  program.name("prs").description("PromptScript CLI - Standardize AI instructions").version(getPackageVersion(__dirname3, "./package.json")).option("--verbose", "Enable verbose output").option("--debug", "Enable debug output (includes verbose)").option("--quiet", "Suppress non-error output").hook("preAction", async (thisCommand, actionCommand) => {
25732
27304
  const opts = thisCommand.opts();
@@ -25798,6 +27370,15 @@ export {
25798
27370
  };
25799
27371
  /*! Bundled license information:
25800
27372
 
27373
+ toad-cache/dist/toad-cache.cjs:
27374
+ (**
27375
+ * toad-cache
27376
+ *
27377
+ * @copyright 2024 Igor Savin <kibertoad@gmail.com>
27378
+ * @license MIT
27379
+ * @version 3.7.0
27380
+ *)
27381
+
25801
27382
  lodash-es/lodash.js:
25802
27383
  (**
25803
27384
  * @license