@basictech/schema 0.5.0-beta.0 → 0.5.0
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/CHANGELOG.md +14 -0
- package/dist/index.d.mts +28 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +24 -0
- package/dist/index.mjs.map +1 -1
- package/index.ts +24 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @basictech/schema
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- publish with origin
|
|
8
|
+
- a41eb20: schema validation to react client
|
|
9
|
+
- c76951e: add origin
|
|
10
|
+
|
|
11
|
+
## 0.5.0-beta.1
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- add origin
|
|
16
|
+
|
|
3
17
|
## 0.5.0-beta.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -131,6 +131,34 @@ declare function getJsonSchema(): {
|
|
|
131
131
|
type: string;
|
|
132
132
|
enum: string[];
|
|
133
133
|
};
|
|
134
|
+
origin: {
|
|
135
|
+
type: string;
|
|
136
|
+
properties: {
|
|
137
|
+
type: {
|
|
138
|
+
type: string;
|
|
139
|
+
enum: string[];
|
|
140
|
+
};
|
|
141
|
+
project_id: {
|
|
142
|
+
type: string;
|
|
143
|
+
};
|
|
144
|
+
table: {
|
|
145
|
+
type: string;
|
|
146
|
+
};
|
|
147
|
+
version: {
|
|
148
|
+
type: string;
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
if: {
|
|
152
|
+
properties: {
|
|
153
|
+
type: {
|
|
154
|
+
const: string;
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
then: {
|
|
159
|
+
required: string[];
|
|
160
|
+
};
|
|
161
|
+
};
|
|
134
162
|
fields: {
|
|
135
163
|
type: string;
|
|
136
164
|
propertyNames: {
|
package/dist/index.d.ts
CHANGED
|
@@ -131,6 +131,34 @@ declare function getJsonSchema(): {
|
|
|
131
131
|
type: string;
|
|
132
132
|
enum: string[];
|
|
133
133
|
};
|
|
134
|
+
origin: {
|
|
135
|
+
type: string;
|
|
136
|
+
properties: {
|
|
137
|
+
type: {
|
|
138
|
+
type: string;
|
|
139
|
+
enum: string[];
|
|
140
|
+
};
|
|
141
|
+
project_id: {
|
|
142
|
+
type: string;
|
|
143
|
+
};
|
|
144
|
+
table: {
|
|
145
|
+
type: string;
|
|
146
|
+
};
|
|
147
|
+
version: {
|
|
148
|
+
type: string;
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
if: {
|
|
152
|
+
properties: {
|
|
153
|
+
type: {
|
|
154
|
+
const: string;
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
then: {
|
|
159
|
+
required: string[];
|
|
160
|
+
};
|
|
161
|
+
};
|
|
134
162
|
fields: {
|
|
135
163
|
type: string;
|
|
136
164
|
propertyNames: {
|
package/dist/index.js
CHANGED
|
@@ -78,6 +78,30 @@ var basicJsonSchema = {
|
|
|
78
78
|
"type": "string",
|
|
79
79
|
"enum": ["collection"]
|
|
80
80
|
},
|
|
81
|
+
"origin": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"properties": {
|
|
84
|
+
"type": {
|
|
85
|
+
"type": "string",
|
|
86
|
+
"enum": ["reference"]
|
|
87
|
+
},
|
|
88
|
+
"project_id": {
|
|
89
|
+
"type": "string"
|
|
90
|
+
},
|
|
91
|
+
"table": {
|
|
92
|
+
"type": "string"
|
|
93
|
+
},
|
|
94
|
+
"version": {
|
|
95
|
+
"type": "integer"
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"if": {
|
|
99
|
+
"properties": { "type": { "const": "reference" } }
|
|
100
|
+
},
|
|
101
|
+
"then": {
|
|
102
|
+
"required": ["project_id", "table"]
|
|
103
|
+
}
|
|
104
|
+
},
|
|
81
105
|
"fields": {
|
|
82
106
|
"type": "object",
|
|
83
107
|
"propertyNames": {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts"],"sourcesContent":["// Basic Schema Library\n// utils for validating and interacting with Basic schemas\nimport Ajv 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 \"propertyNames\": {\n \"pattern\": \"^[a-zA-Z0-9_]+$\",\n \"minLength\": 1,\n \"maxLength\": 50, \n \"type\": \"string\"\n },\n \"patternProperties\": {\n \"^[a-zA-Z0-9_]+$\": {\n \"type\": \"object\",\n \"propertyNames\": {\n \"pattern\": \"^[a-zA-Z0-9_]+$\",\n \"minLength\": 1,\n \"maxLength\": 50, \n \"type\": \"string\"\n },\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"collection\"]\n },\n \"fields\": {\n \"type\": \"object\",\n \"propertyNames\": {\n \"pattern\": \"^[a-zA-Z0-9_]+$\",\n \"minLength\": 1,\n \"maxLength\": 50, \n \"type\": \"string\"\n },\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 foo: { \n name: \"foo\",\n type: \"collection\",\n fields: {\n bar: {\n type: \"string\",\n required: true,\n }\n }\n }\n }\n }\n}\n\ntype Schema = {\n project_id: string,\n version: number,\n tables: any\n}\n\n\n/**\n * Compare two schemas and detect any differences between them\n * @param oldSchema - The original schema to compare against\n * @param newSchema - The new schema to compare with the original\n * @returns {Object} Comparison result containing:\n * - valid: boolean indicating if schemas are identical\n * - changes: Array of detected changes between schemas\n */\nfunction compareSchemas(oldSchema: any, newSchema: any) {\n const changes = _getSchemaChanges(oldSchema, newSchema)\n const valid = changes.length === 0 ? true : false\n return { valid, changes }\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: Schema): { valid: boolean, errors: ErrorObject[] } {\n const v = validator(schema)\n return {\n valid: v,\n errors: validator.errors || []\n }\n}\n\ntype 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 */\nfunction validateData(schema: Schema, table: string, data: Record<string, any>, checkRequired: boolean = true) : { valid: boolean, errors?: ErrorObject[], message?: string } {\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\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\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, errors: [] }\n}\n\n\n/**\n * Get the JSON schema definition for the Basic Schema\n * @returns {Object} The JSON schema\n */\nfunction getJsonSchema() {\n return basicJsonSchema\n}\n\nexport {\n validateSchema,\n validateData,\n generateEmptySchema,\n validateUpdateSchema,\n compareSchemas,\n getJsonSchema\n}"],"mappings":"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","names":["Ajv"]}
|
|
1
|
+
{"version":3,"sources":["../index.ts"],"sourcesContent":["// Basic Schema Library\n// utils for validating and interacting with Basic schemas\nimport Ajv 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 \"propertyNames\": {\n \"pattern\": \"^[a-zA-Z0-9_]+$\",\n \"minLength\": 1,\n \"maxLength\": 50, \n \"type\": \"string\"\n },\n \"patternProperties\": {\n \"^[a-zA-Z0-9_]+$\": {\n \"type\": \"object\",\n \"propertyNames\": {\n \"pattern\": \"^[a-zA-Z0-9_]+$\",\n \"minLength\": 1,\n \"maxLength\": 50, \n \"type\": \"string\"\n },\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"collection\"]\n },\n \"origin\": {\n \"type\": \"object\",\n \"properties\": {\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"reference\"]\n },\n \"project_id\": {\n \"type\": \"string\"\n },\n \"table\": {\n \"type\": \"string\"\n },\n \"version\": {\n \"type\": \"integer\"\n }\n },\n \"if\": {\n \"properties\": { \"type\": { \"const\": \"reference\" } }\n },\n \"then\": {\n \"required\": [\"project_id\", \"table\"]\n }\n },\n \"fields\": {\n \"type\": \"object\",\n \"propertyNames\": {\n \"pattern\": \"^[a-zA-Z0-9_]+$\",\n \"minLength\": 1,\n \"maxLength\": 50, \n \"type\": \"string\"\n },\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 foo: { \n name: \"foo\",\n type: \"collection\",\n fields: {\n bar: {\n type: \"string\",\n required: true,\n }\n }\n }\n }\n }\n}\n\ntype Schema = {\n project_id: string,\n version: number,\n tables: any\n}\n\n\n/**\n * Compare two schemas and detect any differences between them\n * @param oldSchema - The original schema to compare against\n * @param newSchema - The new schema to compare with the original\n * @returns {Object} Comparison result containing:\n * - valid: boolean indicating if schemas are identical\n * - changes: Array of detected changes between schemas\n */\nfunction compareSchemas(oldSchema: any, newSchema: any) {\n const changes = _getSchemaChanges(oldSchema, newSchema)\n const valid = changes.length === 0 ? true : false\n return { valid, changes }\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: Schema): { valid: boolean, errors: ErrorObject[] } {\n const v = validator(schema)\n return {\n valid: v,\n errors: validator.errors || []\n }\n}\n\ntype 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 */\nfunction validateData(schema: Schema, table: string, data: Record<string, any>, checkRequired: boolean = true) : { valid: boolean, errors?: ErrorObject[], message?: string } {\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\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\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, errors: [] }\n}\n\n\n/**\n * Get the JSON schema definition for the Basic Schema\n * @returns {Object} The JSON schema\n */\nfunction getJsonSchema() {\n return basicJsonSchema\n}\n\nexport {\n validateSchema,\n validateData,\n generateEmptySchema,\n validateUpdateSchema,\n compareSchemas,\n getJsonSchema\n}"],"mappings":"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","names":["Ajv"]}
|
package/dist/index.mjs
CHANGED
|
@@ -39,6 +39,30 @@ var basicJsonSchema = {
|
|
|
39
39
|
"type": "string",
|
|
40
40
|
"enum": ["collection"]
|
|
41
41
|
},
|
|
42
|
+
"origin": {
|
|
43
|
+
"type": "object",
|
|
44
|
+
"properties": {
|
|
45
|
+
"type": {
|
|
46
|
+
"type": "string",
|
|
47
|
+
"enum": ["reference"]
|
|
48
|
+
},
|
|
49
|
+
"project_id": {
|
|
50
|
+
"type": "string"
|
|
51
|
+
},
|
|
52
|
+
"table": {
|
|
53
|
+
"type": "string"
|
|
54
|
+
},
|
|
55
|
+
"version": {
|
|
56
|
+
"type": "integer"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"if": {
|
|
60
|
+
"properties": { "type": { "const": "reference" } }
|
|
61
|
+
},
|
|
62
|
+
"then": {
|
|
63
|
+
"required": ["project_id", "table"]
|
|
64
|
+
}
|
|
65
|
+
},
|
|
42
66
|
"fields": {
|
|
43
67
|
"type": "object",
|
|
44
68
|
"propertyNames": {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts"],"sourcesContent":["// Basic Schema Library\n// utils for validating and interacting with Basic schemas\nimport Ajv 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 \"propertyNames\": {\n \"pattern\": \"^[a-zA-Z0-9_]+$\",\n \"minLength\": 1,\n \"maxLength\": 50, \n \"type\": \"string\"\n },\n \"patternProperties\": {\n \"^[a-zA-Z0-9_]+$\": {\n \"type\": \"object\",\n \"propertyNames\": {\n \"pattern\": \"^[a-zA-Z0-9_]+$\",\n \"minLength\": 1,\n \"maxLength\": 50, \n \"type\": \"string\"\n },\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"collection\"]\n },\n \"fields\": {\n \"type\": \"object\",\n \"propertyNames\": {\n \"pattern\": \"^[a-zA-Z0-9_]+$\",\n \"minLength\": 1,\n \"maxLength\": 50, \n \"type\": \"string\"\n },\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 foo: { \n name: \"foo\",\n type: \"collection\",\n fields: {\n bar: {\n type: \"string\",\n required: true,\n }\n }\n }\n }\n }\n}\n\ntype Schema = {\n project_id: string,\n version: number,\n tables: any\n}\n\n\n/**\n * Compare two schemas and detect any differences between them\n * @param oldSchema - The original schema to compare against\n * @param newSchema - The new schema to compare with the original\n * @returns {Object} Comparison result containing:\n * - valid: boolean indicating if schemas are identical\n * - changes: Array of detected changes between schemas\n */\nfunction compareSchemas(oldSchema: any, newSchema: any) {\n const changes = _getSchemaChanges(oldSchema, newSchema)\n const valid = changes.length === 0 ? true : false\n return { valid, changes }\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: Schema): { valid: boolean, errors: ErrorObject[] } {\n const v = validator(schema)\n return {\n valid: v,\n errors: validator.errors || []\n }\n}\n\ntype 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 */\nfunction validateData(schema: Schema, table: string, data: Record<string, any>, checkRequired: boolean = true) : { valid: boolean, errors?: ErrorObject[], message?: string } {\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\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\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, errors: [] }\n}\n\n\n/**\n * Get the JSON schema definition for the Basic Schema\n * @returns {Object} The JSON schema\n */\nfunction getJsonSchema() {\n return basicJsonSchema\n}\n\nexport {\n validateSchema,\n validateData,\n generateEmptySchema,\n validateUpdateSchema,\n compareSchemas,\n getJsonSchema\n}"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../index.ts"],"sourcesContent":["// Basic Schema Library\n// utils for validating and interacting with Basic schemas\nimport Ajv 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 \"propertyNames\": {\n \"pattern\": \"^[a-zA-Z0-9_]+$\",\n \"minLength\": 1,\n \"maxLength\": 50, \n \"type\": \"string\"\n },\n \"patternProperties\": {\n \"^[a-zA-Z0-9_]+$\": {\n \"type\": \"object\",\n \"propertyNames\": {\n \"pattern\": \"^[a-zA-Z0-9_]+$\",\n \"minLength\": 1,\n \"maxLength\": 50, \n \"type\": \"string\"\n },\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"collection\"]\n },\n \"origin\": {\n \"type\": \"object\",\n \"properties\": {\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"reference\"]\n },\n \"project_id\": {\n \"type\": \"string\"\n },\n \"table\": {\n \"type\": \"string\"\n },\n \"version\": {\n \"type\": \"integer\"\n }\n },\n \"if\": {\n \"properties\": { \"type\": { \"const\": \"reference\" } }\n },\n \"then\": {\n \"required\": [\"project_id\", \"table\"]\n }\n },\n \"fields\": {\n \"type\": \"object\",\n \"propertyNames\": {\n \"pattern\": \"^[a-zA-Z0-9_]+$\",\n \"minLength\": 1,\n \"maxLength\": 50, \n \"type\": \"string\"\n },\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 foo: { \n name: \"foo\",\n type: \"collection\",\n fields: {\n bar: {\n type: \"string\",\n required: true,\n }\n }\n }\n }\n }\n}\n\ntype Schema = {\n project_id: string,\n version: number,\n tables: any\n}\n\n\n/**\n * Compare two schemas and detect any differences between them\n * @param oldSchema - The original schema to compare against\n * @param newSchema - The new schema to compare with the original\n * @returns {Object} Comparison result containing:\n * - valid: boolean indicating if schemas are identical\n * - changes: Array of detected changes between schemas\n */\nfunction compareSchemas(oldSchema: any, newSchema: any) {\n const changes = _getSchemaChanges(oldSchema, newSchema)\n const valid = changes.length === 0 ? true : false\n return { valid, changes }\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: Schema): { valid: boolean, errors: ErrorObject[] } {\n const v = validator(schema)\n return {\n valid: v,\n errors: validator.errors || []\n }\n}\n\ntype 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 */\nfunction validateData(schema: Schema, table: string, data: Record<string, any>, checkRequired: boolean = true) : { valid: boolean, errors?: ErrorObject[], message?: string } {\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\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\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, errors: [] }\n}\n\n\n/**\n * Get the JSON schema definition for the Basic Schema\n * @returns {Object} The JSON schema\n */\nfunction getJsonSchema() {\n return basicJsonSchema\n}\n\nexport {\n validateSchema,\n validateData,\n generateEmptySchema,\n validateUpdateSchema,\n compareSchemas,\n getJsonSchema\n}"],"mappings":"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","names":[]}
|
package/index.ts
CHANGED
|
@@ -41,6 +41,30 @@ const basicJsonSchema = {
|
|
|
41
41
|
"type": "string",
|
|
42
42
|
"enum": ["collection"]
|
|
43
43
|
},
|
|
44
|
+
"origin": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"properties": {
|
|
47
|
+
"type": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"enum": ["reference"]
|
|
50
|
+
},
|
|
51
|
+
"project_id": {
|
|
52
|
+
"type": "string"
|
|
53
|
+
},
|
|
54
|
+
"table": {
|
|
55
|
+
"type": "string"
|
|
56
|
+
},
|
|
57
|
+
"version": {
|
|
58
|
+
"type": "integer"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"if": {
|
|
62
|
+
"properties": { "type": { "const": "reference" } }
|
|
63
|
+
},
|
|
64
|
+
"then": {
|
|
65
|
+
"required": ["project_id", "table"]
|
|
66
|
+
}
|
|
67
|
+
},
|
|
44
68
|
"fields": {
|
|
45
69
|
"type": "object",
|
|
46
70
|
"propertyNames": {
|