js-bao 0.3.0-alpha.0 → 0.3.0-alpha.2
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/cloudflare-do.cjs +92 -3
- package/dist/cloudflare-do.d.cts +21 -2
- package/dist/cloudflare-do.d.ts +21 -2
- package/dist/cloudflare-do.js +92 -3
- package/dist/cloudflare.d.cts +16 -1
- package/dist/cloudflare.d.ts +16 -1
- package/dist/codegen.cjs +3 -3
- package/dist/index.cjs +6 -2
- package/dist/index.js +6 -2
- package/dist/node.cjs +6 -2
- package/dist/node.js +6 -2
- package/package.json +3 -3
package/dist/cloudflare-do.cjs
CHANGED
|
@@ -1979,6 +1979,7 @@ function createDatabaseDO(config = {}) {
|
|
|
1979
1979
|
if (request.method === "DELETE" && path === "/destroy") {
|
|
1980
1980
|
await this._doState.storage.deleteAll();
|
|
1981
1981
|
this._initialized = false;
|
|
1982
|
+
this._engine.initialized = false;
|
|
1982
1983
|
return Response.json({
|
|
1983
1984
|
deleted: true,
|
|
1984
1985
|
deletedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -2026,6 +2027,8 @@ function createDatabaseDO(config = {}) {
|
|
|
2026
2027
|
return this._handleHealth();
|
|
2027
2028
|
case "/describe":
|
|
2028
2029
|
return this._handleDescribe(request);
|
|
2030
|
+
case "/models":
|
|
2031
|
+
return this._handleModelList();
|
|
2029
2032
|
default:
|
|
2030
2033
|
return this._errorResponse("Not found", 404);
|
|
2031
2034
|
}
|
|
@@ -2047,6 +2050,7 @@ function createDatabaseDO(config = {}) {
|
|
|
2047
2050
|
modelName,
|
|
2048
2051
|
docId,
|
|
2049
2052
|
request,
|
|
2053
|
+
engine: this._engine,
|
|
2050
2054
|
filter,
|
|
2051
2055
|
options
|
|
2052
2056
|
};
|
|
@@ -2065,7 +2069,18 @@ function createDatabaseDO(config = {}) {
|
|
|
2065
2069
|
});
|
|
2066
2070
|
const { sql, params, sortFields } = translator.translateFind(filter, options);
|
|
2067
2071
|
const rawResults = this._engine.execSqlSync(sql, params);
|
|
2068
|
-
|
|
2072
|
+
let data = rawResults.map((row) => this._parseRow(row));
|
|
2073
|
+
if (hooks?.afterQuery) {
|
|
2074
|
+
const ctx = {
|
|
2075
|
+
modelName,
|
|
2076
|
+
docId,
|
|
2077
|
+
request,
|
|
2078
|
+
engine: this._engine,
|
|
2079
|
+
results: data
|
|
2080
|
+
};
|
|
2081
|
+
const result = await hooks.afterQuery(ctx);
|
|
2082
|
+
data = result.results;
|
|
2083
|
+
}
|
|
2069
2084
|
const limit = options?.limit;
|
|
2070
2085
|
const hasMore = CursorManager.hasMoreResults(limit, data.length);
|
|
2071
2086
|
const isFirstPage = !options?.uniqueStartKey;
|
|
@@ -2083,6 +2098,18 @@ function createDatabaseDO(config = {}) {
|
|
|
2083
2098
|
};
|
|
2084
2099
|
return Response.json(response);
|
|
2085
2100
|
}
|
|
2101
|
+
/** @internal — Check for reserved field names in record data */
|
|
2102
|
+
_checkReservedFields(data) {
|
|
2103
|
+
for (const key of Object.keys(data)) {
|
|
2104
|
+
if (key === "type") {
|
|
2105
|
+
return `Field 'type' is reserved and cannot be used in record data`;
|
|
2106
|
+
}
|
|
2107
|
+
if (key.startsWith("_meta")) {
|
|
2108
|
+
return `Field '${key}' is reserved (fields starting with '_meta' are internal) and cannot be used in record data`;
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
return null;
|
|
2112
|
+
}
|
|
2086
2113
|
/** @internal */
|
|
2087
2114
|
async _handleSave(request, docId) {
|
|
2088
2115
|
const body = await request.json();
|
|
@@ -2090,6 +2117,15 @@ function createDatabaseDO(config = {}) {
|
|
|
2090
2117
|
if (!modelName || !id) {
|
|
2091
2118
|
return this._errorResponse("modelName and id are required", 400);
|
|
2092
2119
|
}
|
|
2120
|
+
if (!data) {
|
|
2121
|
+
return this._errorResponse("data is required", 400);
|
|
2122
|
+
}
|
|
2123
|
+
if (data) {
|
|
2124
|
+
const reservedError = this._checkReservedFields(data);
|
|
2125
|
+
if (reservedError) {
|
|
2126
|
+
return this._errorResponse(reservedError, 400);
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2093
2129
|
if (condition && !this._checkCondition(modelName, id, condition)) {
|
|
2094
2130
|
return this._errorResponse(
|
|
2095
2131
|
`Condition not met for ${modelName}/${id}`,
|
|
@@ -2108,6 +2144,7 @@ function createDatabaseDO(config = {}) {
|
|
|
2108
2144
|
modelName,
|
|
2109
2145
|
docId,
|
|
2110
2146
|
request,
|
|
2147
|
+
engine: this._engine,
|
|
2111
2148
|
id,
|
|
2112
2149
|
data,
|
|
2113
2150
|
stringSets,
|
|
@@ -2146,6 +2183,10 @@ function createDatabaseDO(config = {}) {
|
|
|
2146
2183
|
if (!modelName || !id || !data) {
|
|
2147
2184
|
return this._errorResponse("modelName, id, and data are required", 400);
|
|
2148
2185
|
}
|
|
2186
|
+
const reservedError = this._checkReservedFields(data);
|
|
2187
|
+
if (reservedError) {
|
|
2188
|
+
return this._errorResponse(reservedError, 400);
|
|
2189
|
+
}
|
|
2149
2190
|
if (!this._engine.recordExists(modelName, id)) {
|
|
2150
2191
|
return this._errorResponse(`Record ${modelName}/${id} not found`, 404);
|
|
2151
2192
|
}
|
|
@@ -2160,6 +2201,7 @@ function createDatabaseDO(config = {}) {
|
|
|
2160
2201
|
modelName,
|
|
2161
2202
|
docId,
|
|
2162
2203
|
request,
|
|
2204
|
+
engine: this._engine,
|
|
2163
2205
|
id,
|
|
2164
2206
|
data,
|
|
2165
2207
|
stringSets,
|
|
@@ -2205,11 +2247,21 @@ function createDatabaseDO(config = {}) {
|
|
|
2205
2247
|
);
|
|
2206
2248
|
}
|
|
2207
2249
|
if (hooks?.beforeDelete) {
|
|
2250
|
+
let record = null;
|
|
2251
|
+
const rows = this._engine.execSqlSync(
|
|
2252
|
+
"SELECT id, type, data_json FROM records WHERE id = ? AND type = ?",
|
|
2253
|
+
[id, modelName]
|
|
2254
|
+
);
|
|
2255
|
+
if (rows.length > 0) {
|
|
2256
|
+
record = this._parseRow(rows[0]);
|
|
2257
|
+
}
|
|
2208
2258
|
const ctx = {
|
|
2209
2259
|
modelName,
|
|
2210
2260
|
docId,
|
|
2211
2261
|
request,
|
|
2212
|
-
|
|
2262
|
+
engine: this._engine,
|
|
2263
|
+
id,
|
|
2264
|
+
record
|
|
2213
2265
|
};
|
|
2214
2266
|
const result = await hooks.beforeDelete(ctx);
|
|
2215
2267
|
if (!result.allow) {
|
|
@@ -2243,12 +2295,20 @@ function createDatabaseDO(config = {}) {
|
|
|
2243
2295
|
400
|
|
2244
2296
|
);
|
|
2245
2297
|
}
|
|
2298
|
+
const reservedError = this._checkReservedFields(op.data);
|
|
2299
|
+
if (reservedError) {
|
|
2300
|
+
return this._errorResponse(
|
|
2301
|
+
`Operation ${i}: ${reservedError}`,
|
|
2302
|
+
400
|
|
2303
|
+
);
|
|
2304
|
+
}
|
|
2246
2305
|
if (hooks?.beforeSave) {
|
|
2247
2306
|
const isNew = op.op === "save" ? !this._engine.recordExists(op.modelName, op.id) : false;
|
|
2248
2307
|
const ctx = {
|
|
2249
2308
|
modelName: op.modelName,
|
|
2250
2309
|
docId,
|
|
2251
2310
|
request,
|
|
2311
|
+
engine: this._engine,
|
|
2252
2312
|
id: op.id,
|
|
2253
2313
|
data: op.data,
|
|
2254
2314
|
stringSets: op.stringSets,
|
|
@@ -2261,11 +2321,21 @@ function createDatabaseDO(config = {}) {
|
|
|
2261
2321
|
}
|
|
2262
2322
|
} else if (op.op === "delete") {
|
|
2263
2323
|
if (hooks?.beforeDelete) {
|
|
2324
|
+
let record = null;
|
|
2325
|
+
const rows = this._engine.execSqlSync(
|
|
2326
|
+
"SELECT id, type, data_json FROM records WHERE id = ? AND type = ?",
|
|
2327
|
+
[op.id, op.modelName]
|
|
2328
|
+
);
|
|
2329
|
+
if (rows.length > 0) {
|
|
2330
|
+
record = this._parseRow(rows[0]);
|
|
2331
|
+
}
|
|
2264
2332
|
const ctx = {
|
|
2265
2333
|
modelName: op.modelName,
|
|
2266
2334
|
docId,
|
|
2267
2335
|
request,
|
|
2268
|
-
|
|
2336
|
+
engine: this._engine,
|
|
2337
|
+
id: op.id,
|
|
2338
|
+
record
|
|
2269
2339
|
};
|
|
2270
2340
|
const result = await hooks.beforeDelete(ctx);
|
|
2271
2341
|
if (!result.allow) {
|
|
@@ -2490,6 +2560,7 @@ function createDatabaseDO(config = {}) {
|
|
|
2490
2560
|
modelName,
|
|
2491
2561
|
docId,
|
|
2492
2562
|
request,
|
|
2563
|
+
engine: this._engine,
|
|
2493
2564
|
filter
|
|
2494
2565
|
};
|
|
2495
2566
|
const result = await hooks.beforeQuery(ctx);
|
|
@@ -2602,6 +2673,7 @@ function createDatabaseDO(config = {}) {
|
|
|
2602
2673
|
modelName,
|
|
2603
2674
|
docId,
|
|
2604
2675
|
request,
|
|
2676
|
+
engine: this._engine,
|
|
2605
2677
|
filter
|
|
2606
2678
|
};
|
|
2607
2679
|
const result = await hooks.beforeQuery(ctx);
|
|
@@ -3087,6 +3159,23 @@ function createDatabaseDO(config = {}) {
|
|
|
3087
3159
|
const response = { modelName, fields };
|
|
3088
3160
|
return Response.json(response);
|
|
3089
3161
|
}
|
|
3162
|
+
/** @internal — List all known model names from records and _model_fields */
|
|
3163
|
+
_handleModelList() {
|
|
3164
|
+
const fromRecords = this._engine.execSqlSync(
|
|
3165
|
+
"SELECT DISTINCT type FROM records ORDER BY type"
|
|
3166
|
+
);
|
|
3167
|
+
const fromFields = this._engine.execSqlSync(
|
|
3168
|
+
"SELECT DISTINCT model_name FROM _model_fields ORDER BY model_name"
|
|
3169
|
+
);
|
|
3170
|
+
const fromIndexes = this._engine.execSqlSync(
|
|
3171
|
+
"SELECT DISTINCT model_name FROM _indexes ORDER BY model_name"
|
|
3172
|
+
);
|
|
3173
|
+
const modelSet = /* @__PURE__ */ new Set();
|
|
3174
|
+
for (const row of fromRecords) modelSet.add(row.type);
|
|
3175
|
+
for (const row of fromFields) modelSet.add(row.model_name);
|
|
3176
|
+
for (const row of fromIndexes) modelSet.add(row.model_name);
|
|
3177
|
+
return Response.json({ models: Array.from(modelSet).sort() });
|
|
3178
|
+
}
|
|
3090
3179
|
/** @internal */
|
|
3091
3180
|
_errorResponse(message, status) {
|
|
3092
3181
|
const body = { error: message };
|
package/dist/cloudflare-do.d.cts
CHANGED
|
@@ -194,7 +194,7 @@ interface JsonSchemaEngineOptions extends JsonSchemaOptions {
|
|
|
194
194
|
}
|
|
195
195
|
declare abstract class JsonSchemaEngine extends DatabaseEngine {
|
|
196
196
|
protected schemaOptions: JsonSchemaEngineOptions;
|
|
197
|
-
|
|
197
|
+
initialized: boolean;
|
|
198
198
|
constructor(options: JsonSchemaEngineOptions);
|
|
199
199
|
/**
|
|
200
200
|
* Execute SQL and return results.
|
|
@@ -880,6 +880,8 @@ interface HookContext {
|
|
|
880
880
|
docId: string;
|
|
881
881
|
/** The raw request (for reading headers, auth tokens, etc.) */
|
|
882
882
|
request: Request;
|
|
883
|
+
/** The DO's SQLite engine (for direct queries, e.g. lookup functions) */
|
|
884
|
+
engine: any;
|
|
883
885
|
}
|
|
884
886
|
/** Context for beforeSave hooks */
|
|
885
887
|
interface BeforeSaveContext extends HookContext {
|
|
@@ -896,6 +898,8 @@ interface BeforeSaveContext extends HookContext {
|
|
|
896
898
|
interface BeforeDeleteContext extends HookContext {
|
|
897
899
|
/** Record ID being deleted */
|
|
898
900
|
id: string;
|
|
901
|
+
/** The existing record being deleted (parsed from data_json) */
|
|
902
|
+
record: Record<string, any> | null;
|
|
899
903
|
}
|
|
900
904
|
/** Context for beforeQuery hooks */
|
|
901
905
|
interface BeforeQueryContext extends HookContext {
|
|
@@ -904,6 +908,11 @@ interface BeforeQueryContext extends HookContext {
|
|
|
904
908
|
/** Query options (sort, limit, etc.) */
|
|
905
909
|
options?: QueryOptions;
|
|
906
910
|
}
|
|
911
|
+
/** Context for afterQuery hooks */
|
|
912
|
+
interface AfterQueryContext extends HookContext {
|
|
913
|
+
/** The query results to filter */
|
|
914
|
+
results: Record<string, any>[];
|
|
915
|
+
}
|
|
907
916
|
/** Result from beforeSave/beforeDelete hooks */
|
|
908
917
|
interface HookResult {
|
|
909
918
|
allow: boolean;
|
|
@@ -915,11 +924,17 @@ interface BeforeQueryResult extends HookResult {
|
|
|
915
924
|
/** Additional filter merged into the query via $and */
|
|
916
925
|
injectFilter?: DocumentFilter;
|
|
917
926
|
}
|
|
927
|
+
/** Result from afterQuery hooks — returns filtered results */
|
|
928
|
+
interface AfterQueryResult {
|
|
929
|
+
/** The filtered results to return */
|
|
930
|
+
results: Record<string, any>[];
|
|
931
|
+
}
|
|
918
932
|
/** Hook definitions for createDatabaseDO */
|
|
919
933
|
interface DatabaseDOHooks {
|
|
920
934
|
beforeSave?: (ctx: BeforeSaveContext) => Promise<HookResult>;
|
|
921
935
|
beforeDelete?: (ctx: BeforeDeleteContext) => Promise<HookResult>;
|
|
922
936
|
beforeQuery?: (ctx: BeforeQueryContext) => Promise<BeforeQueryResult>;
|
|
937
|
+
afterQuery?: (ctx: AfterQueryContext) => Promise<AfterQueryResult>;
|
|
923
938
|
}
|
|
924
939
|
|
|
925
940
|
/**
|
|
@@ -1151,6 +1166,8 @@ declare function createDatabaseDO(config?: DatabaseDOConfig): {
|
|
|
1151
1166
|
fetch(request: Request): Promise<Response>;
|
|
1152
1167
|
/** @internal */
|
|
1153
1168
|
_handleQuery(request: Request, docId: string): Promise<Response>;
|
|
1169
|
+
/** @internal — Check for reserved field names in record data */
|
|
1170
|
+
_checkReservedFields(data: Record<string, any>): string | null;
|
|
1154
1171
|
/** @internal */
|
|
1155
1172
|
_handleSave(request: Request, docId: string): Promise<Response>;
|
|
1156
1173
|
/** @internal — Partial update: merge provided fields into existing record */
|
|
@@ -1231,6 +1248,8 @@ declare function createDatabaseDO(config?: DatabaseDOConfig): {
|
|
|
1231
1248
|
_handleHealth(): Response;
|
|
1232
1249
|
/** @internal — Return tracked field names and types for a model */
|
|
1233
1250
|
_handleDescribe(request: Request): Response;
|
|
1251
|
+
/** @internal — List all known model names from records and _model_fields */
|
|
1252
|
+
_handleModelList(): Response;
|
|
1234
1253
|
/** @internal */
|
|
1235
1254
|
_errorResponse(message: string, status: number): Response;
|
|
1236
1255
|
/** @internal */
|
|
@@ -1300,4 +1319,4 @@ interface Env {
|
|
|
1300
1319
|
*/
|
|
1301
1320
|
declare function handleRequest(request: Request, env: Env): Promise<Response>;
|
|
1302
1321
|
|
|
1303
|
-
export { type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type CountRequest, type CountResponse, type DatabaseDOConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DocumentDOConfig, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, DurableObjectEngine, type DurableObjectEngineOptions, type DurableObjectId, type DurableObjectNamespace, type DurableObjectState, type DurableObjectStorage, type DurableObjectStub, type Env, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, JsonQueryTranslator, type JsonQueryTranslatorOptions, JsonSchemaDDL, type JsonSchemaOptions, type PatchRequest, type PatchResponse, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveRequest, type SaveResponse, type SqlStorage, type SqlStorageCursor, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, createDatabaseDO, createDocumentDO, handleRequest };
|
|
1322
|
+
export { type AfterQueryContext, type AfterQueryResult, type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type CountRequest, type CountResponse, type DatabaseDOConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DocumentDOConfig, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, DurableObjectEngine, type DurableObjectEngineOptions, type DurableObjectId, type DurableObjectNamespace, type DurableObjectState, type DurableObjectStorage, type DurableObjectStub, type Env, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, JsonQueryTranslator, type JsonQueryTranslatorOptions, JsonSchemaDDL, type JsonSchemaOptions, type PatchRequest, type PatchResponse, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveRequest, type SaveResponse, type SqlStorage, type SqlStorageCursor, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, createDatabaseDO, createDocumentDO, handleRequest };
|
package/dist/cloudflare-do.d.ts
CHANGED
|
@@ -194,7 +194,7 @@ interface JsonSchemaEngineOptions extends JsonSchemaOptions {
|
|
|
194
194
|
}
|
|
195
195
|
declare abstract class JsonSchemaEngine extends DatabaseEngine {
|
|
196
196
|
protected schemaOptions: JsonSchemaEngineOptions;
|
|
197
|
-
|
|
197
|
+
initialized: boolean;
|
|
198
198
|
constructor(options: JsonSchemaEngineOptions);
|
|
199
199
|
/**
|
|
200
200
|
* Execute SQL and return results.
|
|
@@ -880,6 +880,8 @@ interface HookContext {
|
|
|
880
880
|
docId: string;
|
|
881
881
|
/** The raw request (for reading headers, auth tokens, etc.) */
|
|
882
882
|
request: Request;
|
|
883
|
+
/** The DO's SQLite engine (for direct queries, e.g. lookup functions) */
|
|
884
|
+
engine: any;
|
|
883
885
|
}
|
|
884
886
|
/** Context for beforeSave hooks */
|
|
885
887
|
interface BeforeSaveContext extends HookContext {
|
|
@@ -896,6 +898,8 @@ interface BeforeSaveContext extends HookContext {
|
|
|
896
898
|
interface BeforeDeleteContext extends HookContext {
|
|
897
899
|
/** Record ID being deleted */
|
|
898
900
|
id: string;
|
|
901
|
+
/** The existing record being deleted (parsed from data_json) */
|
|
902
|
+
record: Record<string, any> | null;
|
|
899
903
|
}
|
|
900
904
|
/** Context for beforeQuery hooks */
|
|
901
905
|
interface BeforeQueryContext extends HookContext {
|
|
@@ -904,6 +908,11 @@ interface BeforeQueryContext extends HookContext {
|
|
|
904
908
|
/** Query options (sort, limit, etc.) */
|
|
905
909
|
options?: QueryOptions;
|
|
906
910
|
}
|
|
911
|
+
/** Context for afterQuery hooks */
|
|
912
|
+
interface AfterQueryContext extends HookContext {
|
|
913
|
+
/** The query results to filter */
|
|
914
|
+
results: Record<string, any>[];
|
|
915
|
+
}
|
|
907
916
|
/** Result from beforeSave/beforeDelete hooks */
|
|
908
917
|
interface HookResult {
|
|
909
918
|
allow: boolean;
|
|
@@ -915,11 +924,17 @@ interface BeforeQueryResult extends HookResult {
|
|
|
915
924
|
/** Additional filter merged into the query via $and */
|
|
916
925
|
injectFilter?: DocumentFilter;
|
|
917
926
|
}
|
|
927
|
+
/** Result from afterQuery hooks — returns filtered results */
|
|
928
|
+
interface AfterQueryResult {
|
|
929
|
+
/** The filtered results to return */
|
|
930
|
+
results: Record<string, any>[];
|
|
931
|
+
}
|
|
918
932
|
/** Hook definitions for createDatabaseDO */
|
|
919
933
|
interface DatabaseDOHooks {
|
|
920
934
|
beforeSave?: (ctx: BeforeSaveContext) => Promise<HookResult>;
|
|
921
935
|
beforeDelete?: (ctx: BeforeDeleteContext) => Promise<HookResult>;
|
|
922
936
|
beforeQuery?: (ctx: BeforeQueryContext) => Promise<BeforeQueryResult>;
|
|
937
|
+
afterQuery?: (ctx: AfterQueryContext) => Promise<AfterQueryResult>;
|
|
923
938
|
}
|
|
924
939
|
|
|
925
940
|
/**
|
|
@@ -1151,6 +1166,8 @@ declare function createDatabaseDO(config?: DatabaseDOConfig): {
|
|
|
1151
1166
|
fetch(request: Request): Promise<Response>;
|
|
1152
1167
|
/** @internal */
|
|
1153
1168
|
_handleQuery(request: Request, docId: string): Promise<Response>;
|
|
1169
|
+
/** @internal — Check for reserved field names in record data */
|
|
1170
|
+
_checkReservedFields(data: Record<string, any>): string | null;
|
|
1154
1171
|
/** @internal */
|
|
1155
1172
|
_handleSave(request: Request, docId: string): Promise<Response>;
|
|
1156
1173
|
/** @internal — Partial update: merge provided fields into existing record */
|
|
@@ -1231,6 +1248,8 @@ declare function createDatabaseDO(config?: DatabaseDOConfig): {
|
|
|
1231
1248
|
_handleHealth(): Response;
|
|
1232
1249
|
/** @internal — Return tracked field names and types for a model */
|
|
1233
1250
|
_handleDescribe(request: Request): Response;
|
|
1251
|
+
/** @internal — List all known model names from records and _model_fields */
|
|
1252
|
+
_handleModelList(): Response;
|
|
1234
1253
|
/** @internal */
|
|
1235
1254
|
_errorResponse(message: string, status: number): Response;
|
|
1236
1255
|
/** @internal */
|
|
@@ -1300,4 +1319,4 @@ interface Env {
|
|
|
1300
1319
|
*/
|
|
1301
1320
|
declare function handleRequest(request: Request, env: Env): Promise<Response>;
|
|
1302
1321
|
|
|
1303
|
-
export { type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type CountRequest, type CountResponse, type DatabaseDOConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DocumentDOConfig, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, DurableObjectEngine, type DurableObjectEngineOptions, type DurableObjectId, type DurableObjectNamespace, type DurableObjectState, type DurableObjectStorage, type DurableObjectStub, type Env, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, JsonQueryTranslator, type JsonQueryTranslatorOptions, JsonSchemaDDL, type JsonSchemaOptions, type PatchRequest, type PatchResponse, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveRequest, type SaveResponse, type SqlStorage, type SqlStorageCursor, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, createDatabaseDO, createDocumentDO, handleRequest };
|
|
1322
|
+
export { type AfterQueryContext, type AfterQueryResult, type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type CountRequest, type CountResponse, type DatabaseDOConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DocumentDOConfig, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, DurableObjectEngine, type DurableObjectEngineOptions, type DurableObjectId, type DurableObjectNamespace, type DurableObjectState, type DurableObjectStorage, type DurableObjectStub, type Env, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, JsonQueryTranslator, type JsonQueryTranslatorOptions, JsonSchemaDDL, type JsonSchemaOptions, type PatchRequest, type PatchResponse, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveRequest, type SaveResponse, type SqlStorage, type SqlStorageCursor, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, createDatabaseDO, createDocumentDO, handleRequest };
|
package/dist/cloudflare-do.js
CHANGED
|
@@ -1948,6 +1948,7 @@ function createDatabaseDO(config = {}) {
|
|
|
1948
1948
|
if (request.method === "DELETE" && path === "/destroy") {
|
|
1949
1949
|
await this._doState.storage.deleteAll();
|
|
1950
1950
|
this._initialized = false;
|
|
1951
|
+
this._engine.initialized = false;
|
|
1951
1952
|
return Response.json({
|
|
1952
1953
|
deleted: true,
|
|
1953
1954
|
deletedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -1995,6 +1996,8 @@ function createDatabaseDO(config = {}) {
|
|
|
1995
1996
|
return this._handleHealth();
|
|
1996
1997
|
case "/describe":
|
|
1997
1998
|
return this._handleDescribe(request);
|
|
1999
|
+
case "/models":
|
|
2000
|
+
return this._handleModelList();
|
|
1998
2001
|
default:
|
|
1999
2002
|
return this._errorResponse("Not found", 404);
|
|
2000
2003
|
}
|
|
@@ -2016,6 +2019,7 @@ function createDatabaseDO(config = {}) {
|
|
|
2016
2019
|
modelName,
|
|
2017
2020
|
docId,
|
|
2018
2021
|
request,
|
|
2022
|
+
engine: this._engine,
|
|
2019
2023
|
filter,
|
|
2020
2024
|
options
|
|
2021
2025
|
};
|
|
@@ -2034,7 +2038,18 @@ function createDatabaseDO(config = {}) {
|
|
|
2034
2038
|
});
|
|
2035
2039
|
const { sql, params, sortFields } = translator.translateFind(filter, options);
|
|
2036
2040
|
const rawResults = this._engine.execSqlSync(sql, params);
|
|
2037
|
-
|
|
2041
|
+
let data = rawResults.map((row) => this._parseRow(row));
|
|
2042
|
+
if (hooks?.afterQuery) {
|
|
2043
|
+
const ctx = {
|
|
2044
|
+
modelName,
|
|
2045
|
+
docId,
|
|
2046
|
+
request,
|
|
2047
|
+
engine: this._engine,
|
|
2048
|
+
results: data
|
|
2049
|
+
};
|
|
2050
|
+
const result = await hooks.afterQuery(ctx);
|
|
2051
|
+
data = result.results;
|
|
2052
|
+
}
|
|
2038
2053
|
const limit = options?.limit;
|
|
2039
2054
|
const hasMore = CursorManager.hasMoreResults(limit, data.length);
|
|
2040
2055
|
const isFirstPage = !options?.uniqueStartKey;
|
|
@@ -2052,6 +2067,18 @@ function createDatabaseDO(config = {}) {
|
|
|
2052
2067
|
};
|
|
2053
2068
|
return Response.json(response);
|
|
2054
2069
|
}
|
|
2070
|
+
/** @internal — Check for reserved field names in record data */
|
|
2071
|
+
_checkReservedFields(data) {
|
|
2072
|
+
for (const key of Object.keys(data)) {
|
|
2073
|
+
if (key === "type") {
|
|
2074
|
+
return `Field 'type' is reserved and cannot be used in record data`;
|
|
2075
|
+
}
|
|
2076
|
+
if (key.startsWith("_meta")) {
|
|
2077
|
+
return `Field '${key}' is reserved (fields starting with '_meta' are internal) and cannot be used in record data`;
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
return null;
|
|
2081
|
+
}
|
|
2055
2082
|
/** @internal */
|
|
2056
2083
|
async _handleSave(request, docId) {
|
|
2057
2084
|
const body = await request.json();
|
|
@@ -2059,6 +2086,15 @@ function createDatabaseDO(config = {}) {
|
|
|
2059
2086
|
if (!modelName || !id) {
|
|
2060
2087
|
return this._errorResponse("modelName and id are required", 400);
|
|
2061
2088
|
}
|
|
2089
|
+
if (!data) {
|
|
2090
|
+
return this._errorResponse("data is required", 400);
|
|
2091
|
+
}
|
|
2092
|
+
if (data) {
|
|
2093
|
+
const reservedError = this._checkReservedFields(data);
|
|
2094
|
+
if (reservedError) {
|
|
2095
|
+
return this._errorResponse(reservedError, 400);
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2062
2098
|
if (condition && !this._checkCondition(modelName, id, condition)) {
|
|
2063
2099
|
return this._errorResponse(
|
|
2064
2100
|
`Condition not met for ${modelName}/${id}`,
|
|
@@ -2077,6 +2113,7 @@ function createDatabaseDO(config = {}) {
|
|
|
2077
2113
|
modelName,
|
|
2078
2114
|
docId,
|
|
2079
2115
|
request,
|
|
2116
|
+
engine: this._engine,
|
|
2080
2117
|
id,
|
|
2081
2118
|
data,
|
|
2082
2119
|
stringSets,
|
|
@@ -2115,6 +2152,10 @@ function createDatabaseDO(config = {}) {
|
|
|
2115
2152
|
if (!modelName || !id || !data) {
|
|
2116
2153
|
return this._errorResponse("modelName, id, and data are required", 400);
|
|
2117
2154
|
}
|
|
2155
|
+
const reservedError = this._checkReservedFields(data);
|
|
2156
|
+
if (reservedError) {
|
|
2157
|
+
return this._errorResponse(reservedError, 400);
|
|
2158
|
+
}
|
|
2118
2159
|
if (!this._engine.recordExists(modelName, id)) {
|
|
2119
2160
|
return this._errorResponse(`Record ${modelName}/${id} not found`, 404);
|
|
2120
2161
|
}
|
|
@@ -2129,6 +2170,7 @@ function createDatabaseDO(config = {}) {
|
|
|
2129
2170
|
modelName,
|
|
2130
2171
|
docId,
|
|
2131
2172
|
request,
|
|
2173
|
+
engine: this._engine,
|
|
2132
2174
|
id,
|
|
2133
2175
|
data,
|
|
2134
2176
|
stringSets,
|
|
@@ -2174,11 +2216,21 @@ function createDatabaseDO(config = {}) {
|
|
|
2174
2216
|
);
|
|
2175
2217
|
}
|
|
2176
2218
|
if (hooks?.beforeDelete) {
|
|
2219
|
+
let record = null;
|
|
2220
|
+
const rows = this._engine.execSqlSync(
|
|
2221
|
+
"SELECT id, type, data_json FROM records WHERE id = ? AND type = ?",
|
|
2222
|
+
[id, modelName]
|
|
2223
|
+
);
|
|
2224
|
+
if (rows.length > 0) {
|
|
2225
|
+
record = this._parseRow(rows[0]);
|
|
2226
|
+
}
|
|
2177
2227
|
const ctx = {
|
|
2178
2228
|
modelName,
|
|
2179
2229
|
docId,
|
|
2180
2230
|
request,
|
|
2181
|
-
|
|
2231
|
+
engine: this._engine,
|
|
2232
|
+
id,
|
|
2233
|
+
record
|
|
2182
2234
|
};
|
|
2183
2235
|
const result = await hooks.beforeDelete(ctx);
|
|
2184
2236
|
if (!result.allow) {
|
|
@@ -2212,12 +2264,20 @@ function createDatabaseDO(config = {}) {
|
|
|
2212
2264
|
400
|
|
2213
2265
|
);
|
|
2214
2266
|
}
|
|
2267
|
+
const reservedError = this._checkReservedFields(op.data);
|
|
2268
|
+
if (reservedError) {
|
|
2269
|
+
return this._errorResponse(
|
|
2270
|
+
`Operation ${i}: ${reservedError}`,
|
|
2271
|
+
400
|
|
2272
|
+
);
|
|
2273
|
+
}
|
|
2215
2274
|
if (hooks?.beforeSave) {
|
|
2216
2275
|
const isNew = op.op === "save" ? !this._engine.recordExists(op.modelName, op.id) : false;
|
|
2217
2276
|
const ctx = {
|
|
2218
2277
|
modelName: op.modelName,
|
|
2219
2278
|
docId,
|
|
2220
2279
|
request,
|
|
2280
|
+
engine: this._engine,
|
|
2221
2281
|
id: op.id,
|
|
2222
2282
|
data: op.data,
|
|
2223
2283
|
stringSets: op.stringSets,
|
|
@@ -2230,11 +2290,21 @@ function createDatabaseDO(config = {}) {
|
|
|
2230
2290
|
}
|
|
2231
2291
|
} else if (op.op === "delete") {
|
|
2232
2292
|
if (hooks?.beforeDelete) {
|
|
2293
|
+
let record = null;
|
|
2294
|
+
const rows = this._engine.execSqlSync(
|
|
2295
|
+
"SELECT id, type, data_json FROM records WHERE id = ? AND type = ?",
|
|
2296
|
+
[op.id, op.modelName]
|
|
2297
|
+
);
|
|
2298
|
+
if (rows.length > 0) {
|
|
2299
|
+
record = this._parseRow(rows[0]);
|
|
2300
|
+
}
|
|
2233
2301
|
const ctx = {
|
|
2234
2302
|
modelName: op.modelName,
|
|
2235
2303
|
docId,
|
|
2236
2304
|
request,
|
|
2237
|
-
|
|
2305
|
+
engine: this._engine,
|
|
2306
|
+
id: op.id,
|
|
2307
|
+
record
|
|
2238
2308
|
};
|
|
2239
2309
|
const result = await hooks.beforeDelete(ctx);
|
|
2240
2310
|
if (!result.allow) {
|
|
@@ -2459,6 +2529,7 @@ function createDatabaseDO(config = {}) {
|
|
|
2459
2529
|
modelName,
|
|
2460
2530
|
docId,
|
|
2461
2531
|
request,
|
|
2532
|
+
engine: this._engine,
|
|
2462
2533
|
filter
|
|
2463
2534
|
};
|
|
2464
2535
|
const result = await hooks.beforeQuery(ctx);
|
|
@@ -2571,6 +2642,7 @@ function createDatabaseDO(config = {}) {
|
|
|
2571
2642
|
modelName,
|
|
2572
2643
|
docId,
|
|
2573
2644
|
request,
|
|
2645
|
+
engine: this._engine,
|
|
2574
2646
|
filter
|
|
2575
2647
|
};
|
|
2576
2648
|
const result = await hooks.beforeQuery(ctx);
|
|
@@ -3056,6 +3128,23 @@ function createDatabaseDO(config = {}) {
|
|
|
3056
3128
|
const response = { modelName, fields };
|
|
3057
3129
|
return Response.json(response);
|
|
3058
3130
|
}
|
|
3131
|
+
/** @internal — List all known model names from records and _model_fields */
|
|
3132
|
+
_handleModelList() {
|
|
3133
|
+
const fromRecords = this._engine.execSqlSync(
|
|
3134
|
+
"SELECT DISTINCT type FROM records ORDER BY type"
|
|
3135
|
+
);
|
|
3136
|
+
const fromFields = this._engine.execSqlSync(
|
|
3137
|
+
"SELECT DISTINCT model_name FROM _model_fields ORDER BY model_name"
|
|
3138
|
+
);
|
|
3139
|
+
const fromIndexes = this._engine.execSqlSync(
|
|
3140
|
+
"SELECT DISTINCT model_name FROM _indexes ORDER BY model_name"
|
|
3141
|
+
);
|
|
3142
|
+
const modelSet = /* @__PURE__ */ new Set();
|
|
3143
|
+
for (const row of fromRecords) modelSet.add(row.type);
|
|
3144
|
+
for (const row of fromFields) modelSet.add(row.model_name);
|
|
3145
|
+
for (const row of fromIndexes) modelSet.add(row.model_name);
|
|
3146
|
+
return Response.json({ models: Array.from(modelSet).sort() });
|
|
3147
|
+
}
|
|
3059
3148
|
/** @internal */
|
|
3060
3149
|
_errorResponse(message, status) {
|
|
3061
3150
|
const body = { error: message };
|
package/dist/cloudflare.d.cts
CHANGED
|
@@ -608,6 +608,8 @@ interface HookContext {
|
|
|
608
608
|
docId: string;
|
|
609
609
|
/** The raw request (for reading headers, auth tokens, etc.) */
|
|
610
610
|
request: Request;
|
|
611
|
+
/** The DO's SQLite engine (for direct queries, e.g. lookup functions) */
|
|
612
|
+
engine: any;
|
|
611
613
|
}
|
|
612
614
|
/** Context for beforeSave hooks */
|
|
613
615
|
interface BeforeSaveContext extends HookContext {
|
|
@@ -624,6 +626,8 @@ interface BeforeSaveContext extends HookContext {
|
|
|
624
626
|
interface BeforeDeleteContext extends HookContext {
|
|
625
627
|
/** Record ID being deleted */
|
|
626
628
|
id: string;
|
|
629
|
+
/** The existing record being deleted (parsed from data_json) */
|
|
630
|
+
record: Record<string, any> | null;
|
|
627
631
|
}
|
|
628
632
|
/** Context for beforeQuery hooks */
|
|
629
633
|
interface BeforeQueryContext extends HookContext {
|
|
@@ -632,6 +636,11 @@ interface BeforeQueryContext extends HookContext {
|
|
|
632
636
|
/** Query options (sort, limit, etc.) */
|
|
633
637
|
options?: QueryOptions;
|
|
634
638
|
}
|
|
639
|
+
/** Context for afterQuery hooks */
|
|
640
|
+
interface AfterQueryContext extends HookContext {
|
|
641
|
+
/** The query results to filter */
|
|
642
|
+
results: Record<string, any>[];
|
|
643
|
+
}
|
|
635
644
|
/** Result from beforeSave/beforeDelete hooks */
|
|
636
645
|
interface HookResult {
|
|
637
646
|
allow: boolean;
|
|
@@ -643,11 +652,17 @@ interface BeforeQueryResult extends HookResult {
|
|
|
643
652
|
/** Additional filter merged into the query via $and */
|
|
644
653
|
injectFilter?: DocumentFilter;
|
|
645
654
|
}
|
|
655
|
+
/** Result from afterQuery hooks — returns filtered results */
|
|
656
|
+
interface AfterQueryResult {
|
|
657
|
+
/** The filtered results to return */
|
|
658
|
+
results: Record<string, any>[];
|
|
659
|
+
}
|
|
646
660
|
/** Hook definitions for createDatabaseDO */
|
|
647
661
|
interface DatabaseDOHooks {
|
|
648
662
|
beforeSave?: (ctx: BeforeSaveContext) => Promise<HookResult>;
|
|
649
663
|
beforeDelete?: (ctx: BeforeDeleteContext) => Promise<HookResult>;
|
|
650
664
|
beforeQuery?: (ctx: BeforeQueryContext) => Promise<BeforeQueryResult>;
|
|
665
|
+
afterQuery?: (ctx: AfterQueryContext) => Promise<AfterQueryResult>;
|
|
651
666
|
}
|
|
652
667
|
|
|
653
668
|
/**
|
|
@@ -1346,4 +1361,4 @@ interface DoDb {
|
|
|
1346
1361
|
*/
|
|
1347
1362
|
declare function connectDoDb(options: ConnectDoDbOptions): DoDb;
|
|
1348
1363
|
|
|
1349
|
-
export { type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type ConnectDoDbOptions, type CountRequest, type CountResponse, DOClientEngine, type DOClientEngineConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DoDb, type DocumentFilter, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, type InitJsBaoDOOptions, type InitJsBaoDOResult, type ModelAccessor, type PaginatedResult, type PatchOptions, type PatchRequest, type PatchResponse, type ProjectionSpec, type QueryOptions, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveOptions, type SaveRequest, type SaveResponse, type SortSpec, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, type WriteCondition, connectDoDb, getActiveDOEngine, initJsBaoDO, resetJsBaoDO };
|
|
1364
|
+
export { type AfterQueryContext, type AfterQueryResult, type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type ConnectDoDbOptions, type CountRequest, type CountResponse, DOClientEngine, type DOClientEngineConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DoDb, type DocumentFilter, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, type InitJsBaoDOOptions, type InitJsBaoDOResult, type ModelAccessor, type PaginatedResult, type PatchOptions, type PatchRequest, type PatchResponse, type ProjectionSpec, type QueryOptions, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveOptions, type SaveRequest, type SaveResponse, type SortSpec, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, type WriteCondition, connectDoDb, getActiveDOEngine, initJsBaoDO, resetJsBaoDO };
|
package/dist/cloudflare.d.ts
CHANGED
|
@@ -608,6 +608,8 @@ interface HookContext {
|
|
|
608
608
|
docId: string;
|
|
609
609
|
/** The raw request (for reading headers, auth tokens, etc.) */
|
|
610
610
|
request: Request;
|
|
611
|
+
/** The DO's SQLite engine (for direct queries, e.g. lookup functions) */
|
|
612
|
+
engine: any;
|
|
611
613
|
}
|
|
612
614
|
/** Context for beforeSave hooks */
|
|
613
615
|
interface BeforeSaveContext extends HookContext {
|
|
@@ -624,6 +626,8 @@ interface BeforeSaveContext extends HookContext {
|
|
|
624
626
|
interface BeforeDeleteContext extends HookContext {
|
|
625
627
|
/** Record ID being deleted */
|
|
626
628
|
id: string;
|
|
629
|
+
/** The existing record being deleted (parsed from data_json) */
|
|
630
|
+
record: Record<string, any> | null;
|
|
627
631
|
}
|
|
628
632
|
/** Context for beforeQuery hooks */
|
|
629
633
|
interface BeforeQueryContext extends HookContext {
|
|
@@ -632,6 +636,11 @@ interface BeforeQueryContext extends HookContext {
|
|
|
632
636
|
/** Query options (sort, limit, etc.) */
|
|
633
637
|
options?: QueryOptions;
|
|
634
638
|
}
|
|
639
|
+
/** Context for afterQuery hooks */
|
|
640
|
+
interface AfterQueryContext extends HookContext {
|
|
641
|
+
/** The query results to filter */
|
|
642
|
+
results: Record<string, any>[];
|
|
643
|
+
}
|
|
635
644
|
/** Result from beforeSave/beforeDelete hooks */
|
|
636
645
|
interface HookResult {
|
|
637
646
|
allow: boolean;
|
|
@@ -643,11 +652,17 @@ interface BeforeQueryResult extends HookResult {
|
|
|
643
652
|
/** Additional filter merged into the query via $and */
|
|
644
653
|
injectFilter?: DocumentFilter;
|
|
645
654
|
}
|
|
655
|
+
/** Result from afterQuery hooks — returns filtered results */
|
|
656
|
+
interface AfterQueryResult {
|
|
657
|
+
/** The filtered results to return */
|
|
658
|
+
results: Record<string, any>[];
|
|
659
|
+
}
|
|
646
660
|
/** Hook definitions for createDatabaseDO */
|
|
647
661
|
interface DatabaseDOHooks {
|
|
648
662
|
beforeSave?: (ctx: BeforeSaveContext) => Promise<HookResult>;
|
|
649
663
|
beforeDelete?: (ctx: BeforeDeleteContext) => Promise<HookResult>;
|
|
650
664
|
beforeQuery?: (ctx: BeforeQueryContext) => Promise<BeforeQueryResult>;
|
|
665
|
+
afterQuery?: (ctx: AfterQueryContext) => Promise<AfterQueryResult>;
|
|
651
666
|
}
|
|
652
667
|
|
|
653
668
|
/**
|
|
@@ -1346,4 +1361,4 @@ interface DoDb {
|
|
|
1346
1361
|
*/
|
|
1347
1362
|
declare function connectDoDb(options: ConnectDoDbOptions): DoDb;
|
|
1348
1363
|
|
|
1349
|
-
export { type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type ConnectDoDbOptions, type CountRequest, type CountResponse, DOClientEngine, type DOClientEngineConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DoDb, type DocumentFilter, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, type InitJsBaoDOOptions, type InitJsBaoDOResult, type ModelAccessor, type PaginatedResult, type PatchOptions, type PatchRequest, type PatchResponse, type ProjectionSpec, type QueryOptions, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveOptions, type SaveRequest, type SaveResponse, type SortSpec, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, type WriteCondition, connectDoDb, getActiveDOEngine, initJsBaoDO, resetJsBaoDO };
|
|
1364
|
+
export { type AfterQueryContext, type AfterQueryResult, type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type ConnectDoDbOptions, type CountRequest, type CountResponse, DOClientEngine, type DOClientEngineConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DoDb, type DocumentFilter, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, type InitJsBaoDOOptions, type InitJsBaoDOResult, type ModelAccessor, type PaginatedResult, type PatchOptions, type PatchRequest, type PatchResponse, type ProjectionSpec, type QueryOptions, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveOptions, type SaveRequest, type SaveResponse, type SortSpec, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, type WriteCondition, connectDoDb, getActiveDOEngine, initJsBaoDO, resetJsBaoDO };
|
package/dist/codegen.cjs
CHANGED
|
@@ -1189,7 +1189,7 @@ var SchemaExtractor = class {
|
|
|
1189
1189
|
// package.json
|
|
1190
1190
|
var package_default = {
|
|
1191
1191
|
name: "js-bao",
|
|
1192
|
-
version: "0.3.0-alpha.
|
|
1192
|
+
version: "0.3.0-alpha.2",
|
|
1193
1193
|
description: "A library providing data modeling capabilities which support live updates and queries.",
|
|
1194
1194
|
types: "dist/index.d.ts",
|
|
1195
1195
|
type: "module",
|
|
@@ -1273,7 +1273,7 @@ var package_default = {
|
|
|
1273
1273
|
ulid: "^3.0.0"
|
|
1274
1274
|
},
|
|
1275
1275
|
devDependencies: {
|
|
1276
|
-
"@types/better-sqlite3": "^7.6.
|
|
1276
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
1277
1277
|
"@types/node": "^20.17.51",
|
|
1278
1278
|
"@types/sql.js": "^1.4.9",
|
|
1279
1279
|
commander: "^11.0.0",
|
|
@@ -1287,7 +1287,7 @@ var package_default = {
|
|
|
1287
1287
|
yjs: "^13.6.18"
|
|
1288
1288
|
},
|
|
1289
1289
|
optionalDependencies: {
|
|
1290
|
-
"better-sqlite3": "^
|
|
1290
|
+
"better-sqlite3": "^12.6.2"
|
|
1291
1291
|
},
|
|
1292
1292
|
keywords: [
|
|
1293
1293
|
"yjs",
|
package/dist/index.cjs
CHANGED
|
@@ -6250,12 +6250,16 @@ async function resetJsBao() {
|
|
|
6250
6250
|
ormInitializationPromise = null;
|
|
6251
6251
|
const { BaseModel: BaseModel3 } = await Promise.resolve().then(() => (init_BaseModel(), BaseModel_exports));
|
|
6252
6252
|
BaseModel3.dbInstance = null;
|
|
6253
|
-
|
|
6253
|
+
BaseModel3.connectedDocuments = /* @__PURE__ */ new Map();
|
|
6254
|
+
BaseModel3.documentYMaps = /* @__PURE__ */ new Map();
|
|
6255
|
+
BaseModel3.clearModelDefaultDocumentIds();
|
|
6256
|
+
BaseModel3.clearGlobalDefaultDocumentId();
|
|
6257
|
+
Logger.debug("[resetJsBao] BaseModel database instance and document state cleared.");
|
|
6254
6258
|
const modelRegistryInstance = ModelRegistry.getInstance();
|
|
6255
6259
|
modelRegistryInstance.clearSessionState();
|
|
6256
6260
|
Logger.debug("[resetJsBao] ModelRegistry session state cleared.");
|
|
6257
6261
|
Logger.info(
|
|
6258
|
-
"[resetJsBao] js-bao
|
|
6262
|
+
"[resetJsBao] js-bao state fully reset. DB engine destroyed. Document mappings cleared. ModelRegistry session cleared."
|
|
6259
6263
|
);
|
|
6260
6264
|
}
|
|
6261
6265
|
|
package/dist/index.js
CHANGED
|
@@ -6200,12 +6200,16 @@ async function resetJsBao() {
|
|
|
6200
6200
|
ormInitializationPromise = null;
|
|
6201
6201
|
const { BaseModel: BaseModel3 } = await Promise.resolve().then(() => (init_BaseModel(), BaseModel_exports));
|
|
6202
6202
|
BaseModel3.dbInstance = null;
|
|
6203
|
-
|
|
6203
|
+
BaseModel3.connectedDocuments = /* @__PURE__ */ new Map();
|
|
6204
|
+
BaseModel3.documentYMaps = /* @__PURE__ */ new Map();
|
|
6205
|
+
BaseModel3.clearModelDefaultDocumentIds();
|
|
6206
|
+
BaseModel3.clearGlobalDefaultDocumentId();
|
|
6207
|
+
Logger.debug("[resetJsBao] BaseModel database instance and document state cleared.");
|
|
6204
6208
|
const modelRegistryInstance = ModelRegistry.getInstance();
|
|
6205
6209
|
modelRegistryInstance.clearSessionState();
|
|
6206
6210
|
Logger.debug("[resetJsBao] ModelRegistry session state cleared.");
|
|
6207
6211
|
Logger.info(
|
|
6208
|
-
"[resetJsBao] js-bao
|
|
6212
|
+
"[resetJsBao] js-bao state fully reset. DB engine destroyed. Document mappings cleared. ModelRegistry session cleared."
|
|
6209
6213
|
);
|
|
6210
6214
|
}
|
|
6211
6215
|
|
package/dist/node.cjs
CHANGED
|
@@ -6435,12 +6435,16 @@ async function resetJsBao() {
|
|
|
6435
6435
|
ormInitializationPromise = null;
|
|
6436
6436
|
const { BaseModel: BaseModel3 } = await Promise.resolve().then(() => (init_BaseModel(), BaseModel_exports));
|
|
6437
6437
|
BaseModel3.dbInstance = null;
|
|
6438
|
-
|
|
6438
|
+
BaseModel3.connectedDocuments = /* @__PURE__ */ new Map();
|
|
6439
|
+
BaseModel3.documentYMaps = /* @__PURE__ */ new Map();
|
|
6440
|
+
BaseModel3.clearModelDefaultDocumentIds();
|
|
6441
|
+
BaseModel3.clearGlobalDefaultDocumentId();
|
|
6442
|
+
Logger.debug("[resetJsBao] BaseModel database instance and document state cleared.");
|
|
6439
6443
|
const modelRegistryInstance = ModelRegistry.getInstance();
|
|
6440
6444
|
modelRegistryInstance.clearSessionState();
|
|
6441
6445
|
Logger.debug("[resetJsBao] ModelRegistry session state cleared.");
|
|
6442
6446
|
Logger.info(
|
|
6443
|
-
"[resetJsBao] js-bao
|
|
6447
|
+
"[resetJsBao] js-bao state fully reset. DB engine destroyed. Document mappings cleared. ModelRegistry session cleared."
|
|
6444
6448
|
);
|
|
6445
6449
|
}
|
|
6446
6450
|
|
package/dist/node.js
CHANGED
|
@@ -6382,12 +6382,16 @@ async function resetJsBao() {
|
|
|
6382
6382
|
ormInitializationPromise = null;
|
|
6383
6383
|
const { BaseModel: BaseModel3 } = await Promise.resolve().then(() => (init_BaseModel(), BaseModel_exports));
|
|
6384
6384
|
BaseModel3.dbInstance = null;
|
|
6385
|
-
|
|
6385
|
+
BaseModel3.connectedDocuments = /* @__PURE__ */ new Map();
|
|
6386
|
+
BaseModel3.documentYMaps = /* @__PURE__ */ new Map();
|
|
6387
|
+
BaseModel3.clearModelDefaultDocumentIds();
|
|
6388
|
+
BaseModel3.clearGlobalDefaultDocumentId();
|
|
6389
|
+
Logger.debug("[resetJsBao] BaseModel database instance and document state cleared.");
|
|
6386
6390
|
const modelRegistryInstance = ModelRegistry.getInstance();
|
|
6387
6391
|
modelRegistryInstance.clearSessionState();
|
|
6388
6392
|
Logger.debug("[resetJsBao] ModelRegistry session state cleared.");
|
|
6389
6393
|
Logger.info(
|
|
6390
|
-
"[resetJsBao] js-bao
|
|
6394
|
+
"[resetJsBao] js-bao state fully reset. DB engine destroyed. Document mappings cleared. ModelRegistry session cleared."
|
|
6391
6395
|
);
|
|
6392
6396
|
}
|
|
6393
6397
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "js-bao",
|
|
3
|
-
"version": "0.3.0-alpha.
|
|
3
|
+
"version": "0.3.0-alpha.2",
|
|
4
4
|
"description": "A library providing data modeling capabilities which support live updates and queries.",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"ulid": "^3.0.0"
|
|
85
85
|
},
|
|
86
86
|
"devDependencies": {
|
|
87
|
-
"@types/better-sqlite3": "^7.6.
|
|
87
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
88
88
|
"@types/node": "^20.17.51",
|
|
89
89
|
"@types/sql.js": "^1.4.9",
|
|
90
90
|
"commander": "^11.0.0",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"yjs": "^13.6.18"
|
|
99
99
|
},
|
|
100
100
|
"optionalDependencies": {
|
|
101
|
-
"better-sqlite3": "^
|
|
101
|
+
"better-sqlite3": "^12.6.2"
|
|
102
102
|
},
|
|
103
103
|
"keywords": [
|
|
104
104
|
"yjs",
|