@objectstack/objectql 1.0.4 → 1.0.5
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/.turbo/turbo-build.log +22 -0
- package/CHANGELOG.md +14 -0
- package/dist/{registry.d.ts → index.d.mts} +433 -3
- package/dist/index.d.ts +999 -6
- package/dist/index.js +798 -9
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +768 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +5 -5
- package/tsconfig.json +1 -3
- package/dist/engine.d.ts +0 -304
- package/dist/engine.d.ts.map +0 -1
- package/dist/engine.js +0 -445
- package/dist/index.d.ts.map +0 -1
- package/dist/plugin.d.ts +0 -14
- package/dist/plugin.d.ts.map +0 -1
- package/dist/plugin.js +0 -52
- package/dist/protocol.d.ts +0 -119
- package/dist/protocol.d.ts.map +0 -1
- package/dist/protocol.js +0 -247
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js +0 -119
package/dist/protocol.js
DELETED
|
@@ -1,247 +0,0 @@
|
|
|
1
|
-
// We import SchemaRegistry directly since this class lives in the same package
|
|
2
|
-
import { SchemaRegistry } from './registry.js';
|
|
3
|
-
/**
|
|
4
|
-
* Simple hash function for ETag generation (browser-compatible)
|
|
5
|
-
* Uses a basic hash algorithm instead of crypto.createHash
|
|
6
|
-
*/
|
|
7
|
-
function simpleHash(str) {
|
|
8
|
-
let hash = 0;
|
|
9
|
-
for (let i = 0; i < str.length; i++) {
|
|
10
|
-
const char = str.charCodeAt(i);
|
|
11
|
-
hash = ((hash << 5) - hash) + char;
|
|
12
|
-
hash = hash & hash; // Convert to 32bit integer
|
|
13
|
-
}
|
|
14
|
-
return Math.abs(hash).toString(16);
|
|
15
|
-
}
|
|
16
|
-
export class ObjectStackProtocolImplementation {
|
|
17
|
-
constructor(engine) {
|
|
18
|
-
this.engine = engine;
|
|
19
|
-
}
|
|
20
|
-
async getDiscovery(_request) {
|
|
21
|
-
return {
|
|
22
|
-
version: '1.0',
|
|
23
|
-
apiName: 'ObjectStack API',
|
|
24
|
-
capabilities: {
|
|
25
|
-
graphql: false,
|
|
26
|
-
search: false,
|
|
27
|
-
websockets: false,
|
|
28
|
-
files: true,
|
|
29
|
-
analytics: false,
|
|
30
|
-
hub: false
|
|
31
|
-
},
|
|
32
|
-
endpoints: {
|
|
33
|
-
data: '/api/data',
|
|
34
|
-
metadata: '/api/meta',
|
|
35
|
-
auth: '/api/auth'
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
async getMetaTypes(_request) {
|
|
40
|
-
return {
|
|
41
|
-
types: SchemaRegistry.getRegisteredTypes()
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
async getMetaItems(request) {
|
|
45
|
-
return {
|
|
46
|
-
type: request.type,
|
|
47
|
-
items: SchemaRegistry.listItems(request.type)
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
async getMetaItem(request) {
|
|
51
|
-
return {
|
|
52
|
-
type: request.type,
|
|
53
|
-
name: request.name,
|
|
54
|
-
item: SchemaRegistry.getItem(request.type, request.name)
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
async getUiView(request) {
|
|
58
|
-
const schema = SchemaRegistry.getObject(request.object);
|
|
59
|
-
if (!schema)
|
|
60
|
-
throw new Error(`Object ${request.object} not found`);
|
|
61
|
-
let view;
|
|
62
|
-
if (request.type === 'list') {
|
|
63
|
-
view = {
|
|
64
|
-
type: 'list',
|
|
65
|
-
object: request.object,
|
|
66
|
-
columns: Object.keys(schema.fields || {}).slice(0, 5).map(f => ({
|
|
67
|
-
field: f,
|
|
68
|
-
label: schema.fields[f].label || f
|
|
69
|
-
}))
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
view = {
|
|
74
|
-
type: 'form',
|
|
75
|
-
object: request.object,
|
|
76
|
-
sections: [
|
|
77
|
-
{
|
|
78
|
-
label: 'General',
|
|
79
|
-
fields: Object.keys(schema.fields || {}).map(f => ({
|
|
80
|
-
field: f
|
|
81
|
-
}))
|
|
82
|
-
}
|
|
83
|
-
]
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
return view;
|
|
87
|
-
}
|
|
88
|
-
async findData(request) {
|
|
89
|
-
// TODO: Normalize query from HTTP Query params (string values) to DataEngineQueryOptions (typed)
|
|
90
|
-
// For now, we assume query is partially compatible or simple enough.
|
|
91
|
-
// We should parse 'top', 'skip', 'limit' to numbers if they are strings.
|
|
92
|
-
const options = { ...request.query };
|
|
93
|
-
if (options.top)
|
|
94
|
-
options.top = Number(options.top);
|
|
95
|
-
if (options.skip)
|
|
96
|
-
options.skip = Number(options.skip);
|
|
97
|
-
if (options.limit)
|
|
98
|
-
options.limit = Number(options.limit);
|
|
99
|
-
// Handle OData style $filter if present, or flat filters
|
|
100
|
-
// This is a naive implementation, a real OData parser is needed for complex scenarios.
|
|
101
|
-
const records = await this.engine.find(request.object, options);
|
|
102
|
-
return {
|
|
103
|
-
object: request.object,
|
|
104
|
-
value: records, // OData compaibility
|
|
105
|
-
records, // Legacy
|
|
106
|
-
total: records.length,
|
|
107
|
-
hasMore: false
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
async getData(request) {
|
|
111
|
-
const result = await this.engine.findOne(request.object, {
|
|
112
|
-
filter: { _id: request.id }
|
|
113
|
-
});
|
|
114
|
-
if (result) {
|
|
115
|
-
return {
|
|
116
|
-
object: request.object,
|
|
117
|
-
id: request.id,
|
|
118
|
-
record: result
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
throw new Error(`Record ${request.id} not found in ${request.object}`);
|
|
122
|
-
}
|
|
123
|
-
async createData(request) {
|
|
124
|
-
const result = await this.engine.insert(request.object, request.data);
|
|
125
|
-
return {
|
|
126
|
-
object: request.object,
|
|
127
|
-
id: result._id || result.id,
|
|
128
|
-
record: result
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
async updateData(request) {
|
|
132
|
-
// Adapt: update(obj, id, data) -> update(obj, data, options)
|
|
133
|
-
const result = await this.engine.update(request.object, request.data, { filter: { _id: request.id } });
|
|
134
|
-
return {
|
|
135
|
-
object: request.object,
|
|
136
|
-
id: request.id,
|
|
137
|
-
record: result
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
async deleteData(request) {
|
|
141
|
-
// Adapt: delete(obj, id) -> delete(obj, options)
|
|
142
|
-
await this.engine.delete(request.object, { filter: { _id: request.id } });
|
|
143
|
-
return {
|
|
144
|
-
object: request.object,
|
|
145
|
-
id: request.id,
|
|
146
|
-
success: true
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
// ==========================================
|
|
150
|
-
// Metadata Caching
|
|
151
|
-
// ==========================================
|
|
152
|
-
async getMetaItemCached(request) {
|
|
153
|
-
try {
|
|
154
|
-
const item = SchemaRegistry.getItem(request.type, request.name);
|
|
155
|
-
if (!item) {
|
|
156
|
-
throw new Error(`Metadata item ${request.type}/${request.name} not found`);
|
|
157
|
-
}
|
|
158
|
-
// Calculate ETag (simple hash of the stringified metadata)
|
|
159
|
-
const content = JSON.stringify(item);
|
|
160
|
-
const hash = simpleHash(content);
|
|
161
|
-
const etag = { value: hash, weak: false };
|
|
162
|
-
// Check If-None-Match header
|
|
163
|
-
if (request.cacheRequest?.ifNoneMatch) {
|
|
164
|
-
const clientEtag = request.cacheRequest.ifNoneMatch.replace(/^"(.*)"$/, '$1').replace(/^W\/"(.*)"$/, '$1');
|
|
165
|
-
if (clientEtag === hash) {
|
|
166
|
-
// Return 304 Not Modified
|
|
167
|
-
return {
|
|
168
|
-
notModified: true,
|
|
169
|
-
etag,
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
// Return full metadata with cache headers
|
|
174
|
-
return {
|
|
175
|
-
data: item,
|
|
176
|
-
etag,
|
|
177
|
-
lastModified: new Date().toISOString(),
|
|
178
|
-
cacheControl: {
|
|
179
|
-
directives: ['public', 'max-age'],
|
|
180
|
-
maxAge: 3600, // 1 hour
|
|
181
|
-
},
|
|
182
|
-
notModified: false,
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
catch (error) {
|
|
186
|
-
throw error;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
// ==========================================
|
|
190
|
-
// Batch Operations
|
|
191
|
-
// ==========================================
|
|
192
|
-
async batchData(_request) {
|
|
193
|
-
// Map high-level batch request to DataEngine batch if available
|
|
194
|
-
// Or implement loop here.
|
|
195
|
-
// For now, let's just fail or implement basic loop to satisfying interface
|
|
196
|
-
// since full batch mapping requires careful type handling.
|
|
197
|
-
throw new Error('Batch operations not yet fully implemented in protocol adapter');
|
|
198
|
-
}
|
|
199
|
-
async createManyData(request) {
|
|
200
|
-
const records = await this.engine.insert(request.object, request.records);
|
|
201
|
-
return {
|
|
202
|
-
object: request.object,
|
|
203
|
-
records,
|
|
204
|
-
count: records.length
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
async updateManyData(_request) {
|
|
208
|
-
// TODO: Implement proper updateMany in DataEngine
|
|
209
|
-
throw new Error('updateManyData not implemented');
|
|
210
|
-
}
|
|
211
|
-
async analyticsQuery(_request) {
|
|
212
|
-
throw new Error('analyticsQuery not implemented');
|
|
213
|
-
}
|
|
214
|
-
async getAnalyticsMeta(_request) {
|
|
215
|
-
throw new Error('getAnalyticsMeta not implemented');
|
|
216
|
-
}
|
|
217
|
-
async triggerAutomation(_request) {
|
|
218
|
-
throw new Error('triggerAutomation not implemented');
|
|
219
|
-
}
|
|
220
|
-
async listSpaces(_request) {
|
|
221
|
-
throw new Error('listSpaces not implemented');
|
|
222
|
-
}
|
|
223
|
-
async createSpace(_request) {
|
|
224
|
-
throw new Error('createSpace not implemented');
|
|
225
|
-
}
|
|
226
|
-
async installPlugin(_request) {
|
|
227
|
-
throw new Error('installPlugin not implemented');
|
|
228
|
-
}
|
|
229
|
-
async deleteManyData(request) {
|
|
230
|
-
// This expects deleting by IDs.
|
|
231
|
-
return this.engine.delete(request.object, {
|
|
232
|
-
filter: { _id: { $in: request.ids } },
|
|
233
|
-
...request.options
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
async saveMetaItem(request) {
|
|
237
|
-
if (!request.item) {
|
|
238
|
-
throw new Error('Item data is required');
|
|
239
|
-
}
|
|
240
|
-
// Default implementation saves to Memory Registry
|
|
241
|
-
SchemaRegistry.registerItem(request.type, request.item, 'name');
|
|
242
|
-
return {
|
|
243
|
-
success: true,
|
|
244
|
-
message: 'Saved to memory registry'
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
}
|
package/dist/registry.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/registry.js
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { ObjectSchema } from '@objectstack/spec/data';
|
|
2
|
-
import { ManifestSchema } from '@objectstack/spec/kernel';
|
|
3
|
-
import { AppSchema } from '@objectstack/spec/ui';
|
|
4
|
-
/**
|
|
5
|
-
* Global Schema Registry
|
|
6
|
-
* Unified storage for all metadata types (Objects, Apps, Flows, Layouts, etc.)
|
|
7
|
-
*/
|
|
8
|
-
export class SchemaRegistry {
|
|
9
|
-
/**
|
|
10
|
-
* Universal Register Method
|
|
11
|
-
* @param type The category of metadata (e.g., 'object', 'app', 'plugin')
|
|
12
|
-
* @param item The metadata item itself
|
|
13
|
-
* @param keyField The property to use as the unique key (default: 'name')
|
|
14
|
-
*/
|
|
15
|
-
static registerItem(type, item, keyField = 'name') {
|
|
16
|
-
if (!this.metadata.has(type)) {
|
|
17
|
-
this.metadata.set(type, new Map());
|
|
18
|
-
}
|
|
19
|
-
const collection = this.metadata.get(type);
|
|
20
|
-
const key = String(item[keyField]);
|
|
21
|
-
// Validation Hook
|
|
22
|
-
try {
|
|
23
|
-
this.validate(type, item);
|
|
24
|
-
}
|
|
25
|
-
catch (e) {
|
|
26
|
-
console.error(`[Registry] Validation failed for ${type} ${key}: ${e.message}`);
|
|
27
|
-
// For now, warn but don't crash, allowing partial/legacy loads
|
|
28
|
-
// throw e;
|
|
29
|
-
}
|
|
30
|
-
if (collection.has(key)) {
|
|
31
|
-
console.warn(`[Registry] Overwriting ${type}: ${key}`);
|
|
32
|
-
}
|
|
33
|
-
collection.set(key, item);
|
|
34
|
-
console.log(`[Registry] Registered ${type}: ${key}`);
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Validate Metadata against Spec Zod Schemas
|
|
38
|
-
*/
|
|
39
|
-
static validate(type, item) {
|
|
40
|
-
if (type === 'object') {
|
|
41
|
-
return ObjectSchema.parse(item);
|
|
42
|
-
}
|
|
43
|
-
if (type === 'app') {
|
|
44
|
-
// AppSchema might rely on Zod, imported via UI protocol
|
|
45
|
-
return AppSchema.parse(item);
|
|
46
|
-
}
|
|
47
|
-
if (type === 'plugin') {
|
|
48
|
-
return ManifestSchema.parse(item);
|
|
49
|
-
}
|
|
50
|
-
// Add more validations as needed
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Universal Unregister Method
|
|
55
|
-
*/
|
|
56
|
-
static unregisterItem(type, name) {
|
|
57
|
-
const collection = this.metadata.get(type);
|
|
58
|
-
if (collection && collection.has(name)) {
|
|
59
|
-
collection.delete(name);
|
|
60
|
-
console.log(`[Registry] Unregistered ${type}: ${name}`);
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
console.warn(`[Registry] Attempted to unregister non-existent ${type}: ${name}`);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Universal Get Method
|
|
68
|
-
*/
|
|
69
|
-
static getItem(type, name) {
|
|
70
|
-
return this.metadata.get(type)?.get(name);
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Universal List Method
|
|
74
|
-
*/
|
|
75
|
-
static listItems(type) {
|
|
76
|
-
return Array.from(this.metadata.get(type)?.values() || []);
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Get all registered metadata types (Kinds)
|
|
80
|
-
*/
|
|
81
|
-
static getRegisteredTypes() {
|
|
82
|
-
return Array.from(this.metadata.keys());
|
|
83
|
-
}
|
|
84
|
-
// ==========================================
|
|
85
|
-
// Typed Helper Methods (Shortcuts)
|
|
86
|
-
// ==========================================
|
|
87
|
-
/**
|
|
88
|
-
* Object Helpers
|
|
89
|
-
*/
|
|
90
|
-
static registerObject(schema) {
|
|
91
|
-
this.registerItem('object', schema, 'name');
|
|
92
|
-
}
|
|
93
|
-
static getObject(name) {
|
|
94
|
-
return this.getItem('object', name);
|
|
95
|
-
}
|
|
96
|
-
static getAllObjects() {
|
|
97
|
-
return this.listItems('object');
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Plugin Helpers
|
|
101
|
-
*/
|
|
102
|
-
static registerPlugin(manifest) {
|
|
103
|
-
this.registerItem('plugin', manifest, 'id');
|
|
104
|
-
}
|
|
105
|
-
static getAllPlugins() {
|
|
106
|
-
return this.listItems('plugin');
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Kind (Metadata Type) Helpers
|
|
110
|
-
*/
|
|
111
|
-
static registerKind(kind) {
|
|
112
|
-
this.registerItem('kind', kind, 'id');
|
|
113
|
-
}
|
|
114
|
-
static getAllKinds() {
|
|
115
|
-
return this.listItems('kind');
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
// Nested Map: Type -> Name/ID -> MetadataItem
|
|
119
|
-
SchemaRegistry.metadata = new Map();
|