bigal 16.0.0-beta.1 → 16.0.0-beta.3
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/CHANGELOG.md +12 -0
- package/dist/index.cjs +31 -20
- package/dist/index.d.cts +210 -168
- package/dist/index.d.mts +210 -168
- package/dist/index.d.ts +210 -168
- package/dist/index.mjs +31 -20
- package/docs/getting-started.md +1 -1
- package/docs/guide/crud-operations.md +1 -1
- package/docs/guide/migration-v16.md +11 -25
- package/docs/guide/models.md +9 -11
- package/docs/guide/querying.md +15 -0
- package/docs/guide/relationships.md +26 -11
- package/docs/guide/views.md +1 -1
- package/docs/index.md +1 -1
- package/docs/reference/api.md +12 -10
- package/package.json +14 -9
- package/scripts/migrate-v16.ts +99 -5
- package/skills/upgrade-v16/SKILL.md +91 -15
- package/skills/using-bigal/SKILL.md +15 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [16.0.0-beta.3](https://github.com/bigalorm/bigal/compare/v16.0.0-beta.2...v16.0.0-beta.3) (2026-04-08)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
- Readonly enum arrays, JSONB string operators, codemod improvements, and table() export ([81629fa](https://github.com/bigalorm/bigal/commit/81629fa9dea7d56b223c477a139ca46be1016f16))
|
|
6
|
+
|
|
7
|
+
## [16.0.0-beta.2](https://github.com/bigalorm/bigal/compare/v16.0.0-beta.1...v16.0.0-beta.2) (2026-03-24)
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
- Type-safe populate, EntityOrId, and model registry ([1d68830](https://github.com/bigalorm/bigal/commit/1d688306e1574ae4f3275700c1325b7410daadf3))
|
|
12
|
+
|
|
1
13
|
## [16.0.0-beta.1](https://github.com/bigalorm/bigal/compare/v15.11.4...v16.0.0-beta.1) (2026-03-23)
|
|
2
14
|
|
|
3
15
|
### ⚠ BREAKING CHANGES
|
package/dist/index.cjs
CHANGED
|
@@ -1929,8 +1929,9 @@ function buildJsonAccessor(columnName, path) {
|
|
|
1929
1929
|
}
|
|
1930
1930
|
return result;
|
|
1931
1931
|
}
|
|
1932
|
+
const JSON_CONSTRAINT_OPERATORS = /* @__PURE__ */ new Set(["!", "<", "<=", ">", ">=", "contains", "startsWith", "endsWith", "like"]);
|
|
1932
1933
|
function isJsonConstraintOperator(key) {
|
|
1933
|
-
return key
|
|
1934
|
+
return JSON_CONSTRAINT_OPERATORS.has(key);
|
|
1934
1935
|
}
|
|
1935
1936
|
function buildJsonPropertyClause({
|
|
1936
1937
|
columnName,
|
|
@@ -1973,6 +1974,24 @@ function buildJsonPropertyClause({
|
|
|
1973
1974
|
const castAccessor2 = castSuffix2 ? `(${accessor2})${castSuffix2}` : accessor2;
|
|
1974
1975
|
const effectiveOperator = isNegated ? negatedComparisonOperators[operator] : operator;
|
|
1975
1976
|
clauses2.push(`${castAccessor2}${effectiveOperator}$${params.length}`);
|
|
1977
|
+
} else if (operator === "contains" || operator === "startsWith" || operator === "endsWith" || operator === "like") {
|
|
1978
|
+
const ilikeValues = Array.isArray(operatorValue) ? operatorValue : [operatorValue];
|
|
1979
|
+
const ilikeClauses = [];
|
|
1980
|
+
for (const ilikeValue of ilikeValues) {
|
|
1981
|
+
let pattern;
|
|
1982
|
+
if (operator === "contains") {
|
|
1983
|
+
pattern = `%${ilikeValue}%`;
|
|
1984
|
+
} else if (operator === "startsWith") {
|
|
1985
|
+
pattern = `${ilikeValue}%`;
|
|
1986
|
+
} else if (operator === "endsWith") {
|
|
1987
|
+
pattern = `%${ilikeValue}`;
|
|
1988
|
+
} else {
|
|
1989
|
+
pattern = ilikeValue;
|
|
1990
|
+
}
|
|
1991
|
+
params.push(pattern);
|
|
1992
|
+
ilikeClauses.push(`${accessor2} ${isNegated ? "NOT ILIKE" : "ILIKE"} $${params.length}`);
|
|
1993
|
+
}
|
|
1994
|
+
clauses2.push(ilikeClauses.length === 1 ? ilikeClauses[0] : `(${ilikeClauses.join(" OR ")})`);
|
|
1976
1995
|
}
|
|
1977
1996
|
}
|
|
1978
1997
|
return clauses2.join(" AND ");
|
|
@@ -2387,6 +2406,7 @@ class ReadonlyRepository {
|
|
|
2387
2406
|
* @param {string|object} [args.sort] - Property name(s) to sort by
|
|
2388
2407
|
* @returns Database record or null
|
|
2389
2408
|
*/
|
|
2409
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- runtime; IReadonlyRepository interface provides typed generics
|
|
2390
2410
|
findOne(args = {}) {
|
|
2391
2411
|
const { stack } = new Error(`${this.model.name}.findOne()`);
|
|
2392
2412
|
let select;
|
|
@@ -2464,6 +2484,7 @@ class ReadonlyRepository {
|
|
|
2464
2484
|
* @param {string|number} [options.limit] - Number of results to return
|
|
2465
2485
|
* @returns Query instance
|
|
2466
2486
|
*/
|
|
2487
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- runtime; FindOneResult interface provides type safety for consumers
|
|
2467
2488
|
populate(propertyName, options) {
|
|
2468
2489
|
if (select && !select.has(propertyName)) {
|
|
2469
2490
|
for (const column of modelInstance.model.columns) {
|
|
@@ -2602,6 +2623,7 @@ ${stack ?? ""}`;
|
|
|
2602
2623
|
* @param {string|number} [args.limit] - Number of results to return
|
|
2603
2624
|
* @returns Database records
|
|
2604
2625
|
*/
|
|
2626
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- runtime; IReadonlyRepository interface provides typed generics
|
|
2605
2627
|
find(args = {}) {
|
|
2606
2628
|
const { stack } = new Error(`${this.model.name}.find()`);
|
|
2607
2629
|
let select;
|
|
@@ -2690,6 +2712,7 @@ ${stack ?? ""}`;
|
|
|
2690
2712
|
* @param {string|number} [options.limit] - Number of results to return
|
|
2691
2713
|
* @returns Query instance
|
|
2692
2714
|
*/
|
|
2715
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- runtime; FindResult interface provides type safety for consumers
|
|
2693
2716
|
populate(propertyName, options) {
|
|
2694
2717
|
if (select && !select.has(propertyName)) {
|
|
2695
2718
|
for (const column of modelInstance.model.columns) {
|
|
@@ -3619,26 +3642,20 @@ function initialize(options) {
|
|
|
3619
3642
|
}
|
|
3620
3643
|
return instance;
|
|
3621
3644
|
}
|
|
3622
|
-
function resolveModelName$1(ref) {
|
|
3623
|
-
if (typeof ref === "string") {
|
|
3624
|
-
return ref;
|
|
3625
|
-
}
|
|
3626
|
-
return ref().modelName;
|
|
3627
|
-
}
|
|
3628
3645
|
function validateRelationships(model, repositoriesByModelNameLowered) {
|
|
3629
3646
|
for (const entry of model.belongsToEntries) {
|
|
3630
|
-
const modelName =
|
|
3647
|
+
const modelName = entry.builder.modelRef;
|
|
3631
3648
|
if (!repositoriesByModelNameLowered[modelName.toLowerCase()]) {
|
|
3632
3649
|
throw new Error(`belongsTo reference from "${model.modelName}.${entry.propertyName}" points to model "${modelName}" which is not registered`);
|
|
3633
3650
|
}
|
|
3634
3651
|
}
|
|
3635
3652
|
for (const entry of model.hasManyEntries) {
|
|
3636
|
-
const modelName =
|
|
3653
|
+
const modelName = entry.builder.modelRef;
|
|
3637
3654
|
if (!repositoriesByModelNameLowered[modelName.toLowerCase()]) {
|
|
3638
3655
|
throw new Error(`hasMany reference from "${model.modelName}.${entry.propertyName}" points to model "${modelName}" which is not registered`);
|
|
3639
3656
|
}
|
|
3640
3657
|
if (entry.builder.throughRef) {
|
|
3641
|
-
const throughName =
|
|
3658
|
+
const throughName = entry.builder.throughRef;
|
|
3642
3659
|
if (!repositoriesByModelNameLowered[throughName.toLowerCase()]) {
|
|
3643
3660
|
throw new Error(`hasMany.through reference from "${model.modelName}.${entry.propertyName}" points to junction model "${throughName}" which is not registered`);
|
|
3644
3661
|
}
|
|
@@ -4150,12 +4167,6 @@ function hasMany(modelRef) {
|
|
|
4150
4167
|
return new HasManyBuilder(modelRef);
|
|
4151
4168
|
}
|
|
4152
4169
|
|
|
4153
|
-
function resolveModelName(ref) {
|
|
4154
|
-
if (typeof ref === "string") {
|
|
4155
|
-
return ref;
|
|
4156
|
-
}
|
|
4157
|
-
return ref().modelName;
|
|
4158
|
-
}
|
|
4159
4170
|
function buildColumnTypeMetadata(entry, propertyName, tableName) {
|
|
4160
4171
|
return new ColumnTypeMetadata(entry.toColumnTypeMetadataOptions(propertyName, tableName));
|
|
4161
4172
|
}
|
|
@@ -4164,7 +4175,7 @@ function buildColumnModelMetadata(entry, propertyName, tableName) {
|
|
|
4164
4175
|
target: tableName,
|
|
4165
4176
|
name: entry.dbColumnName,
|
|
4166
4177
|
propertyName,
|
|
4167
|
-
model:
|
|
4178
|
+
model: entry.modelRef
|
|
4168
4179
|
});
|
|
4169
4180
|
}
|
|
4170
4181
|
function buildColumnCollectionMetadata(entry, propertyName, tableName) {
|
|
@@ -4175,9 +4186,9 @@ function buildColumnCollectionMetadata(entry, propertyName, tableName) {
|
|
|
4175
4186
|
required: false,
|
|
4176
4187
|
insert: false,
|
|
4177
4188
|
update: false,
|
|
4178
|
-
collection:
|
|
4189
|
+
collection: entry.modelRef,
|
|
4179
4190
|
via: entry.viaPropertyName ?? "",
|
|
4180
|
-
through: entry.throughRef
|
|
4191
|
+
through: entry.throughRef ?? void 0
|
|
4181
4192
|
});
|
|
4182
4193
|
}
|
|
4183
4194
|
function table(tableName, schemaDefinition, options) {
|
|
@@ -4283,7 +4294,6 @@ exports.bytea = bytea;
|
|
|
4283
4294
|
exports.createdAt = createdAt;
|
|
4284
4295
|
exports.date = dateColumn;
|
|
4285
4296
|
exports.dateColumn = dateColumn;
|
|
4286
|
-
exports.defineTable = table;
|
|
4287
4297
|
exports.double = double;
|
|
4288
4298
|
exports.float = float;
|
|
4289
4299
|
exports.hasMany = hasMany;
|
|
@@ -4297,6 +4307,7 @@ exports.real = real;
|
|
|
4297
4307
|
exports.serial = serial;
|
|
4298
4308
|
exports.smallint = smallint;
|
|
4299
4309
|
exports.subquery = subquery;
|
|
4310
|
+
exports.table = table;
|
|
4300
4311
|
exports.text = text;
|
|
4301
4312
|
exports.textArray = textArray;
|
|
4302
4313
|
exports.timestamp = timestamp;
|