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
package/dist/core/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
2
|
import cluster from "node:cluster";
|
|
3
3
|
import { cpus } from "node:os";
|
|
4
|
-
import { Compile } from "typebox/compile";
|
|
5
4
|
import { Type } from "typebox";
|
|
6
5
|
import Format from "typebox/format";
|
|
7
6
|
import * as Value from "typebox/value";
|
|
7
|
+
import { Compile } from "typebox/compile";
|
|
8
8
|
|
|
9
9
|
//#region ../../src/core/constants/KIND.ts
|
|
10
10
|
/**
|
|
@@ -262,6 +262,7 @@ const $module = (options) => {
|
|
|
262
262
|
const $ = class extends Module {
|
|
263
263
|
options = options;
|
|
264
264
|
register(alepha) {
|
|
265
|
+
if (options.atoms) for (const atom of options.atoms) alepha.store.register(atom);
|
|
265
266
|
if (typeof options.register === "function") {
|
|
266
267
|
options.register(alepha);
|
|
267
268
|
return;
|
|
@@ -313,7 +314,7 @@ var AlsProvider = class AlsProvider {
|
|
|
313
314
|
if (!this.als) return callback();
|
|
314
315
|
data.registry ??= /* @__PURE__ */ new Map();
|
|
315
316
|
data.context ??= this.createContextId();
|
|
316
|
-
return this.als.run(data, callback);
|
|
317
|
+
return this.als.run({ ...data }, callback);
|
|
317
318
|
}
|
|
318
319
|
exists() {
|
|
319
320
|
return !!this.get("context");
|
|
@@ -398,27 +399,6 @@ var JsonSchemaCodec = class extends SchemaCodec {
|
|
|
398
399
|
}
|
|
399
400
|
};
|
|
400
401
|
|
|
401
|
-
//#endregion
|
|
402
|
-
//#region ../../src/core/errors/TypeBoxError.ts
|
|
403
|
-
var TypeBoxError = class extends AlephaError {
|
|
404
|
-
name = "TypeBoxError";
|
|
405
|
-
cause;
|
|
406
|
-
value;
|
|
407
|
-
constructor(error) {
|
|
408
|
-
super(`Invalid input: ${error.message}${error.instancePath ? ` at ${error.instancePath}` : ""}`, { cause: error });
|
|
409
|
-
const params = error.params;
|
|
410
|
-
if (params?.requiredProperties) this.value = {
|
|
411
|
-
path: `/${params.requiredProperties[0]}`,
|
|
412
|
-
message: "must be defined"
|
|
413
|
-
};
|
|
414
|
-
else this.value = {
|
|
415
|
-
path: error.instancePath,
|
|
416
|
-
message: error.message
|
|
417
|
-
};
|
|
418
|
-
this.cause = error;
|
|
419
|
-
}
|
|
420
|
-
};
|
|
421
|
-
|
|
422
402
|
//#endregion
|
|
423
403
|
//#region ../../src/core/primitives/$hook.ts
|
|
424
404
|
/**
|
|
@@ -464,12 +444,13 @@ const $hook = (options) => createPrimitive(HookPrimitive, options);
|
|
|
464
444
|
var HookPrimitive = class extends Primitive {
|
|
465
445
|
called = 0;
|
|
466
446
|
onInit() {
|
|
447
|
+
const handler = this.options.handler;
|
|
467
448
|
this.alepha.events.on(this.options.on, {
|
|
468
449
|
caller: this.config.service,
|
|
469
450
|
priority: this.options.priority,
|
|
470
|
-
callback:
|
|
451
|
+
callback: (args) => {
|
|
471
452
|
this.called += 1;
|
|
472
|
-
|
|
453
|
+
return handler(args);
|
|
473
454
|
}
|
|
474
455
|
});
|
|
475
456
|
}
|
|
@@ -910,6 +891,452 @@ var TypeProvider = class TypeProvider {
|
|
|
910
891
|
};
|
|
911
892
|
const t = new TypeProvider();
|
|
912
893
|
|
|
894
|
+
//#endregion
|
|
895
|
+
//#region ../../src/core/providers/KeylessJsonSchemaCodec.ts
|
|
896
|
+
const UNSAFE_KEYS = new Set([
|
|
897
|
+
"__proto__",
|
|
898
|
+
"constructor",
|
|
899
|
+
"prototype"
|
|
900
|
+
]);
|
|
901
|
+
/**
|
|
902
|
+
* KeylessJsonSchemaCodec provides schema-driven JSON encoding without keys.
|
|
903
|
+
*
|
|
904
|
+
* It uses the schema to determine field order, allowing the encoded output
|
|
905
|
+
* to be a simple JSON array instead of an object with keys.
|
|
906
|
+
*/
|
|
907
|
+
var KeylessJsonSchemaCodec = class extends SchemaCodec {
|
|
908
|
+
cache = /* @__PURE__ */ new Map();
|
|
909
|
+
textEncoder = new TextEncoder();
|
|
910
|
+
textDecoder = new TextDecoder();
|
|
911
|
+
varCounter = 0;
|
|
912
|
+
useFunctionCompilation = true;
|
|
913
|
+
maxArrayLength = 1e4;
|
|
914
|
+
maxStringLength = 1e6;
|
|
915
|
+
maxDepth = 50;
|
|
916
|
+
/**
|
|
917
|
+
* Configure codec options.
|
|
918
|
+
*/
|
|
919
|
+
configure(options) {
|
|
920
|
+
if (options.useFunctionCompilation !== void 0) {
|
|
921
|
+
this.useFunctionCompilation = options.useFunctionCompilation;
|
|
922
|
+
this.cache.clear();
|
|
923
|
+
}
|
|
924
|
+
if (options.maxArrayLength !== void 0) this.maxArrayLength = options.maxArrayLength;
|
|
925
|
+
if (options.maxStringLength !== void 0) this.maxStringLength = options.maxStringLength;
|
|
926
|
+
if (options.maxDepth !== void 0) this.maxDepth = options.maxDepth;
|
|
927
|
+
return this;
|
|
928
|
+
}
|
|
929
|
+
/**
|
|
930
|
+
* Hook to auto-detect safe mode on configure.
|
|
931
|
+
* Disables function compilation in browser by default.
|
|
932
|
+
*/
|
|
933
|
+
onConfigure = $hook({
|
|
934
|
+
on: "configure",
|
|
935
|
+
handler: () => {
|
|
936
|
+
this.useFunctionCompilation = this.canUseFunction();
|
|
937
|
+
}
|
|
938
|
+
});
|
|
939
|
+
/**
|
|
940
|
+
* Encode value to a keyless JSON string.
|
|
941
|
+
*/
|
|
942
|
+
encodeToString(schema, value) {
|
|
943
|
+
return this.getCodec(schema).encode(value);
|
|
944
|
+
}
|
|
945
|
+
/**
|
|
946
|
+
* Encode value to binary (UTF-8 encoded keyless JSON).
|
|
947
|
+
*/
|
|
948
|
+
encodeToBinary(schema, value) {
|
|
949
|
+
return this.textEncoder.encode(this.encodeToString(schema, value));
|
|
950
|
+
}
|
|
951
|
+
/**
|
|
952
|
+
* Decode keyless JSON string or binary to value.
|
|
953
|
+
*/
|
|
954
|
+
decode(schema, value) {
|
|
955
|
+
if (value instanceof Uint8Array) {
|
|
956
|
+
const text = this.textDecoder.decode(value);
|
|
957
|
+
return this.getCodec(schema).decode(text);
|
|
958
|
+
}
|
|
959
|
+
if (typeof value === "string") return this.getCodec(schema).decode(value);
|
|
960
|
+
if (Array.isArray(value)) return this.reconstructObject(schema, value);
|
|
961
|
+
return value;
|
|
962
|
+
}
|
|
963
|
+
/**
|
|
964
|
+
* Test if `new Function()` is available (not blocked by CSP).
|
|
965
|
+
*/
|
|
966
|
+
canUseFunction() {
|
|
967
|
+
try {
|
|
968
|
+
return new Function("return true")() === true;
|
|
969
|
+
} catch {
|
|
970
|
+
return false;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* Validate schema keys for prototype pollution.
|
|
975
|
+
* Uses a visited set to avoid infinite recursion on recursive schemas.
|
|
976
|
+
*/
|
|
977
|
+
validateSchemaKeys(schema, depth = 0, visited = /* @__PURE__ */ new Set()) {
|
|
978
|
+
if (visited.has(schema)) return;
|
|
979
|
+
visited.add(schema);
|
|
980
|
+
if (depth > this.maxDepth) throw new AlephaError(`Schema depth exceeds maximum allowed (${this.maxDepth})`);
|
|
981
|
+
if (t.schema.isObject(schema)) {
|
|
982
|
+
const props = schema.properties;
|
|
983
|
+
for (const key of Object.keys(props)) {
|
|
984
|
+
if (UNSAFE_KEYS.has(key)) throw new AlephaError(`Unsafe schema key "${key}" detected. This key is blocked to prevent prototype pollution.`);
|
|
985
|
+
this.validateSchemaKeys(props[key], depth + 1, visited);
|
|
986
|
+
}
|
|
987
|
+
} else if (t.schema.isArray(schema)) {
|
|
988
|
+
const arrSchema = schema;
|
|
989
|
+
this.validateSchemaKeys(arrSchema.items, depth + 1, visited);
|
|
990
|
+
} else if (t.schema.isUnion(schema) || t.schema.isOptional(schema)) this.validateSchemaKeys(this.unwrap(schema), depth, visited);
|
|
991
|
+
}
|
|
992
|
+
/**
|
|
993
|
+
* Validate array length.
|
|
994
|
+
*/
|
|
995
|
+
validateArrayLength(arr) {
|
|
996
|
+
if (arr.length > this.maxArrayLength) throw new AlephaError(`Array length (${arr.length}) exceeds maximum allowed (${this.maxArrayLength})`);
|
|
997
|
+
}
|
|
998
|
+
/**
|
|
999
|
+
* Validate string length.
|
|
1000
|
+
*/
|
|
1001
|
+
validateStringLength(str) {
|
|
1002
|
+
if (str.length > this.maxStringLength) throw new AlephaError(`String length (${str.length}) exceeds maximum allowed (${this.maxStringLength})`);
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Get a compiled codec for the given schema.
|
|
1006
|
+
* Codecs are cached for reuse.
|
|
1007
|
+
*/
|
|
1008
|
+
getCodec(schema) {
|
|
1009
|
+
let c = this.cache.get(schema);
|
|
1010
|
+
if (!c) {
|
|
1011
|
+
c = this.useFunctionCompilation ? this.compileWithFunction(schema) : this.compileInterpreted(schema);
|
|
1012
|
+
this.cache.set(schema, c);
|
|
1013
|
+
}
|
|
1014
|
+
return c;
|
|
1015
|
+
}
|
|
1016
|
+
nextVar() {
|
|
1017
|
+
return `_${this.varCounter++}`;
|
|
1018
|
+
}
|
|
1019
|
+
/**
|
|
1020
|
+
* Compile codec using `new Function()` for maximum performance.
|
|
1021
|
+
* Only used when CSP allows and useFunctionCompilation is true.
|
|
1022
|
+
*/
|
|
1023
|
+
compileWithFunction(schema) {
|
|
1024
|
+
this.varCounter = 0;
|
|
1025
|
+
const encBody = this.genEnc(schema, "v");
|
|
1026
|
+
this.varCounter = 0;
|
|
1027
|
+
const decBody = this.genDec(schema);
|
|
1028
|
+
return {
|
|
1029
|
+
encode: new Function("v", `return JSON.stringify(${encBody});`),
|
|
1030
|
+
decode: new Function("s", `const a=JSON.parse(s);let i=0;${decBody.code}return ${decBody.result};`)
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
/**
|
|
1034
|
+
* Compile codec using interpreter-based approach.
|
|
1035
|
+
* Safer (no eval/Function) but slower. Used in browser by default.
|
|
1036
|
+
*/
|
|
1037
|
+
compileInterpreted(schema) {
|
|
1038
|
+
const self = this;
|
|
1039
|
+
return {
|
|
1040
|
+
encode(value) {
|
|
1041
|
+
return JSON.stringify(self.interpretEncode(schema, value));
|
|
1042
|
+
},
|
|
1043
|
+
decode(str) {
|
|
1044
|
+
const ctx = {
|
|
1045
|
+
arr: JSON.parse(str),
|
|
1046
|
+
i: 0
|
|
1047
|
+
};
|
|
1048
|
+
return self.interpretDecode(schema, ctx);
|
|
1049
|
+
}
|
|
1050
|
+
};
|
|
1051
|
+
}
|
|
1052
|
+
interpretEncode(schema, value) {
|
|
1053
|
+
if (t.schema.isString(schema) || t.schema.isNumber(schema) || t.schema.isInteger(schema) || t.schema.isBoolean(schema) || this.isEnum(schema)) return value;
|
|
1054
|
+
if (t.schema.isBigInt(schema)) return `${value}n`;
|
|
1055
|
+
if (t.schema.isArray(schema)) {
|
|
1056
|
+
const arrSchema = schema;
|
|
1057
|
+
if (!Array.isArray(value)) return value;
|
|
1058
|
+
if (t.schema.isString(arrSchema.items) || t.schema.isNumber(arrSchema.items) || t.schema.isInteger(arrSchema.items) || t.schema.isBoolean(arrSchema.items)) return value;
|
|
1059
|
+
return value.map((e) => this.interpretEncode(arrSchema.items, e));
|
|
1060
|
+
}
|
|
1061
|
+
if (t.schema.isObject(schema)) {
|
|
1062
|
+
const objSchema = schema;
|
|
1063
|
+
const props = objSchema.properties;
|
|
1064
|
+
const keys = Object.keys(props);
|
|
1065
|
+
const req = new Set(objSchema.required || []);
|
|
1066
|
+
const result = [];
|
|
1067
|
+
for (const k of keys) {
|
|
1068
|
+
const ps = props[k];
|
|
1069
|
+
const isOpt = !req.has(k) || t.schema.isOptional(ps);
|
|
1070
|
+
const isNullable = this.isNullable(ps);
|
|
1071
|
+
const inner = this.unwrap(ps);
|
|
1072
|
+
const v = value[k];
|
|
1073
|
+
if (isOpt) result.push(v !== void 0 ? this.interpretEncode(inner, v) : null);
|
|
1074
|
+
else if (isNullable) result.push(v !== null ? this.interpretEncode(inner, v) : null);
|
|
1075
|
+
else result.push(this.interpretEncode(inner, v));
|
|
1076
|
+
}
|
|
1077
|
+
return result;
|
|
1078
|
+
}
|
|
1079
|
+
if (t.schema.isOptional(schema) || t.schema.isUnion(schema)) {
|
|
1080
|
+
const inner = this.unwrap(schema);
|
|
1081
|
+
if (this.isNullable(schema)) return value !== null ? this.interpretEncode(inner, value) : null;
|
|
1082
|
+
return value !== void 0 ? this.interpretEncode(inner, value) : null;
|
|
1083
|
+
}
|
|
1084
|
+
return value;
|
|
1085
|
+
}
|
|
1086
|
+
interpretDecode(schema, ctx) {
|
|
1087
|
+
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++];
|
|
1088
|
+
if (t.schema.isBigInt(schema)) return BigInt(ctx.arr[ctx.i++].slice(0, -1));
|
|
1089
|
+
if (t.schema.isArray(schema)) {
|
|
1090
|
+
const arrSchema = schema;
|
|
1091
|
+
const arr = ctx.arr[ctx.i++];
|
|
1092
|
+
if (!Array.isArray(arr)) return arr;
|
|
1093
|
+
if (t.schema.isObject(arrSchema.items)) return arr.map((e) => this.interpretDecodeFromValue(arrSchema.items, e));
|
|
1094
|
+
return arr;
|
|
1095
|
+
}
|
|
1096
|
+
if (t.schema.isObject(schema)) {
|
|
1097
|
+
const objSchema = schema;
|
|
1098
|
+
const props = objSchema.properties;
|
|
1099
|
+
const keys = Object.keys(props);
|
|
1100
|
+
const req = new Set(objSchema.required || []);
|
|
1101
|
+
const result = {};
|
|
1102
|
+
for (const k of keys) {
|
|
1103
|
+
const ps = props[k];
|
|
1104
|
+
const isOpt = !req.has(k) || t.schema.isOptional(ps);
|
|
1105
|
+
const isNullable = this.isNullable(ps);
|
|
1106
|
+
const inner = this.unwrap(ps);
|
|
1107
|
+
const val = ctx.arr[ctx.i++];
|
|
1108
|
+
if (isOpt) {
|
|
1109
|
+
if (val !== null) result[k] = this.interpretDecodeFromValue(inner, val);
|
|
1110
|
+
} else if (isNullable) result[k] = val === null ? null : this.interpretDecodeFromValue(inner, val);
|
|
1111
|
+
else result[k] = this.interpretDecodeFromValue(inner, val);
|
|
1112
|
+
}
|
|
1113
|
+
return result;
|
|
1114
|
+
}
|
|
1115
|
+
if (t.schema.isOptional(schema) || t.schema.isUnion(schema)) {
|
|
1116
|
+
const inner = this.unwrap(schema);
|
|
1117
|
+
const val = ctx.arr[ctx.i++];
|
|
1118
|
+
if (val === null) return this.isNullable(schema) ? null : void 0;
|
|
1119
|
+
if (t.schema.isObject(inner) || t.schema.isArray(inner)) return this.interpretDecodeFromValue(inner, val);
|
|
1120
|
+
return val;
|
|
1121
|
+
}
|
|
1122
|
+
return ctx.arr[ctx.i++];
|
|
1123
|
+
}
|
|
1124
|
+
interpretDecodeFromValue(schema, value) {
|
|
1125
|
+
if (t.schema.isString(schema) || t.schema.isNumber(schema) || t.schema.isInteger(schema) || t.schema.isBoolean(schema) || this.isEnum(schema)) return value;
|
|
1126
|
+
if (t.schema.isBigInt(schema)) return BigInt(value.slice(0, -1));
|
|
1127
|
+
if (t.schema.isArray(schema)) {
|
|
1128
|
+
if (!Array.isArray(value)) return value;
|
|
1129
|
+
const arrSchema = schema;
|
|
1130
|
+
if (t.schema.isObject(arrSchema.items)) return value.map((e) => this.interpretDecodeFromValue(arrSchema.items, e));
|
|
1131
|
+
return value;
|
|
1132
|
+
}
|
|
1133
|
+
if (t.schema.isObject(schema)) {
|
|
1134
|
+
const props = schema.properties;
|
|
1135
|
+
const keys = Object.keys(props);
|
|
1136
|
+
const result = {};
|
|
1137
|
+
for (let idx = 0; idx < keys.length; idx++) {
|
|
1138
|
+
const k = keys[idx];
|
|
1139
|
+
const inner = this.unwrap(props[k]);
|
|
1140
|
+
const v = value[idx];
|
|
1141
|
+
if (t.schema.isObject(inner)) result[k] = this.interpretDecodeFromValue(inner, v);
|
|
1142
|
+
else if (t.schema.isBigInt(inner)) result[k] = BigInt(v.slice(0, -1));
|
|
1143
|
+
else result[k] = v;
|
|
1144
|
+
}
|
|
1145
|
+
return result;
|
|
1146
|
+
}
|
|
1147
|
+
return value;
|
|
1148
|
+
}
|
|
1149
|
+
genEnc(schema, ve) {
|
|
1150
|
+
if (t.schema.isString(schema) || t.schema.isNumber(schema) || t.schema.isInteger(schema) || t.schema.isBoolean(schema) || this.isEnum(schema)) return ve;
|
|
1151
|
+
if (t.schema.isBigInt(schema)) return `${ve}+'n'`;
|
|
1152
|
+
if (t.schema.isArray(schema)) {
|
|
1153
|
+
const arrSchema = schema;
|
|
1154
|
+
const itemEnc = this.genEnc(arrSchema.items, "e");
|
|
1155
|
+
if (t.schema.isString(arrSchema.items) || t.schema.isNumber(arrSchema.items) || t.schema.isInteger(arrSchema.items) || t.schema.isBoolean(arrSchema.items)) return ve;
|
|
1156
|
+
return `${ve}.map(e=>${itemEnc})`;
|
|
1157
|
+
}
|
|
1158
|
+
if (t.schema.isObject(schema)) {
|
|
1159
|
+
const objSchema = schema;
|
|
1160
|
+
const props = objSchema.properties;
|
|
1161
|
+
const keys = Object.keys(props);
|
|
1162
|
+
const req = new Set(objSchema.required || []);
|
|
1163
|
+
const parts = [];
|
|
1164
|
+
for (const k of keys) {
|
|
1165
|
+
const ps = props[k];
|
|
1166
|
+
const isOpt = !req.has(k) || t.schema.isOptional(ps);
|
|
1167
|
+
const isNullable = this.isNullable(ps);
|
|
1168
|
+
const inner = this.unwrap(ps);
|
|
1169
|
+
const innerEnc = this.genEnc(inner, `${ve}.${k}`);
|
|
1170
|
+
if (isOpt) parts.push(`${ve}.${k}!==undefined?${innerEnc}:null`);
|
|
1171
|
+
else if (isNullable) parts.push(`${ve}.${k}!==null?${innerEnc}:null`);
|
|
1172
|
+
else parts.push(innerEnc);
|
|
1173
|
+
}
|
|
1174
|
+
return `[${parts.join(",")}]`;
|
|
1175
|
+
}
|
|
1176
|
+
if (t.schema.isOptional(schema) || t.schema.isUnion(schema)) {
|
|
1177
|
+
const inner = this.unwrap(schema);
|
|
1178
|
+
const innerEnc = this.genEnc(inner, ve);
|
|
1179
|
+
if (this.isNullable(schema)) return `${ve}!==null?${innerEnc}:null`;
|
|
1180
|
+
return `${ve}!==undefined?${innerEnc}:null`;
|
|
1181
|
+
}
|
|
1182
|
+
return ve;
|
|
1183
|
+
}
|
|
1184
|
+
genDec(schema) {
|
|
1185
|
+
const v = this.nextVar();
|
|
1186
|
+
if (t.schema.isString(schema) || t.schema.isNumber(schema) || t.schema.isInteger(schema) || t.schema.isBoolean(schema) || this.isEnum(schema)) return {
|
|
1187
|
+
code: "",
|
|
1188
|
+
result: "a[i++]"
|
|
1189
|
+
};
|
|
1190
|
+
if (t.schema.isBigInt(schema)) return {
|
|
1191
|
+
code: "",
|
|
1192
|
+
result: "BigInt(a[i++].slice(0,-1))"
|
|
1193
|
+
};
|
|
1194
|
+
if (t.schema.isArray(schema)) {
|
|
1195
|
+
const arrSchema = schema;
|
|
1196
|
+
if (t.schema.isObject(arrSchema.items)) return {
|
|
1197
|
+
code: "",
|
|
1198
|
+
result: `a[i++].map(e=>${this.genDecFromValue(arrSchema.items, "e")})`
|
|
1199
|
+
};
|
|
1200
|
+
return {
|
|
1201
|
+
code: "",
|
|
1202
|
+
result: "a[i++]"
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
if (t.schema.isObject(schema)) {
|
|
1206
|
+
const objSchema = schema;
|
|
1207
|
+
const props = objSchema.properties;
|
|
1208
|
+
const keys = Object.keys(props);
|
|
1209
|
+
const req = new Set(objSchema.required || []);
|
|
1210
|
+
let simple = true;
|
|
1211
|
+
for (const k of keys) {
|
|
1212
|
+
const ps = props[k];
|
|
1213
|
+
const isOpt = !req.has(k) || t.schema.isOptional(ps);
|
|
1214
|
+
const isNullable = this.isNullable(ps);
|
|
1215
|
+
const inner = this.unwrap(ps);
|
|
1216
|
+
if (isOpt || isNullable || t.schema.isObject(inner) || t.schema.isArray(inner)) {
|
|
1217
|
+
simple = false;
|
|
1218
|
+
break;
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
if (simple) return {
|
|
1222
|
+
code: "",
|
|
1223
|
+
result: `{${keys.map((k) => `${k}:a[i++]`).join(",")}}`
|
|
1224
|
+
};
|
|
1225
|
+
let code = `const ${v}={};`;
|
|
1226
|
+
for (const k of keys) {
|
|
1227
|
+
const ps = props[k];
|
|
1228
|
+
const isOpt = !req.has(k) || t.schema.isOptional(ps);
|
|
1229
|
+
const isNullable = this.isNullable(ps);
|
|
1230
|
+
const inner = this.unwrap(ps);
|
|
1231
|
+
if (isOpt) {
|
|
1232
|
+
const nested = this.genDecFromValue(inner, "t");
|
|
1233
|
+
code += `{const t=a[i++];if(t!==null){${v}.${k}=${nested};}}`;
|
|
1234
|
+
} else if (isNullable) {
|
|
1235
|
+
const nested = this.genDecFromValue(inner, "t");
|
|
1236
|
+
code += `{const t=a[i++];if(t===null){${v}.${k}=null;}else{${v}.${k}=${nested};}}`;
|
|
1237
|
+
} else if (t.schema.isObject(inner)) {
|
|
1238
|
+
const nested = this.genDecFromValue(inner, "a[i++]");
|
|
1239
|
+
code += `${v}.${k}=${nested};`;
|
|
1240
|
+
} else if (t.schema.isArray(inner)) {
|
|
1241
|
+
const arrSchema = inner;
|
|
1242
|
+
if (t.schema.isObject(arrSchema.items)) {
|
|
1243
|
+
const itemTransform = this.genDecFromValue(arrSchema.items, "e");
|
|
1244
|
+
code += `${v}.${k}=a[i++].map(e=>${itemTransform});`;
|
|
1245
|
+
} else code += `${v}.${k}=a[i++];`;
|
|
1246
|
+
} else code += `${v}.${k}=a[i++];`;
|
|
1247
|
+
}
|
|
1248
|
+
return {
|
|
1249
|
+
code,
|
|
1250
|
+
result: v
|
|
1251
|
+
};
|
|
1252
|
+
}
|
|
1253
|
+
if (t.schema.isOptional(schema) || t.schema.isUnion(schema)) {
|
|
1254
|
+
const inner = this.unwrap(schema);
|
|
1255
|
+
const innerDec = this.genDec(inner);
|
|
1256
|
+
return {
|
|
1257
|
+
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`)};}`,
|
|
1258
|
+
result: v
|
|
1259
|
+
};
|
|
1260
|
+
}
|
|
1261
|
+
return {
|
|
1262
|
+
code: "",
|
|
1263
|
+
result: "a[i++]"
|
|
1264
|
+
};
|
|
1265
|
+
}
|
|
1266
|
+
genDecFromValue(schema, expr) {
|
|
1267
|
+
if (t.schema.isString(schema) || t.schema.isNumber(schema) || t.schema.isInteger(schema) || t.schema.isBoolean(schema) || this.isEnum(schema)) return expr;
|
|
1268
|
+
if (t.schema.isBigInt(schema)) return `BigInt(${expr}.slice(0,-1))`;
|
|
1269
|
+
if (t.schema.isArray(schema)) return expr;
|
|
1270
|
+
if (t.schema.isObject(schema)) {
|
|
1271
|
+
const props = schema.properties;
|
|
1272
|
+
const keys = Object.keys(props);
|
|
1273
|
+
const v = this.nextVar();
|
|
1274
|
+
return `((${v}=${expr})=>({${keys.map((k, idx) => {
|
|
1275
|
+
const inner = this.unwrap(props[k]);
|
|
1276
|
+
const innerExpr = `${v}[${idx}]`;
|
|
1277
|
+
if (t.schema.isObject(inner)) return `${k}:${this.genDecFromValue(inner, innerExpr)}`;
|
|
1278
|
+
if (t.schema.isBigInt(inner)) return `${k}:BigInt(${innerExpr}.slice(0,-1))`;
|
|
1279
|
+
return `${k}:${innerExpr}`;
|
|
1280
|
+
}).join(",")}}))()`;
|
|
1281
|
+
}
|
|
1282
|
+
return expr;
|
|
1283
|
+
}
|
|
1284
|
+
isEnum(schema) {
|
|
1285
|
+
return "enum" in schema && Array.isArray(schema.enum) && (schema.enum?.length ?? 0) > 0;
|
|
1286
|
+
}
|
|
1287
|
+
isNullable(schema) {
|
|
1288
|
+
if (!t.schema.isUnion(schema)) return false;
|
|
1289
|
+
return schema.anyOf?.some((s) => t.schema.isNull(s)) ?? false;
|
|
1290
|
+
}
|
|
1291
|
+
unwrap(schema) {
|
|
1292
|
+
if ("anyOf" in schema && Array.isArray(schema.anyOf)) return schema.anyOf.find((s) => !t.schema.isNull(s)) || schema;
|
|
1293
|
+
return schema;
|
|
1294
|
+
}
|
|
1295
|
+
/**
|
|
1296
|
+
* Reconstruct an object from a parsed array (for when input is already parsed).
|
|
1297
|
+
*/
|
|
1298
|
+
reconstructObject(schema, arr) {
|
|
1299
|
+
if (!t.schema.isObject(schema)) return arr;
|
|
1300
|
+
const props = schema.properties;
|
|
1301
|
+
const keys = Object.keys(props);
|
|
1302
|
+
const result = {};
|
|
1303
|
+
let i = 0;
|
|
1304
|
+
for (const k of keys) {
|
|
1305
|
+
const ps = props[k];
|
|
1306
|
+
const isOpt = t.schema.isOptional(ps);
|
|
1307
|
+
const isNullable = this.isNullable(ps);
|
|
1308
|
+
const inner = this.unwrap(ps);
|
|
1309
|
+
const val = arr[i++];
|
|
1310
|
+
if (isOpt) {
|
|
1311
|
+
if (val !== null) result[k] = t.schema.isObject(inner) ? this.reconstructObject(inner, val) : val;
|
|
1312
|
+
} else if (isNullable) result[k] = val === null ? null : t.schema.isObject(inner) ? this.reconstructObject(inner, val) : val;
|
|
1313
|
+
else result[k] = t.schema.isObject(inner) ? this.reconstructObject(inner, val) : val;
|
|
1314
|
+
}
|
|
1315
|
+
return result;
|
|
1316
|
+
}
|
|
1317
|
+
};
|
|
1318
|
+
|
|
1319
|
+
//#endregion
|
|
1320
|
+
//#region ../../src/core/errors/TypeBoxError.ts
|
|
1321
|
+
var TypeBoxError = class extends AlephaError {
|
|
1322
|
+
name = "TypeBoxError";
|
|
1323
|
+
cause;
|
|
1324
|
+
value;
|
|
1325
|
+
constructor(error) {
|
|
1326
|
+
super(`Invalid input: ${error.message}${error.instancePath ? ` at ${error.instancePath}` : ""}`, { cause: error });
|
|
1327
|
+
const params = error.params;
|
|
1328
|
+
if (params?.requiredProperties) this.value = {
|
|
1329
|
+
path: `/${params.requiredProperties[0]}`,
|
|
1330
|
+
message: "must be defined"
|
|
1331
|
+
};
|
|
1332
|
+
else this.value = {
|
|
1333
|
+
path: error.instancePath,
|
|
1334
|
+
message: error.message
|
|
1335
|
+
};
|
|
1336
|
+
this.cause = error;
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
|
|
913
1340
|
//#endregion
|
|
914
1341
|
//#region ../../src/core/providers/SchemaValidator.ts
|
|
915
1342
|
var SchemaValidator = class {
|
|
@@ -1004,19 +1431,26 @@ var SchemaValidator = class {
|
|
|
1004
1431
|
var CodecManager = class {
|
|
1005
1432
|
codecs = /* @__PURE__ */ new Map();
|
|
1006
1433
|
jsonCodec = $inject(JsonSchemaCodec);
|
|
1434
|
+
keylessCodec = $inject(KeylessJsonSchemaCodec);
|
|
1007
1435
|
schemaValidator = $inject(SchemaValidator);
|
|
1008
1436
|
default = "json";
|
|
1009
1437
|
constructor() {
|
|
1010
|
-
this.register(
|
|
1438
|
+
this.register({
|
|
1439
|
+
name: "json",
|
|
1440
|
+
codec: this.jsonCodec,
|
|
1441
|
+
default: true
|
|
1442
|
+
});
|
|
1443
|
+
this.register({
|
|
1444
|
+
name: "keyless",
|
|
1445
|
+
codec: this.keylessCodec
|
|
1446
|
+
});
|
|
1011
1447
|
}
|
|
1012
1448
|
/**
|
|
1013
1449
|
* Register a new codec format.
|
|
1014
|
-
*
|
|
1015
|
-
* @param name - The name of the codec (e.g., 'json', 'protobuf')
|
|
1016
|
-
* @param codec - The codec implementation
|
|
1017
1450
|
*/
|
|
1018
|
-
register(
|
|
1019
|
-
this.codecs.set(name, codec);
|
|
1451
|
+
register(opts) {
|
|
1452
|
+
this.codecs.set(opts.name, opts.codec);
|
|
1453
|
+
if (opts.default) this.default = opts.name;
|
|
1020
1454
|
}
|
|
1021
1455
|
/**
|
|
1022
1456
|
* Get a specific codec by name.
|
|
@@ -1095,35 +1529,110 @@ var EventManager = class {
|
|
|
1095
1529
|
};
|
|
1096
1530
|
}
|
|
1097
1531
|
/**
|
|
1532
|
+
* Compiles an event into an optimized executor function.
|
|
1533
|
+
*
|
|
1534
|
+
* Call this after all hooks are registered (e.g., after Alepha.start()).
|
|
1535
|
+
* The returned function checks each hook's return value and awaits promises.
|
|
1536
|
+
* Returns undefined if all hooks are sync, or a Promise if any hook returns one.
|
|
1537
|
+
*
|
|
1538
|
+
* @example
|
|
1539
|
+
* ```ts
|
|
1540
|
+
* // At startup (after hooks are registered)
|
|
1541
|
+
* const onRequest = alepha.events.compile("server:onRequest", { catch: true });
|
|
1542
|
+
*
|
|
1543
|
+
* // In hot path - only await if promise returned
|
|
1544
|
+
* const result = onRequest({ request, route });
|
|
1545
|
+
* if (result) await result;
|
|
1546
|
+
* ```
|
|
1547
|
+
*/
|
|
1548
|
+
compile(event, options = {}) {
|
|
1549
|
+
const hooks = this.events[event];
|
|
1550
|
+
if (!hooks || hooks.length === 0) return () => {};
|
|
1551
|
+
const catchErrors = options.catch ?? false;
|
|
1552
|
+
const log = this.log;
|
|
1553
|
+
const runRemainingAsync = async (startIndex, payload) => {
|
|
1554
|
+
for (let i = startIndex; i < hooks.length; i++) {
|
|
1555
|
+
const hook = hooks[i];
|
|
1556
|
+
try {
|
|
1557
|
+
const result = hook.callback(payload);
|
|
1558
|
+
if (result && typeof result === "object" && "then" in result) if (catchErrors) await result.catch((error) => {
|
|
1559
|
+
log?.error(`${String(event)}(${hook.caller?.name ?? "unknown"}) ERROR`, error);
|
|
1560
|
+
});
|
|
1561
|
+
else await result;
|
|
1562
|
+
} catch (error) {
|
|
1563
|
+
if (catchErrors) log?.error(`${String(event)}(${hook.caller?.name ?? "unknown"}) ERROR`, error);
|
|
1564
|
+
else throw error;
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
};
|
|
1568
|
+
return (payload) => {
|
|
1569
|
+
for (let i = 0; i < hooks.length; i++) {
|
|
1570
|
+
const hook = hooks[i];
|
|
1571
|
+
try {
|
|
1572
|
+
const result = hook.callback(payload);
|
|
1573
|
+
if (result && typeof result === "object" && "then" in result) {
|
|
1574
|
+
if (catchErrors) return result.catch((error) => {
|
|
1575
|
+
log?.error(`${String(event)}(${hook.caller?.name ?? "unknown"}) ERROR`, error);
|
|
1576
|
+
}).then(() => runRemainingAsync(i + 1, payload));
|
|
1577
|
+
return result.then(() => runRemainingAsync(i + 1, payload));
|
|
1578
|
+
}
|
|
1579
|
+
} catch (error) {
|
|
1580
|
+
if (catchErrors) log?.error(`${String(event)}(${hook.caller?.name ?? "unknown"}) ERROR`, error);
|
|
1581
|
+
else throw error;
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
};
|
|
1585
|
+
}
|
|
1586
|
+
/**
|
|
1098
1587
|
* Emits the specified event with the given payload.
|
|
1588
|
+
*
|
|
1589
|
+
* For hot paths (like HTTP request handling), use compile() instead
|
|
1590
|
+
* to get an optimized executor.
|
|
1099
1591
|
*/
|
|
1100
1592
|
async emit(func, payload, options = {}) {
|
|
1593
|
+
const events = this.events[func];
|
|
1594
|
+
if (!events || events.length === 0) return;
|
|
1595
|
+
if (events.length === 1 && !options.log && !options.reverse) {
|
|
1596
|
+
const hook = events[0];
|
|
1597
|
+
try {
|
|
1598
|
+
const result = hook.callback(payload);
|
|
1599
|
+
if (result && typeof result === "object" && "then" in result) await result;
|
|
1600
|
+
} catch (error) {
|
|
1601
|
+
if (options.catch) {
|
|
1602
|
+
this.log?.error(`${String(func)}(${hook.caller?.name ?? "unknown"}) ERROR`, error);
|
|
1603
|
+
return;
|
|
1604
|
+
}
|
|
1605
|
+
throw error;
|
|
1606
|
+
}
|
|
1607
|
+
return;
|
|
1608
|
+
}
|
|
1101
1609
|
const ctx = {};
|
|
1102
1610
|
if (options.log) {
|
|
1103
|
-
ctx.now =
|
|
1104
|
-
this.log?.trace(`${func} ...`);
|
|
1611
|
+
ctx.now = performance.now();
|
|
1612
|
+
this.log?.trace(`${String(func)} ...`);
|
|
1105
1613
|
}
|
|
1106
|
-
let
|
|
1107
|
-
if (options.reverse)
|
|
1108
|
-
for (const hook of
|
|
1614
|
+
let eventList = events;
|
|
1615
|
+
if (options.reverse) eventList = events.toReversed();
|
|
1616
|
+
for (const hook of eventList) {
|
|
1109
1617
|
const name = hook.caller?.name ?? "unknown";
|
|
1110
1618
|
if (options.log) {
|
|
1111
|
-
ctx.now2 =
|
|
1112
|
-
this.log?.trace(`${func}(${name}) ...`);
|
|
1619
|
+
ctx.now2 = performance.now();
|
|
1620
|
+
this.log?.trace(`${String(func)}(${name}) ...`);
|
|
1113
1621
|
}
|
|
1114
1622
|
try {
|
|
1115
|
-
|
|
1623
|
+
const result = hook.callback(payload);
|
|
1624
|
+
if (result && typeof result === "object" && "then" in result) await result;
|
|
1116
1625
|
} catch (error) {
|
|
1117
1626
|
if (options.catch) {
|
|
1118
|
-
this.log?.error(`${func}(${name}) ERROR`, error);
|
|
1627
|
+
this.log?.error(`${String(func)}(${name}) ERROR`, error);
|
|
1119
1628
|
continue;
|
|
1120
1629
|
}
|
|
1121
|
-
if (options.log) throw new AlephaError(`Failed during '${func}()' hook for service: ${name}`, { cause: error });
|
|
1630
|
+
if (options.log) throw new AlephaError(`Failed during '${String(func)}()' hook for service: ${name}`, { cause: error });
|
|
1122
1631
|
throw error;
|
|
1123
1632
|
}
|
|
1124
|
-
if (options.log) this.log?.debug(`${func}(${name}) OK [${
|
|
1633
|
+
if (options.log) this.log?.debug(`${String(func)}(${name}) OK [${(performance.now() - ctx.now2).toFixed(1)}ms]`);
|
|
1125
1634
|
}
|
|
1126
|
-
if (options.log) this.log?.debug(`${func} OK [${
|
|
1635
|
+
if (options.log) this.log?.debug(`${String(func)} OK [${(performance.now() - ctx.now).toFixed(1)}ms]`);
|
|
1127
1636
|
}
|
|
1128
1637
|
};
|
|
1129
1638
|
|
|
@@ -1407,13 +1916,10 @@ var Alepha = class Alepha {
|
|
|
1407
1916
|
* If you are not interested about these helpers, you can use the constructor directly.
|
|
1408
1917
|
*/
|
|
1409
1918
|
static create(state = {}) {
|
|
1410
|
-
if (typeof process === "object" && typeof process.env === "object") {
|
|
1411
|
-
state.env
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
};
|
|
1415
|
-
for (const key in state.env) if (state.env[key] === "") delete state.env[key];
|
|
1416
|
-
}
|
|
1919
|
+
if (typeof process === "object" && typeof process.env === "object") state.env = {
|
|
1920
|
+
...state.env,
|
|
1921
|
+
...process.env
|
|
1922
|
+
};
|
|
1417
1923
|
if (process.env.NODE_ENV === "production") {
|
|
1418
1924
|
state.env ??= {};
|
|
1419
1925
|
Object.assign(state.env, { NODE_ENV: "production" });
|
|
@@ -1775,7 +2281,10 @@ var Alepha = class Alepha {
|
|
|
1775
2281
|
if (!match.parents.includes(parent) && parent !== service) match.parents.push(parent);
|
|
1776
2282
|
return match.instance;
|
|
1777
2283
|
}
|
|
1778
|
-
if (this.started)
|
|
2284
|
+
if (this.started) {
|
|
2285
|
+
const mod = service[MODULE]?.name;
|
|
2286
|
+
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.` : ""}`);
|
|
2287
|
+
}
|
|
1779
2288
|
}
|
|
1780
2289
|
const module = service[MODULE];
|
|
1781
2290
|
if (module && typeof module === "function") this.with(module);
|
|
@@ -1791,10 +2300,10 @@ var Alepha = class Alepha {
|
|
|
1791
2300
|
if (!transient) registry.set(service, definition);
|
|
1792
2301
|
if (instance instanceof Module) {
|
|
1793
2302
|
this.modules.push(instance);
|
|
1794
|
-
const parent
|
|
2303
|
+
const parent = __alephaRef.parent;
|
|
1795
2304
|
__alephaRef.parent = instance.constructor;
|
|
1796
2305
|
instance.register(this);
|
|
1797
|
-
__alephaRef.parent = parent
|
|
2306
|
+
__alephaRef.parent = parent;
|
|
1798
2307
|
}
|
|
1799
2308
|
return instance;
|
|
1800
2309
|
}
|
|
@@ -2321,6 +2830,7 @@ const AlephaCore = $module({
|
|
|
2321
2830
|
AlsProvider,
|
|
2322
2831
|
Json,
|
|
2323
2832
|
JsonSchemaCodec,
|
|
2833
|
+
KeylessJsonSchemaCodec,
|
|
2324
2834
|
SchemaCodec,
|
|
2325
2835
|
SchemaValidator
|
|
2326
2836
|
],
|
|
@@ -2408,5 +2918,5 @@ const withCluster = (entry, opts) => {
|
|
|
2408
2918
|
};
|
|
2409
2919
|
|
|
2410
2920
|
//#endregion
|
|
2411
|
-
export { $atom, $context, $env, $hook, $inject, $module, $use, Alepha, AlephaCore, 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 };
|
|
2921
|
+
export { $atom, $context, $env, $hook, $inject, $module, $use, Alepha, AlephaCore, 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 };
|
|
2412
2922
|
//# sourceMappingURL=index.js.map
|