alepha 0.14.4 → 0.15.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 +44 -102
- package/dist/api/audits/index.d.ts +331 -443
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js +2 -2
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.d.ts +0 -113
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +2 -3
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +151 -262
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/notifications/index.browser.js +4 -4
- package/dist/api/notifications/index.browser.js.map +1 -1
- package/dist/api/notifications/index.d.ts +164 -276
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/notifications/index.js +4 -4
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/parameters/index.d.ts +265 -377
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/users/index.browser.js +1 -2
- package/dist/api/users/index.browser.js.map +1 -1
- package/dist/api/users/index.d.ts +195 -301
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +203 -184
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/batch/index.d.ts.map +1 -1
- package/dist/batch/index.js +1 -2
- package/dist/batch/index.js.map +1 -1
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/cache/core/index.d.ts.map +1 -1
- package/dist/cache/redis/index.d.ts.map +1 -1
- package/dist/cache/redis/index.js +2 -2
- package/dist/cache/redis/index.js.map +1 -1
- package/dist/cli/index.d.ts +5900 -165
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +1481 -639
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +8 -4
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +29 -25
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +563 -54
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +175 -8
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +564 -54
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +563 -54
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/datetime/index.js +4 -4
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/index.d.ts +89 -42
- package/dist/email/index.d.ts.map +1 -1
- package/dist/email/index.js +129 -33
- package/dist/email/index.js.map +1 -1
- package/dist/fake/index.d.ts +7969 -2
- package/dist/fake/index.d.ts.map +1 -1
- package/dist/fake/index.js +22 -22
- package/dist/fake/index.js.map +1 -1
- package/dist/file/index.d.ts +134 -1
- package/dist/file/index.d.ts.map +1 -1
- package/dist/file/index.js +253 -1
- package/dist/file/index.js.map +1 -1
- package/dist/lock/core/index.d.ts.map +1 -1
- package/dist/lock/redis/index.d.ts.map +1 -1
- package/dist/logger/index.d.ts +1 -2
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +1 -5
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts +19 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +28 -4
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/chunk-DH6iiROE.js +38 -0
- package/dist/orm/index.browser.js +9 -9
- package/dist/orm/index.browser.js.map +1 -1
- package/dist/orm/index.bun.js +2821 -0
- package/dist/orm/index.bun.js.map +1 -0
- package/dist/orm/index.d.ts +318 -169
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +2086 -1776
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +4 -4
- package/dist/queue/core/index.d.ts.map +1 -1
- package/dist/queue/redis/index.d.ts.map +1 -1
- package/dist/redis/index.bun.js +285 -0
- package/dist/redis/index.bun.js.map +1 -0
- package/dist/redis/index.d.ts +13 -31
- package/dist/redis/index.d.ts.map +1 -1
- package/dist/redis/index.js +18 -38
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.d.ts.map +1 -1
- package/dist/router/index.d.ts.map +1 -1
- package/dist/scheduler/index.d.ts +83 -1
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +393 -1
- package/dist/scheduler/index.js.map +1 -1
- package/dist/security/index.browser.js +5 -1
- package/dist/security/index.browser.js.map +1 -1
- package/dist/security/index.d.ts +598 -112
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +1808 -97
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +1200 -175
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +1268 -37
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cache/index.d.ts +6 -3
- package/dist/server/cache/index.d.ts.map +1 -1
- package/dist/server/cache/index.js +1 -1
- package/dist/server/cache/index.js.map +1 -1
- package/dist/server/compress/index.d.ts.map +1 -1
- package/dist/server/cookies/index.d.ts.map +1 -1
- package/dist/server/cookies/index.js +3 -3
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.d.ts +115 -13
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +321 -139
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts +0 -1
- package/dist/server/cors/index.d.ts.map +1 -1
- package/dist/server/health/index.d.ts +0 -1
- package/dist/server/health/index.d.ts.map +1 -1
- package/dist/server/helmet/index.d.ts.map +1 -1
- package/dist/server/links/index.browser.js +9 -1
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.d.ts +1 -2
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +14 -7
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts +514 -1
- package/dist/server/metrics/index.d.ts.map +1 -1
- package/dist/server/metrics/index.js +4462 -4
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/multipart/index.d.ts.map +1 -1
- package/dist/server/proxy/index.d.ts +0 -1
- package/dist/server/proxy/index.d.ts.map +1 -1
- package/dist/server/rate-limit/index.d.ts.map +1 -1
- package/dist/server/static/index.d.ts.map +1 -1
- package/dist/server/swagger/index.d.ts +1 -2
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js +1 -2
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/sms/index.d.ts +3 -1
- package/dist/sms/index.d.ts.map +1 -1
- package/dist/sms/index.js +10 -10
- package/dist/sms/index.js.map +1 -1
- package/dist/thread/index.d.ts +0 -1
- package/dist/thread/index.d.ts.map +1 -1
- package/dist/thread/index.js +2 -2
- package/dist/thread/index.js.map +1 -1
- package/dist/topic/core/index.d.ts.map +1 -1
- package/dist/topic/redis/index.d.ts.map +1 -1
- package/dist/vite/index.d.ts +6315 -149
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +140 -469
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.browser.js +9 -9
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +28 -28
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +9 -9
- package/dist/websocket/index.js.map +1 -1
- package/package.json +13 -18
- package/src/api/files/controllers/AdminFileStatsController.ts +0 -1
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +5 -0
- package/src/api/users/controllers/{UserRealmController.ts → RealmController.ts} +11 -11
- package/src/api/users/entities/users.ts +1 -1
- package/src/api/users/index.ts +8 -8
- package/src/api/users/primitives/{$userRealm.ts → $realm.ts} +17 -19
- package/src/api/users/providers/{UserRealmProvider.ts → RealmProvider.ts} +26 -30
- package/src/api/users/schemas/{userRealmConfigSchema.ts → realmConfigSchema.ts} +2 -2
- package/src/api/users/services/CredentialService.ts +7 -7
- package/src/api/users/services/IdentityService.ts +4 -4
- package/src/api/users/services/RegistrationService.spec.ts +25 -27
- package/src/api/users/services/RegistrationService.ts +38 -27
- package/src/api/users/services/SessionCrudService.ts +3 -3
- package/src/api/users/services/SessionService.spec.ts +3 -3
- package/src/api/users/services/SessionService.ts +27 -18
- package/src/api/users/services/UserService.ts +7 -7
- package/src/batch/providers/BatchProvider.ts +1 -2
- package/src/cli/apps/AlephaCli.ts +2 -2
- package/src/cli/apps/AlephaPackageBuilderCli.ts +47 -20
- package/src/cli/assets/apiHelloControllerTs.ts +19 -0
- package/src/cli/assets/apiIndexTs.ts +16 -0
- package/src/cli/assets/biomeJson.ts +2 -1
- package/src/cli/assets/claudeMd.ts +308 -0
- package/src/cli/assets/dummySpecTs.ts +2 -1
- package/src/cli/assets/editorconfig.ts +2 -1
- package/src/cli/assets/mainBrowserTs.ts +4 -3
- package/src/cli/assets/mainCss.ts +24 -0
- package/src/cli/assets/mainServerTs.ts +24 -0
- package/src/cli/assets/tsconfigJson.ts +2 -1
- package/src/cli/assets/webAppRouterTs.ts +16 -0
- package/src/cli/assets/webHelloComponentTsx.ts +20 -0
- package/src/cli/assets/webIndexTs.ts +16 -0
- package/src/cli/atoms/appEntryOptions.ts +13 -0
- package/src/cli/atoms/buildOptions.ts +1 -1
- package/src/cli/atoms/changelogOptions.ts +1 -1
- package/src/cli/commands/build.ts +97 -61
- package/src/cli/commands/db.ts +21 -18
- package/src/cli/commands/deploy.ts +17 -5
- package/src/cli/commands/dev.ts +26 -47
- package/src/cli/commands/gen/env.ts +1 -1
- package/src/cli/commands/init.ts +79 -25
- package/src/cli/commands/lint.ts +9 -3
- package/src/cli/commands/test.ts +8 -2
- package/src/cli/commands/typecheck.ts +5 -1
- package/src/cli/commands/verify.ts +4 -2
- package/src/cli/defineConfig.ts +9 -0
- package/src/cli/index.ts +2 -1
- package/src/cli/providers/AppEntryProvider.ts +131 -0
- package/src/cli/providers/ViteBuildProvider.ts +82 -0
- package/src/cli/providers/ViteDevServerProvider.ts +350 -0
- package/src/cli/providers/ViteTemplateProvider.ts +27 -0
- package/src/cli/services/AlephaCliUtils.ts +72 -602
- package/src/cli/services/PackageManagerUtils.ts +308 -0
- package/src/cli/services/ProjectScaffolder.ts +329 -0
- package/src/command/helpers/Runner.ts +15 -3
- package/src/core/Alepha.ts +2 -8
- package/src/core/__tests__/Alepha-graph.spec.ts +4 -0
- package/src/core/index.shared.ts +1 -0
- package/src/core/index.ts +2 -0
- package/src/core/primitives/$hook.ts +6 -2
- package/src/core/primitives/$module.spec.ts +4 -0
- package/src/core/primitives/$module.ts +12 -0
- package/src/core/providers/AlsProvider.ts +1 -1
- package/src/core/providers/CodecManager.spec.ts +12 -6
- package/src/core/providers/CodecManager.ts +26 -6
- package/src/core/providers/EventManager.ts +169 -13
- package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +878 -0
- package/src/core/providers/KeylessJsonSchemaCodec.ts +789 -0
- package/src/core/providers/SchemaValidator.spec.ts +236 -0
- package/src/core/providers/StateManager.spec.ts +27 -16
- package/src/email/providers/LocalEmailProvider.spec.ts +111 -87
- package/src/email/providers/LocalEmailProvider.ts +52 -15
- package/src/email/providers/NodemailerEmailProvider.ts +167 -56
- package/src/file/errors/FileError.ts +7 -0
- package/src/file/index.ts +9 -1
- package/src/file/providers/MemoryFileSystemProvider.ts +393 -0
- package/src/logger/providers/PrettyFormatterProvider.ts +0 -9
- package/src/mcp/errors/McpError.ts +30 -0
- package/src/mcp/index.ts +3 -0
- package/src/mcp/transports/SseMcpTransport.ts +16 -6
- package/src/orm/index.browser.ts +1 -19
- package/src/orm/index.bun.ts +77 -0
- package/src/orm/index.shared-server.ts +22 -0
- package/src/orm/index.shared.ts +15 -0
- package/src/orm/index.ts +19 -39
- package/src/orm/providers/DrizzleKitProvider.ts +3 -5
- package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -5
- package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
- package/src/orm/providers/drivers/CloudflareD1Provider.ts +4 -0
- package/src/orm/providers/drivers/DatabaseProvider.ts +4 -0
- package/src/orm/providers/drivers/PglitePostgresProvider.ts +4 -0
- package/src/orm/services/Repository.ts +19 -0
- package/src/redis/index.bun.ts +35 -0
- package/src/redis/providers/BunRedisProvider.ts +12 -43
- package/src/redis/providers/BunRedisSubscriberProvider.ts +2 -3
- package/src/redis/providers/NodeRedisProvider.ts +16 -34
- package/src/{server/security → security}/__tests__/BasicAuth.spec.ts +11 -11
- package/src/{server/security → security}/__tests__/ServerSecurityProvider-realm.spec.ts +21 -16
- package/src/{server/security/providers → security/__tests__}/ServerSecurityProvider.spec.ts +5 -5
- package/src/security/index.browser.ts +5 -0
- package/src/security/index.ts +90 -7
- package/src/security/primitives/{$realm.spec.ts → $issuer.spec.ts} +11 -11
- package/src/security/primitives/{$realm.ts → $issuer.ts} +20 -17
- package/src/security/primitives/$role.ts +5 -5
- package/src/security/primitives/$serviceAccount.spec.ts +5 -5
- package/src/security/primitives/$serviceAccount.ts +3 -3
- package/src/{server/security → security}/providers/ServerSecurityProvider.ts +5 -7
- package/src/server/auth/primitives/$auth.ts +10 -10
- package/src/server/auth/primitives/$authCredentials.ts +3 -3
- package/src/server/auth/primitives/$authGithub.ts +3 -3
- package/src/server/auth/primitives/$authGoogle.ts +3 -3
- package/src/server/auth/providers/ServerAuthProvider.ts +13 -13
- package/src/server/cache/providers/ServerCacheProvider.ts +1 -1
- package/src/server/cookies/providers/ServerCookiesProvider.ts +3 -3
- package/src/server/core/index.ts +1 -1
- package/src/server/core/providers/BunHttpServerProvider.ts +1 -1
- package/src/server/core/providers/NodeHttpServerProvider.spec.ts +125 -0
- package/src/server/core/providers/NodeHttpServerProvider.ts +92 -24
- package/src/server/core/providers/ServerBodyParserProvider.ts +19 -23
- package/src/server/core/providers/ServerLoggerProvider.ts +23 -19
- package/src/server/core/providers/ServerProvider.ts +144 -24
- package/src/server/core/providers/ServerRouterProvider.ts +259 -115
- package/src/server/core/providers/ServerTimingProvider.ts +2 -2
- package/src/server/links/atoms/apiLinksAtom.ts +7 -0
- package/src/server/links/index.browser.ts +2 -0
- package/src/server/links/index.ts +3 -1
- package/src/server/links/providers/LinkProvider.ts +1 -1
- package/src/server/swagger/index.ts +1 -1
- package/src/sms/providers/LocalSmsProvider.spec.ts +153 -111
- package/src/sms/providers/LocalSmsProvider.ts +8 -7
- package/src/vite/index.ts +3 -2
- package/src/vite/tasks/buildClient.ts +0 -1
- package/src/vite/tasks/buildServer.ts +80 -22
- package/src/vite/tasks/copyAssets.ts +5 -4
- package/src/vite/tasks/generateCloudflare.ts +7 -0
- package/src/vite/tasks/generateSitemap.ts +64 -23
- package/src/vite/tasks/index.ts +0 -2
- package/src/vite/tasks/prerenderPages.ts +49 -24
- package/dist/server/security/index.browser.js +0 -13
- package/dist/server/security/index.browser.js.map +0 -1
- package/dist/server/security/index.d.ts +0 -173
- package/dist/server/security/index.d.ts.map +0 -1
- package/dist/server/security/index.js +0 -311
- package/dist/server/security/index.js.map +0 -1
- package/src/cli/assets/appRouterTs.ts +0 -9
- package/src/cli/assets/indexHtml.ts +0 -15
- package/src/cli/assets/mainTs.ts +0 -13
- package/src/cli/commands/format.ts +0 -17
- package/src/server/security/index.browser.ts +0 -10
- package/src/server/security/index.ts +0 -94
- package/src/vite/helpers/boot.ts +0 -106
- package/src/vite/plugins/viteAlephaDev.ts +0 -177
- package/src/vite/tasks/devServer.ts +0 -69
- package/src/vite/tasks/runAlepha.ts +0 -270
- /package/src/{server/security → security}/primitives/$basicAuth.ts +0 -0
- /package/src/{server/security → security}/providers/ServerBasicAuthProvider.ts +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Compile } from "typebox/compile";
|
|
2
1
|
import { Type } from "typebox";
|
|
3
2
|
import Format from "typebox/format";
|
|
4
3
|
import * as Value from "typebox/value";
|
|
4
|
+
import { Compile } from "typebox/compile";
|
|
5
5
|
|
|
6
6
|
//#region ../../src/core/constants/KIND.ts
|
|
7
7
|
/**
|
|
@@ -259,6 +259,7 @@ const $module = (options) => {
|
|
|
259
259
|
const $ = class extends Module {
|
|
260
260
|
options = options;
|
|
261
261
|
register(alepha) {
|
|
262
|
+
if (options.atoms) for (const atom of options.atoms) alepha.store.register(atom);
|
|
262
263
|
if (typeof options.register === "function") {
|
|
263
264
|
options.register(alepha);
|
|
264
265
|
return;
|
|
@@ -310,7 +311,7 @@ var AlsProvider = class AlsProvider {
|
|
|
310
311
|
if (!this.als) return callback();
|
|
311
312
|
data.registry ??= /* @__PURE__ */ new Map();
|
|
312
313
|
data.context ??= this.createContextId();
|
|
313
|
-
return this.als.run(data, callback);
|
|
314
|
+
return this.als.run({ ...data }, callback);
|
|
314
315
|
}
|
|
315
316
|
exists() {
|
|
316
317
|
return !!this.get("context");
|
|
@@ -395,27 +396,6 @@ var JsonSchemaCodec = class extends SchemaCodec {
|
|
|
395
396
|
}
|
|
396
397
|
};
|
|
397
398
|
|
|
398
|
-
//#endregion
|
|
399
|
-
//#region ../../src/core/errors/TypeBoxError.ts
|
|
400
|
-
var TypeBoxError = class extends AlephaError {
|
|
401
|
-
name = "TypeBoxError";
|
|
402
|
-
cause;
|
|
403
|
-
value;
|
|
404
|
-
constructor(error) {
|
|
405
|
-
super(`Invalid input: ${error.message}${error.instancePath ? ` at ${error.instancePath}` : ""}`, { cause: error });
|
|
406
|
-
const params = error.params;
|
|
407
|
-
if (params?.requiredProperties) this.value = {
|
|
408
|
-
path: `/${params.requiredProperties[0]}`,
|
|
409
|
-
message: "must be defined"
|
|
410
|
-
};
|
|
411
|
-
else this.value = {
|
|
412
|
-
path: error.instancePath,
|
|
413
|
-
message: error.message
|
|
414
|
-
};
|
|
415
|
-
this.cause = error;
|
|
416
|
-
}
|
|
417
|
-
};
|
|
418
|
-
|
|
419
399
|
//#endregion
|
|
420
400
|
//#region ../../src/core/primitives/$hook.ts
|
|
421
401
|
/**
|
|
@@ -461,12 +441,13 @@ const $hook = (options) => createPrimitive(HookPrimitive, options);
|
|
|
461
441
|
var HookPrimitive = class extends Primitive {
|
|
462
442
|
called = 0;
|
|
463
443
|
onInit() {
|
|
444
|
+
const handler = this.options.handler;
|
|
464
445
|
this.alepha.events.on(this.options.on, {
|
|
465
446
|
caller: this.config.service,
|
|
466
447
|
priority: this.options.priority,
|
|
467
|
-
callback:
|
|
448
|
+
callback: (args) => {
|
|
468
449
|
this.called += 1;
|
|
469
|
-
|
|
450
|
+
return handler(args);
|
|
470
451
|
}
|
|
471
452
|
});
|
|
472
453
|
}
|
|
@@ -907,6 +888,452 @@ var TypeProvider = class TypeProvider {
|
|
|
907
888
|
};
|
|
908
889
|
const t = new TypeProvider();
|
|
909
890
|
|
|
891
|
+
//#endregion
|
|
892
|
+
//#region ../../src/core/providers/KeylessJsonSchemaCodec.ts
|
|
893
|
+
const UNSAFE_KEYS = new Set([
|
|
894
|
+
"__proto__",
|
|
895
|
+
"constructor",
|
|
896
|
+
"prototype"
|
|
897
|
+
]);
|
|
898
|
+
/**
|
|
899
|
+
* KeylessJsonSchemaCodec provides schema-driven JSON encoding without keys.
|
|
900
|
+
*
|
|
901
|
+
* It uses the schema to determine field order, allowing the encoded output
|
|
902
|
+
* to be a simple JSON array instead of an object with keys.
|
|
903
|
+
*/
|
|
904
|
+
var KeylessJsonSchemaCodec = class extends SchemaCodec {
|
|
905
|
+
cache = /* @__PURE__ */ new Map();
|
|
906
|
+
textEncoder = new TextEncoder();
|
|
907
|
+
textDecoder = new TextDecoder();
|
|
908
|
+
varCounter = 0;
|
|
909
|
+
useFunctionCompilation = true;
|
|
910
|
+
maxArrayLength = 1e4;
|
|
911
|
+
maxStringLength = 1e6;
|
|
912
|
+
maxDepth = 50;
|
|
913
|
+
/**
|
|
914
|
+
* Configure codec options.
|
|
915
|
+
*/
|
|
916
|
+
configure(options) {
|
|
917
|
+
if (options.useFunctionCompilation !== void 0) {
|
|
918
|
+
this.useFunctionCompilation = options.useFunctionCompilation;
|
|
919
|
+
this.cache.clear();
|
|
920
|
+
}
|
|
921
|
+
if (options.maxArrayLength !== void 0) this.maxArrayLength = options.maxArrayLength;
|
|
922
|
+
if (options.maxStringLength !== void 0) this.maxStringLength = options.maxStringLength;
|
|
923
|
+
if (options.maxDepth !== void 0) this.maxDepth = options.maxDepth;
|
|
924
|
+
return this;
|
|
925
|
+
}
|
|
926
|
+
/**
|
|
927
|
+
* Hook to auto-detect safe mode on configure.
|
|
928
|
+
* Disables function compilation in browser by default.
|
|
929
|
+
*/
|
|
930
|
+
onConfigure = $hook({
|
|
931
|
+
on: "configure",
|
|
932
|
+
handler: () => {
|
|
933
|
+
this.useFunctionCompilation = this.canUseFunction();
|
|
934
|
+
}
|
|
935
|
+
});
|
|
936
|
+
/**
|
|
937
|
+
* Encode value to a keyless JSON string.
|
|
938
|
+
*/
|
|
939
|
+
encodeToString(schema, value) {
|
|
940
|
+
return this.getCodec(schema).encode(value);
|
|
941
|
+
}
|
|
942
|
+
/**
|
|
943
|
+
* Encode value to binary (UTF-8 encoded keyless JSON).
|
|
944
|
+
*/
|
|
945
|
+
encodeToBinary(schema, value) {
|
|
946
|
+
return this.textEncoder.encode(this.encodeToString(schema, value));
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* Decode keyless JSON string or binary to value.
|
|
950
|
+
*/
|
|
951
|
+
decode(schema, value) {
|
|
952
|
+
if (value instanceof Uint8Array) {
|
|
953
|
+
const text = this.textDecoder.decode(value);
|
|
954
|
+
return this.getCodec(schema).decode(text);
|
|
955
|
+
}
|
|
956
|
+
if (typeof value === "string") return this.getCodec(schema).decode(value);
|
|
957
|
+
if (Array.isArray(value)) return this.reconstructObject(schema, value);
|
|
958
|
+
return value;
|
|
959
|
+
}
|
|
960
|
+
/**
|
|
961
|
+
* Test if `new Function()` is available (not blocked by CSP).
|
|
962
|
+
*/
|
|
963
|
+
canUseFunction() {
|
|
964
|
+
try {
|
|
965
|
+
return new Function("return true")() === true;
|
|
966
|
+
} catch {
|
|
967
|
+
return false;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
/**
|
|
971
|
+
* Validate schema keys for prototype pollution.
|
|
972
|
+
* Uses a visited set to avoid infinite recursion on recursive schemas.
|
|
973
|
+
*/
|
|
974
|
+
validateSchemaKeys(schema, depth = 0, visited = /* @__PURE__ */ new Set()) {
|
|
975
|
+
if (visited.has(schema)) return;
|
|
976
|
+
visited.add(schema);
|
|
977
|
+
if (depth > this.maxDepth) throw new AlephaError(`Schema depth exceeds maximum allowed (${this.maxDepth})`);
|
|
978
|
+
if (t.schema.isObject(schema)) {
|
|
979
|
+
const props = schema.properties;
|
|
980
|
+
for (const key of Object.keys(props)) {
|
|
981
|
+
if (UNSAFE_KEYS.has(key)) throw new AlephaError(`Unsafe schema key "${key}" detected. This key is blocked to prevent prototype pollution.`);
|
|
982
|
+
this.validateSchemaKeys(props[key], depth + 1, visited);
|
|
983
|
+
}
|
|
984
|
+
} else if (t.schema.isArray(schema)) {
|
|
985
|
+
const arrSchema = schema;
|
|
986
|
+
this.validateSchemaKeys(arrSchema.items, depth + 1, visited);
|
|
987
|
+
} else if (t.schema.isUnion(schema) || t.schema.isOptional(schema)) this.validateSchemaKeys(this.unwrap(schema), depth, visited);
|
|
988
|
+
}
|
|
989
|
+
/**
|
|
990
|
+
* Validate array length.
|
|
991
|
+
*/
|
|
992
|
+
validateArrayLength(arr) {
|
|
993
|
+
if (arr.length > this.maxArrayLength) throw new AlephaError(`Array length (${arr.length}) exceeds maximum allowed (${this.maxArrayLength})`);
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* Validate string length.
|
|
997
|
+
*/
|
|
998
|
+
validateStringLength(str) {
|
|
999
|
+
if (str.length > this.maxStringLength) throw new AlephaError(`String length (${str.length}) exceeds maximum allowed (${this.maxStringLength})`);
|
|
1000
|
+
}
|
|
1001
|
+
/**
|
|
1002
|
+
* Get a compiled codec for the given schema.
|
|
1003
|
+
* Codecs are cached for reuse.
|
|
1004
|
+
*/
|
|
1005
|
+
getCodec(schema) {
|
|
1006
|
+
let c = this.cache.get(schema);
|
|
1007
|
+
if (!c) {
|
|
1008
|
+
c = this.useFunctionCompilation ? this.compileWithFunction(schema) : this.compileInterpreted(schema);
|
|
1009
|
+
this.cache.set(schema, c);
|
|
1010
|
+
}
|
|
1011
|
+
return c;
|
|
1012
|
+
}
|
|
1013
|
+
nextVar() {
|
|
1014
|
+
return `_${this.varCounter++}`;
|
|
1015
|
+
}
|
|
1016
|
+
/**
|
|
1017
|
+
* Compile codec using `new Function()` for maximum performance.
|
|
1018
|
+
* Only used when CSP allows and useFunctionCompilation is true.
|
|
1019
|
+
*/
|
|
1020
|
+
compileWithFunction(schema) {
|
|
1021
|
+
this.varCounter = 0;
|
|
1022
|
+
const encBody = this.genEnc(schema, "v");
|
|
1023
|
+
this.varCounter = 0;
|
|
1024
|
+
const decBody = this.genDec(schema);
|
|
1025
|
+
return {
|
|
1026
|
+
encode: new Function("v", `return JSON.stringify(${encBody});`),
|
|
1027
|
+
decode: new Function("s", `const a=JSON.parse(s);let i=0;${decBody.code}return ${decBody.result};`)
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
/**
|
|
1031
|
+
* Compile codec using interpreter-based approach.
|
|
1032
|
+
* Safer (no eval/Function) but slower. Used in browser by default.
|
|
1033
|
+
*/
|
|
1034
|
+
compileInterpreted(schema) {
|
|
1035
|
+
const self = this;
|
|
1036
|
+
return {
|
|
1037
|
+
encode(value) {
|
|
1038
|
+
return JSON.stringify(self.interpretEncode(schema, value));
|
|
1039
|
+
},
|
|
1040
|
+
decode(str) {
|
|
1041
|
+
const ctx = {
|
|
1042
|
+
arr: JSON.parse(str),
|
|
1043
|
+
i: 0
|
|
1044
|
+
};
|
|
1045
|
+
return self.interpretDecode(schema, ctx);
|
|
1046
|
+
}
|
|
1047
|
+
};
|
|
1048
|
+
}
|
|
1049
|
+
interpretEncode(schema, value) {
|
|
1050
|
+
if (t.schema.isString(schema) || t.schema.isNumber(schema) || t.schema.isInteger(schema) || t.schema.isBoolean(schema) || this.isEnum(schema)) return value;
|
|
1051
|
+
if (t.schema.isBigInt(schema)) return `${value}n`;
|
|
1052
|
+
if (t.schema.isArray(schema)) {
|
|
1053
|
+
const arrSchema = schema;
|
|
1054
|
+
if (!Array.isArray(value)) return value;
|
|
1055
|
+
if (t.schema.isString(arrSchema.items) || t.schema.isNumber(arrSchema.items) || t.schema.isInteger(arrSchema.items) || t.schema.isBoolean(arrSchema.items)) return value;
|
|
1056
|
+
return value.map((e) => this.interpretEncode(arrSchema.items, e));
|
|
1057
|
+
}
|
|
1058
|
+
if (t.schema.isObject(schema)) {
|
|
1059
|
+
const objSchema = schema;
|
|
1060
|
+
const props = objSchema.properties;
|
|
1061
|
+
const keys = Object.keys(props);
|
|
1062
|
+
const req = new Set(objSchema.required || []);
|
|
1063
|
+
const result = [];
|
|
1064
|
+
for (const k of keys) {
|
|
1065
|
+
const ps = props[k];
|
|
1066
|
+
const isOpt = !req.has(k) || t.schema.isOptional(ps);
|
|
1067
|
+
const isNullable = this.isNullable(ps);
|
|
1068
|
+
const inner = this.unwrap(ps);
|
|
1069
|
+
const v = value[k];
|
|
1070
|
+
if (isOpt) result.push(v !== void 0 ? this.interpretEncode(inner, v) : null);
|
|
1071
|
+
else if (isNullable) result.push(v !== null ? this.interpretEncode(inner, v) : null);
|
|
1072
|
+
else result.push(this.interpretEncode(inner, v));
|
|
1073
|
+
}
|
|
1074
|
+
return result;
|
|
1075
|
+
}
|
|
1076
|
+
if (t.schema.isOptional(schema) || t.schema.isUnion(schema)) {
|
|
1077
|
+
const inner = this.unwrap(schema);
|
|
1078
|
+
if (this.isNullable(schema)) return value !== null ? this.interpretEncode(inner, value) : null;
|
|
1079
|
+
return value !== void 0 ? this.interpretEncode(inner, value) : null;
|
|
1080
|
+
}
|
|
1081
|
+
return value;
|
|
1082
|
+
}
|
|
1083
|
+
interpretDecode(schema, ctx) {
|
|
1084
|
+
if (t.schema.isString(schema) || t.schema.isNumber(schema) || t.schema.isInteger(schema) || t.schema.isBoolean(schema) || this.isEnum(schema)) return ctx.arr[ctx.i++];
|
|
1085
|
+
if (t.schema.isBigInt(schema)) return BigInt(ctx.arr[ctx.i++].slice(0, -1));
|
|
1086
|
+
if (t.schema.isArray(schema)) {
|
|
1087
|
+
const arrSchema = schema;
|
|
1088
|
+
const arr = ctx.arr[ctx.i++];
|
|
1089
|
+
if (!Array.isArray(arr)) return arr;
|
|
1090
|
+
if (t.schema.isObject(arrSchema.items)) return arr.map((e) => this.interpretDecodeFromValue(arrSchema.items, e));
|
|
1091
|
+
return arr;
|
|
1092
|
+
}
|
|
1093
|
+
if (t.schema.isObject(schema)) {
|
|
1094
|
+
const objSchema = schema;
|
|
1095
|
+
const props = objSchema.properties;
|
|
1096
|
+
const keys = Object.keys(props);
|
|
1097
|
+
const req = new Set(objSchema.required || []);
|
|
1098
|
+
const result = {};
|
|
1099
|
+
for (const k of keys) {
|
|
1100
|
+
const ps = props[k];
|
|
1101
|
+
const isOpt = !req.has(k) || t.schema.isOptional(ps);
|
|
1102
|
+
const isNullable = this.isNullable(ps);
|
|
1103
|
+
const inner = this.unwrap(ps);
|
|
1104
|
+
const val = ctx.arr[ctx.i++];
|
|
1105
|
+
if (isOpt) {
|
|
1106
|
+
if (val !== null) result[k] = this.interpretDecodeFromValue(inner, val);
|
|
1107
|
+
} else if (isNullable) result[k] = val === null ? null : this.interpretDecodeFromValue(inner, val);
|
|
1108
|
+
else result[k] = this.interpretDecodeFromValue(inner, val);
|
|
1109
|
+
}
|
|
1110
|
+
return result;
|
|
1111
|
+
}
|
|
1112
|
+
if (t.schema.isOptional(schema) || t.schema.isUnion(schema)) {
|
|
1113
|
+
const inner = this.unwrap(schema);
|
|
1114
|
+
const val = ctx.arr[ctx.i++];
|
|
1115
|
+
if (val === null) return this.isNullable(schema) ? null : void 0;
|
|
1116
|
+
if (t.schema.isObject(inner) || t.schema.isArray(inner)) return this.interpretDecodeFromValue(inner, val);
|
|
1117
|
+
return val;
|
|
1118
|
+
}
|
|
1119
|
+
return ctx.arr[ctx.i++];
|
|
1120
|
+
}
|
|
1121
|
+
interpretDecodeFromValue(schema, value) {
|
|
1122
|
+
if (t.schema.isString(schema) || t.schema.isNumber(schema) || t.schema.isInteger(schema) || t.schema.isBoolean(schema) || this.isEnum(schema)) return value;
|
|
1123
|
+
if (t.schema.isBigInt(schema)) return BigInt(value.slice(0, -1));
|
|
1124
|
+
if (t.schema.isArray(schema)) {
|
|
1125
|
+
if (!Array.isArray(value)) return value;
|
|
1126
|
+
const arrSchema = schema;
|
|
1127
|
+
if (t.schema.isObject(arrSchema.items)) return value.map((e) => this.interpretDecodeFromValue(arrSchema.items, e));
|
|
1128
|
+
return value;
|
|
1129
|
+
}
|
|
1130
|
+
if (t.schema.isObject(schema)) {
|
|
1131
|
+
const props = schema.properties;
|
|
1132
|
+
const keys = Object.keys(props);
|
|
1133
|
+
const result = {};
|
|
1134
|
+
for (let idx = 0; idx < keys.length; idx++) {
|
|
1135
|
+
const k = keys[idx];
|
|
1136
|
+
const inner = this.unwrap(props[k]);
|
|
1137
|
+
const v = value[idx];
|
|
1138
|
+
if (t.schema.isObject(inner)) result[k] = this.interpretDecodeFromValue(inner, v);
|
|
1139
|
+
else if (t.schema.isBigInt(inner)) result[k] = BigInt(v.slice(0, -1));
|
|
1140
|
+
else result[k] = v;
|
|
1141
|
+
}
|
|
1142
|
+
return result;
|
|
1143
|
+
}
|
|
1144
|
+
return value;
|
|
1145
|
+
}
|
|
1146
|
+
genEnc(schema, ve) {
|
|
1147
|
+
if (t.schema.isString(schema) || t.schema.isNumber(schema) || t.schema.isInteger(schema) || t.schema.isBoolean(schema) || this.isEnum(schema)) return ve;
|
|
1148
|
+
if (t.schema.isBigInt(schema)) return `${ve}+'n'`;
|
|
1149
|
+
if (t.schema.isArray(schema)) {
|
|
1150
|
+
const arrSchema = schema;
|
|
1151
|
+
const itemEnc = this.genEnc(arrSchema.items, "e");
|
|
1152
|
+
if (t.schema.isString(arrSchema.items) || t.schema.isNumber(arrSchema.items) || t.schema.isInteger(arrSchema.items) || t.schema.isBoolean(arrSchema.items)) return ve;
|
|
1153
|
+
return `${ve}.map(e=>${itemEnc})`;
|
|
1154
|
+
}
|
|
1155
|
+
if (t.schema.isObject(schema)) {
|
|
1156
|
+
const objSchema = schema;
|
|
1157
|
+
const props = objSchema.properties;
|
|
1158
|
+
const keys = Object.keys(props);
|
|
1159
|
+
const req = new Set(objSchema.required || []);
|
|
1160
|
+
const parts = [];
|
|
1161
|
+
for (const k of keys) {
|
|
1162
|
+
const ps = props[k];
|
|
1163
|
+
const isOpt = !req.has(k) || t.schema.isOptional(ps);
|
|
1164
|
+
const isNullable = this.isNullable(ps);
|
|
1165
|
+
const inner = this.unwrap(ps);
|
|
1166
|
+
const innerEnc = this.genEnc(inner, `${ve}.${k}`);
|
|
1167
|
+
if (isOpt) parts.push(`${ve}.${k}!==undefined?${innerEnc}:null`);
|
|
1168
|
+
else if (isNullable) parts.push(`${ve}.${k}!==null?${innerEnc}:null`);
|
|
1169
|
+
else parts.push(innerEnc);
|
|
1170
|
+
}
|
|
1171
|
+
return `[${parts.join(",")}]`;
|
|
1172
|
+
}
|
|
1173
|
+
if (t.schema.isOptional(schema) || t.schema.isUnion(schema)) {
|
|
1174
|
+
const inner = this.unwrap(schema);
|
|
1175
|
+
const innerEnc = this.genEnc(inner, ve);
|
|
1176
|
+
if (this.isNullable(schema)) return `${ve}!==null?${innerEnc}:null`;
|
|
1177
|
+
return `${ve}!==undefined?${innerEnc}:null`;
|
|
1178
|
+
}
|
|
1179
|
+
return ve;
|
|
1180
|
+
}
|
|
1181
|
+
genDec(schema) {
|
|
1182
|
+
const v = this.nextVar();
|
|
1183
|
+
if (t.schema.isString(schema) || t.schema.isNumber(schema) || t.schema.isInteger(schema) || t.schema.isBoolean(schema) || this.isEnum(schema)) return {
|
|
1184
|
+
code: "",
|
|
1185
|
+
result: "a[i++]"
|
|
1186
|
+
};
|
|
1187
|
+
if (t.schema.isBigInt(schema)) return {
|
|
1188
|
+
code: "",
|
|
1189
|
+
result: "BigInt(a[i++].slice(0,-1))"
|
|
1190
|
+
};
|
|
1191
|
+
if (t.schema.isArray(schema)) {
|
|
1192
|
+
const arrSchema = schema;
|
|
1193
|
+
if (t.schema.isObject(arrSchema.items)) return {
|
|
1194
|
+
code: "",
|
|
1195
|
+
result: `a[i++].map(e=>${this.genDecFromValue(arrSchema.items, "e")})`
|
|
1196
|
+
};
|
|
1197
|
+
return {
|
|
1198
|
+
code: "",
|
|
1199
|
+
result: "a[i++]"
|
|
1200
|
+
};
|
|
1201
|
+
}
|
|
1202
|
+
if (t.schema.isObject(schema)) {
|
|
1203
|
+
const objSchema = schema;
|
|
1204
|
+
const props = objSchema.properties;
|
|
1205
|
+
const keys = Object.keys(props);
|
|
1206
|
+
const req = new Set(objSchema.required || []);
|
|
1207
|
+
let simple = true;
|
|
1208
|
+
for (const k of keys) {
|
|
1209
|
+
const ps = props[k];
|
|
1210
|
+
const isOpt = !req.has(k) || t.schema.isOptional(ps);
|
|
1211
|
+
const isNullable = this.isNullable(ps);
|
|
1212
|
+
const inner = this.unwrap(ps);
|
|
1213
|
+
if (isOpt || isNullable || t.schema.isObject(inner) || t.schema.isArray(inner)) {
|
|
1214
|
+
simple = false;
|
|
1215
|
+
break;
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
if (simple) return {
|
|
1219
|
+
code: "",
|
|
1220
|
+
result: `{${keys.map((k) => `${k}:a[i++]`).join(",")}}`
|
|
1221
|
+
};
|
|
1222
|
+
let code = `const ${v}={};`;
|
|
1223
|
+
for (const k of keys) {
|
|
1224
|
+
const ps = props[k];
|
|
1225
|
+
const isOpt = !req.has(k) || t.schema.isOptional(ps);
|
|
1226
|
+
const isNullable = this.isNullable(ps);
|
|
1227
|
+
const inner = this.unwrap(ps);
|
|
1228
|
+
if (isOpt) {
|
|
1229
|
+
const nested = this.genDecFromValue(inner, "t");
|
|
1230
|
+
code += `{const t=a[i++];if(t!==null){${v}.${k}=${nested};}}`;
|
|
1231
|
+
} else if (isNullable) {
|
|
1232
|
+
const nested = this.genDecFromValue(inner, "t");
|
|
1233
|
+
code += `{const t=a[i++];if(t===null){${v}.${k}=null;}else{${v}.${k}=${nested};}}`;
|
|
1234
|
+
} else if (t.schema.isObject(inner)) {
|
|
1235
|
+
const nested = this.genDecFromValue(inner, "a[i++]");
|
|
1236
|
+
code += `${v}.${k}=${nested};`;
|
|
1237
|
+
} else if (t.schema.isArray(inner)) {
|
|
1238
|
+
const arrSchema = inner;
|
|
1239
|
+
if (t.schema.isObject(arrSchema.items)) {
|
|
1240
|
+
const itemTransform = this.genDecFromValue(arrSchema.items, "e");
|
|
1241
|
+
code += `${v}.${k}=a[i++].map(e=>${itemTransform});`;
|
|
1242
|
+
} else code += `${v}.${k}=a[i++];`;
|
|
1243
|
+
} else code += `${v}.${k}=a[i++];`;
|
|
1244
|
+
}
|
|
1245
|
+
return {
|
|
1246
|
+
code,
|
|
1247
|
+
result: v
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
if (t.schema.isOptional(schema) || t.schema.isUnion(schema)) {
|
|
1251
|
+
const inner = this.unwrap(schema);
|
|
1252
|
+
const innerDec = this.genDec(inner);
|
|
1253
|
+
return {
|
|
1254
|
+
code: `const ${v}t=a[i++];let ${v};if(${v}t===null){${v}=${this.isNullable(schema) ? "null" : "undefined"};}else{${innerDec.code.replace(/a\[i\+\+\]/g, `${v}t`)}${v}=${innerDec.result.replace(/a\[i\+\+\]/g, `${v}t`)};}`,
|
|
1255
|
+
result: v
|
|
1256
|
+
};
|
|
1257
|
+
}
|
|
1258
|
+
return {
|
|
1259
|
+
code: "",
|
|
1260
|
+
result: "a[i++]"
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
genDecFromValue(schema, expr) {
|
|
1264
|
+
if (t.schema.isString(schema) || t.schema.isNumber(schema) || t.schema.isInteger(schema) || t.schema.isBoolean(schema) || this.isEnum(schema)) return expr;
|
|
1265
|
+
if (t.schema.isBigInt(schema)) return `BigInt(${expr}.slice(0,-1))`;
|
|
1266
|
+
if (t.schema.isArray(schema)) return expr;
|
|
1267
|
+
if (t.schema.isObject(schema)) {
|
|
1268
|
+
const props = schema.properties;
|
|
1269
|
+
const keys = Object.keys(props);
|
|
1270
|
+
const v = this.nextVar();
|
|
1271
|
+
return `((${v}=${expr})=>({${keys.map((k, idx) => {
|
|
1272
|
+
const inner = this.unwrap(props[k]);
|
|
1273
|
+
const innerExpr = `${v}[${idx}]`;
|
|
1274
|
+
if (t.schema.isObject(inner)) return `${k}:${this.genDecFromValue(inner, innerExpr)}`;
|
|
1275
|
+
if (t.schema.isBigInt(inner)) return `${k}:BigInt(${innerExpr}.slice(0,-1))`;
|
|
1276
|
+
return `${k}:${innerExpr}`;
|
|
1277
|
+
}).join(",")}}))()`;
|
|
1278
|
+
}
|
|
1279
|
+
return expr;
|
|
1280
|
+
}
|
|
1281
|
+
isEnum(schema) {
|
|
1282
|
+
return "enum" in schema && Array.isArray(schema.enum) && (schema.enum?.length ?? 0) > 0;
|
|
1283
|
+
}
|
|
1284
|
+
isNullable(schema) {
|
|
1285
|
+
if (!t.schema.isUnion(schema)) return false;
|
|
1286
|
+
return schema.anyOf?.some((s) => t.schema.isNull(s)) ?? false;
|
|
1287
|
+
}
|
|
1288
|
+
unwrap(schema) {
|
|
1289
|
+
if ("anyOf" in schema && Array.isArray(schema.anyOf)) return schema.anyOf.find((s) => !t.schema.isNull(s)) || schema;
|
|
1290
|
+
return schema;
|
|
1291
|
+
}
|
|
1292
|
+
/**
|
|
1293
|
+
* Reconstruct an object from a parsed array (for when input is already parsed).
|
|
1294
|
+
*/
|
|
1295
|
+
reconstructObject(schema, arr) {
|
|
1296
|
+
if (!t.schema.isObject(schema)) return arr;
|
|
1297
|
+
const props = schema.properties;
|
|
1298
|
+
const keys = Object.keys(props);
|
|
1299
|
+
const result = {};
|
|
1300
|
+
let i = 0;
|
|
1301
|
+
for (const k of keys) {
|
|
1302
|
+
const ps = props[k];
|
|
1303
|
+
const isOpt = t.schema.isOptional(ps);
|
|
1304
|
+
const isNullable = this.isNullable(ps);
|
|
1305
|
+
const inner = this.unwrap(ps);
|
|
1306
|
+
const val = arr[i++];
|
|
1307
|
+
if (isOpt) {
|
|
1308
|
+
if (val !== null) result[k] = t.schema.isObject(inner) ? this.reconstructObject(inner, val) : val;
|
|
1309
|
+
} else if (isNullable) result[k] = val === null ? null : t.schema.isObject(inner) ? this.reconstructObject(inner, val) : val;
|
|
1310
|
+
else result[k] = t.schema.isObject(inner) ? this.reconstructObject(inner, val) : val;
|
|
1311
|
+
}
|
|
1312
|
+
return result;
|
|
1313
|
+
}
|
|
1314
|
+
};
|
|
1315
|
+
|
|
1316
|
+
//#endregion
|
|
1317
|
+
//#region ../../src/core/errors/TypeBoxError.ts
|
|
1318
|
+
var TypeBoxError = class extends AlephaError {
|
|
1319
|
+
name = "TypeBoxError";
|
|
1320
|
+
cause;
|
|
1321
|
+
value;
|
|
1322
|
+
constructor(error) {
|
|
1323
|
+
super(`Invalid input: ${error.message}${error.instancePath ? ` at ${error.instancePath}` : ""}`, { cause: error });
|
|
1324
|
+
const params = error.params;
|
|
1325
|
+
if (params?.requiredProperties) this.value = {
|
|
1326
|
+
path: `/${params.requiredProperties[0]}`,
|
|
1327
|
+
message: "must be defined"
|
|
1328
|
+
};
|
|
1329
|
+
else this.value = {
|
|
1330
|
+
path: error.instancePath,
|
|
1331
|
+
message: error.message
|
|
1332
|
+
};
|
|
1333
|
+
this.cause = error;
|
|
1334
|
+
}
|
|
1335
|
+
};
|
|
1336
|
+
|
|
910
1337
|
//#endregion
|
|
911
1338
|
//#region ../../src/core/providers/SchemaValidator.ts
|
|
912
1339
|
var SchemaValidator = class {
|
|
@@ -1001,19 +1428,26 @@ var SchemaValidator = class {
|
|
|
1001
1428
|
var CodecManager = class {
|
|
1002
1429
|
codecs = /* @__PURE__ */ new Map();
|
|
1003
1430
|
jsonCodec = $inject(JsonSchemaCodec);
|
|
1431
|
+
keylessCodec = $inject(KeylessJsonSchemaCodec);
|
|
1004
1432
|
schemaValidator = $inject(SchemaValidator);
|
|
1005
1433
|
default = "json";
|
|
1006
1434
|
constructor() {
|
|
1007
|
-
this.register(
|
|
1435
|
+
this.register({
|
|
1436
|
+
name: "json",
|
|
1437
|
+
codec: this.jsonCodec,
|
|
1438
|
+
default: true
|
|
1439
|
+
});
|
|
1440
|
+
this.register({
|
|
1441
|
+
name: "keyless",
|
|
1442
|
+
codec: this.keylessCodec
|
|
1443
|
+
});
|
|
1008
1444
|
}
|
|
1009
1445
|
/**
|
|
1010
1446
|
* Register a new codec format.
|
|
1011
|
-
*
|
|
1012
|
-
* @param name - The name of the codec (e.g., 'json', 'protobuf')
|
|
1013
|
-
* @param codec - The codec implementation
|
|
1014
1447
|
*/
|
|
1015
|
-
register(
|
|
1016
|
-
this.codecs.set(name, codec);
|
|
1448
|
+
register(opts) {
|
|
1449
|
+
this.codecs.set(opts.name, opts.codec);
|
|
1450
|
+
if (opts.default) this.default = opts.name;
|
|
1017
1451
|
}
|
|
1018
1452
|
/**
|
|
1019
1453
|
* Get a specific codec by name.
|
|
@@ -1092,35 +1526,110 @@ var EventManager = class {
|
|
|
1092
1526
|
};
|
|
1093
1527
|
}
|
|
1094
1528
|
/**
|
|
1529
|
+
* Compiles an event into an optimized executor function.
|
|
1530
|
+
*
|
|
1531
|
+
* Call this after all hooks are registered (e.g., after Alepha.start()).
|
|
1532
|
+
* The returned function checks each hook's return value and awaits promises.
|
|
1533
|
+
* Returns undefined if all hooks are sync, or a Promise if any hook returns one.
|
|
1534
|
+
*
|
|
1535
|
+
* @example
|
|
1536
|
+
* ```ts
|
|
1537
|
+
* // At startup (after hooks are registered)
|
|
1538
|
+
* const onRequest = alepha.events.compile("server:onRequest", { catch: true });
|
|
1539
|
+
*
|
|
1540
|
+
* // In hot path - only await if promise returned
|
|
1541
|
+
* const result = onRequest({ request, route });
|
|
1542
|
+
* if (result) await result;
|
|
1543
|
+
* ```
|
|
1544
|
+
*/
|
|
1545
|
+
compile(event, options = {}) {
|
|
1546
|
+
const hooks = this.events[event];
|
|
1547
|
+
if (!hooks || hooks.length === 0) return () => {};
|
|
1548
|
+
const catchErrors = options.catch ?? false;
|
|
1549
|
+
const log = this.log;
|
|
1550
|
+
const runRemainingAsync = async (startIndex, payload) => {
|
|
1551
|
+
for (let i = startIndex; i < hooks.length; i++) {
|
|
1552
|
+
const hook = hooks[i];
|
|
1553
|
+
try {
|
|
1554
|
+
const result = hook.callback(payload);
|
|
1555
|
+
if (result && typeof result === "object" && "then" in result) if (catchErrors) await result.catch((error) => {
|
|
1556
|
+
log?.error(`${String(event)}(${hook.caller?.name ?? "unknown"}) ERROR`, error);
|
|
1557
|
+
});
|
|
1558
|
+
else await result;
|
|
1559
|
+
} catch (error) {
|
|
1560
|
+
if (catchErrors) log?.error(`${String(event)}(${hook.caller?.name ?? "unknown"}) ERROR`, error);
|
|
1561
|
+
else throw error;
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
};
|
|
1565
|
+
return (payload) => {
|
|
1566
|
+
for (let i = 0; i < hooks.length; i++) {
|
|
1567
|
+
const hook = hooks[i];
|
|
1568
|
+
try {
|
|
1569
|
+
const result = hook.callback(payload);
|
|
1570
|
+
if (result && typeof result === "object" && "then" in result) {
|
|
1571
|
+
if (catchErrors) return result.catch((error) => {
|
|
1572
|
+
log?.error(`${String(event)}(${hook.caller?.name ?? "unknown"}) ERROR`, error);
|
|
1573
|
+
}).then(() => runRemainingAsync(i + 1, payload));
|
|
1574
|
+
return result.then(() => runRemainingAsync(i + 1, payload));
|
|
1575
|
+
}
|
|
1576
|
+
} catch (error) {
|
|
1577
|
+
if (catchErrors) log?.error(`${String(event)}(${hook.caller?.name ?? "unknown"}) ERROR`, error);
|
|
1578
|
+
else throw error;
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
};
|
|
1582
|
+
}
|
|
1583
|
+
/**
|
|
1095
1584
|
* Emits the specified event with the given payload.
|
|
1585
|
+
*
|
|
1586
|
+
* For hot paths (like HTTP request handling), use compile() instead
|
|
1587
|
+
* to get an optimized executor.
|
|
1096
1588
|
*/
|
|
1097
1589
|
async emit(func, payload, options = {}) {
|
|
1590
|
+
const events = this.events[func];
|
|
1591
|
+
if (!events || events.length === 0) return;
|
|
1592
|
+
if (events.length === 1 && !options.log && !options.reverse) {
|
|
1593
|
+
const hook = events[0];
|
|
1594
|
+
try {
|
|
1595
|
+
const result = hook.callback(payload);
|
|
1596
|
+
if (result && typeof result === "object" && "then" in result) await result;
|
|
1597
|
+
} catch (error) {
|
|
1598
|
+
if (options.catch) {
|
|
1599
|
+
this.log?.error(`${String(func)}(${hook.caller?.name ?? "unknown"}) ERROR`, error);
|
|
1600
|
+
return;
|
|
1601
|
+
}
|
|
1602
|
+
throw error;
|
|
1603
|
+
}
|
|
1604
|
+
return;
|
|
1605
|
+
}
|
|
1098
1606
|
const ctx = {};
|
|
1099
1607
|
if (options.log) {
|
|
1100
|
-
ctx.now =
|
|
1101
|
-
this.log?.trace(`${func} ...`);
|
|
1608
|
+
ctx.now = performance.now();
|
|
1609
|
+
this.log?.trace(`${String(func)} ...`);
|
|
1102
1610
|
}
|
|
1103
|
-
let
|
|
1104
|
-
if (options.reverse)
|
|
1105
|
-
for (const hook of
|
|
1611
|
+
let eventList = events;
|
|
1612
|
+
if (options.reverse) eventList = events.toReversed();
|
|
1613
|
+
for (const hook of eventList) {
|
|
1106
1614
|
const name = hook.caller?.name ?? "unknown";
|
|
1107
1615
|
if (options.log) {
|
|
1108
|
-
ctx.now2 =
|
|
1109
|
-
this.log?.trace(`${func}(${name}) ...`);
|
|
1616
|
+
ctx.now2 = performance.now();
|
|
1617
|
+
this.log?.trace(`${String(func)}(${name}) ...`);
|
|
1110
1618
|
}
|
|
1111
1619
|
try {
|
|
1112
|
-
|
|
1620
|
+
const result = hook.callback(payload);
|
|
1621
|
+
if (result && typeof result === "object" && "then" in result) await result;
|
|
1113
1622
|
} catch (error) {
|
|
1114
1623
|
if (options.catch) {
|
|
1115
|
-
this.log?.error(`${func}(${name}) ERROR`, error);
|
|
1624
|
+
this.log?.error(`${String(func)}(${name}) ERROR`, error);
|
|
1116
1625
|
continue;
|
|
1117
1626
|
}
|
|
1118
|
-
if (options.log) throw new AlephaError(`Failed during '${func}()' hook for service: ${name}`, { cause: error });
|
|
1627
|
+
if (options.log) throw new AlephaError(`Failed during '${String(func)}()' hook for service: ${name}`, { cause: error });
|
|
1119
1628
|
throw error;
|
|
1120
1629
|
}
|
|
1121
|
-
if (options.log) this.log?.debug(`${func}(${name}) OK [${
|
|
1630
|
+
if (options.log) this.log?.debug(`${String(func)}(${name}) OK [${(performance.now() - ctx.now2).toFixed(1)}ms]`);
|
|
1122
1631
|
}
|
|
1123
|
-
if (options.log) this.log?.debug(`${func} OK [${
|
|
1632
|
+
if (options.log) this.log?.debug(`${String(func)} OK [${(performance.now() - ctx.now).toFixed(1)}ms]`);
|
|
1124
1633
|
}
|
|
1125
1634
|
};
|
|
1126
1635
|
|
|
@@ -1404,13 +1913,10 @@ var Alepha = class Alepha {
|
|
|
1404
1913
|
* If you are not interested about these helpers, you can use the constructor directly.
|
|
1405
1914
|
*/
|
|
1406
1915
|
static create(state = {}) {
|
|
1407
|
-
if (typeof process === "object" && typeof process.env === "object") {
|
|
1408
|
-
state.env
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
};
|
|
1412
|
-
for (const key in state.env) if (state.env[key] === "") delete state.env[key];
|
|
1413
|
-
}
|
|
1916
|
+
if (typeof process === "object" && typeof process.env === "object") state.env = {
|
|
1917
|
+
...state.env,
|
|
1918
|
+
...process.env
|
|
1919
|
+
};
|
|
1414
1920
|
if (process.env.NODE_ENV === "production") {
|
|
1415
1921
|
state.env ??= {};
|
|
1416
1922
|
Object.assign(state.env, { NODE_ENV: "production" });
|
|
@@ -1772,7 +2278,10 @@ var Alepha = class Alepha {
|
|
|
1772
2278
|
if (!match.parents.includes(parent) && parent !== service) match.parents.push(parent);
|
|
1773
2279
|
return match.instance;
|
|
1774
2280
|
}
|
|
1775
|
-
if (this.started)
|
|
2281
|
+
if (this.started) {
|
|
2282
|
+
const mod = service[MODULE]?.name;
|
|
2283
|
+
throw new ContainerLockedError(`Container is locked. No more services can be added. Attempted to inject '${service.name}' from '${parent?.name}'. ${mod ? `Maybe register module '${mod}' in Alepha.` : ""}`);
|
|
2284
|
+
}
|
|
1776
2285
|
}
|
|
1777
2286
|
const module = service[MODULE];
|
|
1778
2287
|
if (module && typeof module === "function") this.with(module);
|
|
@@ -1788,10 +2297,10 @@ var Alepha = class Alepha {
|
|
|
1788
2297
|
if (!transient) registry.set(service, definition);
|
|
1789
2298
|
if (instance instanceof Module) {
|
|
1790
2299
|
this.modules.push(instance);
|
|
1791
|
-
const parent
|
|
2300
|
+
const parent = __alephaRef.parent;
|
|
1792
2301
|
__alephaRef.parent = instance.constructor;
|
|
1793
2302
|
instance.register(this);
|
|
1794
|
-
__alephaRef.parent = parent
|
|
2303
|
+
__alephaRef.parent = parent;
|
|
1795
2304
|
}
|
|
1796
2305
|
return instance;
|
|
1797
2306
|
}
|
|
@@ -2331,5 +2840,5 @@ const run = (entry, opts) => {
|
|
|
2331
2840
|
};
|
|
2332
2841
|
|
|
2333
2842
|
//#endregion
|
|
2334
|
-
export { $atom, $context, $env, $hook, $inject, $module, $use, Alepha, AlephaError, AlsProvider, AppNotStartedError, Atom, CircularDependencyError, CodecManager, ContainerLockedError, EventManager, Format, HookPrimitive, InjectPrimitive, JsonSchemaCodec, KIND, Module, OPTIONS, Primitive, SchemaCodec, StateManager, TooLateSubstitutionError, Type, TypeBoxError, TypeGuard, TypeProvider, Value, createPagination, createPrimitive, isClass, isFileLike, isTypeFile, isUUID, jsonSchemaToTypeBox, pageMetadataSchema, pageQuerySchema, pageSchema, run, t };
|
|
2843
|
+
export { $atom, $context, $env, $hook, $inject, $module, $use, Alepha, AlephaError, AlsProvider, AppNotStartedError, Atom, CircularDependencyError, CodecManager, ContainerLockedError, EventManager, Format, HookPrimitive, InjectPrimitive, JsonSchemaCodec, KIND, KeylessJsonSchemaCodec, Module, OPTIONS, Primitive, SchemaCodec, StateManager, TooLateSubstitutionError, Type, TypeBoxError, TypeGuard, TypeProvider, Value, createPagination, createPrimitive, isClass, isFileLike, isTypeFile, isUUID, jsonSchemaToTypeBox, pageMetadataSchema, pageQuerySchema, pageSchema, run, t };
|
|
2335
2844
|
//# sourceMappingURL=index.native.js.map
|