@promptscript/cli 1.4.1 → 1.4.3
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 +1598 -17
- package/package.json +7 -2
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
|
|
18
|
-
await
|
|
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
|
|
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((
|
|
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
|
|
20398
|
-
size +=
|
|
21969
|
+
const stat2 = await fs2.stat(fullPath);
|
|
21970
|
+
size += stat2.size;
|
|
20399
21971
|
}
|
|
20400
21972
|
}
|
|
20401
21973
|
return size;
|
|
@@ -21892,7 +23464,7 @@ var suspiciousUrls = {
|
|
|
21892
23464
|
var AUTHORITY_PATTERNS = [
|
|
21893
23465
|
// Mandatory/strict mode indicators
|
|
21894
23466
|
/\[?\s{0,10}MANDATORY\s{0,10}(?:POLICY|UPDATE|FOOTER|INSTRUCTION|DIRECTIVE)\s{0,10}\]?/i,
|
|
21895
|
-
/\[
|
|
23467
|
+
/\[\s{0,10}OVERRIDE\s{0,10}\]/i,
|
|
21896
23468
|
/\[?\s{0,10}STRICT[_\s]{0,10}MODE\s{0,10}[:\s]{1,10}ON\s{0,10}\]?/i,
|
|
21897
23469
|
/\[?\s{0,10}SYSTEM\s{0,10}(?:OVERRIDE|UPDATE|DIRECTIVE)\s{0,10}\]?/i,
|
|
21898
23470
|
/\[?\s{0,10}ADMIN(?:ISTRATOR)?\s{0,10}(?:MODE|OVERRIDE|ACCESS)\s{0,10}\]?/i,
|
|
@@ -21951,7 +23523,7 @@ var DECODED_CONTENT_SECURITY_PATTERNS = [
|
|
|
21951
23523
|
description: "Mandatory/policy override directive"
|
|
21952
23524
|
},
|
|
21953
23525
|
{
|
|
21954
|
-
pattern: /\[
|
|
23526
|
+
pattern: /\[\s{0,10}OVERRIDE\s{0,10}\]/i,
|
|
21955
23527
|
description: "Override directive"
|
|
21956
23528
|
},
|
|
21957
23529
|
{
|
|
@@ -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:
|
|
23280
|
-
const baseDir =
|
|
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) =>
|
|
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((
|
|
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
|
-
|
|
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
|
-
|
|
25051
|
+
resolve15();
|
|
23480
25052
|
});
|
|
23481
25053
|
pager.on("close", () => {
|
|
23482
|
-
|
|
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
|
-
|
|
25061
|
+
resolve15();
|
|
23490
25062
|
}
|
|
23491
25063
|
});
|
|
23492
25064
|
}
|
|
@@ -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 =
|
|
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
|