easy-ping 0.9.0 → 0.10.1
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/README.md +2 -2
- package/dist/adapters/drizzle.cjs +6 -4
- package/dist/adapters/drizzle.cjs.map +1 -1
- package/dist/adapters/drizzle.js +7 -5
- package/dist/adapters/drizzle.js.map +1 -1
- package/dist/adapters/mongodb.cjs.map +1 -1
- package/dist/adapters/mongodb.d.cts +1 -1
- package/dist/adapters/mongodb.d.ts +1 -1
- package/dist/adapters/mongodb.js +1 -1
- package/dist/adapters/mysql.cjs.map +1 -1
- package/dist/adapters/mysql.d.cts +1 -1
- package/dist/adapters/mysql.d.ts +1 -1
- package/dist/adapters/mysql.js +2 -2
- package/dist/adapters/postgres.cjs +3 -3
- package/dist/adapters/postgres.cjs.map +1 -1
- package/dist/adapters/postgres.d.cts +2 -2
- package/dist/adapters/postgres.d.ts +2 -2
- package/dist/adapters/postgres.js +5 -5
- package/dist/adapters/postgres.js.map +1 -1
- package/dist/adapters/sqlite.cjs.map +1 -1
- package/dist/adapters/sqlite.d.cts +1 -1
- package/dist/adapters/sqlite.d.ts +1 -1
- package/dist/adapters/sqlite.js +2 -2
- package/dist/{chunk-EROWLUL4.js → chunk-A4HX5YTG.js} +5 -3
- package/dist/chunk-A4HX5YTG.js.map +1 -0
- package/dist/{chunk-JOVIZXO6.js → chunk-CFLVAF2R.js} +20 -6
- package/dist/chunk-CFLVAF2R.js.map +1 -0
- package/dist/{chunk-2EYKPF5A.js → chunk-CMWOIYVQ.js} +3 -3
- package/dist/{chunk-2EYKPF5A.js.map → chunk-CMWOIYVQ.js.map} +1 -1
- package/dist/{chunk-E4IZ2CQC.js → chunk-JN3UCQBP.js} +2 -2
- package/dist/chunk-JN3UCQBP.js.map +1 -0
- package/dist/{chunk-3VOQOGDR.js → chunk-O2PBBL5X.js} +24 -6
- package/dist/chunk-O2PBBL5X.js.map +1 -0
- package/dist/index.cjs +74 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +39 -7
- package/dist/index.js.map +1 -1
- package/dist/node.cjs +14 -2
- package/dist/node.cjs.map +1 -1
- package/dist/node.js +15 -3
- package/dist/node.js.map +1 -1
- package/dist/{plugin-C4fikLl7.d.ts → plugin-Bp68CCnd.d.ts} +1 -0
- package/dist/{plugin-6S8tpH0n.d.cts → plugin-p4HS8yjS.d.cts} +1 -0
- package/dist/plugins/digests.cjs +1 -1
- package/dist/plugins/digests.cjs.map +1 -1
- package/dist/plugins/digests.d.cts +1 -1
- package/dist/plugins/digests.d.ts +1 -1
- package/dist/plugins/digests.js +1 -1
- package/dist/plugins/digests.js.map +1 -1
- package/dist/plugins/mobile-push.cjs +2 -1
- package/dist/plugins/mobile-push.cjs.map +1 -1
- package/dist/plugins/mobile-push.d.cts +1 -1
- package/dist/plugins/mobile-push.d.ts +1 -1
- package/dist/plugins/mobile-push.js +3 -2
- package/dist/plugins/mobile-push.js.map +1 -1
- package/dist/plugins/preferences-client.cjs.map +1 -1
- package/dist/plugins/preferences-client.d.cts +1 -1
- package/dist/plugins/preferences-client.d.ts +1 -1
- package/dist/plugins/preferences-client.js +1 -1
- package/dist/plugins/preferences.cjs.map +1 -1
- package/dist/plugins/preferences.d.cts +1 -1
- package/dist/plugins/preferences.d.ts +1 -1
- package/dist/plugins/preferences.js +1 -1
- package/dist/plugins/push.cjs.map +1 -1
- package/dist/plugins/push.d.cts +1 -1
- package/dist/plugins/push.d.ts +1 -1
- package/dist/plugins/push.js +1 -1
- package/dist/plugins/telegram.cjs +22 -1
- package/dist/plugins/telegram.cjs.map +1 -1
- package/dist/plugins/telegram.d.cts +1 -1
- package/dist/plugins/telegram.d.ts +1 -1
- package/dist/plugins/telegram.js +23 -2
- package/dist/plugins/telegram.js.map +1 -1
- package/dist/providers/expo-push.cjs +1 -1
- package/dist/providers/expo-push.cjs.map +1 -1
- package/dist/providers/expo-push.js +1 -1
- package/dist/providers/expo-push.js.map +1 -1
- package/dist/providers/web-push.cjs +3 -7
- package/dist/providers/web-push.cjs.map +1 -1
- package/dist/providers/web-push.d.cts +1 -1
- package/dist/providers/web-push.d.ts +1 -1
- package/dist/providers/web-push.js +3 -7
- package/dist/providers/web-push.js.map +1 -1
- package/dist/react-native.cjs +20 -2
- package/dist/react-native.cjs.map +1 -1
- package/dist/react-native.js +20 -2
- package/dist/react-native.js.map +1 -1
- package/dist/react.cjs +20 -2
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +20 -2
- package/dist/react.js.map +1 -1
- package/dist/schema.cjs +3 -1
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +2 -1
- package/dist/schema.d.ts +2 -1
- package/dist/schema.js +1 -1
- package/package.json +8 -3
- package/dist/chunk-3VOQOGDR.js.map +0 -1
- package/dist/chunk-E4IZ2CQC.js.map +0 -1
- package/dist/chunk-EROWLUL4.js.map +0 -1
- package/dist/chunk-JOVIZXO6.js.map +0 -1
|
@@ -68,6 +68,22 @@ function createPluginStore(pluginId, schema, storage, prefix) {
|
|
|
68
68
|
}
|
|
69
69
|
return declaration;
|
|
70
70
|
}
|
|
71
|
+
function writable(table) {
|
|
72
|
+
const declaration = resolve(table);
|
|
73
|
+
if (declaration.readOnly) {
|
|
74
|
+
throw new ConfigError(
|
|
75
|
+
`plugin "${pluginId}" tried to write "${table}", which it declares readOnly.`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
return declaration;
|
|
79
|
+
}
|
|
80
|
+
function notEverything(table, where, action) {
|
|
81
|
+
if (Object.keys(where).length === 0) {
|
|
82
|
+
throw new ConfigError(
|
|
83
|
+
`plugin "${pluginId}" called ${action}("${table}", {}), which would touch every row. Pass a condition.`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
71
87
|
function checkFields(table, fields, context) {
|
|
72
88
|
for (const field of fields) {
|
|
73
89
|
const spec = Object.hasOwn(table.fields, field) ? table.fields[field] : void 0;
|
|
@@ -126,7 +142,7 @@ function createPluginStore(pluginId, schema, storage, prefix) {
|
|
|
126
142
|
});
|
|
127
143
|
},
|
|
128
144
|
async insert(table, rows) {
|
|
129
|
-
const declaration =
|
|
145
|
+
const declaration = writable(table);
|
|
130
146
|
for (const row of rows) checkRow(declaration, row, "insert");
|
|
131
147
|
return storage.insertRows(
|
|
132
148
|
qualified(declaration),
|
|
@@ -134,7 +150,7 @@ function createPluginStore(pluginId, schema, storage, prefix) {
|
|
|
134
150
|
);
|
|
135
151
|
},
|
|
136
152
|
async upsert(table, rows, options) {
|
|
137
|
-
const declaration =
|
|
153
|
+
const declaration = writable(table);
|
|
138
154
|
for (const row of rows) checkRow(declaration, row, "upsert");
|
|
139
155
|
checkFields(declaration, options.onConflict, "onConflict");
|
|
140
156
|
return storage.insertRows(
|
|
@@ -144,19 +160,21 @@ function createPluginStore(pluginId, schema, storage, prefix) {
|
|
|
144
160
|
);
|
|
145
161
|
},
|
|
146
162
|
async update(table, where, set) {
|
|
147
|
-
const declaration =
|
|
163
|
+
const declaration = writable(table);
|
|
148
164
|
checkWhere(declaration, where);
|
|
165
|
+
notEverything(table, where, "update");
|
|
149
166
|
checkRow(declaration, set, "update");
|
|
150
167
|
return storage.updateRows(qualified(declaration), where, serialize(declaration, set));
|
|
151
168
|
},
|
|
152
169
|
async remove(table, where) {
|
|
153
|
-
const declaration =
|
|
170
|
+
const declaration = writable(table);
|
|
154
171
|
checkWhere(declaration, where);
|
|
172
|
+
notEverything(table, where, "remove");
|
|
155
173
|
return storage.deleteRows(qualified(declaration), where);
|
|
156
174
|
}
|
|
157
175
|
};
|
|
158
176
|
}
|
|
159
177
|
|
|
160
178
|
export { ConfigError, EasyPingError, ValidationError, consoleLogger, createPluginStore, isOperator };
|
|
161
|
-
//# sourceMappingURL=chunk-
|
|
162
|
-
//# sourceMappingURL=chunk-
|
|
179
|
+
//# sourceMappingURL=chunk-O2PBBL5X.js.map
|
|
180
|
+
//# sourceMappingURL=chunk-O2PBBL5X.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/errors.ts","../src/core/store.ts"],"names":[],"mappings":"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","file":"chunk-O2PBBL5X.js","sourcesContent":["export class EasyPingError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"EasyPingError\";\n }\n}\n\n/** Thrown when a payload fails its Standard Schema. Developer error. */\nexport class ValidationError extends EasyPingError {\n readonly issues: readonly { message: string; path?: string }[];\n\n constructor(type: string, issues: readonly { message: string; path?: string }[]) {\n super(`Payload for \"${type}\" failed validation: ${issues.map((i) => i.message).join(\"; \")}`);\n this.name = \"ValidationError\";\n this.issues = issues;\n }\n}\n\n/** Thrown at startup for a malformed config. Never at send time. */\nexport class ConfigError extends EasyPingError {\n constructor(message: string) {\n super(message);\n this.name = \"ConfigError\";\n }\n}\n\nexport type Logger = {\n warn: (message: string, meta?: Record<string, unknown>) => void;\n error: (message: string, meta?: Record<string, unknown>) => void;\n};\n\nexport const consoleLogger: Logger = {\n warn: (message, meta) => console.warn(`[easy-ping] ${message}`, meta ?? \"\"),\n error: (message, meta) => console.error(`[easy-ping] ${message}`, meta ?? \"\"),\n};\n","import { toSnakeCase } from \"../schema/declaration\";\nimport { ConfigError } from \"./errors\";\nimport type { FieldDeclaration, SchemaDeclaration, TableDeclaration } from \"./plugin\";\n\nexport type Scalar = string | number | boolean | Date | null;\n\n/** Operators are tagged objects so a bare value is always equality; json columns cannot be filtered. */\nexport type WhereCondition =\n | Scalar\n | { in: readonly (string | number)[] }\n | { lt: Date | number }\n | { lte: Date | number }\n | { gt: Date | number }\n | { gte: Date | number }\n | { not: Scalar };\n\nexport type WhereClause = Record<string, WhereCondition>;\n\nexport type QueryOptions = {\n limit?: number;\n orderBy?: { field: string; direction: \"asc\" | \"desc\" };\n};\n\nexport type UpsertOptions = { onConflict: readonly string[] };\n\n/** Table access for plugins, scoped to the tables the plugin declared. */\nexport type PluginStore = {\n find<T = Record<string, unknown>>(\n table: string,\n where?: WhereClause,\n options?: QueryOptions,\n ): Promise<T[]>;\n insert(table: string, rows: readonly Record<string, unknown>[]): Promise<number>;\n upsert(\n table: string,\n rows: readonly Record<string, unknown>[],\n options: UpsertOptions,\n ): Promise<number>;\n update(table: string, where: WhereClause, set: Record<string, unknown>): Promise<number>;\n remove(table: string, where: WhereClause): Promise<number>;\n};\n\nexport type TableStorage = {\n readonly naming?: \"snake_case\" | \"preserve\";\n readonly serializesJson?: boolean;\n\n queryTable(\n table: string,\n where: WhereClause,\n options: QueryOptions,\n ): Promise<Record<string, unknown>[]>;\n insertRows(\n table: string,\n rows: readonly Record<string, unknown>[],\n onConflict?: readonly string[],\n ): Promise<number>;\n updateRows(table: string, where: WhereClause, set: Record<string, unknown>): Promise<number>;\n deleteRows(table: string, where: WhereClause): Promise<number>;\n};\n\nconst OPERATORS = [\"in\", \"lt\", \"lte\", \"gt\", \"gte\", \"not\"] as const;\n\nexport const isOperator = (value: unknown): boolean =>\n typeof value === \"object\" &&\n value !== null &&\n !(value instanceof Date) &&\n OPERATORS.some((op) => Object.hasOwn(value, op));\n\nconst isScalar = (value: unknown): value is Scalar =>\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n value instanceof Date;\n\n/** A forwarded JSON body can carry `{ $ne: … }`; refuse anything that is not a scalar or a known operator. */\nfunction assertCondition(pluginId: string, field: string, condition: unknown): void {\n if (isScalar(condition)) return;\n\n if (isOperator(condition)) {\n const operator = condition as Record<string, unknown>;\n const keys = Object.keys(operator);\n const [op] = keys;\n if (keys.length !== 1 || op === undefined) {\n throw new ConfigError(`plugin \"${pluginId}\" gave field \"${field}\" more than one operator.`);\n }\n const payload = operator[op];\n const valid =\n op === \"in\"\n ? Array.isArray(payload) &&\n payload.every((item) => typeof item === \"string\" || typeof item === \"number\")\n : isScalar(payload);\n if (valid) return;\n }\n\n throw new ConfigError(\n `plugin \"${pluginId}\" passed a non-scalar value for field \"${field}\"; ` +\n \"validate request bodies before querying with them.\",\n );\n}\n\nfunction assertValue(pluginId: string, field: string, spec: FieldDeclaration, value: unknown) {\n if (value === undefined || isScalar(value)) return;\n if (spec.type === \"json\" && typeof value === \"object\") return;\n throw new ConfigError(\n `plugin \"${pluginId}\" passed a non-scalar value for ${spec.type} field \"${field}\".`,\n );\n}\n\n/** Every table and column is checked against the plugin's own declaration. */\nexport function createPluginStore(\n pluginId: string,\n schema: SchemaDeclaration | undefined,\n storage: TableStorage,\n prefix: string,\n): PluginStore {\n const byTableName = new Map<string, TableDeclaration>();\n for (const declaration of Object.values(schema ?? {})) {\n byTableName.set(declaration.tableName, declaration);\n }\n\n function resolve(table: string): TableDeclaration {\n const declaration = byTableName.get(table);\n if (!declaration) {\n throw new ConfigError(\n `plugin \"${pluginId}\" accessed table \"${table}\", which it does not declare in schema().`,\n );\n }\n return declaration;\n }\n\n function writable(table: string): TableDeclaration {\n const declaration = resolve(table);\n if (declaration.readOnly) {\n throw new ConfigError(\n `plugin \"${pluginId}\" tried to write \"${table}\", which it declares readOnly.`,\n );\n }\n return declaration;\n }\n\n function notEverything(table: string, where: WhereClause, action: string) {\n if (Object.keys(where).length === 0) {\n throw new ConfigError(\n `plugin \"${pluginId}\" called ${action}(\"${table}\", {}), which would touch every row. ` +\n \"Pass a condition.\",\n );\n }\n }\n\n function checkFields(table: TableDeclaration, fields: Iterable<string>, context: string) {\n for (const field of fields) {\n // hasOwn, not a lookup: `constructor` and `__proto__` are not columns.\n const spec = Object.hasOwn(table.fields, field) ? table.fields[field] : undefined;\n if (!spec) {\n throw new ConfigError(\n `plugin \"${pluginId}\" used unknown field \"${field}\" on \"${table.tableName}\" (${context}).`,\n );\n }\n if (context === \"where\" && spec.type === \"json\") {\n throw new ConfigError(\n `plugin \"${pluginId}\" cannot filter on json field \"${field}\"; ` +\n \"a bare object value is indistinguishable from an operator.\",\n );\n }\n }\n }\n\n function checkWhere(table: TableDeclaration, where: WhereClause) {\n checkFields(table, Object.keys(where), \"where\");\n for (const [field, condition] of Object.entries(where)) {\n assertCondition(pluginId, field, condition);\n }\n }\n\n function checkRow(table: TableDeclaration, row: Record<string, unknown>, context: string) {\n checkFields(table, Object.keys(row), context);\n for (const [field, value] of Object.entries(row)) {\n const spec = table.fields[field];\n if (spec) assertValue(pluginId, field, spec, value);\n }\n }\n\n const qualified = (table: TableDeclaration) => prefix + table.tableName;\n\n // A document store keeps the declared names; a SQL adapter wants columns.\n const column = (field: string) => (storage.naming === \"preserve\" ? field : toSnakeCase(field));\n\n // json must reach postgres-js as text.\n const serialize = (table: TableDeclaration, row: Record<string, unknown>) => {\n if (storage.serializesJson === false) return row;\n\n const out: Record<string, unknown> = {};\n for (const [field, value] of Object.entries(row)) {\n out[field] =\n table.fields[field]?.type === \"json\" && value !== null && value !== undefined\n ? JSON.stringify(value)\n : value;\n }\n return out;\n };\n\n return {\n async find(table, where = {}, options = {}) {\n const declaration = resolve(table);\n checkWhere(declaration, where);\n if (options.orderBy) checkFields(declaration, [options.orderBy.field], \"orderBy\");\n\n const rows = await storage.queryTable(qualified(declaration), where, options);\n\n // SELECT * returns snake_case; plugins read camelCase.\n return rows.map((row) => {\n const mapped: Record<string, unknown> = {};\n for (const field of Object.keys(declaration.fields)) {\n const value = row[column(field)];\n const type = declaration.fields[field]?.type;\n // Drivers differ on jsonb (parsed or text) and timestamptz (Date or text).\n if (type === \"json\" && typeof value === \"string\") mapped[field] = JSON.parse(value);\n else if (type === \"date\" && typeof value === \"string\") mapped[field] = new Date(value);\n // MySQL and SQLite have no boolean column; they hand back 0 and 1.\n else if (type === \"boolean\" && typeof value === \"number\") mapped[field] = value !== 0;\n else mapped[field] = value;\n }\n return mapped;\n }) as never;\n },\n\n async insert(table, rows) {\n const declaration = writable(table);\n for (const row of rows) checkRow(declaration, row, \"insert\");\n return storage.insertRows(\n qualified(declaration),\n rows.map((row) => serialize(declaration, row)),\n );\n },\n\n async upsert(table, rows, options) {\n const declaration = writable(table);\n for (const row of rows) checkRow(declaration, row, \"upsert\");\n checkFields(declaration, options.onConflict, \"onConflict\");\n return storage.insertRows(\n qualified(declaration),\n rows.map((row) => serialize(declaration, row)),\n options.onConflict,\n );\n },\n\n async update(table, where, set) {\n const declaration = writable(table);\n checkWhere(declaration, where);\n notEverything(table, where, \"update\");\n checkRow(declaration, set, \"update\");\n return storage.updateRows(qualified(declaration), where, serialize(declaration, set));\n },\n\n async remove(table, where) {\n const declaration = writable(table);\n checkWhere(declaration, where);\n notEverything(table, where, \"remove\");\n return storage.deleteRows(qualified(declaration), where);\n },\n };\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -209,6 +209,7 @@ function createScopedSigner(secret, pluginId, purposes, onViolation) {
|
|
|
209
209
|
var STREAM_HIGH_WATER_MARK = 256;
|
|
210
210
|
var MAX_BODY_BYTES = 64 * 1024;
|
|
211
211
|
var MAX_READ_IDS = 200;
|
|
212
|
+
var SESSION_ERROR = /* @__PURE__ */ Symbol("session-error");
|
|
212
213
|
var PRIVATE_HEADERS = {
|
|
213
214
|
"cache-control": "private, no-store",
|
|
214
215
|
"x-content-type-options": "nosniff"
|
|
@@ -308,13 +309,26 @@ function csrfCheck(request, url, trusted) {
|
|
|
308
309
|
function createHandler(deps) {
|
|
309
310
|
const trustedOrigins = deps.trustedOrigins ?? [];
|
|
310
311
|
const maxBodyBytes = deps.maxBodyBytes ?? MAX_BODY_BYTES;
|
|
312
|
+
let warnedBadUserId = false;
|
|
311
313
|
async function resolveUserId(request) {
|
|
314
|
+
let id;
|
|
312
315
|
try {
|
|
313
|
-
|
|
316
|
+
id = await deps.session.getUserId(request);
|
|
314
317
|
} catch (error) {
|
|
315
318
|
deps.logger.error("session.getUserId threw", { error });
|
|
316
|
-
return
|
|
319
|
+
return SESSION_ERROR;
|
|
317
320
|
}
|
|
321
|
+
if (id === null || id === void 0) return null;
|
|
322
|
+
if (typeof id !== "string" || id === "") {
|
|
323
|
+
if (!warnedBadUserId) {
|
|
324
|
+
warnedBadUserId = true;
|
|
325
|
+
deps.logger.warn(
|
|
326
|
+
`session.getUserId returned ${id === "" ? "an empty string" : typeof id}; treating the request as unauthenticated. Return a non-empty string or null.`
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
return id;
|
|
318
332
|
}
|
|
319
333
|
async function bearerMatches(request, secret) {
|
|
320
334
|
if (!secret) return false;
|
|
@@ -337,7 +351,7 @@ function createHandler(deps) {
|
|
|
337
351
|
if (rejected) return rejected;
|
|
338
352
|
}
|
|
339
353
|
const userId = await resolveUserId(request);
|
|
340
|
-
if (userId ===
|
|
354
|
+
if (userId === SESSION_ERROR) return empty(500);
|
|
341
355
|
if (userId === null) return empty(401);
|
|
342
356
|
return harden(await route2.handler({ request, userId, claims: null, params: {} }));
|
|
343
357
|
}
|
|
@@ -378,7 +392,7 @@ function createHandler(deps) {
|
|
|
378
392
|
if (rejected) return rejected;
|
|
379
393
|
}
|
|
380
394
|
const userId = await resolveUserId(request);
|
|
381
|
-
if (userId ===
|
|
395
|
+
if (userId === SESSION_ERROR) return empty(500);
|
|
382
396
|
if (userId === null) return empty(401);
|
|
383
397
|
if (request.method === "GET" && path === "/events") {
|
|
384
398
|
if (!deps.events) return empty(404);
|
|
@@ -582,12 +596,23 @@ var ESCAPES = {
|
|
|
582
596
|
var escapeHtml = (value) => String(value ?? "").replace(/[&<>"']/g, (char) => ESCAPES[char] ?? char);
|
|
583
597
|
|
|
584
598
|
// src/core/rate-limit.ts
|
|
599
|
+
var UNKEYED = "\0unkeyed";
|
|
585
600
|
var clientAddress = (request) => {
|
|
586
601
|
const headers = request.headers;
|
|
587
602
|
return headers.get("cf-connecting-ip") ?? headers.get("x-real-ip") ?? headers.get("x-forwarded-for")?.split(",")[0]?.trim() ?? null;
|
|
588
603
|
};
|
|
589
604
|
function createRateLimiter(config) {
|
|
590
|
-
|
|
605
|
+
let warned = false;
|
|
606
|
+
const keyOf = config.key ?? ((request) => {
|
|
607
|
+
const address = clientAddress(request);
|
|
608
|
+
if (address !== null) return address;
|
|
609
|
+
if (!warned) {
|
|
610
|
+
warned = true;
|
|
611
|
+
config.onUnkeyed?.();
|
|
612
|
+
}
|
|
613
|
+
return UNKEYED;
|
|
614
|
+
});
|
|
615
|
+
const maxKeys = Math.max(1, config.maxKeys ?? 1e4);
|
|
591
616
|
const buckets = /* @__PURE__ */ new Map();
|
|
592
617
|
let lastSweep = 0;
|
|
593
618
|
return (request) => {
|
|
@@ -600,7 +625,12 @@ function createRateLimiter(config) {
|
|
|
600
625
|
}
|
|
601
626
|
let bucket = buckets.get(key);
|
|
602
627
|
if (!bucket || bucket.resetAt <= now) {
|
|
628
|
+
if (!bucket && buckets.size >= maxKeys) {
|
|
629
|
+
const oldest = buckets.keys().next().value;
|
|
630
|
+
if (oldest !== void 0) buckets.delete(oldest);
|
|
631
|
+
}
|
|
603
632
|
bucket = { count: 0, resetAt: now + config.windowMs };
|
|
633
|
+
buckets.delete(key);
|
|
604
634
|
buckets.set(key, bucket);
|
|
605
635
|
}
|
|
606
636
|
bucket.count += 1;
|
|
@@ -1095,6 +1125,22 @@ function createPluginStore(pluginId, schema, storage, prefix) {
|
|
|
1095
1125
|
}
|
|
1096
1126
|
return declaration;
|
|
1097
1127
|
}
|
|
1128
|
+
function writable(table) {
|
|
1129
|
+
const declaration = resolve(table);
|
|
1130
|
+
if (declaration.readOnly) {
|
|
1131
|
+
throw new ConfigError(
|
|
1132
|
+
`plugin "${pluginId}" tried to write "${table}", which it declares readOnly.`
|
|
1133
|
+
);
|
|
1134
|
+
}
|
|
1135
|
+
return declaration;
|
|
1136
|
+
}
|
|
1137
|
+
function notEverything(table, where, action) {
|
|
1138
|
+
if (Object.keys(where).length === 0) {
|
|
1139
|
+
throw new ConfigError(
|
|
1140
|
+
`plugin "${pluginId}" called ${action}("${table}", {}), which would touch every row. Pass a condition.`
|
|
1141
|
+
);
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1098
1144
|
function checkFields(table, fields, context) {
|
|
1099
1145
|
for (const field of fields) {
|
|
1100
1146
|
const spec = Object.hasOwn(table.fields, field) ? table.fields[field] : void 0;
|
|
@@ -1153,7 +1199,7 @@ function createPluginStore(pluginId, schema, storage, prefix) {
|
|
|
1153
1199
|
});
|
|
1154
1200
|
},
|
|
1155
1201
|
async insert(table, rows) {
|
|
1156
|
-
const declaration =
|
|
1202
|
+
const declaration = writable(table);
|
|
1157
1203
|
for (const row of rows) checkRow(declaration, row, "insert");
|
|
1158
1204
|
return storage.insertRows(
|
|
1159
1205
|
qualified(declaration),
|
|
@@ -1161,7 +1207,7 @@ function createPluginStore(pluginId, schema, storage, prefix) {
|
|
|
1161
1207
|
);
|
|
1162
1208
|
},
|
|
1163
1209
|
async upsert(table, rows, options) {
|
|
1164
|
-
const declaration =
|
|
1210
|
+
const declaration = writable(table);
|
|
1165
1211
|
for (const row of rows) checkRow(declaration, row, "upsert");
|
|
1166
1212
|
checkFields(declaration, options.onConflict, "onConflict");
|
|
1167
1213
|
return storage.insertRows(
|
|
@@ -1171,14 +1217,16 @@ function createPluginStore(pluginId, schema, storage, prefix) {
|
|
|
1171
1217
|
);
|
|
1172
1218
|
},
|
|
1173
1219
|
async update(table, where, set) {
|
|
1174
|
-
const declaration =
|
|
1220
|
+
const declaration = writable(table);
|
|
1175
1221
|
checkWhere(declaration, where);
|
|
1222
|
+
notEverything(table, where, "update");
|
|
1176
1223
|
checkRow(declaration, set, "update");
|
|
1177
1224
|
return storage.updateRows(qualified(declaration), where, serialize(declaration, set));
|
|
1178
1225
|
},
|
|
1179
1226
|
async remove(table, where) {
|
|
1180
|
-
const declaration =
|
|
1227
|
+
const declaration = writable(table);
|
|
1181
1228
|
checkWhere(declaration, where);
|
|
1229
|
+
notEverything(table, where, "remove");
|
|
1182
1230
|
return storage.deleteRows(qualified(declaration), where);
|
|
1183
1231
|
}
|
|
1184
1232
|
};
|
|
@@ -1257,7 +1305,18 @@ function validate(config, plugins) {
|
|
|
1257
1305
|
}
|
|
1258
1306
|
}
|
|
1259
1307
|
}
|
|
1308
|
+
const core = new Set(CORE_ROUTES.map((route) => `${route.method} ${route.path}`));
|
|
1260
1309
|
const routes = /* @__PURE__ */ new Set();
|
|
1310
|
+
for (const plugin of plugins) {
|
|
1311
|
+
for (const route of plugin.routes ?? []) {
|
|
1312
|
+
const signature = `${route.method} ${route.path}`;
|
|
1313
|
+
if (core.has(signature)) {
|
|
1314
|
+
throw new ConfigError(
|
|
1315
|
+
`plugin "${plugin.id}" registers "${signature}", which is a core route. Pick another path.`
|
|
1316
|
+
);
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1261
1320
|
for (const plugin of plugins) {
|
|
1262
1321
|
for (const route of plugin.routes ?? []) {
|
|
1263
1322
|
const signature = `${route.method} ${route.path}`;
|
|
@@ -1374,7 +1433,12 @@ function easyPing(config) {
|
|
|
1374
1433
|
trustedOrigins: config.trustedOrigins,
|
|
1375
1434
|
onRequest: config.onRequest,
|
|
1376
1435
|
maxBodyBytes: config.maxBodyBytes,
|
|
1377
|
-
rateLimit: config.rateLimit ? createRateLimiter(
|
|
1436
|
+
rateLimit: config.rateLimit ? createRateLimiter({
|
|
1437
|
+
onUnkeyed: () => logger.warn(
|
|
1438
|
+
"rateLimit: a request arrived with no cf-connecting-ip, x-real-ip or x-forwarded-for header, so every such request shares one bucket. Put the app behind a proxy that sets one of them, or pass rateLimit.key (a session or API key)."
|
|
1439
|
+
),
|
|
1440
|
+
...config.rateLimit
|
|
1441
|
+
}) : void 0,
|
|
1378
1442
|
cronMaxSweeps: config.cron?.maxSweeps,
|
|
1379
1443
|
...config.cron?.secret ? { cronSecret: config.cron.secret } : {},
|
|
1380
1444
|
...config.machineSecret ?? config.cron?.secret ? { machineSecret: config.machineSecret ?? config.cron?.secret } : {}
|