monorise 1.1.0-dev.0 → 1.1.0-dev.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/dist/base/index.d.ts +27 -1
- package/dist/base/index.js +3 -1
- package/dist/base/index.js.map +1 -1
- package/dist/core/index.d.ts +9 -3
- package/dist/core/index.js +55 -30
- package/dist/core/index.js.map +1 -1
- package/dist/react/{chunk-4Y4KWGJD.js → chunk-2QOYO3GF.js} +2 -2
- package/dist/react/{chunk-DRH2BB7I.js → chunk-4WSYM746.js} +4 -4
- package/dist/react/{chunk-XCDCVRJR.js → chunk-5XIRNUBL.js} +2 -2
- package/dist/react/{chunk-MO35V2Y7.js → chunk-7JDOKZGQ.js} +5 -5
- package/dist/react/chunk-BJXCFDMF.js +15 -0
- package/dist/react/{chunk-UC3E72G7.js.map → chunk-BJXCFDMF.js.map} +1 -1
- package/dist/react/{chunk-YNFQEPO5.js → chunk-BUTF5RJU.js} +2 -2
- package/dist/react/{chunk-EQ3PKQ2S.js → chunk-DTRWUIDH.js} +2 -2
- package/dist/react/{chunk-UQPQBWEQ.js → chunk-GFVCNWVT.js} +2 -2
- package/dist/react/{chunk-B3XDGUFO.js → chunk-JT5EZZSL.js} +4 -4
- package/dist/react/{chunk-4D22OCZG.js → chunk-KLXK4V6G.js} +2 -2
- package/dist/react/{chunk-H64MMAL7.js → chunk-LJLMKEKI.js} +4 -4
- package/dist/react/{chunk-CQBOIXWK.js → chunk-MIXAYX55.js} +6 -1
- package/dist/react/{chunk-BPBCUO2Z.js → chunk-RPNCWADG.js} +2 -2
- package/dist/react/{chunk-XOYAZDIH.js → chunk-S6RDMHHH.js} +3 -3
- package/dist/react/{chunk-757E5UYA.js → chunk-U6RIOMF4.js} +2 -2
- package/dist/react/{chunk-UHMKB3OR.js → chunk-WCRLJFBW.js} +9 -9
- package/dist/react/{chunk-4N3P4ONH.js → chunk-YF6S7S36.js} +8 -8
- package/dist/react/{dist-es-VU33JFTZ.js → dist-es-5WYA7CWK.js} +6 -6
- package/dist/react/{dist-es-5GDBXNKQ.js → dist-es-CR5AOOCO.js} +7 -7
- package/dist/react/{dist-es-NRIS3TYJ.js → dist-es-KZ3GLAJI.js} +15 -15
- package/dist/react/{dist-es-VCXAEYYN.js → dist-es-R4TRTT45.js} +4 -4
- package/dist/react/{dist-es-IWIE5JLA.js → dist-es-SKDPAJEW.js} +6 -6
- package/dist/react/{dist-es-B3JDGWY6.js → dist-es-TOHBZNTZ.js} +5 -5
- package/dist/react/{dist-es-35AO47NO.js → dist-es-XNAC47MK.js} +4 -4
- package/dist/react/{event-streams-OSOTOTTP.js → event-streams-WAZW4P3K.js} +2 -2
- package/dist/react/index.js +343 -300
- package/dist/react/index.js.map +1 -1
- package/dist/react/{loadSso-ME7MKAM3.js → loadSso-KXVD6CBM.js} +13 -13
- package/dist/react/{service.config-ZJEZ6EKA-FC2TR3GH.js → service.config-I7RKP6FE.js} +3 -3
- package/dist/react/{signin-LOXYIE5I.js → signin-SEY3FDQ5.js} +14 -14
- package/dist/react/{sso-oidc-X63KRRLO.js → sso-oidc-REODVHH5.js} +14 -14
- package/dist/react/{sts-OXBEY7HY.js → sts-I3M4QP37.js} +12 -12
- package/dist/react/websocket-OSLLJSNO.js +10 -0
- package/package.json +1 -1
- package/dist/react/chunk-UC3E72G7.js +0 -73
- package/dist/react/websocket-QHA7SQXG.js +0 -10
- /package/dist/react/{chunk-4Y4KWGJD.js.map → chunk-2QOYO3GF.js.map} +0 -0
- /package/dist/react/{chunk-DRH2BB7I.js.map → chunk-4WSYM746.js.map} +0 -0
- /package/dist/react/{chunk-XCDCVRJR.js.map → chunk-5XIRNUBL.js.map} +0 -0
- /package/dist/react/{chunk-MO35V2Y7.js.map → chunk-7JDOKZGQ.js.map} +0 -0
- /package/dist/react/{chunk-YNFQEPO5.js.map → chunk-BUTF5RJU.js.map} +0 -0
- /package/dist/react/{chunk-EQ3PKQ2S.js.map → chunk-DTRWUIDH.js.map} +0 -0
- /package/dist/react/{chunk-UQPQBWEQ.js.map → chunk-GFVCNWVT.js.map} +0 -0
- /package/dist/react/{chunk-B3XDGUFO.js.map → chunk-JT5EZZSL.js.map} +0 -0
- /package/dist/react/{chunk-4D22OCZG.js.map → chunk-KLXK4V6G.js.map} +0 -0
- /package/dist/react/{chunk-H64MMAL7.js.map → chunk-LJLMKEKI.js.map} +0 -0
- /package/dist/react/{chunk-CQBOIXWK.js.map → chunk-MIXAYX55.js.map} +0 -0
- /package/dist/react/{chunk-BPBCUO2Z.js.map → chunk-RPNCWADG.js.map} +0 -0
- /package/dist/react/{chunk-XOYAZDIH.js.map → chunk-S6RDMHHH.js.map} +0 -0
- /package/dist/react/{chunk-757E5UYA.js.map → chunk-U6RIOMF4.js.map} +0 -0
- /package/dist/react/{chunk-UHMKB3OR.js.map → chunk-WCRLJFBW.js.map} +0 -0
- /package/dist/react/{chunk-4N3P4ONH.js.map → chunk-YF6S7S36.js.map} +0 -0
- /package/dist/react/{dist-es-VU33JFTZ.js.map → dist-es-5WYA7CWK.js.map} +0 -0
- /package/dist/react/{dist-es-5GDBXNKQ.js.map → dist-es-CR5AOOCO.js.map} +0 -0
- /package/dist/react/{dist-es-NRIS3TYJ.js.map → dist-es-KZ3GLAJI.js.map} +0 -0
- /package/dist/react/{dist-es-VCXAEYYN.js.map → dist-es-R4TRTT45.js.map} +0 -0
- /package/dist/react/{dist-es-IWIE5JLA.js.map → dist-es-SKDPAJEW.js.map} +0 -0
- /package/dist/react/{dist-es-B3JDGWY6.js.map → dist-es-TOHBZNTZ.js.map} +0 -0
- /package/dist/react/{dist-es-35AO47NO.js.map → dist-es-XNAC47MK.js.map} +0 -0
- /package/dist/react/{event-streams-OSOTOTTP.js.map → event-streams-WAZW4P3K.js.map} +0 -0
- /package/dist/react/{loadSso-ME7MKAM3.js.map → loadSso-KXVD6CBM.js.map} +0 -0
- /package/dist/react/{service.config-ZJEZ6EKA-FC2TR3GH.js.map → service.config-I7RKP6FE.js.map} +0 -0
- /package/dist/react/{signin-LOXYIE5I.js.map → signin-SEY3FDQ5.js.map} +0 -0
- /package/dist/react/{sso-oidc-X63KRRLO.js.map → sso-oidc-REODVHH5.js.map} +0 -0
- /package/dist/react/{sts-OXBEY7HY.js.map → sts-I3M4QP37.js.map} +0 -0
- /package/dist/react/{websocket-QHA7SQXG.js.map → websocket-OSLLJSNO.js.map} +0 -0
package/dist/base/index.d.ts
CHANGED
|
@@ -29,6 +29,25 @@ declare enum Entity {
|
|
|
29
29
|
interface EntitySchemaMap {
|
|
30
30
|
[key: string]: Record<string, any>;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* @description Configuration for a mutual relationship between two entities.
|
|
34
|
+
* Defines the schema for mutualData validation. Define once, reference from both entity configs.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* const enrollmentMutual = createMutualConfig({
|
|
39
|
+
* entities: [Entity.STUDENT, Entity.COURSE],
|
|
40
|
+
* mutualDataSchema: z.object({
|
|
41
|
+
* role: z.enum(['student', 'auditor']),
|
|
42
|
+
* enrolledAt: z.string().datetime(),
|
|
43
|
+
* }),
|
|
44
|
+
* });
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
interface MutualConfig<MD extends z.ZodRawShape = z.ZodRawShape> {
|
|
48
|
+
entities: [Entity, Entity];
|
|
49
|
+
mutualDataSchema: z.ZodObject<MD>;
|
|
50
|
+
}
|
|
32
51
|
type DraftEntity<T extends Entity = Entity> = T extends keyof EntitySchemaMap ? EntitySchemaMap[T] : never;
|
|
33
52
|
type NumericFields<T> = {
|
|
34
53
|
[K in keyof T as T[K] extends number ? K : never]?: number;
|
|
@@ -133,6 +152,11 @@ interface MonoriseEntityConfig<T extends Entity = Entity, B extends z.ZodRawShap
|
|
|
133
152
|
* @returns the final state of `mutualData` to be stored in the mutual record. Must be an object.
|
|
134
153
|
*/
|
|
135
154
|
mutualDataProcessor?: (mutualIds: string[], currentMutual: any, customContext?: Record<string, any>) => Record<string, any>;
|
|
155
|
+
/**
|
|
156
|
+
* @description (Optional) Reference to a mutual config created by `createMutualConfig`.
|
|
157
|
+
* Provides mutualData schema validation for create/update operations on this mutual relationship.
|
|
158
|
+
*/
|
|
159
|
+
mutual?: MutualConfig;
|
|
136
160
|
};
|
|
137
161
|
};
|
|
138
162
|
/**
|
|
@@ -353,6 +377,7 @@ declare const createEntityConfig: <T extends Entity, B extends z.ZodRawShape, C
|
|
|
353
377
|
entityType: Entity;
|
|
354
378
|
toMutualIds?: (context: any) => string[];
|
|
355
379
|
mutualDataProcessor?: (mutualIds: string[], currentMutual: any, customContext?: Record<string, any>) => Record<string, any>;
|
|
380
|
+
mutual?: MutualConfig;
|
|
356
381
|
};
|
|
357
382
|
};
|
|
358
383
|
prejoins?: {
|
|
@@ -394,5 +419,6 @@ declare const createEntityConfig: <T extends Entity, B extends z.ZodRawShape, C
|
|
|
394
419
|
[conditionName: string]: undefined | ((data: Partial<z.objectUtil.addQuestionMarks<z.baseObjectOutputType<B>, any> extends infer T_35 ? { [k_6 in keyof T_35]: T_35[k_6]; } : never>) => undefined);
|
|
395
420
|
} | undefined;
|
|
396
421
|
};
|
|
422
|
+
declare const createMutualConfig: <MD extends z.ZodRawShape>(config: MutualConfig<MD>) => MutualConfig<MD>;
|
|
397
423
|
|
|
398
|
-
export { type AdjustmentCondition, type AdjustmentConditionFn, type CreatedEntity, type DraftEntity, Entity, type EntitySchemaMap, type MonoriseEntityConfig, type NumericFields, type UpdateCondition, type UpdateConditionFn, type WhereClause, type WhereConditions, type WhereOperator, createEntityConfig };
|
|
424
|
+
export { type AdjustmentCondition, type AdjustmentConditionFn, type CreatedEntity, type DraftEntity, Entity, type EntitySchemaMap, type MonoriseEntityConfig, type MutualConfig, type NumericFields, type UpdateCondition, type UpdateConditionFn, type WhereClause, type WhereConditions, type WhereOperator, createEntityConfig, createMutualConfig };
|
package/dist/base/index.js
CHANGED
|
@@ -37,8 +37,10 @@ function makeSchema(config) {
|
|
|
37
37
|
var createEntityConfig = (config) => __spreadProps(__spreadValues({}, config), {
|
|
38
38
|
finalSchema: makeSchema(config)
|
|
39
39
|
});
|
|
40
|
+
var createMutualConfig = (config) => config;
|
|
40
41
|
export {
|
|
41
42
|
Entity,
|
|
42
|
-
createEntityConfig
|
|
43
|
+
createEntityConfig,
|
|
44
|
+
createMutualConfig
|
|
43
45
|
};
|
|
44
46
|
//# sourceMappingURL=index.js.map
|
package/dist/base/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../types/monorise.type.ts","../utils/index.ts"],"sourcesContent":["import type { z } from 'zod';\nimport type { WhereConditions } from './conditions.type';\n\nexport enum Entity {}\n\nexport interface EntitySchemaMap {\n [key: string]: Record<string, any>;\n}\n\nexport type DraftEntity<T extends Entity = Entity> =\n T extends keyof EntitySchemaMap ? EntitySchemaMap[T] : never;\n\nexport type NumericFields<T> = {\n [K in keyof T as T[K] extends number ? K : never]?: number;\n};\n\nexport type CreatedEntity<T extends Entity = Entity> = {\n entityId: string;\n entityType: string;\n data: T extends keyof EntitySchemaMap ? EntitySchemaMap[T] : never;\n createdAt: string;\n updatedAt: string;\n};\n\n/**\n * @description Configuration for a monorise entity, a shared configuration that is used across frontend and backend.\n * This can be served as a single source of truth for the entity configuration.\n * It is used to define the schema, and mutual relationships between this entity and other entities.\n *\n * @example\n * ```ts\n * const baseSchema = z.object({\n * title: z.string(),\n * }).partial();\n *\n * const createSchema = baseSchema.extend({\n * title: z.string(),\n * })\n *\n * const config = createEntityConfig({\n * name: 'learner',\n * displayName: 'Learner',\n * baseSchema,\n * createSchema,\n * });\n * ```\n */\nexport interface MonoriseEntityConfig<\n T extends Entity = Entity,\n B extends z.ZodRawShape = z.ZodRawShape,\n C extends z.ZodRawShape = z.ZodRawShape,\n M extends z.ZodRawShape = z.ZodRawShape,\n CO extends z.ZodObject<C> | undefined = undefined,\n MO extends z.ZodObject<M> | undefined = undefined,\n> {\n /**\n * @description Name of the entity. Must be in **lower-kebab-case** and **unique** across all entities\n *\n * @example `learner`, `learning-activity`\n */\n name: string | T;\n\n /**\n * @description Display name of the entity. It is not required to be unique\n */\n displayName: string;\n\n /**\n * @description (DEPRECATED) Use `uniqueFields` instead, Monorise should not handle auth mechanism\n * @description (Optional) Specify the authentication method to be used for the entity\n */\n authMethod?: {\n /**\n * @description Authentication method using email\n *\n * Note: The email used for authentication is unique per entity.\n * For example, if `johndoe@mail.com` is used for `learner` entity,\n * it can be reused again on `admin` entity. However, the same email\n * address cannot be repeated for the same entity.\n */\n email: {\n /**\n * @description Number of milliseconds before the token expires\n */\n tokenExpiresIn: number;\n };\n };\n\n /**\n * @description Base schema for the entity\n */\n baseSchema: z.ZodObject<B>;\n\n /**\n * @description Minimal schema required to create an entity\n */\n createSchema?: CO;\n searchableFields?: (keyof B)[];\n uniqueFields?: (keyof B)[];\n\n /**\n * @description Define mutual relationship of this entity with other entities\n */\n mutual?: {\n /**\n * @description Subscribes to update events from specified entities in the array.\n * These events will be used to run prejoin processor.\n */\n subscribes?: { entityType: Entity }[];\n /**\n * @description Virtual schema for mutual relationship. The schema is only used for validation purpose, but these fields are not stored in the database\n */\n mutualSchema: MO;\n\n /**\n * @description Keys of `mutualFields` are fields defined in `mutualSchema`.\n * Each field is a mutual relationship between this entity and another entity.\n */\n mutualFields: {\n [key: string]: {\n entityType: Entity;\n toMutualIds?: (context: any) => string[];\n /**\n * @description (Optional) Custom function to process `mutualData`. If not provided, `mutualData` will be empty.\n *\n * @returns the final state of `mutualData` to be stored in the mutual record. Must be an object.\n */\n mutualDataProcessor?: (\n mutualIds: string[],\n currentMutual: any,\n customContext?: Record<string, any>,\n ) => Record<string, any>;\n };\n };\n\n /**\n * @description (Optional) Better known as tree processor\n * This is used to prejoin entities that are not directly related as mutual.\n * For example, if `learner` entity is related to `course` entity, and `course` entity is related to `module` entity,\n * prejoins can be used to join `learner` and `module` entities.\n * With this, the `learner` entity can access the `module` entity without having to go through the `course` entity,\n * hence reducing the number of queries.\n *\n * DynamoDB best practices: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-general-normalization.html\n *\n */\n prejoins?: {\n mutualField: string;\n targetEntityType: Entity;\n entityPaths: {\n skipCache?: boolean;\n entityType: Entity;\n processor?: (items: any[], context: Record<string, any>) => any;\n }[];\n }[];\n };\n /**\n * Use this function to perform side effects on the final schema for example refine/superRefine the schema\n *\n * @param schema The final schema of the entity (the combination of `baseSchema`/`createSchema` and `mutualSchema` if specified)\n * @returns void\n *\n * @example\n * ```ts\n * effect: (schema) => {\n * schema.refine(\n * // refinement logic here\n * )\n * }\n */\n effect?: (\n schema: z.ZodObject<z.ZodRawShape>,\n ) => z.ZodEffects<z.ZodObject<z.ZodRawShape>>;\n\n /**\n * @description (Optional) Use tags to create additional access patterns for the entity.\n * Time complexity for retrieving tagged entities is O(1).\n *\n * The following configuration will create a tag named `region` for the `organization` entity grouped by `region`.\n * You would then be able to retrieve all organizations in a specific region by:\n * GET `/core/tag/organization/region?group={region_name}`\n *\n * @example\n *\n * ```ts\n * {\n * name: 'organization',\n * tags: [\n * {\n * name: 'region',\n * processor: (entity) => {\n * return [\n * {\n * group: entity.data.region\n * }\n * ]\n * },\n * }\n * ]\n * }\n * ```\n *\n * @description\n *\n * The following configuration will create a tag named `dob` for the `user` entity sorted by `dob`.\n * You would then be able to retrieve all users sorted by `dob` by:\n * GET `/core/tag/user/dob?start=2000-01-01&end=2020-12-31`\n *\n * @example\n * ```ts\n * {\n * name: 'user',\n * tags: [\n * {\n * name: 'dob',\n * processor: (entity) => {\n * return [\n * {\n * sortValue: entity.data.dob\n * }\n * ]\n * },\n * }\n * ]\n * }\n * ```\n */\n tags?: {\n name: string;\n processor: (entity: { entityId: string; entityType: string; data: Record<string, any>; createdAt: string; updatedAt: string }) => {\n group?: string;\n sortValue?: string;\n }[];\n }[];\n\n /**\n * @description (Optional) Constraints for `adjustEntity` operations.\n * When adjusting numeric fields, these constraints are enforced at the database level.\n * If an adjustment would violate a constraint, the operation is rejected.\n *\n * @deprecated Use `conditions` instead. Will be removed in a future version.\n *\n * @example\n * ```ts\n * {\n * adjustmentConstraints: {\n * // Static: same for all entities of this type\n * balance: { min: 0 },\n * credits: { min: 0, max: 10000 },\n *\n * // Dynamic: reads constraint value from entity's own data\n * balance: { minField: 'minBalance' },\n * credits: { min: 0, maxField: 'creditLimit' },\n * }\n * }\n * ```\n */\n adjustmentConstraints?: {\n [fieldName: string]: {\n /** Static minimum value */\n min?: number;\n /** Static maximum value */\n max?: number;\n /** Field name on the entity whose value is used as the minimum (must be a numeric field) */\n minField?: keyof {\n [K in keyof B as B[K] extends z.ZodNumber | z.ZodOptional<z.ZodNumber> ? K : never]: K;\n } extends never ? string : keyof {\n [K in keyof B as B[K] extends z.ZodNumber | z.ZodOptional<z.ZodNumber> ? K : never]: K;\n };\n /** Field name on the entity whose value is used as the maximum (must be a numeric field) */\n maxField?: keyof {\n [K in keyof B as B[K] extends z.ZodNumber | z.ZodOptional<z.ZodNumber> ? K : never]: K;\n } extends never ? string : keyof {\n [K in keyof B as B[K] extends z.ZodNumber | z.ZodOptional<z.ZodNumber> ? K : never]: K;\n };\n };\n };\n\n /**\n * @description Named conditions for adjustEntity operations.\n * Each condition is either a static `WhereConditions` object or a function\n * `(data, adjustments) => WhereConditions` that receives the entity's current data\n * and the adjustment deltas.\n *\n * When defined, `$condition` is **required** in the adjustEntity request body.\n * The client sends a condition name (string), the server resolves it to a\n * DynamoDB ConditionExpression.\n *\n * @example\n * ```ts\n * {\n * adjustmentConditions: {\n * withdraw: (data, adjustments) => ({\n * balance: { $gte: (data.minBalance ?? 0) + Math.abs(adjustments?.balance ?? 0) },\n * }),\n * deposit: (data, adjustments) => ({\n * balance: { $lte: 1000000 - (adjustments.balance ?? 0) },\n * }),\n * }\n * }\n * ```\n */\n adjustmentConditions?: {\n [conditionName: string]:\n | WhereConditions\n | ((\n data: Partial<z.infer<z.ZodObject<B>>>,\n adjustments: Record<string, number>,\n ) => WhereConditions);\n };\n\n /**\n * @description Named conditions for updateEntity operations.\n * Each condition is either a static `WhereConditions` object or a function\n * `(data) => WhereConditions` that receives the entity's current data.\n *\n * `$condition` is always **optional** for updateEntity.\n * The client sends a condition name (string), the server resolves it to a\n * DynamoDB ConditionExpression. Replaces raw `$where` (deprecated).\n *\n * @example\n * ```ts\n * {\n * updateConditions: {\n * publish: { status: { $eq: 'draft' } },\n * archive: (data) => ({ status: { $ne: 'archived' } }),\n * }\n * }\n * ```\n */\n updateConditions?: {\n [conditionName: string]:\n | WhereConditions\n | ((data: Partial<z.infer<z.ZodObject<B>>>) => WhereConditions);\n };\n}\n","import type { Entity, MonoriseEntityConfig } from '../types/monorise.type';\nimport { z } from 'zod';\n\nfunction makeSchema<\n T extends Entity,\n B extends z.ZodRawShape,\n C extends z.ZodRawShape,\n M extends z.ZodRawShape,\n CO extends z.ZodObject<C> | undefined = undefined,\n MO extends z.ZodObject<M> | undefined = undefined,\n>(config: MonoriseEntityConfig<T, B, C, M, CO, MO>) {\n const { baseSchema, createSchema, mutual, effect } = config;\n const { mutualSchema } = mutual || {};\n\n type FinalSchemaType = CO extends z.AnyZodObject\n ? MO extends z.AnyZodObject\n ? z.ZodObject<B & CO['shape'] & MO['shape']>\n : z.ZodObject<B & CO['shape']>\n : MO extends z.AnyZodObject\n ? z.ZodObject<B & MO['shape']>\n : z.ZodObject<B>;\n\n const finalSchema = z.object({\n ...baseSchema.shape,\n ...createSchema?.shape,\n ...mutualSchema?.shape,\n }) as FinalSchemaType;\n\n if (effect) {\n return effect(finalSchema) as z.ZodEffects<FinalSchemaType>;\n }\n\n return finalSchema;\n}\n\nconst createEntityConfig = <\n T extends Entity,\n B extends z.ZodRawShape,\n C extends z.ZodRawShape,\n M extends z.ZodRawShape,\n CO extends z.ZodObject<C> | undefined = undefined,\n MO extends z.ZodObject<M> | undefined = undefined,\n>(\n config: MonoriseEntityConfig<T, B, C, M, CO, MO>,\n) => ({\n ...config,\n finalSchema: makeSchema(config),\n});\n\nexport { createEntityConfig };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAGO,IAAK,SAAL,kBAAKA,YAAL;AAAK,SAAAA;AAAA,GAAA;;;ACFZ,SAAS,SAAS;AAElB,SAAS,WAOP,QAAkD;AAClD,QAAM,EAAE,YAAY,cAAc,QAAQ,OAAO,IAAI;AACrD,QAAM,EAAE,aAAa,IAAI,UAAU,CAAC;AAUpC,QAAM,cAAc,EAAE,OAAO,iDACxB,WAAW,QACX,6CAAc,QACd,6CAAc,MAClB;AAED,MAAI,QAAQ;AACV,WAAO,OAAO,WAAW;AAAA,EAC3B;AAEA,SAAO;AACT;AAEA,IAAM,qBAAqB,CAQzB,WACI,iCACD,SADC;AAAA,EAEJ,aAAa,WAAW,MAAM;AAChC;","names":["Entity"]}
|
|
1
|
+
{"version":3,"sources":["../types/monorise.type.ts","../utils/index.ts"],"sourcesContent":["import type { z } from 'zod';\nimport type { WhereConditions } from './conditions.type';\n\nexport enum Entity {}\n\nexport interface EntitySchemaMap {\n [key: string]: Record<string, any>;\n}\n\n/**\n * @description Configuration for a mutual relationship between two entities.\n * Defines the schema for mutualData validation. Define once, reference from both entity configs.\n *\n * @example\n * ```ts\n * const enrollmentMutual = createMutualConfig({\n * entities: [Entity.STUDENT, Entity.COURSE],\n * mutualDataSchema: z.object({\n * role: z.enum(['student', 'auditor']),\n * enrolledAt: z.string().datetime(),\n * }),\n * });\n * ```\n */\nexport interface MutualConfig<\n MD extends z.ZodRawShape = z.ZodRawShape,\n> {\n entities: [Entity, Entity];\n mutualDataSchema: z.ZodObject<MD>;\n}\n\nexport type DraftEntity<T extends Entity = Entity> =\n T extends keyof EntitySchemaMap ? EntitySchemaMap[T] : never;\n\nexport type NumericFields<T> = {\n [K in keyof T as T[K] extends number ? K : never]?: number;\n};\n\nexport type CreatedEntity<T extends Entity = Entity> = {\n entityId: string;\n entityType: string;\n data: T extends keyof EntitySchemaMap ? EntitySchemaMap[T] : never;\n createdAt: string;\n updatedAt: string;\n};\n\n/**\n * @description Configuration for a monorise entity, a shared configuration that is used across frontend and backend.\n * This can be served as a single source of truth for the entity configuration.\n * It is used to define the schema, and mutual relationships between this entity and other entities.\n *\n * @example\n * ```ts\n * const baseSchema = z.object({\n * title: z.string(),\n * }).partial();\n *\n * const createSchema = baseSchema.extend({\n * title: z.string(),\n * })\n *\n * const config = createEntityConfig({\n * name: 'learner',\n * displayName: 'Learner',\n * baseSchema,\n * createSchema,\n * });\n * ```\n */\nexport interface MonoriseEntityConfig<\n T extends Entity = Entity,\n B extends z.ZodRawShape = z.ZodRawShape,\n C extends z.ZodRawShape = z.ZodRawShape,\n M extends z.ZodRawShape = z.ZodRawShape,\n CO extends z.ZodObject<C> | undefined = undefined,\n MO extends z.ZodObject<M> | undefined = undefined,\n> {\n /**\n * @description Name of the entity. Must be in **lower-kebab-case** and **unique** across all entities\n *\n * @example `learner`, `learning-activity`\n */\n name: string | T;\n\n /**\n * @description Display name of the entity. It is not required to be unique\n */\n displayName: string;\n\n /**\n * @description (DEPRECATED) Use `uniqueFields` instead, Monorise should not handle auth mechanism\n * @description (Optional) Specify the authentication method to be used for the entity\n */\n authMethod?: {\n /**\n * @description Authentication method using email\n *\n * Note: The email used for authentication is unique per entity.\n * For example, if `johndoe@mail.com` is used for `learner` entity,\n * it can be reused again on `admin` entity. However, the same email\n * address cannot be repeated for the same entity.\n */\n email: {\n /**\n * @description Number of milliseconds before the token expires\n */\n tokenExpiresIn: number;\n };\n };\n\n /**\n * @description Base schema for the entity\n */\n baseSchema: z.ZodObject<B>;\n\n /**\n * @description Minimal schema required to create an entity\n */\n createSchema?: CO;\n searchableFields?: (keyof B)[];\n uniqueFields?: (keyof B)[];\n\n /**\n * @description Define mutual relationship of this entity with other entities\n */\n mutual?: {\n /**\n * @description Subscribes to update events from specified entities in the array.\n * These events will be used to run prejoin processor.\n */\n subscribes?: { entityType: Entity }[];\n /**\n * @description Virtual schema for mutual relationship. The schema is only used for validation purpose, but these fields are not stored in the database\n */\n mutualSchema: MO;\n\n /**\n * @description Keys of `mutualFields` are fields defined in `mutualSchema`.\n * Each field is a mutual relationship between this entity and another entity.\n */\n mutualFields: {\n [key: string]: {\n entityType: Entity;\n toMutualIds?: (context: any) => string[];\n /**\n * @description (Optional) Custom function to process `mutualData`. If not provided, `mutualData` will be empty.\n *\n * @returns the final state of `mutualData` to be stored in the mutual record. Must be an object.\n */\n mutualDataProcessor?: (\n mutualIds: string[],\n currentMutual: any,\n customContext?: Record<string, any>,\n ) => Record<string, any>;\n /**\n * @description (Optional) Reference to a mutual config created by `createMutualConfig`.\n * Provides mutualData schema validation for create/update operations on this mutual relationship.\n */\n mutual?: MutualConfig;\n };\n };\n\n /**\n * @description (Optional) Better known as tree processor\n * This is used to prejoin entities that are not directly related as mutual.\n * For example, if `learner` entity is related to `course` entity, and `course` entity is related to `module` entity,\n * prejoins can be used to join `learner` and `module` entities.\n * With this, the `learner` entity can access the `module` entity without having to go through the `course` entity,\n * hence reducing the number of queries.\n *\n * DynamoDB best practices: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-general-normalization.html\n *\n */\n prejoins?: {\n mutualField: string;\n targetEntityType: Entity;\n entityPaths: {\n skipCache?: boolean;\n entityType: Entity;\n processor?: (items: any[], context: Record<string, any>) => any;\n }[];\n }[];\n };\n /**\n * Use this function to perform side effects on the final schema for example refine/superRefine the schema\n *\n * @param schema The final schema of the entity (the combination of `baseSchema`/`createSchema` and `mutualSchema` if specified)\n * @returns void\n *\n * @example\n * ```ts\n * effect: (schema) => {\n * schema.refine(\n * // refinement logic here\n * )\n * }\n */\n effect?: (\n schema: z.ZodObject<z.ZodRawShape>,\n ) => z.ZodEffects<z.ZodObject<z.ZodRawShape>>;\n\n /**\n * @description (Optional) Use tags to create additional access patterns for the entity.\n * Time complexity for retrieving tagged entities is O(1).\n *\n * The following configuration will create a tag named `region` for the `organization` entity grouped by `region`.\n * You would then be able to retrieve all organizations in a specific region by:\n * GET `/core/tag/organization/region?group={region_name}`\n *\n * @example\n *\n * ```ts\n * {\n * name: 'organization',\n * tags: [\n * {\n * name: 'region',\n * processor: (entity) => {\n * return [\n * {\n * group: entity.data.region\n * }\n * ]\n * },\n * }\n * ]\n * }\n * ```\n *\n * @description\n *\n * The following configuration will create a tag named `dob` for the `user` entity sorted by `dob`.\n * You would then be able to retrieve all users sorted by `dob` by:\n * GET `/core/tag/user/dob?start=2000-01-01&end=2020-12-31`\n *\n * @example\n * ```ts\n * {\n * name: 'user',\n * tags: [\n * {\n * name: 'dob',\n * processor: (entity) => {\n * return [\n * {\n * sortValue: entity.data.dob\n * }\n * ]\n * },\n * }\n * ]\n * }\n * ```\n */\n tags?: {\n name: string;\n processor: (entity: { entityId: string; entityType: string; data: Record<string, any>; createdAt: string; updatedAt: string }) => {\n group?: string;\n sortValue?: string;\n }[];\n }[];\n\n /**\n * @description (Optional) Constraints for `adjustEntity` operations.\n * When adjusting numeric fields, these constraints are enforced at the database level.\n * If an adjustment would violate a constraint, the operation is rejected.\n *\n * @deprecated Use `conditions` instead. Will be removed in a future version.\n *\n * @example\n * ```ts\n * {\n * adjustmentConstraints: {\n * // Static: same for all entities of this type\n * balance: { min: 0 },\n * credits: { min: 0, max: 10000 },\n *\n * // Dynamic: reads constraint value from entity's own data\n * balance: { minField: 'minBalance' },\n * credits: { min: 0, maxField: 'creditLimit' },\n * }\n * }\n * ```\n */\n adjustmentConstraints?: {\n [fieldName: string]: {\n /** Static minimum value */\n min?: number;\n /** Static maximum value */\n max?: number;\n /** Field name on the entity whose value is used as the minimum (must be a numeric field) */\n minField?: keyof {\n [K in keyof B as B[K] extends z.ZodNumber | z.ZodOptional<z.ZodNumber> ? K : never]: K;\n } extends never ? string : keyof {\n [K in keyof B as B[K] extends z.ZodNumber | z.ZodOptional<z.ZodNumber> ? K : never]: K;\n };\n /** Field name on the entity whose value is used as the maximum (must be a numeric field) */\n maxField?: keyof {\n [K in keyof B as B[K] extends z.ZodNumber | z.ZodOptional<z.ZodNumber> ? K : never]: K;\n } extends never ? string : keyof {\n [K in keyof B as B[K] extends z.ZodNumber | z.ZodOptional<z.ZodNumber> ? K : never]: K;\n };\n };\n };\n\n /**\n * @description Named conditions for adjustEntity operations.\n * Each condition is either a static `WhereConditions` object or a function\n * `(data, adjustments) => WhereConditions` that receives the entity's current data\n * and the adjustment deltas.\n *\n * When defined, `$condition` is **required** in the adjustEntity request body.\n * The client sends a condition name (string), the server resolves it to a\n * DynamoDB ConditionExpression.\n *\n * @example\n * ```ts\n * {\n * adjustmentConditions: {\n * withdraw: (data, adjustments) => ({\n * balance: { $gte: (data.minBalance ?? 0) + Math.abs(adjustments?.balance ?? 0) },\n * }),\n * deposit: (data, adjustments) => ({\n * balance: { $lte: 1000000 - (adjustments.balance ?? 0) },\n * }),\n * }\n * }\n * ```\n */\n adjustmentConditions?: {\n [conditionName: string]:\n | WhereConditions\n | ((\n data: Partial<z.infer<z.ZodObject<B>>>,\n adjustments: Record<string, number>,\n ) => WhereConditions);\n };\n\n /**\n * @description Named conditions for updateEntity operations.\n * Each condition is either a static `WhereConditions` object or a function\n * `(data) => WhereConditions` that receives the entity's current data.\n *\n * `$condition` is always **optional** for updateEntity.\n * The client sends a condition name (string), the server resolves it to a\n * DynamoDB ConditionExpression. Replaces raw `$where` (deprecated).\n *\n * @example\n * ```ts\n * {\n * updateConditions: {\n * publish: { status: { $eq: 'draft' } },\n * archive: (data) => ({ status: { $ne: 'archived' } }),\n * }\n * }\n * ```\n */\n updateConditions?: {\n [conditionName: string]:\n | WhereConditions\n | ((data: Partial<z.infer<z.ZodObject<B>>>) => WhereConditions);\n };\n}\n","import type { Entity, MonoriseEntityConfig, MutualConfig } from '../types/monorise.type';\nimport { z } from 'zod';\n\nfunction makeSchema<\n T extends Entity,\n B extends z.ZodRawShape,\n C extends z.ZodRawShape,\n M extends z.ZodRawShape,\n CO extends z.ZodObject<C> | undefined = undefined,\n MO extends z.ZodObject<M> | undefined = undefined,\n>(config: MonoriseEntityConfig<T, B, C, M, CO, MO>) {\n const { baseSchema, createSchema, mutual, effect } = config;\n const { mutualSchema } = mutual || {};\n\n type FinalSchemaType = CO extends z.AnyZodObject\n ? MO extends z.AnyZodObject\n ? z.ZodObject<B & CO['shape'] & MO['shape']>\n : z.ZodObject<B & CO['shape']>\n : MO extends z.AnyZodObject\n ? z.ZodObject<B & MO['shape']>\n : z.ZodObject<B>;\n\n const finalSchema = z.object({\n ...baseSchema.shape,\n ...createSchema?.shape,\n ...mutualSchema?.shape,\n }) as FinalSchemaType;\n\n if (effect) {\n return effect(finalSchema) as z.ZodEffects<FinalSchemaType>;\n }\n\n return finalSchema;\n}\n\nconst createEntityConfig = <\n T extends Entity,\n B extends z.ZodRawShape,\n C extends z.ZodRawShape,\n M extends z.ZodRawShape,\n CO extends z.ZodObject<C> | undefined = undefined,\n MO extends z.ZodObject<M> | undefined = undefined,\n>(\n config: MonoriseEntityConfig<T, B, C, M, CO, MO>,\n) => ({\n ...config,\n finalSchema: makeSchema(config),\n});\n\nconst createMutualConfig = <MD extends z.ZodRawShape>(\n config: MutualConfig<MD>,\n) => config;\n\nexport { createEntityConfig, createMutualConfig };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAGO,IAAK,SAAL,kBAAKA,YAAL;AAAK,SAAAA;AAAA,GAAA;;;ACFZ,SAAS,SAAS;AAElB,SAAS,WAOP,QAAkD;AAClD,QAAM,EAAE,YAAY,cAAc,QAAQ,OAAO,IAAI;AACrD,QAAM,EAAE,aAAa,IAAI,UAAU,CAAC;AAUpC,QAAM,cAAc,EAAE,OAAO,iDACxB,WAAW,QACX,6CAAc,QACd,6CAAc,MAClB;AAED,MAAI,QAAQ;AACV,WAAO,OAAO,WAAW;AAAA,EAC3B;AAEA,SAAO;AACT;AAEA,IAAM,qBAAqB,CAQzB,WACI,iCACD,SADC;AAAA,EAEJ,aAAa,WAAW,MAAM;AAChC;AAEA,IAAM,qBAAqB,CACzB,WACG;","names":["Entity"]}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -4608,12 +4608,14 @@ declare class UpsertEntityController {
|
|
|
4608
4608
|
}
|
|
4609
4609
|
|
|
4610
4610
|
declare class MutualService {
|
|
4611
|
+
private EntityConfig;
|
|
4611
4612
|
private entityRepository;
|
|
4612
4613
|
private mutualRepository;
|
|
4613
4614
|
private publishEvent;
|
|
4614
4615
|
private ddbUtils;
|
|
4615
4616
|
private entityServiceLifeCycle;
|
|
4616
|
-
constructor(entityRepository: EntityRepository, mutualRepository: MutualRepository, publishEvent: typeof publishEvent, ddbUtils: DbUtils, entityServiceLifeCycle: EntityServiceLifeCycle);
|
|
4617
|
+
constructor(EntityConfig: Record<Entity$2, ReturnType<typeof createEntityConfig>>, entityRepository: EntityRepository, mutualRepository: MutualRepository, publishEvent: typeof publishEvent, ddbUtils: DbUtils, entityServiceLifeCycle: EntityServiceLifeCycle);
|
|
4618
|
+
private getMutualDataSchema;
|
|
4617
4619
|
createMutual: <B extends Entity$2, T extends Entity$2, A extends Entity$2>({ byEntityType, byEntityId, entityType, entityId, mutualPayload, accountId, options, }: {
|
|
4618
4620
|
byEntityType: B;
|
|
4619
4621
|
byEntityId: string;
|
|
@@ -4632,13 +4634,17 @@ declare class MutualService {
|
|
|
4632
4634
|
ExpressionAttributeValues?: Record<string, AttributeValue>;
|
|
4633
4635
|
};
|
|
4634
4636
|
}) => Promise<{
|
|
4635
|
-
mutual: Mutual<B, T,
|
|
4637
|
+
mutual: Mutual<B, T, {
|
|
4638
|
+
[x: string]: any;
|
|
4639
|
+
}>;
|
|
4636
4640
|
eventPayload: {
|
|
4637
4641
|
byEntityType: B;
|
|
4638
4642
|
byEntityId: string;
|
|
4639
4643
|
entityType: T;
|
|
4640
4644
|
entityId: string;
|
|
4641
|
-
parsedMutualPayload:
|
|
4645
|
+
parsedMutualPayload: {
|
|
4646
|
+
[x: string]: any;
|
|
4647
|
+
};
|
|
4642
4648
|
accountId: string | string[] | undefined;
|
|
4643
4649
|
publishedAt: string;
|
|
4644
4650
|
};
|
package/dist/core/index.js
CHANGED
|
@@ -2315,7 +2315,7 @@ var handler2 = (container) => (ev) => __async(null, null, function* () {
|
|
|
2315
2315
|
const { entityRepository, mutualRepository, publishEvent: publishEvent2 } = container;
|
|
2316
2316
|
yield Promise.allSettled(
|
|
2317
2317
|
ev.Records.map((record) => __async(null, null, function* () {
|
|
2318
|
-
var _a, _b, _c, _d;
|
|
2318
|
+
var _a, _b, _c, _d, _e;
|
|
2319
2319
|
const errorContext = {};
|
|
2320
2320
|
const body = parseSQSBusEvent(record.body);
|
|
2321
2321
|
const { detail } = body;
|
|
@@ -2338,6 +2338,7 @@ var handler2 = (container) => (ev) => __async(null, null, function* () {
|
|
|
2338
2338
|
);
|
|
2339
2339
|
}
|
|
2340
2340
|
const mutualDataProcessor = (_d = config.mutualDataProcessor) != null ? _d : (() => ({}));
|
|
2341
|
+
const mutualDataSchema = (_e = config.mutual) == null ? void 0 : _e.mutualDataSchema;
|
|
2341
2342
|
yield mutualRepository.createMutualLock({
|
|
2342
2343
|
byEntityType,
|
|
2343
2344
|
byEntityId,
|
|
@@ -2373,6 +2374,20 @@ var handler2 = (container) => (ev) => __async(null, null, function* () {
|
|
|
2373
2374
|
addedEntityIds,
|
|
2374
2375
|
(id) => __async(null, null, function* () {
|
|
2375
2376
|
const entity = yield entityRepository.getEntity(entityType, id);
|
|
2377
|
+
const processedMutualData = mutualDataProcessor(
|
|
2378
|
+
mutualIds,
|
|
2379
|
+
new Mutual(
|
|
2380
|
+
byEntityType,
|
|
2381
|
+
byEntityId,
|
|
2382
|
+
byEntity.data,
|
|
2383
|
+
entityType,
|
|
2384
|
+
id,
|
|
2385
|
+
entity.data,
|
|
2386
|
+
{}
|
|
2387
|
+
),
|
|
2388
|
+
customContext
|
|
2389
|
+
);
|
|
2390
|
+
const parsedMutualData = mutualDataSchema ? mutualDataSchema.parse(processedMutualData) : processedMutualData;
|
|
2376
2391
|
yield mutualRepository.createMutual(
|
|
2377
2392
|
byEntityType,
|
|
2378
2393
|
byEntityId,
|
|
@@ -2380,19 +2395,7 @@ var handler2 = (container) => (ev) => __async(null, null, function* () {
|
|
|
2380
2395
|
entityType,
|
|
2381
2396
|
id,
|
|
2382
2397
|
entity.data,
|
|
2383
|
-
|
|
2384
|
-
mutualIds,
|
|
2385
|
-
new Mutual(
|
|
2386
|
-
byEntityType,
|
|
2387
|
-
byEntityId,
|
|
2388
|
-
byEntity.data,
|
|
2389
|
-
entityType,
|
|
2390
|
-
id,
|
|
2391
|
-
entity.data,
|
|
2392
|
-
{}
|
|
2393
|
-
),
|
|
2394
|
-
customContext
|
|
2395
|
-
),
|
|
2398
|
+
parsedMutualData,
|
|
2396
2399
|
{
|
|
2397
2400
|
ConditionExpression: "attribute_not_exists(#mutualUpdatedAt) OR #mutualUpdatedAt < :publishedAt",
|
|
2398
2401
|
ExpressionAttributeNames: {
|
|
@@ -2429,25 +2432,27 @@ var handler2 = (container) => (ev) => __async(null, null, function* () {
|
|
|
2429
2432
|
const updateEntities = yield processEntities(
|
|
2430
2433
|
toUpdateEntityIds,
|
|
2431
2434
|
(id) => __async(null, null, function* () {
|
|
2435
|
+
const processedMutualData = mutualDataProcessor(
|
|
2436
|
+
mutualIds,
|
|
2437
|
+
new Mutual(
|
|
2438
|
+
byEntityType,
|
|
2439
|
+
byEntityId,
|
|
2440
|
+
byEntity.data,
|
|
2441
|
+
entityType,
|
|
2442
|
+
id,
|
|
2443
|
+
{},
|
|
2444
|
+
{}
|
|
2445
|
+
),
|
|
2446
|
+
customContext
|
|
2447
|
+
);
|
|
2448
|
+
const parsedMutualData = mutualDataSchema ? mutualDataSchema.parse(processedMutualData) : processedMutualData;
|
|
2432
2449
|
yield mutualRepository.updateMutual(
|
|
2433
2450
|
byEntityType,
|
|
2434
2451
|
byEntityId,
|
|
2435
2452
|
entityType,
|
|
2436
2453
|
id,
|
|
2437
2454
|
{
|
|
2438
|
-
mutualData:
|
|
2439
|
-
mutualIds,
|
|
2440
|
-
new Mutual(
|
|
2441
|
-
byEntityType,
|
|
2442
|
-
byEntityId,
|
|
2443
|
-
byEntity.data,
|
|
2444
|
-
entityType,
|
|
2445
|
-
id,
|
|
2446
|
-
{},
|
|
2447
|
-
{}
|
|
2448
|
-
),
|
|
2449
|
-
customContext
|
|
2450
|
-
),
|
|
2455
|
+
mutualData: parsedMutualData,
|
|
2451
2456
|
mutualUpdatedAt: publishedAt
|
|
2452
2457
|
},
|
|
2453
2458
|
{
|
|
@@ -8510,7 +8515,8 @@ var EntityService = class {
|
|
|
8510
8515
|
// services/mutual.service.ts
|
|
8511
8516
|
import { ulid as ulid4 } from "ulid";
|
|
8512
8517
|
var MutualService = class {
|
|
8513
|
-
constructor(entityRepository, mutualRepository, publishEvent2, ddbUtils, entityServiceLifeCycle) {
|
|
8518
|
+
constructor(EntityConfig, entityRepository, mutualRepository, publishEvent2, ddbUtils, entityServiceLifeCycle) {
|
|
8519
|
+
this.EntityConfig = EntityConfig;
|
|
8514
8520
|
this.entityRepository = entityRepository;
|
|
8515
8521
|
this.mutualRepository = mutualRepository;
|
|
8516
8522
|
this.publishEvent = publishEvent2;
|
|
@@ -8525,6 +8531,7 @@ var MutualService = class {
|
|
|
8525
8531
|
accountId,
|
|
8526
8532
|
options = {}
|
|
8527
8533
|
}) {
|
|
8534
|
+
var _a;
|
|
8528
8535
|
const {
|
|
8529
8536
|
ensureEntityStrongConsistentWrite = false,
|
|
8530
8537
|
asEntity,
|
|
@@ -8545,7 +8552,7 @@ var MutualService = class {
|
|
|
8545
8552
|
options
|
|
8546
8553
|
}
|
|
8547
8554
|
};
|
|
8548
|
-
const schema = external_exports.record(external_exports.string(), external_exports.any());
|
|
8555
|
+
const schema = (_a = this.getMutualDataSchema(byEntityType, entityType)) != null ? _a : external_exports.record(external_exports.string(), external_exports.any());
|
|
8549
8556
|
const parsedMutualPayload = schema.parse(mutualPayload);
|
|
8550
8557
|
const [{ data: byEntityData }, { data: entityData }] = yield Promise.all([
|
|
8551
8558
|
this.entityRepository.getEntity(byEntityType, byEntityId),
|
|
@@ -8648,7 +8655,8 @@ var MutualService = class {
|
|
|
8648
8655
|
accountId,
|
|
8649
8656
|
options
|
|
8650
8657
|
}) {
|
|
8651
|
-
|
|
8658
|
+
var _a;
|
|
8659
|
+
const schema = (_a = this.getMutualDataSchema(byEntityType, entityType)) != null ? _a : external_exports.record(external_exports.string(), external_exports.any());
|
|
8652
8660
|
const parsedMutualPayload = schema.parse(mutualPayload);
|
|
8653
8661
|
const mutual = yield this.mutualRepository.updateMutual(
|
|
8654
8662
|
byEntityType,
|
|
@@ -8697,6 +8705,22 @@ var MutualService = class {
|
|
|
8697
8705
|
return mutual;
|
|
8698
8706
|
});
|
|
8699
8707
|
}
|
|
8708
|
+
getMutualDataSchema(byEntityType, entityType) {
|
|
8709
|
+
var _a, _b, _c;
|
|
8710
|
+
for (const [from, to] of [
|
|
8711
|
+
[byEntityType, entityType],
|
|
8712
|
+
[entityType, byEntityType]
|
|
8713
|
+
]) {
|
|
8714
|
+
const mutualFields = (_b = (_a = this.EntityConfig[from]) == null ? void 0 : _a.mutual) == null ? void 0 : _b.mutualFields;
|
|
8715
|
+
if (!mutualFields) continue;
|
|
8716
|
+
for (const config of Object.values(mutualFields)) {
|
|
8717
|
+
if (config.entityType === to && ((_c = config.mutual) == null ? void 0 : _c.mutualDataSchema)) {
|
|
8718
|
+
return config.mutual.mutualDataSchema;
|
|
8719
|
+
}
|
|
8720
|
+
}
|
|
8721
|
+
}
|
|
8722
|
+
return void 0;
|
|
8723
|
+
}
|
|
8700
8724
|
};
|
|
8701
8725
|
|
|
8702
8726
|
// controllers/tag/list-tags.controller.ts
|
|
@@ -9395,6 +9419,7 @@ var DependencyContainer = class {
|
|
|
9395
9419
|
get mutualService() {
|
|
9396
9420
|
return this.createCachedInstance(
|
|
9397
9421
|
MutualService,
|
|
9422
|
+
this.config.EntityConfig,
|
|
9398
9423
|
this.entityRepository,
|
|
9399
9424
|
this.mutualRepository,
|
|
9400
9425
|
this.publishEvent,
|