@based/schema 5.0.4-alpha.1 → 5.0.4
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/dist/dbSchema.js +37 -0
- package/dist/def/selvaBuffer.js +12 -31
- package/dist/def/typeDef.js +139 -104
- package/dist/def/types.d.ts +6 -2
- package/dist/parse/props.js +6 -0
- package/dist/parse/utils.js +5 -0
- package/dist/types.d.ts +15 -1
- package/dist/types.js +0 -1
- package/package.json +3 -2
package/dist/dbSchema.js
CHANGED
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
import { hash } from '@based/hash';
|
|
2
2
|
import { getPropType } from "./parse/utils.js";
|
|
3
3
|
import { deepCopy } from '@based/utils';
|
|
4
|
+
function _makeEdgeTypes(newTypes, typeName, props, propPrefix) {
|
|
5
|
+
const putEdgeProps = (typeName, refPath, edgeProps) => newTypes[`_${typeName}:${refPath}`] = { props: edgeProps };
|
|
6
|
+
for (const propName in props) {
|
|
7
|
+
const prop = props[propName];
|
|
8
|
+
const propType = getPropType(prop);
|
|
9
|
+
const nextPropPrefix = propPrefix ? `${propPrefix}.${propName}` : propName;
|
|
10
|
+
if (propType === 'object') {
|
|
11
|
+
_makeEdgeTypes(newTypes, typeName, prop.props, nextPropPrefix);
|
|
12
|
+
}
|
|
13
|
+
else if (propType === 'reference') {
|
|
14
|
+
const edgeProps = {};
|
|
15
|
+
Object.keys(prop).filter((k) => k[0] === '$').forEach((k) => edgeProps[k] = prop[k]);
|
|
16
|
+
if (Object.keys(edgeProps).length > 0) {
|
|
17
|
+
putEdgeProps(typeName, nextPropPrefix, edgeProps);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
else if (propType === 'references') {
|
|
21
|
+
const edgeProps = {};
|
|
22
|
+
Object.keys(prop.items).filter((k) => k[0] === '$').forEach((k) => edgeProps[k] = prop.items[k]);
|
|
23
|
+
if (Object.keys(edgeProps).length > 0) {
|
|
24
|
+
putEdgeProps(typeName, nextPropPrefix, edgeProps);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function makeEdgeTypes(types) {
|
|
30
|
+
const newTypes = {};
|
|
31
|
+
for (const typeName in types) {
|
|
32
|
+
const type = types[typeName];
|
|
33
|
+
_makeEdgeTypes(newTypes, typeName, type.props, '');
|
|
34
|
+
}
|
|
35
|
+
return newTypes;
|
|
36
|
+
}
|
|
4
37
|
export const strictSchemaToDbSchema = (schema) => {
|
|
5
38
|
// @ts-ignore
|
|
6
39
|
let dbSchema = deepCopy(schema);
|
|
@@ -45,6 +78,10 @@ export const strictSchemaToDbSchema = (schema) => {
|
|
|
45
78
|
};
|
|
46
79
|
delete dbSchema.props;
|
|
47
80
|
}
|
|
81
|
+
const edgeTypes = makeEdgeTypes(dbSchema.types);
|
|
82
|
+
for (const et in edgeTypes) {
|
|
83
|
+
dbSchema.types[et] = edgeTypes[et];
|
|
84
|
+
}
|
|
48
85
|
// Assign typeIds
|
|
49
86
|
for (const typeName in dbSchema.types) {
|
|
50
87
|
if (!('id' in dbSchema.types[typeName])) {
|
package/dist/def/selvaBuffer.js
CHANGED
|
@@ -48,13 +48,13 @@ function makeEdgeConstraintFlags(refSet, nodeTypeId, prop, dstNodeTypeId, invers
|
|
|
48
48
|
inverseProp.typeIndex === REFERENCES
|
|
49
49
|
? EDGE_FIELD_CONSTRAINT_FLAG_SKIP_DUMP
|
|
50
50
|
: 0x00;
|
|
51
|
-
if (
|
|
51
|
+
if (inverseProp) {
|
|
52
52
|
const x = refSet.add(nodeTypeId, prop.prop, dstNodeTypeId, inverseProp.prop);
|
|
53
53
|
flags |= x ? 0x00 : EDGE_FIELD_CONSTRAINT_FLAG_SKIP_DUMP;
|
|
54
54
|
}
|
|
55
55
|
return flags;
|
|
56
56
|
}
|
|
57
|
-
const propDefBuffer = (refSet, nodeTypeId, schema, prop
|
|
57
|
+
const propDefBuffer = (refSet, nodeTypeId, schema, prop) => {
|
|
58
58
|
const type = prop.typeIndex;
|
|
59
59
|
const selvaType = selvaTypeMap[type];
|
|
60
60
|
if (prop.len && (type === MICRO_BUFFER || type === VECTOR)) {
|
|
@@ -74,41 +74,22 @@ const propDefBuffer = (refSet, nodeTypeId, schema, prop, isEdge) => {
|
|
|
74
74
|
return [...buf];
|
|
75
75
|
}
|
|
76
76
|
else if (type === REFERENCE || type === REFERENCES) {
|
|
77
|
-
const buf = new Uint8Array(
|
|
77
|
+
const buf = new Uint8Array(7);
|
|
78
78
|
const view = new DataView(buf.buffer);
|
|
79
79
|
const dstType = schema[prop.inverseTypeName];
|
|
80
|
-
let eschema = [];
|
|
81
80
|
// @ts-ignore
|
|
82
|
-
buf[0] = selvaType + 2 * !!
|
|
81
|
+
buf[0] = selvaType + 2 * !!prop.__isEdge; // field type
|
|
83
82
|
buf[1] = makeEdgeConstraintFlags(refSet, nodeTypeId, prop, dstType.id, dstType.props[prop.inversePropName]); // flags
|
|
84
83
|
view.setUint16(2, dstType.id, true); // dst_node_type
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
if (prop.__isEdge) {
|
|
85
|
+
buf[4] = 0;
|
|
86
|
+
view.setUint16(5, 0, true);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
87
89
|
buf[4] = prop.inversePropNumber;
|
|
88
|
-
|
|
89
|
-
const edgesS = Object.values(prop.edges);
|
|
90
|
-
if (edgesS.length) {
|
|
91
|
-
const props = edgesS
|
|
92
|
-
.filter((v) => v.separate === true)
|
|
93
|
-
.sort((a, b) => (a.prop > b.prop ? 1 : -1));
|
|
94
|
-
const p = [
|
|
95
|
-
{
|
|
96
|
-
...EMPTY_MICRO_BUFFER,
|
|
97
|
-
len: prop.edgeMainLen || 1, // allow zero here... else useless padding
|
|
98
|
-
__isEdgeDef: true,
|
|
99
|
-
},
|
|
100
|
-
// or handle this here...
|
|
101
|
-
...props,
|
|
102
|
-
];
|
|
103
|
-
eschema = p
|
|
104
|
-
.map((prop) => propDefBuffer(null, 0, schema, prop, true))
|
|
105
|
-
.flat(1);
|
|
106
|
-
eschema.unshift(0, 0, 0, 0, sepPropCount(p), 0, 0, 0);
|
|
107
|
-
view.setUint32(5, eschema.length, true);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
90
|
+
view.setUint16(5, prop.edgeNodeTypeId, true); // meta_node_type
|
|
110
91
|
}
|
|
111
|
-
return [...buf
|
|
92
|
+
return [...buf];
|
|
112
93
|
}
|
|
113
94
|
else if (type === STRING ||
|
|
114
95
|
type === BINARY ||
|
|
@@ -153,7 +134,7 @@ export function schemaToSelvaBuffer(schema) {
|
|
|
153
134
|
1 + refFields, // u8 nrFixedFields
|
|
154
135
|
virtualFields, // u8 nrVirtualFields
|
|
155
136
|
0, // u8 spare1
|
|
156
|
-
...propDefBuffer(
|
|
137
|
+
...propDefBuffer(refSet, t.id, schema, {
|
|
157
138
|
...EMPTY_MICRO_BUFFER,
|
|
158
139
|
len: t.mainLen === 0 ? 1 : t.mainLen,
|
|
159
140
|
}),
|
package/dist/def/typeDef.js
CHANGED
|
@@ -17,27 +17,58 @@ export const updateTypeDefs = (schema) => {
|
|
|
17
17
|
if (!type.id) {
|
|
18
18
|
throw new Error('NEED ID ON TYPE');
|
|
19
19
|
}
|
|
20
|
-
const def = createSchemaTypeDef(typeName, type,
|
|
20
|
+
const def = createSchemaTypeDef(typeName, type, schema.locales ?? {
|
|
21
21
|
en: {},
|
|
22
22
|
});
|
|
23
23
|
schemaTypesParsed[typeName] = def;
|
|
24
24
|
schemaTypesParsedById[type.id] = def;
|
|
25
25
|
}
|
|
26
|
-
// Update inverseProps in references
|
|
27
26
|
for (const schema of Object.values(schemaTypesParsed)) {
|
|
28
27
|
for (const prop of Object.values(schema.props)) {
|
|
29
28
|
if (prop.typeIndex === REFERENCE || prop.typeIndex === REFERENCES) {
|
|
29
|
+
// FIXME Now references in edgeType are missing __isEdge
|
|
30
|
+
// However, we can soon just delete weak refs
|
|
31
|
+
if (!prop.__isEdge && !prop.inversePropName) {
|
|
32
|
+
prop.__isEdge = true;
|
|
33
|
+
}
|
|
30
34
|
if (!prop.__isEdge) {
|
|
35
|
+
// Update inverseProps in references
|
|
31
36
|
const dstType = schemaTypesParsed[prop.inverseTypeName];
|
|
32
37
|
prop.inverseTypeId = dstType.id;
|
|
33
38
|
prop.inversePropNumber = dstType.props[prop.inversePropName].prop;
|
|
39
|
+
if (prop.edges) {
|
|
40
|
+
if (dstType.props[prop.inversePropName].edges) {
|
|
41
|
+
// this currently is not allowed, but might be
|
|
42
|
+
const mergedEdges = {
|
|
43
|
+
...dstType.props[prop.inversePropName].edges,
|
|
44
|
+
...prop.edges,
|
|
45
|
+
};
|
|
46
|
+
dstType.props[prop.inversePropName].edges = mergedEdges;
|
|
47
|
+
prop.edges = mergedEdges;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
dstType.props[prop.inversePropName].edges = prop.edges;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Update edgeNodeTypeId
|
|
54
|
+
if (!prop.edgeNodeTypeId) {
|
|
55
|
+
if (prop.edges) {
|
|
56
|
+
const edgeTypeName = `_${schema.type}:${prop.path.join('.')}`;
|
|
57
|
+
const edgeType = schemaTypesParsed[edgeTypeName];
|
|
58
|
+
prop.edgeNodeTypeId = edgeType.id;
|
|
59
|
+
dstType.props[prop.inversePropName].edgeNodeTypeId = edgeType.id;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
prop.edgeNodeTypeId = 0;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
34
65
|
}
|
|
35
66
|
}
|
|
36
67
|
}
|
|
37
68
|
}
|
|
38
69
|
return { schemaTypesParsed, schemaTypesParsedById };
|
|
39
70
|
};
|
|
40
|
-
const createSchemaTypeDef = (typeName, type,
|
|
71
|
+
const createSchemaTypeDef = (typeName, type, locales, result = createEmptyDef(typeName, type, locales), path = [], top = true) => {
|
|
41
72
|
if (top) {
|
|
42
73
|
if (result.id == 0) {
|
|
43
74
|
if ('id' in type) {
|
|
@@ -82,116 +113,120 @@ const createSchemaTypeDef = (typeName, type, parsed, locales, result = createEmp
|
|
|
82
113
|
const propPath = [...path, key];
|
|
83
114
|
const propType = getPropType(schemaProp);
|
|
84
115
|
if (propType === 'object') {
|
|
85
|
-
createSchemaTypeDef(typeName, schemaProp,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
result.separateSortProps++;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
116
|
+
createSchemaTypeDef(typeName, schemaProp, locales, result, propPath, false);
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const len = getPropLen(schemaProp);
|
|
120
|
+
if (isPropType('string', schemaProp) ||
|
|
121
|
+
isPropType('alias', schemaProp) ||
|
|
122
|
+
isPropType('cardinality', schemaProp)) {
|
|
123
|
+
if (typeof schemaProp === 'object') {
|
|
124
|
+
if (!(schemaProp.maxBytes < 61) ||
|
|
125
|
+
!('max' in schemaProp && schemaProp.max < 31)) {
|
|
99
126
|
result.separateSortProps++;
|
|
100
127
|
}
|
|
101
128
|
}
|
|
102
|
-
else
|
|
103
|
-
result.
|
|
129
|
+
else {
|
|
130
|
+
result.separateSortProps++;
|
|
104
131
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
132
|
+
}
|
|
133
|
+
else if (isPropType('text', schemaProp)) {
|
|
134
|
+
result.separateSortText++;
|
|
135
|
+
}
|
|
136
|
+
else if (isPropType('colvec', schemaProp)) {
|
|
137
|
+
if (!result.insertOnly) {
|
|
138
|
+
throw new Error('colvec requires insertOnly');
|
|
109
139
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
if (schemaProp.step !== undefined) {
|
|
132
|
-
prop.step = parseMinMaxStep(schemaProp.step);
|
|
133
|
-
}
|
|
134
|
-
if (prop.typeIndex !== NUMBER && prop.step === undefined) {
|
|
135
|
-
prop.step = 1;
|
|
136
|
-
}
|
|
137
|
-
if (prop.typeIndex === VECTOR || prop.typeIndex === COLVEC) {
|
|
138
|
-
prop.vectorBaseType = schemaVectorBaseTypeToEnum(schemaProp.baseType ?? 'number');
|
|
139
|
-
}
|
|
140
|
-
if (prop.typeIndex === CARDINALITY) {
|
|
141
|
-
prop.cardinalityMode ??= cardinalityModeToEnum((schemaProp.mode ??= 'sparse'));
|
|
142
|
-
const prec = typeName == '_root' ? 14 : 8;
|
|
143
|
-
prop.cardinalityPrecision ??= schemaProp.precision ??= prec;
|
|
144
|
-
}
|
|
145
|
-
if (isPropType('enum', schemaProp)) {
|
|
146
|
-
prop.enum = Array.isArray(schemaProp) ? schemaProp : schemaProp.enum;
|
|
147
|
-
prop.reverseEnum = {};
|
|
148
|
-
for (let i = 0; i < prop.enum.length; i++) {
|
|
149
|
-
prop.reverseEnum[prop.enum[i]] = i;
|
|
150
|
-
}
|
|
140
|
+
}
|
|
141
|
+
const isseparate = isSeparate(schemaProp, len);
|
|
142
|
+
const typeIndex = TYPE_INDEX_MAP[propType];
|
|
143
|
+
const prop = {
|
|
144
|
+
typeIndex,
|
|
145
|
+
__isPropDef: true,
|
|
146
|
+
separate: isseparate,
|
|
147
|
+
path: propPath,
|
|
148
|
+
start: 0,
|
|
149
|
+
validation: schemaProp.validation ?? VALIDATION_MAP[typeIndex] ?? defaultValidation,
|
|
150
|
+
len,
|
|
151
|
+
default: schemaProp.default ?? DEFAULT_MAP[typeIndex],
|
|
152
|
+
prop: isseparate ? ++result.cnt : 0,
|
|
153
|
+
};
|
|
154
|
+
if (schemaProp.hooks) {
|
|
155
|
+
result.propHooks ??= {};
|
|
156
|
+
for (const key in schemaProp.hooks) {
|
|
157
|
+
prop.hooks = schemaProp.hooks;
|
|
158
|
+
result.propHooks[key] ??= new Set();
|
|
159
|
+
result.propHooks[key].add(prop);
|
|
151
160
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
161
|
+
}
|
|
162
|
+
if (schemaProp.max !== undefined) {
|
|
163
|
+
prop.max = parseMinMaxStep(schemaProp.max);
|
|
164
|
+
}
|
|
165
|
+
if (schemaProp.min !== undefined) {
|
|
166
|
+
prop.min = parseMinMaxStep(schemaProp.min);
|
|
167
|
+
}
|
|
168
|
+
if (schemaProp.step !== undefined) {
|
|
169
|
+
prop.step = parseMinMaxStep(schemaProp.step);
|
|
170
|
+
}
|
|
171
|
+
if (prop.typeIndex !== NUMBER && prop.step === undefined) {
|
|
172
|
+
prop.step = 1;
|
|
173
|
+
}
|
|
174
|
+
if (prop.typeIndex === VECTOR || prop.typeIndex === COLVEC) {
|
|
175
|
+
prop.vectorBaseType = schemaVectorBaseTypeToEnum(schemaProp.baseType ?? 'number');
|
|
176
|
+
}
|
|
177
|
+
if (prop.typeIndex === CARDINALITY) {
|
|
178
|
+
prop.cardinalityMode ??= cardinalityModeToEnum((schemaProp.mode ??= 'sparse'));
|
|
179
|
+
const prec = typeName == '_root' ? 14 : 8;
|
|
180
|
+
prop.cardinalityPrecision ??= schemaProp.precision ??= prec;
|
|
181
|
+
}
|
|
182
|
+
if (isPropType('enum', schemaProp)) {
|
|
183
|
+
prop.enum = Array.isArray(schemaProp) ? schemaProp : schemaProp.enum;
|
|
184
|
+
prop.reverseEnum = {};
|
|
185
|
+
for (let i = 0; i < prop.enum.length; i++) {
|
|
186
|
+
prop.reverseEnum[prop.enum[i]] = i;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
else if (isPropType('references', schemaProp)) {
|
|
190
|
+
if (result.partial) {
|
|
191
|
+
throw new Error('references is not supported with partial');
|
|
192
|
+
}
|
|
193
|
+
prop.inversePropName = schemaProp.items.prop;
|
|
194
|
+
prop.inverseTypeName = schemaProp.items.ref;
|
|
195
|
+
prop.dependent = schemaProp.items.dependent;
|
|
196
|
+
addEdges(prop, schemaProp.items);
|
|
197
|
+
}
|
|
198
|
+
else if (isPropType('reference', schemaProp)) {
|
|
199
|
+
if (result.partial) {
|
|
200
|
+
throw new Error('reference is not supported with partial');
|
|
201
|
+
}
|
|
202
|
+
prop.inversePropName = schemaProp.prop;
|
|
203
|
+
prop.inverseTypeName = schemaProp.ref;
|
|
204
|
+
prop.dependent = schemaProp.dependent;
|
|
205
|
+
addEdges(prop, schemaProp);
|
|
206
|
+
}
|
|
207
|
+
else if (typeof schemaProp === 'object') {
|
|
208
|
+
if (isPropType('string', schemaProp) || isPropType('text', schemaProp)) {
|
|
209
|
+
prop.compression =
|
|
210
|
+
'compression' in schemaProp && schemaProp.compression === 'none'
|
|
211
|
+
? 0
|
|
212
|
+
: 1;
|
|
213
|
+
}
|
|
214
|
+
else if (isPropType('timestamp', schemaProp) && 'on' in schemaProp) {
|
|
215
|
+
if (schemaProp.on[0] === 'c') {
|
|
216
|
+
result.createTs ??= [];
|
|
217
|
+
result.createTs.push(prop);
|
|
177
218
|
}
|
|
178
|
-
else if (
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
else if (schemaProp.on[0] === 'u') {
|
|
184
|
-
result.createTs ??= [];
|
|
185
|
-
result.createTs.push(prop);
|
|
186
|
-
result.updateTs ??= [];
|
|
187
|
-
result.updateTs.push(prop);
|
|
188
|
-
}
|
|
219
|
+
else if (schemaProp.on[0] === 'u') {
|
|
220
|
+
result.createTs ??= [];
|
|
221
|
+
result.createTs.push(prop);
|
|
222
|
+
result.updateTs ??= [];
|
|
223
|
+
result.updateTs.push(prop);
|
|
189
224
|
}
|
|
190
225
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
226
|
+
}
|
|
227
|
+
result.props[propPath.join('.')] = prop;
|
|
228
|
+
if (isseparate) {
|
|
229
|
+
result.separate.push(prop);
|
|
195
230
|
}
|
|
196
231
|
}
|
|
197
232
|
if (top) {
|
package/dist/def/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LangCode, SchemaHooks, SchemaLocales } from '../index.js';
|
|
1
|
+
import type { LangCode, SchemaHooks, SchemaLocales, SchemaPropHooks } from '../index.js';
|
|
2
2
|
import { Validation } from './validation.js';
|
|
3
3
|
import { TypeIndex, VectorBaseType } from './typeIndexes.js';
|
|
4
4
|
export * from './typeIndexes.js';
|
|
@@ -35,6 +35,7 @@ export type PropDef = {
|
|
|
35
35
|
vectorSize?: number;
|
|
36
36
|
cardinalityMode?: number;
|
|
37
37
|
cardinalityPrecision?: number;
|
|
38
|
+
edgeNodeTypeId?: number;
|
|
38
39
|
edgeMainLen?: 0;
|
|
39
40
|
hasDefaultEdges?: boolean;
|
|
40
41
|
reverseEnum?: {
|
|
@@ -55,6 +56,7 @@ export type PropDef = {
|
|
|
55
56
|
max?: any;
|
|
56
57
|
min?: any;
|
|
57
58
|
step?: any;
|
|
59
|
+
hooks?: SchemaPropHooks;
|
|
58
60
|
};
|
|
59
61
|
export type PropDefEdge = Partial<PropDef> & {
|
|
60
62
|
__isPropDef: true;
|
|
@@ -88,7 +90,6 @@ export type SchemaTypeDef = {
|
|
|
88
90
|
cnt: number;
|
|
89
91
|
checksum: number;
|
|
90
92
|
type: string;
|
|
91
|
-
lastId: number;
|
|
92
93
|
blockCapacity: number;
|
|
93
94
|
mainLen: number;
|
|
94
95
|
insertOnly: boolean;
|
|
@@ -130,6 +131,9 @@ export type SchemaTypeDef = {
|
|
|
130
131
|
locales: Partial<SchemaLocales>;
|
|
131
132
|
localeSize: number;
|
|
132
133
|
hooks?: SchemaHooks;
|
|
134
|
+
propHooks?: {
|
|
135
|
+
[K in keyof SchemaPropHooks]: Set<PropDef>;
|
|
136
|
+
};
|
|
133
137
|
};
|
|
134
138
|
export declare const VECTOR_BASE_TYPE_SIZE_MAP: Record<VectorBaseType, number>;
|
|
135
139
|
export declare const SIZE_MAP: Record<InternalSchemaProp, number>;
|
package/dist/parse/props.js
CHANGED
|
@@ -58,6 +58,12 @@ const shared = {
|
|
|
58
58
|
validation(val) {
|
|
59
59
|
expectFunction(val);
|
|
60
60
|
},
|
|
61
|
+
hooks(val, prop, ctx) {
|
|
62
|
+
expectObject(val);
|
|
63
|
+
for (const key in val) {
|
|
64
|
+
expectFunction(val[key]);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
61
67
|
};
|
|
62
68
|
function propParser(required, optional, allowShorthand) {
|
|
63
69
|
return (prop, ctx) => {
|
package/dist/parse/utils.js
CHANGED
|
@@ -17,6 +17,11 @@ export const getPropType = (prop, props, key) => {
|
|
|
17
17
|
}
|
|
18
18
|
if ('items' in prop) {
|
|
19
19
|
if (getPropType(prop.items) === 'reference') {
|
|
20
|
+
Object.keys(prop.items).filter((v) => v[0] === '$').forEach((v) => {
|
|
21
|
+
if (typeof prop.items[v] === 'string') {
|
|
22
|
+
prop.items[v] = { type: prop.items[v] };
|
|
23
|
+
}
|
|
24
|
+
});
|
|
20
25
|
return 'references';
|
|
21
26
|
}
|
|
22
27
|
return 'set';
|
package/dist/types.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { LangName } from './lang.js';
|
|
|
2
2
|
import type { Validation } from './def/validation.js';
|
|
3
3
|
type Role = 'title' | 'source' | 'media' | string;
|
|
4
4
|
export declare const numberDisplays: readonly ["short", "human", "ratio", "bytes", "euro", "dollar", "pound", "meter"];
|
|
5
|
-
export declare const dateDisplays: readonly ["date", "date-time", "date-time-text", "date-time-human", "
|
|
5
|
+
export declare const dateDisplays: readonly ["date", "date-time", "date-time-text", "date-time-human", "time", "time-precise"];
|
|
6
6
|
export declare const stringFormats: readonly ["alpha", "alphaLocales", "alphanumeric", "alphanumericLocales", "ascii", "base32", "base58", "base64", "BIC", "btcAddress", "clike", "code", "creditCard", "css", "currency", "dataURI", "EAN", "email", "ethereumAddress", "FQDN", "hexadecimal", "hexColor", "HSL", "html", "IBAN", "identityCard", "IMEI", "IP", "IPRange", "ISBN", "ISIN", "ISO31661Alpha2", "ISO31661Alpha3", "ISO4217", "ISO6391", "ISO8601", "ISRC", "ISSN", "javascript", "json", "JWT", "latLong", "licensePlate", "lowercase", "luhnNumber", "MACAddress", "magnetURI", "markdown", "MD5", "mimeType", "mobilePhone", "mobilePhoneLocales", "octal", "password", "passportNumber", "port", "postalCode", "postalCodeLocales", "python", "RFC3339", "rgbColor", "rust", "semVer", "slug", "surrogatePair", "taxID", "typescript", "uppercase", "URL", "UUID", "VAT", "multiline"];
|
|
7
7
|
type DateDisplay = (typeof dateDisplays)[number];
|
|
8
8
|
type NumberDisplay = (typeof numberDisplays)[number] | `round-${number}`;
|
|
@@ -27,6 +27,7 @@ type Prop<V extends PropValues> = {
|
|
|
27
27
|
readOnly?: boolean;
|
|
28
28
|
examples?: string[];
|
|
29
29
|
validation?: Validation;
|
|
30
|
+
hooks?: SchemaPropHooks;
|
|
30
31
|
} & V;
|
|
31
32
|
type EnumItem = string | number | boolean;
|
|
32
33
|
type NeverInItems = {
|
|
@@ -196,6 +197,19 @@ export type SchemaHooks = {
|
|
|
196
197
|
groupBy?: (query: BasedDbQuery, field: string) => void;
|
|
197
198
|
aggregate?: (query: BasedDbQuery, fields: Set<string>) => void;
|
|
198
199
|
};
|
|
200
|
+
export type SchemaPropHooks = {
|
|
201
|
+
create?: (value: any, payload: Record<string, any>) => any;
|
|
202
|
+
update?: (value: any, payload: Record<string, any>) => any;
|
|
203
|
+
read?: (value: any, result: Record<string, any>) => any;
|
|
204
|
+
aggregate?: (query: BasedDbQuery, fields: Set<string>) => void;
|
|
205
|
+
search?: (query: BasedDbQuery, fields: Set<string>) => void;
|
|
206
|
+
groupBy?: (query: BasedDbQuery, field: string) => void;
|
|
207
|
+
filter?: (query: BasedDbQuery, field: string, operator: Operator, value: any) => void;
|
|
208
|
+
include?: (query: BasedDbQuery, fields: Map<string, {
|
|
209
|
+
field: string;
|
|
210
|
+
opts?: any;
|
|
211
|
+
}>) => void;
|
|
212
|
+
};
|
|
199
213
|
type GenericSchemaType<isStrict = false> = {
|
|
200
214
|
hooks?: SchemaHooks;
|
|
201
215
|
id?: number;
|
package/dist/types.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@based/schema",
|
|
3
|
-
"version": "5.0.4
|
|
3
|
+
"version": "5.0.4",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist",
|
|
6
6
|
"README.md",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
".": "./dist/index.js"
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
|
+
"clean": "rm -rf .node_modules ./dist ./tsconfig.tsbuildinfo",
|
|
18
19
|
"build": "tsc",
|
|
19
20
|
"watch": "tsc --watch",
|
|
20
21
|
"test": "tsc && tsc $npm_config --noEmit && tsx --test $npm_config"
|
|
@@ -30,7 +31,7 @@
|
|
|
30
31
|
"typescript": "^5.6.3"
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {
|
|
33
|
-
"@based/utils": "
|
|
34
|
+
"@based/utils": "1.1.1",
|
|
34
35
|
"picocolors": "^1.1.0"
|
|
35
36
|
}
|
|
36
37
|
}
|