@basictech/react 0.7.0-beta.0 → 0.7.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.
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { useState } from "react";
2
- import { useBasic, BasicProvider } from "./AuthContext";
2
+ import { useBasic, BasicProvider, BasicStorage, LocalStorageAdapter } from "./AuthContext";
3
3
  import { useLiveQuery as useQuery } from "dexie-react-hooks";
4
4
 
5
5
  // const useQuery = (queryable: any) => {
@@ -34,5 +34,5 @@ import { useLiveQuery as useQuery } from "dexie-react-hooks";
34
34
 
35
35
 
36
36
  export {
37
- useBasic, BasicProvider, useQuery
37
+ useBasic, BasicProvider, useQuery, BasicStorage, LocalStorageAdapter
38
38
  }
package/src/schema.ts ADDED
@@ -0,0 +1,159 @@
1
+ // Basic Schema Library
2
+ // utils for validating and interacting with Basic schemas
3
+ import Ajv, { ErrorObject } from 'ajv'
4
+
5
+ const basicJsonSchema = {
6
+ "$schema": "http://json-schema.org/draft-07/schema#",
7
+ "type": "object",
8
+ "properties": {
9
+ "project_id": {
10
+ "type": "string"
11
+ },
12
+ "namespace": {
13
+ "type": "string",
14
+ },
15
+ "version": {
16
+ "type": "integer",
17
+ "minimum": 0
18
+ },
19
+ "tables": {
20
+ "type": "object",
21
+ "patternProperties": {
22
+ "^[a-zA-Z0-9_]+$": {
23
+ "type": "object",
24
+ "properties": {
25
+ "name": {
26
+ "type": "string"
27
+ },
28
+ "type": {
29
+ "type": "string",
30
+ "enum": ["collection"]
31
+ },
32
+ "fields": {
33
+ "type": "object",
34
+ "patternProperties": {
35
+ "^[a-zA-Z0-9_]+$": {
36
+ "type": "object",
37
+ "properties": {
38
+ "type": {
39
+ "type": "string",
40
+ "enum": ["string", "boolean", "number", "json"]
41
+ },
42
+ "indexed": {
43
+ "type": "boolean"
44
+ },
45
+ "required": {
46
+ "type": "boolean"
47
+ }
48
+ },
49
+ "required": ["type"]
50
+ }
51
+ },
52
+ "additionalProperties": true
53
+ }
54
+ },
55
+ "required": ["fields"]
56
+ }
57
+ },
58
+ "additionalProperties": true
59
+ }
60
+ },
61
+ "required": ["project_id", "version", "tables"]
62
+ }
63
+ const ajv = new Ajv()
64
+ const validator = ajv.compile(basicJsonSchema)
65
+
66
+ type Schema = typeof basicJsonSchema
67
+
68
+ function generateEmptySchema() {
69
+
70
+ }
71
+
72
+
73
+ /**
74
+ * Validate a schema
75
+ * only checks if the schema is formatted correctly, not if can be published
76
+ * @param schema - The schema to validate
77
+ * @returns {valid: boolean, errors: any[]} - The validation result
78
+ */
79
+ function validateSchema(schema: Schema) : {valid: boolean, errors: ErrorObject[]} {
80
+ const v = validator(schema)
81
+ return {
82
+ valid: v,
83
+ errors: validator.errors || []
84
+ }
85
+ }
86
+
87
+ // type ErrorObject = {
88
+ // keyword: string;
89
+ // instancePath: string;
90
+ // schemaPath: string;
91
+ // params: Record<string, any>;
92
+ // propertyName?: string;
93
+ // message?: string;
94
+ // schema?: any;
95
+ // parentSchema?: any;
96
+ // data?: any;
97
+ // }
98
+
99
+
100
+ function validateData(schema: any, table: string, data: Record<string, any>, checkRequired: boolean = true) {
101
+ const valid = validateSchema(schema)
102
+ if (!valid.valid) {
103
+ return { valid: false, errors: valid.errors, message: "Schema is invalid" }
104
+ }
105
+
106
+ const tableSchema = schema.tables[table]
107
+
108
+ if (!tableSchema) {
109
+ return { valid: false, errors: [{ message: `Table ${table} not found in schema` }], message: "Table not found" }
110
+ }
111
+
112
+ for (const [fieldName, fieldValue] of Object.entries(data)) {
113
+ const fieldSchema = tableSchema.fields[fieldName]
114
+
115
+ if (!fieldSchema) {
116
+ return {
117
+ valid: false,
118
+ errors: [{ message: `Field ${fieldName} not found in schema` }],
119
+ message: "Invalid field"
120
+ }
121
+ }
122
+
123
+ const schemaType = fieldSchema.type
124
+ const valueType = typeof fieldValue
125
+
126
+ if (
127
+ (schemaType === 'string' && valueType !== 'string') ||
128
+ (schemaType === 'number' && valueType !== 'number') ||
129
+ (schemaType === 'boolean' && valueType !== 'boolean') ||
130
+ (schemaType === 'json' && valueType !== 'object')
131
+ ) {
132
+ return {
133
+ valid: false,
134
+ errors: [{
135
+ message: `Field ${fieldName} should be type ${schemaType}, got ${valueType}`
136
+ }],
137
+ message: "invalid type"
138
+ }
139
+ }
140
+ }
141
+
142
+ if (checkRequired) {
143
+ for (const [fieldName, fieldSchema] of Object.entries(tableSchema.fields)) {
144
+ if ((fieldSchema as { required?: boolean }).required && !data[fieldName]) {
145
+ return { valid: false, errors: [{ message: `Field ${fieldName} is required` }], message: "Required field missing" }
146
+ }
147
+ }
148
+ }
149
+
150
+ return { valid: true, errors: [] }
151
+ }
152
+
153
+
154
+ export {
155
+ validateSchema,
156
+ validateData,
157
+ generateEmptySchema
158
+ }
159
+
package/src/sync/index.ts CHANGED
@@ -8,7 +8,7 @@ import 'dexie-observable';
8
8
  import { syncProtocol } from './syncProtocol'
9
9
  import { log } from '../config'
10
10
 
11
- import { validateSchema, validateData } from '@basictech/schema'
11
+ import { validateSchema, validateData } from '../schema'
12
12
  syncProtocol()
13
13
 
14
14