js-bao 0.3.1 → 0.4.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/dist/browser.cjs +91 -158
- package/dist/browser.d.cts +22 -6
- package/dist/browser.d.ts +22 -6
- package/dist/browser.js +89 -156
- package/dist/client.d.cts +7 -0
- package/dist/client.d.ts +7 -0
- package/dist/cloudflare-do.cjs +70 -5
- package/dist/cloudflare-do.d.cts +22 -3
- package/dist/cloudflare-do.d.ts +22 -3
- package/dist/cloudflare-do.js +70 -5
- package/dist/cloudflare.cjs +70 -5
- package/dist/cloudflare.d.cts +20 -1
- package/dist/cloudflare.d.ts +20 -1
- package/dist/cloudflare.js +70 -5
- package/dist/codegen-v2.cjs +1766 -0
- package/dist/codegen-v2.d.cts +1 -0
- package/dist/codegen.cjs +8 -19
- package/dist/index.cjs +91 -162
- package/dist/index.d.cts +23 -7
- package/dist/index.d.ts +23 -7
- package/dist/index.js +91 -160
- package/dist/node.cjs +94 -163
- package/dist/node.d.cts +23 -7
- package/dist/node.d.ts +23 -7
- package/dist/node.js +91 -158
- package/package.json +7 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/codegen.cjs
CHANGED
|
@@ -312,7 +312,7 @@ var ModelAnalyzer = class {
|
|
|
312
312
|
return {};
|
|
313
313
|
}
|
|
314
314
|
/**
|
|
315
|
-
* Parse relationships object from
|
|
315
|
+
* Parse relationships object from a model schema definition
|
|
316
316
|
*/
|
|
317
317
|
parseRelationships(obj) {
|
|
318
318
|
const relationships = {};
|
|
@@ -461,14 +461,6 @@ var ModelAnalyzer = class {
|
|
|
461
461
|
type: this.getTypeString(member.type),
|
|
462
462
|
isOptional: !!member.questionToken
|
|
463
463
|
};
|
|
464
|
-
const memberDecorators = ts.getDecorators?.(member) || member.decorators;
|
|
465
|
-
if (memberDecorators) {
|
|
466
|
-
for (const decorator of memberDecorators) {
|
|
467
|
-
if (ts.isCallExpression(decorator.expression) && ts.isIdentifier(decorator.expression.expression) && decorator.expression.expression.text === "Field") {
|
|
468
|
-
field.decoratorOptions = {};
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
464
|
fields[fieldName] = field;
|
|
473
465
|
}
|
|
474
466
|
}
|
|
@@ -1189,7 +1181,7 @@ var SchemaExtractor = class {
|
|
|
1189
1181
|
// package.json
|
|
1190
1182
|
var package_default = {
|
|
1191
1183
|
name: "js-bao",
|
|
1192
|
-
version: "0.
|
|
1184
|
+
version: "0.4.1",
|
|
1193
1185
|
description: "A library providing data modeling capabilities which support live updates and queries.",
|
|
1194
1186
|
types: "dist/index.d.ts",
|
|
1195
1187
|
type: "module",
|
|
@@ -1240,10 +1232,12 @@ var package_default = {
|
|
|
1240
1232
|
},
|
|
1241
1233
|
bin: {
|
|
1242
1234
|
"js-bao-codegen": "./dist/codegen.cjs",
|
|
1243
|
-
"jsbao-codegen": "./dist/codegen.cjs"
|
|
1235
|
+
"jsbao-codegen": "./dist/codegen.cjs",
|
|
1236
|
+
"js-bao-codegen-v2": "./dist/codegen-v2.cjs",
|
|
1237
|
+
"jsbao-codegen-v2": "./dist/codegen-v2.cjs"
|
|
1244
1238
|
},
|
|
1245
1239
|
scripts: {
|
|
1246
|
-
build: "pnpm build:cli && pnpm codegen && rm -f dist/index.* dist/node.* dist/browser.* dist/cloudflare.* dist/cloudflare-do.* dist/client.* && pnpm build:main",
|
|
1240
|
+
build: "pnpm build:cli && pnpm build:cli-v2 && pnpm codegen && rm -f dist/index.* dist/node.* dist/browser.* dist/cloudflare.* dist/cloudflare-do.* dist/client.* && pnpm build:main",
|
|
1247
1241
|
"build:main": "pnpm build:browser && pnpm build:node && pnpm build:universal && pnpm build:cloudflare && pnpm build:cloudflare-do && pnpm build:client",
|
|
1248
1242
|
"build:browser": "tsup src/browser.ts --format esm,cjs --dts --platform browser --external better-sqlite3 --external sql.js --external async-mutex --external ulid --external yjs --external fs --no-splitting",
|
|
1249
1243
|
"build:node": "tsup src/node.ts --format esm,cjs --dts --platform node --external better-sqlite3 --external sql.js --external async-mutex --external ulid --external yjs --no-splitting",
|
|
@@ -1252,6 +1246,7 @@ var package_default = {
|
|
|
1252
1246
|
"build:cloudflare-do": "tsup src/cloudflare-do.ts --format esm,cjs --dts --platform neutral --external better-sqlite3 --external sql.js --external async-mutex --external ulid --external yjs --external fs --no-splitting",
|
|
1253
1247
|
"build:client": "tsup src/client.ts --format esm,cjs --dts --platform browser --external better-sqlite3 --external sql.js --external async-mutex --external ulid --external yjs --external fs --no-splitting",
|
|
1254
1248
|
"build:cli": "tsup src/cli/codegen.ts --format cjs --dts --platform node --target node18 --external commander --external typescript --external fs --external path --external util --no-splitting",
|
|
1249
|
+
"build:cli-v2": "tsup src/cli/codegen-v2.ts --format cjs --dts --platform node --target node18 --external commander --external typescript --external fs --external path --external util --no-splitting",
|
|
1255
1250
|
dev: 'pnpm build:cli && concurrently "pnpm codegen:watch" "pnpm dev:main"',
|
|
1256
1251
|
"dev:main": 'concurrently "pnpm build:browser:dev --watch" "pnpm build:node:dev --watch" "pnpm build:universal:dev --watch"',
|
|
1257
1252
|
"dev:simple": "pnpm build:cli && pnpm codegen && pnpm build:main --watch",
|
|
@@ -1305,13 +1300,7 @@ var package_default = {
|
|
|
1305
1300
|
"workers"
|
|
1306
1301
|
],
|
|
1307
1302
|
author: "Primitive LLC",
|
|
1308
|
-
license: "UNLICENSED"
|
|
1309
|
-
pnpm: {
|
|
1310
|
-
onlyBuiltDependencies: [
|
|
1311
|
-
"better-sqlite3",
|
|
1312
|
-
"esbuild"
|
|
1313
|
-
]
|
|
1314
|
-
}
|
|
1303
|
+
license: "UNLICENSED"
|
|
1315
1304
|
};
|
|
1316
1305
|
|
|
1317
1306
|
// src/cli/codegen.ts
|
package/dist/index.cjs
CHANGED
|
@@ -1877,7 +1877,7 @@ var init_BaseModel = __esm({
|
|
|
1877
1877
|
getDocumentId() {
|
|
1878
1878
|
return this._metaDocId;
|
|
1879
1879
|
}
|
|
1880
|
-
// id is
|
|
1880
|
+
// id is a plain property. Subclasses define it via defineModelSchema.
|
|
1881
1881
|
id;
|
|
1882
1882
|
type;
|
|
1883
1883
|
// This should be the modelName from ModelOptions
|
|
@@ -2424,7 +2424,7 @@ var init_BaseModel = __esm({
|
|
|
2424
2424
|
const verboseEnabled = Logger.getLogLevel() >= 5 /* VERBOSE */;
|
|
2425
2425
|
if (!schema || !schema.options || !schema.options.name || !schema.resolvedUniqueConstraints) {
|
|
2426
2426
|
throw new Error(
|
|
2427
|
-
`[${this.name}] Model schema is not registered, missing options, or missing resolvedUniqueConstraints. Did you forget to
|
|
2427
|
+
`[${this.name}] Model schema is not registered, missing options, or missing resolvedUniqueConstraints. Did you forget to call attachAndRegisterModel (or autoRegisterModel) for this model?`
|
|
2428
2428
|
);
|
|
2429
2429
|
}
|
|
2430
2430
|
const modelName = schema.options.name;
|
|
@@ -5132,11 +5132,11 @@ var init_ModelRegistry = __esm({
|
|
|
5132
5132
|
init_relationshipManager();
|
|
5133
5133
|
ModelRegistry = class _ModelRegistry {
|
|
5134
5134
|
static instance;
|
|
5135
|
-
// Stores globally registered model classes by their name
|
|
5135
|
+
// Stores globally registered model classes by their name
|
|
5136
5136
|
models = /* @__PURE__ */ new Map();
|
|
5137
|
-
// Stores options for globally registered models
|
|
5137
|
+
// Stores options for globally registered models
|
|
5138
5138
|
modelOptions = /* @__PURE__ */ new Map();
|
|
5139
|
-
// Stores fields for globally registered models (
|
|
5139
|
+
// Stores fields for globally registered models (or a static getter on class)
|
|
5140
5140
|
// For simplicity, let's assume fields can be derived or are less critical for this registry part
|
|
5141
5141
|
// private modelFields: Map<string, Map<string, FieldOptions>> = new Map();
|
|
5142
5142
|
// Holds the subset of models explicitly set for the current initialization session
|
|
@@ -5154,7 +5154,7 @@ var init_ModelRegistry = __esm({
|
|
|
5154
5154
|
registerModel(modelClass, options, fields) {
|
|
5155
5155
|
if (!options.name) {
|
|
5156
5156
|
throw new Error(
|
|
5157
|
-
`[ModelRegistry] Model class is missing a name in its
|
|
5157
|
+
`[ModelRegistry] Model class is missing a name in its options. Ensure the schema passed to defineModelSchema/createModelClass/attachAndRegisterModel includes a 'name' property.`
|
|
5158
5158
|
);
|
|
5159
5159
|
}
|
|
5160
5160
|
if (this.models.has(options.name)) {
|
|
@@ -5198,7 +5198,7 @@ var init_ModelRegistry = __esm({
|
|
|
5198
5198
|
}
|
|
5199
5199
|
return infos;
|
|
5200
5200
|
}
|
|
5201
|
-
// Helper to get model name from class (
|
|
5201
|
+
// Helper to get model name from class (set by attachAndRegisterModel/createModelClass)
|
|
5202
5202
|
getModelNameFromClass(modelClass) {
|
|
5203
5203
|
return modelClass.modelName;
|
|
5204
5204
|
}
|
|
@@ -5209,13 +5209,13 @@ var init_ModelRegistry = __esm({
|
|
|
5209
5209
|
const modelName = this.getModelNameFromClass(modelClass);
|
|
5210
5210
|
if (!modelName) {
|
|
5211
5211
|
console.warn(
|
|
5212
|
-
`[ModelRegistry] A model class provided to setExplicitModelsForSession does not have a static 'modelName' property or it's undefined. It will be ignored. Ensure
|
|
5212
|
+
`[ModelRegistry] A model class provided to setExplicitModelsForSession does not have a static 'modelName' property or it's undefined. It will be ignored. Ensure attachAndRegisterModel (or createModelClass) was called for this model.`
|
|
5213
5213
|
);
|
|
5214
5214
|
return;
|
|
5215
5215
|
}
|
|
5216
5216
|
if (!this.models.has(modelName) || this.models.get(modelName) !== modelClass) {
|
|
5217
5217
|
console.warn(
|
|
5218
|
-
`[ModelRegistry] Model class with name ${modelName} provided to setExplicitModelsForSession was not found in the global
|
|
5218
|
+
`[ModelRegistry] Model class with name ${modelName} provided to setExplicitModelsForSession was not found in the global registry or does not match. It will be ignored. Ensure the model file is imported and attachAndRegisterModel (or createModelClass) has run.`
|
|
5219
5219
|
);
|
|
5220
5220
|
return;
|
|
5221
5221
|
}
|
|
@@ -5245,7 +5245,7 @@ var init_ModelRegistry = __esm({
|
|
|
5245
5245
|
} else {
|
|
5246
5246
|
this.activeSessionModels = null;
|
|
5247
5247
|
console.log(
|
|
5248
|
-
"[ModelRegistry] No explicit models specified for session (undefined), will use all
|
|
5248
|
+
"[ModelRegistry] No explicit models specified for session (undefined), will use all globally registered models."
|
|
5249
5249
|
);
|
|
5250
5250
|
}
|
|
5251
5251
|
this.validateSessionModels();
|
|
@@ -5256,7 +5256,7 @@ var init_ModelRegistry = __esm({
|
|
|
5256
5256
|
const modelsToInitialize = this.activeSessionModels || this.models;
|
|
5257
5257
|
if (modelsToInitialize.size === 0) {
|
|
5258
5258
|
console.warn(
|
|
5259
|
-
"[ModelRegistry] No models to initialize (either no explicit models set for session or no models globally registered via
|
|
5259
|
+
"[ModelRegistry] No models to initialize (either no explicit models set for session or no models globally registered via attachAndRegisterModel)."
|
|
5260
5260
|
);
|
|
5261
5261
|
return;
|
|
5262
5262
|
}
|
|
@@ -5287,7 +5287,7 @@ var init_ModelRegistry = __esm({
|
|
|
5287
5287
|
const modelsToInitialize = this.activeSessionModels || this.models;
|
|
5288
5288
|
if (modelsToInitialize.size === 0) {
|
|
5289
5289
|
Logger.warn(
|
|
5290
|
-
"[ModelRegistry] No models to initialize for document (either no explicit models set for session or no models globally registered via
|
|
5290
|
+
"[ModelRegistry] No models to initialize for document (either no explicit models set for session or no models globally registered via attachAndRegisterModel)."
|
|
5291
5291
|
);
|
|
5292
5292
|
return;
|
|
5293
5293
|
}
|
|
@@ -5325,7 +5325,7 @@ var init_ModelRegistry = __esm({
|
|
|
5325
5325
|
const modelsToCleanup = this.activeSessionModels || this.models;
|
|
5326
5326
|
if (modelsToCleanup.size === 0) {
|
|
5327
5327
|
console.warn(
|
|
5328
|
-
"[ModelRegistry] No models to cleanup for document (either no explicit models set for session or no models globally registered via
|
|
5328
|
+
"[ModelRegistry] No models to cleanup for document (either no explicit models set for session or no models globally registered via attachAndRegisterModel)."
|
|
5329
5329
|
);
|
|
5330
5330
|
return;
|
|
5331
5331
|
}
|
|
@@ -6649,10 +6649,8 @@ __export(index_exports, {
|
|
|
6649
6649
|
DatabaseEngine: () => DatabaseEngine,
|
|
6650
6650
|
DocumentClosedError: () => DocumentClosedError,
|
|
6651
6651
|
DocumentResolutionError: () => DocumentResolutionError,
|
|
6652
|
-
Field: () => Field,
|
|
6653
6652
|
LogLevel: () => LogLevel,
|
|
6654
6653
|
Logger: () => Logger,
|
|
6655
|
-
Model: () => Model,
|
|
6656
6654
|
ModelRegistry: () => ModelRegistry,
|
|
6657
6655
|
RecordNotFoundError: () => RecordNotFoundError,
|
|
6658
6656
|
StringSet: () => StringSet,
|
|
@@ -6894,133 +6892,6 @@ async function resetJsBao() {
|
|
|
6894
6892
|
// src/index.ts
|
|
6895
6893
|
init_documentTypes();
|
|
6896
6894
|
init_BaseModel();
|
|
6897
|
-
|
|
6898
|
-
// src/models/decorators.ts
|
|
6899
|
-
init_ModelRegistry();
|
|
6900
|
-
init_BaseModel();
|
|
6901
|
-
init_sql();
|
|
6902
|
-
var SCHEMA_FIELDS_PROPERTY = "_jsbaoSchemaFields";
|
|
6903
|
-
function Field(options) {
|
|
6904
|
-
return function(target, propertyKey) {
|
|
6905
|
-
const fieldName = String(propertyKey);
|
|
6906
|
-
const modelConstructor = target.constructor || target;
|
|
6907
|
-
assertValidIdentifier(
|
|
6908
|
-
fieldName,
|
|
6909
|
-
`[Field Decorator] Invalid field name on ${modelConstructor?.name || "unknown"}`
|
|
6910
|
-
);
|
|
6911
|
-
if (!modelConstructor) {
|
|
6912
|
-
console.error(
|
|
6913
|
-
"[Field Decorator] Could not determine model constructor for field:",
|
|
6914
|
-
fieldName,
|
|
6915
|
-
"Target:",
|
|
6916
|
-
target
|
|
6917
|
-
);
|
|
6918
|
-
throw new Error(
|
|
6919
|
-
`Failed to resolve model constructor for field '${fieldName}'.`
|
|
6920
|
-
);
|
|
6921
|
-
}
|
|
6922
|
-
if (!Object.prototype.hasOwnProperty.call(
|
|
6923
|
-
modelConstructor,
|
|
6924
|
-
SCHEMA_FIELDS_PROPERTY
|
|
6925
|
-
)) {
|
|
6926
|
-
modelConstructor[SCHEMA_FIELDS_PROPERTY] = /* @__PURE__ */ new Map();
|
|
6927
|
-
}
|
|
6928
|
-
modelConstructor[SCHEMA_FIELDS_PROPERTY].set(
|
|
6929
|
-
fieldName,
|
|
6930
|
-
options
|
|
6931
|
-
);
|
|
6932
|
-
Logger.debug(
|
|
6933
|
-
`[Field Decorator] Staged field "${fieldName}" for class ${modelConstructor.name}:`,
|
|
6934
|
-
options
|
|
6935
|
-
);
|
|
6936
|
-
};
|
|
6937
|
-
}
|
|
6938
|
-
function Model(options) {
|
|
6939
|
-
return function(targetClass) {
|
|
6940
|
-
Logger.debug(
|
|
6941
|
-
`[Model Decorator] Registering model:`,
|
|
6942
|
-
targetClass.name,
|
|
6943
|
-
options
|
|
6944
|
-
);
|
|
6945
|
-
assertValidIdentifier(
|
|
6946
|
-
options.name,
|
|
6947
|
-
`[Model Decorator] Invalid model name for ${targetClass.name}`
|
|
6948
|
-
);
|
|
6949
|
-
const registry = ModelRegistry.getInstance();
|
|
6950
|
-
targetClass.modelName = options.name;
|
|
6951
|
-
targetClass.getSchema = () => {
|
|
6952
|
-
const combinedFields = /* @__PURE__ */ new Map();
|
|
6953
|
-
const hierarchyStack = [];
|
|
6954
|
-
let currentEvalClass = targetClass;
|
|
6955
|
-
while (currentEvalClass && currentEvalClass.prototype) {
|
|
6956
|
-
hierarchyStack.push(currentEvalClass);
|
|
6957
|
-
const parentPrototype = Object.getPrototypeOf(
|
|
6958
|
-
currentEvalClass.prototype
|
|
6959
|
-
);
|
|
6960
|
-
currentEvalClass = parentPrototype ? parentPrototype.constructor : null;
|
|
6961
|
-
if (currentEvalClass === Object) break;
|
|
6962
|
-
}
|
|
6963
|
-
for (let i = hierarchyStack.length - 1; i >= 0; i--) {
|
|
6964
|
-
const cls = hierarchyStack[i];
|
|
6965
|
-
if (Object.prototype.hasOwnProperty.call(cls, SCHEMA_FIELDS_PROPERTY)) {
|
|
6966
|
-
const fieldsForClass = cls[SCHEMA_FIELDS_PROPERTY];
|
|
6967
|
-
fieldsForClass.forEach((fieldOpts, fieldName) => {
|
|
6968
|
-
combinedFields.set(fieldName, fieldOpts);
|
|
6969
|
-
});
|
|
6970
|
-
}
|
|
6971
|
-
}
|
|
6972
|
-
const resolvedUniqueConstraints = [];
|
|
6973
|
-
combinedFields.forEach((fieldOpts, fieldName) => {
|
|
6974
|
-
if (fieldOpts.unique) {
|
|
6975
|
-
const constraintName = `${options.name}_${fieldName}_unique`;
|
|
6976
|
-
resolvedUniqueConstraints.push({
|
|
6977
|
-
name: constraintName,
|
|
6978
|
-
fields: [fieldName]
|
|
6979
|
-
});
|
|
6980
|
-
}
|
|
6981
|
-
});
|
|
6982
|
-
if (options.uniqueConstraints) {
|
|
6983
|
-
options.uniqueConstraints.forEach(
|
|
6984
|
-
(constraintConfig) => {
|
|
6985
|
-
const allFieldsExist = constraintConfig.fields.every(
|
|
6986
|
-
(f) => combinedFields.has(f)
|
|
6987
|
-
);
|
|
6988
|
-
if (!allFieldsExist) {
|
|
6989
|
-
console.warn(
|
|
6990
|
-
`[Model Decorator] Unique constraint "${constraintConfig.name}" for model "${options.name}" specifies non-existent fields. Skipping.`
|
|
6991
|
-
);
|
|
6992
|
-
return;
|
|
6993
|
-
}
|
|
6994
|
-
if (resolvedUniqueConstraints.some(
|
|
6995
|
-
(rc) => rc.name === constraintConfig.name
|
|
6996
|
-
)) {
|
|
6997
|
-
console.warn(
|
|
6998
|
-
`[Model Decorator] Duplicate unique constraint name "${constraintConfig.name}" in model "${options.name}".`
|
|
6999
|
-
);
|
|
7000
|
-
}
|
|
7001
|
-
resolvedUniqueConstraints.push({
|
|
7002
|
-
name: constraintConfig.name,
|
|
7003
|
-
fields: constraintConfig.fields
|
|
7004
|
-
});
|
|
7005
|
-
}
|
|
7006
|
-
);
|
|
7007
|
-
}
|
|
7008
|
-
return {
|
|
7009
|
-
class: targetClass,
|
|
7010
|
-
options,
|
|
7011
|
-
fields: combinedFields,
|
|
7012
|
-
resolvedUniqueConstraints
|
|
7013
|
-
};
|
|
7014
|
-
};
|
|
7015
|
-
const directFieldsForThisClass = Object.prototype.hasOwnProperty.call(
|
|
7016
|
-
targetClass,
|
|
7017
|
-
SCHEMA_FIELDS_PROPERTY
|
|
7018
|
-
) ? targetClass[SCHEMA_FIELDS_PROPERTY] : /* @__PURE__ */ new Map();
|
|
7019
|
-
registry.registerModel(targetClass, options, directFieldsForThisClass);
|
|
7020
|
-
};
|
|
7021
|
-
}
|
|
7022
|
-
|
|
7023
|
-
// src/index.ts
|
|
7024
6895
|
init_StringSet();
|
|
7025
6896
|
|
|
7026
6897
|
// src/models/schema.ts
|
|
@@ -7030,6 +6901,7 @@ function defineModelSchema(input) {
|
|
|
7030
6901
|
const { name, fields } = input;
|
|
7031
6902
|
const options = {
|
|
7032
6903
|
name,
|
|
6904
|
+
className: input.options?.className,
|
|
7033
6905
|
uniqueConstraints: input.options?.uniqueConstraints ? [...input.options.uniqueConstraints] : void 0,
|
|
7034
6906
|
relationships: input.options?.relationships
|
|
7035
6907
|
};
|
|
@@ -7129,18 +7001,13 @@ function resolveUniqueConstraints(modelName, fields, customConstraints) {
|
|
|
7129
7001
|
function attachSchemaToClass(modelClass, schema) {
|
|
7130
7002
|
modelClass.schema = schema;
|
|
7131
7003
|
modelClass.modelName = schema.options.name;
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
value: function() {
|
|
7135
|
-
return schema.buildRuntimeShape(modelClass);
|
|
7136
|
-
},
|
|
7137
|
-
writable: false
|
|
7138
|
-
});
|
|
7139
|
-
} else {
|
|
7140
|
-
modelClass.getSchema = function() {
|
|
7004
|
+
Object.defineProperty(modelClass, "getSchema", {
|
|
7005
|
+
value: function() {
|
|
7141
7006
|
return schema.buildRuntimeShape(modelClass);
|
|
7142
|
-
}
|
|
7143
|
-
|
|
7007
|
+
},
|
|
7008
|
+
writable: false,
|
|
7009
|
+
configurable: true
|
|
7010
|
+
});
|
|
7144
7011
|
const runtimeShape = schema.buildRuntimeShape(modelClass);
|
|
7145
7012
|
BaseModel.attachFieldAccessors(modelClass, runtimeShape.fields);
|
|
7146
7013
|
return runtimeShape;
|
|
@@ -7217,12 +7084,52 @@ var VALID_FIELD_TYPES = /* @__PURE__ */ new Set([
|
|
|
7217
7084
|
"id",
|
|
7218
7085
|
"stringset"
|
|
7219
7086
|
]);
|
|
7220
|
-
|
|
7087
|
+
var KNOWN_FIELD_KEYS = /* @__PURE__ */ new Set([
|
|
7088
|
+
"type",
|
|
7089
|
+
"indexed",
|
|
7090
|
+
"unique",
|
|
7091
|
+
"required",
|
|
7092
|
+
"auto_assign",
|
|
7093
|
+
"max_length",
|
|
7094
|
+
"max_count",
|
|
7095
|
+
"default"
|
|
7096
|
+
]);
|
|
7097
|
+
var KNOWN_MODEL_KEYS = /* @__PURE__ */ new Set([
|
|
7098
|
+
"fields",
|
|
7099
|
+
"relationships",
|
|
7100
|
+
"unique_constraints",
|
|
7101
|
+
"class_name"
|
|
7102
|
+
]);
|
|
7103
|
+
var KNOWN_RELATIONSHIP_KEYS = /* @__PURE__ */ new Set([
|
|
7104
|
+
"type",
|
|
7105
|
+
"model",
|
|
7106
|
+
"related_id_field",
|
|
7107
|
+
"join_model",
|
|
7108
|
+
"join_model_local_field",
|
|
7109
|
+
"join_model_related_field",
|
|
7110
|
+
"order_by_field",
|
|
7111
|
+
"order_direction",
|
|
7112
|
+
"join_model_order_by_field",
|
|
7113
|
+
"join_model_order_direction"
|
|
7114
|
+
]);
|
|
7115
|
+
var KNOWN_UNIQUE_CONSTRAINT_KEYS = /* @__PURE__ */ new Set(["name", "fields"]);
|
|
7116
|
+
function checkUnknownKeys(raw, known, context, strict) {
|
|
7117
|
+
if (!strict) return;
|
|
7118
|
+
for (const key of Object.keys(raw)) {
|
|
7119
|
+
if (!known.has(key)) {
|
|
7120
|
+
throw new Error(
|
|
7121
|
+
`${context}: unknown key "${key}". Allowed: ${[...known].join(", ")}`
|
|
7122
|
+
);
|
|
7123
|
+
}
|
|
7124
|
+
}
|
|
7125
|
+
}
|
|
7126
|
+
function parseFieldOptions(raw, context, strict) {
|
|
7221
7127
|
if (!raw.type || !VALID_FIELD_TYPES.has(raw.type)) {
|
|
7222
7128
|
throw new Error(
|
|
7223
7129
|
`Invalid field type "${raw.type}". Must be one of: ${[...VALID_FIELD_TYPES].join(", ")}`
|
|
7224
7130
|
);
|
|
7225
7131
|
}
|
|
7132
|
+
checkUnknownKeys(raw, KNOWN_FIELD_KEYS, context, strict);
|
|
7226
7133
|
const opts = { type: raw.type };
|
|
7227
7134
|
if (raw.indexed === true) opts.indexed = true;
|
|
7228
7135
|
if (raw.unique === true) opts.unique = true;
|
|
@@ -7238,8 +7145,9 @@ function requireField(raw, field, context) {
|
|
|
7238
7145
|
throw new Error(`Relationship ${context}: missing required field "${field}"`);
|
|
7239
7146
|
}
|
|
7240
7147
|
}
|
|
7241
|
-
function parseRelationship(raw) {
|
|
7148
|
+
function parseRelationship(raw, context, strict) {
|
|
7242
7149
|
const type = raw.type;
|
|
7150
|
+
checkUnknownKeys(raw, KNOWN_RELATIONSHIP_KEYS, context, strict);
|
|
7243
7151
|
if (type === "refersTo") {
|
|
7244
7152
|
requireField(raw, "model", "refersTo");
|
|
7245
7153
|
requireField(raw, "related_id_field", "refersTo");
|
|
@@ -7281,7 +7189,8 @@ function parseRelationship(raw) {
|
|
|
7281
7189
|
}
|
|
7282
7190
|
throw new Error(`Unknown relationship type: ${type}`);
|
|
7283
7191
|
}
|
|
7284
|
-
function loadSchemaFromTomlString(tomlString) {
|
|
7192
|
+
function loadSchemaFromTomlString(tomlString, options = {}) {
|
|
7193
|
+
const strict = options.strict !== false;
|
|
7285
7194
|
const parsed = (0, import_smol_toml.parse)(tomlString);
|
|
7286
7195
|
const models = parsed.models;
|
|
7287
7196
|
if (!models || typeof models !== "object") {
|
|
@@ -7289,10 +7198,20 @@ function loadSchemaFromTomlString(tomlString) {
|
|
|
7289
7198
|
}
|
|
7290
7199
|
const schemas = [];
|
|
7291
7200
|
for (const [modelName, modelDef] of Object.entries(models)) {
|
|
7201
|
+
checkUnknownKeys(
|
|
7202
|
+
modelDef,
|
|
7203
|
+
KNOWN_MODEL_KEYS,
|
|
7204
|
+
`[models.${modelName}]`,
|
|
7205
|
+
strict
|
|
7206
|
+
);
|
|
7292
7207
|
const fields = {};
|
|
7293
7208
|
if (modelDef.fields) {
|
|
7294
7209
|
for (const [fieldName, fieldDef] of Object.entries(modelDef.fields)) {
|
|
7295
|
-
fields[fieldName] = parseFieldOptions(
|
|
7210
|
+
fields[fieldName] = parseFieldOptions(
|
|
7211
|
+
fieldDef,
|
|
7212
|
+
`[models.${modelName}.fields.${fieldName}]`,
|
|
7213
|
+
strict
|
|
7214
|
+
);
|
|
7296
7215
|
}
|
|
7297
7216
|
}
|
|
7298
7217
|
let relationships;
|
|
@@ -7301,24 +7220,36 @@ function loadSchemaFromTomlString(tomlString) {
|
|
|
7301
7220
|
for (const [relName, relDef] of Object.entries(
|
|
7302
7221
|
modelDef.relationships
|
|
7303
7222
|
)) {
|
|
7304
|
-
relationships[relName] = parseRelationship(
|
|
7223
|
+
relationships[relName] = parseRelationship(
|
|
7224
|
+
relDef,
|
|
7225
|
+
`[models.${modelName}.relationships.${relName}]`,
|
|
7226
|
+
strict
|
|
7227
|
+
);
|
|
7305
7228
|
}
|
|
7306
7229
|
}
|
|
7307
7230
|
let uniqueConstraints;
|
|
7308
7231
|
if (modelDef.unique_constraints) {
|
|
7309
7232
|
uniqueConstraints = [];
|
|
7310
7233
|
for (const raw of modelDef.unique_constraints) {
|
|
7234
|
+
checkUnknownKeys(
|
|
7235
|
+
raw,
|
|
7236
|
+
KNOWN_UNIQUE_CONSTRAINT_KEYS,
|
|
7237
|
+
`[[models.${modelName}.unique_constraints]]`,
|
|
7238
|
+
strict
|
|
7239
|
+
);
|
|
7311
7240
|
uniqueConstraints.push({
|
|
7312
7241
|
name: raw.name,
|
|
7313
7242
|
fields: [...raw.fields]
|
|
7314
7243
|
});
|
|
7315
7244
|
}
|
|
7316
7245
|
}
|
|
7246
|
+
const className = typeof modelDef.class_name === "string" ? modelDef.class_name : void 0;
|
|
7317
7247
|
schemas.push(
|
|
7318
7248
|
defineModelSchema({
|
|
7319
7249
|
name: modelName,
|
|
7320
7250
|
fields,
|
|
7321
7251
|
options: {
|
|
7252
|
+
className,
|
|
7322
7253
|
uniqueConstraints,
|
|
7323
7254
|
relationships
|
|
7324
7255
|
}
|
|
@@ -7327,10 +7258,10 @@ function loadSchemaFromTomlString(tomlString) {
|
|
|
7327
7258
|
}
|
|
7328
7259
|
return schemas;
|
|
7329
7260
|
}
|
|
7330
|
-
async function loadSchemaFromToml(filePath) {
|
|
7261
|
+
async function loadSchemaFromToml(filePath, options = {}) {
|
|
7331
7262
|
const { readFile } = await import("fs/promises");
|
|
7332
7263
|
const content = await readFile(filePath, "utf-8");
|
|
7333
|
-
return loadSchemaFromTomlString(content);
|
|
7264
|
+
return loadSchemaFromTomlString(content, options);
|
|
7334
7265
|
}
|
|
7335
7266
|
|
|
7336
7267
|
// src/utils/yDocSchema.ts
|
|
@@ -7593,10 +7524,8 @@ function summarizePlainYDoc(dump) {
|
|
|
7593
7524
|
DatabaseEngine,
|
|
7594
7525
|
DocumentClosedError,
|
|
7595
7526
|
DocumentResolutionError,
|
|
7596
|
-
Field,
|
|
7597
7527
|
LogLevel,
|
|
7598
7528
|
Logger,
|
|
7599
|
-
Model,
|
|
7600
7529
|
ModelRegistry,
|
|
7601
7530
|
RecordNotFoundError,
|
|
7602
7531
|
StringSet,
|
package/dist/index.d.cts
CHANGED
|
@@ -40,6 +40,13 @@ interface UniqueConstraintConfig {
|
|
|
40
40
|
}
|
|
41
41
|
interface ModelOptions {
|
|
42
42
|
name: string;
|
|
43
|
+
/**
|
|
44
|
+
* Optional PascalCase class name. Used by the v2 codegen to drive
|
|
45
|
+
* generated TypeScript class names (and relationship method names that
|
|
46
|
+
* derive from a target's class name). When absent, the v2 codegen
|
|
47
|
+
* falls back to suffix-based singularization of `name`.
|
|
48
|
+
*/
|
|
49
|
+
className?: string;
|
|
43
50
|
uniqueConstraints?: UniqueConstraintConfig[];
|
|
44
51
|
relationships?: Record<string, RelationshipConfig>;
|
|
45
52
|
}
|
|
@@ -702,7 +709,7 @@ interface InitJsBaoOptions {
|
|
|
702
709
|
/**
|
|
703
710
|
* Optional array of model classes to initialize.
|
|
704
711
|
* If not provided, the ORM will rely on models being registered
|
|
705
|
-
* via
|
|
712
|
+
* via attachAndRegisterModel (assuming they have been imported by the application).
|
|
706
713
|
*/
|
|
707
714
|
models?: (typeof BaseModel)[];
|
|
708
715
|
}
|
|
@@ -742,9 +749,6 @@ declare function initJsBao(options: InitJsBaoOptions): Promise<InitJsBaoResult>;
|
|
|
742
749
|
*/
|
|
743
750
|
declare function resetJsBao(): Promise<void>;
|
|
744
751
|
|
|
745
|
-
declare function Field(options: FieldOptions): (target: any, propertyKey: string | symbol) => void;
|
|
746
|
-
declare function Model(options: ModelOptions): (targetClass: Function) => void;
|
|
747
|
-
|
|
748
752
|
interface ResolvedUniqueConstraint {
|
|
749
753
|
name: string;
|
|
750
754
|
fields: string[];
|
|
@@ -850,15 +854,27 @@ declare function syncInferredMeta(yDoc: Y.Doc, modelName: string, recordData: Re
|
|
|
850
854
|
* - Compound unique constraints are [[models.*.unique_constraints]]
|
|
851
855
|
*/
|
|
852
856
|
|
|
857
|
+
interface LoadSchemaOptions {
|
|
858
|
+
/**
|
|
859
|
+
* When true (default), throw on unknown keys at the model, field,
|
|
860
|
+
* relationship, and unique-constraint level. When false, unknown
|
|
861
|
+
* keys are silently ignored (legacy behavior).
|
|
862
|
+
*/
|
|
863
|
+
strict?: boolean;
|
|
864
|
+
}
|
|
853
865
|
/**
|
|
854
866
|
* Parse a TOML string and return an array of DefinedModelSchema objects.
|
|
867
|
+
*
|
|
868
|
+
* By default operates in strict mode: unknown keys at the model, field,
|
|
869
|
+
* relationship, or unique-constraint level cause an error. Pass
|
|
870
|
+
* `{ strict: false }` to silently ignore unknown keys (legacy behavior).
|
|
855
871
|
*/
|
|
856
|
-
declare function loadSchemaFromTomlString(tomlString: string): DefinedModelSchema[];
|
|
872
|
+
declare function loadSchemaFromTomlString(tomlString: string, options?: LoadSchemaOptions): DefinedModelSchema[];
|
|
857
873
|
/**
|
|
858
874
|
* Read a TOML file from disk and return an array of DefinedModelSchema objects.
|
|
859
875
|
* Only available in Node.js environments.
|
|
860
876
|
*/
|
|
861
|
-
declare function loadSchemaFromToml(filePath: string): Promise<DefinedModelSchema[]>;
|
|
877
|
+
declare function loadSchemaFromToml(filePath: string, options?: LoadSchemaOptions): Promise<DefinedModelSchema[]>;
|
|
862
878
|
|
|
863
879
|
/**
|
|
864
880
|
* YDoc Schema Discovery
|
|
@@ -956,4 +972,4 @@ declare function dumpYDocToPlain(yDoc: Y.Doc, options?: DumpOptions): PlainYDoc;
|
|
|
956
972
|
*/
|
|
957
973
|
declare function summarizePlainYDoc(dump: PlainYDoc): DumpSummary;
|
|
958
974
|
|
|
959
|
-
export { BaseModel, type ConnectedDocument, type DatabaseConfig, DatabaseEngine, type DiscoveredConstraint, type DiscoveredField, type DiscoveredModel, type DiscoveredRelationship, type DiscoveredSchema, DocumentClosedError, type DocumentConnectionCallback, type DocumentConnectionEvent, type DocumentFilter, type DocumentManager, type DocumentPermissionHint, DocumentResolutionError, type DumpOptions, type DumpSummary, type DumpSummaryEntry,
|
|
975
|
+
export { BaseModel, type ConnectedDocument, type DatabaseConfig, DatabaseEngine, type DiscoveredConstraint, type DiscoveredField, type DiscoveredModel, type DiscoveredRelationship, type DiscoveredSchema, DocumentClosedError, type DocumentConnectionCallback, type DocumentConnectionEvent, type DocumentFilter, type DocumentManager, type DocumentPermissionHint, DocumentResolutionError, type DumpOptions, type DumpSummary, type DumpSummaryEntry, type FieldOptions, type IncludeSpec, type InferAttrs, type InitJsBaoOptions, type InitJsBaoResult, LogLevel, Logger, type ModelConstructor, type ModelOptions, ModelRegistry, type PaginatedResult, type PaginationOptions, type PlainYDoc, type ProjectionSpec, type QueryOptions, type QueryResult, RecordNotFoundError, type SaveOptions, StringSet, UniqueConstraintViolationError, attachAndRegisterModel, attachSchemaToClass, autoRegisterModel, clearMetaSyncCache, createModelClass, defineModelSchema, discoverModelNames, discoverSchema, dumpYDocToPlain, generateULID, inferFieldType, initJsBao, loadSchemaFromToml, loadSchemaFromTomlString, registerFunctionDefault, resetJsBao, schemaToToml, summarizePlainYDoc, syncInferredMeta, syncModelMeta };
|
package/dist/index.d.ts
CHANGED
|
@@ -40,6 +40,13 @@ interface UniqueConstraintConfig {
|
|
|
40
40
|
}
|
|
41
41
|
interface ModelOptions {
|
|
42
42
|
name: string;
|
|
43
|
+
/**
|
|
44
|
+
* Optional PascalCase class name. Used by the v2 codegen to drive
|
|
45
|
+
* generated TypeScript class names (and relationship method names that
|
|
46
|
+
* derive from a target's class name). When absent, the v2 codegen
|
|
47
|
+
* falls back to suffix-based singularization of `name`.
|
|
48
|
+
*/
|
|
49
|
+
className?: string;
|
|
43
50
|
uniqueConstraints?: UniqueConstraintConfig[];
|
|
44
51
|
relationships?: Record<string, RelationshipConfig>;
|
|
45
52
|
}
|
|
@@ -702,7 +709,7 @@ interface InitJsBaoOptions {
|
|
|
702
709
|
/**
|
|
703
710
|
* Optional array of model classes to initialize.
|
|
704
711
|
* If not provided, the ORM will rely on models being registered
|
|
705
|
-
* via
|
|
712
|
+
* via attachAndRegisterModel (assuming they have been imported by the application).
|
|
706
713
|
*/
|
|
707
714
|
models?: (typeof BaseModel)[];
|
|
708
715
|
}
|
|
@@ -742,9 +749,6 @@ declare function initJsBao(options: InitJsBaoOptions): Promise<InitJsBaoResult>;
|
|
|
742
749
|
*/
|
|
743
750
|
declare function resetJsBao(): Promise<void>;
|
|
744
751
|
|
|
745
|
-
declare function Field(options: FieldOptions): (target: any, propertyKey: string | symbol) => void;
|
|
746
|
-
declare function Model(options: ModelOptions): (targetClass: Function) => void;
|
|
747
|
-
|
|
748
752
|
interface ResolvedUniqueConstraint {
|
|
749
753
|
name: string;
|
|
750
754
|
fields: string[];
|
|
@@ -850,15 +854,27 @@ declare function syncInferredMeta(yDoc: Y.Doc, modelName: string, recordData: Re
|
|
|
850
854
|
* - Compound unique constraints are [[models.*.unique_constraints]]
|
|
851
855
|
*/
|
|
852
856
|
|
|
857
|
+
interface LoadSchemaOptions {
|
|
858
|
+
/**
|
|
859
|
+
* When true (default), throw on unknown keys at the model, field,
|
|
860
|
+
* relationship, and unique-constraint level. When false, unknown
|
|
861
|
+
* keys are silently ignored (legacy behavior).
|
|
862
|
+
*/
|
|
863
|
+
strict?: boolean;
|
|
864
|
+
}
|
|
853
865
|
/**
|
|
854
866
|
* Parse a TOML string and return an array of DefinedModelSchema objects.
|
|
867
|
+
*
|
|
868
|
+
* By default operates in strict mode: unknown keys at the model, field,
|
|
869
|
+
* relationship, or unique-constraint level cause an error. Pass
|
|
870
|
+
* `{ strict: false }` to silently ignore unknown keys (legacy behavior).
|
|
855
871
|
*/
|
|
856
|
-
declare function loadSchemaFromTomlString(tomlString: string): DefinedModelSchema[];
|
|
872
|
+
declare function loadSchemaFromTomlString(tomlString: string, options?: LoadSchemaOptions): DefinedModelSchema[];
|
|
857
873
|
/**
|
|
858
874
|
* Read a TOML file from disk and return an array of DefinedModelSchema objects.
|
|
859
875
|
* Only available in Node.js environments.
|
|
860
876
|
*/
|
|
861
|
-
declare function loadSchemaFromToml(filePath: string): Promise<DefinedModelSchema[]>;
|
|
877
|
+
declare function loadSchemaFromToml(filePath: string, options?: LoadSchemaOptions): Promise<DefinedModelSchema[]>;
|
|
862
878
|
|
|
863
879
|
/**
|
|
864
880
|
* YDoc Schema Discovery
|
|
@@ -956,4 +972,4 @@ declare function dumpYDocToPlain(yDoc: Y.Doc, options?: DumpOptions): PlainYDoc;
|
|
|
956
972
|
*/
|
|
957
973
|
declare function summarizePlainYDoc(dump: PlainYDoc): DumpSummary;
|
|
958
974
|
|
|
959
|
-
export { BaseModel, type ConnectedDocument, type DatabaseConfig, DatabaseEngine, type DiscoveredConstraint, type DiscoveredField, type DiscoveredModel, type DiscoveredRelationship, type DiscoveredSchema, DocumentClosedError, type DocumentConnectionCallback, type DocumentConnectionEvent, type DocumentFilter, type DocumentManager, type DocumentPermissionHint, DocumentResolutionError, type DumpOptions, type DumpSummary, type DumpSummaryEntry,
|
|
975
|
+
export { BaseModel, type ConnectedDocument, type DatabaseConfig, DatabaseEngine, type DiscoveredConstraint, type DiscoveredField, type DiscoveredModel, type DiscoveredRelationship, type DiscoveredSchema, DocumentClosedError, type DocumentConnectionCallback, type DocumentConnectionEvent, type DocumentFilter, type DocumentManager, type DocumentPermissionHint, DocumentResolutionError, type DumpOptions, type DumpSummary, type DumpSummaryEntry, type FieldOptions, type IncludeSpec, type InferAttrs, type InitJsBaoOptions, type InitJsBaoResult, LogLevel, Logger, type ModelConstructor, type ModelOptions, ModelRegistry, type PaginatedResult, type PaginationOptions, type PlainYDoc, type ProjectionSpec, type QueryOptions, type QueryResult, RecordNotFoundError, type SaveOptions, StringSet, UniqueConstraintViolationError, attachAndRegisterModel, attachSchemaToClass, autoRegisterModel, clearMetaSyncCache, createModelClass, defineModelSchema, discoverModelNames, discoverSchema, dumpYDocToPlain, generateULID, inferFieldType, initJsBao, loadSchemaFromToml, loadSchemaFromTomlString, registerFunctionDefault, resetJsBao, schemaToToml, summarizePlainYDoc, syncInferredMeta, syncModelMeta };
|