@oneuptime/common 7.0.4358 → 7.0.4372
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/Models/AnalyticsModels/ExceptionInstance.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleTeam.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleUser.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyTimeLog.ts +2 -2
- package/Models/DatabaseModels/Probe.ts +7 -1
- package/Models/DatabaseModels/ServiceCatalog.ts +2 -2
- package/Models/DatabaseModels/ServiceCopilotCodeRepository.ts +2 -2
- package/Server/Utils/OpenAPI.ts +564 -2
- package/Utils/Schema/AnalyticsModelSchema.ts +764 -0
- package/Utils/Schema/BaseSchema.ts +450 -0
- package/Utils/Schema/ModelSchema.ts +176 -407
- package/build/dist/Models/AnalyticsModels/ExceptionInstance.js +2 -2
- package/build/dist/Models/AnalyticsModels/ExceptionInstance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleTeam.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleTeam.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleUser.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyEscalationRuleUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Probe.js +7 -1
- package/build/dist/Models/DatabaseModels/Probe.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceCatalog.js +2 -2
- package/build/dist/Models/DatabaseModels/ServiceCatalog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceCopilotCodeRepository.js +2 -2
- package/build/dist/Models/DatabaseModels/ServiceCopilotCodeRepository.js.map +1 -1
- package/build/dist/Server/Utils/OpenAPI.js +445 -2
- package/build/dist/Server/Utils/OpenAPI.js.map +1 -1
- package/build/dist/Utils/Schema/AnalyticsModelSchema.js +636 -0
- package/build/dist/Utils/Schema/AnalyticsModelSchema.js.map +1 -0
- package/build/dist/Utils/Schema/BaseSchema.js +295 -0
- package/build/dist/Utils/Schema/BaseSchema.js.map +1 -0
- package/build/dist/Utils/Schema/ModelSchema.js +155 -337
- package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import z from "./Zod";
|
|
2
2
|
import TableColumnType from "../../Types/Database/TableColumnType";
|
|
3
3
|
import { getTableColumns, } from "../../Types/Database/TableColumn";
|
|
4
|
-
import SortOrder from "../../Types/BaseDatabase/SortOrder";
|
|
5
4
|
import logger from "../../Server/Utils/Logger";
|
|
6
5
|
import Color from "../../Types/Color";
|
|
7
6
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
8
7
|
import { PermissionHelper } from "../../Types/Permission";
|
|
9
|
-
|
|
8
|
+
import { BaseSchema } from "./BaseSchema";
|
|
9
|
+
export class ModelSchema extends BaseSchema {
|
|
10
10
|
/**
|
|
11
11
|
* Format permissions array into a human-readable string for OpenAPI documentation
|
|
12
12
|
*/
|
|
13
13
|
static formatPermissionsForSchema(permissions) {
|
|
14
14
|
if (!permissions || permissions.length === 0) {
|
|
15
|
-
return "No
|
|
15
|
+
return "No access - you don't have permission for this operation";
|
|
16
16
|
}
|
|
17
17
|
return PermissionHelper.getPermissionTitles(permissions).join(", ");
|
|
18
18
|
}
|
|
@@ -34,11 +34,23 @@ export class ModelSchema {
|
|
|
34
34
|
const model = new modelType();
|
|
35
35
|
const columns = getTableColumns(model);
|
|
36
36
|
const shape = {};
|
|
37
|
+
// Get column access control for permission filtering
|
|
38
|
+
const columnAccessControl = model.getColumnAccessControlForAllColumns();
|
|
37
39
|
for (const key in columns) {
|
|
38
40
|
const column = columns[key];
|
|
39
41
|
if (!column) {
|
|
40
42
|
continue;
|
|
41
43
|
}
|
|
44
|
+
// Filter out columns with no permissions (root-only access)
|
|
45
|
+
const accessControl = columnAccessControl[key];
|
|
46
|
+
if (accessControl) {
|
|
47
|
+
// Check if column has any permissions defined for read operation (general schema assumes read access)
|
|
48
|
+
const hasReadPermissions = accessControl.read && accessControl.read.length > 0;
|
|
49
|
+
// If no read permissions are defined, exclude the column from general schema
|
|
50
|
+
if (!hasReadPermissions) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
42
54
|
let zodType;
|
|
43
55
|
if (column.type === TableColumnType.ObjectID) {
|
|
44
56
|
zodType = z.string().openapi({
|
|
@@ -331,52 +343,33 @@ export class ModelSchema {
|
|
|
331
343
|
static getQueryModelSchema(data) {
|
|
332
344
|
const modelType = data.modelType;
|
|
333
345
|
const model = new modelType();
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
// Fallback for empty operators array
|
|
361
|
-
columnSchema = z.any().optional();
|
|
362
|
-
}
|
|
363
|
-
// Add OpenAPI documentation for query operators
|
|
364
|
-
const operatorExamples = this.getQueryOperatorExamples(column.type, validOperators);
|
|
365
|
-
columnSchema = columnSchema.openapi({
|
|
366
|
-
type: "object",
|
|
367
|
-
description: `Query operators for ${key} field of type ${column.type}. Supported operators: ${validOperators.join(", ")}`,
|
|
368
|
-
example: operatorExamples.length > 0 && operatorExamples[0]
|
|
369
|
-
? operatorExamples[0].example
|
|
370
|
-
: {},
|
|
371
|
-
});
|
|
372
|
-
shape[key] = columnSchema;
|
|
373
|
-
}
|
|
374
|
-
const schema = z.object(shape).openapi({
|
|
375
|
-
type: "object",
|
|
376
|
-
description: `Query schema for ${model.tableName || "model"} model. Each field can use various operators based on its data type.`,
|
|
377
|
-
example: this.getQuerySchemaExample(modelType),
|
|
346
|
+
return this.generateQuerySchema({
|
|
347
|
+
model,
|
|
348
|
+
tableName: model.tableName || "model",
|
|
349
|
+
getColumns: (model) => {
|
|
350
|
+
const columns = getTableColumns(model);
|
|
351
|
+
return Object.keys(columns)
|
|
352
|
+
.map((key) => {
|
|
353
|
+
const column = columns[key];
|
|
354
|
+
return column ? { key, type: column.type } : null;
|
|
355
|
+
})
|
|
356
|
+
.filter((col) => {
|
|
357
|
+
return col !== null;
|
|
358
|
+
});
|
|
359
|
+
},
|
|
360
|
+
getValidOperatorsForColumnType: (columnType) => {
|
|
361
|
+
return this.getValidOperatorsForColumnType(columnType);
|
|
362
|
+
},
|
|
363
|
+
getOperatorSchema: (operatorType, columnType) => {
|
|
364
|
+
return this.getOperatorSchema(operatorType, columnType);
|
|
365
|
+
},
|
|
366
|
+
getQuerySchemaExample: () => {
|
|
367
|
+
return this.getQuerySchemaExample(modelType);
|
|
368
|
+
},
|
|
369
|
+
getExampleValueForColumn: (columnType) => {
|
|
370
|
+
return this.getExampleValueForColumn(columnType);
|
|
371
|
+
},
|
|
378
372
|
});
|
|
379
|
-
return schema;
|
|
380
373
|
}
|
|
381
374
|
static getValidOperatorsForColumnType(columnType) {
|
|
382
375
|
const commonOperators = [
|
|
@@ -546,303 +539,102 @@ export class ModelSchema {
|
|
|
546
539
|
static getSortModelSchema(data) {
|
|
547
540
|
const modelType = data.modelType;
|
|
548
541
|
const model = new modelType();
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
description: `Sort order for ${key} field`,
|
|
567
|
-
example: SortOrder.Ascending,
|
|
568
|
-
});
|
|
569
|
-
}
|
|
570
|
-
return z.object(shape).openapi({
|
|
571
|
-
type: "object",
|
|
572
|
-
description: `Sort schema for ${model.tableName || "model"} model. Only sortable fields are included.`,
|
|
573
|
-
example: this.getSortSchemaExample(),
|
|
574
|
-
additionalProperties: false,
|
|
542
|
+
return this.generateSortSchema({
|
|
543
|
+
model,
|
|
544
|
+
tableName: model.tableName || "model",
|
|
545
|
+
getSortableTypes: () => {
|
|
546
|
+
return this.getSortableTypes();
|
|
547
|
+
},
|
|
548
|
+
getColumnsForSorting: (model) => {
|
|
549
|
+
const columns = getTableColumns(model);
|
|
550
|
+
return Object.keys(columns)
|
|
551
|
+
.map((key) => {
|
|
552
|
+
const column = columns[key];
|
|
553
|
+
return column ? { key, type: column.type } : null;
|
|
554
|
+
})
|
|
555
|
+
.filter((col) => {
|
|
556
|
+
return col !== null;
|
|
557
|
+
});
|
|
558
|
+
},
|
|
575
559
|
});
|
|
576
560
|
}
|
|
577
561
|
static getSelectModelSchema(data) {
|
|
578
562
|
const modelType = data.modelType;
|
|
579
563
|
const model = new modelType();
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
// can only do one level of nesting
|
|
593
|
-
shape[key] = this.getSelectModelSchema({
|
|
594
|
-
modelType: column.modelType,
|
|
595
|
-
isNested: true,
|
|
596
|
-
}).openapi({
|
|
597
|
-
type: "object",
|
|
598
|
-
description: `Select fields for nested ${key} entity`,
|
|
599
|
-
example: { id: true, name: true },
|
|
564
|
+
return this.generateSelectSchema({
|
|
565
|
+
model,
|
|
566
|
+
tableName: model.tableName || "model",
|
|
567
|
+
getColumns: (model) => {
|
|
568
|
+
const columns = getTableColumns(model);
|
|
569
|
+
return Object.keys(columns)
|
|
570
|
+
.map((key) => {
|
|
571
|
+
const column = columns[key];
|
|
572
|
+
return column ? { key, type: column.type } : null;
|
|
573
|
+
})
|
|
574
|
+
.filter((col) => {
|
|
575
|
+
return col !== null;
|
|
600
576
|
});
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
577
|
+
},
|
|
578
|
+
getSelectSchemaExample: () => {
|
|
579
|
+
return this.getSelectSchemaExample(modelType);
|
|
580
|
+
},
|
|
581
|
+
allowNested: !data.isNested,
|
|
582
|
+
getNestedSchema: (key, model) => {
|
|
583
|
+
const columns = getTableColumns(model);
|
|
584
|
+
const column = columns[key];
|
|
585
|
+
if (column &&
|
|
586
|
+
column.modelType &&
|
|
587
|
+
(column.type === TableColumnType.EntityArray ||
|
|
588
|
+
column.type === TableColumnType.Entity)) {
|
|
589
|
+
return this.getSelectModelSchema({
|
|
590
|
+
modelType: column.modelType,
|
|
591
|
+
isNested: true,
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
return null;
|
|
595
|
+
},
|
|
617
596
|
});
|
|
618
597
|
}
|
|
619
598
|
static getGroupByModelSchema(data) {
|
|
620
599
|
const modelType = data.modelType;
|
|
621
600
|
const model = new modelType();
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
return z.object(shape).openapi({
|
|
659
|
-
type: "object",
|
|
660
|
-
description: `Group by schema for ${model.tableName || "model"} model. Only one field can be set to true for grouping.`,
|
|
661
|
-
example: this.getGroupBySchemaExample(modelType),
|
|
662
|
-
additionalProperties: false,
|
|
601
|
+
return this.generateGroupBySchema({
|
|
602
|
+
model,
|
|
603
|
+
tableName: model.tableName || "model",
|
|
604
|
+
getColumns: (model) => {
|
|
605
|
+
const columns = getTableColumns(model);
|
|
606
|
+
return Object.keys(columns)
|
|
607
|
+
.map((key) => {
|
|
608
|
+
const column = columns[key];
|
|
609
|
+
return column ? { key, type: column.type } : null;
|
|
610
|
+
})
|
|
611
|
+
.filter((col) => {
|
|
612
|
+
return col !== null;
|
|
613
|
+
});
|
|
614
|
+
},
|
|
615
|
+
getGroupableTypes: () => {
|
|
616
|
+
return [
|
|
617
|
+
TableColumnType.ShortText,
|
|
618
|
+
TableColumnType.LongText,
|
|
619
|
+
TableColumnType.Name,
|
|
620
|
+
TableColumnType.Email,
|
|
621
|
+
TableColumnType.Slug,
|
|
622
|
+
TableColumnType.ObjectID,
|
|
623
|
+
TableColumnType.Boolean,
|
|
624
|
+
TableColumnType.Date,
|
|
625
|
+
TableColumnType.Number,
|
|
626
|
+
TableColumnType.PositiveNumber,
|
|
627
|
+
TableColumnType.SmallNumber,
|
|
628
|
+
TableColumnType.SmallPositiveNumber,
|
|
629
|
+
TableColumnType.BigNumber,
|
|
630
|
+
TableColumnType.BigPositiveNumber,
|
|
631
|
+
];
|
|
632
|
+
},
|
|
633
|
+
getGroupBySchemaExample: () => {
|
|
634
|
+
return this.getGroupBySchemaExample(modelType);
|
|
635
|
+
},
|
|
663
636
|
});
|
|
664
637
|
}
|
|
665
|
-
static getQueryOperatorExamples(columnType, validOperators) {
|
|
666
|
-
const examples = [];
|
|
667
|
-
for (const operator of validOperators) {
|
|
668
|
-
switch (operator) {
|
|
669
|
-
case "EqualTo":
|
|
670
|
-
examples.push({
|
|
671
|
-
properties: {
|
|
672
|
-
_type: { type: "string", enum: ["EqualTo"] },
|
|
673
|
-
value: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
674
|
-
},
|
|
675
|
-
required: ["_type", "value"],
|
|
676
|
-
example: {
|
|
677
|
-
_type: "EqualTo",
|
|
678
|
-
value: this.getExampleValueForColumn(columnType),
|
|
679
|
-
},
|
|
680
|
-
});
|
|
681
|
-
break;
|
|
682
|
-
case "NotEqual":
|
|
683
|
-
examples.push({
|
|
684
|
-
properties: {
|
|
685
|
-
_type: { type: "string", enum: ["NotEqual"] },
|
|
686
|
-
value: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
687
|
-
},
|
|
688
|
-
required: ["_type", "value"],
|
|
689
|
-
example: {
|
|
690
|
-
_type: "NotEqual",
|
|
691
|
-
value: this.getExampleValueForColumn(columnType),
|
|
692
|
-
},
|
|
693
|
-
});
|
|
694
|
-
break;
|
|
695
|
-
case "Search":
|
|
696
|
-
examples.push({
|
|
697
|
-
properties: {
|
|
698
|
-
_type: { type: "string", enum: ["Search"] },
|
|
699
|
-
value: { type: "string" },
|
|
700
|
-
},
|
|
701
|
-
required: ["_type", "value"],
|
|
702
|
-
example: { _type: "Search", value: "search term" },
|
|
703
|
-
});
|
|
704
|
-
break;
|
|
705
|
-
case "GreaterThan":
|
|
706
|
-
examples.push({
|
|
707
|
-
properties: {
|
|
708
|
-
_type: { type: "string", enum: ["GreaterThan"] },
|
|
709
|
-
value: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
710
|
-
},
|
|
711
|
-
required: ["_type", "value"],
|
|
712
|
-
example: {
|
|
713
|
-
_type: "GreaterThan",
|
|
714
|
-
value: this.getExampleValueForColumn(columnType),
|
|
715
|
-
},
|
|
716
|
-
});
|
|
717
|
-
break;
|
|
718
|
-
case "LessThan":
|
|
719
|
-
examples.push({
|
|
720
|
-
properties: {
|
|
721
|
-
_type: { type: "string", enum: ["LessThan"] },
|
|
722
|
-
value: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
723
|
-
},
|
|
724
|
-
required: ["_type", "value"],
|
|
725
|
-
example: {
|
|
726
|
-
_type: "LessThan",
|
|
727
|
-
value: this.getExampleValueForColumn(columnType),
|
|
728
|
-
},
|
|
729
|
-
});
|
|
730
|
-
break;
|
|
731
|
-
case "GreaterThanOrEqual":
|
|
732
|
-
examples.push({
|
|
733
|
-
properties: {
|
|
734
|
-
_type: { type: "string", enum: ["GreaterThanOrEqual"] },
|
|
735
|
-
value: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
736
|
-
},
|
|
737
|
-
required: ["_type", "value"],
|
|
738
|
-
example: {
|
|
739
|
-
_type: "GreaterThanOrEqual",
|
|
740
|
-
value: this.getExampleValueForColumn(columnType),
|
|
741
|
-
},
|
|
742
|
-
});
|
|
743
|
-
break;
|
|
744
|
-
case "LessThanOrEqual":
|
|
745
|
-
examples.push({
|
|
746
|
-
properties: {
|
|
747
|
-
_type: { type: "string", enum: ["LessThanOrEqual"] },
|
|
748
|
-
value: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
749
|
-
},
|
|
750
|
-
required: ["_type", "value"],
|
|
751
|
-
example: {
|
|
752
|
-
_type: "LessThanOrEqual",
|
|
753
|
-
value: this.getExampleValueForColumn(columnType),
|
|
754
|
-
},
|
|
755
|
-
});
|
|
756
|
-
break;
|
|
757
|
-
case "EqualToOrNull":
|
|
758
|
-
examples.push({
|
|
759
|
-
properties: {
|
|
760
|
-
_type: { type: "string", enum: ["EqualToOrNull"] },
|
|
761
|
-
value: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
762
|
-
},
|
|
763
|
-
required: ["_type", "value"],
|
|
764
|
-
example: {
|
|
765
|
-
_type: "EqualToOrNull",
|
|
766
|
-
value: this.getExampleValueForColumn(columnType),
|
|
767
|
-
},
|
|
768
|
-
});
|
|
769
|
-
break;
|
|
770
|
-
case "InBetween":
|
|
771
|
-
examples.push({
|
|
772
|
-
properties: {
|
|
773
|
-
_type: { type: "string", enum: ["InBetween"] },
|
|
774
|
-
startValue: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
775
|
-
endValue: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
776
|
-
},
|
|
777
|
-
required: ["_type", "startValue", "endValue"],
|
|
778
|
-
example: {
|
|
779
|
-
_type: "InBetween",
|
|
780
|
-
startValue: this.getExampleValueForColumn(columnType),
|
|
781
|
-
endValue: this.getExampleValueForColumn(columnType, true),
|
|
782
|
-
},
|
|
783
|
-
});
|
|
784
|
-
break;
|
|
785
|
-
case "IsNull":
|
|
786
|
-
examples.push({
|
|
787
|
-
properties: {
|
|
788
|
-
_type: { type: "string", enum: ["IsNull"] },
|
|
789
|
-
},
|
|
790
|
-
required: ["_type"],
|
|
791
|
-
example: { _type: "IsNull" },
|
|
792
|
-
});
|
|
793
|
-
break;
|
|
794
|
-
case "NotNull":
|
|
795
|
-
examples.push({
|
|
796
|
-
properties: {
|
|
797
|
-
_type: { type: "string", enum: ["NotNull"] },
|
|
798
|
-
},
|
|
799
|
-
required: ["_type"],
|
|
800
|
-
example: { _type: "NotNull" },
|
|
801
|
-
});
|
|
802
|
-
break;
|
|
803
|
-
case "Includes":
|
|
804
|
-
examples.push({
|
|
805
|
-
properties: {
|
|
806
|
-
_type: { type: "string", enum: ["Includes"] },
|
|
807
|
-
value: {
|
|
808
|
-
type: "array",
|
|
809
|
-
items: { type: this.getOpenAPITypeForColumn(columnType) },
|
|
810
|
-
},
|
|
811
|
-
},
|
|
812
|
-
required: ["_type", "value"],
|
|
813
|
-
example: {
|
|
814
|
-
_type: "Includes",
|
|
815
|
-
value: [
|
|
816
|
-
this.getExampleValueForColumn(columnType),
|
|
817
|
-
this.getExampleValueForColumn(columnType, true),
|
|
818
|
-
],
|
|
819
|
-
},
|
|
820
|
-
});
|
|
821
|
-
break;
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
return examples;
|
|
825
|
-
}
|
|
826
|
-
static getOpenAPITypeForColumn(columnType) {
|
|
827
|
-
switch (columnType) {
|
|
828
|
-
case TableColumnType.Number:
|
|
829
|
-
case TableColumnType.PositiveNumber:
|
|
830
|
-
case TableColumnType.SmallNumber:
|
|
831
|
-
case TableColumnType.SmallPositiveNumber:
|
|
832
|
-
case TableColumnType.BigNumber:
|
|
833
|
-
case TableColumnType.BigPositiveNumber:
|
|
834
|
-
return "number";
|
|
835
|
-
case TableColumnType.Boolean:
|
|
836
|
-
return "boolean";
|
|
837
|
-
case TableColumnType.Date:
|
|
838
|
-
return "string";
|
|
839
|
-
case TableColumnType.JSON:
|
|
840
|
-
case TableColumnType.Array:
|
|
841
|
-
return "object";
|
|
842
|
-
default:
|
|
843
|
-
return "string";
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
638
|
static getExampleValueForColumn(columnType, isSecondValue = false) {
|
|
847
639
|
switch (columnType) {
|
|
848
640
|
case TableColumnType.ObjectID:
|
|
@@ -954,11 +746,6 @@ export class ModelSchema {
|
|
|
954
746
|
}
|
|
955
747
|
return example;
|
|
956
748
|
}
|
|
957
|
-
static getSortSchemaExample() {
|
|
958
|
-
return {
|
|
959
|
-
createdAt: "Descending",
|
|
960
|
-
};
|
|
961
|
-
}
|
|
962
749
|
static getSelectSchemaExample(modelType) {
|
|
963
750
|
if (!modelType) {
|
|
964
751
|
throw new BadDataException("Model type is required to generate select schema example.");
|
|
@@ -1050,6 +837,8 @@ export class ModelSchema {
|
|
|
1050
837
|
const model = new modelType();
|
|
1051
838
|
const columns = getTableColumns(model);
|
|
1052
839
|
const shape = {};
|
|
840
|
+
// Get column access control for permission filtering
|
|
841
|
+
const columnAccessControl = model.getColumnAccessControlForAllColumns();
|
|
1053
842
|
for (const key in columns) {
|
|
1054
843
|
const column = columns[key];
|
|
1055
844
|
if (!column) {
|
|
@@ -1063,6 +852,35 @@ export class ModelSchema {
|
|
|
1063
852
|
if (data.includedFields && !data.includedFields.includes(key)) {
|
|
1064
853
|
continue;
|
|
1065
854
|
}
|
|
855
|
+
// Filter out columns with no permissions (root-only access)
|
|
856
|
+
const accessControl = columnAccessControl[key];
|
|
857
|
+
if (accessControl) {
|
|
858
|
+
let hasPermissions = false;
|
|
859
|
+
// Check if column has any permissions defined for the current operation
|
|
860
|
+
if (data.schemaType === "create" &&
|
|
861
|
+
accessControl.create &&
|
|
862
|
+
accessControl.create.length > 0) {
|
|
863
|
+
hasPermissions = true;
|
|
864
|
+
}
|
|
865
|
+
else if (data.schemaType === "read" &&
|
|
866
|
+
accessControl.read &&
|
|
867
|
+
accessControl.read.length > 0) {
|
|
868
|
+
hasPermissions = true;
|
|
869
|
+
}
|
|
870
|
+
else if (data.schemaType === "update" &&
|
|
871
|
+
accessControl.update &&
|
|
872
|
+
accessControl.update.length > 0) {
|
|
873
|
+
hasPermissions = true;
|
|
874
|
+
}
|
|
875
|
+
else if (data.schemaType === "delete") {
|
|
876
|
+
// For delete operations, we don't filter by column permissions
|
|
877
|
+
hasPermissions = true;
|
|
878
|
+
}
|
|
879
|
+
// If no permissions are defined for this operation, exclude the column
|
|
880
|
+
if (!hasPermissions) {
|
|
881
|
+
continue;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
1066
884
|
let zodType = this.getZodTypeForColumn(column, key, data.schemaType);
|
|
1067
885
|
// Make fields optional if specified
|
|
1068
886
|
if (data.makeOptional) {
|