@zohodesk/library-platform 1.2.2-exp.1 → 1.2.2-exp.2

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,30 +1,5 @@
1
- // OPTIMIZE: Duplicated comparator values from bc/zrecord/Types.ts enums (CommonComparators, TextComparators, NumberComparators, DateComparators)
2
- const filterConfigSchema = {
3
- type: 'object',
4
- properties: {
5
- conditions: {
6
- type: 'array',
7
- items: {
8
- type: 'object',
9
- properties: {
10
- fieldName: {
11
- type: 'string'
12
- },
13
- condition: {
14
- type: 'string',
15
- enum: ['is empty', 'is not empty', 'is', "isn't", 'starts with', 'ends with', 'contains', "doesn't contain", '=', '<>', '<', '<=', '>', '>=', 'is after', 'is before', 'between', 'not between']
16
- },
17
- value: {}
18
- },
19
- required: ['fieldName', 'condition', 'value']
20
- }
21
- },
22
- pattern: {
23
- type: 'string'
24
- }
25
- },
26
- required: ['conditions', 'pattern']
27
- };
1
+ import { SortOrder } from "../../bc/zlist/Types";
2
+ import { filterConfigSchema } from "../../bc/zrecord/Schemas";
28
3
  export const SdkContracts = {
29
4
  getRecordInputMeta: {
30
5
  type: 'object',
@@ -192,7 +167,7 @@ export const SdkContracts = {
192
167
  },
193
168
  order: {
194
169
  type: 'string',
195
- enum: ['ASC', 'DES', 'NONE']
170
+ enum: [SortOrder.ASC, SortOrder.DES, SortOrder.NONE]
196
171
  }
197
172
  }
198
173
  },
@@ -1,8 +1,7 @@
1
+ import { Alignment, Width, SortedBy } from "./data-types/Header";
2
+ import RowCursor from "./data-types/RowCursor";
1
3
  import SelectionConfigProperties from "../../bc/list-selection/Properties";
2
- const actionsSchema = {
3
- type: 'array',
4
- minItems: 0
5
- };
4
+ import { actionsSchema } from "../../platform/client-actions/cc/action-event-mediator/Properties";
6
5
  const TableListProperties = {
7
6
  isReOrderLoading: {
8
7
  required: false,
@@ -48,7 +47,7 @@ const TableListProperties = {
48
47
  properties: {
49
48
  order: {
50
49
  type: 'string',
51
- enum: ['none', 'ascending', 'descending']
50
+ enum: Object.values(SortedBy)
52
51
  },
53
52
  name: {
54
53
  type: 'string'
@@ -111,7 +110,7 @@ const TableListProperties = {
111
110
  required: false,
112
111
  defaultValue: {
113
112
  hasActions: false,
114
- columnWidth: 120
113
+ columnWidth: Width.XSmall
115
114
  },
116
115
  typeMetadata: {
117
116
  schema: {
@@ -143,7 +142,7 @@ const TableListProperties = {
143
142
  typeMetadata: {
144
143
  schema: {
145
144
  type: 'string',
146
- enum: ['default', 'pointer', 'not-allowed']
145
+ enum: Object.values(RowCursor)
147
146
  }
148
147
  }
149
148
  },
@@ -176,11 +175,11 @@ const TableListProperties = {
176
175
  },
177
176
  alignment: {
178
177
  type: 'string',
179
- enum: ['left', 'center', 'right']
178
+ enum: Object.values(Alignment)
180
179
  },
181
180
  sortOrder: {
182
181
  type: 'string',
183
- enum: ['none', 'ascending', 'descending']
182
+ enum: Object.values(SortedBy)
184
183
  }
185
184
  },
186
185
  required: ['id', 'name', 'text']
@@ -1,19 +1,6 @@
1
- // OPTIMIZE: Duplicated clientScriptsSchema in platform/client-actions/cc/action-event-mediator/Properties.ts
2
- const clientScriptsSchema = {
3
- type: 'array',
4
- minItems: 0,
5
- items: {
6
- type: 'object',
7
- properties: {
8
- targetEventName: {
9
- type: 'string'
10
- },
11
- clientScript: {
12
- type: 'string'
13
- }
14
- }
15
- }
16
- };
1
+ import { Width } from "../data-types/Header";
2
+ import RowCursor from "../data-types/RowCursor";
3
+ import { clientScriptsSchema } from "../../../platform/client-scripts/cc/zclient-scripts-execution/clientScriptsSchema";
17
4
  const TableRowProperties = {
18
5
  isReorderEnabled: {
19
6
  required: false,
@@ -102,7 +89,7 @@ const TableRowProperties = {
102
89
  typeMetadata: {
103
90
  schema: {
104
91
  type: 'string',
105
- enum: ['default', 'pointer', 'not-allowed']
92
+ enum: Object.values(RowCursor)
106
93
  }
107
94
  }
108
95
  },
@@ -135,11 +122,11 @@ const TableRowProperties = {
135
122
  },
136
123
  rowActionsColumnWidth: {
137
124
  required: false,
138
- defaultValue: 120,
125
+ defaultValue: Width.XSmall,
139
126
  typeMetadata: {
140
127
  schema: {
141
128
  type: 'number',
142
- enum: [120, 160, 200, 240, 280, 320]
129
+ enum: Object.values(Width)
143
130
  }
144
131
  }
145
132
  },
@@ -1,177 +1 @@
1
- /* eslint-disable complexity */
2
- // Map from schema object reference to precompiled validator function
3
- const precompiledSchemaMap = new WeakMap(); // Precompiled registry: JSON-stringified schema → validator function
4
-
5
- let precompiledByHash = null;
6
-
7
- class Validator {
8
- /**
9
- * Register precompiled validators from the build-time generated registry.
10
- * Builds a hash-based lookup so validate() can auto-match schemas.
11
- * Called once at app startup.
12
- */
13
- static registerPrecompiled(registry) {
14
- precompiledByHash = new Map(); // Each precompiled validator has its schema embedded — extract and hash it
15
-
16
- for (const [, validate] of Object.entries(registry)) {
17
- if (typeof validate === 'function' && validate.schema) {
18
- const hash = JSON.stringify(validate.schema);
19
- precompiledByHash.set(hash, validate);
20
- }
21
- }
22
- }
23
-
24
- static normalizeErrors(ajvErrors) {
25
- return ajvErrors.map(e => ({ ...e,
26
- dataPath: e.instancePath || e.dataPath || ''
27
- }));
28
- }
29
-
30
- static validate(schema, value) {
31
- if (schema.schema) {
32
- return Validator.validatePropertySchema(schema, value);
33
- }
34
-
35
- let errors = [];
36
- Validator.checkFunctionsRecursively(schema, value, '', '#', errors); // Try precompiled validator first (cached by schema reference)
37
-
38
- let precompiled = precompiledSchemaMap.get(schema); // On first encounter, try to match against precompiled registry by schema hash
39
-
40
- if (!precompiled && precompiledByHash) {
41
- const ajvSchema = JSON.parse(JSON.stringify(schema, (key, val) => val === 'function' ? undefined : val));
42
- const hash = JSON.stringify(ajvSchema);
43
- precompiled = precompiledByHash.get(hash);
44
-
45
- if (precompiled) {
46
- // Cache for subsequent calls — O(1) lookup from now on
47
- precompiledSchemaMap.set(schema, precompiled);
48
- }
49
- }
50
-
51
- if (precompiled) {
52
- const isValid = precompiled(value);
53
-
54
- if (!isValid && precompiled.errors) {
55
- errors.push(...Validator.normalizeErrors(precompiled.errors));
56
- }
57
-
58
- return {
59
- isValid: isValid && errors.length === 0,
60
- errors,
61
- warnings: []
62
- };
63
- } // No precompiled validator found — skip AJV validation, return function-check errors only
64
-
65
-
66
- if (process.env.NODE_ENV === 'development') {
67
- console.warn('[Validator] No precompiled validator found for schema. Skipping AJV validation.', schema);
68
- }
69
-
70
- return {
71
- isValid: errors.length === 0,
72
- errors,
73
- warnings: []
74
- };
75
- }
76
-
77
- static checkFunctionsRecursively(schema, value) {
78
- let path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
79
- let schemaPath = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '#';
80
- let errors = arguments.length > 4 ? arguments[4] : undefined;
81
-
82
- if (schema.type === 'function') {
83
- if (typeof value !== 'function') {
84
- errors.push({
85
- keyword: 'type',
86
- dataPath: path ? `.${path}` : '',
87
- schemaPath: `${schemaPath}/type`,
88
- params: {
89
- type: 'function'
90
- },
91
- message: 'should be function'
92
- });
93
- }
94
-
95
- return;
96
- }
97
-
98
- if (schema.type === 'object' && schema.properties && typeof value === 'object' && value !== null) {
99
- for (const key in schema.properties) {
100
- Validator.checkFunctionsRecursively(schema.properties[key], value[key], path ? `${path}.${key}` : key, `${schemaPath}/properties/${key}`, errors);
101
- }
102
- }
103
-
104
- if (schema.type === 'array' && Array.isArray(value) && schema.items) {
105
- value.forEach((item, index) => {
106
- Validator.checkFunctionsRecursively(schema.items, item, `${path}[${index}]`, `${schemaPath}/items`, errors);
107
- });
108
- }
109
- }
110
-
111
- static validatePropertySchema(propertySchema, value) {
112
- const {
113
- schema
114
- } = propertySchema;
115
- const result = Validator.validateRequired(propertySchema, value);
116
- const isProvided = propertySchema.isValueProvided;
117
-
118
- if (result.isValid === false) {
119
- return result;
120
- }
121
-
122
- if (!isProvided) {
123
- return {
124
- isValid: true,
125
- errors: [],
126
- warnings: result.warnings
127
- };
128
- }
129
-
130
- const {
131
- isValid,
132
- errors,
133
- warnings
134
- } = Validator.validate(schema, value);
135
- return {
136
- key: propertySchema.name,
137
- isValid,
138
- errors,
139
- warnings: [...result.warnings, ...warnings]
140
- };
141
- }
142
-
143
- static validateRequired(propertySchema, value) {
144
- const errors = [];
145
- const warnings = [];
146
- const isRequired = propertySchema.required === true;
147
- const hasDefault = Object.prototype.hasOwnProperty.call(propertySchema, 'defaultValue');
148
- const isProvided = propertySchema.isValueProvided;
149
-
150
- if (!isProvided && isRequired) {
151
- if (hasDefault) {
152
- if (propertySchema.defaultValue === undefined) {
153
- errors.push({
154
- message: `is required but missing. So, default value is undefined.`
155
- });
156
- } else {
157
- warnings.push({
158
- message: `is required but missing. So, Default value will be used.`
159
- });
160
- }
161
- } else {
162
- errors.push({
163
- message: `is required but missing. And, neither a value nor a default value is present.`
164
- });
165
- }
166
- }
167
-
168
- return {
169
- isValid: errors.length === 0,
170
- warnings,
171
- errors
172
- };
173
- }
174
-
175
- }
176
-
177
- export default Validator;
1
+ export { default } from "../../../json-schema-validator/Validator";
@@ -2,30 +2,14 @@ import Presenter from "../../adapters/presenters/Presenter";
2
2
  import Service from "../../adapters/gateways/service/Service";
3
3
  import Controller from "../../adapters/controllers/Controller";
4
4
  import Repository from "../../adapters/gateways/repository/Repository";
5
- import Validator from "../json-schema-validator/Validator";
5
+ import { Validator } from "../../../json-schema-validator";
6
6
  import EventManager from "../../adapters/gateways/event-manager/EventManager";
7
- // One-time registration of precompiled validators
8
- let precompiledRegistered = false;
9
-
10
- function ensurePrecompiledRegistered() {
11
- if (precompiledRegistered) return;
12
- precompiledRegistered = true;
13
-
14
- try {
15
- // eslint-disable-next-line @typescript-eslint/no-var-requires
16
- const registry = require("../json-schema-validator/__generated__/registry");
17
-
18
- Validator.registerPrecompiled(registry.default || registry);
19
- } catch (e) {// __generated__ not available (e.g., first build) — runtime fallback
20
- }
21
- }
22
7
 
23
8
  class DependencyFactory {
24
9
  static create(_ref, input) {
25
10
  let {
26
11
  updateState
27
12
  } = _ref;
28
- ensurePrecompiledRegistered();
29
13
  const repository = new Repository();
30
14
  const presenter = new Presenter({
31
15
  updateState
@@ -0,0 +1,338 @@
1
+ /* eslint-disable complexity */
2
+ export class Validator {
3
+ static validate(schema, value) {
4
+ if (schema.schema) {
5
+ return Validator.validatePropertySchema(schema, value);
6
+ }
7
+
8
+ const errors = [];
9
+ Validator.validateNode(schema, value, '', errors, schema.definitions || schema.$defs || {});
10
+ return {
11
+ isValid: errors.length === 0,
12
+ errors,
13
+ warnings: []
14
+ };
15
+ }
16
+
17
+ static validateNode(schema, value, dataPath, errors, rootDefinitions) {
18
+ if (!schema || typeof schema !== 'object') return; // undefined is not a JSON type — skip validation (matches AJV behavior)
19
+
20
+ if (value === undefined) return; // $ref resolution
21
+
22
+ if (schema.$ref) {
23
+ const resolved = Validator.resolveRef(schema.$ref, rootDefinitions);
24
+
25
+ if (resolved) {
26
+ Validator.validateNode(resolved, value, dataPath, errors, rootDefinitions);
27
+ }
28
+
29
+ return;
30
+ } // Hoist definitions from nested schema to root
31
+
32
+
33
+ const definitions = schema.definitions || schema.$defs ? { ...rootDefinitions,
34
+ ...(schema.definitions || schema.$defs)
35
+ } : rootDefinitions; // anyOf
36
+
37
+ if (schema.anyOf) {
38
+ const anyOfValid = schema.anyOf.some(subSchema => {
39
+ const subErrors = [];
40
+ Validator.validateNode(subSchema, value, dataPath, subErrors, definitions);
41
+ return subErrors.length === 0;
42
+ });
43
+
44
+ if (!anyOfValid) {
45
+ errors.push({
46
+ keyword: 'anyOf',
47
+ dataPath,
48
+ message: 'should match at least one schema in anyOf'
49
+ });
50
+ }
51
+
52
+ return;
53
+ } // oneOf
54
+
55
+
56
+ if (schema.oneOf) {
57
+ const matchCount = schema.oneOf.filter(subSchema => {
58
+ const subErrors = [];
59
+ Validator.validateNode(subSchema, value, dataPath, subErrors, definitions);
60
+ return subErrors.length === 0;
61
+ }).length;
62
+
63
+ if (matchCount !== 1) {
64
+ errors.push({
65
+ keyword: 'oneOf',
66
+ dataPath,
67
+ message: 'should match exactly one schema in oneOf'
68
+ });
69
+ }
70
+
71
+ return;
72
+ } // not
73
+
74
+
75
+ if (schema.not) {
76
+ const notErrors = [];
77
+ Validator.validateNode(schema.not, value, dataPath, notErrors, definitions);
78
+
79
+ if (notErrors.length === 0) {
80
+ errors.push({
81
+ keyword: 'not',
82
+ dataPath,
83
+ message: 'should NOT match schema in not'
84
+ });
85
+ }
86
+
87
+ return;
88
+ } // type validation
89
+
90
+
91
+ if (schema.type) {
92
+ if (!Validator.checkType(schema.type, value)) {
93
+ const typeLabel = Array.isArray(schema.type) ? schema.type.join(',') : schema.type;
94
+ errors.push({
95
+ keyword: 'type',
96
+ dataPath,
97
+ message: `should be ${typeLabel}`
98
+ });
99
+ return; // Type mismatch — skip further checks
100
+ }
101
+ } // enum
102
+
103
+
104
+ if (schema.enum) {
105
+ if (!schema.enum.includes(value)) {
106
+ errors.push({
107
+ keyword: 'enum',
108
+ dataPath,
109
+ message: `should be one of ${JSON.stringify(schema.enum)}`
110
+ });
111
+ }
112
+ } // String constraints
113
+
114
+
115
+ if (typeof value === 'string') {
116
+ if (schema.minLength !== undefined && value.length < schema.minLength) {
117
+ errors.push({
118
+ keyword: 'minLength',
119
+ dataPath,
120
+ message: `should have at least ${schema.minLength} characters`
121
+ });
122
+ }
123
+
124
+ if (schema.maxLength !== undefined && value.length > schema.maxLength) {
125
+ errors.push({
126
+ keyword: 'maxLength',
127
+ dataPath,
128
+ message: `should have at most ${schema.maxLength} characters`
129
+ });
130
+ }
131
+
132
+ if (schema.pattern !== undefined) {
133
+ const regex = new RegExp(schema.pattern);
134
+
135
+ if (!regex.test(value)) {
136
+ errors.push({
137
+ keyword: 'pattern',
138
+ dataPath,
139
+ message: `should match pattern "${schema.pattern}"`
140
+ });
141
+ }
142
+ }
143
+ } // Array constraints
144
+
145
+
146
+ if (Array.isArray(value)) {
147
+ if (schema.minItems !== undefined && value.length < schema.minItems) {
148
+ errors.push({
149
+ keyword: 'minItems',
150
+ dataPath,
151
+ message: `should have at least ${schema.minItems} items`
152
+ });
153
+ }
154
+
155
+ if (schema.uniqueItems === true) {
156
+ const seen = new Set();
157
+ const hasDuplicates = value.some(item => {
158
+ const key = typeof item === 'object' ? JSON.stringify(item) : item;
159
+ if (seen.has(key)) return true;
160
+ seen.add(key);
161
+ return false;
162
+ });
163
+
164
+ if (hasDuplicates) {
165
+ errors.push({
166
+ keyword: 'uniqueItems',
167
+ dataPath,
168
+ message: 'should have unique items'
169
+ });
170
+ }
171
+ }
172
+
173
+ if (schema.items) {
174
+ value.forEach((item, index) => {
175
+ Validator.validateNode(schema.items, item, `${dataPath}[${index}]`, errors, definitions);
176
+ });
177
+ }
178
+ } // Object constraints
179
+
180
+
181
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
182
+ if (schema.required) {
183
+ schema.required.forEach(key => {
184
+ if (!(key in value)) {
185
+ const propPath = dataPath ? `${dataPath}.${key}` : `.${key}`;
186
+ errors.push({
187
+ keyword: 'required',
188
+ dataPath: propPath,
189
+ message: `should have required property '${key}'`
190
+ });
191
+ }
192
+ });
193
+ }
194
+
195
+ if (schema.properties) {
196
+ for (const key in schema.properties) {
197
+ if (key in value) {
198
+ const propPath = dataPath ? `${dataPath}.${key}` : `.${key}`;
199
+ Validator.validateNode(schema.properties[key], value[key], propPath, errors, definitions);
200
+ }
201
+ }
202
+ }
203
+
204
+ if (schema.additionalProperties !== undefined && schema.additionalProperties !== true && schema.properties) {
205
+ const allowed = new Set(Object.keys(schema.properties));
206
+
207
+ for (const key in value) {
208
+ if (!allowed.has(key)) {
209
+ if (schema.additionalProperties === false) {
210
+ const propPath = dataPath ? `${dataPath}.${key}` : `.${key}`;
211
+ errors.push({
212
+ keyword: 'additionalProperties',
213
+ dataPath: propPath,
214
+ message: `should NOT have additional property '${key}'`
215
+ });
216
+ } else if (typeof schema.additionalProperties === 'object') {
217
+ const propPath = dataPath ? `${dataPath}.${key}` : `.${key}`;
218
+ Validator.validateNode(schema.additionalProperties, value[key], propPath, errors, definitions);
219
+ }
220
+ }
221
+ }
222
+ }
223
+ }
224
+ }
225
+
226
+ static checkType(type, value) {
227
+ if (Array.isArray(type)) {
228
+ return type.some(t => Validator.checkSingleType(t, value));
229
+ }
230
+
231
+ return Validator.checkSingleType(type, value);
232
+ }
233
+
234
+ static checkSingleType(type, value) {
235
+ switch (type) {
236
+ case 'string':
237
+ return typeof value === 'string';
238
+
239
+ case 'number':
240
+ return typeof value === 'number';
241
+
242
+ case 'boolean':
243
+ return typeof value === 'boolean';
244
+
245
+ case 'object':
246
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
247
+
248
+ case 'array':
249
+ return Array.isArray(value);
250
+
251
+ case 'null':
252
+ return value === null;
253
+
254
+ case 'function':
255
+ return typeof value === 'function';
256
+
257
+ default:
258
+ return true;
259
+ // 'any' or unknown types — accept anything
260
+ }
261
+ }
262
+
263
+ static resolveRef(ref, definitions) {
264
+ // Supports: #/definitions/Name and #/$defs/Name
265
+ const match = ref.match(/^#\/(definitions|\$defs)\/(.+)$/);
266
+
267
+ if (match && definitions[match[2]]) {
268
+ return definitions[match[2]];
269
+ }
270
+
271
+ return null;
272
+ }
273
+
274
+ static validatePropertySchema(propertySchema, value) {
275
+ const {
276
+ schema
277
+ } = propertySchema;
278
+ const result = Validator.validateRequired(propertySchema, value);
279
+ const isProvided = propertySchema.isValueProvided;
280
+
281
+ if (result.isValid === false) {
282
+ return result;
283
+ }
284
+
285
+ if (!isProvided) {
286
+ return {
287
+ isValid: true,
288
+ errors: [],
289
+ warnings: result.warnings
290
+ };
291
+ }
292
+
293
+ const {
294
+ isValid,
295
+ errors,
296
+ warnings
297
+ } = Validator.validate(schema, value);
298
+ return {
299
+ key: propertySchema.name,
300
+ isValid,
301
+ errors,
302
+ warnings: [...result.warnings, ...warnings]
303
+ };
304
+ }
305
+
306
+ static validateRequired(propertySchema, value) {
307
+ const errors = [];
308
+ const warnings = [];
309
+ const isRequired = propertySchema.required === true;
310
+ const hasDefault = Object.prototype.hasOwnProperty.call(propertySchema, 'defaultValue');
311
+ const isProvided = propertySchema.isValueProvided;
312
+
313
+ if (!isProvided && isRequired) {
314
+ if (hasDefault) {
315
+ if (propertySchema.defaultValue === undefined) {
316
+ errors.push({
317
+ message: `is required but missing. So, default value is undefined.`
318
+ });
319
+ } else {
320
+ warnings.push({
321
+ message: `is required but missing. So, Default value will be used.`
322
+ });
323
+ }
324
+ } else {
325
+ errors.push({
326
+ message: `is required but missing. And, neither a value nor a default value is present.`
327
+ });
328
+ }
329
+ }
330
+
331
+ return {
332
+ isValid: errors.length === 0,
333
+ warnings,
334
+ errors
335
+ };
336
+ }
337
+
338
+ }