@mondaydotcomorg/monday-authorization 3.5.3-feat-shaime-support-entity-attributes-in-authorization-sdk-a77c130 → 3.7.0-feat-shaime-support-entity-attributes-4-49e1de0

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.
Files changed (98) hide show
  1. package/dist/authorization-attributes-ms-service.d.ts +6 -8
  2. package/dist/authorization-attributes-ms-service.d.ts.map +1 -1
  3. package/dist/authorization-attributes-ms-service.js +13 -75
  4. package/dist/authorization-attributes-service.d.ts +1 -2
  5. package/dist/authorization-attributes-service.d.ts.map +1 -1
  6. package/dist/authorization-attributes-service.js +0 -1
  7. package/dist/authorization-attributes-sns-service.d.ts +4 -3
  8. package/dist/authorization-attributes-sns-service.d.ts.map +1 -1
  9. package/dist/authorization-middleware.d.ts +2 -2
  10. package/dist/authorization-middleware.d.ts.map +1 -1
  11. package/dist/authorization-service.d.ts +3 -3
  12. package/dist/authorization-service.d.ts.map +1 -1
  13. package/dist/base-attribute-assignment.d.ts +2 -0
  14. package/dist/base-attribute-assignment.d.ts.map +1 -1
  15. package/dist/base-attribute-assignment.js +11 -18
  16. package/dist/entity-attribute-assignment.js +1 -1
  17. package/dist/entity-attributes-constants.d.ts +6 -6
  18. package/dist/entity-attributes-constants.d.ts.map +1 -1
  19. package/dist/entity-attributes-constants.js +7 -5
  20. package/dist/errors/argument-error.d.ts.map +1 -1
  21. package/dist/errors/argument-error.js +0 -1
  22. package/dist/esm/authorization-attributes-ms-service.d.ts +6 -8
  23. package/dist/esm/authorization-attributes-ms-service.d.ts.map +1 -1
  24. package/dist/esm/authorization-attributes-ms-service.mjs +13 -75
  25. package/dist/esm/authorization-attributes-service.d.ts +1 -2
  26. package/dist/esm/authorization-attributes-service.d.ts.map +1 -1
  27. package/dist/esm/authorization-attributes-service.mjs +0 -1
  28. package/dist/esm/authorization-attributes-sns-service.d.ts +4 -3
  29. package/dist/esm/authorization-attributes-sns-service.d.ts.map +1 -1
  30. package/dist/esm/authorization-middleware.d.ts +2 -2
  31. package/dist/esm/authorization-middleware.d.ts.map +1 -1
  32. package/dist/esm/authorization-service.d.ts +3 -3
  33. package/dist/esm/authorization-service.d.ts.map +1 -1
  34. package/dist/esm/base-attribute-assignment.d.ts +2 -0
  35. package/dist/esm/base-attribute-assignment.d.ts.map +1 -1
  36. package/dist/esm/base-attribute-assignment.mjs +7 -18
  37. package/dist/esm/entity-attribute-assignment.mjs +1 -1
  38. package/dist/esm/entity-attributes-constants.d.ts +6 -6
  39. package/dist/esm/entity-attributes-constants.d.ts.map +1 -1
  40. package/dist/esm/entity-attributes-constants.mjs +8 -6
  41. package/dist/esm/errors/argument-error.d.ts.map +1 -1
  42. package/dist/esm/errors/argument-error.mjs +0 -1
  43. package/dist/esm/index.d.ts +0 -9
  44. package/dist/esm/index.d.ts.map +1 -1
  45. package/dist/esm/index.mjs +0 -7
  46. package/dist/esm/prometheus-service.d.ts +2 -1
  47. package/dist/esm/prometheus-service.d.ts.map +1 -1
  48. package/dist/esm/resource-attribute-assignment.d.ts +1 -1
  49. package/dist/esm/resource-attribute-assignment.d.ts.map +1 -1
  50. package/dist/esm/resource-attributes-constants.d.ts +12 -2
  51. package/dist/esm/resource-attributes-constants.d.ts.map +1 -1
  52. package/dist/esm/resource-attributes-constants.mjs +15 -12
  53. package/dist/esm/types/authorization-attributes-contracts.d.ts +1 -1
  54. package/dist/esm/types/authorization-attributes-contracts.d.ts.map +1 -1
  55. package/dist/esm/types/authorization-attributes-service.interface.d.ts +4 -3
  56. package/dist/esm/types/authorization-attributes-service.interface.d.ts.map +1 -1
  57. package/dist/esm/types/general.d.ts +2 -1
  58. package/dist/esm/types/general.d.ts.map +1 -1
  59. package/dist/esm/utils/validation.d.ts +30 -30
  60. package/dist/esm/utils/validation.d.ts.map +1 -1
  61. package/dist/esm/utils/validation.mjs +121 -86
  62. package/dist/index.d.ts +0 -9
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +0 -15
  65. package/dist/prometheus-service.d.ts +2 -1
  66. package/dist/prometheus-service.d.ts.map +1 -1
  67. package/dist/resource-attribute-assignment.d.ts +1 -1
  68. package/dist/resource-attribute-assignment.d.ts.map +1 -1
  69. package/dist/resource-attributes-constants.d.ts +12 -2
  70. package/dist/resource-attributes-constants.d.ts.map +1 -1
  71. package/dist/resource-attributes-constants.js +14 -11
  72. package/dist/types/authorization-attributes-contracts.d.ts +1 -1
  73. package/dist/types/authorization-attributes-contracts.d.ts.map +1 -1
  74. package/dist/types/authorization-attributes-service.interface.d.ts +4 -3
  75. package/dist/types/authorization-attributes-service.interface.d.ts.map +1 -1
  76. package/dist/types/general.d.ts +2 -1
  77. package/dist/types/general.d.ts.map +1 -1
  78. package/dist/utils/validation.d.ts +30 -30
  79. package/dist/utils/validation.d.ts.map +1 -1
  80. package/dist/utils/validation.js +125 -86
  81. package/package.json +4 -3
  82. package/src/authorization-attributes-ms-service.ts +20 -97
  83. package/src/authorization-attributes-service.ts +1 -2
  84. package/src/authorization-attributes-sns-service.ts +3 -3
  85. package/src/authorization-middleware.ts +2 -2
  86. package/src/authorization-service.ts +4 -4
  87. package/src/base-attribute-assignment.ts +14 -23
  88. package/src/entity-attribute-assignment.ts +1 -1
  89. package/src/entity-attributes-constants.ts +6 -6
  90. package/src/errors/argument-error.ts +0 -1
  91. package/src/index.ts +0 -9
  92. package/src/prometheus-service.ts +3 -1
  93. package/src/resource-attribute-assignment.ts +1 -1
  94. package/src/resource-attributes-constants.ts +13 -21
  95. package/src/types/authorization-attributes-contracts.ts +0 -2
  96. package/src/types/authorization-attributes-service.interface.ts +3 -3
  97. package/src/types/general.ts +2 -3
  98. package/src/utils/validation.ts +139 -82
@@ -1,45 +1,45 @@
1
+ import { Resource } from '../types/general';
1
2
  /**
2
- * Utility class for common validation operations using Zod
3
+ * Utility class for common validation operations using AJV
3
4
  */
4
5
  export declare class ValidationUtils {
6
+ private static ajv;
5
7
  /**
6
- * Validates that a value is an integer
7
- * @param value The value to validate
8
- * @param fieldName The name of the field for error messages
9
- * @throws ArgumentError if value is not an integer
8
+ * Validates that a value is an integer. Throws ArgumentError with a descriptive message on failure.
10
9
  */
11
- static validateInteger(value: any, fieldName: string): void;
10
+ static validateInteger(value: number): void;
12
11
  /**
13
- * Validates that a value is a non-empty string
14
- * @param value The value to validate
15
- * @param fieldName The name of the field for error messages
16
- * @throws ArgumentError if value is not a string or is empty
12
+ * Validates that a value is a non-empty string. Throws ArgumentError on failure.
17
13
  */
18
- static validateString(value: any, fieldName: string): void;
14
+ static validateString(value: string): void;
19
15
  /**
20
- * Validates that a value is an array and optionally checks minimum length
21
- * @param value The value to validate
22
- * @param fieldName The name of the field for error messages
23
- * @param minLength Minimum required length (default: 0)
24
- * @returns The validated array
25
- * @throws ArgumentError if value is not an array or doesn't meet minimum length
16
+ * Validates that a value is an array of non-empty strings. Throws ArgumentError on failure.
17
+ * Allows empty arrays - caller should handle early return.
26
18
  */
27
- static validateArray<T>(value: any, fieldName: string, minLength?: number): T[];
19
+ static validateStringArray(value: string[]): void;
28
20
  /**
29
- * Validates that a value is one of the allowed enum values
30
- * @param value The value to validate
31
- * @param validValues Array of valid values
32
- * @param fieldName The name of the field for error messages
33
- * @returns The validated value as the enum type
34
- * @throws ArgumentError if value is not in validValues
21
+ * Validates an attribute assignment object using a single AJV schema.
22
+ * Preserves legacy error messages for each field.
35
23
  */
36
- static validateEnum<T extends string>(value: string, validValues: readonly T[], fieldName: string): T;
24
+ static validateAssignment<TType extends string>(data: {
25
+ id: any;
26
+ type: string;
27
+ attributeKey: any;
28
+ attributeValue: any;
29
+ }, validTypes: readonly TType[], fieldNames: {
30
+ id: string;
31
+ type: string;
32
+ }): {
33
+ id: number;
34
+ type: TType;
35
+ attributeKey: string;
36
+ attributeValue: string;
37
+ };
37
38
  /**
38
- * Validates that all items in an array are strings
39
- * @param value Array to validate
40
- * @param fieldName The name of the field for error messages
41
- * @throws ArgumentError if any item is not a string
39
+ * Validates a Resource-like object shape: { id: number; type: string }.
40
+ * Throws ArgumentError with legacy-compatible messages.
42
41
  */
43
- static validateStringArray(value: any[], fieldName: string): void;
42
+ static validateResource(resource: Resource): void;
43
+ static validateArrayTypeOf<T>(attributesMessages: T[], messageClass: abstract new (...args: any[]) => T): void;
44
44
  }
45
45
  //# sourceMappingURL=validation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,qBAAa,eAAe;IAC1B;;;;;OAKG;IACH,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAY3D;;;;;OAKG;IACH,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAe1D;;;;;;;OAOG;IACH,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,SAAI,GAAG,CAAC,EAAE;IAe1E;;;;;;;OAOG;IACH,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,CAAC;IAYrG;;;;;OAKG;IACH,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;CAkBlE"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,GAAG,CAAgC;IAClD;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAS3C;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAa1C;;;OAGG;IACH,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAkBjD;;;OAGG;IACH,MAAM,CAAC,kBAAkB,CAAC,KAAK,SAAS,MAAM,EAC5C,IAAI,EAAE;QAAE,EAAE,EAAE,GAAG,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,GAAG,CAAC;QAAC,cAAc,EAAE,GAAG,CAAA;KAAE,EACvE,UAAU,EAAE,SAAS,KAAK,EAAE,EAC5B,UAAU,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GACvC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,KAAK,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE;IA0D5E;;;OAGG;IACH,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAqBjD,MAAM,CAAC,mBAAmB,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI;CAoB/G"}
@@ -1,117 +1,156 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
- const zod = require('zod');
3
+ const Ajv = require('ajv');
4
4
  const errors_argumentError = require('../errors/argument-error.js');
5
5
 
6
+ const _interopDefault = e => e && e.__esModule ? e : { default: e };
7
+
8
+ const Ajv__default = /*#__PURE__*/_interopDefault(Ajv);
9
+
6
10
  /**
7
- * Utility class for common validation operations using Zod
11
+ * Utility class for common validation operations using AJV
8
12
  */
9
13
  class ValidationUtils {
14
+ static ajv = new Ajv__default.default({ allErrors: true });
10
15
  /**
11
- * Validates that a value is an integer
12
- * @param value The value to validate
13
- * @param fieldName The name of the field for error messages
14
- * @throws ArgumentError if value is not an integer
16
+ * Validates that a value is an integer. Throws ArgumentError with a descriptive message on failure.
15
17
  */
16
- static validateInteger(value, fieldName) {
17
- const schema = zod.z.number().int();
18
- try {
19
- schema.parse(value);
20
- }
21
- catch (error) {
22
- if (error instanceof zod.z.ZodError) {
23
- throw new errors_argumentError.ArgumentError(`${fieldName} must be an integer, got: ${value}`);
24
- }
25
- throw error;
18
+ static validateInteger(value) {
19
+ const numberSchema = { type: 'number', multipleOf: 1 };
20
+ const validate = ValidationUtils.ajv.compile(numberSchema);
21
+ const isValid = validate(value);
22
+ if (!isValid) {
23
+ throw new errors_argumentError.ArgumentError(`Value must be an integer, got: ${value}`);
26
24
  }
27
25
  }
28
26
  /**
29
- * Validates that a value is a non-empty string
30
- * @param value The value to validate
31
- * @param fieldName The name of the field for error messages
32
- * @throws ArgumentError if value is not a string or is empty
27
+ * Validates that a value is a non-empty string. Throws ArgumentError on failure.
33
28
  */
34
- static validateString(value, fieldName) {
35
- const schema = zod.z.string().min(1);
36
- try {
37
- schema.parse(value);
38
- }
39
- catch (error) {
40
- if (error instanceof zod.z.ZodError) {
41
- if (typeof value !== 'string') {
42
- throw new errors_argumentError.ArgumentError(`${fieldName} must be a string, got: ${typeof value}`);
43
- }
44
- throw new errors_argumentError.ArgumentError(`${fieldName} must be a non-empty string`);
45
- }
46
- throw error;
29
+ static validateString(value) {
30
+ const non_empty_string_schema = {
31
+ type: 'string',
32
+ minLength: 1,
33
+ pattern: '\\S',
34
+ };
35
+ const validate = ValidationUtils.ajv.compile(non_empty_string_schema);
36
+ const isValid = validate(value);
37
+ if (!isValid) {
38
+ throw new errors_argumentError.ArgumentError(`Value must be a non-empty string, got: ${value}`);
47
39
  }
48
40
  }
49
41
  /**
50
- * Validates that a value is an array and optionally checks minimum length
51
- * @param value The value to validate
52
- * @param fieldName The name of the field for error messages
53
- * @param minLength Minimum required length (default: 0)
54
- * @returns The validated array
55
- * @throws ArgumentError if value is not an array or doesn't meet minimum length
42
+ * Validates that a value is an array of non-empty strings. Throws ArgumentError on failure.
43
+ * Allows empty arrays - caller should handle early return.
56
44
  */
57
- static validateArray(value, fieldName, minLength = 0) {
58
- const schema = zod.z.array(zod.z.any()).min(minLength);
59
- try {
60
- return schema.parse(value);
61
- }
62
- catch (error) {
63
- if (error instanceof zod.z.ZodError) {
64
- if (!Array.isArray(value)) {
65
- throw new errors_argumentError.ArgumentError(`${fieldName} must be an array`);
66
- }
67
- throw new errors_argumentError.ArgumentError(`${fieldName} must have at least ${minLength} items`);
68
- }
69
- throw error;
45
+ static validateStringArray(value) {
46
+ const string_array_schema = {
47
+ type: 'array',
48
+ items: {
49
+ type: 'string',
50
+ minLength: 1,
51
+ pattern: '\\S',
52
+ },
53
+ };
54
+ const validateStringArray = ValidationUtils.ajv.compile(string_array_schema);
55
+ const isValid = validateStringArray(value);
56
+ if (!isValid) {
57
+ throw new errors_argumentError.ArgumentError(`Value must be an array of non-empty strings, got: ${value}`);
70
58
  }
59
+ // Allow empty arrays to pass validation - caller should handle early return
60
+ // Non-empty arrays will be validated for string content above
71
61
  }
72
62
  /**
73
- * Validates that a value is one of the allowed enum values
74
- * @param value The value to validate
75
- * @param validValues Array of valid values
76
- * @param fieldName The name of the field for error messages
77
- * @returns The validated value as the enum type
78
- * @throws ArgumentError if value is not in validValues
63
+ * Validates an attribute assignment object using a single AJV schema.
64
+ * Preserves legacy error messages for each field.
79
65
  */
80
- static validateEnum(value, validValues, fieldName) {
81
- const schema = zod.z.enum(validValues);
82
- try {
83
- return schema.parse(value);
84
- }
85
- catch (error) {
86
- if (error instanceof zod.z.ZodError) {
87
- throw new errors_argumentError.ArgumentError(`${fieldName} must be one of [${validValues.join(', ')}], got: ${value}`);
66
+ static validateAssignment(data, validTypes, fieldNames) {
67
+ const schema = {
68
+ type: 'object',
69
+ properties: {
70
+ id: { type: 'number', multipleOf: 1 },
71
+ type: { type: 'string', enum: validTypes },
72
+ attributeKey: { type: 'string', minLength: 1 },
73
+ attributeValue: { type: 'string', minLength: 1 },
74
+ },
75
+ required: ['id', 'type', 'attributeKey', 'attributeValue'],
76
+ additionalProperties: false,
77
+ };
78
+ const validate = this.ajv.compile(schema);
79
+ const valid = validate(data);
80
+ if (!valid) {
81
+ // Map to legacy error messages deterministically
82
+ const { id, type, attributeKey, attributeValue } = data;
83
+ // id must be integer
84
+ const isInteger = typeof id === 'number' && Number.isFinite(id) && Math.floor(id) === id;
85
+ if (!isInteger) {
86
+ throw new errors_argumentError.ArgumentError(`${fieldNames.id} must be an integer, got: ${id}`);
88
87
  }
89
- throw error;
88
+ // type must be within enum
89
+ if (typeof type !== 'string' || !validTypes.includes(type)) {
90
+ throw new errors_argumentError.ArgumentError(`${fieldNames.type} must be one of [${validTypes.join(', ')}], got: ${type}`);
91
+ }
92
+ // attributeKey
93
+ if (typeof attributeKey !== 'string') {
94
+ throw new errors_argumentError.ArgumentError(`attributeKey must be a string, got: ${typeof attributeKey}`);
95
+ }
96
+ if (!attributeKey) {
97
+ throw new errors_argumentError.ArgumentError('attributeKey must be a non-empty string');
98
+ }
99
+ // attributeValue
100
+ if (typeof attributeValue !== 'string') {
101
+ throw new errors_argumentError.ArgumentError(`attributeValue must be a string, got: ${typeof attributeValue}`);
102
+ }
103
+ if (!attributeValue) {
104
+ throw new errors_argumentError.ArgumentError('attributeValue must be a non-empty string');
105
+ }
106
+ // Fallback
107
+ throw new errors_argumentError.ArgumentError('Invalid attribute assignment');
90
108
  }
109
+ return {
110
+ id: data.id,
111
+ type: data.type,
112
+ attributeKey: data.attributeKey,
113
+ attributeValue: data.attributeValue,
114
+ };
91
115
  }
92
116
  /**
93
- * Validates that all items in an array are strings
94
- * @param value Array to validate
95
- * @param fieldName The name of the field for error messages
96
- * @throws ArgumentError if any item is not a string
117
+ * Validates a Resource-like object shape: { id: number; type: string }.
118
+ * Throws ArgumentError with legacy-compatible messages.
97
119
  */
98
- static validateStringArray(value, fieldName) {
99
- const schema = zod.z.array(zod.z.string());
100
- try {
101
- schema.parse(value);
120
+ static validateResource(resource) {
121
+ if (!resource || typeof resource !== 'object') {
122
+ throw new errors_argumentError.ArgumentError('resource must be an object');
123
+ }
124
+ const schema = {
125
+ type: 'object',
126
+ properties: {
127
+ id: { type: 'number', multipleOf: 1 },
128
+ type: { type: 'string', minLength: 1 },
129
+ wrapperData: { type: 'string' },
130
+ },
131
+ required: ['type', 'id'],
132
+ additionalProperties: false,
133
+ };
134
+ const validate = this.ajv.compile(schema);
135
+ const isValid = validate(resource);
136
+ if (!isValid) {
137
+ throw new errors_argumentError.ArgumentError('Invalid resource');
138
+ }
139
+ }
140
+ static validateArrayTypeOf(attributesMessages, messageClass) {
141
+ const arraySchema = {
142
+ type: 'array',
143
+ };
144
+ const validateArray = ValidationUtils.ajv.compile(arraySchema);
145
+ const isArrayValid = validateArray(attributesMessages);
146
+ if (!isArrayValid) {
147
+ throw new errors_argumentError.ArgumentError(`attributesMessages must be an array`);
102
148
  }
103
- catch (error) {
104
- if (error instanceof zod.z.ZodError) {
105
- const zodError = error;
106
- const firstError = zodError.issues[0];
107
- // Check if it's an array item validation error
108
- if (firstError.path.length > 0 && typeof firstError.path[0] === 'number') {
109
- const index = firstError.path[0];
110
- throw new errors_argumentError.ArgumentError(`All ${fieldName} must be strings, but item at index ${index} is not`);
111
- }
112
- throw new errors_argumentError.ArgumentError(`${fieldName} must be an array`);
149
+ for (let i = 0; i < attributesMessages.length; i++) {
150
+ const item = attributesMessages[i];
151
+ if (!(item instanceof messageClass)) {
152
+ throw new errors_argumentError.ArgumentError(`attributesMessages[${i}] must be an instance of ${messageClass.name}, got: ${item?.constructor?.name || typeof item}`);
113
153
  }
114
- throw error;
115
154
  }
116
155
  }
117
156
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mondaydotcomorg/monday-authorization",
3
- "version": "3.5.3-feat-shaime-support-entity-attributes-in-authorization-sdk-a77c130",
3
+ "version": "3.7.0-feat-shaime-support-entity-attributes-4-49e1de0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "BSD-3-Clause",
@@ -28,11 +28,12 @@
28
28
  "@mondaydotcomorg/monday-observability-kit": "^1.5.3",
29
29
  "@mondaydotcomorg/monday-sns": "^1.2.1",
30
30
  "@mondaydotcomorg/trident-backend-api": "^0.24.3",
31
+ "ajv": "^8.17.1",
32
+ "ajv-keywords": "^5.1.0",
31
33
  "lodash": "^4.17.21",
32
34
  "node-fetch": "^2.6.7",
33
35
  "on-headers": "^1.0.2",
34
- "ts-node": "^10.0.0",
35
- "zod": "^4.1.13"
36
+ "ts-node": "^10.0.0"
36
37
  },
37
38
  "devDependencies": {
38
39
  "@mondaydotcomorg/trident-library": "^1.1.44",
@@ -1,20 +1,19 @@
1
1
  import { Api, HttpClient } from '@mondaydotcomorg/trident-backend-api';
2
2
  import { signAuthorizationHeader } from '@mondaydotcomorg/monday-jwt';
3
- import { z } from 'zod';
4
3
  import { ResourceAttributeAssignment } from './resource-attribute-assignment';
5
4
  import { EntityAttributeAssignment } from './entity-attribute-assignment';
6
5
  import {
7
6
  AttributeOperation,
8
- EntityType,
9
7
  ResourceAttributeOperation,
10
8
  EntityAttributeOperation,
11
9
  } from './types/authorization-attributes-contracts';
10
+ import { EntityType } from './entity-attributes-constants';
12
11
  import { ArgumentError } from './errors/argument-error';
13
12
  import { AuthorizationInternalService, logger } from './authorization-internal-service';
14
13
  import { getAttributionsFromApi } from './attributions-service';
15
14
  import { APP_NAME } from './constants';
16
15
  import { ValidationUtils } from './utils/validation';
17
- import { IAuthorizationAttributesService } from './types/authorization-attributes-service.interface';
16
+ import { AuthorizationAttributesService } from './types/authorization-attributes-service.interface';
18
17
  import { Resource } from './types/general';
19
18
  const INTERNAL_APP_NAME = 'internal_ms';
20
19
  const UPSERT_RESOURCE_ATTRIBUTES_PATH = '/attributes/{accountId}/resource';
@@ -30,9 +29,14 @@ interface DeleteRequestBody {
30
29
  * Service class for managing resource attributes in the authorization microservice.
31
30
  * Provides synchronous HTTP operations to create/update and delete attributes on resources.
32
31
  */
33
- export class AuthorizationAttributesMsService implements IAuthorizationAttributesService {
32
+ export class AuthorizationAttributesMsService implements AuthorizationAttributesService {
34
33
  private static LOG_TAG = 'authorization_attributes_ms';
35
- private static httpClient: HttpClient | undefined = Api.getPart('httpClient');
34
+ private static httpClient: HttpClient | null = Api.getPart('httpClient') ?? null;
35
+
36
+ public static destroyHttpClient(): void {
37
+ AuthorizationAttributesMsService.httpClient = null;
38
+ }
39
+
36
40
  /**
37
41
  * Creates or updates resource attributes synchronously.
38
42
  * @param accountId The account ID
@@ -70,22 +74,14 @@ export class AuthorizationAttributesMsService implements IAuthorizationAttribute
70
74
  _appName?: string,
71
75
  _callerActionIdentifier?: string
72
76
  ): Promise<void> {
73
- // Validate resource object
74
- if (!resource || typeof resource !== 'object') {
75
- throw new ArgumentError('resource must be an object');
76
- }
77
- if (!resource.id) {
78
- throw new ArgumentError('resource.id is required');
79
- }
80
- ValidationUtils.validateInteger(resource.id, 'resource.id');
81
- ValidationUtils.validateString(resource.type, 'resource.type');
82
-
77
+ ValidationUtils.validateResource(resource);
78
+ ValidationUtils.validateStringArray(attributeKeys);
83
79
  return AuthorizationAttributesMsService.executeDeleteRequest(
84
80
  accountId,
85
81
  DELETE_RESOURCE_ATTRIBUTES_PATH,
86
82
  {
87
83
  resourceType: resource.type,
88
- resourceId: resource.id,
84
+ resourceId: resource.id as number,
89
85
  },
90
86
  attributeKeys,
91
87
  'resource',
@@ -127,7 +123,7 @@ export class AuthorizationAttributesMsService implements IAuthorizationAttribute
127
123
  */
128
124
  async deleteEntityAttributes(
129
125
  accountId: number,
130
- entityType: EntityType | string,
126
+ entityType: EntityType,
131
127
  entityId: number,
132
128
  attributeKeys: string[],
133
129
  _appName?: string,
@@ -136,7 +132,7 @@ export class AuthorizationAttributesMsService implements IAuthorizationAttribute
136
132
  if (!entityType || typeof entityType !== 'string' || entityType.trim() === '') {
137
133
  throw new ArgumentError(`entityType must be a non-empty string, got: ${entityType}`);
138
134
  }
139
- ValidationUtils.validateInteger(entityId, 'entityId');
135
+ ValidationUtils.validateInteger(entityId);
140
136
 
141
137
  return AuthorizationAttributesMsService.executeDeleteRequest(
142
138
  accountId,
@@ -262,21 +258,14 @@ export class AuthorizationAttributesMsService implements IAuthorizationAttribute
262
258
  context: Record<string, any> = {}
263
259
  ): Promise<void> {
264
260
  // Validate inputs
265
- ValidationUtils.validateInteger(accountId, 'accountId');
266
- ValidationUtils.validateArray(keys, 'attributeKeys');
261
+ ValidationUtils.validateInteger(accountId);
262
+ ValidationUtils.validateStringArray(keys);
267
263
 
268
264
  if (!keys.length) {
269
265
  logger.warn({ tag: this.LOG_TAG, accountId, ...pathParams }, `${methodName} called with empty keys array`);
270
266
  return;
271
267
  }
272
-
273
- // Validate all keys are strings
274
- ValidationUtils.validateStringArray(keys, 'attributeKeys');
275
-
276
- // Build request body
277
- const requestBody: DeleteRequestBody = {
278
- keys,
279
- };
268
+ const requestBody: DeleteRequestBody = { keys };
280
269
 
281
270
  if (!AuthorizationAttributesMsService.httpClient) {
282
271
  throw new Error('AuthorizationAttributesMsService: HTTP client is not initialized');
@@ -306,7 +295,7 @@ export class AuthorizationAttributesMsService implements IAuthorizationAttribute
306
295
  }
307
296
  );
308
297
 
309
- logger.info(
298
+ logger.debug(
310
299
  { tag: AuthorizationAttributesMsService.LOG_TAG, accountId, ...pathParams, keys },
311
300
  `Successfully deleted ${logPrefix} attributes`
312
301
  );
@@ -376,63 +365,6 @@ export class AuthorizationAttributesMsService implements IAuthorizationAttribute
376
365
  return headers;
377
366
  }
378
367
 
379
- /**
380
- * Validates that all messages are instances of the specified message class
381
- */
382
- private static validateMessages<T>(attributesMessages: T[], messageClass: abstract new (...args: any[]) => T): void {
383
- // Validate messageClass is a function using Zod
384
- const classSchema = z.custom<abstract new (...args: any[]) => T>(value => typeof value === 'function', {
385
- message: 'messageClass must be a class/constructor function',
386
- });
387
-
388
- try {
389
- classSchema.parse(messageClass);
390
- } catch (error) {
391
- if (error instanceof z.ZodError) {
392
- const firstError = error.issues[0];
393
- throw new ArgumentError(firstError.message);
394
- }
395
- throw error;
396
- }
397
-
398
- const className = messageClass.name || 'ResourceAttributeAssignment';
399
-
400
- // First validate it's an array
401
- ValidationUtils.validateArray(attributesMessages, 'attributesMessages');
402
-
403
- // Then use Zod to validate each item is an instance of the class
404
- const schema = z.array(z.any()).refine(
405
- items => {
406
- for (let i = 0; i < items.length; i++) {
407
- if (!(items[i] instanceof messageClass)) {
408
- return false;
409
- }
410
- }
411
- return true;
412
- },
413
- {
414
- message: `All attributesMessages must be instances of ${className}`,
415
- }
416
- );
417
-
418
- try {
419
- schema.parse(attributesMessages);
420
- } catch (error) {
421
- if (error instanceof z.ZodError) {
422
- // Find the first invalid index for a more specific error message
423
- const invalidIndex = attributesMessages.findIndex(item => !(item instanceof messageClass));
424
- if (invalidIndex !== -1) {
425
- throw new ArgumentError(
426
- `All attributesMessages must be instances of ${className}, but item at index ${invalidIndex} is not`
427
- );
428
- }
429
- const firstError = error.issues[0];
430
- throw new ArgumentError(firstError.message);
431
- }
432
- throw error;
433
- }
434
- }
435
-
436
368
  /**
437
369
  * Generic helper for executing upsert requests
438
370
  */
@@ -445,20 +377,11 @@ export class AuthorizationAttributesMsService implements IAuthorizationAttribute
445
377
  logPrefix: string,
446
378
  methodName: string
447
379
  ): Promise<void> {
448
- // Validate inputs
449
- ValidationUtils.validateInteger(accountId, 'accountId');
450
- ValidationUtils.validateArray(assignments, 'assignments');
451
-
380
+ ValidationUtils.validateInteger(accountId);
381
+ ValidationUtils.validateArrayTypeOf(assignments, assignmentClass);
452
382
  if (!assignments.length) {
453
- logger.warn(
454
- { tag: AuthorizationAttributesMsService.LOG_TAG, accountId },
455
- `${methodName} called with empty array`
456
- );
457
383
  return;
458
384
  }
459
-
460
- // Validate all assignments are instances of the correct class
461
- AuthorizationAttributesMsService.validateMessages(assignments, assignmentClass);
462
385
  const assignmentDto = assignments.map(assignment => assignment.toDataTransferObject());
463
386
 
464
387
  const requestBody =
@@ -1,13 +1,12 @@
1
1
  import { AuthorizationAttributesMsService } from './authorization-attributes-ms-service';
2
2
  import { AuthorizationAttributesSnsService } from './authorization-attributes-sns-service';
3
- import { IAuthorizationAttributesService } from './types/authorization-attributes-service.interface';
3
+ import { AuthorizationAttributesService as IAuthorizationAttributesService } from './types/authorization-attributes-service.interface';
4
4
 
5
5
  /**
6
6
  * Main service class for managing resource and entity attributes.
7
7
  * Provides access to both direct (MS) and SNS operations.
8
8
  *
9
9
  * @example
10
- * ```typescript
11
10
  * const service = new AuthorizationAttributesService();
12
11
  *
13
12
  * // Use direct operations
@@ -5,7 +5,6 @@ import {
5
5
  ResourceAttributeOperation,
6
6
  EntityAttributeOperation,
7
7
  AttributeOperation,
8
- EntityType,
9
8
  } from './types/authorization-attributes-contracts';
10
9
  import { EntityAttributeAssignment } from './entity-attribute-assignment';
11
10
  import { Resource } from './types/general';
@@ -22,13 +21,14 @@ import {
22
21
  SnsTopicType,
23
22
  } from './constants/sns';
24
23
  import type { TopicAttributesMap } from 'aws-sdk/clients/sns';
25
- import { IAuthorizationAttributesService } from './types/authorization-attributes-service.interface';
24
+ import { AuthorizationAttributesService } from './types/authorization-attributes-service.interface';
25
+ import { EntityType } from './entity-attributes-constants';
26
26
 
27
27
  /**
28
28
  * Service class for managing resource attributes asynchronously via SNS.
29
29
  * Provides asynchronous operations to create/update and delete attributes on resources.
30
30
  */
31
- export class AuthorizationAttributesSnsService implements IAuthorizationAttributesService {
31
+ export class AuthorizationAttributesSnsService implements AuthorizationAttributesService {
32
32
  private static LOG_TAG = 'authorization_attributes';
33
33
  private resourceSnsArn: string;
34
34
  private entitySnsArn: string;
@@ -1,13 +1,13 @@
1
1
  import onHeaders from 'on-headers';
2
2
  import { AuthorizationInternalService } from './authorization-internal-service';
3
3
  import { AuthorizationService, createAuthorizationParams } from './authorization-service';
4
- import { BaseRequest, BaseResponse, Context, ContextGetter, ResourceGetter } from './types/general';
4
+ import { Action, BaseRequest, BaseResponse, Context, ContextGetter, ResourceGetter } from './types/general';
5
5
  import type { NextFunction } from 'express';
6
6
 
7
7
  // getAuthorizationMiddleware is duplicated in testKit/index.ts
8
8
  // If you are making changes to this function, please make sure to update the other file as well
9
9
  export function getAuthorizationMiddleware(
10
- action: string,
10
+ action: Action,
11
11
  resourceGetter: ResourceGetter,
12
12
  contextGetter?: ContextGetter
13
13
  ) {
@@ -3,7 +3,7 @@ import { MondayFetchOptions } from '@mondaydotcomorg/monday-fetch';
3
3
  import { Api } from '@mondaydotcomorg/trident-backend-api';
4
4
  import { HttpFetcherError } from '@mondaydotcomorg/monday-fetch-api';
5
5
  import { getIgniteClient, IgniteClient } from '@mondaydotcomorg/ignite-sdk';
6
- import { AuthorizationObject, AuthorizationParams, Resource } from './types/general';
6
+ import { Action, AuthorizationObject, AuthorizationParams, Resource } from './types/general';
7
7
  import { sendAuthorizationCheckResponseTimeMetric } from './prometheus-service';
8
8
  import { recordAuthorizationTiming } from './metrics-service';
9
9
  import {
@@ -74,7 +74,7 @@ export class AuthorizationService {
74
74
  accountId: number,
75
75
  userId: number,
76
76
  resources: Resource[],
77
- action: string
77
+ action: Action
78
78
  ): Promise<AuthorizeResponse>;
79
79
 
80
80
  static async isAuthorized(
@@ -223,7 +223,7 @@ export class AuthorizationService {
223
223
  accountId: number,
224
224
  userId: number,
225
225
  resources: Resource[],
226
- action: string
226
+ action: Action
227
227
  ): Promise<AuthorizeResponse> {
228
228
  const { authorizationObjects } = createAuthorizationParams(resources, action);
229
229
  return this.isAuthorizedMultiple(accountId, userId, authorizationObjects);
@@ -338,7 +338,7 @@ export async function setIgniteClient() {
338
338
  AuthorizationInternalService.setIgniteClient(igniteClient);
339
339
  }
340
340
 
341
- export function createAuthorizationParams(resources: Resource[], action: string): AuthorizationParams {
341
+ export function createAuthorizationParams(resources: Resource[], action: Action): AuthorizationParams {
342
342
  const params = {
343
343
  authorizationObjects: resources.map((resource: Resource) => {
344
344
  const authorizationObject: AuthorizationObject = {