alepha 0.15.0 → 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 +43 -98
- package/dist/api/audits/index.d.ts +240 -240
- 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 +185 -185
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +2 -2
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +245 -245
- 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 +74 -74
- 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 +221 -221
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/users/index.d.ts +1632 -1631
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +26 -34
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts +132 -132
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/batch/index.d.ts +122 -122
- package/dist/batch/index.d.ts.map +1 -1
- package/dist/bucket/index.d.ts +163 -163
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/cache/core/index.d.ts +46 -46
- 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 +5933 -201
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +609 -169
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +296 -296
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +19 -19
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +268 -79
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +768 -694
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +268 -79
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +268 -79
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.d.ts +44 -44
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/email/index.d.ts +25 -25
- package/dist/email/index.d.ts.map +1 -1
- package/dist/fake/index.d.ts +5409 -5409
- 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 +435 -435
- package/dist/file/index.d.ts.map +1 -1
- package/dist/lock/core/index.d.ts +208 -208
- 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 +24 -24
- 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 +216 -198
- 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/index.browser.js +9 -9
- package/dist/orm/index.browser.js.map +1 -1
- package/dist/orm/index.bun.js +83 -76
- package/dist/orm/index.bun.js.map +1 -1
- package/dist/orm/index.d.ts +961 -960
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +88 -81
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +244 -244
- package/dist/queue/core/index.d.ts.map +1 -1
- package/dist/queue/redis/index.d.ts.map +1 -1
- package/dist/redis/index.d.ts +105 -105
- package/dist/redis/index.d.ts.map +1 -1
- package/dist/retry/index.d.ts +69 -69
- package/dist/retry/index.d.ts.map +1 -1
- package/dist/router/index.d.ts +6 -6
- package/dist/router/index.d.ts.map +1 -1
- package/dist/scheduler/index.d.ts +108 -26
- 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.d.ts +532 -209
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +1422 -11
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +1296 -271
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +1249 -18
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cache/index.d.ts +56 -56
- package/dist/server/cache/index.d.ts.map +1 -1
- package/dist/server/compress/index.d.ts +3 -3
- package/dist/server/compress/index.d.ts.map +1 -1
- package/dist/server/cookies/index.d.ts +6 -6
- package/dist/server/cookies/index.d.ts.map +1 -1
- package/dist/server/core/index.d.ts +196 -186
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +43 -27
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts +11 -11
- package/dist/server/cors/index.d.ts.map +1 -1
- package/dist/server/health/index.d.ts.map +1 -1
- package/dist/server/helmet/index.d.ts +2 -2
- 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 +83 -83
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +13 -5
- 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 +6 -6
- package/dist/server/multipart/index.d.ts.map +1 -1
- package/dist/server/proxy/index.d.ts +102 -102
- package/dist/server/proxy/index.d.ts.map +1 -1
- package/dist/server/rate-limit/index.d.ts +16 -16
- package/dist/server/rate-limit/index.d.ts.map +1 -1
- package/dist/server/static/index.d.ts +44 -44
- package/dist/server/static/index.d.ts.map +1 -1
- package/dist/server/swagger/index.d.ts +47 -47
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/sms/index.d.ts +11 -11
- package/dist/sms/index.d.ts.map +1 -1
- package/dist/sms/index.js +3 -3
- package/dist/sms/index.js.map +1 -1
- package/dist/thread/index.d.ts +71 -71
- 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 +318 -318
- package/dist/topic/core/index.d.ts.map +1 -1
- package/dist/topic/redis/index.d.ts +6 -6
- package/dist/topic/redis/index.d.ts.map +1 -1
- package/dist/vite/index.d.ts +2324 -1719
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +123 -475
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.browser.js +3 -3
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +275 -275
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +3 -3
- package/dist/websocket/index.js.map +1 -1
- package/package.json +9 -9
- package/src/api/users/services/SessionService.ts +0 -10
- package/src/cli/apps/AlephaCli.ts +2 -2
- package/src/cli/apps/AlephaPackageBuilderCli.ts +9 -1
- package/src/cli/assets/apiHelloControllerTs.ts +2 -1
- package/src/cli/assets/biomeJson.ts +2 -1
- package/src/cli/assets/claudeMd.ts +9 -4
- package/src/cli/assets/dummySpecTs.ts +2 -1
- package/src/cli/assets/editorconfig.ts +2 -1
- package/src/cli/assets/mainBrowserTs.ts +2 -1
- package/src/cli/assets/mainCss.ts +24 -0
- package/src/cli/assets/tsconfigJson.ts +2 -1
- package/src/cli/assets/webAppRouterTs.ts +2 -1
- package/src/cli/assets/webHelloComponentTsx.ts +6 -2
- 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 +63 -47
- package/src/cli/commands/dev.ts +16 -33
- package/src/cli/commands/gen/env.ts +1 -1
- package/src/cli/commands/init.ts +17 -8
- package/src/cli/commands/lint.ts +1 -1
- 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 +33 -2
- package/src/cli/services/PackageManagerUtils.ts +13 -6
- package/src/cli/services/ProjectScaffolder.ts +72 -49
- package/src/core/Alepha.ts +2 -8
- package/src/core/primitives/$module.ts +12 -0
- package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +257 -0
- package/src/core/providers/KeylessJsonSchemaCodec.ts +396 -14
- package/src/core/providers/SchemaValidator.spec.ts +236 -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/providers/DrizzleKitProvider.ts +3 -5
- package/src/orm/services/Repository.ts +11 -0
- 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 +71 -22
- package/src/server/core/providers/ServerLoggerProvider.ts +2 -2
- package/src/server/core/providers/ServerProvider.ts +9 -12
- package/src/server/links/atoms/apiLinksAtom.ts +7 -0
- package/src/server/links/index.browser.ts +2 -0
- package/src/server/links/index.ts +2 -0
- package/src/vite/index.ts +3 -2
- package/src/vite/tasks/buildClient.ts +0 -1
- package/src/vite/tasks/buildServer.ts +68 -21
- package/src/vite/tasks/copyAssets.ts +5 -4
- 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/src/cli/assets/indexHtml.ts +0 -15
- package/src/cli/commands/format.ts +0 -23
- package/src/vite/helpers/boot.ts +0 -117
- package/src/vite/plugins/viteAlephaDev.ts +0 -177
- package/src/vite/tasks/devServer.ts +0 -71
- package/src/vite/tasks/runAlepha.ts +0 -270
- /package/dist/orm/{chunk-DtkW-qnP.js → chunk-DH6iiROE.js} +0 -0
|
@@ -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;
|
|
@@ -395,6 +396,64 @@ var JsonSchemaCodec = class extends SchemaCodec {
|
|
|
395
396
|
}
|
|
396
397
|
};
|
|
397
398
|
|
|
399
|
+
//#endregion
|
|
400
|
+
//#region ../../src/core/primitives/$hook.ts
|
|
401
|
+
/**
|
|
402
|
+
* Registers a new hook.
|
|
403
|
+
*
|
|
404
|
+
* ```ts
|
|
405
|
+
* import { $hook } from "alepha";
|
|
406
|
+
*
|
|
407
|
+
* class MyProvider {
|
|
408
|
+
* onStart = $hook({
|
|
409
|
+
* name: "start", // or "configure", "ready", "stop", ...
|
|
410
|
+
* handler: async (app) => {
|
|
411
|
+
* // await db.connect(); ...
|
|
412
|
+
* }
|
|
413
|
+
* });
|
|
414
|
+
* }
|
|
415
|
+
* ```
|
|
416
|
+
*
|
|
417
|
+
* Hooks are used to run async functions from all registered providers/services.
|
|
418
|
+
*
|
|
419
|
+
* You can't register a hook after the App has started.
|
|
420
|
+
*
|
|
421
|
+
* It's used under the hood by the `configure`, `start`, and `stop` methods.
|
|
422
|
+
* Some modules also use hooks to run their own logic. (e.g. `alepha/server`).
|
|
423
|
+
*
|
|
424
|
+
* You can create your own hooks by using module augmentation:
|
|
425
|
+
*
|
|
426
|
+
* ```ts
|
|
427
|
+
* declare module "alepha" {
|
|
428
|
+
*
|
|
429
|
+
* interface Hooks {
|
|
430
|
+
* "my:custom:hook": {
|
|
431
|
+
* arg1: string;
|
|
432
|
+
* }
|
|
433
|
+
* }
|
|
434
|
+
* }
|
|
435
|
+
*
|
|
436
|
+
* await alepha.events.emit("my:custom:hook", { arg1: "value" });
|
|
437
|
+
* ```
|
|
438
|
+
*
|
|
439
|
+
*/
|
|
440
|
+
const $hook = (options) => createPrimitive(HookPrimitive, options);
|
|
441
|
+
var HookPrimitive = class extends Primitive {
|
|
442
|
+
called = 0;
|
|
443
|
+
onInit() {
|
|
444
|
+
const handler = this.options.handler;
|
|
445
|
+
this.alepha.events.on(this.options.on, {
|
|
446
|
+
caller: this.config.service,
|
|
447
|
+
priority: this.options.priority,
|
|
448
|
+
callback: (args) => {
|
|
449
|
+
this.called += 1;
|
|
450
|
+
return handler(args);
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
$hook[KIND] = HookPrimitive;
|
|
456
|
+
|
|
398
457
|
//#endregion
|
|
399
458
|
//#region ../../src/core/helpers/FileLike.ts
|
|
400
459
|
const isTypeFile = (value) => {
|
|
@@ -831,22 +890,49 @@ const t = new TypeProvider();
|
|
|
831
890
|
|
|
832
891
|
//#endregion
|
|
833
892
|
//#region ../../src/core/providers/KeylessJsonSchemaCodec.ts
|
|
893
|
+
const UNSAFE_KEYS = new Set([
|
|
894
|
+
"__proto__",
|
|
895
|
+
"constructor",
|
|
896
|
+
"prototype"
|
|
897
|
+
]);
|
|
834
898
|
/**
|
|
835
899
|
* KeylessJsonSchemaCodec provides schema-driven JSON encoding without keys.
|
|
836
900
|
*
|
|
837
901
|
* It uses the schema to determine field order, allowing the encoded output
|
|
838
902
|
* to be a simple JSON array instead of an object with keys.
|
|
839
|
-
*
|
|
840
|
-
* Performance characteristics:
|
|
841
|
-
* - Encode: 0.94-1.53x vs JSON.stringify (faster for complex objects)
|
|
842
|
-
* - Decode: 1.76-2.00x vs JSON.parse
|
|
843
|
-
* - Size: 50-56% smaller than JSON
|
|
844
903
|
*/
|
|
845
904
|
var KeylessJsonSchemaCodec = class extends SchemaCodec {
|
|
846
905
|
cache = /* @__PURE__ */ new Map();
|
|
847
|
-
|
|
848
|
-
|
|
906
|
+
textEncoder = new TextEncoder();
|
|
907
|
+
textDecoder = new TextDecoder();
|
|
849
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
|
+
});
|
|
850
936
|
/**
|
|
851
937
|
* Encode value to a keyless JSON string.
|
|
852
938
|
*/
|
|
@@ -857,14 +943,14 @@ var KeylessJsonSchemaCodec = class extends SchemaCodec {
|
|
|
857
943
|
* Encode value to binary (UTF-8 encoded keyless JSON).
|
|
858
944
|
*/
|
|
859
945
|
encodeToBinary(schema, value) {
|
|
860
|
-
return this.
|
|
946
|
+
return this.textEncoder.encode(this.encodeToString(schema, value));
|
|
861
947
|
}
|
|
862
948
|
/**
|
|
863
949
|
* Decode keyless JSON string or binary to value.
|
|
864
950
|
*/
|
|
865
951
|
decode(schema, value) {
|
|
866
952
|
if (value instanceof Uint8Array) {
|
|
867
|
-
const text = this.
|
|
953
|
+
const text = this.textDecoder.decode(value);
|
|
868
954
|
return this.getCodec(schema).decode(text);
|
|
869
955
|
}
|
|
870
956
|
if (typeof value === "string") return this.getCodec(schema).decode(value);
|
|
@@ -872,13 +958,54 @@ var KeylessJsonSchemaCodec = class extends SchemaCodec {
|
|
|
872
958
|
return value;
|
|
873
959
|
}
|
|
874
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
|
+
/**
|
|
875
1002
|
* Get a compiled codec for the given schema.
|
|
876
1003
|
* Codecs are cached for reuse.
|
|
877
1004
|
*/
|
|
878
1005
|
getCodec(schema) {
|
|
879
1006
|
let c = this.cache.get(schema);
|
|
880
1007
|
if (!c) {
|
|
881
|
-
c = this.
|
|
1008
|
+
c = this.useFunctionCompilation ? this.compileWithFunction(schema) : this.compileInterpreted(schema);
|
|
882
1009
|
this.cache.set(schema, c);
|
|
883
1010
|
}
|
|
884
1011
|
return c;
|
|
@@ -886,7 +1013,11 @@ var KeylessJsonSchemaCodec = class extends SchemaCodec {
|
|
|
886
1013
|
nextVar() {
|
|
887
1014
|
return `_${this.varCounter++}`;
|
|
888
1015
|
}
|
|
889
|
-
|
|
1016
|
+
/**
|
|
1017
|
+
* Compile codec using `new Function()` for maximum performance.
|
|
1018
|
+
* Only used when CSP allows and useFunctionCompilation is true.
|
|
1019
|
+
*/
|
|
1020
|
+
compileWithFunction(schema) {
|
|
890
1021
|
this.varCounter = 0;
|
|
891
1022
|
const encBody = this.genEnc(schema, "v");
|
|
892
1023
|
this.varCounter = 0;
|
|
@@ -896,6 +1027,122 @@ var KeylessJsonSchemaCodec = class extends SchemaCodec {
|
|
|
896
1027
|
decode: new Function("s", `const a=JSON.parse(s);let i=0;${decBody.code}return ${decBody.result};`)
|
|
897
1028
|
};
|
|
898
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
|
+
}
|
|
899
1146
|
genEnc(schema, ve) {
|
|
900
1147
|
if (t.schema.isString(schema) || t.schema.isNumber(schema) || t.schema.isInteger(schema) || t.schema.isBoolean(schema) || this.isEnum(schema)) return ve;
|
|
901
1148
|
if (t.schema.isBigInt(schema)) return `${ve}+'n'`;
|
|
@@ -1087,64 +1334,6 @@ var TypeBoxError = class extends AlephaError {
|
|
|
1087
1334
|
}
|
|
1088
1335
|
};
|
|
1089
1336
|
|
|
1090
|
-
//#endregion
|
|
1091
|
-
//#region ../../src/core/primitives/$hook.ts
|
|
1092
|
-
/**
|
|
1093
|
-
* Registers a new hook.
|
|
1094
|
-
*
|
|
1095
|
-
* ```ts
|
|
1096
|
-
* import { $hook } from "alepha";
|
|
1097
|
-
*
|
|
1098
|
-
* class MyProvider {
|
|
1099
|
-
* onStart = $hook({
|
|
1100
|
-
* name: "start", // or "configure", "ready", "stop", ...
|
|
1101
|
-
* handler: async (app) => {
|
|
1102
|
-
* // await db.connect(); ...
|
|
1103
|
-
* }
|
|
1104
|
-
* });
|
|
1105
|
-
* }
|
|
1106
|
-
* ```
|
|
1107
|
-
*
|
|
1108
|
-
* Hooks are used to run async functions from all registered providers/services.
|
|
1109
|
-
*
|
|
1110
|
-
* You can't register a hook after the App has started.
|
|
1111
|
-
*
|
|
1112
|
-
* It's used under the hood by the `configure`, `start`, and `stop` methods.
|
|
1113
|
-
* Some modules also use hooks to run their own logic. (e.g. `alepha/server`).
|
|
1114
|
-
*
|
|
1115
|
-
* You can create your own hooks by using module augmentation:
|
|
1116
|
-
*
|
|
1117
|
-
* ```ts
|
|
1118
|
-
* declare module "alepha" {
|
|
1119
|
-
*
|
|
1120
|
-
* interface Hooks {
|
|
1121
|
-
* "my:custom:hook": {
|
|
1122
|
-
* arg1: string;
|
|
1123
|
-
* }
|
|
1124
|
-
* }
|
|
1125
|
-
* }
|
|
1126
|
-
*
|
|
1127
|
-
* await alepha.events.emit("my:custom:hook", { arg1: "value" });
|
|
1128
|
-
* ```
|
|
1129
|
-
*
|
|
1130
|
-
*/
|
|
1131
|
-
const $hook = (options) => createPrimitive(HookPrimitive, options);
|
|
1132
|
-
var HookPrimitive = class extends Primitive {
|
|
1133
|
-
called = 0;
|
|
1134
|
-
onInit() {
|
|
1135
|
-
const handler = this.options.handler;
|
|
1136
|
-
this.alepha.events.on(this.options.on, {
|
|
1137
|
-
caller: this.config.service,
|
|
1138
|
-
priority: this.options.priority,
|
|
1139
|
-
callback: (args) => {
|
|
1140
|
-
this.called += 1;
|
|
1141
|
-
return handler(args);
|
|
1142
|
-
}
|
|
1143
|
-
});
|
|
1144
|
-
}
|
|
1145
|
-
};
|
|
1146
|
-
$hook[KIND] = HookPrimitive;
|
|
1147
|
-
|
|
1148
1337
|
//#endregion
|
|
1149
1338
|
//#region ../../src/core/providers/SchemaValidator.ts
|
|
1150
1339
|
var SchemaValidator = class {
|
|
@@ -1724,13 +1913,10 @@ var Alepha = class Alepha {
|
|
|
1724
1913
|
* If you are not interested about these helpers, you can use the constructor directly.
|
|
1725
1914
|
*/
|
|
1726
1915
|
static create(state = {}) {
|
|
1727
|
-
if (typeof process === "object" && typeof process.env === "object") {
|
|
1728
|
-
state.env
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
};
|
|
1732
|
-
for (const key in state.env) if (state.env[key] === "") delete state.env[key];
|
|
1733
|
-
}
|
|
1916
|
+
if (typeof process === "object" && typeof process.env === "object") state.env = {
|
|
1917
|
+
...state.env,
|
|
1918
|
+
...process.env
|
|
1919
|
+
};
|
|
1734
1920
|
const alepha = new Alepha(state);
|
|
1735
1921
|
if (alepha.isTest()) {
|
|
1736
1922
|
const g = globalThis;
|
|
@@ -2088,7 +2274,10 @@ var Alepha = class Alepha {
|
|
|
2088
2274
|
if (!match.parents.includes(parent) && parent !== service) match.parents.push(parent);
|
|
2089
2275
|
return match.instance;
|
|
2090
2276
|
}
|
|
2091
|
-
if (this.started)
|
|
2277
|
+
if (this.started) {
|
|
2278
|
+
const mod = service[MODULE]?.name;
|
|
2279
|
+
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.` : ""}`);
|
|
2280
|
+
}
|
|
2092
2281
|
}
|
|
2093
2282
|
const module = service[MODULE];
|
|
2094
2283
|
if (module && typeof module === "function") this.with(module);
|
|
@@ -2104,10 +2293,10 @@ var Alepha = class Alepha {
|
|
|
2104
2293
|
if (!transient) registry.set(service, definition);
|
|
2105
2294
|
if (instance instanceof Module) {
|
|
2106
2295
|
this.modules.push(instance);
|
|
2107
|
-
const parent
|
|
2296
|
+
const parent = __alephaRef.parent;
|
|
2108
2297
|
__alephaRef.parent = instance.constructor;
|
|
2109
2298
|
instance.register(this);
|
|
2110
|
-
__alephaRef.parent = parent
|
|
2299
|
+
__alephaRef.parent = parent;
|
|
2111
2300
|
}
|
|
2112
2301
|
return instance;
|
|
2113
2302
|
}
|