@getstrata/core 0.5.13 → 0.5.15
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 +16 -6
- package/dist/bootstrap/contracts.d.ts +2 -0
- package/dist/bootstrap/httpKernel.d.ts +1 -2
- package/dist/core/admin/registry.d.ts +1 -0
- package/dist/core/auth/membershipService.d.ts +5 -1
- package/dist/core/database/baseRepository.d.ts +6 -1
- package/dist/core/database/connectionContext.d.ts +2 -1
- package/dist/core/database/defaultConnection.d.ts +6 -0
- package/dist/core/database/queryProxy.d.ts +3 -0
- package/dist/core/database/repositoryConnection.d.ts +3 -3
- package/dist/core/jobs/dispatchWebhookJob.d.ts +0 -1
- package/dist/core/security/safeFetch.d.ts +2 -0
- package/dist/core/security/safeUrl.d.ts +16 -1
- package/dist/core/storage/storage.d.ts +6 -3
- package/dist/core/tenant/tenantDatabaseScope.d.ts +2 -1
- package/dist/db/connection/index.d.ts +1 -1
- package/dist/entries/auth/accessControl.js +1 -113
- package/dist/entries/auth/authContext.js +1 -15
- package/dist/entries/auth/guard.js +1 -3044
- package/dist/entries/auth/membershipContext.js +1 -276
- package/dist/entries/auth/membershipScope.js +1 -390
- package/dist/entries/auth/membershipService.js +1 -480
- package/dist/entries/auth/policy.js +1 -134
- package/dist/entries/database.js +1 -2398
- package/dist/entries/http/csrfToken.js +0 -6
- package/dist/entries/http/middleware.js +1 -68
- package/dist/entries/http/requestMetaContext.js +1 -18
- package/dist/entries/http/webErrorResponse.js +94 -563
- package/dist/entries/http/webFormRequest.js +0 -131
- package/dist/entries/http.js +1 -4091
- package/dist/entries/jobs/dispatchWebhookJob.js +109 -102
- package/dist/entries/queue/createAppQueue.js +111 -631
- package/dist/entries/queue/jobRunner.js +0 -3
- package/dist/entries/queue/publicQueue.js +45 -546
- package/dist/entries/queue/queueMetrics.js +111 -631
- package/dist/entries/security/safeUrl.js +29 -0
- package/dist/entries/security/securityEvents.js +1 -41
- package/dist/entries/storage/storage.js +14 -4
- package/dist/entries/tenant/tenantContext.js +1 -30
- package/dist/entries/tenant/tenantMiddleware.js +1 -312
- package/dist/entries/tracing/traceContext.js +1 -15
- package/dist/entries/view.js +94 -563
- package/dist/framework/public-api.d.ts +36 -4
- package/dist/index.js +2270 -1666
- package/dist/modules/user/repository.d.ts +1 -0
- package/package.json +6 -5
|
@@ -109,9 +109,6 @@ function formDataToRecord(formData) {
|
|
|
109
109
|
// ../../src/core/auth/authContext.ts
|
|
110
110
|
import { AsyncLocalStorage } from "async_hooks";
|
|
111
111
|
var authContext = new AsyncLocalStorage;
|
|
112
|
-
function runWithAuthUser(user, callback) {
|
|
113
|
-
return authContext.run(user, callback);
|
|
114
|
-
}
|
|
115
112
|
function currentAuthUser() {
|
|
116
113
|
return authContext.getStore() ?? null;
|
|
117
114
|
}
|
|
@@ -119,86 +116,14 @@ function currentAuthUser() {
|
|
|
119
116
|
// ../../src/core/tenant/tenantContext.ts
|
|
120
117
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
121
118
|
var tenantContext = new AsyncLocalStorage2;
|
|
122
|
-
function runWithTenant(tenant, callback) {
|
|
123
|
-
return tenantContext.run(tenant, callback);
|
|
124
|
-
}
|
|
125
119
|
function currentTenant() {
|
|
126
120
|
return tenantContext.getStore() ?? null;
|
|
127
121
|
}
|
|
128
122
|
function currentTenantId() {
|
|
129
123
|
return currentTenant()?.id ?? 1;
|
|
130
124
|
}
|
|
131
|
-
function rateLimitMultiplierForPlan(plan) {
|
|
132
|
-
switch (plan) {
|
|
133
|
-
case "enterprise":
|
|
134
|
-
return 4;
|
|
135
|
-
case "pro":
|
|
136
|
-
return 2;
|
|
137
|
-
default:
|
|
138
|
-
return 1;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
125
|
|
|
142
126
|
// ../../src/core/http/validation.ts
|
|
143
|
-
function buildRequestCacheKey(fallbackPath, request) {
|
|
144
|
-
if (!request) {
|
|
145
|
-
return fallbackPath;
|
|
146
|
-
}
|
|
147
|
-
const url = new URL(request.url);
|
|
148
|
-
const user = currentAuthUser();
|
|
149
|
-
const authScope = user ? `u:${user.id}` : "guest";
|
|
150
|
-
const tenantScope = `t:${currentTenantId()}`;
|
|
151
|
-
return `${authScope}|${tenantScope}|${url.pathname}${url.search}`;
|
|
152
|
-
}
|
|
153
|
-
function getQueryParams(request) {
|
|
154
|
-
if (!request) {
|
|
155
|
-
return new URLSearchParams;
|
|
156
|
-
}
|
|
157
|
-
return new URL(request.url).searchParams;
|
|
158
|
-
}
|
|
159
|
-
function parseOptionalPositiveIntQueryParam(params, name) {
|
|
160
|
-
const value = params.get(name);
|
|
161
|
-
if (value === null || value.trim() === "") {
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
const parsed = Number.parseInt(value, 10);
|
|
165
|
-
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
166
|
-
throw new BadRequestError(`Invalid query parameter "${name}". Expected a positive integer.`);
|
|
167
|
-
}
|
|
168
|
-
return parsed;
|
|
169
|
-
}
|
|
170
|
-
function parseOptionalBooleanQueryParam(params, name) {
|
|
171
|
-
const value = params.get(name);
|
|
172
|
-
if (value === null || value.trim() === "") {
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
switch (value.toLowerCase()) {
|
|
176
|
-
case "true":
|
|
177
|
-
case "1":
|
|
178
|
-
return true;
|
|
179
|
-
case "false":
|
|
180
|
-
case "0":
|
|
181
|
-
return false;
|
|
182
|
-
default:
|
|
183
|
-
throw new BadRequestError(`Invalid query parameter "${name}". Expected a boolean.`);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
function parseOptionalEnumQueryParam(params, name, allowedValues) {
|
|
187
|
-
const value = params.get(name);
|
|
188
|
-
if (value === null || value.trim() === "") {
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
if (!allowedValues.includes(value)) {
|
|
192
|
-
throw new BadRequestError(`Invalid query parameter "${name}". Expected one of: ${allowedValues.join(", ")}.`);
|
|
193
|
-
}
|
|
194
|
-
return value;
|
|
195
|
-
}
|
|
196
|
-
function expectObject(value, label = "request body") {
|
|
197
|
-
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
198
|
-
throw new BadRequestError(`${label} must be a JSON object.`);
|
|
199
|
-
}
|
|
200
|
-
return value;
|
|
201
|
-
}
|
|
202
127
|
async function parseJsonBody(request, validator) {
|
|
203
128
|
let payload;
|
|
204
129
|
try {
|
|
@@ -208,62 +133,6 @@ async function parseJsonBody(request, validator) {
|
|
|
208
133
|
}
|
|
209
134
|
return validator(payload);
|
|
210
135
|
}
|
|
211
|
-
function readRequiredString(payload, field, options = {}) {
|
|
212
|
-
const value = payload[field];
|
|
213
|
-
if (typeof value !== "string" || value.trim() === "") {
|
|
214
|
-
throw new BadRequestError(`"${field}" is required and must be a string.`);
|
|
215
|
-
}
|
|
216
|
-
const trimmed = value.trim();
|
|
217
|
-
if (options.minLength !== undefined && trimmed.length < options.minLength) {
|
|
218
|
-
throw new BadRequestError(`"${field}" must be at least ${options.minLength} characters.`);
|
|
219
|
-
}
|
|
220
|
-
if (options.maxLength !== undefined && trimmed.length > options.maxLength) {
|
|
221
|
-
throw new BadRequestError(`"${field}" must be at most ${options.maxLength} characters.`);
|
|
222
|
-
}
|
|
223
|
-
if (options.pattern && !options.pattern.test(trimmed)) {
|
|
224
|
-
throw new BadRequestError(`"${field}" has an invalid format.`);
|
|
225
|
-
}
|
|
226
|
-
return trimmed;
|
|
227
|
-
}
|
|
228
|
-
function readOptionalString(payload, field, options = {}) {
|
|
229
|
-
if (!(field in payload) || payload[field] === undefined) {
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
return readRequiredString(payload, field, options);
|
|
233
|
-
}
|
|
234
|
-
function readRequiredEnum(payload, field, allowedValues) {
|
|
235
|
-
const value = readRequiredString(payload, field);
|
|
236
|
-
if (!allowedValues.includes(value)) {
|
|
237
|
-
throw new BadRequestError(`"${field}" must be one of: ${allowedValues.join(", ")}.`);
|
|
238
|
-
}
|
|
239
|
-
return value;
|
|
240
|
-
}
|
|
241
|
-
function readOptionalEnum(payload, field, allowedValues) {
|
|
242
|
-
if (!(field in payload) || payload[field] === undefined) {
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
return readRequiredEnum(payload, field, allowedValues);
|
|
246
|
-
}
|
|
247
|
-
function readRequiredPositiveInt(payload, field) {
|
|
248
|
-
const value = payload[field];
|
|
249
|
-
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
|
|
250
|
-
throw new BadRequestError(`"${field}" is required and must be a positive integer.`);
|
|
251
|
-
}
|
|
252
|
-
return value;
|
|
253
|
-
}
|
|
254
|
-
function readOptionalPositiveInt(payload, field) {
|
|
255
|
-
if (!(field in payload) || payload[field] === undefined) {
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
return readRequiredPositiveInt(payload, field);
|
|
259
|
-
}
|
|
260
|
-
function parsePositiveIntParam(value, name = "id") {
|
|
261
|
-
const parsed = Number.parseInt(value, 10);
|
|
262
|
-
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
263
|
-
throw new BadRequestError(`Invalid ${name}. Expected a positive integer.`);
|
|
264
|
-
}
|
|
265
|
-
return parsed;
|
|
266
|
-
}
|
|
267
136
|
|
|
268
137
|
// ../../src/core/http/webFormRequest.ts
|
|
269
138
|
class WebFormRequest {
|