js-bao 0.4.0 → 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 +76 -16
- package/dist/browser.d.cts +20 -1
- package/dist/browser.d.ts +20 -1
- package/dist/browser.js +76 -16
- 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 +7 -10
- package/dist/index.cjs +78 -18
- package/dist/index.d.cts +21 -2
- package/dist/index.d.ts +21 -2
- package/dist/index.js +78 -18
- package/dist/node.cjs +78 -18
- package/dist/node.d.cts +21 -2
- package/dist/node.d.ts +21 -2
- package/dist/node.js +78 -18
- package/package.json +7 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/codegen.cjs
CHANGED
|
@@ -1181,7 +1181,7 @@ var SchemaExtractor = class {
|
|
|
1181
1181
|
// package.json
|
|
1182
1182
|
var package_default = {
|
|
1183
1183
|
name: "js-bao",
|
|
1184
|
-
version: "0.4.
|
|
1184
|
+
version: "0.4.1",
|
|
1185
1185
|
description: "A library providing data modeling capabilities which support live updates and queries.",
|
|
1186
1186
|
types: "dist/index.d.ts",
|
|
1187
1187
|
type: "module",
|
|
@@ -1232,10 +1232,12 @@ var package_default = {
|
|
|
1232
1232
|
},
|
|
1233
1233
|
bin: {
|
|
1234
1234
|
"js-bao-codegen": "./dist/codegen.cjs",
|
|
1235
|
-
"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"
|
|
1236
1238
|
},
|
|
1237
1239
|
scripts: {
|
|
1238
|
-
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",
|
|
1239
1241
|
"build:main": "pnpm build:browser && pnpm build:node && pnpm build:universal && pnpm build:cloudflare && pnpm build:cloudflare-do && pnpm build:client",
|
|
1240
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",
|
|
1241
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",
|
|
@@ -1244,6 +1246,7 @@ var package_default = {
|
|
|
1244
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",
|
|
1245
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",
|
|
1246
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",
|
|
1247
1250
|
dev: 'pnpm build:cli && concurrently "pnpm codegen:watch" "pnpm dev:main"',
|
|
1248
1251
|
"dev:main": 'concurrently "pnpm build:browser:dev --watch" "pnpm build:node:dev --watch" "pnpm build:universal:dev --watch"',
|
|
1249
1252
|
"dev:simple": "pnpm build:cli && pnpm codegen && pnpm build:main --watch",
|
|
@@ -1297,13 +1300,7 @@ var package_default = {
|
|
|
1297
1300
|
"workers"
|
|
1298
1301
|
],
|
|
1299
1302
|
author: "Primitive LLC",
|
|
1300
|
-
license: "UNLICENSED"
|
|
1301
|
-
pnpm: {
|
|
1302
|
-
onlyBuiltDependencies: [
|
|
1303
|
-
"better-sqlite3",
|
|
1304
|
-
"esbuild"
|
|
1305
|
-
]
|
|
1306
|
-
}
|
|
1303
|
+
license: "UNLICENSED"
|
|
1307
1304
|
};
|
|
1308
1305
|
|
|
1309
1306
|
// src/cli/codegen.ts
|
package/dist/index.cjs
CHANGED
|
@@ -6901,6 +6901,7 @@ function defineModelSchema(input) {
|
|
|
6901
6901
|
const { name, fields } = input;
|
|
6902
6902
|
const options = {
|
|
6903
6903
|
name,
|
|
6904
|
+
className: input.options?.className,
|
|
6904
6905
|
uniqueConstraints: input.options?.uniqueConstraints ? [...input.options.uniqueConstraints] : void 0,
|
|
6905
6906
|
relationships: input.options?.relationships
|
|
6906
6907
|
};
|
|
@@ -7000,18 +7001,13 @@ function resolveUniqueConstraints(modelName, fields, customConstraints) {
|
|
|
7000
7001
|
function attachSchemaToClass(modelClass, schema) {
|
|
7001
7002
|
modelClass.schema = schema;
|
|
7002
7003
|
modelClass.modelName = schema.options.name;
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
value: function() {
|
|
7006
|
-
return schema.buildRuntimeShape(modelClass);
|
|
7007
|
-
},
|
|
7008
|
-
writable: false
|
|
7009
|
-
});
|
|
7010
|
-
} else {
|
|
7011
|
-
modelClass.getSchema = function() {
|
|
7004
|
+
Object.defineProperty(modelClass, "getSchema", {
|
|
7005
|
+
value: function() {
|
|
7012
7006
|
return schema.buildRuntimeShape(modelClass);
|
|
7013
|
-
}
|
|
7014
|
-
|
|
7007
|
+
},
|
|
7008
|
+
writable: false,
|
|
7009
|
+
configurable: true
|
|
7010
|
+
});
|
|
7015
7011
|
const runtimeShape = schema.buildRuntimeShape(modelClass);
|
|
7016
7012
|
BaseModel.attachFieldAccessors(modelClass, runtimeShape.fields);
|
|
7017
7013
|
return runtimeShape;
|
|
@@ -7088,12 +7084,52 @@ var VALID_FIELD_TYPES = /* @__PURE__ */ new Set([
|
|
|
7088
7084
|
"id",
|
|
7089
7085
|
"stringset"
|
|
7090
7086
|
]);
|
|
7091
|
-
|
|
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) {
|
|
7092
7127
|
if (!raw.type || !VALID_FIELD_TYPES.has(raw.type)) {
|
|
7093
7128
|
throw new Error(
|
|
7094
7129
|
`Invalid field type "${raw.type}". Must be one of: ${[...VALID_FIELD_TYPES].join(", ")}`
|
|
7095
7130
|
);
|
|
7096
7131
|
}
|
|
7132
|
+
checkUnknownKeys(raw, KNOWN_FIELD_KEYS, context, strict);
|
|
7097
7133
|
const opts = { type: raw.type };
|
|
7098
7134
|
if (raw.indexed === true) opts.indexed = true;
|
|
7099
7135
|
if (raw.unique === true) opts.unique = true;
|
|
@@ -7109,8 +7145,9 @@ function requireField(raw, field, context) {
|
|
|
7109
7145
|
throw new Error(`Relationship ${context}: missing required field "${field}"`);
|
|
7110
7146
|
}
|
|
7111
7147
|
}
|
|
7112
|
-
function parseRelationship(raw) {
|
|
7148
|
+
function parseRelationship(raw, context, strict) {
|
|
7113
7149
|
const type = raw.type;
|
|
7150
|
+
checkUnknownKeys(raw, KNOWN_RELATIONSHIP_KEYS, context, strict);
|
|
7114
7151
|
if (type === "refersTo") {
|
|
7115
7152
|
requireField(raw, "model", "refersTo");
|
|
7116
7153
|
requireField(raw, "related_id_field", "refersTo");
|
|
@@ -7152,7 +7189,8 @@ function parseRelationship(raw) {
|
|
|
7152
7189
|
}
|
|
7153
7190
|
throw new Error(`Unknown relationship type: ${type}`);
|
|
7154
7191
|
}
|
|
7155
|
-
function loadSchemaFromTomlString(tomlString) {
|
|
7192
|
+
function loadSchemaFromTomlString(tomlString, options = {}) {
|
|
7193
|
+
const strict = options.strict !== false;
|
|
7156
7194
|
const parsed = (0, import_smol_toml.parse)(tomlString);
|
|
7157
7195
|
const models = parsed.models;
|
|
7158
7196
|
if (!models || typeof models !== "object") {
|
|
@@ -7160,10 +7198,20 @@ function loadSchemaFromTomlString(tomlString) {
|
|
|
7160
7198
|
}
|
|
7161
7199
|
const schemas = [];
|
|
7162
7200
|
for (const [modelName, modelDef] of Object.entries(models)) {
|
|
7201
|
+
checkUnknownKeys(
|
|
7202
|
+
modelDef,
|
|
7203
|
+
KNOWN_MODEL_KEYS,
|
|
7204
|
+
`[models.${modelName}]`,
|
|
7205
|
+
strict
|
|
7206
|
+
);
|
|
7163
7207
|
const fields = {};
|
|
7164
7208
|
if (modelDef.fields) {
|
|
7165
7209
|
for (const [fieldName, fieldDef] of Object.entries(modelDef.fields)) {
|
|
7166
|
-
fields[fieldName] = parseFieldOptions(
|
|
7210
|
+
fields[fieldName] = parseFieldOptions(
|
|
7211
|
+
fieldDef,
|
|
7212
|
+
`[models.${modelName}.fields.${fieldName}]`,
|
|
7213
|
+
strict
|
|
7214
|
+
);
|
|
7167
7215
|
}
|
|
7168
7216
|
}
|
|
7169
7217
|
let relationships;
|
|
@@ -7172,24 +7220,36 @@ function loadSchemaFromTomlString(tomlString) {
|
|
|
7172
7220
|
for (const [relName, relDef] of Object.entries(
|
|
7173
7221
|
modelDef.relationships
|
|
7174
7222
|
)) {
|
|
7175
|
-
relationships[relName] = parseRelationship(
|
|
7223
|
+
relationships[relName] = parseRelationship(
|
|
7224
|
+
relDef,
|
|
7225
|
+
`[models.${modelName}.relationships.${relName}]`,
|
|
7226
|
+
strict
|
|
7227
|
+
);
|
|
7176
7228
|
}
|
|
7177
7229
|
}
|
|
7178
7230
|
let uniqueConstraints;
|
|
7179
7231
|
if (modelDef.unique_constraints) {
|
|
7180
7232
|
uniqueConstraints = [];
|
|
7181
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
|
+
);
|
|
7182
7240
|
uniqueConstraints.push({
|
|
7183
7241
|
name: raw.name,
|
|
7184
7242
|
fields: [...raw.fields]
|
|
7185
7243
|
});
|
|
7186
7244
|
}
|
|
7187
7245
|
}
|
|
7246
|
+
const className = typeof modelDef.class_name === "string" ? modelDef.class_name : void 0;
|
|
7188
7247
|
schemas.push(
|
|
7189
7248
|
defineModelSchema({
|
|
7190
7249
|
name: modelName,
|
|
7191
7250
|
fields,
|
|
7192
7251
|
options: {
|
|
7252
|
+
className,
|
|
7193
7253
|
uniqueConstraints,
|
|
7194
7254
|
relationships
|
|
7195
7255
|
}
|
|
@@ -7198,10 +7258,10 @@ function loadSchemaFromTomlString(tomlString) {
|
|
|
7198
7258
|
}
|
|
7199
7259
|
return schemas;
|
|
7200
7260
|
}
|
|
7201
|
-
async function loadSchemaFromToml(filePath) {
|
|
7261
|
+
async function loadSchemaFromToml(filePath, options = {}) {
|
|
7202
7262
|
const { readFile } = await import("fs/promises");
|
|
7203
7263
|
const content = await readFile(filePath, "utf-8");
|
|
7204
|
-
return loadSchemaFromTomlString(content);
|
|
7264
|
+
return loadSchemaFromTomlString(content, options);
|
|
7205
7265
|
}
|
|
7206
7266
|
|
|
7207
7267
|
// src/utils/yDocSchema.ts
|
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
|
}
|
|
@@ -847,15 +854,27 @@ declare function syncInferredMeta(yDoc: Y.Doc, modelName: string, recordData: Re
|
|
|
847
854
|
* - Compound unique constraints are [[models.*.unique_constraints]]
|
|
848
855
|
*/
|
|
849
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
|
+
}
|
|
850
865
|
/**
|
|
851
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).
|
|
852
871
|
*/
|
|
853
|
-
declare function loadSchemaFromTomlString(tomlString: string): DefinedModelSchema[];
|
|
872
|
+
declare function loadSchemaFromTomlString(tomlString: string, options?: LoadSchemaOptions): DefinedModelSchema[];
|
|
854
873
|
/**
|
|
855
874
|
* Read a TOML file from disk and return an array of DefinedModelSchema objects.
|
|
856
875
|
* Only available in Node.js environments.
|
|
857
876
|
*/
|
|
858
|
-
declare function loadSchemaFromToml(filePath: string): Promise<DefinedModelSchema[]>;
|
|
877
|
+
declare function loadSchemaFromToml(filePath: string, options?: LoadSchemaOptions): Promise<DefinedModelSchema[]>;
|
|
859
878
|
|
|
860
879
|
/**
|
|
861
880
|
* YDoc Schema Discovery
|
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
|
}
|
|
@@ -847,15 +854,27 @@ declare function syncInferredMeta(yDoc: Y.Doc, modelName: string, recordData: Re
|
|
|
847
854
|
* - Compound unique constraints are [[models.*.unique_constraints]]
|
|
848
855
|
*/
|
|
849
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
|
+
}
|
|
850
865
|
/**
|
|
851
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).
|
|
852
871
|
*/
|
|
853
|
-
declare function loadSchemaFromTomlString(tomlString: string): DefinedModelSchema[];
|
|
872
|
+
declare function loadSchemaFromTomlString(tomlString: string, options?: LoadSchemaOptions): DefinedModelSchema[];
|
|
854
873
|
/**
|
|
855
874
|
* Read a TOML file from disk and return an array of DefinedModelSchema objects.
|
|
856
875
|
* Only available in Node.js environments.
|
|
857
876
|
*/
|
|
858
|
-
declare function loadSchemaFromToml(filePath: string): Promise<DefinedModelSchema[]>;
|
|
877
|
+
declare function loadSchemaFromToml(filePath: string, options?: LoadSchemaOptions): Promise<DefinedModelSchema[]>;
|
|
859
878
|
|
|
860
879
|
/**
|
|
861
880
|
* YDoc Schema Discovery
|
package/dist/index.js
CHANGED
|
@@ -6843,6 +6843,7 @@ function defineModelSchema(input) {
|
|
|
6843
6843
|
const { name, fields } = input;
|
|
6844
6844
|
const options = {
|
|
6845
6845
|
name,
|
|
6846
|
+
className: input.options?.className,
|
|
6846
6847
|
uniqueConstraints: input.options?.uniqueConstraints ? [...input.options.uniqueConstraints] : void 0,
|
|
6847
6848
|
relationships: input.options?.relationships
|
|
6848
6849
|
};
|
|
@@ -6942,18 +6943,13 @@ function resolveUniqueConstraints(modelName, fields, customConstraints) {
|
|
|
6942
6943
|
function attachSchemaToClass(modelClass, schema) {
|
|
6943
6944
|
modelClass.schema = schema;
|
|
6944
6945
|
modelClass.modelName = schema.options.name;
|
|
6945
|
-
|
|
6946
|
-
|
|
6947
|
-
value: function() {
|
|
6948
|
-
return schema.buildRuntimeShape(modelClass);
|
|
6949
|
-
},
|
|
6950
|
-
writable: false
|
|
6951
|
-
});
|
|
6952
|
-
} else {
|
|
6953
|
-
modelClass.getSchema = function() {
|
|
6946
|
+
Object.defineProperty(modelClass, "getSchema", {
|
|
6947
|
+
value: function() {
|
|
6954
6948
|
return schema.buildRuntimeShape(modelClass);
|
|
6955
|
-
}
|
|
6956
|
-
|
|
6949
|
+
},
|
|
6950
|
+
writable: false,
|
|
6951
|
+
configurable: true
|
|
6952
|
+
});
|
|
6957
6953
|
const runtimeShape = schema.buildRuntimeShape(modelClass);
|
|
6958
6954
|
BaseModel.attachFieldAccessors(modelClass, runtimeShape.fields);
|
|
6959
6955
|
return runtimeShape;
|
|
@@ -7030,12 +7026,52 @@ var VALID_FIELD_TYPES = /* @__PURE__ */ new Set([
|
|
|
7030
7026
|
"id",
|
|
7031
7027
|
"stringset"
|
|
7032
7028
|
]);
|
|
7033
|
-
|
|
7029
|
+
var KNOWN_FIELD_KEYS = /* @__PURE__ */ new Set([
|
|
7030
|
+
"type",
|
|
7031
|
+
"indexed",
|
|
7032
|
+
"unique",
|
|
7033
|
+
"required",
|
|
7034
|
+
"auto_assign",
|
|
7035
|
+
"max_length",
|
|
7036
|
+
"max_count",
|
|
7037
|
+
"default"
|
|
7038
|
+
]);
|
|
7039
|
+
var KNOWN_MODEL_KEYS = /* @__PURE__ */ new Set([
|
|
7040
|
+
"fields",
|
|
7041
|
+
"relationships",
|
|
7042
|
+
"unique_constraints",
|
|
7043
|
+
"class_name"
|
|
7044
|
+
]);
|
|
7045
|
+
var KNOWN_RELATIONSHIP_KEYS = /* @__PURE__ */ new Set([
|
|
7046
|
+
"type",
|
|
7047
|
+
"model",
|
|
7048
|
+
"related_id_field",
|
|
7049
|
+
"join_model",
|
|
7050
|
+
"join_model_local_field",
|
|
7051
|
+
"join_model_related_field",
|
|
7052
|
+
"order_by_field",
|
|
7053
|
+
"order_direction",
|
|
7054
|
+
"join_model_order_by_field",
|
|
7055
|
+
"join_model_order_direction"
|
|
7056
|
+
]);
|
|
7057
|
+
var KNOWN_UNIQUE_CONSTRAINT_KEYS = /* @__PURE__ */ new Set(["name", "fields"]);
|
|
7058
|
+
function checkUnknownKeys(raw, known, context, strict) {
|
|
7059
|
+
if (!strict) return;
|
|
7060
|
+
for (const key of Object.keys(raw)) {
|
|
7061
|
+
if (!known.has(key)) {
|
|
7062
|
+
throw new Error(
|
|
7063
|
+
`${context}: unknown key "${key}". Allowed: ${[...known].join(", ")}`
|
|
7064
|
+
);
|
|
7065
|
+
}
|
|
7066
|
+
}
|
|
7067
|
+
}
|
|
7068
|
+
function parseFieldOptions(raw, context, strict) {
|
|
7034
7069
|
if (!raw.type || !VALID_FIELD_TYPES.has(raw.type)) {
|
|
7035
7070
|
throw new Error(
|
|
7036
7071
|
`Invalid field type "${raw.type}". Must be one of: ${[...VALID_FIELD_TYPES].join(", ")}`
|
|
7037
7072
|
);
|
|
7038
7073
|
}
|
|
7074
|
+
checkUnknownKeys(raw, KNOWN_FIELD_KEYS, context, strict);
|
|
7039
7075
|
const opts = { type: raw.type };
|
|
7040
7076
|
if (raw.indexed === true) opts.indexed = true;
|
|
7041
7077
|
if (raw.unique === true) opts.unique = true;
|
|
@@ -7051,8 +7087,9 @@ function requireField(raw, field, context) {
|
|
|
7051
7087
|
throw new Error(`Relationship ${context}: missing required field "${field}"`);
|
|
7052
7088
|
}
|
|
7053
7089
|
}
|
|
7054
|
-
function parseRelationship(raw) {
|
|
7090
|
+
function parseRelationship(raw, context, strict) {
|
|
7055
7091
|
const type = raw.type;
|
|
7092
|
+
checkUnknownKeys(raw, KNOWN_RELATIONSHIP_KEYS, context, strict);
|
|
7056
7093
|
if (type === "refersTo") {
|
|
7057
7094
|
requireField(raw, "model", "refersTo");
|
|
7058
7095
|
requireField(raw, "related_id_field", "refersTo");
|
|
@@ -7094,7 +7131,8 @@ function parseRelationship(raw) {
|
|
|
7094
7131
|
}
|
|
7095
7132
|
throw new Error(`Unknown relationship type: ${type}`);
|
|
7096
7133
|
}
|
|
7097
|
-
function loadSchemaFromTomlString(tomlString) {
|
|
7134
|
+
function loadSchemaFromTomlString(tomlString, options = {}) {
|
|
7135
|
+
const strict = options.strict !== false;
|
|
7098
7136
|
const parsed = parseToml(tomlString);
|
|
7099
7137
|
const models = parsed.models;
|
|
7100
7138
|
if (!models || typeof models !== "object") {
|
|
@@ -7102,10 +7140,20 @@ function loadSchemaFromTomlString(tomlString) {
|
|
|
7102
7140
|
}
|
|
7103
7141
|
const schemas = [];
|
|
7104
7142
|
for (const [modelName, modelDef] of Object.entries(models)) {
|
|
7143
|
+
checkUnknownKeys(
|
|
7144
|
+
modelDef,
|
|
7145
|
+
KNOWN_MODEL_KEYS,
|
|
7146
|
+
`[models.${modelName}]`,
|
|
7147
|
+
strict
|
|
7148
|
+
);
|
|
7105
7149
|
const fields = {};
|
|
7106
7150
|
if (modelDef.fields) {
|
|
7107
7151
|
for (const [fieldName, fieldDef] of Object.entries(modelDef.fields)) {
|
|
7108
|
-
fields[fieldName] = parseFieldOptions(
|
|
7152
|
+
fields[fieldName] = parseFieldOptions(
|
|
7153
|
+
fieldDef,
|
|
7154
|
+
`[models.${modelName}.fields.${fieldName}]`,
|
|
7155
|
+
strict
|
|
7156
|
+
);
|
|
7109
7157
|
}
|
|
7110
7158
|
}
|
|
7111
7159
|
let relationships;
|
|
@@ -7114,24 +7162,36 @@ function loadSchemaFromTomlString(tomlString) {
|
|
|
7114
7162
|
for (const [relName, relDef] of Object.entries(
|
|
7115
7163
|
modelDef.relationships
|
|
7116
7164
|
)) {
|
|
7117
|
-
relationships[relName] = parseRelationship(
|
|
7165
|
+
relationships[relName] = parseRelationship(
|
|
7166
|
+
relDef,
|
|
7167
|
+
`[models.${modelName}.relationships.${relName}]`,
|
|
7168
|
+
strict
|
|
7169
|
+
);
|
|
7118
7170
|
}
|
|
7119
7171
|
}
|
|
7120
7172
|
let uniqueConstraints;
|
|
7121
7173
|
if (modelDef.unique_constraints) {
|
|
7122
7174
|
uniqueConstraints = [];
|
|
7123
7175
|
for (const raw of modelDef.unique_constraints) {
|
|
7176
|
+
checkUnknownKeys(
|
|
7177
|
+
raw,
|
|
7178
|
+
KNOWN_UNIQUE_CONSTRAINT_KEYS,
|
|
7179
|
+
`[[models.${modelName}.unique_constraints]]`,
|
|
7180
|
+
strict
|
|
7181
|
+
);
|
|
7124
7182
|
uniqueConstraints.push({
|
|
7125
7183
|
name: raw.name,
|
|
7126
7184
|
fields: [...raw.fields]
|
|
7127
7185
|
});
|
|
7128
7186
|
}
|
|
7129
7187
|
}
|
|
7188
|
+
const className = typeof modelDef.class_name === "string" ? modelDef.class_name : void 0;
|
|
7130
7189
|
schemas.push(
|
|
7131
7190
|
defineModelSchema({
|
|
7132
7191
|
name: modelName,
|
|
7133
7192
|
fields,
|
|
7134
7193
|
options: {
|
|
7194
|
+
className,
|
|
7135
7195
|
uniqueConstraints,
|
|
7136
7196
|
relationships
|
|
7137
7197
|
}
|
|
@@ -7140,10 +7200,10 @@ function loadSchemaFromTomlString(tomlString) {
|
|
|
7140
7200
|
}
|
|
7141
7201
|
return schemas;
|
|
7142
7202
|
}
|
|
7143
|
-
async function loadSchemaFromToml(filePath) {
|
|
7203
|
+
async function loadSchemaFromToml(filePath, options = {}) {
|
|
7144
7204
|
const { readFile } = await import("fs/promises");
|
|
7145
7205
|
const content = await readFile(filePath, "utf-8");
|
|
7146
|
-
return loadSchemaFromTomlString(content);
|
|
7206
|
+
return loadSchemaFromTomlString(content, options);
|
|
7147
7207
|
}
|
|
7148
7208
|
|
|
7149
7209
|
// src/utils/yDocSchema.ts
|
package/dist/node.cjs
CHANGED
|
@@ -6965,6 +6965,7 @@ function defineModelSchema(input) {
|
|
|
6965
6965
|
const { name, fields } = input;
|
|
6966
6966
|
const options = {
|
|
6967
6967
|
name,
|
|
6968
|
+
className: input.options?.className,
|
|
6968
6969
|
uniqueConstraints: input.options?.uniqueConstraints ? [...input.options.uniqueConstraints] : void 0,
|
|
6969
6970
|
relationships: input.options?.relationships
|
|
6970
6971
|
};
|
|
@@ -7064,18 +7065,13 @@ function resolveUniqueConstraints(modelName, fields, customConstraints) {
|
|
|
7064
7065
|
function attachSchemaToClass(modelClass, schema) {
|
|
7065
7066
|
modelClass.schema = schema;
|
|
7066
7067
|
modelClass.modelName = schema.options.name;
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
value: function() {
|
|
7070
|
-
return schema.buildRuntimeShape(modelClass);
|
|
7071
|
-
},
|
|
7072
|
-
writable: false
|
|
7073
|
-
});
|
|
7074
|
-
} else {
|
|
7075
|
-
modelClass.getSchema = function() {
|
|
7068
|
+
Object.defineProperty(modelClass, "getSchema", {
|
|
7069
|
+
value: function() {
|
|
7076
7070
|
return schema.buildRuntimeShape(modelClass);
|
|
7077
|
-
}
|
|
7078
|
-
|
|
7071
|
+
},
|
|
7072
|
+
writable: false,
|
|
7073
|
+
configurable: true
|
|
7074
|
+
});
|
|
7079
7075
|
const runtimeShape = schema.buildRuntimeShape(modelClass);
|
|
7080
7076
|
BaseModel2.attachFieldAccessors(modelClass, runtimeShape.fields);
|
|
7081
7077
|
return runtimeShape;
|
|
@@ -7308,12 +7304,52 @@ var VALID_FIELD_TYPES = /* @__PURE__ */ new Set([
|
|
|
7308
7304
|
"id",
|
|
7309
7305
|
"stringset"
|
|
7310
7306
|
]);
|
|
7311
|
-
|
|
7307
|
+
var KNOWN_FIELD_KEYS = /* @__PURE__ */ new Set([
|
|
7308
|
+
"type",
|
|
7309
|
+
"indexed",
|
|
7310
|
+
"unique",
|
|
7311
|
+
"required",
|
|
7312
|
+
"auto_assign",
|
|
7313
|
+
"max_length",
|
|
7314
|
+
"max_count",
|
|
7315
|
+
"default"
|
|
7316
|
+
]);
|
|
7317
|
+
var KNOWN_MODEL_KEYS = /* @__PURE__ */ new Set([
|
|
7318
|
+
"fields",
|
|
7319
|
+
"relationships",
|
|
7320
|
+
"unique_constraints",
|
|
7321
|
+
"class_name"
|
|
7322
|
+
]);
|
|
7323
|
+
var KNOWN_RELATIONSHIP_KEYS = /* @__PURE__ */ new Set([
|
|
7324
|
+
"type",
|
|
7325
|
+
"model",
|
|
7326
|
+
"related_id_field",
|
|
7327
|
+
"join_model",
|
|
7328
|
+
"join_model_local_field",
|
|
7329
|
+
"join_model_related_field",
|
|
7330
|
+
"order_by_field",
|
|
7331
|
+
"order_direction",
|
|
7332
|
+
"join_model_order_by_field",
|
|
7333
|
+
"join_model_order_direction"
|
|
7334
|
+
]);
|
|
7335
|
+
var KNOWN_UNIQUE_CONSTRAINT_KEYS = /* @__PURE__ */ new Set(["name", "fields"]);
|
|
7336
|
+
function checkUnknownKeys(raw, known, context, strict) {
|
|
7337
|
+
if (!strict) return;
|
|
7338
|
+
for (const key of Object.keys(raw)) {
|
|
7339
|
+
if (!known.has(key)) {
|
|
7340
|
+
throw new Error(
|
|
7341
|
+
`${context}: unknown key "${key}". Allowed: ${[...known].join(", ")}`
|
|
7342
|
+
);
|
|
7343
|
+
}
|
|
7344
|
+
}
|
|
7345
|
+
}
|
|
7346
|
+
function parseFieldOptions(raw, context, strict) {
|
|
7312
7347
|
if (!raw.type || !VALID_FIELD_TYPES.has(raw.type)) {
|
|
7313
7348
|
throw new Error(
|
|
7314
7349
|
`Invalid field type "${raw.type}". Must be one of: ${[...VALID_FIELD_TYPES].join(", ")}`
|
|
7315
7350
|
);
|
|
7316
7351
|
}
|
|
7352
|
+
checkUnknownKeys(raw, KNOWN_FIELD_KEYS, context, strict);
|
|
7317
7353
|
const opts = { type: raw.type };
|
|
7318
7354
|
if (raw.indexed === true) opts.indexed = true;
|
|
7319
7355
|
if (raw.unique === true) opts.unique = true;
|
|
@@ -7329,8 +7365,9 @@ function requireField(raw, field, context) {
|
|
|
7329
7365
|
throw new Error(`Relationship ${context}: missing required field "${field}"`);
|
|
7330
7366
|
}
|
|
7331
7367
|
}
|
|
7332
|
-
function parseRelationship(raw) {
|
|
7368
|
+
function parseRelationship(raw, context, strict) {
|
|
7333
7369
|
const type = raw.type;
|
|
7370
|
+
checkUnknownKeys(raw, KNOWN_RELATIONSHIP_KEYS, context, strict);
|
|
7334
7371
|
if (type === "refersTo") {
|
|
7335
7372
|
requireField(raw, "model", "refersTo");
|
|
7336
7373
|
requireField(raw, "related_id_field", "refersTo");
|
|
@@ -7372,7 +7409,8 @@ function parseRelationship(raw) {
|
|
|
7372
7409
|
}
|
|
7373
7410
|
throw new Error(`Unknown relationship type: ${type}`);
|
|
7374
7411
|
}
|
|
7375
|
-
function loadSchemaFromTomlString(tomlString) {
|
|
7412
|
+
function loadSchemaFromTomlString(tomlString, options = {}) {
|
|
7413
|
+
const strict = options.strict !== false;
|
|
7376
7414
|
const parsed = (0, import_smol_toml.parse)(tomlString);
|
|
7377
7415
|
const models = parsed.models;
|
|
7378
7416
|
if (!models || typeof models !== "object") {
|
|
@@ -7380,10 +7418,20 @@ function loadSchemaFromTomlString(tomlString) {
|
|
|
7380
7418
|
}
|
|
7381
7419
|
const schemas = [];
|
|
7382
7420
|
for (const [modelName, modelDef] of Object.entries(models)) {
|
|
7421
|
+
checkUnknownKeys(
|
|
7422
|
+
modelDef,
|
|
7423
|
+
KNOWN_MODEL_KEYS,
|
|
7424
|
+
`[models.${modelName}]`,
|
|
7425
|
+
strict
|
|
7426
|
+
);
|
|
7383
7427
|
const fields = {};
|
|
7384
7428
|
if (modelDef.fields) {
|
|
7385
7429
|
for (const [fieldName, fieldDef] of Object.entries(modelDef.fields)) {
|
|
7386
|
-
fields[fieldName] = parseFieldOptions(
|
|
7430
|
+
fields[fieldName] = parseFieldOptions(
|
|
7431
|
+
fieldDef,
|
|
7432
|
+
`[models.${modelName}.fields.${fieldName}]`,
|
|
7433
|
+
strict
|
|
7434
|
+
);
|
|
7387
7435
|
}
|
|
7388
7436
|
}
|
|
7389
7437
|
let relationships;
|
|
@@ -7392,24 +7440,36 @@ function loadSchemaFromTomlString(tomlString) {
|
|
|
7392
7440
|
for (const [relName, relDef] of Object.entries(
|
|
7393
7441
|
modelDef.relationships
|
|
7394
7442
|
)) {
|
|
7395
|
-
relationships[relName] = parseRelationship(
|
|
7443
|
+
relationships[relName] = parseRelationship(
|
|
7444
|
+
relDef,
|
|
7445
|
+
`[models.${modelName}.relationships.${relName}]`,
|
|
7446
|
+
strict
|
|
7447
|
+
);
|
|
7396
7448
|
}
|
|
7397
7449
|
}
|
|
7398
7450
|
let uniqueConstraints;
|
|
7399
7451
|
if (modelDef.unique_constraints) {
|
|
7400
7452
|
uniqueConstraints = [];
|
|
7401
7453
|
for (const raw of modelDef.unique_constraints) {
|
|
7454
|
+
checkUnknownKeys(
|
|
7455
|
+
raw,
|
|
7456
|
+
KNOWN_UNIQUE_CONSTRAINT_KEYS,
|
|
7457
|
+
`[[models.${modelName}.unique_constraints]]`,
|
|
7458
|
+
strict
|
|
7459
|
+
);
|
|
7402
7460
|
uniqueConstraints.push({
|
|
7403
7461
|
name: raw.name,
|
|
7404
7462
|
fields: [...raw.fields]
|
|
7405
7463
|
});
|
|
7406
7464
|
}
|
|
7407
7465
|
}
|
|
7466
|
+
const className = typeof modelDef.class_name === "string" ? modelDef.class_name : void 0;
|
|
7408
7467
|
schemas.push(
|
|
7409
7468
|
defineModelSchema({
|
|
7410
7469
|
name: modelName,
|
|
7411
7470
|
fields,
|
|
7412
7471
|
options: {
|
|
7472
|
+
className,
|
|
7413
7473
|
uniqueConstraints,
|
|
7414
7474
|
relationships
|
|
7415
7475
|
}
|
|
@@ -7418,10 +7478,10 @@ function loadSchemaFromTomlString(tomlString) {
|
|
|
7418
7478
|
}
|
|
7419
7479
|
return schemas;
|
|
7420
7480
|
}
|
|
7421
|
-
async function loadSchemaFromToml(filePath) {
|
|
7481
|
+
async function loadSchemaFromToml(filePath, options = {}) {
|
|
7422
7482
|
const { readFile } = await import("fs/promises");
|
|
7423
7483
|
const content = await readFile(filePath, "utf-8");
|
|
7424
|
-
return loadSchemaFromTomlString(content);
|
|
7484
|
+
return loadSchemaFromTomlString(content, options);
|
|
7425
7485
|
}
|
|
7426
7486
|
|
|
7427
7487
|
// src/node.ts
|