@oneuptime/common 7.0.4372 → 7.0.4395
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/AnalyticsBaseModel/AnalyticsBaseModel.ts +0 -7
- package/Models/AnalyticsModels/AnalyticsBaseModel/CommonModel.ts +0 -13
- package/Models/DatabaseModels/Monitor.ts +1 -1
- package/Server/Middleware/ProjectAuthorization.ts +11 -3
- package/Server/Services/OpenTelemetryIngestService.ts +13 -9
- package/Server/Utils/AnalyticsDatabase/Statement.ts +0 -1
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +28 -81
- package/Server/Utils/OpenAPI.ts +47 -20
- package/Server/Utils/StartServer.ts +2 -2
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +0 -49
- package/Types/AnalyticsDatabase/TableColumn.ts +0 -26
- package/Types/AnalyticsDatabase/TableColumnType.ts +2 -1
- package/Types/Database/TableColumnType.ts +3 -0
- package/Types/GenericFunction.ts +1 -1
- package/Types/GenericObject.ts +1 -1
- package/Types/Object.ts +1 -1
- package/UI/esbuild-config.js +214 -0
- package/Utils/Schema/AnalyticsModelSchema.ts +39 -62
- package/Utils/Schema/ModelSchema.ts +51 -53
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.js +0 -6
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/CommonModel.js +0 -9
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/CommonModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js +7 -3
- package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +8 -4
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +0 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +15 -55
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/OpenAPI.js +22 -10
- package/build/dist/Server/Utils/OpenAPI.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +2 -2
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.js +0 -43
- package/build/dist/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/TableColumn.js +0 -19
- package/build/dist/Types/AnalyticsDatabase/TableColumn.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/TableColumnType.js +2 -1
- package/build/dist/Types/AnalyticsDatabase/TableColumnType.js.map +1 -1
- package/build/dist/Types/Database/TableColumnType.js +3 -0
- package/build/dist/Types/Database/TableColumnType.js.map +1 -1
- package/build/dist/Utils/Schema/AnalyticsModelSchema.js +38 -55
- package/build/dist/Utils/Schema/AnalyticsModelSchema.js.map +1 -1
- package/build/dist/Utils/Schema/ModelSchema.js +52 -53
- package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
- package/package.json +3 -1
- package/Models/AnalyticsModels/AnalyticsBaseModel/NestedModel.ts +0 -8
- package/Models/AnalyticsModels/NestedModels/KeyValueNestedModel.ts +0 -59
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/NestedModel.js +0 -7
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/NestedModel.js.map +0 -1
- package/build/dist/Models/AnalyticsModels/NestedModels/KeyValueNestedModel.js +0 -51
- package/build/dist/Models/AnalyticsModels/NestedModels/KeyValueNestedModel.js.map +0 -1
|
@@ -140,13 +140,6 @@ export default class AnalyticsBaseModel extends CommonModel {
|
|
|
140
140
|
this.crudApiPath = data.crudApiPath;
|
|
141
141
|
this.enableRealtimeEventsOn = data.enableRealtimeEventsOn;
|
|
142
142
|
this.partitionKey = data.partitionKey;
|
|
143
|
-
|
|
144
|
-
// initialize Arrays.
|
|
145
|
-
for (const column of this.tableColumns) {
|
|
146
|
-
if (column.type === TableColumnType.NestedModel) {
|
|
147
|
-
this.setColumnValue(column.key, []);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
143
|
}
|
|
151
144
|
|
|
152
145
|
private _enableWorkflowOn: EnableWorkflowOn | undefined;
|
|
@@ -207,19 +207,6 @@ export default class CommonModel {
|
|
|
207
207
|
return;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
if (recordValue instanceof Array) {
|
|
211
|
-
if (recordValue.length > 0 && column.nestedModelType) {
|
|
212
|
-
json[column.key] = CommonModel.toJSONArray(
|
|
213
|
-
recordValue as Array<CommonModel>,
|
|
214
|
-
column.nestedModelType,
|
|
215
|
-
);
|
|
216
|
-
} else {
|
|
217
|
-
json[column.key] = recordValue;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
210
|
json[column.key] = recordValue;
|
|
224
211
|
});
|
|
225
212
|
|
|
@@ -531,7 +531,7 @@ export default class Monitor extends BaseModel {
|
|
|
531
531
|
],
|
|
532
532
|
})
|
|
533
533
|
@TableColumn({
|
|
534
|
-
type: TableColumnType.
|
|
534
|
+
type: TableColumnType.MonitorSteps,
|
|
535
535
|
required: false,
|
|
536
536
|
title: "Monitor Steps",
|
|
537
537
|
description: "What would you like to monitor and what is the criteria?",
|
|
@@ -67,7 +67,7 @@ export default class ProjectMiddleware {
|
|
|
67
67
|
next: NextFunction,
|
|
68
68
|
): Promise<void> {
|
|
69
69
|
try {
|
|
70
|
-
|
|
70
|
+
let tenantId: ObjectID | null = this.getProjectId(req);
|
|
71
71
|
|
|
72
72
|
const apiKey: ObjectID | null = this.getApiKey(req);
|
|
73
73
|
|
|
@@ -81,19 +81,27 @@ export default class ProjectMiddleware {
|
|
|
81
81
|
|
|
82
82
|
let apiKeyModel: ApiKey | null = null;
|
|
83
83
|
|
|
84
|
-
if (
|
|
84
|
+
if (apiKey) {
|
|
85
85
|
apiKeyModel = await ApiKeyService.findOneBy({
|
|
86
86
|
query: {
|
|
87
|
-
projectId: tenantId,
|
|
88
87
|
apiKey: apiKey,
|
|
89
88
|
expiresAt: QueryHelper.greaterThan(OneUptimeDate.getCurrentDate()),
|
|
90
89
|
},
|
|
91
90
|
select: {
|
|
92
91
|
_id: true,
|
|
92
|
+
projectId: true,
|
|
93
93
|
},
|
|
94
94
|
props: { isRoot: true },
|
|
95
95
|
});
|
|
96
96
|
|
|
97
|
+
tenantId = apiKeyModel?.projectId || null;
|
|
98
|
+
|
|
99
|
+
if (!tenantId) {
|
|
100
|
+
throw new BadDataException(
|
|
101
|
+
"Project ID not found for the provided API Key.",
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
97
105
|
if (apiKeyModel) {
|
|
98
106
|
(req as OneUptimeRequest).userType = UserType.API;
|
|
99
107
|
// TODO: Add API key permissions.
|
|
@@ -125,18 +125,22 @@ export default class OTelIngestService {
|
|
|
125
125
|
|
|
126
126
|
const newDbMetric: Metric = Metric.fromJSON(
|
|
127
127
|
dbMetric.toJSON(),
|
|
128
|
-
Metric
|
|
128
|
+
Metric
|
|
129
129
|
) as Metric;
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
if (datapoint["startTimeUnixNano"]) {
|
|
132
|
+
newDbMetric.startTimeUnixNano = datapoint["startTimeUnixNano"] as number;
|
|
133
|
+
newDbMetric.startTime = OneUptimeDate.fromUnixNano(
|
|
134
|
+
datapoint["startTimeUnixNano"] as number
|
|
135
|
+
);
|
|
136
|
+
}
|
|
135
137
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
if (datapoint["timeUnixNano"]) {
|
|
139
|
+
newDbMetric.timeUnixNano = datapoint["timeUnixNano"] as number;
|
|
140
|
+
newDbMetric.time = OneUptimeDate.fromUnixNano(
|
|
141
|
+
datapoint["timeUnixNano"] as number
|
|
142
|
+
);
|
|
143
|
+
}
|
|
140
144
|
|
|
141
145
|
if (Object.keys(datapoint).includes("asInt")) {
|
|
142
146
|
newDbMetric.value = datapoint["asInt"] as number;
|
|
@@ -169,7 +169,6 @@ export class Statement implements BaseQueryParams {
|
|
|
169
169
|
[TableColumnType.Decimal]: "Double",
|
|
170
170
|
[TableColumnType.Date]: "DateTime",
|
|
171
171
|
[TableColumnType.JSON]: "JSON",
|
|
172
|
-
[TableColumnType.NestedModel]: "Nested",
|
|
173
172
|
[TableColumnType.ArrayNumber]: "Array(Int32)",
|
|
174
173
|
[TableColumnType.ArrayText]: "Array(String)",
|
|
175
174
|
[TableColumnType.LongNumber]: "Int128",
|
|
@@ -53,12 +53,18 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
53
53
|
const whereStatement: Statement = this.toWhereStatement(updateBy.query);
|
|
54
54
|
|
|
55
55
|
/* eslint-disable prettier/prettier */
|
|
56
|
-
|
|
57
|
-
ALTER TABLE ${this.database.getDatasourceOptions().database!}.${
|
|
56
|
+
const statement: Statement = SQL`
|
|
57
|
+
ALTER TABLE ${this.database.getDatasourceOptions().database!}.${
|
|
58
|
+
this.model.tableName
|
|
58
59
|
}
|
|
59
|
-
UPDATE
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
UPDATE `
|
|
61
|
+
.append(setStatement)
|
|
62
|
+
.append(
|
|
63
|
+
SQL`
|
|
64
|
+
WHERE TRUE `
|
|
65
|
+
)
|
|
66
|
+
.append(whereStatement);
|
|
67
|
+
/* eslint-enable prettier/prettier */
|
|
62
68
|
|
|
63
69
|
logger.debug(`${this.model.tableName} Update Statement`);
|
|
64
70
|
logger.debug(statement);
|
|
@@ -71,27 +77,7 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
71
77
|
): Array<string> {
|
|
72
78
|
const columnNames: Array<string> = [];
|
|
73
79
|
for (const column of tableColumns) {
|
|
74
|
-
|
|
75
|
-
// Example of nested model query:
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
*
|
|
79
|
-
* INSERT INTO opentelemetry_spans (trace_id, span_id, attributes.key, attributes.value) VALUES
|
|
80
|
-
('trace1', 'span1', ['key1', 'key2'], ['value1', 'value2']),
|
|
81
|
-
('trace2', 'span2', ['keyA', 'keyB'], ['valueA', 'valueB']);
|
|
82
|
-
*/
|
|
83
|
-
|
|
84
|
-
// Nested Model Support.
|
|
85
|
-
const nestedModelColumnNames: Array<string> = this.getColumnNames(
|
|
86
|
-
column.nestedModel!.tableColumns,
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
for (const nestedModelColumnName of nestedModelColumnNames) {
|
|
90
|
-
columnNames.push(`${column.key}.${nestedModelColumnName}`);
|
|
91
|
-
}
|
|
92
|
-
} else {
|
|
93
|
-
columnNames.push(column.key);
|
|
94
|
-
}
|
|
80
|
+
columnNames.push(column.key);
|
|
95
81
|
}
|
|
96
82
|
|
|
97
83
|
return columnNames;
|
|
@@ -168,45 +154,12 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
168
154
|
const record: Record = [];
|
|
169
155
|
|
|
170
156
|
for (const column of item.getTableColumns()) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
*
|
|
178
|
-
* INSERT INTO opentelemetry_spans (trace_id, span_id, attributes.key, attributes.value) VALUES
|
|
179
|
-
('trace1', 'span1', ['key1', 'key2'], ['value1', 'value2']),
|
|
180
|
-
('trace2', 'span2', ['keyA', 'keyB'], ['valueA', 'valueB']);
|
|
181
|
-
*/
|
|
182
|
-
|
|
183
|
-
for (const subColumn of column.nestedModel!.tableColumns) {
|
|
184
|
-
const subRecord: Record = [];
|
|
185
|
-
|
|
186
|
-
for (const nestedModelItem of item.getColumnValue(
|
|
187
|
-
column.key,
|
|
188
|
-
) as Array<CommonModel>) {
|
|
189
|
-
const value: RecordValue = this.sanitizeValue(
|
|
190
|
-
nestedModelItem.getColumnValue(subColumn.key),
|
|
191
|
-
subColumn,
|
|
192
|
-
{
|
|
193
|
-
isNestedModel: true,
|
|
194
|
-
},
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
subRecord.push(value);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
record.push(subRecord);
|
|
201
|
-
}
|
|
202
|
-
} else {
|
|
203
|
-
const value: RecordValue | undefined = this.sanitizeValue(
|
|
204
|
-
item.getColumnValue(column.key),
|
|
205
|
-
column,
|
|
206
|
-
);
|
|
157
|
+
const value: RecordValue | undefined = this.sanitizeValue(
|
|
158
|
+
item.getColumnValue(column.key),
|
|
159
|
+
column,
|
|
160
|
+
);
|
|
207
161
|
|
|
208
|
-
|
|
209
|
-
}
|
|
162
|
+
record.push(value);
|
|
210
163
|
}
|
|
211
164
|
|
|
212
165
|
return record;
|
|
@@ -625,16 +578,6 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
625
578
|
columns.append(SQL`, `);
|
|
626
579
|
}
|
|
627
580
|
|
|
628
|
-
let nestedModelColumns: Statement | null = null;
|
|
629
|
-
|
|
630
|
-
if (column.type === TableColumnType.NestedModel) {
|
|
631
|
-
nestedModelColumns = SQL`(`
|
|
632
|
-
.append(
|
|
633
|
-
this.toColumnsCreateStatement(column.nestedModel!.tableColumns),
|
|
634
|
-
)
|
|
635
|
-
.append(SQL`)`);
|
|
636
|
-
}
|
|
637
|
-
|
|
638
581
|
// special case - ClickHouse does not support using an a query parameter
|
|
639
582
|
// to specify the column name when creating the table
|
|
640
583
|
const keyStatement: string = column.key;
|
|
@@ -649,10 +592,6 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
649
592
|
.append(this.toColumnType(column.type))
|
|
650
593
|
.append(SQL`)`),
|
|
651
594
|
);
|
|
652
|
-
|
|
653
|
-
if (nestedModelColumns) {
|
|
654
|
-
columns.append(SQL` `).append(nestedModelColumns);
|
|
655
|
-
}
|
|
656
595
|
}
|
|
657
596
|
|
|
658
597
|
return columns;
|
|
@@ -672,26 +611,34 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
672
611
|
"Array(String)": TableColumnType.ArrayText,
|
|
673
612
|
"Array(Int32)": TableColumnType.ArrayNumber,
|
|
674
613
|
JSON: TableColumnType.JSON, //JSONArray is also JSON
|
|
675
|
-
Nested: TableColumnType.NestedModel,
|
|
676
614
|
Bool: TableColumnType.Boolean,
|
|
677
615
|
}[clickhouseType];
|
|
678
616
|
}
|
|
679
617
|
|
|
680
618
|
public toColumnType(type: TableColumnType): Statement {
|
|
681
|
-
|
|
619
|
+
const statement: Statement | undefined = {
|
|
682
620
|
[TableColumnType.Text]: SQL`String`,
|
|
683
621
|
[TableColumnType.ObjectID]: SQL`String`,
|
|
684
622
|
[TableColumnType.Boolean]: SQL`Bool`,
|
|
685
623
|
[TableColumnType.Number]: SQL`Int32`,
|
|
686
624
|
[TableColumnType.Decimal]: SQL`Double`,
|
|
625
|
+
[TableColumnType.IP]: SQL`String`,
|
|
626
|
+
[TableColumnType.Port]: SQL`String`,
|
|
687
627
|
[TableColumnType.Date]: SQL`DateTime`,
|
|
688
628
|
[TableColumnType.JSON]: SQL`String`, // we use JSON as a string because ClickHouse has really good JSON support for string types
|
|
689
629
|
[TableColumnType.JSONArray]: SQL`String`, // we use JSON as a string because ClickHouse has really good JSON support for string types
|
|
690
|
-
[TableColumnType.NestedModel]: SQL`Nested`,
|
|
691
630
|
[TableColumnType.ArrayNumber]: SQL`Array(Int32)`,
|
|
692
631
|
[TableColumnType.ArrayText]: SQL`Array(String)`,
|
|
693
632
|
[TableColumnType.LongNumber]: SQL`Int128`,
|
|
694
633
|
}[type];
|
|
634
|
+
|
|
635
|
+
if (!statement) {
|
|
636
|
+
throw new BadDataException(
|
|
637
|
+
`Unknown column type: ${type}. Please add support for this column type.`,
|
|
638
|
+
);
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
return statement;
|
|
695
642
|
}
|
|
696
643
|
|
|
697
644
|
public toDoesColumnExistStatement(columnName: string): string {
|
package/Server/Utils/OpenAPI.ts
CHANGED
|
@@ -2,6 +2,10 @@ import {
|
|
|
2
2
|
OpenAPIRegistry,
|
|
3
3
|
OpenApiGeneratorV3,
|
|
4
4
|
} from "@asteasolutions/zod-to-openapi";
|
|
5
|
+
import type {
|
|
6
|
+
ParameterObject,
|
|
7
|
+
ReferenceObject,
|
|
8
|
+
} from "@asteasolutions/zod-to-openapi/dist/types";
|
|
5
9
|
import DatabaseBaseModel from "../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
6
10
|
import Models from "../../Models/DatabaseModels/Index";
|
|
7
11
|
import AnalyticsBaseModel from "../../Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel";
|
|
@@ -196,11 +200,37 @@ export default class OpenAPIUtil {
|
|
|
196
200
|
description: "API Server",
|
|
197
201
|
},
|
|
198
202
|
],
|
|
199
|
-
tags: tags.sort(
|
|
200
|
-
|
|
201
|
-
|
|
203
|
+
tags: tags.sort(
|
|
204
|
+
(
|
|
205
|
+
a: { name: string; description: string },
|
|
206
|
+
b: { name: string; description: string },
|
|
207
|
+
) => {
|
|
208
|
+
return a.name.localeCompare(b.name);
|
|
209
|
+
},
|
|
210
|
+
),
|
|
202
211
|
}) as unknown as JSONObject;
|
|
203
212
|
|
|
213
|
+
// Add security schemes and global security requirement
|
|
214
|
+
if (!spec["components"]) {
|
|
215
|
+
spec["components"] = {};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
(spec["components"] as JSONObject)["securitySchemes"] = {
|
|
219
|
+
ApiKeyAuth: {
|
|
220
|
+
type: "apiKey",
|
|
221
|
+
in: "header",
|
|
222
|
+
name: "APIKey",
|
|
223
|
+
description:
|
|
224
|
+
"API key for authentication. Required for all API requests.",
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
spec["security"] = [
|
|
229
|
+
{
|
|
230
|
+
ApiKeyAuth: [],
|
|
231
|
+
},
|
|
232
|
+
];
|
|
233
|
+
|
|
204
234
|
LocalCache.setJSON("openapi", "spec", spec as JSONObject);
|
|
205
235
|
|
|
206
236
|
return spec;
|
|
@@ -227,6 +257,7 @@ export default class OpenAPIUtil {
|
|
|
227
257
|
summary: `List ${singularModelName}`,
|
|
228
258
|
description: `Endpoint to list all ${singularModelName} items`,
|
|
229
259
|
tags: [singularModelName],
|
|
260
|
+
parameters: [...OpenAPIUtil.getDefaultApiHeaders()],
|
|
230
261
|
requestBody: {
|
|
231
262
|
required: false,
|
|
232
263
|
content: {
|
|
@@ -286,6 +317,7 @@ export default class OpenAPIUtil {
|
|
|
286
317
|
summary: `Count ${singularModelName}`,
|
|
287
318
|
description: `Endpoint to count ${singularModelName} items`,
|
|
288
319
|
tags: [singularModelName],
|
|
320
|
+
parameters: [...OpenAPIUtil.getDefaultApiHeaders()],
|
|
289
321
|
requestBody: {
|
|
290
322
|
required: false,
|
|
291
323
|
content: {
|
|
@@ -451,7 +483,7 @@ export default class OpenAPIUtil {
|
|
|
451
483
|
description: `Endpoint to retrieve a single ${singularModelName} by ID`,
|
|
452
484
|
tags: [singularModelName],
|
|
453
485
|
parameters: [
|
|
454
|
-
...
|
|
486
|
+
...OpenAPIUtil.getDefaultApiHeaders(),
|
|
455
487
|
{
|
|
456
488
|
name: "id",
|
|
457
489
|
in: "path",
|
|
@@ -497,17 +529,10 @@ export default class OpenAPIUtil {
|
|
|
497
529
|
});
|
|
498
530
|
}
|
|
499
531
|
|
|
500
|
-
public static getDefaultApiHeaders(): Array<
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
in: "header",
|
|
505
|
-
required: true,
|
|
506
|
-
schema: { type: "string" },
|
|
507
|
-
description: "API key for authentication",
|
|
508
|
-
example: "your-api-key-here",
|
|
509
|
-
},
|
|
510
|
-
];
|
|
532
|
+
public static getDefaultApiHeaders(): Array<
|
|
533
|
+
ParameterObject | ReferenceObject
|
|
534
|
+
> {
|
|
535
|
+
return [];
|
|
511
536
|
}
|
|
512
537
|
|
|
513
538
|
public static generateUpdateApiSpec(data: {
|
|
@@ -536,7 +561,7 @@ export default class OpenAPIUtil {
|
|
|
536
561
|
description: `Endpoint to update an existing ${singularModelName}`,
|
|
537
562
|
tags: [singularModelName],
|
|
538
563
|
parameters: [
|
|
539
|
-
...
|
|
564
|
+
...OpenAPIUtil.getDefaultApiHeaders(),
|
|
540
565
|
{
|
|
541
566
|
name: "id",
|
|
542
567
|
in: "path",
|
|
@@ -607,7 +632,7 @@ export default class OpenAPIUtil {
|
|
|
607
632
|
description: `Endpoint to delete a ${singularModelName}`,
|
|
608
633
|
tags: [singularModelName],
|
|
609
634
|
parameters: [
|
|
610
|
-
...
|
|
635
|
+
...OpenAPIUtil.getDefaultApiHeaders(),
|
|
611
636
|
{
|
|
612
637
|
name: "id",
|
|
613
638
|
in: "path",
|
|
@@ -850,6 +875,7 @@ export default class OpenAPIUtil {
|
|
|
850
875
|
summary: `List ${singularModelName}`,
|
|
851
876
|
description: `Endpoint to list all ${singularModelName} items`,
|
|
852
877
|
tags: [singularModelName],
|
|
878
|
+
parameters: [...OpenAPIUtil.getDefaultApiHeaders()],
|
|
853
879
|
requestBody: {
|
|
854
880
|
required: false,
|
|
855
881
|
content: {
|
|
@@ -909,6 +935,7 @@ export default class OpenAPIUtil {
|
|
|
909
935
|
summary: `Count ${singularModelName}`,
|
|
910
936
|
description: `Endpoint to count ${singularModelName} items`,
|
|
911
937
|
tags: [singularModelName],
|
|
938
|
+
parameters: [...OpenAPIUtil.getDefaultApiHeaders()],
|
|
912
939
|
requestBody: {
|
|
913
940
|
required: false,
|
|
914
941
|
content: {
|
|
@@ -1033,7 +1060,7 @@ export default class OpenAPIUtil {
|
|
|
1033
1060
|
description: `Endpoint to retrieve a single ${singularModelName} by ID`,
|
|
1034
1061
|
tags: [singularModelName],
|
|
1035
1062
|
parameters: [
|
|
1036
|
-
...
|
|
1063
|
+
...OpenAPIUtil.getDefaultApiHeaders(),
|
|
1037
1064
|
{
|
|
1038
1065
|
name: "id",
|
|
1039
1066
|
in: "path",
|
|
@@ -1105,7 +1132,7 @@ export default class OpenAPIUtil {
|
|
|
1105
1132
|
description: `Endpoint to update an existing ${singularModelName}`,
|
|
1106
1133
|
tags: [singularModelName],
|
|
1107
1134
|
parameters: [
|
|
1108
|
-
...
|
|
1135
|
+
...OpenAPIUtil.getDefaultApiHeaders(),
|
|
1109
1136
|
{
|
|
1110
1137
|
name: "id",
|
|
1111
1138
|
in: "path",
|
|
@@ -1176,7 +1203,7 @@ export default class OpenAPIUtil {
|
|
|
1176
1203
|
description: `Endpoint to delete a ${singularModelName}`,
|
|
1177
1204
|
tags: [singularModelName],
|
|
1178
1205
|
parameters: [
|
|
1179
|
-
...
|
|
1206
|
+
...OpenAPIUtil.getDefaultApiHeaders(),
|
|
1180
1207
|
{
|
|
1181
1208
|
name: "id",
|
|
1182
1209
|
in: "path",
|
|
@@ -198,9 +198,9 @@ const init: InitFunction = async (
|
|
|
198
198
|
app.use(`/${appName}`, ExpressStatic("/usr/src/app/public"));
|
|
199
199
|
|
|
200
200
|
app.get(
|
|
201
|
-
`/${appName}/dist/
|
|
201
|
+
`/${appName}/dist/Index.js`,
|
|
202
202
|
(_req: ExpressRequest, res: ExpressResponse) => {
|
|
203
|
-
res.sendFile("/usr/src/app/public/dist/
|
|
203
|
+
res.sendFile("/usr/src/app/public/dist/Index.js");
|
|
204
204
|
},
|
|
205
205
|
);
|
|
206
206
|
|
|
@@ -8,7 +8,6 @@ import StatementGenerator from "../../../../Server/Utils/AnalyticsDatabase/State
|
|
|
8
8
|
import logger from "../../../../Server/Utils/Logger";
|
|
9
9
|
import "../../TestingUtils/Init";
|
|
10
10
|
import AnalyticsBaseModel from "../../../../Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel";
|
|
11
|
-
import NestedModel from "../../../../Models/AnalyticsModels/AnalyticsBaseModel/NestedModel";
|
|
12
11
|
import Route from "../../../../Types/API/Route";
|
|
13
12
|
import AnalyticsTableEngine from "../../../../Types/AnalyticsDatabase/AnalyticsTableEngine";
|
|
14
13
|
import AnalyticsTableColumn from "../../../../Types/AnalyticsDatabase/TableColumn";
|
|
@@ -238,54 +237,6 @@ describe("StatementGenerator", () => {
|
|
|
238
237
|
);
|
|
239
238
|
});
|
|
240
239
|
|
|
241
|
-
test("should support nested models", () => {
|
|
242
|
-
class TestNestedModel extends NestedModel {
|
|
243
|
-
public constructor() {
|
|
244
|
-
super({
|
|
245
|
-
tableColumns: [
|
|
246
|
-
new AnalyticsTableColumn({
|
|
247
|
-
key: "nested_column_1",
|
|
248
|
-
title: "<title>",
|
|
249
|
-
description: "<description>",
|
|
250
|
-
required: true,
|
|
251
|
-
type: TableColumnType.Text,
|
|
252
|
-
}),
|
|
253
|
-
new AnalyticsTableColumn({
|
|
254
|
-
key: "nested_column_2",
|
|
255
|
-
title: "<title>",
|
|
256
|
-
description: "<description>",
|
|
257
|
-
required: false,
|
|
258
|
-
type: TableColumnType.Number,
|
|
259
|
-
}),
|
|
260
|
-
],
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
const statement: Statement = generator.toColumnsCreateStatement([
|
|
266
|
-
new AnalyticsTableColumn({
|
|
267
|
-
key: "column_1",
|
|
268
|
-
title: "<title>",
|
|
269
|
-
description: "<description>",
|
|
270
|
-
required: true,
|
|
271
|
-
type: TableColumnType.Text,
|
|
272
|
-
}),
|
|
273
|
-
new AnalyticsTableColumn({
|
|
274
|
-
key: "column_2",
|
|
275
|
-
title: "<title>",
|
|
276
|
-
description: "<description>",
|
|
277
|
-
required: false,
|
|
278
|
-
type: TableColumnType.NestedModel,
|
|
279
|
-
nestedModelType: TestNestedModel,
|
|
280
|
-
}),
|
|
281
|
-
]);
|
|
282
|
-
|
|
283
|
-
expectStatement(
|
|
284
|
-
statement,
|
|
285
|
-
SQL`column_1 String, column_2 Nullable(Nested) (nested_column_1 String, nested_column_2 Nullable(Int32))`,
|
|
286
|
-
);
|
|
287
|
-
});
|
|
288
|
-
|
|
289
240
|
test("should not add NULL|NOT NULL to Array types", () => {
|
|
290
241
|
const statement: Statement = generator.toColumnsCreateStatement([
|
|
291
242
|
new AnalyticsTableColumn({
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import NestedModel from "../../Models/AnalyticsModels/AnalyticsBaseModel/NestedModel";
|
|
2
1
|
import TableColumnType from "../AnalyticsDatabase/TableColumnType";
|
|
3
2
|
import { ColumnAccessControl } from "../BaseDatabase/AccessControl";
|
|
4
3
|
import ColumnBillingAccessControl from "../BaseDatabase/ColumnBillingAccessControl";
|
|
@@ -104,25 +103,8 @@ export default class AnalyticsTableColumn {
|
|
|
104
103
|
this._accessControl = v;
|
|
105
104
|
}
|
|
106
105
|
|
|
107
|
-
private _nestedModel?: NestedModel | undefined;
|
|
108
|
-
public get nestedModel(): NestedModel | undefined {
|
|
109
|
-
return this._nestedModel;
|
|
110
|
-
}
|
|
111
|
-
public set nestedModel(v: NestedModel | undefined) {
|
|
112
|
-
this._nestedModel = v;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
private _nestedModelType?: { new (): NestedModel } | undefined;
|
|
116
|
-
public get nestedModelType(): { new (): NestedModel } | undefined {
|
|
117
|
-
return this._nestedModelType;
|
|
118
|
-
}
|
|
119
|
-
public set nestedModelType(v: { new (): NestedModel } | undefined) {
|
|
120
|
-
this._nestedModelType = v;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
106
|
public constructor(data: {
|
|
124
107
|
key: string;
|
|
125
|
-
nestedModelType?: { new (): NestedModel } | undefined;
|
|
126
108
|
title: string;
|
|
127
109
|
description: string;
|
|
128
110
|
required: boolean;
|
|
@@ -136,10 +118,6 @@ export default class AnalyticsTableColumn {
|
|
|
136
118
|
| (() => Date | string | number | boolean)
|
|
137
119
|
| undefined;
|
|
138
120
|
}) {
|
|
139
|
-
if (data.type === TableColumnType.NestedModel && !data.nestedModelType) {
|
|
140
|
-
throw new Error("NestedModel is required when type is NestedModel");
|
|
141
|
-
}
|
|
142
|
-
|
|
143
121
|
this.accessControl = data.accessControl;
|
|
144
122
|
this.key = data.key;
|
|
145
123
|
this.title = data.title;
|
|
@@ -152,9 +130,5 @@ export default class AnalyticsTableColumn {
|
|
|
152
130
|
this.billingAccessControl = data.billingAccessControl;
|
|
153
131
|
this.allowAccessIfSubscriptionIsUnpaid =
|
|
154
132
|
data.allowAccessIfSubscriptionIsUnpaid || false;
|
|
155
|
-
if (data.nestedModelType) {
|
|
156
|
-
this.nestedModel = new data.nestedModelType();
|
|
157
|
-
this.nestedModelType = data.nestedModelType;
|
|
158
|
-
}
|
|
159
133
|
}
|
|
160
134
|
}
|
|
@@ -4,13 +4,14 @@ enum ColumnType {
|
|
|
4
4
|
Boolean = "Boolean",
|
|
5
5
|
Number = "Number",
|
|
6
6
|
Text = "Text",
|
|
7
|
-
NestedModel = "Nested Model",
|
|
8
7
|
JSON = "JSON",
|
|
9
8
|
JSONArray = "JSON Array",
|
|
10
9
|
Decimal = "Decimal",
|
|
11
10
|
ArrayNumber = "Array of Numbers",
|
|
12
11
|
ArrayText = "Array of Text",
|
|
13
12
|
LongNumber = "Long Number",
|
|
13
|
+
IP = "IP",
|
|
14
|
+
Port = "Port",
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
export default ColumnType;
|
|
@@ -14,6 +14,7 @@ enum ColumnType {
|
|
|
14
14
|
ShortURL = "Short URL",
|
|
15
15
|
Markdown = "Markdown",
|
|
16
16
|
Domain = "Domain",
|
|
17
|
+
MonitorSteps = "Monitor Steps",
|
|
17
18
|
LongURL = "URL",
|
|
18
19
|
ShortText = "Text",
|
|
19
20
|
OTP = "One Time Password",
|
|
@@ -38,6 +39,8 @@ enum ColumnType {
|
|
|
38
39
|
CustomFieldType = "Custom Field Type",
|
|
39
40
|
MonitorType = "Monitor Type",
|
|
40
41
|
WorkflowStatus = "Workflow Status",
|
|
42
|
+
IP = "IP",
|
|
43
|
+
Port = "Port",
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
export default ColumnType;
|
package/Types/GenericFunction.ts
CHANGED
package/Types/GenericObject.ts
CHANGED
package/Types/Object.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// eslint-disable-next-line @typescript-eslint/
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-restricted-types
|
|
2
2
|
export type GlobalObject = object;
|