@scpxl/nodejs-framework 1.0.25 → 1.0.27

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.
@@ -1,18 +1,32 @@
1
1
  import { BaseEntity } from '@mikro-orm/core';
2
2
  import { z } from 'zod';
3
3
  export declare abstract class DynamicEntity extends BaseEntity {
4
- static schema: z.ZodSchema;
5
- static schemaUpdate: z.ZodSchema;
4
+ /** Required fields for creating a new entity */
5
+ static createSchema: z.ZodSchema;
6
+ /** Allowed (partial) fields for updating an entity */
7
+ static updateSchema: z.ZodSchema;
8
+ /** Optional projection/read schema (includes persistence augment) */
9
+ static readSchema?: z.ZodSchema;
6
10
  static get singularName(): string;
7
11
  static get pluralName(): string;
8
12
  static get singularNameLowerCase(): string;
9
13
  static get pluralNameLowerCase(): string;
10
14
  static get singularNameCapitalized(): string;
11
15
  static get pluralNameCapitalized(): string;
12
- static validate<T>(item: T, isCreating: boolean): {
16
+ static validateCreate<T>(item: unknown): {
17
+ error?: Error;
18
+ value?: T;
19
+ };
20
+ static validateUpdate<T>(item: unknown): {
13
21
  error?: Error;
14
22
  value?: T;
15
23
  };
16
24
  static getSearchFields(): string[];
25
+ static defineSchemas<Shape extends z.ZodRawShape, Updatable extends readonly (keyof Shape)[]>(options: {
26
+ shape: Shape;
27
+ updatableFields?: Updatable;
28
+ requireAtLeastOneOnUpdate?: boolean;
29
+ readAugment?: z.ZodRawShape;
30
+ }): void;
17
31
  }
18
32
  //# sourceMappingURL=dynamic-entity.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic-entity.d.ts","sourceRoot":"","sources":["../../src/database/dynamic-entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,8BAAsB,aAAc,SAAQ,UAAU;IACpD,OAAc,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC;IAClC,OAAc,YAAY,EAAE,CAAC,CAAC,SAAS,CAAC;IAExC,WAAkB,YAAY,IAAI,MAAM,CAEvC;IAED,WAAkB,UAAU,IAAI,MAAM,CAErC;IAED,WAAkB,qBAAqB,IAAI,MAAM,CAEhD;IAED,WAAkB,mBAAmB,IAAI,MAAM,CAE9C;IAED,WAAkB,uBAAuB,IAAI,MAAM,CAElD;IAED,WAAkB,qBAAqB,IAAI,MAAM,CAEhD;WAEa,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,OAAO,GAAG;QAAE,KAAK,CAAC,EAAE,KAAK,CAAC;QAAC,KAAK,CAAC,EAAE,CAAC,CAAA;KAAE;WAuBvE,eAAe,IAAI,MAAM,EAAE;CAG1C"}
1
+ {"version":3,"file":"dynamic-entity.d.ts","sourceRoot":"","sources":["../../src/database/dynamic-entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,8BAAsB,aAAc,SAAQ,UAAU;IACpD,gDAAgD;IAChD,OAAc,YAAY,EAAE,CAAC,CAAC,SAAS,CAAC;IACxC,sDAAsD;IACtD,OAAc,YAAY,EAAE,CAAC,CAAC,SAAS,CAAC;IACxC,qEAAqE;IACrE,OAAc,UAAU,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IAEvC,WAAkB,YAAY,IAAI,MAAM,CAEvC;IAED,WAAkB,UAAU,IAAI,MAAM,CAErC;IAED,WAAkB,qBAAqB,IAAI,MAAM,CAEhD;IAED,WAAkB,mBAAmB,IAAI,MAAM,CAE9C;IAED,WAAkB,uBAAuB,IAAI,MAAM,CAElD;IAED,WAAkB,qBAAqB,IAAI,MAAM,CAEhD;WAEa,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,GAAG;QAAE,KAAK,CAAC,EAAE,KAAK,CAAC;QAAC,KAAK,CAAC,EAAE,CAAC,CAAA;KAAE;WAW9D,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,GAAG;QAAE,KAAK,CAAC,EAAE,KAAK,CAAC;QAAC,KAAK,CAAC,EAAE,CAAC,CAAA;KAAE;WAW9D,eAAe,IAAI,MAAM,EAAE;WAI3B,aAAa,CAAC,KAAK,SAAS,CAAC,CAAC,WAAW,EAAE,SAAS,SAAS,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE;QAC5G,KAAK,EAAE,KAAK,CAAC;QACb,eAAe,CAAC,EAAE,SAAS,CAAC;QAC5B,yBAAyB,CAAC,EAAE,OAAO,CAAC;QACpC,WAAW,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC;KAC7B,GAAG,IAAI;CAcT"}
@@ -2,12 +2,17 @@ var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
3
  import { BaseEntity } from "@mikro-orm/core";
4
4
  import { z } from "zod";
5
+ import { buildEntitySchemas } from "../schemas/entity-builder.js";
5
6
  class DynamicEntity extends BaseEntity {
6
7
  static {
7
8
  __name(this, "DynamicEntity");
8
9
  }
9
- static schema;
10
- static schemaUpdate;
10
+ /** Required fields for creating a new entity */
11
+ static createSchema;
12
+ /** Allowed (partial) fields for updating an entity */
13
+ static updateSchema;
14
+ /** Optional projection/read schema (includes persistence augment) */
15
+ static readSchema;
11
16
  static get singularName() {
12
17
  return "Item";
13
18
  }
@@ -26,22 +31,22 @@ class DynamicEntity extends BaseEntity {
26
31
  static get pluralNameCapitalized() {
27
32
  return this.pluralName.charAt(0).toUpperCase() + this.pluralName.slice(1).toLowerCase();
28
33
  }
29
- static validate(item, isCreating) {
30
- const schemaName = isCreating ? "schema" : "schemaUpdate";
31
- if (!["schema", "schemaUpdate"].includes(schemaName)) {
32
- throw new Error("Invalid schema reference");
33
- }
34
- const selectedSchema = schemaName === "schema" ? this.schema : this.schemaUpdate;
35
- if (!selectedSchema) {
36
- throw new Error("Schema not defined in entity.");
34
+ static validateCreate(item) {
35
+ try {
36
+ return { value: this.createSchema.parse(item) };
37
+ } catch (err) {
38
+ if (err instanceof z.ZodError) {
39
+ return { error: new Error(err.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join(", ")) };
40
+ }
41
+ return { error: err };
37
42
  }
43
+ }
44
+ static validateUpdate(item) {
38
45
  try {
39
- const value = selectedSchema.parse(item);
40
- return { value };
46
+ return { value: this.updateSchema.parse(item) };
41
47
  } catch (err) {
42
48
  if (err instanceof z.ZodError) {
43
- const error = new Error(err.issues.map((e) => `${e.path.join(".")}: ${e.message}`).join(", "));
44
- return { error };
49
+ return { error: new Error(err.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join(", ")) };
45
50
  }
46
51
  return { error: err };
47
52
  }
@@ -49,6 +54,20 @@ class DynamicEntity extends BaseEntity {
49
54
  static getSearchFields() {
50
55
  return [];
51
56
  }
57
+ static defineSchemas(options) {
58
+ const { shape, updatableFields, requireAtLeastOneOnUpdate = true, readAugment } = options;
59
+ const schemas = buildEntitySchemas({
60
+ shape,
61
+ updatableFields,
62
+ requireAtLeastOneOnUpdate,
63
+ readAugment
64
+ });
65
+ this.createSchema = schemas.create;
66
+ this.updateSchema = schemas.update;
67
+ if (readAugment) {
68
+ this.readSchema = schemas.read;
69
+ }
70
+ }
52
71
  }
53
72
  export {
54
73
  DynamicEntity
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/database/dynamic-entity.ts"],
4
- "sourcesContent": ["import { BaseEntity } from '@mikro-orm/core';\nimport { z } from 'zod';\n\nexport abstract class DynamicEntity extends BaseEntity {\n public static schema: z.ZodSchema;\n public static schemaUpdate: z.ZodSchema;\n\n public static get singularName(): string {\n return 'Item';\n }\n\n public static get pluralName(): string {\n return 'Items';\n }\n\n public static get singularNameLowerCase(): string {\n return this.singularName.toLowerCase();\n }\n\n public static get pluralNameLowerCase(): string {\n return this.pluralName.toLowerCase();\n }\n\n public static get singularNameCapitalized(): string {\n return this.singularName.charAt(0).toUpperCase() + this.singularName.slice(1).toLowerCase();\n }\n\n public static get pluralNameCapitalized(): string {\n return this.pluralName.charAt(0).toUpperCase() + this.pluralName.slice(1).toLowerCase();\n }\n\n public static validate<T>(item: T, isCreating: boolean): { error?: Error; value?: T } {\n const schemaName = isCreating ? 'schema' : 'schemaUpdate';\n // Explicit whitelist of schema properties to prevent object injection\n if (!['schema', 'schemaUpdate'].includes(schemaName)) {\n throw new Error('Invalid schema reference');\n }\n const selectedSchema: z.ZodSchema | undefined = schemaName === 'schema' ? this.schema : this.schemaUpdate;\n if (!selectedSchema) {\n throw new Error('Schema not defined in entity.');\n }\n\n try {\n const value = selectedSchema.parse(item);\n return { value: value as T };\n } catch (err) {\n if (err instanceof z.ZodError) {\n const error = new Error(err.issues.map((e: z.ZodIssue) => `${e.path.join('.')}: ${e.message}`).join(', '));\n return { error };\n }\n return { error: err as Error };\n }\n }\n\n public static getSearchFields(): string[] {\n return [];\n }\n}\n"],
5
- "mappings": ";;AAAA,SAAS,kBAAkB;AAC3B,SAAS,SAAS;AAEX,MAAe,sBAAsB,WAAW;AAAA,EAHvD,OAGuD;AAAA;AAAA;AAAA,EACrD,OAAc;AAAA,EACd,OAAc;AAAA,EAEd,WAAkB,eAAuB;AACvC,WAAO;AAAA,EACT;AAAA,EAEA,WAAkB,aAAqB;AACrC,WAAO;AAAA,EACT;AAAA,EAEA,WAAkB,wBAAgC;AAChD,WAAO,KAAK,aAAa,YAAY;AAAA,EACvC;AAAA,EAEA,WAAkB,sBAA8B;AAC9C,WAAO,KAAK,WAAW,YAAY;AAAA,EACrC;AAAA,EAEA,WAAkB,0BAAkC;AAClD,WAAO,KAAK,aAAa,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,aAAa,MAAM,CAAC,EAAE,YAAY;AAAA,EAC5F;AAAA,EAEA,WAAkB,wBAAgC;AAChD,WAAO,KAAK,WAAW,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,WAAW,MAAM,CAAC,EAAE,YAAY;AAAA,EACxF;AAAA,EAEA,OAAc,SAAY,MAAS,YAAmD;AACpF,UAAM,aAAa,aAAa,WAAW;AAE3C,QAAI,CAAC,CAAC,UAAU,cAAc,EAAE,SAAS,UAAU,GAAG;AACpD,YAAM,IAAI,MAAM,0BAA0B;AAAA,IAC5C;AACA,UAAM,iBAA0C,eAAe,WAAW,KAAK,SAAS,KAAK;AAC7F,QAAI,CAAC,gBAAgB;AACnB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AAEA,QAAI;AACF,YAAM,QAAQ,eAAe,MAAM,IAAI;AACvC,aAAO,EAAE,MAAkB;AAAA,IAC7B,SAAS,KAAK;AACZ,UAAI,eAAe,EAAE,UAAU;AAC7B,cAAM,QAAQ,IAAI,MAAM,IAAI,OAAO,IAAI,CAAC,MAAkB,GAAG,EAAE,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI,CAAC;AACzG,eAAO,EAAE,MAAM;AAAA,MACjB;AACA,aAAO,EAAE,OAAO,IAAa;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,OAAc,kBAA4B;AACxC,WAAO,CAAC;AAAA,EACV;AACF;",
4
+ "sourcesContent": ["import { BaseEntity } from '@mikro-orm/core';\nimport { z } from 'zod';\nimport { buildEntitySchemas } from '../schemas/entity-builder.js';\n\nexport abstract class DynamicEntity extends BaseEntity {\n /** Required fields for creating a new entity */\n public static createSchema: z.ZodSchema;\n /** Allowed (partial) fields for updating an entity */\n public static updateSchema: z.ZodSchema;\n /** Optional projection/read schema (includes persistence augment) */\n public static readSchema?: z.ZodSchema;\n\n public static get singularName(): string {\n return 'Item';\n }\n\n public static get pluralName(): string {\n return 'Items';\n }\n\n public static get singularNameLowerCase(): string {\n return this.singularName.toLowerCase();\n }\n\n public static get pluralNameLowerCase(): string {\n return this.pluralName.toLowerCase();\n }\n\n public static get singularNameCapitalized(): string {\n return this.singularName.charAt(0).toUpperCase() + this.singularName.slice(1).toLowerCase();\n }\n\n public static get pluralNameCapitalized(): string {\n return this.pluralName.charAt(0).toUpperCase() + this.pluralName.slice(1).toLowerCase();\n }\n\n public static validateCreate<T>(item: unknown): { error?: Error; value?: T } {\n try {\n return { value: this.createSchema.parse(item) as T };\n } catch (err) {\n if (err instanceof z.ZodError) {\n return { error: new Error(err.issues.map(i => `${i.path.join('.')}: ${i.message}`).join(', ')) };\n }\n return { error: err as Error };\n }\n }\n\n public static validateUpdate<T>(item: unknown): { error?: Error; value?: T } {\n try {\n return { value: this.updateSchema.parse(item) as T };\n } catch (err) {\n if (err instanceof z.ZodError) {\n return { error: new Error(err.issues.map(i => `${i.path.join('.')}: ${i.message}`).join(', ')) };\n }\n return { error: err as Error };\n }\n }\n\n public static getSearchFields(): string[] {\n return [];\n }\n\n public static defineSchemas<Shape extends z.ZodRawShape, Updatable extends readonly (keyof Shape)[]>(options: {\n shape: Shape;\n updatableFields?: Updatable;\n requireAtLeastOneOnUpdate?: boolean;\n readAugment?: z.ZodRawShape;\n }): void {\n const { shape, updatableFields, requireAtLeastOneOnUpdate = true, readAugment } = options;\n const schemas = buildEntitySchemas({\n shape,\n updatableFields: updatableFields as any,\n requireAtLeastOneOnUpdate,\n readAugment,\n });\n this.createSchema = schemas.create;\n this.updateSchema = schemas.update;\n if (readAugment) {\n this.readSchema = schemas.read;\n }\n }\n}\n"],
5
+ "mappings": ";;AAAA,SAAS,kBAAkB;AAC3B,SAAS,SAAS;AAClB,SAAS,0BAA0B;AAE5B,MAAe,sBAAsB,WAAW;AAAA,EAJvD,OAIuD;AAAA;AAAA;AAAA;AAAA,EAErD,OAAc;AAAA;AAAA,EAEd,OAAc;AAAA;AAAA,EAEd,OAAc;AAAA,EAEd,WAAkB,eAAuB;AACvC,WAAO;AAAA,EACT;AAAA,EAEA,WAAkB,aAAqB;AACrC,WAAO;AAAA,EACT;AAAA,EAEA,WAAkB,wBAAgC;AAChD,WAAO,KAAK,aAAa,YAAY;AAAA,EACvC;AAAA,EAEA,WAAkB,sBAA8B;AAC9C,WAAO,KAAK,WAAW,YAAY;AAAA,EACrC;AAAA,EAEA,WAAkB,0BAAkC;AAClD,WAAO,KAAK,aAAa,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,aAAa,MAAM,CAAC,EAAE,YAAY;AAAA,EAC5F;AAAA,EAEA,WAAkB,wBAAgC;AAChD,WAAO,KAAK,WAAW,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,WAAW,MAAM,CAAC,EAAE,YAAY;AAAA,EACxF;AAAA,EAEA,OAAc,eAAkB,MAA6C;AAC3E,QAAI;AACF,aAAO,EAAE,OAAO,KAAK,aAAa,MAAM,IAAI,EAAO;AAAA,IACrD,SAAS,KAAK;AACZ,UAAI,eAAe,EAAE,UAAU;AAC7B,eAAO,EAAE,OAAO,IAAI,MAAM,IAAI,OAAO,IAAI,OAAK,GAAG,EAAE,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,MACjG;AACA,aAAO,EAAE,OAAO,IAAa;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,OAAc,eAAkB,MAA6C;AAC3E,QAAI;AACF,aAAO,EAAE,OAAO,KAAK,aAAa,MAAM,IAAI,EAAO;AAAA,IACrD,SAAS,KAAK;AACZ,UAAI,eAAe,EAAE,UAAU;AAC7B,eAAO,EAAE,OAAO,IAAI,MAAM,IAAI,OAAO,IAAI,OAAK,GAAG,EAAE,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,MACjG;AACA,aAAO,EAAE,OAAO,IAAa;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,OAAc,kBAA4B;AACxC,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,OAAc,cAAuF,SAK5F;AACP,UAAM,EAAE,OAAO,iBAAiB,4BAA4B,MAAM,YAAY,IAAI;AAClF,UAAM,UAAU,mBAAmB;AAAA,MACjC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,SAAK,eAAe,QAAQ;AAC5B,SAAK,eAAe,QAAQ;AAC5B,QAAI,aAAa;AACf,WAAK,aAAa,QAAQ;AAAA,IAC5B;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Options for building standardized entity schemas.
4
+ * - shape: base create shape (required fields for creation)
5
+ * - updatableFields: subset of keys allowed in updates (defaults to all keys of shape)
6
+ * - readAugment: additional fields present on the persisted/read model (e.g. id, timestamps)
7
+ * - strict: apply .strict() to objects (defaults true)
8
+ */
9
+ export interface BuildEntitySchemasOptions<Shape extends z.ZodRawShape, Updatable extends keyof Shape = keyof Shape, ReadAugment extends z.ZodRawShape = {}> {
10
+ shape: Shape;
11
+ updatableFields?: readonly Updatable[];
12
+ readAugment?: ReadAugment;
13
+ strict?: boolean;
14
+ requireAtLeastOneOnUpdate?: boolean;
15
+ }
16
+ export interface BuiltEntitySchemas<Shape extends z.ZodRawShape, Updatable extends keyof Shape, ReadAugment extends z.ZodRawShape> {
17
+ create: z.ZodObject<Shape>;
18
+ /** Update schema is a partial over selected updatable keys. */
19
+ update: z.ZodTypeAny;
20
+ read: z.ZodObject<Shape & ReadAugment>;
21
+ keys: (keyof Shape)[];
22
+ updatableKeys: Updatable[];
23
+ }
24
+ export declare function buildEntitySchemas<Shape extends z.ZodRawShape, Updatable extends keyof Shape = keyof Shape, ReadAugment extends z.ZodRawShape = {}>(options: BuildEntitySchemasOptions<Shape, Updatable, ReadAugment>): BuiltEntitySchemas<Shape, Updatable, ReadAugment>;
25
+ export declare const HttpMethodSchema: z.ZodEnum<{
26
+ GET: "GET";
27
+ POST: "POST";
28
+ PUT: "PUT";
29
+ DELETE: "DELETE";
30
+ HEAD: "HEAD";
31
+ PATCH: "PATCH";
32
+ OPTIONS: "OPTIONS";
33
+ }>;
34
+ export declare const HttpStatusCodeSchema: z.core.$ZodBranded<z.ZodNumber, "HttpStatusCode">;
35
+ //# sourceMappingURL=entity-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-builder.d.ts","sourceRoot":"","sources":["../../src/schemas/entity-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB,CACxC,KAAK,SAAS,CAAC,CAAC,WAAW,EAC3B,SAAS,SAAS,MAAM,KAAK,GAAG,MAAM,KAAK,EAC3C,WAAW,SAAS,CAAC,CAAC,WAAW,GAAG,EAAE;IAEtC,KAAK,EAAE,KAAK,CAAC;IACb,eAAe,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IACvC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB,CACjC,KAAK,SAAS,CAAC,CAAC,WAAW,EAC3B,SAAS,SAAS,MAAM,KAAK,EAC7B,WAAW,SAAS,CAAC,CAAC,WAAW;IAEjC,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC3B,+DAA+D;IAC/D,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC;IACrB,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,GAAG,WAAW,CAAC,CAAC;IACvC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IACtB,aAAa,EAAE,SAAS,EAAE,CAAC;CAC5B;AAED,wBAAgB,kBAAkB,CAChC,KAAK,SAAS,CAAC,CAAC,WAAW,EAC3B,SAAS,SAAS,MAAM,KAAK,GAAG,MAAM,KAAK,EAC3C,WAAW,SAAS,CAAC,CAAC,WAAW,GAAG,EAAE,EAEtC,OAAO,EAAE,yBAAyB,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,CAAC,GAChE,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,CAAC,CAoCnD;AAGD,eAAO,MAAM,gBAAgB;;;;;;;;EAAuE,CAAC;AACrG,eAAO,MAAM,oBAAoB,mDAA+D,CAAC"}
@@ -0,0 +1,39 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+ import { z } from "zod";
4
+ function buildEntitySchemas(options) {
5
+ const { shape, updatableFields, readAugment, strict = true, requireAtLeastOneOnUpdate = true } = options;
6
+ Object.freeze(shape);
7
+ const create = strict ? z.object(shape).strict() : z.object(shape);
8
+ const updatableKeys = updatableFields ? [...updatableFields] : Object.keys(shape);
9
+ const pickMask = updatableKeys.reduce((acc, key) => {
10
+ acc[String(key)] = true;
11
+ return acc;
12
+ }, {});
13
+ const updateBase = updatableFields ? create.pick(pickMask) : create;
14
+ let updateObject = updateBase.partial();
15
+ if (requireAtLeastOneOnUpdate) {
16
+ updateObject = updateObject.refine(
17
+ (value) => !!value && typeof value === "object" && Object.keys(value).length > 0,
18
+ "At least one field must be provided for update"
19
+ );
20
+ }
21
+ const readShape = { ...shape, ...readAugment ?? {} };
22
+ const read = strict ? z.object(readShape).strict() : z.object(readShape);
23
+ return {
24
+ create,
25
+ update: updateObject,
26
+ read,
27
+ keys: Object.keys(shape),
28
+ updatableKeys
29
+ };
30
+ }
31
+ __name(buildEntitySchemas, "buildEntitySchemas");
32
+ const HttpMethodSchema = z.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]);
33
+ const HttpStatusCodeSchema = z.number().int().min(100).max(599).brand();
34
+ export {
35
+ HttpMethodSchema,
36
+ HttpStatusCodeSchema,
37
+ buildEntitySchemas
38
+ };
39
+ //# sourceMappingURL=entity-builder.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/schemas/entity-builder.ts"],
4
+ "sourcesContent": ["import { z } from 'zod';\n\n/**\n * Options for building standardized entity schemas.\n * - shape: base create shape (required fields for creation)\n * - updatableFields: subset of keys allowed in updates (defaults to all keys of shape)\n * - readAugment: additional fields present on the persisted/read model (e.g. id, timestamps)\n * - strict: apply .strict() to objects (defaults true)\n */\nexport interface BuildEntitySchemasOptions<\n Shape extends z.ZodRawShape,\n Updatable extends keyof Shape = keyof Shape,\n ReadAugment extends z.ZodRawShape = {},\n> {\n shape: Shape;\n updatableFields?: readonly Updatable[];\n readAugment?: ReadAugment; // fields that exist after persistence (e.g. id, createdAt)\n strict?: boolean;\n requireAtLeastOneOnUpdate?: boolean; // default true\n}\n\nexport interface BuiltEntitySchemas<\n Shape extends z.ZodRawShape,\n Updatable extends keyof Shape,\n ReadAugment extends z.ZodRawShape,\n> {\n create: z.ZodObject<Shape>;\n /** Update schema is a partial over selected updatable keys. */\n update: z.ZodTypeAny;\n read: z.ZodObject<Shape & ReadAugment>;\n keys: (keyof Shape)[];\n updatableKeys: Updatable[];\n}\n\nexport function buildEntitySchemas<\n Shape extends z.ZodRawShape,\n Updatable extends keyof Shape = keyof Shape,\n ReadAugment extends z.ZodRawShape = {},\n>(\n options: BuildEntitySchemasOptions<Shape, Updatable, ReadAugment>,\n): BuiltEntitySchemas<Shape, Updatable, ReadAugment> {\n const { shape, updatableFields, readAugment, strict = true, requireAtLeastOneOnUpdate = true } = options;\n\n // Freeze to avoid accidental mutation\n Object.freeze(shape);\n\n const create = strict ? z.object(shape).strict() : z.object(shape);\n\n const updatableKeys = updatableFields ? [...updatableFields] : (Object.keys(shape) as Updatable[]);\n // Build pick mask for updatable keys\n const pickMask = updatableKeys.reduce<Record<string, true>>((acc, key) => {\n acc[String(key)] = true;\n return acc;\n }, {});\n\n const updateBase = updatableFields ? (create as z.ZodObject<any>).pick(pickMask) : (create as z.ZodObject<any>);\n let updateObject: z.ZodTypeAny = updateBase.partial();\n\n if (requireAtLeastOneOnUpdate) {\n updateObject = updateObject.refine(\n (value: unknown) =>\n !!value && typeof value === 'object' && Object.keys(value as Record<string, unknown>).length > 0,\n 'At least one field must be provided for update',\n );\n }\n\n const readShape = { ...shape, ...(readAugment ?? {}) } as Shape & ReadAugment;\n const read = strict ? z.object(readShape).strict() : z.object(readShape);\n\n return {\n create,\n update: updateObject,\n read: read as z.ZodObject<Shape & ReadAugment>,\n keys: Object.keys(shape) as (keyof Shape)[],\n updatableKeys,\n };\n}\n\n// Common atoms for reuse in entity schemas\nexport const HttpMethodSchema = z.enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS']);\nexport const HttpStatusCodeSchema = z.number().int().min(100).max(599).brand<'HttpStatusCode'>();\n"],
5
+ "mappings": ";;AAAA,SAAS,SAAS;AAkCX,SAAS,mBAKd,SACmD;AACnD,QAAM,EAAE,OAAO,iBAAiB,aAAa,SAAS,MAAM,4BAA4B,KAAK,IAAI;AAGjG,SAAO,OAAO,KAAK;AAEnB,QAAM,SAAS,SAAS,EAAE,OAAO,KAAK,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;AAEjE,QAAM,gBAAgB,kBAAkB,CAAC,GAAG,eAAe,IAAK,OAAO,KAAK,KAAK;AAEjF,QAAM,WAAW,cAAc,OAA6B,CAAC,KAAK,QAAQ;AACxE,QAAI,OAAO,GAAG,CAAC,IAAI;AACnB,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,kBAAmB,OAA4B,KAAK,QAAQ,IAAK;AACpF,MAAI,eAA6B,WAAW,QAAQ;AAEpD,MAAI,2BAA2B;AAC7B,mBAAe,aAAa;AAAA,MAC1B,CAAC,UACC,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,OAAO,KAAK,KAAgC,EAAE,SAAS;AAAA,MACjG;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAY,EAAE,GAAG,OAAO,GAAI,eAAe,CAAC,EAAG;AACrD,QAAM,OAAO,SAAS,EAAE,OAAO,SAAS,EAAE,OAAO,IAAI,EAAE,OAAO,SAAS;AAEvE,SAAO;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA,MAAM,OAAO,KAAK,KAAK;AAAA,IACvB;AAAA,EACF;AACF;AA1CgB;AA6CT,MAAM,mBAAmB,EAAE,KAAK,CAAC,OAAO,QAAQ,OAAO,UAAU,SAAS,QAAQ,SAAS,CAAC;AAC5F,MAAM,uBAAuB,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,IAAI,GAAG,EAAE,MAAwB;",
6
+ "names": []
7
+ }
@@ -288,7 +288,7 @@ class EntityController extends BaseController {
288
288
  request = preCreateOneRequest;
289
289
  }
290
290
  }
291
- const { error, value } = EntityClass.validate(request.body, true);
291
+ const { error, value } = EntityClass.validateCreate(request.body);
292
292
  if (error) {
293
293
  return this.sendErrorResponse({ reply, error: error.message });
294
294
  }
@@ -315,7 +315,7 @@ class EntityController extends BaseController {
315
315
  return;
316
316
  }
317
317
  const id = request.params.id;
318
- const { error, value } = EntityClass.validate(request.body, false);
318
+ const { error, value } = EntityClass.validateUpdate(request.body);
319
319
  if (error) {
320
320
  return this.sendErrorResponse({ reply, error: error.message });
321
321
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/webserver/controller/entity.ts"],
4
- "sourcesContent": ["import 'reflect-metadata';\nimport path from 'path';\nimport type { EntityManager, FilterQuery, Populate } from '@mikro-orm/core';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport { StatusCodes } from 'http-status-codes';\nimport BaseController from './base.js';\nimport type { DynamicEntity } from '../../database/dynamic-entity.js';\nimport { generateFormFields } from '../../database/dynamic-entity-form-decorators.js';\nimport { Helper } from '../../util/index.js';\nimport type { WebServerBaseControllerConstructorParams } from './base.interface.js';\n\nexport default abstract class EntityController extends BaseController {\n protected abstract entityName: string;\n\n protected entityManager: EntityManager;\n\n // Cache for entity modules to avoid repeated dynamic imports\n private static entityCache = new Map<string, typeof DynamicEntity>();\n\n constructor(props: WebServerBaseControllerConstructorParams) {\n super(props);\n\n const { databaseInstance } = props;\n\n this.entityManager = databaseInstance.getEntityManager();\n }\n\n protected getEntity = async (): Promise<typeof DynamicEntity | undefined> => {\n if (!this.applicationConfig.database || this.applicationConfig.database.enabled !== true) {\n throw new Error(`Database not enabled (Entity: ${this.entityName})`);\n }\n\n // Check cache first\n const cacheKey = `${this.applicationConfig.database.entitiesDirectory}:${this.entityName}`;\n if (EntityController.entityCache.has(cacheKey)) {\n return EntityController.entityCache.get(cacheKey);\n }\n\n // Define entity module path\n const entityModulePath = path.join(\n this.applicationConfig.database.entitiesDirectory,\n `${this.entityName}.${Helper.getScriptFileExtension()}`,\n );\n\n // Import entity module\n const entityModule = await import(entityModulePath);\n\n if (!entityModule?.[this.entityName]) {\n throw new Error(`Entity not found (Entity: ${this.entityName})`);\n }\n\n // Get entity class\n const EntityClass = entityModule[this.entityName];\n\n // Cache the entity for future use\n EntityController.entityCache.set(cacheKey, EntityClass);\n\n return EntityClass;\n };\n\n private getEntityProperties(entityClass: any): string[] {\n const properties: string[] = [];\n\n const reservedPropertyKeys = ['constructor', 'toJSON'];\n\n for (const propertyKey of Object.getOwnPropertyNames(entityClass.prototype)) {\n if (propertyKey.startsWith('__')) {\n continue;\n } else if (reservedPropertyKeys.includes(propertyKey)) {\n continue;\n }\n\n properties.push(propertyKey);\n }\n\n return properties;\n }\n\n public options = async (request: FastifyRequest, reply: FastifyReply) => {\n try {\n const EntityClass = await this.getEntity();\n\n if (!EntityClass) {\n this.sendErrorResponse({ reply, error: 'Entity not found' });\n\n return;\n }\n\n const formFields = generateFormFields({ model: EntityClass });\n\n this.sendSuccessResponse({\n reply,\n data: {\n formFields,\n },\n });\n } catch (error) {\n this.sendErrorResponse({ reply, error });\n }\n };\n\n public metadata = async (request: FastifyRequest, reply: FastifyReply) => {\n try {\n const EntityClass = await this.getEntity();\n\n if (!EntityClass) {\n this.sendErrorResponse({ reply, error: 'Entity not found' });\n\n return;\n }\n\n const formFields = generateFormFields({ model: EntityClass });\n\n this.sendSuccessResponse({\n reply,\n data: {\n formFields,\n },\n });\n } catch (error) {\n this.sendErrorResponse({ reply, error });\n }\n };\n\n // Pre-getMany hook (can be overridden in the child controller)\n protected async preGetMany(_: {\n entityManager: EntityManager;\n request: FastifyRequest;\n reply: FastifyReply;\n }): Promise<void> {\n // Default implementation: do nothing\n }\n\n // Post-getMany hook (can be overridden in the child controller)\n // await this.postGetMany({ entityManager: this.entityManager, request, reply, data });\n protected async postGetMany(_: {\n entityManager: EntityManager;\n request: FastifyRequest;\n reply: FastifyReply;\n data: {\n items: any[];\n total: number;\n page: number;\n totalPages: number;\n limit: number;\n };\n }): Promise<void> {\n // Default implementation: do nothing\n }\n\n public getMany = async (\n request: FastifyRequest<{\n Querystring: {\n page: string;\n limit: string;\n filters: string;\n sort: string;\n 'sort-order': string;\n search: string;\n [key: string]: any;\n };\n }>,\n reply: FastifyReply,\n ) => {\n try {\n // Call preGetMany hook\n await this.preGetMany({\n entityManager: this.entityManager,\n request,\n reply,\n });\n\n const EntityClass = await this.getEntity();\n\n if (!EntityClass) {\n this.sendErrorResponse({ reply, error: 'Entity not found' });\n\n return;\n }\n\n // Pagination parameters\n const page = parseInt(request.query.page) || 1;\n const limit = parseInt(request.query.limit);\n const offset = (page - 1) * (limit > 0 ? limit : 0);\n\n // Filtering and sorting\n const filters = request.query.filters ? JSON.parse(request.query.filters) : {};\n const sortOrder = request.query['sort-order'] || 'ASC';\n const orderBy = request.query.sort ? { [request.query.sort]: sortOrder } : { id: sortOrder };\n\n const normalizedQuery: { [key: string]: any } = {};\n\n for (const key in request.query) {\n // Skip prototype pollution attempts\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n continue;\n }\n\n // Only process own properties\n if (!Object.prototype.hasOwnProperty.call(request.query, key)) {\n continue;\n }\n\n if (key.endsWith('[]')) {\n const normalizedKey = key.slice(0, -2);\n\n // Safe property assignment\n if (normalizedKey !== '__proto__' && normalizedKey !== 'constructor' && normalizedKey !== 'prototype') {\n Reflect.set(normalizedQuery, normalizedKey, Reflect.get(request.query, key));\n }\n } else {\n Reflect.set(normalizedQuery, key, Reflect.get(request.query, key));\n }\n }\n\n // Build query options\n const options: {\n limit?: number;\n offset?: number;\n filters: FilterQuery<any>;\n orderBy: { [key: string]: string };\n } = {\n filters,\n offset,\n orderBy,\n };\n\n if (limit > 0) {\n options.limit = limit;\n }\n\n const entityProperties = this.getEntityProperties(EntityClass);\n const reservedQueryKeys = ['page', 'limit', 'filters', 'sort', 'populate', 'search'];\n const searchQuery = request.query.search || '';\n\n for (const key in normalizedQuery) {\n // Skip prototype pollution attempts\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n continue;\n }\n\n // Only process own properties\n if (!Object.prototype.hasOwnProperty.call(normalizedQuery, key)) {\n continue;\n }\n\n if (reservedQueryKeys.includes(key)) {\n continue;\n }\n\n if (!entityProperties.includes(key)) {\n const [relation, subProperty] = key.split('.');\n\n if (relation && subProperty) {\n // Validate relation and subProperty names\n if (\n relation === '__proto__' ||\n relation === 'constructor' ||\n relation === 'prototype' ||\n subProperty === '__proto__' ||\n subProperty === 'constructor' ||\n subProperty === 'prototype'\n ) {\n continue;\n }\n\n let queryValue = Reflect.get(normalizedQuery, key);\n\n if (!queryValue) continue;\n\n if (typeof queryValue === 'string' && queryValue.includes(',')) {\n queryValue = queryValue.split(',');\n }\n\n if (Array.isArray(queryValue)) {\n Reflect.set(options.filters, relation, {\n [subProperty]: { $in: queryValue },\n });\n } else {\n Reflect.set(options.filters, relation, {\n [subProperty]: queryValue,\n });\n }\n }\n\n continue;\n }\n\n let queryValue = Reflect.get(normalizedQuery, key);\n\n if (!queryValue) {\n continue;\n }\n\n if (typeof queryValue === 'string' && queryValue.includes(',')) {\n queryValue = queryValue.split(',');\n }\n\n if (Array.isArray(queryValue)) {\n Reflect.set(options.filters, key, { $in: queryValue });\n } else {\n Reflect.set(options.filters, key, queryValue);\n }\n }\n\n // Add search filter if a search query is provided\n if (searchQuery) {\n const searchFields = EntityClass.getSearchFields();\n\n options.filters.$or = searchFields\n .filter(field => {\n const isIntegerField = ['id', 'originId'].includes(field);\n\n return !isIntegerField;\n })\n .map(field => {\n return {\n [field]: { $like: `%${searchQuery}%` },\n };\n });\n }\n\n const populate = request.query.populate ? request.query.populate.split(',') : [];\n\n // Fetch items from the database\n const [items, total] = await this.entityManager.findAndCount(this.entityName, options.filters, {\n limit: options.limit,\n offset: options.offset,\n orderBy: options.orderBy,\n populate,\n });\n\n const totalPages = limit > 0 ? Math.ceil(total / limit) : 1;\n\n const data = {\n items,\n total,\n page,\n totalPages,\n limit: limit > 0 ? limit : total,\n };\n\n // Call postGetMany hook\n await this.postGetMany({\n entityManager: this.entityManager,\n request,\n reply,\n data,\n });\n\n reply.send({\n data: data.items,\n total_items: data.total,\n page: data.page,\n total_pages: data.totalPages,\n limit: data.limit,\n });\n } catch (error) {\n this.sendErrorResponse({ reply, error });\n }\n };\n\n protected async preGetOne(_: {\n entityManager: EntityManager;\n request: FastifyRequest;\n reply: FastifyReply;\n }): Promise<void> {\n // Default implementation: do nothing\n }\n\n protected async postGetOne(_: {\n entityManager: EntityManager;\n request: FastifyRequest;\n reply: FastifyReply;\n item: any;\n }): Promise<void> {\n // Default implementation: do nothing\n }\n\n public getOne = async (\n request: FastifyRequest<{\n Params: { id: number };\n Querystring: { populate: string };\n }>,\n reply: FastifyReply,\n ) => {\n try {\n await this.preGetOne({\n entityManager: this.entityManager,\n request,\n reply,\n });\n\n const queryPopulate = request.query.populate || null;\n const populateList: string[] = queryPopulate ? queryPopulate.split(',') : [];\n\n // Ensure populate is typed correctly for MikroORM\n const populate = populateList.map(field => `${field}.*`) as unknown as Populate<\n object,\n `${string}.*` | `${string}.$infer`\n >;\n\n const EntityClass = await this.getEntity();\n\n if (!EntityClass) {\n this.sendErrorResponse({ reply, error: 'Entity not found' });\n return;\n }\n\n const id = request.params.id;\n\n const item = await this.entityManager.findOne(this.entityName, { id }, { populate });\n\n if (!item) {\n return this.sendNotFoundResponse(reply, `${EntityClass.singularNameCapitalized} not found`);\n }\n\n await this.postGetOne({\n entityManager: this.entityManager,\n request,\n reply,\n item,\n });\n\n this.sendSuccessResponse({ reply, data: item });\n } catch (error) {\n this.sendErrorResponse({ reply, error });\n }\n };\n\n protected preCreateOne = ({\n request,\n reply,\n }: {\n request: FastifyRequest;\n reply: FastifyReply;\n }): { request: FastifyRequest; reply: FastifyReply } => {\n return { request, reply };\n };\n\n protected async postCreateOne(_: {\n entityManager: EntityManager;\n request: FastifyRequest;\n reply: FastifyReply;\n item: any;\n }): Promise<void> {}\n\n public createOne = async (request: FastifyRequest, reply: FastifyReply) => {\n try {\n const EntityClass = await this.getEntity();\n\n if (!EntityClass) {\n this.sendErrorResponse({ reply, error: 'Entity not found' });\n return;\n }\n\n // Listen for preCreateOne hook\n if (this.preCreateOne) {\n const { request: preCreateOneRequest } = await this.preCreateOne({\n request,\n reply,\n });\n if (preCreateOneRequest) {\n request = preCreateOneRequest;\n }\n }\n\n const { error, value } = EntityClass.validate(request.body, true);\n\n if (error) {\n return this.sendErrorResponse({ reply, error: error.message });\n }\n\n const item = this.entityManager.create(this.entityName, value as object);\n\n await this.entityManager.persistAndFlush(item);\n\n // Call postCreateOne hook\n await this.postCreateOne({\n entityManager: this.entityManager,\n request,\n reply,\n item,\n });\n\n this.sendSuccessResponse({ reply, data: item, statusCode: StatusCodes.CREATED });\n } catch (error) {\n this.sendErrorResponse({ reply, error });\n }\n };\n\n protected async postUpdateOne(_: {\n entityManager: EntityManager;\n request: FastifyRequest;\n reply: FastifyReply;\n item: any;\n }): Promise<void> {}\n\n public updateOne = async (request: FastifyRequest<{ Params: { id: number } }>, reply: FastifyReply) => {\n try {\n const EntityClass = await this.getEntity();\n\n if (!EntityClass) {\n this.sendErrorResponse({ reply, error: 'Entity not found' });\n return;\n }\n\n const id = request.params.id;\n\n const { error, value } = EntityClass.validate(request.body, false);\n\n if (error) {\n return this.sendErrorResponse({ reply, error: error.message });\n }\n\n const item = await this.entityManager.findOne(this.entityName, { id });\n\n if (!item) {\n return this.sendNotFoundResponse(reply, `${EntityClass.singularNameCapitalized} not found`);\n }\n\n this.entityManager.assign(item, value as object);\n\n await this.entityManager.persistAndFlush(item);\n\n // Call postUpdateOne hook\n await this.postUpdateOne({\n entityManager: this.entityManager,\n request,\n reply,\n item,\n });\n\n this.sendSuccessResponse({ reply, data: item });\n } catch (error) {\n this.sendErrorResponse({ reply, error });\n }\n };\n\n public deleteOne = async (request: FastifyRequest<{ Params: { id: number } }>, reply: FastifyReply) => {\n try {\n const EntityClass = await this.getEntity();\n\n if (!EntityClass) {\n this.sendErrorResponse({ reply, error: 'Entity not found' });\n\n return;\n }\n\n const id = request.params.id;\n\n const item = await this.entityManager.findOne(this.entityName, { id });\n\n if (!item) {\n return this.sendNotFoundResponse(reply, `${EntityClass.singularNameCapitalized} not found`);\n }\n\n await this.entityManager.removeAndFlush(item);\n\n reply.status(StatusCodes.NO_CONTENT).send();\n } catch (error) {\n this.sendErrorResponse({ reply, error });\n }\n };\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import 'reflect-metadata';\nimport path from 'path';\nimport type { EntityManager, FilterQuery, Populate } from '@mikro-orm/core';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport { StatusCodes } from 'http-status-codes';\nimport BaseController from './base.js';\nimport type { DynamicEntity } from '../../database/dynamic-entity.js';\nimport { generateFormFields } from '../../database/dynamic-entity-form-decorators.js';\nimport { Helper } from '../../util/index.js';\nimport type { WebServerBaseControllerConstructorParams } from './base.interface.js';\n\nexport default abstract class EntityController extends BaseController {\n protected abstract entityName: string;\n\n protected entityManager: EntityManager;\n\n // Cache for entity modules to avoid repeated dynamic imports\n private static entityCache = new Map<string, typeof DynamicEntity>();\n\n constructor(props: WebServerBaseControllerConstructorParams) {\n super(props);\n\n const { databaseInstance } = props;\n\n this.entityManager = databaseInstance.getEntityManager();\n }\n\n protected getEntity = async (): Promise<typeof DynamicEntity | undefined> => {\n if (!this.applicationConfig.database || this.applicationConfig.database.enabled !== true) {\n throw new Error(`Database not enabled (Entity: ${this.entityName})`);\n }\n\n // Check cache first\n const cacheKey = `${this.applicationConfig.database.entitiesDirectory}:${this.entityName}`;\n if (EntityController.entityCache.has(cacheKey)) {\n return EntityController.entityCache.get(cacheKey);\n }\n\n // Define entity module path\n const entityModulePath = path.join(\n this.applicationConfig.database.entitiesDirectory,\n `${this.entityName}.${Helper.getScriptFileExtension()}`,\n );\n\n // Import entity module\n const entityModule = await import(entityModulePath);\n\n if (!entityModule?.[this.entityName]) {\n throw new Error(`Entity not found (Entity: ${this.entityName})`);\n }\n\n // Get entity class\n const EntityClass = entityModule[this.entityName];\n\n // Cache the entity for future use\n EntityController.entityCache.set(cacheKey, EntityClass);\n\n return EntityClass;\n };\n\n private getEntityProperties(entityClass: any): string[] {\n const properties: string[] = [];\n\n const reservedPropertyKeys = ['constructor', 'toJSON'];\n\n for (const propertyKey of Object.getOwnPropertyNames(entityClass.prototype)) {\n if (propertyKey.startsWith('__')) {\n continue;\n } else if (reservedPropertyKeys.includes(propertyKey)) {\n continue;\n }\n\n properties.push(propertyKey);\n }\n\n return properties;\n }\n\n public options = async (request: FastifyRequest, reply: FastifyReply) => {\n try {\n const EntityClass = await this.getEntity();\n\n if (!EntityClass) {\n this.sendErrorResponse({ reply, error: 'Entity not found' });\n\n return;\n }\n\n const formFields = generateFormFields({ model: EntityClass });\n\n this.sendSuccessResponse({\n reply,\n data: {\n formFields,\n },\n });\n } catch (error) {\n this.sendErrorResponse({ reply, error });\n }\n };\n\n public metadata = async (request: FastifyRequest, reply: FastifyReply) => {\n try {\n const EntityClass = await this.getEntity();\n\n if (!EntityClass) {\n this.sendErrorResponse({ reply, error: 'Entity not found' });\n\n return;\n }\n\n const formFields = generateFormFields({ model: EntityClass });\n\n this.sendSuccessResponse({\n reply,\n data: {\n formFields,\n },\n });\n } catch (error) {\n this.sendErrorResponse({ reply, error });\n }\n };\n\n // Pre-getMany hook (can be overridden in the child controller)\n protected async preGetMany(_: {\n entityManager: EntityManager;\n request: FastifyRequest;\n reply: FastifyReply;\n }): Promise<void> {\n // Default implementation: do nothing\n }\n\n // Post-getMany hook (can be overridden in the child controller)\n // await this.postGetMany({ entityManager: this.entityManager, request, reply, data });\n protected async postGetMany(_: {\n entityManager: EntityManager;\n request: FastifyRequest;\n reply: FastifyReply;\n data: {\n items: any[];\n total: number;\n page: number;\n totalPages: number;\n limit: number;\n };\n }): Promise<void> {\n // Default implementation: do nothing\n }\n\n public getMany = async (\n request: FastifyRequest<{\n Querystring: {\n page: string;\n limit: string;\n filters: string;\n sort: string;\n 'sort-order': string;\n search: string;\n [key: string]: any;\n };\n }>,\n reply: FastifyReply,\n ) => {\n try {\n // Call preGetMany hook\n await this.preGetMany({\n entityManager: this.entityManager,\n request,\n reply,\n });\n\n const EntityClass = await this.getEntity();\n\n if (!EntityClass) {\n this.sendErrorResponse({ reply, error: 'Entity not found' });\n\n return;\n }\n\n // Pagination parameters\n const page = parseInt(request.query.page) || 1;\n const limit = parseInt(request.query.limit);\n const offset = (page - 1) * (limit > 0 ? limit : 0);\n\n // Filtering and sorting\n const filters = request.query.filters ? JSON.parse(request.query.filters) : {};\n const sortOrder = request.query['sort-order'] || 'ASC';\n const orderBy = request.query.sort ? { [request.query.sort]: sortOrder } : { id: sortOrder };\n\n const normalizedQuery: { [key: string]: any } = {};\n\n for (const key in request.query) {\n // Skip prototype pollution attempts\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n continue;\n }\n\n // Only process own properties\n if (!Object.prototype.hasOwnProperty.call(request.query, key)) {\n continue;\n }\n\n if (key.endsWith('[]')) {\n const normalizedKey = key.slice(0, -2);\n\n // Safe property assignment\n if (normalizedKey !== '__proto__' && normalizedKey !== 'constructor' && normalizedKey !== 'prototype') {\n Reflect.set(normalizedQuery, normalizedKey, Reflect.get(request.query, key));\n }\n } else {\n Reflect.set(normalizedQuery, key, Reflect.get(request.query, key));\n }\n }\n\n // Build query options\n const options: {\n limit?: number;\n offset?: number;\n filters: FilterQuery<any>;\n orderBy: { [key: string]: string };\n } = {\n filters,\n offset,\n orderBy,\n };\n\n if (limit > 0) {\n options.limit = limit;\n }\n\n const entityProperties = this.getEntityProperties(EntityClass);\n const reservedQueryKeys = ['page', 'limit', 'filters', 'sort', 'populate', 'search'];\n const searchQuery = request.query.search || '';\n\n for (const key in normalizedQuery) {\n // Skip prototype pollution attempts\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n continue;\n }\n\n // Only process own properties\n if (!Object.prototype.hasOwnProperty.call(normalizedQuery, key)) {\n continue;\n }\n\n if (reservedQueryKeys.includes(key)) {\n continue;\n }\n\n if (!entityProperties.includes(key)) {\n const [relation, subProperty] = key.split('.');\n\n if (relation && subProperty) {\n // Validate relation and subProperty names\n if (\n relation === '__proto__' ||\n relation === 'constructor' ||\n relation === 'prototype' ||\n subProperty === '__proto__' ||\n subProperty === 'constructor' ||\n subProperty === 'prototype'\n ) {\n continue;\n }\n\n let queryValue = Reflect.get(normalizedQuery, key);\n\n if (!queryValue) continue;\n\n if (typeof queryValue === 'string' && queryValue.includes(',')) {\n queryValue = queryValue.split(',');\n }\n\n if (Array.isArray(queryValue)) {\n Reflect.set(options.filters, relation, {\n [subProperty]: { $in: queryValue },\n });\n } else {\n Reflect.set(options.filters, relation, {\n [subProperty]: queryValue,\n });\n }\n }\n\n continue;\n }\n\n let queryValue = Reflect.get(normalizedQuery, key);\n\n if (!queryValue) {\n continue;\n }\n\n if (typeof queryValue === 'string' && queryValue.includes(',')) {\n queryValue = queryValue.split(',');\n }\n\n if (Array.isArray(queryValue)) {\n Reflect.set(options.filters, key, { $in: queryValue });\n } else {\n Reflect.set(options.filters, key, queryValue);\n }\n }\n\n // Add search filter if a search query is provided\n if (searchQuery) {\n const searchFields = EntityClass.getSearchFields();\n\n options.filters.$or = searchFields\n .filter(field => {\n const isIntegerField = ['id', 'originId'].includes(field);\n\n return !isIntegerField;\n })\n .map(field => {\n return {\n [field]: { $like: `%${searchQuery}%` },\n };\n });\n }\n\n const populate = request.query.populate ? request.query.populate.split(',') : [];\n\n // Fetch items from the database\n const [items, total] = await this.entityManager.findAndCount(this.entityName, options.filters, {\n limit: options.limit,\n offset: options.offset,\n orderBy: options.orderBy,\n populate,\n });\n\n const totalPages = limit > 0 ? Math.ceil(total / limit) : 1;\n\n const data = {\n items,\n total,\n page,\n totalPages,\n limit: limit > 0 ? limit : total,\n };\n\n // Call postGetMany hook\n await this.postGetMany({\n entityManager: this.entityManager,\n request,\n reply,\n data,\n });\n\n reply.send({\n data: data.items,\n total_items: data.total,\n page: data.page,\n total_pages: data.totalPages,\n limit: data.limit,\n });\n } catch (error) {\n this.sendErrorResponse({ reply, error });\n }\n };\n\n protected async preGetOne(_: {\n entityManager: EntityManager;\n request: FastifyRequest;\n reply: FastifyReply;\n }): Promise<void> {\n // Default implementation: do nothing\n }\n\n protected async postGetOne(_: {\n entityManager: EntityManager;\n request: FastifyRequest;\n reply: FastifyReply;\n item: any;\n }): Promise<void> {\n // Default implementation: do nothing\n }\n\n public getOne = async (\n request: FastifyRequest<{\n Params: { id: number };\n Querystring: { populate: string };\n }>,\n reply: FastifyReply,\n ) => {\n try {\n await this.preGetOne({\n entityManager: this.entityManager,\n request,\n reply,\n });\n\n const queryPopulate = request.query.populate || null;\n const populateList: string[] = queryPopulate ? queryPopulate.split(',') : [];\n\n // Ensure populate is typed correctly for MikroORM\n const populate = populateList.map(field => `${field}.*`) as unknown as Populate<\n object,\n `${string}.*` | `${string}.$infer`\n >;\n\n const EntityClass = await this.getEntity();\n\n if (!EntityClass) {\n this.sendErrorResponse({ reply, error: 'Entity not found' });\n return;\n }\n\n const id = request.params.id;\n\n const item = await this.entityManager.findOne(this.entityName, { id }, { populate });\n\n if (!item) {\n return this.sendNotFoundResponse(reply, `${EntityClass.singularNameCapitalized} not found`);\n }\n\n await this.postGetOne({\n entityManager: this.entityManager,\n request,\n reply,\n item,\n });\n\n this.sendSuccessResponse({ reply, data: item });\n } catch (error) {\n this.sendErrorResponse({ reply, error });\n }\n };\n\n protected preCreateOne = ({\n request,\n reply,\n }: {\n request: FastifyRequest;\n reply: FastifyReply;\n }): { request: FastifyRequest; reply: FastifyReply } => {\n return { request, reply };\n };\n\n protected async postCreateOne(_: {\n entityManager: EntityManager;\n request: FastifyRequest;\n reply: FastifyReply;\n item: any;\n }): Promise<void> {}\n\n public createOne = async (request: FastifyRequest, reply: FastifyReply) => {\n try {\n const EntityClass = await this.getEntity();\n\n if (!EntityClass) {\n this.sendErrorResponse({ reply, error: 'Entity not found' });\n return;\n }\n\n // Listen for preCreateOne hook\n if (this.preCreateOne) {\n const { request: preCreateOneRequest } = await this.preCreateOne({\n request,\n reply,\n });\n if (preCreateOneRequest) {\n request = preCreateOneRequest;\n }\n }\n\n const { error, value } = EntityClass.validateCreate(request.body);\n\n if (error) {\n return this.sendErrorResponse({ reply, error: error.message });\n }\n\n const item = this.entityManager.create(this.entityName, value as object);\n\n await this.entityManager.persistAndFlush(item);\n\n // Call postCreateOne hook\n await this.postCreateOne({\n entityManager: this.entityManager,\n request,\n reply,\n item,\n });\n\n this.sendSuccessResponse({ reply, data: item, statusCode: StatusCodes.CREATED });\n } catch (error) {\n this.sendErrorResponse({ reply, error });\n }\n };\n\n protected async postUpdateOne(_: {\n entityManager: EntityManager;\n request: FastifyRequest;\n reply: FastifyReply;\n item: any;\n }): Promise<void> {}\n\n public updateOne = async (request: FastifyRequest<{ Params: { id: number } }>, reply: FastifyReply) => {\n try {\n const EntityClass = await this.getEntity();\n\n if (!EntityClass) {\n this.sendErrorResponse({ reply, error: 'Entity not found' });\n return;\n }\n\n const id = request.params.id;\n\n const { error, value } = EntityClass.validateUpdate(request.body);\n\n if (error) {\n return this.sendErrorResponse({ reply, error: error.message });\n }\n\n const item = await this.entityManager.findOne(this.entityName, { id });\n\n if (!item) {\n return this.sendNotFoundResponse(reply, `${EntityClass.singularNameCapitalized} not found`);\n }\n\n this.entityManager.assign(item, value as object);\n\n await this.entityManager.persistAndFlush(item);\n\n // Call postUpdateOne hook\n await this.postUpdateOne({\n entityManager: this.entityManager,\n request,\n reply,\n item,\n });\n\n this.sendSuccessResponse({ reply, data: item });\n } catch (error) {\n this.sendErrorResponse({ reply, error });\n }\n };\n\n public deleteOne = async (request: FastifyRequest<{ Params: { id: number } }>, reply: FastifyReply) => {\n try {\n const EntityClass = await this.getEntity();\n\n if (!EntityClass) {\n this.sendErrorResponse({ reply, error: 'Entity not found' });\n\n return;\n }\n\n const id = request.params.id;\n\n const item = await this.entityManager.findOne(this.entityName, { id });\n\n if (!item) {\n return this.sendNotFoundResponse(reply, `${EntityClass.singularNameCapitalized} not found`);\n }\n\n await this.entityManager.removeAndFlush(item);\n\n reply.status(StatusCodes.NO_CONTENT).send();\n } catch (error) {\n this.sendErrorResponse({ reply, error });\n }\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["queryValue"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scpxl/nodejs-framework",
3
- "version": "1.0.25",
3
+ "version": "1.0.27",
4
4
  "description": "PXL Node.js Framework",
5
5
  "engines": {
6
6
  "node": ">=22.0.0"