@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/changelog.md +6 -5
- package/dist/index.d.mts +14 -4
- package/dist/index.d.ts +14 -4
- package/dist/index.js +450 -79
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +440 -79
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/readme.md +127 -1
- package/src/AuthContext.tsx +424 -120
- package/src/index.ts +2 -2
- package/src/schema.ts +159 -0
- package/src/sync/index.ts +1 -1
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