@stndrds/schema 0.1.0-alpha.20 → 0.1.0-alpha.22
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/chunk-3RVLIIUK.mjs +9257 -0
- package/dist/chunk-6FNFXEQY.mjs +9316 -0
- package/dist/chunk-6TJR4WDK.mjs +9262 -0
- package/dist/chunk-7GLSGSUP.mjs +9456 -0
- package/dist/chunk-B74KNXDP.mjs +9457 -0
- package/dist/chunk-F27AKBTL.mjs +9452 -0
- package/dist/chunk-HSNBVKQU.mjs +9316 -0
- package/dist/chunk-IKUIWNHZ.mjs +9460 -0
- package/dist/chunk-JJLODIBK.mjs +9389 -0
- package/dist/chunk-MAXEN3GU.mjs +9266 -0
- package/dist/chunk-ZD3BFM25.mjs +9316 -0
- package/dist/index.d.mts +3 -197
- package/dist/index.d.ts +3 -197
- package/dist/index.js +632 -21
- package/dist/index.mjs +21 -1
- package/dist/runtime-0gaIqXql.d.mts +7074 -0
- package/dist/runtime-0gaIqXql.d.ts +7074 -0
- package/dist/runtime-3u5doYAK.d.mts +6934 -0
- package/dist/runtime-3u5doYAK.d.ts +6934 -0
- package/dist/runtime-B6mOrMV4.d.mts +6985 -0
- package/dist/runtime-B6mOrMV4.d.ts +6985 -0
- package/dist/runtime-BNML-fPx.d.mts +6969 -0
- package/dist/runtime-BNML-fPx.d.ts +6969 -0
- package/dist/runtime-BPdsKDJo.d.mts +6969 -0
- package/dist/runtime-BPdsKDJo.d.ts +6969 -0
- package/dist/runtime-BZZRu7A1.d.mts +7083 -0
- package/dist/runtime-BZZRu7A1.d.ts +7083 -0
- package/dist/runtime-CmYcicVr.d.mts +7083 -0
- package/dist/runtime-CmYcicVr.d.ts +7083 -0
- package/dist/runtime-D1jyS1lS.d.mts +7008 -0
- package/dist/runtime-D1jyS1lS.d.ts +7008 -0
- package/dist/runtime-DjEUAeL4.d.mts +6713 -0
- package/dist/runtime-DjEUAeL4.d.ts +6713 -0
- package/dist/runtime-rTM9ddEe.d.mts +6934 -0
- package/dist/runtime-rTM9ddEe.d.ts +6934 -0
- package/dist/runtime-xLzAkAnp.d.mts +6969 -0
- package/dist/runtime-xLzAkAnp.d.ts +6969 -0
- package/dist/runtime.d.mts +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +620 -21
- package/dist/runtime.mjs +17 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -159,6 +159,9 @@ __export(index_exports, {
|
|
|
159
159
|
PermissionService: () => PermissionService,
|
|
160
160
|
ProtectedResourceError: () => ProtectedResourceError,
|
|
161
161
|
ProtectedRoleError: () => ProtectedRoleError,
|
|
162
|
+
QueryBuilder: () => QueryBuilder,
|
|
163
|
+
QueryMultipleResultsError: () => QueryMultipleResultsError,
|
|
164
|
+
QueryNoResultError: () => QueryNoResultError,
|
|
162
165
|
RecordNotFoundError: () => RecordNotFoundError,
|
|
163
166
|
RecordReferencedError: () => RecordReferencedError,
|
|
164
167
|
RecordService: () => RecordService,
|
|
@@ -167,6 +170,8 @@ __export(index_exports, {
|
|
|
167
170
|
RoleNotFoundError: () => RoleNotFoundError,
|
|
168
171
|
RollupScheduler: () => RollupScheduler,
|
|
169
172
|
RollupService: () => RollupService,
|
|
173
|
+
SHORTCUT_TO_FILTER_OPERATOR: () => SHORTCUT_TO_FILTER_OPERATOR,
|
|
174
|
+
SYSTEM_FIELD_NAMES: () => SYSTEM_FIELD_NAMES,
|
|
170
175
|
SYSTEM_RESOURCES: () => SYSTEM_RESOURCES,
|
|
171
176
|
SYSTEM_RESOURCE_LABELS: () => SYSTEM_RESOURCE_LABELS,
|
|
172
177
|
SchemaError: () => SchemaError,
|
|
@@ -189,6 +194,7 @@ __export(index_exports, {
|
|
|
189
194
|
createCheckboxValidator: () => createCheckboxValidator,
|
|
190
195
|
createCurrencyValidator: () => createCurrencyValidator,
|
|
191
196
|
createDateValidator: () => createDateValidator,
|
|
197
|
+
createDefaultState: () => createDefaultState,
|
|
192
198
|
createDraftValidator: () => createDraftValidator,
|
|
193
199
|
createFileValidator: () => createFileValidator,
|
|
194
200
|
createFormulaValidator: () => createFormulaValidator,
|
|
@@ -199,6 +205,7 @@ __export(index_exports, {
|
|
|
199
205
|
createNumberValidator: () => createNumberValidator,
|
|
200
206
|
createObjectValidator: () => createObjectValidator,
|
|
201
207
|
createPhoneValidator: () => createPhoneValidator,
|
|
208
|
+
createQueryBuilder: () => createQueryBuilder,
|
|
202
209
|
createRatingValidator: () => createRatingValidator,
|
|
203
210
|
createRelationValidator: () => createRelationValidator,
|
|
204
211
|
createRollupValidator: () => createRollupValidator,
|
|
@@ -228,6 +235,8 @@ __export(index_exports, {
|
|
|
228
235
|
flow: () => flow,
|
|
229
236
|
formatAttributeValue: () => formatAttributeValue,
|
|
230
237
|
formatFormulaResult: () => formatFormulaResult,
|
|
238
|
+
formatRecord: () => formatRecord,
|
|
239
|
+
formatRecords: () => formatRecords,
|
|
231
240
|
formula: () => formula,
|
|
232
241
|
formulaConfigSchema: () => formulaConfigSchema,
|
|
233
242
|
generateId: () => generateId,
|
|
@@ -482,6 +491,9 @@ var NoopGeocodingAdapter = class {
|
|
|
482
491
|
}
|
|
483
492
|
};
|
|
484
493
|
|
|
494
|
+
// src/types/inference.ts
|
|
495
|
+
var SYSTEM_FIELD_NAMES = ["id", "createdAt", "updatedAt"];
|
|
496
|
+
|
|
485
497
|
// src/types/views.ts
|
|
486
498
|
function isFormTab(tab) {
|
|
487
499
|
return tab.type === "form";
|
|
@@ -889,6 +901,7 @@ var VALID_ICONS = new Set(import_constants2.ICONS);
|
|
|
889
901
|
var ATTRIBUTE_NAME_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
890
902
|
var MAX_NAME_LENGTH = 63;
|
|
891
903
|
var MAX_LABEL_LENGTH = 128;
|
|
904
|
+
var RESERVED_ATTRIBUTE_NAMES = ["id", "createdAt", "updatedAt", "metadata"];
|
|
892
905
|
function validateAttributeName(name) {
|
|
893
906
|
if (!name || name.length === 0) {
|
|
894
907
|
throw new Error("[AttributeBuilder] Attribute name cannot be empty");
|
|
@@ -903,6 +916,12 @@ function validateAttributeName(name) {
|
|
|
903
916
|
"[AttributeBuilder] Invalid attribute name format.\nName must be a valid variable identifier:\n \u2705 Valid: 'firstName', 'first_name', 'FirstName', 'FIRST_NAME'\n \u274C Invalid: 'first-name', 'first name', '123name', 'first.name'"
|
|
904
917
|
);
|
|
905
918
|
}
|
|
919
|
+
if (RESERVED_ATTRIBUTE_NAMES.includes(name)) {
|
|
920
|
+
throw new Error(
|
|
921
|
+
`[AttributeBuilder] "${name}" is a reserved name and cannot be used as an attribute name.
|
|
922
|
+
Reserved names: ${RESERVED_ATTRIBUTE_NAMES.join(", ")}`
|
|
923
|
+
);
|
|
924
|
+
}
|
|
906
925
|
}
|
|
907
926
|
function validateLabel(label) {
|
|
908
927
|
if (!label || label.length === 0) {
|
|
@@ -3057,7 +3076,7 @@ function createCheckboxValidator(_attr) {
|
|
|
3057
3076
|
return import_zod4.z.boolean();
|
|
3058
3077
|
}
|
|
3059
3078
|
function createDateValidator(attr) {
|
|
3060
|
-
return import_zod4.z.
|
|
3079
|
+
return import_zod4.z.coerce.date({ message: `${attr.label} must be a valid ISO date` });
|
|
3061
3080
|
}
|
|
3062
3081
|
function createPhoneValidator(_attr) {
|
|
3063
3082
|
return import_zod4.z.object({
|
|
@@ -3163,7 +3182,7 @@ function createRelationValidator(attr) {
|
|
|
3163
3182
|
return createSingleRelationValidator(attr);
|
|
3164
3183
|
}
|
|
3165
3184
|
function createRatingValidator(attr) {
|
|
3166
|
-
let schema = import_zod4.z.number().
|
|
3185
|
+
let schema = import_zod4.z.number().min(0);
|
|
3167
3186
|
if (attr.max !== void 0) {
|
|
3168
3187
|
schema = schema.max(attr.max, `${attr.label} must be at most ${attr.max}`);
|
|
3169
3188
|
}
|
|
@@ -3336,6 +3355,477 @@ function computeRecordStatus(objectDef, data) {
|
|
|
3336
3355
|
return isRecordComplete(objectDef, data) ? "complete" : "draft";
|
|
3337
3356
|
}
|
|
3338
3357
|
|
|
3358
|
+
// src/runtime/client/types.ts
|
|
3359
|
+
function formatRecord(record) {
|
|
3360
|
+
return {
|
|
3361
|
+
id: record.id,
|
|
3362
|
+
createdAt: record.createdAt,
|
|
3363
|
+
updatedAt: record.updatedAt,
|
|
3364
|
+
metadata: record.metadata ?? {},
|
|
3365
|
+
...record.values
|
|
3366
|
+
};
|
|
3367
|
+
}
|
|
3368
|
+
function formatRecords(records) {
|
|
3369
|
+
return records.map((r) => formatRecord(r));
|
|
3370
|
+
}
|
|
3371
|
+
function createDefaultState(objectName) {
|
|
3372
|
+
return {
|
|
3373
|
+
objectName,
|
|
3374
|
+
filters: [],
|
|
3375
|
+
combinator: "and",
|
|
3376
|
+
sorts: [],
|
|
3377
|
+
raw: false,
|
|
3378
|
+
includeDeleted: false
|
|
3379
|
+
};
|
|
3380
|
+
}
|
|
3381
|
+
var SHORTCUT_TO_FILTER_OPERATOR = {
|
|
3382
|
+
eq: "is",
|
|
3383
|
+
neq: "is_not",
|
|
3384
|
+
gt: "gt",
|
|
3385
|
+
gte: "gte",
|
|
3386
|
+
lt: "lt",
|
|
3387
|
+
lte: "lte",
|
|
3388
|
+
contains: "contains",
|
|
3389
|
+
notContains: "not_contains",
|
|
3390
|
+
startsWith: "starts_with",
|
|
3391
|
+
endsWith: "ends_with",
|
|
3392
|
+
isEmpty: "is_empty",
|
|
3393
|
+
isNotEmpty: "is_not_empty"
|
|
3394
|
+
};
|
|
3395
|
+
var QueryNoResultError = class extends Error {
|
|
3396
|
+
constructor(objectName, filters) {
|
|
3397
|
+
const filterInfo = filters?.length ? ` with filters: ${JSON.stringify(filters)}` : "";
|
|
3398
|
+
super(`No record found in "${objectName}"${filterInfo}`);
|
|
3399
|
+
this.name = "QueryNoResultError";
|
|
3400
|
+
this.objectName = objectName;
|
|
3401
|
+
this.filters = filters;
|
|
3402
|
+
}
|
|
3403
|
+
};
|
|
3404
|
+
var QueryMultipleResultsError = class extends Error {
|
|
3405
|
+
constructor(objectName, count) {
|
|
3406
|
+
super(
|
|
3407
|
+
`Expected single record in "${objectName}", but found ${count}. Use first() or add more filters.`
|
|
3408
|
+
);
|
|
3409
|
+
this.name = "QueryMultipleResultsError";
|
|
3410
|
+
this.objectName = objectName;
|
|
3411
|
+
this.count = count;
|
|
3412
|
+
}
|
|
3413
|
+
};
|
|
3414
|
+
|
|
3415
|
+
// src/runtime/client/query-builder.ts
|
|
3416
|
+
var QueryBuilder = class _QueryBuilder {
|
|
3417
|
+
constructor(recordService, adapter, objectName, state) {
|
|
3418
|
+
this.objectId = null;
|
|
3419
|
+
this.recordService = recordService;
|
|
3420
|
+
this.adapter = adapter;
|
|
3421
|
+
this.state = {
|
|
3422
|
+
...createDefaultState(objectName),
|
|
3423
|
+
...state
|
|
3424
|
+
};
|
|
3425
|
+
}
|
|
3426
|
+
/**
|
|
3427
|
+
* Clone the builder with new state (immutability pattern)
|
|
3428
|
+
*/
|
|
3429
|
+
clone(updates) {
|
|
3430
|
+
return new _QueryBuilder(this.recordService, this.adapter, this.state.objectName, {
|
|
3431
|
+
...this.state,
|
|
3432
|
+
...updates
|
|
3433
|
+
});
|
|
3434
|
+
}
|
|
3435
|
+
/**
|
|
3436
|
+
* Resolve object name to object ID (cached)
|
|
3437
|
+
*/
|
|
3438
|
+
async resolveObjectId() {
|
|
3439
|
+
if (this.objectId) return this.objectId;
|
|
3440
|
+
const tenantId = this.recordService.tenantId;
|
|
3441
|
+
const dbObject = await this.adapter.objects.findByName(tenantId, this.state.objectName);
|
|
3442
|
+
if (!dbObject) {
|
|
3443
|
+
throw new Error(`Object "${this.state.objectName}" not found`);
|
|
3444
|
+
}
|
|
3445
|
+
this.objectId = dbObject.id;
|
|
3446
|
+
return dbObject.id;
|
|
3447
|
+
}
|
|
3448
|
+
// ============================================================================
|
|
3449
|
+
// FILTER METHODS
|
|
3450
|
+
// ============================================================================
|
|
3451
|
+
/**
|
|
3452
|
+
* Add a filter rule with explicit operator
|
|
3453
|
+
*
|
|
3454
|
+
* @example
|
|
3455
|
+
* ```typescript
|
|
3456
|
+
* qb.where('status', 'is', 'active')
|
|
3457
|
+
* .where('price', 'gte', 100)
|
|
3458
|
+
* ```
|
|
3459
|
+
*/
|
|
3460
|
+
where(attribute, operator, value) {
|
|
3461
|
+
const rule = { attribute, operator, value };
|
|
3462
|
+
return this.clone({
|
|
3463
|
+
filters: [...this.state.filters, rule]
|
|
3464
|
+
});
|
|
3465
|
+
}
|
|
3466
|
+
/**
|
|
3467
|
+
* Set filter combinator (default: 'and')
|
|
3468
|
+
*/
|
|
3469
|
+
or() {
|
|
3470
|
+
return this.clone({ combinator: "or" });
|
|
3471
|
+
}
|
|
3472
|
+
// ============================================================================
|
|
3473
|
+
// SHORTCUT OPERATORS
|
|
3474
|
+
// ============================================================================
|
|
3475
|
+
/**
|
|
3476
|
+
* Equal (is)
|
|
3477
|
+
*/
|
|
3478
|
+
eq(attribute, value) {
|
|
3479
|
+
return this.where(attribute, SHORTCUT_TO_FILTER_OPERATOR.eq, value);
|
|
3480
|
+
}
|
|
3481
|
+
/**
|
|
3482
|
+
* Not equal (is_not)
|
|
3483
|
+
*/
|
|
3484
|
+
neq(attribute, value) {
|
|
3485
|
+
return this.where(attribute, SHORTCUT_TO_FILTER_OPERATOR.neq, value);
|
|
3486
|
+
}
|
|
3487
|
+
/**
|
|
3488
|
+
* Greater than
|
|
3489
|
+
*/
|
|
3490
|
+
gt(attribute, value) {
|
|
3491
|
+
return this.where(attribute, SHORTCUT_TO_FILTER_OPERATOR.gt, value);
|
|
3492
|
+
}
|
|
3493
|
+
/**
|
|
3494
|
+
* Greater than or equal
|
|
3495
|
+
*/
|
|
3496
|
+
gte(attribute, value) {
|
|
3497
|
+
return this.where(attribute, SHORTCUT_TO_FILTER_OPERATOR.gte, value);
|
|
3498
|
+
}
|
|
3499
|
+
/**
|
|
3500
|
+
* Less than
|
|
3501
|
+
*/
|
|
3502
|
+
lt(attribute, value) {
|
|
3503
|
+
return this.where(attribute, SHORTCUT_TO_FILTER_OPERATOR.lt, value);
|
|
3504
|
+
}
|
|
3505
|
+
/**
|
|
3506
|
+
* Less than or equal
|
|
3507
|
+
*/
|
|
3508
|
+
lte(attribute, value) {
|
|
3509
|
+
return this.where(attribute, SHORTCUT_TO_FILTER_OPERATOR.lte, value);
|
|
3510
|
+
}
|
|
3511
|
+
/**
|
|
3512
|
+
* Contains (text/relation)
|
|
3513
|
+
*/
|
|
3514
|
+
contains(attribute, value) {
|
|
3515
|
+
return this.where(attribute, SHORTCUT_TO_FILTER_OPERATOR.contains, value);
|
|
3516
|
+
}
|
|
3517
|
+
/**
|
|
3518
|
+
* Not contains
|
|
3519
|
+
*/
|
|
3520
|
+
notContains(attribute, value) {
|
|
3521
|
+
return this.where(attribute, SHORTCUT_TO_FILTER_OPERATOR.notContains, value);
|
|
3522
|
+
}
|
|
3523
|
+
/**
|
|
3524
|
+
* Starts with (text)
|
|
3525
|
+
*/
|
|
3526
|
+
startsWith(attribute, value) {
|
|
3527
|
+
return this.where(attribute, SHORTCUT_TO_FILTER_OPERATOR.startsWith, value);
|
|
3528
|
+
}
|
|
3529
|
+
/**
|
|
3530
|
+
* Ends with (text)
|
|
3531
|
+
*/
|
|
3532
|
+
endsWith(attribute, value) {
|
|
3533
|
+
return this.where(attribute, SHORTCUT_TO_FILTER_OPERATOR.endsWith, value);
|
|
3534
|
+
}
|
|
3535
|
+
/**
|
|
3536
|
+
* Is empty
|
|
3537
|
+
*/
|
|
3538
|
+
isEmpty(attribute) {
|
|
3539
|
+
return this.where(attribute, SHORTCUT_TO_FILTER_OPERATOR.isEmpty, null);
|
|
3540
|
+
}
|
|
3541
|
+
/**
|
|
3542
|
+
* Is not empty
|
|
3543
|
+
*/
|
|
3544
|
+
isNotEmpty(attribute) {
|
|
3545
|
+
return this.where(attribute, SHORTCUT_TO_FILTER_OPERATOR.isNotEmpty, null);
|
|
3546
|
+
}
|
|
3547
|
+
/**
|
|
3548
|
+
* In list (any_of)
|
|
3549
|
+
*/
|
|
3550
|
+
in(attribute, values) {
|
|
3551
|
+
return this.where(attribute, "any_of", values);
|
|
3552
|
+
}
|
|
3553
|
+
/**
|
|
3554
|
+
* Not in list (none_of)
|
|
3555
|
+
*/
|
|
3556
|
+
notIn(attribute, values) {
|
|
3557
|
+
return this.where(attribute, "none_of", values);
|
|
3558
|
+
}
|
|
3559
|
+
// ============================================================================
|
|
3560
|
+
// SORT & PAGINATION
|
|
3561
|
+
// ============================================================================
|
|
3562
|
+
/**
|
|
3563
|
+
* Add sort rule
|
|
3564
|
+
*/
|
|
3565
|
+
orderBy(attribute, direction = "asc") {
|
|
3566
|
+
return this.clone({
|
|
3567
|
+
sorts: [...this.state.sorts, { attribute, direction }]
|
|
3568
|
+
});
|
|
3569
|
+
}
|
|
3570
|
+
/**
|
|
3571
|
+
* Set limit
|
|
3572
|
+
*/
|
|
3573
|
+
limit(count) {
|
|
3574
|
+
return this.clone({ limit: count });
|
|
3575
|
+
}
|
|
3576
|
+
/**
|
|
3577
|
+
* Set offset
|
|
3578
|
+
*/
|
|
3579
|
+
offset(count) {
|
|
3580
|
+
return this.clone({ offset: count });
|
|
3581
|
+
}
|
|
3582
|
+
/**
|
|
3583
|
+
* Include soft-deleted records
|
|
3584
|
+
*/
|
|
3585
|
+
withDeleted() {
|
|
3586
|
+
return this.clone({ includeDeleted: true });
|
|
3587
|
+
}
|
|
3588
|
+
// ============================================================================
|
|
3589
|
+
// GROUP BY (KANBAN)
|
|
3590
|
+
// ============================================================================
|
|
3591
|
+
/**
|
|
3592
|
+
* Group results by an attribute (for Kanban views).
|
|
3593
|
+
* Only status and select attributes are supported.
|
|
3594
|
+
*
|
|
3595
|
+
* @example
|
|
3596
|
+
* ```typescript
|
|
3597
|
+
* const grouped = await qb
|
|
3598
|
+
* .groupBy('status')
|
|
3599
|
+
* .fetchGrouped();
|
|
3600
|
+
* // → { groups: { 'pending': [...], 'active': [...] }, total: 50 }
|
|
3601
|
+
* ```
|
|
3602
|
+
*/
|
|
3603
|
+
groupBy(attribute) {
|
|
3604
|
+
return this.clone({ groupBy: attribute });
|
|
3605
|
+
}
|
|
3606
|
+
// ============================================================================
|
|
3607
|
+
// RAW MODE
|
|
3608
|
+
// ============================================================================
|
|
3609
|
+
/**
|
|
3610
|
+
* Return raw ObjectRecord instead of formatted record.
|
|
3611
|
+
* Includes all metadata (objectId, label, completionStatus, etc.)
|
|
3612
|
+
*/
|
|
3613
|
+
raw() {
|
|
3614
|
+
return this.clone({ raw: true });
|
|
3615
|
+
}
|
|
3616
|
+
// ============================================================================
|
|
3617
|
+
// TERMINATION METHODS (READ)
|
|
3618
|
+
// ============================================================================
|
|
3619
|
+
/**
|
|
3620
|
+
* Fetch records with current filters
|
|
3621
|
+
* Returns formatted records by default, raw ObjectRecords if raw() was called
|
|
3622
|
+
*/
|
|
3623
|
+
async fetch() {
|
|
3624
|
+
const objectId = await this.resolveObjectId();
|
|
3625
|
+
const filters = this.state.filters.length > 0 ? { combinator: this.state.combinator, rules: this.state.filters } : void 0;
|
|
3626
|
+
const result = await this.recordService.listRecords(objectId, {
|
|
3627
|
+
filters,
|
|
3628
|
+
sorts: this.state.sorts.length > 0 ? this.state.sorts : void 0,
|
|
3629
|
+
limit: this.state.limit,
|
|
3630
|
+
offset: this.state.offset,
|
|
3631
|
+
includeDeleted: this.state.includeDeleted
|
|
3632
|
+
});
|
|
3633
|
+
if (this.state.raw) {
|
|
3634
|
+
return result;
|
|
3635
|
+
}
|
|
3636
|
+
return {
|
|
3637
|
+
records: formatRecords(result.records),
|
|
3638
|
+
total: result.total
|
|
3639
|
+
};
|
|
3640
|
+
}
|
|
3641
|
+
/**
|
|
3642
|
+
* Get a single record (throws if 0 or >1 results)
|
|
3643
|
+
*/
|
|
3644
|
+
async single() {
|
|
3645
|
+
const result = await this.limit(2).fetch();
|
|
3646
|
+
if (result.records.length === 0) {
|
|
3647
|
+
throw new QueryNoResultError(this.state.objectName, this.state.filters);
|
|
3648
|
+
}
|
|
3649
|
+
if (result.records.length > 1) {
|
|
3650
|
+
throw new QueryMultipleResultsError(this.state.objectName, result.total);
|
|
3651
|
+
}
|
|
3652
|
+
return result.records[0];
|
|
3653
|
+
}
|
|
3654
|
+
/**
|
|
3655
|
+
* Get first record or null
|
|
3656
|
+
*/
|
|
3657
|
+
async first() {
|
|
3658
|
+
const result = await this.limit(1).fetch();
|
|
3659
|
+
return result.records[0] ?? null;
|
|
3660
|
+
}
|
|
3661
|
+
/**
|
|
3662
|
+
* Get record by ID
|
|
3663
|
+
*/
|
|
3664
|
+
async findById(id) {
|
|
3665
|
+
const record = await this.recordService.getRecord(id);
|
|
3666
|
+
if (!record) return null;
|
|
3667
|
+
if (this.state.raw) {
|
|
3668
|
+
return record;
|
|
3669
|
+
}
|
|
3670
|
+
return formatRecord(record);
|
|
3671
|
+
}
|
|
3672
|
+
/**
|
|
3673
|
+
* Count records matching filters
|
|
3674
|
+
*/
|
|
3675
|
+
async count() {
|
|
3676
|
+
const result = await this.limit(0).fetch();
|
|
3677
|
+
return result.total;
|
|
3678
|
+
}
|
|
3679
|
+
/**
|
|
3680
|
+
* Fetch records grouped by the groupBy attribute (for Kanban views).
|
|
3681
|
+
* Requires groupBy() to be called first.
|
|
3682
|
+
*
|
|
3683
|
+
* @example
|
|
3684
|
+
* ```typescript
|
|
3685
|
+
* const result = await schema.from('tasks')
|
|
3686
|
+
* .groupBy('status')
|
|
3687
|
+
* .fetchGrouped();
|
|
3688
|
+
* // → { groups: { 'todo': [...], 'in_progress': [...], 'done': [...] }, total: 50 }
|
|
3689
|
+
* ```
|
|
3690
|
+
*/
|
|
3691
|
+
async fetchGrouped() {
|
|
3692
|
+
if (!this.state.groupBy) {
|
|
3693
|
+
throw new Error("groupBy() must be called before fetchGrouped()");
|
|
3694
|
+
}
|
|
3695
|
+
const result = await this.fetch();
|
|
3696
|
+
const groupByAttr = this.state.groupBy;
|
|
3697
|
+
const groups = {};
|
|
3698
|
+
for (const record of result.records) {
|
|
3699
|
+
const value = record[groupByAttr];
|
|
3700
|
+
const key = value != null ? String(value) : "__null__";
|
|
3701
|
+
if (!groups[key]) {
|
|
3702
|
+
groups[key] = [];
|
|
3703
|
+
}
|
|
3704
|
+
groups[key].push(record);
|
|
3705
|
+
}
|
|
3706
|
+
return {
|
|
3707
|
+
groups,
|
|
3708
|
+
total: result.total
|
|
3709
|
+
};
|
|
3710
|
+
}
|
|
3711
|
+
// ============================================================================
|
|
3712
|
+
// TERMINATION METHODS (WRITE)
|
|
3713
|
+
// ============================================================================
|
|
3714
|
+
/**
|
|
3715
|
+
* Create a new record
|
|
3716
|
+
* System fields (id, createdAt, updatedAt) are managed automatically.
|
|
3717
|
+
*
|
|
3718
|
+
* @example
|
|
3719
|
+
* ```typescript
|
|
3720
|
+
* const product = await schema.from('products')
|
|
3721
|
+
* .insert({ name: 'iPhone', price: 999 });
|
|
3722
|
+
*
|
|
3723
|
+
* // Allow draft (missing required fields)
|
|
3724
|
+
* const draft = await schema.from('products')
|
|
3725
|
+
* .insert({ name: 'Draft' }, { allowDraft: true });
|
|
3726
|
+
*
|
|
3727
|
+
* // With custom metadata
|
|
3728
|
+
* const withMeta = await schema.from('products')
|
|
3729
|
+
* .insert({ name: 'iPhone' }, { metadata: { externalId: 'ext-123' } });
|
|
3730
|
+
* ```
|
|
3731
|
+
*/
|
|
3732
|
+
async insert(data, options) {
|
|
3733
|
+
const objectId = await this.resolveObjectId();
|
|
3734
|
+
const record = await this.recordService.createRecord(
|
|
3735
|
+
objectId,
|
|
3736
|
+
data,
|
|
3737
|
+
{
|
|
3738
|
+
allowDraft: options?.allowDraft,
|
|
3739
|
+
validate: options?.validate,
|
|
3740
|
+
metadata: options?.metadata
|
|
3741
|
+
}
|
|
3742
|
+
);
|
|
3743
|
+
if (this.state.raw) {
|
|
3744
|
+
return record;
|
|
3745
|
+
}
|
|
3746
|
+
return formatRecord(record);
|
|
3747
|
+
}
|
|
3748
|
+
/**
|
|
3749
|
+
* Update records matching filters (expects exactly 1 record by default)
|
|
3750
|
+
* Use with eq('id', ...) for single record update.
|
|
3751
|
+
* System fields (id, createdAt, updatedAt) are managed automatically.
|
|
3752
|
+
*
|
|
3753
|
+
* @example
|
|
3754
|
+
* ```typescript
|
|
3755
|
+
* const updated = await schema.from('products')
|
|
3756
|
+
* .eq('id', 'rec-123')
|
|
3757
|
+
* .update({ price: 899 });
|
|
3758
|
+
*
|
|
3759
|
+
* // Update with metadata (merged with existing, set undefined to remove)
|
|
3760
|
+
* const withMeta = await schema.from('products')
|
|
3761
|
+
* .eq('id', 'rec-123')
|
|
3762
|
+
* .update({ price: 899 }, { metadata: { synced: true, oldKey: undefined } });
|
|
3763
|
+
* ```
|
|
3764
|
+
*/
|
|
3765
|
+
async update(data, options) {
|
|
3766
|
+
const existing = await this.single();
|
|
3767
|
+
const recordId = this.state.raw ? existing.id : existing.id;
|
|
3768
|
+
const record = await this.recordService.updateRecord(
|
|
3769
|
+
recordId,
|
|
3770
|
+
data,
|
|
3771
|
+
{
|
|
3772
|
+
partial: true,
|
|
3773
|
+
metadata: options?.metadata
|
|
3774
|
+
}
|
|
3775
|
+
);
|
|
3776
|
+
if (this.state.raw) {
|
|
3777
|
+
return record;
|
|
3778
|
+
}
|
|
3779
|
+
return formatRecord(record);
|
|
3780
|
+
}
|
|
3781
|
+
/**
|
|
3782
|
+
* Delete record matching filters (expects exactly 1 record)
|
|
3783
|
+
*
|
|
3784
|
+
* @example
|
|
3785
|
+
* ```typescript
|
|
3786
|
+
* await schema.from('products')
|
|
3787
|
+
* .eq('id', 'rec-123')
|
|
3788
|
+
* .delete();
|
|
3789
|
+
* ```
|
|
3790
|
+
*/
|
|
3791
|
+
async delete() {
|
|
3792
|
+
const existing = await this.single();
|
|
3793
|
+
const recordId = this.state.raw ? existing.id : existing.id;
|
|
3794
|
+
await this.recordService.deleteRecord(recordId);
|
|
3795
|
+
}
|
|
3796
|
+
/**
|
|
3797
|
+
* Upsert (update if exists by ID, insert otherwise)
|
|
3798
|
+
* Provide 'id' for lookup. System fields (createdAt, updatedAt) are managed automatically.
|
|
3799
|
+
*
|
|
3800
|
+
* @example
|
|
3801
|
+
* ```typescript
|
|
3802
|
+
* // Insert if not exists, update if exists
|
|
3803
|
+
* const product = await schema.from('products')
|
|
3804
|
+
* .upsert({ id: 'rec-123', name: 'iPhone', price: 999 });
|
|
3805
|
+
*
|
|
3806
|
+
* // With metadata
|
|
3807
|
+
* const withMeta = await schema.from('products')
|
|
3808
|
+
* .upsert({ name: 'iPhone' }, { metadata: { source: 'import' } });
|
|
3809
|
+
* ```
|
|
3810
|
+
*/
|
|
3811
|
+
async upsert(data, options) {
|
|
3812
|
+
const { id, ...rest } = data;
|
|
3813
|
+
const writeData = rest;
|
|
3814
|
+
if (id) {
|
|
3815
|
+
const existing = await this.findById(id);
|
|
3816
|
+
if (existing) {
|
|
3817
|
+
return this.eq("id", id).update(writeData, {
|
|
3818
|
+
metadata: options?.metadata
|
|
3819
|
+
});
|
|
3820
|
+
}
|
|
3821
|
+
}
|
|
3822
|
+
return this.insert(writeData, options);
|
|
3823
|
+
}
|
|
3824
|
+
};
|
|
3825
|
+
function createQueryBuilder(recordService, adapter, objectName) {
|
|
3826
|
+
return new QueryBuilder(recordService, adapter, objectName);
|
|
3827
|
+
}
|
|
3828
|
+
|
|
3339
3829
|
// src/runtime/formula/evaluator.ts
|
|
3340
3830
|
var import_expr_eval = require("expr-eval");
|
|
3341
3831
|
function createFormulaParser() {
|
|
@@ -4177,6 +4667,7 @@ function createMockObjectRecordsRepository(stores) {
|
|
|
4177
4667
|
label: data.label,
|
|
4178
4668
|
completionStatus: data.completionStatus,
|
|
4179
4669
|
values: data.data,
|
|
4670
|
+
metadata: data.metadata ?? {},
|
|
4180
4671
|
createdAt: /* @__PURE__ */ new Date(),
|
|
4181
4672
|
updatedAt: /* @__PURE__ */ new Date()
|
|
4182
4673
|
};
|
|
@@ -4189,11 +4680,13 @@ function createMockObjectRecordsRepository(stores) {
|
|
|
4189
4680
|
if (!existing) {
|
|
4190
4681
|
return Promise.reject(new Error(`ObjectRecord ${id} not found`));
|
|
4191
4682
|
}
|
|
4192
|
-
const { __completionStatus, __label, ...valueData } = data;
|
|
4683
|
+
const { __completionStatus, __label, __metadata, ...valueData } = data;
|
|
4193
4684
|
const updated = {
|
|
4194
4685
|
...existing,
|
|
4195
4686
|
label: __label ?? existing.label,
|
|
4196
4687
|
completionStatus: __completionStatus ?? existing.completionStatus,
|
|
4688
|
+
// Metadata uses replace behavior (not merge)
|
|
4689
|
+
metadata: __metadata !== void 0 ? __metadata : existing.metadata,
|
|
4197
4690
|
values: { ...existing.values, ...valueData },
|
|
4198
4691
|
updatedAt: /* @__PURE__ */ new Date()
|
|
4199
4692
|
};
|
|
@@ -5871,7 +6364,7 @@ var GlobalSearchService = class {
|
|
|
5871
6364
|
};
|
|
5872
6365
|
|
|
5873
6366
|
// src/runtime/services/object-schema.service.ts
|
|
5874
|
-
var
|
|
6367
|
+
var _ObjectSchemaService = class _ObjectSchemaService {
|
|
5875
6368
|
constructor(adapter, nativeRegistry, options) {
|
|
5876
6369
|
this.adapter = adapter;
|
|
5877
6370
|
this.nativeRegistry = nativeRegistry;
|
|
@@ -6294,6 +6787,14 @@ var ObjectSchemaService = class {
|
|
|
6294
6787
|
"Invalid attribute name format.\nName must be a valid variable identifier:\n \u2705 Valid: 'firstName', 'first_name', 'FirstName', 'FIRST_NAME'\n \u274C Invalid: 'first-name', 'first name', '123name', 'first.name'"
|
|
6295
6788
|
);
|
|
6296
6789
|
}
|
|
6790
|
+
if (_ObjectSchemaService.RESERVED_ATTRIBUTE_NAMES.includes(
|
|
6791
|
+
name
|
|
6792
|
+
)) {
|
|
6793
|
+
throw new Error(
|
|
6794
|
+
`"${name}" is a reserved name and cannot be used as an attribute name.
|
|
6795
|
+
Reserved names: ${_ObjectSchemaService.RESERVED_ATTRIBUTE_NAMES.join(", ")}`
|
|
6796
|
+
);
|
|
6797
|
+
}
|
|
6297
6798
|
}
|
|
6298
6799
|
/**
|
|
6299
6800
|
* Get complete object schema (system + custom attributes)
|
|
@@ -6540,6 +7041,17 @@ var ObjectSchemaService = class {
|
|
|
6540
7041
|
return baseAttr;
|
|
6541
7042
|
}
|
|
6542
7043
|
};
|
|
7044
|
+
/**
|
|
7045
|
+
* Reserved attribute names that cannot be used.
|
|
7046
|
+
* These names conflict with system fields on ObjectRecord.
|
|
7047
|
+
*/
|
|
7048
|
+
_ObjectSchemaService.RESERVED_ATTRIBUTE_NAMES = [
|
|
7049
|
+
"id",
|
|
7050
|
+
"createdAt",
|
|
7051
|
+
"updatedAt",
|
|
7052
|
+
"metadata"
|
|
7053
|
+
];
|
|
7054
|
+
var ObjectSchemaService = _ObjectSchemaService;
|
|
6543
7055
|
|
|
6544
7056
|
// src/runtime/services/permission.service.ts
|
|
6545
7057
|
var PermissionService = class {
|
|
@@ -7353,6 +7865,9 @@ var RollupService = class {
|
|
|
7353
7865
|
* Extract and aggregate values from related records
|
|
7354
7866
|
*/
|
|
7355
7867
|
aggregateValues(relatedRecords, rollupAttr) {
|
|
7868
|
+
if (rollupAttr.function === "count") {
|
|
7869
|
+
return { value: relatedRecords.length, recordCount: relatedRecords.length };
|
|
7870
|
+
}
|
|
7356
7871
|
const values = relatedRecords.map((r) => r.values[rollupAttr.targetAttribute]).filter((v) => v !== void 0 && v !== null);
|
|
7357
7872
|
const aggregated = this.aggregate(values, rollupAttr.function);
|
|
7358
7873
|
const result = typeof aggregated === "number" && rollupAttr.decimals !== void 0 ? Number(aggregated.toFixed(rollupAttr.decimals)) : aggregated;
|
|
@@ -7501,6 +8016,71 @@ var RollupService = class {
|
|
|
7501
8016
|
}
|
|
7502
8017
|
return [...new Set(affectedIds)];
|
|
7503
8018
|
}
|
|
8019
|
+
/**
|
|
8020
|
+
* Find records that have forward rollups pointing to the modified record.
|
|
8021
|
+
*
|
|
8022
|
+
* Forward rollups are rollups where the record has a relation attribute
|
|
8023
|
+
* pointing to another object, and the rollup aggregates values from that target.
|
|
8024
|
+
* When the target record changes, we need to recalculate these rollups.
|
|
8025
|
+
*
|
|
8026
|
+
* Example: Order has relation "company" → Company, and rollup "capitalSocial"
|
|
8027
|
+
* aggregating from the Company. When Company.capitalSocial changes,
|
|
8028
|
+
* all Orders pointing to that Company need their rollup recalculated.
|
|
8029
|
+
*
|
|
8030
|
+
* @param changedRecord - The record that was modified
|
|
8031
|
+
* @param changedSchema - Schema of the changed record's object
|
|
8032
|
+
* @returns Array of records that need their forward rollups recalculated
|
|
8033
|
+
*/
|
|
8034
|
+
async findRecordsWithForwardRollup(changedRecord, changedSchema) {
|
|
8035
|
+
const affectedRecords = [];
|
|
8036
|
+
const recordObject = await this.adapter.objects.findById(changedRecord.objectId);
|
|
8037
|
+
if (!recordObject) {
|
|
8038
|
+
return affectedRecords;
|
|
8039
|
+
}
|
|
8040
|
+
const tenantId = recordObject.tenantId;
|
|
8041
|
+
const allObjects = await this.adapter.objects.list(tenantId);
|
|
8042
|
+
for (const obj of allObjects) {
|
|
8043
|
+
if (obj.id === changedRecord.objectId) {
|
|
8044
|
+
continue;
|
|
8045
|
+
}
|
|
8046
|
+
const attributes = await this.adapter.attributes.findByObjectId(obj.id);
|
|
8047
|
+
const rollupAttrs = attributes.filter((a) => a.type === "rollup");
|
|
8048
|
+
if (rollupAttrs.length === 0) {
|
|
8049
|
+
continue;
|
|
8050
|
+
}
|
|
8051
|
+
for (const rollupDbAttr of rollupAttrs) {
|
|
8052
|
+
const rollupConfig = rollupDbAttr.config;
|
|
8053
|
+
if (!rollupConfig?.relationAttribute) {
|
|
8054
|
+
continue;
|
|
8055
|
+
}
|
|
8056
|
+
const relationAttr = attributes.find(
|
|
8057
|
+
(a) => a.type === "relation" && a.name === rollupConfig.relationAttribute
|
|
8058
|
+
);
|
|
8059
|
+
if (!relationAttr) {
|
|
8060
|
+
continue;
|
|
8061
|
+
}
|
|
8062
|
+
const relationConfig = relationAttr.config;
|
|
8063
|
+
const targetsChangedObject = relationConfig?.targets?.some(
|
|
8064
|
+
(t) => t.object === changedSchema.name
|
|
8065
|
+
);
|
|
8066
|
+
if (!targetsChangedObject) {
|
|
8067
|
+
continue;
|
|
8068
|
+
}
|
|
8069
|
+
const recordsPointingToChanged = await this.adapter.objectRecords.findByRelation(
|
|
8070
|
+
tenantId,
|
|
8071
|
+
obj.id,
|
|
8072
|
+
relationAttr.name,
|
|
8073
|
+
changedRecord.id
|
|
8074
|
+
);
|
|
8075
|
+
affectedRecords.push(...recordsPointingToChanged);
|
|
8076
|
+
}
|
|
8077
|
+
}
|
|
8078
|
+
const uniqueRecords = /* @__PURE__ */ new Map();
|
|
8079
|
+
for (const record of affectedRecords) {
|
|
8080
|
+
uniqueRecords.set(record.id, record);
|
|
8081
|
+
}
|
|
8082
|
+
return Array.from(uniqueRecords.values());
|
|
8083
|
+
}
|
|
7504
8084
|
};
|
|
7505
8085
|
|
|
7506
8086
|
// src/runtime/services/user.service.ts
|
|
@@ -7625,7 +8205,11 @@ var RecordService = class {
|
|
|
7625
8205
|
constructor(adapter, tenantId, options) {
|
|
7626
8206
|
this.adapter = adapter;
|
|
7627
8207
|
this.tenantId = tenantId;
|
|
7628
|
-
this.schemaService = new ObjectSchemaService(adapter, registry
|
|
8208
|
+
this.schemaService = new ObjectSchemaService(adapter, registry, {
|
|
8209
|
+
userId: options?.userId,
|
|
8210
|
+
userEmail: options?.userEmail,
|
|
8211
|
+
auditService: options?.auditService
|
|
8212
|
+
});
|
|
7629
8213
|
this.relationService = new RelationService(adapter, registry);
|
|
7630
8214
|
this.userService = new UserService(adapter, tenantId);
|
|
7631
8215
|
this.rollupService = new RollupService(adapter);
|
|
@@ -7780,7 +8364,8 @@ var RecordService = class {
|
|
|
7780
8364
|
objectId,
|
|
7781
8365
|
data,
|
|
7782
8366
|
label,
|
|
7783
|
-
completionStatus
|
|
8367
|
+
completionStatus,
|
|
8368
|
+
metadata: options?.metadata
|
|
7784
8369
|
});
|
|
7785
8370
|
if (!options?.skipHooks) {
|
|
7786
8371
|
const afterCtx = {
|
|
@@ -7894,11 +8479,20 @@ var RecordService = class {
|
|
|
7894
8479
|
}
|
|
7895
8480
|
const completionStatus = computeRecordStatus(schema, mergedData);
|
|
7896
8481
|
const label = await this.computeLabel(schema, mergedData);
|
|
7897
|
-
const
|
|
8482
|
+
const updatePayload = {
|
|
7898
8483
|
...data,
|
|
7899
8484
|
__completionStatus: completionStatus,
|
|
7900
8485
|
__label: label
|
|
7901
|
-
}
|
|
8486
|
+
};
|
|
8487
|
+
if (options?.metadata !== void 0) {
|
|
8488
|
+
const existingMetadata = existing.metadata ?? {};
|
|
8489
|
+
const mergedMetadata = { ...existingMetadata, ...options.metadata };
|
|
8490
|
+
const cleanedMetadata = Object.fromEntries(
|
|
8491
|
+
Object.entries(mergedMetadata).filter(([, value]) => value !== void 0)
|
|
8492
|
+
);
|
|
8493
|
+
updatePayload.__metadata = cleanedMetadata;
|
|
8494
|
+
}
|
|
8495
|
+
const updated = await this.adapter.objectRecords.update(recordId, updatePayload);
|
|
7902
8496
|
if (!options?.skipHooks) {
|
|
7903
8497
|
const afterCtx = {
|
|
7904
8498
|
...hookCtx,
|
|
@@ -8167,9 +8761,10 @@ var RecordService = class {
|
|
|
8167
8761
|
/**
|
|
8168
8762
|
* Recalculate rollups after a record changes
|
|
8169
8763
|
*
|
|
8170
|
-
* This handles
|
|
8764
|
+
* This handles three cases:
|
|
8171
8765
|
* 1. The record itself has rollups (e.g., aggregating from related records it points to)
|
|
8172
|
-
* 2. Parent records have rollups that aggregate from this record
|
|
8766
|
+
* 2. Parent records have rollups that aggregate from this record (reverse pattern)
|
|
8767
|
+
* 3. Records that have forward rollups pointing to this record (forward pattern)
|
|
8173
8768
|
*
|
|
8174
8769
|
* @param record - The record that was modified
|
|
8175
8770
|
* @param schema - Schema of the record's object
|
|
@@ -8183,19 +8778,26 @@ var RecordService = class {
|
|
|
8183
8778
|
await this.rollupService.recalculateAndUpdate(record, schema);
|
|
8184
8779
|
}
|
|
8185
8780
|
const affectedParentIds = await this.rollupService.findAffectedParentRecords(record, schema);
|
|
8186
|
-
if (affectedParentIds.length
|
|
8187
|
-
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
(
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
await this.rollupService.recalculateAndUpdate(parentRecord, parentSchema);
|
|
8781
|
+
if (affectedParentIds.length > 0) {
|
|
8782
|
+
const parentRecords = await this.adapter.objectRecords.findByIds(affectedParentIds);
|
|
8783
|
+
for (const parentRecord of parentRecords) {
|
|
8784
|
+
const parentSchema = await this.schemaService.getObjectSchema(parentRecord.objectId);
|
|
8785
|
+
const rollupAttrs = parentSchema.attributes.filter(
|
|
8786
|
+
(a) => a.type === "rollup"
|
|
8787
|
+
);
|
|
8788
|
+
if (rollupAttrs.length > 0) {
|
|
8789
|
+
await this.rollupService.recalculateAndUpdate(parentRecord, parentSchema);
|
|
8790
|
+
}
|
|
8197
8791
|
}
|
|
8198
8792
|
}
|
|
8793
|
+
const affectedForwardRecords = await this.rollupService.findRecordsWithForwardRollup(
|
|
8794
|
+
record,
|
|
8795
|
+
schema
|
|
8796
|
+
);
|
|
8797
|
+
for (const forwardRecord of affectedForwardRecords) {
|
|
8798
|
+
const forwardSchema = await this.schemaService.getObjectSchema(forwardRecord.objectId);
|
|
8799
|
+
await this.rollupService.recalculateAndUpdate(forwardRecord, forwardSchema);
|
|
8800
|
+
}
|
|
8199
8801
|
}
|
|
8200
8802
|
/**
|
|
8201
8803
|
* Permanently delete a record (hard delete)
|
|
@@ -9323,6 +9925,9 @@ async function syncAll(adapter, objectRegistry, nativeViewRegistry, options = {}
|
|
|
9323
9925
|
PermissionService,
|
|
9324
9926
|
ProtectedResourceError,
|
|
9325
9927
|
ProtectedRoleError,
|
|
9928
|
+
QueryBuilder,
|
|
9929
|
+
QueryMultipleResultsError,
|
|
9930
|
+
QueryNoResultError,
|
|
9326
9931
|
RecordNotFoundError,
|
|
9327
9932
|
RecordReferencedError,
|
|
9328
9933
|
RecordService,
|
|
@@ -9331,6 +9936,8 @@ async function syncAll(adapter, objectRegistry, nativeViewRegistry, options = {}
|
|
|
9331
9936
|
RoleNotFoundError,
|
|
9332
9937
|
RollupScheduler,
|
|
9333
9938
|
RollupService,
|
|
9939
|
+
SHORTCUT_TO_FILTER_OPERATOR,
|
|
9940
|
+
SYSTEM_FIELD_NAMES,
|
|
9334
9941
|
SYSTEM_RESOURCES,
|
|
9335
9942
|
SYSTEM_RESOURCE_LABELS,
|
|
9336
9943
|
SchemaError,
|
|
@@ -9353,6 +9960,7 @@ async function syncAll(adapter, objectRegistry, nativeViewRegistry, options = {}
|
|
|
9353
9960
|
createCheckboxValidator,
|
|
9354
9961
|
createCurrencyValidator,
|
|
9355
9962
|
createDateValidator,
|
|
9963
|
+
createDefaultState,
|
|
9356
9964
|
createDraftValidator,
|
|
9357
9965
|
createFileValidator,
|
|
9358
9966
|
createFormulaValidator,
|
|
@@ -9363,6 +9971,7 @@ async function syncAll(adapter, objectRegistry, nativeViewRegistry, options = {}
|
|
|
9363
9971
|
createNumberValidator,
|
|
9364
9972
|
createObjectValidator,
|
|
9365
9973
|
createPhoneValidator,
|
|
9974
|
+
createQueryBuilder,
|
|
9366
9975
|
createRatingValidator,
|
|
9367
9976
|
createRelationValidator,
|
|
9368
9977
|
createRollupValidator,
|
|
@@ -9392,6 +10001,8 @@ async function syncAll(adapter, objectRegistry, nativeViewRegistry, options = {}
|
|
|
9392
10001
|
flow,
|
|
9393
10002
|
formatAttributeValue,
|
|
9394
10003
|
formatFormulaResult,
|
|
10004
|
+
formatRecord,
|
|
10005
|
+
formatRecords,
|
|
9395
10006
|
formula,
|
|
9396
10007
|
formulaConfigSchema,
|
|
9397
10008
|
generateId,
|