@basictech/schema 0.1.0-beta.0 → 0.1.0-beta.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.
@@ -1,22 +1,23 @@
1
1
 
2
2
  
3
- > @basictech/schema@0.0.1 build
3
+ > @basictech/schema@0.1.0-beta.0 build
4
4
  > tsup
5
5
 
6
6
  CLI Building entry: ./index.ts
7
+ CLI Using tsconfig: tsconfig.json
7
8
  CLI tsup v7.2.0
8
9
  CLI Using tsup config: /Users/raz/codebook/basic/libs/client-ts/packages/schema/tsup.config.ts
9
- CLI Target: node16
10
+ CLI Target: es2022
10
11
  CLI Cleaning output folder
11
12
  CJS Build start
12
13
  ESM Build start
13
- ESM dist/index.mjs 153.00 B
14
- ESM dist/index.mjs.map 210.00 B
15
- ESM ⚡️ Build success in 6ms
16
- CJS dist/index.js 1.01 KB
17
- CJS dist/index.js.map 253.00 B
18
- CJS ⚡️ Build success in 6ms
14
+ ESM dist/index.mjs 8.36 KB
15
+ ESM dist/index.mjs.map 19.00 KB
16
+ ESM ⚡️ Build success in 7ms
17
+ CJS dist/index.js 10.11 KB
18
+ CJS dist/index.js.map 19.08 KB
19
+ CJS ⚡️ Build success in 8ms
19
20
  DTS Build start
20
- DTS ⚡️ Build success in 747ms
21
- DTS dist/index.d.ts 64.00 B
22
- DTS dist/index.d.mts 64.00 B
21
+ DTS ⚡️ Build success in 786ms
22
+ DTS dist/index.d.ts 2.67 KB
23
+ DTS dist/index.d.mts 2.67 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @basictech/schema
2
2
 
3
+ ## 0.1.0-beta.1
4
+
5
+ ### Minor Changes
6
+
7
+ - update schema validation
8
+
3
9
  ## 0.1.0-beta.0
4
10
 
5
11
  ### Minor Changes
package/dist/index.d.mts CHANGED
@@ -1,3 +1,86 @@
1
- declare function hello(): string;
1
+ import { ErrorObject } from 'ajv';
2
2
 
3
- export { hello as default };
3
+ declare function generateEmptySchema(project_id?: string, version?: number): {
4
+ project_id: string;
5
+ version: number;
6
+ tables: {
7
+ fields: {
8
+ example: {
9
+ type: string;
10
+ };
11
+ };
12
+ };
13
+ };
14
+ /**
15
+ * Validate a schema
16
+ * only checks if the schema is formatted correctly, not if can be published
17
+ * @param schema - The schema to validate
18
+ * @returns {valid: boolean, errors: any[]} - The validation result
19
+ */
20
+ declare function validateSchema(schema: any): {
21
+ valid: boolean;
22
+ errors: ErrorObject[];
23
+ };
24
+ /**
25
+ * Validate data against a schema's table definition. Only checks against provided schema.
26
+ * @param schema - The schema to validate against
27
+ * @param table - The table name in the schema to validate against
28
+ * @param data - The data object to validate
29
+ * @param checkRequired - Whether to check if required fields are present (default: true)
30
+ * @returns {Object} Validation result containing:
31
+ * - valid: boolean indicating if validation passed
32
+ * - errors: Array of validation error objects
33
+ * - message: Error message if validation failed
34
+ */
35
+ declare function validateData(schema: any, table: string, data: Record<string, any>, checkRequired?: boolean): {
36
+ valid: boolean;
37
+ errors: ErrorObject<string, Record<string, any>, unknown>[];
38
+ message: string;
39
+ } | {
40
+ valid: boolean;
41
+ errors: {
42
+ message: string;
43
+ }[];
44
+ message: string;
45
+ } | {
46
+ valid: boolean;
47
+ errors: never[];
48
+ message?: undefined;
49
+ };
50
+ type SchemaChangeType = "property_changed" | "property_removed" | "table_added" | "table_removed" | "field_added" | "field_removed" | "field_type_changed" | "field_required_changed" | "field_property_added" | "field_property_changed" | "field_property_removed";
51
+ type SchemaChange = {
52
+ type: SchemaChangeType;
53
+ property?: string;
54
+ table?: string;
55
+ field?: string;
56
+ old?: any;
57
+ new?: any;
58
+ };
59
+ declare function validateUpdateSchema(oldSchema: any, newSchema: any): {
60
+ valid: boolean;
61
+ errors: ErrorObject<string, Record<string, any>, unknown>[];
62
+ message: string;
63
+ changes?: undefined;
64
+ } | {
65
+ valid: boolean;
66
+ errors: {
67
+ change: SchemaChange;
68
+ message: string;
69
+ }[];
70
+ message: string;
71
+ changes?: undefined;
72
+ } | {
73
+ valid: boolean;
74
+ changes: SchemaChange[];
75
+ errors?: undefined;
76
+ message?: undefined;
77
+ };
78
+
79
+ declare const schema: {
80
+ validateSchema: typeof validateSchema;
81
+ validateData: typeof validateData;
82
+ generateEmptySchema: typeof generateEmptySchema;
83
+ validateUpdateSchema: typeof validateUpdateSchema;
84
+ };
85
+
86
+ export { schema as default, generateEmptySchema, validateData, validateSchema, validateUpdateSchema };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,86 @@
1
- declare function hello(): string;
1
+ import { ErrorObject } from 'ajv';
2
2
 
3
- export { hello as default };
3
+ declare function generateEmptySchema(project_id?: string, version?: number): {
4
+ project_id: string;
5
+ version: number;
6
+ tables: {
7
+ fields: {
8
+ example: {
9
+ type: string;
10
+ };
11
+ };
12
+ };
13
+ };
14
+ /**
15
+ * Validate a schema
16
+ * only checks if the schema is formatted correctly, not if can be published
17
+ * @param schema - The schema to validate
18
+ * @returns {valid: boolean, errors: any[]} - The validation result
19
+ */
20
+ declare function validateSchema(schema: any): {
21
+ valid: boolean;
22
+ errors: ErrorObject[];
23
+ };
24
+ /**
25
+ * Validate data against a schema's table definition. Only checks against provided schema.
26
+ * @param schema - The schema to validate against
27
+ * @param table - The table name in the schema to validate against
28
+ * @param data - The data object to validate
29
+ * @param checkRequired - Whether to check if required fields are present (default: true)
30
+ * @returns {Object} Validation result containing:
31
+ * - valid: boolean indicating if validation passed
32
+ * - errors: Array of validation error objects
33
+ * - message: Error message if validation failed
34
+ */
35
+ declare function validateData(schema: any, table: string, data: Record<string, any>, checkRequired?: boolean): {
36
+ valid: boolean;
37
+ errors: ErrorObject<string, Record<string, any>, unknown>[];
38
+ message: string;
39
+ } | {
40
+ valid: boolean;
41
+ errors: {
42
+ message: string;
43
+ }[];
44
+ message: string;
45
+ } | {
46
+ valid: boolean;
47
+ errors: never[];
48
+ message?: undefined;
49
+ };
50
+ type SchemaChangeType = "property_changed" | "property_removed" | "table_added" | "table_removed" | "field_added" | "field_removed" | "field_type_changed" | "field_required_changed" | "field_property_added" | "field_property_changed" | "field_property_removed";
51
+ type SchemaChange = {
52
+ type: SchemaChangeType;
53
+ property?: string;
54
+ table?: string;
55
+ field?: string;
56
+ old?: any;
57
+ new?: any;
58
+ };
59
+ declare function validateUpdateSchema(oldSchema: any, newSchema: any): {
60
+ valid: boolean;
61
+ errors: ErrorObject<string, Record<string, any>, unknown>[];
62
+ message: string;
63
+ changes?: undefined;
64
+ } | {
65
+ valid: boolean;
66
+ errors: {
67
+ change: SchemaChange;
68
+ message: string;
69
+ }[];
70
+ message: string;
71
+ changes?: undefined;
72
+ } | {
73
+ valid: boolean;
74
+ changes: SchemaChange[];
75
+ errors?: undefined;
76
+ message?: undefined;
77
+ };
78
+
79
+ declare const schema: {
80
+ validateSchema: typeof validateSchema;
81
+ validateData: typeof validateData;
82
+ generateEmptySchema: typeof generateEmptySchema;
83
+ validateUpdateSchema: typeof validateUpdateSchema;
84
+ };
85
+
86
+ export { schema as default, generateEmptySchema, validateData, validateSchema, validateUpdateSchema };
package/dist/index.js CHANGED
@@ -1,6 +1,9 @@
1
+ "use strict";
2
+ var __create = Object.create;
1
3
  var __defProp = Object.defineProperty;
2
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
4
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
8
  var __export = (target, all) => {
6
9
  for (var name in all)
@@ -14,16 +17,325 @@ var __copyProps = (to, from, except, desc) => {
14
17
  }
15
18
  return to;
16
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
17
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
29
 
19
30
  // index.ts
20
31
  var schema_exports = {};
21
32
  __export(schema_exports, {
22
- default: () => schema_default
33
+ default: () => schema_default,
34
+ generateEmptySchema: () => generateEmptySchema,
35
+ validateData: () => validateData,
36
+ validateSchema: () => validateSchema,
37
+ validateUpdateSchema: () => validateUpdateSchema
23
38
  });
24
39
  module.exports = __toCommonJS(schema_exports);
25
- function hello() {
26
- return "hello";
40
+ var import_ajv = __toESM(require("ajv"));
41
+ var basicJsonSchema = {
42
+ "$schema": "http://json-schema.org/draft-07/schema#",
43
+ "type": "object",
44
+ "properties": {
45
+ "project_id": {
46
+ "type": "string"
47
+ },
48
+ "namespace": {
49
+ "type": "string"
50
+ },
51
+ "version": {
52
+ "type": "integer",
53
+ "minimum": 0
54
+ },
55
+ "tables": {
56
+ "type": "object",
57
+ "patternProperties": {
58
+ "^[a-zA-Z0-9_]+$": {
59
+ "type": "object",
60
+ "properties": {
61
+ "name": {
62
+ "type": "string"
63
+ },
64
+ "type": {
65
+ "type": "string",
66
+ "enum": ["collection"]
67
+ },
68
+ "fields": {
69
+ "type": "object",
70
+ "patternProperties": {
71
+ "^[a-zA-Z0-9_]+$": {
72
+ "type": "object",
73
+ "properties": {
74
+ "type": {
75
+ "type": "string",
76
+ "enum": ["string", "boolean", "number", "json"]
77
+ },
78
+ "indexed": {
79
+ "type": "boolean"
80
+ },
81
+ "required": {
82
+ "type": "boolean"
83
+ }
84
+ },
85
+ "required": ["type"]
86
+ }
87
+ },
88
+ "additionalProperties": true
89
+ }
90
+ },
91
+ "required": ["fields"]
92
+ }
93
+ },
94
+ "additionalProperties": true
95
+ }
96
+ },
97
+ "required": ["project_id", "version", "tables"]
98
+ };
99
+ var ajv = new import_ajv.default();
100
+ var validator = ajv.compile(basicJsonSchema);
101
+ function generateEmptySchema(project_id = "", version = 0) {
102
+ return {
103
+ project_id,
104
+ version,
105
+ tables: {
106
+ fields: {
107
+ example: {
108
+ type: "string"
109
+ }
110
+ }
111
+ }
112
+ };
113
+ }
114
+ function validateSchema(schema2) {
115
+ const v = validator(schema2);
116
+ return {
117
+ valid: v,
118
+ errors: validator.errors || []
119
+ };
120
+ }
121
+ function validateData(schema2, table, data, checkRequired = true) {
122
+ const valid = validateSchema(schema2);
123
+ if (!valid.valid) {
124
+ return { valid: false, errors: valid.errors, message: "Schema is invalid" };
125
+ }
126
+ const tableSchema = schema2.tables[table];
127
+ if (!tableSchema) {
128
+ return { valid: false, errors: [{ message: `Table ${table} not found in schema` }], message: "Table not found" };
129
+ }
130
+ for (const [fieldName, fieldValue] of Object.entries(data)) {
131
+ const fieldSchema = tableSchema.fields[fieldName];
132
+ if (!fieldSchema) {
133
+ return {
134
+ valid: false,
135
+ errors: [{ message: `Field ${fieldName} not found in schema` }],
136
+ message: "Invalid field"
137
+ };
138
+ }
139
+ const schemaType = fieldSchema.type;
140
+ const valueType = typeof fieldValue;
141
+ if (schemaType === "string" && valueType !== "string" || schemaType === "number" && valueType !== "number" || schemaType === "boolean" && valueType !== "boolean" || schemaType === "json" && valueType !== "object") {
142
+ return {
143
+ valid: false,
144
+ errors: [{
145
+ message: `Field ${fieldName} should be type ${schemaType}, got ${valueType}`
146
+ }],
147
+ message: "invalid type"
148
+ };
149
+ }
150
+ }
151
+ if (checkRequired) {
152
+ for (const [fieldName, fieldSchema] of Object.entries(tableSchema.fields)) {
153
+ if (fieldSchema.required && !data[fieldName]) {
154
+ return { valid: false, errors: [{ message: `Field ${fieldName} is required` }], message: "Required field missing" };
155
+ }
156
+ }
157
+ }
158
+ return { valid: true, errors: [] };
27
159
  }
28
- var schema_default = hello;
160
+ function _getSchemaChanges(oldSchema, newSchema) {
161
+ const changes = [];
162
+ for (const key in newSchema) {
163
+ if (key !== "tables" && newSchema[key] !== oldSchema[key]) {
164
+ changes.push({
165
+ type: "property_changed",
166
+ property: key,
167
+ old: oldSchema[key],
168
+ new: newSchema[key]
169
+ });
170
+ }
171
+ }
172
+ for (const key in oldSchema) {
173
+ if (key !== "tables" && !newSchema.hasOwnProperty(key)) {
174
+ changes.push({
175
+ type: "property_removed",
176
+ property: key,
177
+ old: oldSchema[key]
178
+ });
179
+ }
180
+ }
181
+ for (const tableName in oldSchema.tables) {
182
+ if (!newSchema.tables[tableName]) {
183
+ changes.push({
184
+ type: "table_removed",
185
+ table: tableName
186
+ });
187
+ }
188
+ }
189
+ for (const tableName in newSchema.tables) {
190
+ const newTable = newSchema.tables[tableName];
191
+ const oldTable = oldSchema.tables[tableName];
192
+ if (!oldTable) {
193
+ changes.push({
194
+ type: "table_added",
195
+ table: tableName
196
+ });
197
+ continue;
198
+ }
199
+ for (const fieldName in newTable.fields) {
200
+ const newField = newTable.fields[fieldName];
201
+ const oldField = oldTable.fields[fieldName];
202
+ if (!oldField) {
203
+ changes.push({
204
+ type: "field_added",
205
+ table: tableName,
206
+ field: fieldName
207
+ });
208
+ continue;
209
+ }
210
+ if (newField.type !== oldField.type) {
211
+ changes.push({
212
+ type: "field_type_changed",
213
+ table: tableName,
214
+ field: fieldName,
215
+ old: oldField.type,
216
+ new: newField.type
217
+ });
218
+ }
219
+ if (newField.required !== oldField.required) {
220
+ changes.push({
221
+ type: "field_required_changed",
222
+ table: tableName,
223
+ field: fieldName,
224
+ old: oldField.required,
225
+ new: newField.required
226
+ });
227
+ }
228
+ }
229
+ for (const fieldName in oldTable.fields) {
230
+ if (!newTable.fields[fieldName]) {
231
+ changes.push({
232
+ type: "field_removed",
233
+ table: tableName,
234
+ field: fieldName
235
+ });
236
+ }
237
+ }
238
+ }
239
+ for (const tableName in newSchema.tables) {
240
+ const newTable = newSchema.tables[tableName];
241
+ const oldTable = oldSchema.tables[tableName];
242
+ if (!oldTable)
243
+ continue;
244
+ for (const fieldName in newTable.fields) {
245
+ const newField = newTable.fields[fieldName];
246
+ const oldField = oldTable.fields[fieldName];
247
+ if (!oldField)
248
+ continue;
249
+ for (const prop in newField) {
250
+ if (prop === "type")
251
+ continue;
252
+ if (!(prop in oldField)) {
253
+ changes.push({
254
+ type: "field_property_added",
255
+ table: tableName,
256
+ field: fieldName,
257
+ property: prop,
258
+ new: newField[prop]
259
+ });
260
+ } else if (JSON.stringify(newField[prop]) !== JSON.stringify(oldField[prop])) {
261
+ changes.push({
262
+ type: "field_property_changed",
263
+ table: tableName,
264
+ field: fieldName,
265
+ property: prop,
266
+ old: oldField[prop],
267
+ new: newField[prop]
268
+ });
269
+ }
270
+ }
271
+ for (const prop in oldField) {
272
+ if (prop === "type")
273
+ continue;
274
+ if (!(prop in newField)) {
275
+ changes.push({
276
+ type: "field_property_removed",
277
+ table: tableName,
278
+ field: fieldName,
279
+ property: prop,
280
+ old: oldField[prop]
281
+ });
282
+ }
283
+ }
284
+ }
285
+ }
286
+ return changes;
287
+ }
288
+ function validateUpdateSchema(oldSchema, newSchema) {
289
+ const oldValid = validateSchema(oldSchema);
290
+ const newValid = validateSchema(newSchema);
291
+ if (!oldValid.valid || !newValid.valid) {
292
+ return { valid: false, errors: oldValid.errors.concat(newValid.errors), message: "schemas are is invalid" };
293
+ }
294
+ const changes = _getSchemaChanges(oldSchema, newSchema);
295
+ const changeErrors = [];
296
+ for (const change of changes) {
297
+ if (change.type === "property_changed" && change.property === "project_id") {
298
+ changeErrors.push({
299
+ change,
300
+ message: "Cannot modify project_id property"
301
+ });
302
+ }
303
+ if (change.type === "property_changed" && change.property === "version") {
304
+ if (change.new !== change.old + 1) {
305
+ changeErrors.push({
306
+ change,
307
+ message: `Version must be incremented by 1. Expected version:${change.old + 1}, got version:${change.new}`
308
+ });
309
+ }
310
+ }
311
+ if (change.type === "field_type_changed") {
312
+ changeErrors.push({
313
+ change,
314
+ message: `Cannot change type of field "${change.field}" from "${change.old}" to "${change.new}"`
315
+ });
316
+ }
317
+ }
318
+ if (changeErrors.length > 0) {
319
+ return {
320
+ valid: false,
321
+ errors: changeErrors,
322
+ message: "Invalid schema changes detected"
323
+ };
324
+ }
325
+ return { valid: true, changes };
326
+ }
327
+ var schema = {
328
+ validateSchema,
329
+ validateData,
330
+ generateEmptySchema,
331
+ validateUpdateSchema
332
+ };
333
+ var schema_default = schema;
334
+ // Annotate the CommonJS export names for ESM import in node:
335
+ 0 && (module.exports = {
336
+ generateEmptySchema,
337
+ validateData,
338
+ validateSchema,
339
+ validateUpdateSchema
340
+ });
29
341
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts"],"sourcesContent":["function hello() : string { \n return 'hello'\n}\n\nexport default hello"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,QAAiB;AACtB,SAAO;AACX;AAEA,IAAO,iBAAQ;","names":[]}
1
+ {"version":3,"sources":["../index.ts"],"sourcesContent":["// Basic Schema Library\n// utils for validating and interacting with Basic schemas\nimport Ajv, { ErrorObject } from 'ajv'\n\nconst basicJsonSchema = {\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"type\": \"object\",\n \"properties\": {\n \"project_id\": {\n \"type\": \"string\"\n },\n \"namespace\": {\n \"type\": \"string\",\n },\n \"version\": {\n \"type\": \"integer\",\n \"minimum\": 0\n },\n \"tables\": {\n \"type\": \"object\",\n \"patternProperties\": {\n \"^[a-zA-Z0-9_]+$\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"collection\"]\n },\n \"fields\": {\n \"type\": \"object\",\n \"patternProperties\": {\n \"^[a-zA-Z0-9_]+$\": {\n \"type\": \"object\",\n \"properties\": {\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"string\", \"boolean\", \"number\", \"json\"]\n },\n \"indexed\": {\n \"type\": \"boolean\"\n }, \n \"required\": {\n \"type\": \"boolean\"\n }\n },\n \"required\": [\"type\"]\n }\n },\n \"additionalProperties\": true\n }\n },\n \"required\": [\"fields\"]\n }\n },\n \"additionalProperties\": true\n }\n },\n \"required\": [\"project_id\", \"version\", \"tables\"]\n }\n\nconst ajv = new Ajv()\nconst validator = ajv.compile(basicJsonSchema)\n\n\nfunction generateEmptySchema(project_id: string = \"\", version: number = 0) {\n return {\n project_id: project_id,\n version: version,\n tables: {\n fields: {\n example: { \n type: \"string\",\n }\n }\n }\n }\n}\n\ntype Schema = { \n project_id : string,\n version : number,\n tables : any\n}\n\n\n/**\n * Validate a schema\n * only checks if the schema is formatted correctly, not if can be published\n * @param schema - The schema to validate\n * @returns {valid: boolean, errors: any[]} - The validation result\n */\nfunction validateSchema(schema: any) : {valid: boolean, errors: ErrorObject[]} {\n const v = validator(schema)\n return { \n valid: v,\n errors: validator.errors || []\n }\n}\n\n// type ErrorObject = {\n// keyword: string;\n// instancePath: string; \n// schemaPath: string;\n// params: Record<string, any>;\n// propertyName?: string;\n// message?: string;\n// schema?: any;\n// parentSchema?: any;\n// data?: any;\n// }\n\n\n/**\n * Validate data against a schema's table definition. Only checks against provided schema.\n * @param schema - The schema to validate against\n * @param table - The table name in the schema to validate against\n * @param data - The data object to validate\n * @param checkRequired - Whether to check if required fields are present (default: true)\n * @returns {Object} Validation result containing:\n * - valid: boolean indicating if validation passed\n * - errors: Array of validation error objects\n * - message: Error message if validation failed\n */\n\nfunction validateData(schema: any, table: string, data: Record<string, any>, checkRequired: boolean = true) {\n const valid = validateSchema(schema)\n if (!valid.valid) {\n return { valid: false, errors: valid.errors, message: \"Schema is invalid\" }\n }\n\n const tableSchema = schema.tables[table]\n\n if (!tableSchema) {\n return { valid: false, errors: [{ message: `Table ${table} not found in schema` }], message: \"Table not found\" }\n }\n\n for (const [fieldName, fieldValue] of Object.entries(data)) {\n const fieldSchema = tableSchema.fields[fieldName]\n \n if (!fieldSchema) {\n return { \n valid: false, \n errors: [{ message: `Field ${fieldName} not found in schema` }],\n message: \"Invalid field\"\n }\n }\n\n const schemaType = fieldSchema.type\n const valueType = typeof fieldValue\n\n if ( \n (schemaType === 'string' && valueType !== 'string') ||\n (schemaType === 'number' && valueType !== 'number') ||\n (schemaType === 'boolean' && valueType !== 'boolean') ||\n (schemaType === 'json' && valueType !== 'object')\n ) {\n return {\n valid: false,\n errors: [{ \n message: `Field ${fieldName} should be type ${schemaType}, got ${valueType}` \n }],\n message: \"invalid type\"\n }\n }\n }\n\n if (checkRequired) {\n for (const [fieldName, fieldSchema] of Object.entries(tableSchema.fields)) {\n if ((fieldSchema as { required?: boolean }).required && !data[fieldName]) {\n return { valid: false, errors: [{ message: `Field ${fieldName} is required` }], message: \"Required field missing\" }\n }\n }\n }\n\n return { valid: true, errors: [] }\n}\n\ntype SchemaChangeType = \"property_changed\" | \"property_removed\" | \"table_added\" | \"table_removed\" | \"field_added\" | \"field_removed\" | \"field_type_changed\" | \"field_required_changed\" | \"field_property_added\" | \"field_property_changed\" | \"field_property_removed\"\n\n\ntype SchemaChange = {\n type: SchemaChangeType,\n property?: string,\n table?: string,\n field?: string,\n old?: any,\n new?: any\n}\n\nfunction _getSchemaChanges(oldSchema: any, newSchema: any) : SchemaChange[] {\n // Compare tables between schemas\n const changes : SchemaChange[] = []\n\n // Check for top level property changes\n for (const key in newSchema) {\n if (key !== 'tables' && newSchema[key] !== oldSchema[key]) {\n changes.push({\n type: 'property_changed',\n property: key,\n old: oldSchema[key],\n new: newSchema[key]\n })\n }\n }\n\n for (const key in oldSchema) {\n if (key !== 'tables' && !newSchema.hasOwnProperty(key)) {\n changes.push({\n type: 'property_removed',\n property: key,\n old: oldSchema[key]\n })\n }\n }\n\n // Check for removed tables\n for (const tableName in oldSchema.tables) {\n if (!newSchema.tables[tableName]) {\n changes.push({\n type: 'table_removed',\n table: tableName\n })\n }\n }\n\n // Check for added tables and field changes\n for (const tableName in newSchema.tables) {\n const newTable = newSchema.tables[tableName]\n const oldTable = oldSchema.tables[tableName]\n\n if (!oldTable) {\n changes.push({\n type: 'table_added', \n table: tableName\n })\n continue\n }\n\n // Compare fields\n for (const fieldName in newTable.fields) {\n const newField = newTable.fields[fieldName]\n const oldField = oldTable.fields[fieldName]\n\n if (!oldField) {\n changes.push({\n type: 'field_added',\n table: tableName,\n field: fieldName\n })\n continue\n }\n\n // Check for field type changes\n if (newField.type !== oldField.type) {\n changes.push({\n type: 'field_type_changed',\n table: tableName,\n field: fieldName,\n old: oldField.type,\n new: newField.type\n })\n }\n\n // Check for required flag changes\n if (newField.required !== oldField.required) {\n changes.push({\n type: 'field_required_changed',\n table: tableName,\n field: fieldName,\n old: oldField.required,\n new: newField.required\n })\n }\n }\n\n // Check for removed fields\n for (const fieldName in oldTable.fields) {\n if (!newTable.fields[fieldName]) {\n changes.push({\n type: 'field_removed',\n table: tableName,\n field: fieldName\n })\n }\n }\n }\n\n // Check for field property changes (excluding type which is already checked)\n for (const tableName in newSchema.tables) {\n const newTable = newSchema.tables[tableName]\n const oldTable = oldSchema.tables[tableName]\n\n if (!oldTable) continue\n\n for (const fieldName in newTable.fields) {\n const newField = newTable.fields[fieldName]\n const oldField = oldTable.fields[fieldName]\n\n if (!oldField) continue\n\n // Compare all properties except type\n for (const prop in newField) {\n if (prop === 'type') continue\n \n if (!(prop in oldField)) {\n changes.push({\n type: 'field_property_added',\n table: tableName,\n field: fieldName,\n property: prop,\n new: newField[prop]\n })\n } else if (JSON.stringify(newField[prop]) !== JSON.stringify(oldField[prop])) {\n changes.push({\n type: 'field_property_changed',\n table: tableName,\n field: fieldName,\n property: prop,\n old: oldField[prop],\n new: newField[prop]\n })\n }\n }\n\n // Check for removed properties\n for (const prop in oldField) {\n if (prop === 'type') continue\n if (!(prop in newField)) {\n changes.push({\n type: 'field_property_removed',\n table: tableName,\n field: fieldName,\n property: prop,\n old: oldField[prop]\n })\n }\n }\n }\n }\n\n return changes\n}\n\n\n// function verifyScehma(schema : any ) { \n// const valid = validateSchema(schema)\n// if (!valid.valid) {\n// return { valid: false, errors: valid.errors, message: \"Schema is invalid\" }\n// }\n\n\n\n\n// return { valid: true, errors: [] }\n// }\n\n\nfunction validateUpdateSchema(oldSchema: any, newSchema: any) {\n const oldValid = validateSchema(oldSchema)\n const newValid = validateSchema(newSchema)\n\n if (!oldValid.valid || !newValid.valid) {\n return { valid: false, errors: oldValid.errors.concat(newValid.errors), message: \"schemas are is invalid\" }\n }\n\n \n const changes = _getSchemaChanges(oldSchema, newSchema)\n\n const changeErrors = []\n for (const change of changes) {\n if (change.type === 'property_changed' && change.property === 'project_id') {\n changeErrors.push({ \n change: change,\n message: \"Cannot modify project_id property\"\n })\n }\n\n if (change.type === 'property_changed' && change.property === 'version') {\n if (change.new !== change.old + 1) {\n changeErrors.push({\n change: change,\n message: `Version must be incremented by 1. Expected version:${change.old + 1}, got version:${change.new}`\n })\n }\n }\n\n if (change.type === 'field_type_changed') {\n changeErrors.push({\n change: change,\n message: `Cannot change type of field \"${change.field}\" from \"${change.old}\" to \"${change.new}\"`\n })\n }\n }\n\n if (changeErrors.length > 0) {\n return {\n valid: false,\n errors: changeErrors,\n message: \"Invalid schema changes detected\"\n }\n }\n\n return { valid: true, changes: changes }\n}\n\nexport {\n validateSchema,\n validateData,\n generateEmptySchema,\n validateUpdateSchema\n}\n\nconst schema = {\n validateSchema,\n validateData,\n generateEmptySchema,\n validateUpdateSchema\n}\n\nexport default schema"],"mappings":"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","names":["Ajv","schema"]}