harperdb 4.3.24 → 4.4.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -3
- package/application-template/config.yaml +2 -5
- package/bin/harperdb.js +103 -74
- package/bin/lite.js +121 -22
- package/config/yaml/defaultConfig.yaml +11 -43
- package/config/yaml/defaultNatsConfig.yaml +36 -0
- package/index.js +3 -12
- package/json/hdbConnectorOptions.json +14 -14
- package/json/interNodeConnectorOptions.json +15 -15
- package/json/systemSchema.json +260 -307
- package/launchServiceScripts/launchInstallNATSServer.js +4 -4
- package/launchServiceScripts/launchNatsIngestService.js +121 -22
- package/launchServiceScripts/launchNatsReplyService.js +121 -22
- package/launchServiceScripts/launchUpdateNodes4-0-0.js +121 -22
- package/logs/README.md +1 -1
- package/npm-shrinkwrap.json +7545 -7228
- package/package.json +130 -131
- package/resources/DatabaseTransaction.d.ts +1 -0
- package/resources/ErrorResource.d.ts +26 -0
- package/resources/RecordEncoder.d.ts +3 -1
- package/resources/Resource.d.ts +8 -1
- package/resources/ResourceInterface.d.ts +7 -3
- package/resources/Resources.d.ts +5 -4
- package/resources/Table.d.ts +50 -19
- package/resources/auditStore.d.ts +45 -1
- package/resources/databases.d.ts +54 -17
- package/resources/search.d.ts +6 -0
- package/resources/transactionBroadcast.d.ts +2 -1
- package/server/Server.d.ts +1 -1
- package/server/jobs/jobProcess.js +121 -22
- package/server/serverHelpers/Headers.d.ts +9 -1
- package/server/threads/threadServer.js +121 -22
- package/utility/scripts/restartHdb.js +121 -22
- package/application-template/routes/index.js +0 -14
- package/studio/build-local/asset-manifest.json +0 -53
- package/studio/build-local/index.html +0 -1
- package/studio/build-local/static/css/main.6c0f1b63.css +0 -13
- package/studio/build-local/static/js/110.ca4244a6.chunk.js +0 -2
- package/studio/build-local/static/js/110.ca4244a6.chunk.js.LICENSE.txt +0 -1
- package/studio/build-local/static/js/228.302d7db9.chunk.js +0 -1
- package/studio/build-local/static/js/287.21477cf9.chunk.js +0 -1
- package/studio/build-local/static/js/409.17daa4fe.chunk.js +0 -2
- package/studio/build-local/static/js/409.17daa4fe.chunk.js.LICENSE.txt +0 -8
- package/studio/build-local/static/js/424.ad87c8fd.chunk.js +0 -1
- package/studio/build-local/static/js/446.5237e847.chunk.js +0 -2
- package/studio/build-local/static/js/446.5237e847.chunk.js.LICENSE.txt +0 -13
- package/studio/build-local/static/js/662.92e32ffc.chunk.js +0 -1
- package/studio/build-local/static/js/718.74e9355d.chunk.js +0 -1
- package/studio/build-local/static/js/723.c58acced.chunk.js +0 -2
- package/studio/build-local/static/js/723.c58acced.chunk.js.LICENSE.txt +0 -5
- package/studio/build-local/static/js/731.8a941eb3.chunk.js +0 -1
- package/studio/build-local/static/js/807.510f66df.chunk.js +0 -2
- package/studio/build-local/static/js/807.510f66df.chunk.js.LICENSE.txt +0 -5
- package/studio/build-local/static/js/926.88d6f9ce.chunk.js +0 -1
- package/studio/build-local/static/js/browse-csvupload.453237f3.chunk.js +0 -1
- package/studio/build-local/static/js/browse-datatable.b9ef2d28.chunk.js +0 -1
- package/studio/build-local/static/js/browse-entitymanager.50827a5a.chunk.js +0 -1
- package/studio/build-local/static/js/browse-jsonviewer.a2534004.chunk.js +0 -1
- package/studio/build-local/static/js/custom-functions.dd7e182c.chunk.js +0 -1
- package/studio/build-local/static/js/instance-charts.34d15f02.chunk.js +0 -1
- package/studio/build-local/static/js/instance-cluster.5bce430c.chunk.js +0 -1
- package/studio/build-local/static/js/instance-config.70c17b53.chunk.js +0 -1
- package/studio/build-local/static/js/instance-query.4f6eec62.chunk.js +0 -1
- package/studio/build-local/static/js/instance-roles.507a4ed0.chunk.js +0 -1
- package/studio/build-local/static/js/instance-status.ce9d7f64.chunk.js +0 -1
- package/studio/build-local/static/js/instance-users-datatable.190640fd.chunk.js +0 -1
- package/studio/build-local/static/js/instance-users-edit.d2444479.chunk.js +0 -1
- package/studio/build-local/static/js/instance-users.eabfbbde.chunk.js +0 -1
- package/studio/build-local/static/js/instance.a163623f.chunk.js +0 -1
- package/studio/build-local/static/js/instances.6b88a87c.chunk.js +0 -1
- package/studio/build-local/static/js/main.7106edfd.js +0 -2
- package/studio/build-local/static/js/main.7106edfd.js.LICENSE.txt +0 -72
- package/studio/build-local/static/js/offline-app.7371216b.chunk.js +0 -1
- package/studio/build-local/static/js/online-app.db436eec.chunk.js +0 -1
- package/studio/build-local/static/js/organization-billing.b2f260f0.chunk.js +0 -1
- package/studio/build-local/static/js/organization-users.b6171b18.chunk.js +0 -1
- package/studio/build-local/static/js/organization.7800f16a.chunk.js +0 -1
- package/studio/build-local/static/js/organizations.8bb505f2.chunk.js +0 -1
- package/studio/build-local/static/js/profile.292bdd86.chunk.js +0 -1
- package/studio/build-local/static/js/resetPassword.8fdfba77.chunk.js +0 -1
- package/studio/build-local/static/js/roles-jsonviewer.c11f1816.chunk.js +0 -1
- package/studio/build-local/static/js/signIn.b11bdc50.chunk.js +0 -1
- package/studio/build-local/static/js/signUp.564d4e0b.chunk.js +0 -1
- package/studio/build-local/static/js/structure-reloader.b6de4091.chunk.js +0 -1
- package/studio/build-local/static/js/topnav.4fd41d60.chunk.js +0 -1
- package/studio/build-local/static/js/updatePassword.e23019c7.chunk.js +0 -1
|
@@ -10,22 +10,66 @@ export declare const AUDIT_STORE_OPTIONS: {
|
|
|
10
10
|
};
|
|
11
11
|
};
|
|
12
12
|
export declare function openAuditStore(root_store: any): any;
|
|
13
|
+
export declare function getLastRemoved(audit_store: any): number;
|
|
13
14
|
export declare function setAuditRetention(retention_time: any, default_delay?: number): void;
|
|
14
|
-
|
|
15
|
+
/** Used to indicate we have received a remote local time update */
|
|
16
|
+
export declare const REMOTE_SEQUENCE_UPDATE = 11;
|
|
17
|
+
export declare const HAS_CURRENT_RESIDENCY_ID = 512;
|
|
18
|
+
export declare const HAS_PREVIOUS_RESIDENCY_ID = 1024;
|
|
19
|
+
export declare const HAS_ORIGINATING_OPERATION = 2048;
|
|
20
|
+
export declare const HAS_EXPIRATION_EXTENDED_TYPE = 4096;
|
|
21
|
+
/**
|
|
22
|
+
* Creates a binary audit entry
|
|
23
|
+
* @param txn_time
|
|
24
|
+
* @param table_id
|
|
25
|
+
* @param record_id
|
|
26
|
+
* @param previous_local_time
|
|
27
|
+
* @param node_id
|
|
28
|
+
* @param username
|
|
29
|
+
* @param type
|
|
30
|
+
* @param encoded_record
|
|
31
|
+
* @param extended_type
|
|
32
|
+
* @param residency_id
|
|
33
|
+
* @param previous_residency_id
|
|
34
|
+
*/
|
|
35
|
+
export declare function createAuditEntry(txn_time: any, table_id: any, record_id: any, previous_local_time: any, node_id: any, username: any, type: any, encoded_record: any, extended_type: any, residency_id: any, previous_residency_id: any, expires_at: any, originating_operation?: string): Buffer;
|
|
15
36
|
export declare function readAuditEntry(buffer: any): {
|
|
16
37
|
type: any;
|
|
17
38
|
tableId: any;
|
|
39
|
+
nodeId: any;
|
|
18
40
|
readonly recordId: import("ordered-binary").Key;
|
|
41
|
+
getBinaryRecordId(): any;
|
|
19
42
|
version: any;
|
|
20
43
|
previousLocalTime: any;
|
|
21
44
|
readonly user: import("ordered-binary").Key;
|
|
45
|
+
encoded: any;
|
|
22
46
|
getValue(store: any, full_record?: any, audit_time?: any): any;
|
|
47
|
+
getBinaryValue(): any;
|
|
48
|
+
extendedType: any;
|
|
49
|
+
residencyId: any;
|
|
50
|
+
previousResidencyId: any;
|
|
51
|
+
expiresAt: any;
|
|
52
|
+
originatingOperation: any;
|
|
23
53
|
} | {
|
|
24
54
|
type?: undefined;
|
|
25
55
|
tableId?: undefined;
|
|
56
|
+
nodeId?: undefined;
|
|
26
57
|
readonly recordId?: undefined;
|
|
58
|
+
getBinaryRecordId?: undefined;
|
|
27
59
|
version?: undefined;
|
|
28
60
|
previousLocalTime?: undefined;
|
|
29
61
|
readonly user?: undefined;
|
|
62
|
+
encoded?: undefined;
|
|
30
63
|
getValue?: undefined;
|
|
64
|
+
getBinaryValue?: undefined;
|
|
65
|
+
extendedType?: undefined;
|
|
66
|
+
residencyId?: undefined;
|
|
67
|
+
previousResidencyId?: undefined;
|
|
68
|
+
expiresAt?: undefined;
|
|
69
|
+
originatingOperation?: undefined;
|
|
31
70
|
};
|
|
71
|
+
export declare class Decoder extends DataView {
|
|
72
|
+
position: number;
|
|
73
|
+
readInt(): any;
|
|
74
|
+
readFloat64(): number;
|
|
75
|
+
}
|
package/resources/databases.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ interface TableDefinition {
|
|
|
39
39
|
scanInterval?: number;
|
|
40
40
|
audit?: boolean;
|
|
41
41
|
sealed?: boolean;
|
|
42
|
+
replicate?: boolean;
|
|
42
43
|
trackDeletes?: boolean;
|
|
43
44
|
attributes: any[];
|
|
44
45
|
schemaDefined?: boolean;
|
|
@@ -69,20 +70,23 @@ export declare function dropDatabase(database_name: any): Promise<void>;
|
|
|
69
70
|
* @param attributes
|
|
70
71
|
* @param audit
|
|
71
72
|
* @param sealed
|
|
73
|
+
* @param replicate
|
|
72
74
|
*/
|
|
73
|
-
export declare function table(
|
|
75
|
+
export declare function table(table_definition: TableDefinition): {
|
|
74
76
|
new (identifier: import("./ResourceInterface").Id, source: any): {
|
|
75
77
|
ensureLoaded(): any;
|
|
76
78
|
get(query?: import("./ResourceInterface").Query | string): Promise<object | void> | object | void;
|
|
77
79
|
allowRead(user: any, query: any): any;
|
|
78
80
|
allowUpdate(user: any, updated_data: any): boolean;
|
|
79
81
|
allowCreate(user: any, new_data: {}): boolean;
|
|
80
|
-
allowDelete(user: any):
|
|
82
|
+
allowDelete(user: any): boolean;
|
|
81
83
|
update(updates?: any, full_update?: boolean): any;
|
|
82
84
|
addTo(property: any, value: any): void;
|
|
83
85
|
subtractFrom(property: any, value: any): void;
|
|
84
86
|
getMetadata(): any;
|
|
85
|
-
invalidate(
|
|
87
|
+
invalidate(): void;
|
|
88
|
+
_writeInvalidate(options: any): void;
|
|
89
|
+
_writeRelocate(options: any): void;
|
|
86
90
|
lock(): void;
|
|
87
91
|
put(record: any): void;
|
|
88
92
|
patch(record_update: any): void;
|
|
@@ -144,7 +148,7 @@ export declare function table({ table: table_name, database: database_name, expi
|
|
|
144
148
|
validate(record: any, patch?: any): void;
|
|
145
149
|
getUpdatedTime(): any;
|
|
146
150
|
wasLoadedFromSource(): boolean | void;
|
|
147
|
-
post(new_record: any): any
|
|
151
|
+
post(new_record: any): Promise<any>;
|
|
148
152
|
connect(query?: {}): AsyncIterable<any>;
|
|
149
153
|
getId(): any;
|
|
150
154
|
getContext(): import("./ResourceInterface").Context;
|
|
@@ -154,32 +158,51 @@ export declare function table({ table: table_name, database: database_name, expi
|
|
|
154
158
|
auditStore: any;
|
|
155
159
|
primaryKey: any;
|
|
156
160
|
tableName: any;
|
|
161
|
+
tableId: any;
|
|
157
162
|
indices: any;
|
|
158
163
|
audit: any;
|
|
159
164
|
databasePath: any;
|
|
160
165
|
databaseName: any;
|
|
161
166
|
attributes: any;
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
167
|
+
replicate: any;
|
|
168
|
+
sealed: any;
|
|
169
|
+
createdTimeProperty: {
|
|
170
|
+
name: string;
|
|
171
|
+
type: string;
|
|
172
|
+
assignCreatedTime?: boolean;
|
|
173
|
+
assignUpdatedTime?: boolean;
|
|
174
|
+
expiresAt?: boolean;
|
|
175
|
+
isPrimaryKey?: boolean;
|
|
176
|
+
};
|
|
177
|
+
updatedTimeProperty: {
|
|
178
|
+
name: string;
|
|
179
|
+
type: string;
|
|
180
|
+
assignCreatedTime?: boolean;
|
|
181
|
+
assignUpdatedTime?: boolean;
|
|
182
|
+
expiresAt?: boolean;
|
|
183
|
+
isPrimaryKey?: boolean;
|
|
184
|
+
};
|
|
165
185
|
propertyResolvers: any;
|
|
186
|
+
userResolvers: {};
|
|
166
187
|
sources: any[];
|
|
167
188
|
readonly expirationMS: any;
|
|
168
189
|
dbisDB: any;
|
|
169
190
|
schemaDefined: any;
|
|
170
191
|
sourcedFrom(source: any, options: any): any;
|
|
171
|
-
getResource(id: import("./ResourceInterface").Id, request:
|
|
192
|
+
getResource(id: import("./ResourceInterface").Id, request: import("./ResourceInterface").Context, resource_options?: any): Promise<{
|
|
172
193
|
ensureLoaded(): any;
|
|
173
194
|
get(query?: import("./ResourceInterface").Query | string): Promise<object | void> | object | void;
|
|
174
195
|
allowRead(user: any, query: any): any;
|
|
175
196
|
allowUpdate(user: any, updated_data: any): boolean;
|
|
176
197
|
allowCreate(user: any, new_data: {}): boolean;
|
|
177
|
-
allowDelete(user: any):
|
|
198
|
+
allowDelete(user: any): boolean;
|
|
178
199
|
update(updates?: any, full_update?: boolean): any;
|
|
179
200
|
addTo(property: any, value: any): void;
|
|
180
201
|
subtractFrom(property: any, value: any): void;
|
|
181
202
|
getMetadata(): any;
|
|
182
|
-
invalidate(
|
|
203
|
+
invalidate(): void;
|
|
204
|
+
_writeInvalidate(options: any): void;
|
|
205
|
+
_writeRelocate(options: any): void;
|
|
183
206
|
lock(): void;
|
|
184
207
|
put(record: any): void;
|
|
185
208
|
patch(record_update: any): void;
|
|
@@ -241,7 +264,7 @@ export declare function table({ table: table_name, database: database_name, expi
|
|
|
241
264
|
validate(record: any, patch?: any): void;
|
|
242
265
|
getUpdatedTime(): any;
|
|
243
266
|
wasLoadedFromSource(): boolean | void;
|
|
244
|
-
post(new_record: any): any
|
|
267
|
+
post(new_record: any): Promise<any>;
|
|
245
268
|
connect(query?: {}): AsyncIterable<any>;
|
|
246
269
|
getId(): any;
|
|
247
270
|
getContext(): import("./ResourceInterface").Context;
|
|
@@ -251,12 +274,14 @@ export declare function table({ table: table_name, database: database_name, expi
|
|
|
251
274
|
allowRead(user: any, query: any): any;
|
|
252
275
|
allowUpdate(user: any, updated_data: any): boolean;
|
|
253
276
|
allowCreate(user: any, new_data: {}): boolean;
|
|
254
|
-
allowDelete(user: any):
|
|
277
|
+
allowDelete(user: any): boolean;
|
|
255
278
|
update(updates?: any, full_update?: boolean): any;
|
|
256
279
|
addTo(property: any, value: any): void;
|
|
257
280
|
subtractFrom(property: any, value: any): void;
|
|
258
281
|
getMetadata(): any;
|
|
259
|
-
invalidate(
|
|
282
|
+
invalidate(): void;
|
|
283
|
+
_writeInvalidate(options: any): void;
|
|
284
|
+
_writeRelocate(options: any): void;
|
|
260
285
|
lock(): void;
|
|
261
286
|
put(record: any): void;
|
|
262
287
|
patch(record_update: any): void;
|
|
@@ -318,22 +343,28 @@ export declare function table({ table: table_name, database: database_name, expi
|
|
|
318
343
|
validate(record: any, patch?: any): void;
|
|
319
344
|
getUpdatedTime(): any;
|
|
320
345
|
wasLoadedFromSource(): boolean | void;
|
|
321
|
-
post(new_record: any): any
|
|
346
|
+
post(new_record: any): Promise<any>;
|
|
322
347
|
connect(query?: {}): AsyncIterable<any>;
|
|
323
348
|
getId(): any;
|
|
324
349
|
getContext(): import("./ResourceInterface").Context;
|
|
325
350
|
};
|
|
351
|
+
getNewId(): any;
|
|
326
352
|
setTTLExpiration(expiration: number | {
|
|
327
353
|
expiration: number;
|
|
328
354
|
eviction?: number;
|
|
329
355
|
scanInterval?: number;
|
|
330
356
|
}): void;
|
|
357
|
+
getResidencyRecord(id: any): any;
|
|
358
|
+
setResidency(getResidency: (record: object, context: import("./ResourceInterface").Context, previous_residency: string[]) => string[]): void;
|
|
359
|
+
setResidencyById(getResidencyById: (id: import("./ResourceInterface").Id) => string[]): void;
|
|
360
|
+
getResidency(record: object, context: import("./ResourceInterface").Context, previous_residency: string[]): any;
|
|
331
361
|
enableAuditing(audit_enabled?: boolean): void;
|
|
332
362
|
coerceId(id: string): number | string;
|
|
333
363
|
dropTable(): Promise<void>;
|
|
364
|
+
_recordRelocate(existing_entry: any, entry: any): void;
|
|
334
365
|
evict(id: any, existing_record: any, existing_version: any): any;
|
|
335
366
|
operation(operation: any, context: any): any;
|
|
336
|
-
transformToOrderedSelect(entries: any, select:
|
|
367
|
+
transformToOrderedSelect(entries: any[], select: (string | import("./ResourceInterface").SubSelect)[], sort: import("./ResourceInterface").Sort, context: import("./ResourceInterface").Context, read_txn: any, transformToRecord: Function): any;
|
|
337
368
|
transformEntryForSelect(select: any, context: any, read_txn: any, filtered: any, ensure_loaded?: any, can_skip?: any): (entry: any) => any;
|
|
338
369
|
addAttributes(attributes_to_add: any): Promise<any>;
|
|
339
370
|
removeAttributes(names: string[]): Promise<any>;
|
|
@@ -345,6 +376,7 @@ export declare function table({ table: table_name, database: database_name, expi
|
|
|
345
376
|
estimatedRange?: undefined;
|
|
346
377
|
};
|
|
347
378
|
updatedAttributes(): void;
|
|
379
|
+
setComputedAttribute(attribute_name: any, resolver: any): void;
|
|
348
380
|
deleteHistory(end_time?: number): Promise<void>;
|
|
349
381
|
getHistory(start_time?: number, end_time?: number): AsyncGenerator<{
|
|
350
382
|
id: import("ordered-binary").Key;
|
|
@@ -353,6 +385,7 @@ export declare function table({ table: table_name, database: database_name, expi
|
|
|
353
385
|
type: any;
|
|
354
386
|
value: any;
|
|
355
387
|
user: import("ordered-binary").Key;
|
|
388
|
+
operation: any;
|
|
356
389
|
}, void, unknown>;
|
|
357
390
|
getHistoryOfRecord(id: any): Promise<any[]>;
|
|
358
391
|
cleanup(): void;
|
|
@@ -371,7 +404,6 @@ export declare function table({ table: table_name, database: database_name, expi
|
|
|
371
404
|
};
|
|
372
405
|
delete(identifier: import("./ResourceInterface").Id, context?: import("./ResourceInterface").Context): Promise<boolean>;
|
|
373
406
|
delete(request: import("./ResourceInterface").Context, context?: import("./ResourceInterface").Context): Promise<object>;
|
|
374
|
-
getNewId(): `${string}-${string}-${string}-${string}-${string}`;
|
|
375
407
|
create(id_prefix: import("./ResourceInterface").Id, record: any, context: import("./ResourceInterface").Context): Promise<import("./ResourceInterface").Id>;
|
|
376
408
|
create(record: any, context: import("./ResourceInterface").Context): Promise<import("./ResourceInterface").Id>;
|
|
377
409
|
invalidate: {
|
|
@@ -419,7 +451,12 @@ export declare function dropTableMeta({ table: table_name, database: database_na
|
|
|
419
451
|
table: any;
|
|
420
452
|
database: any;
|
|
421
453
|
}): Promise<any[]>;
|
|
422
|
-
export declare function onUpdatedTable(listener: any):
|
|
454
|
+
export declare function onUpdatedTable(listener: any): {
|
|
455
|
+
remove(): void;
|
|
456
|
+
};
|
|
457
|
+
export declare function onRemovedDB(listener: any): {
|
|
458
|
+
remove(): void;
|
|
459
|
+
};
|
|
423
460
|
export declare function getDefaultCompression(): {
|
|
424
461
|
startingOffset: number;
|
|
425
462
|
};
|
package/resources/search.d.ts
CHANGED
|
@@ -24,3 +24,9 @@ export declare function estimateCondition(table: any): (condition: any) => any;
|
|
|
24
24
|
export declare function parseQuery(query_to_parse: any): any;
|
|
25
25
|
export declare function flattenKey(key: any): any;
|
|
26
26
|
export declare function intersectionEstimate(store: any, left: any, right: any): number;
|
|
27
|
+
export declare class SimpleURLQuery {
|
|
28
|
+
url: string;
|
|
29
|
+
constructor(url: string);
|
|
30
|
+
get(): void;
|
|
31
|
+
[Symbol.iterator](): ArrayIterator<any>;
|
|
32
|
+
}
|
|
@@ -24,8 +24,9 @@ declare class Subscription extends IterableEventQueue {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
|
-
* Interface with lmdb-js to listen for commits and
|
|
27
|
+
* Interface with lmdb-js to listen for commits and traverse the audit log.
|
|
28
28
|
* @param primary_store
|
|
29
29
|
*/
|
|
30
30
|
export declare function listenToCommits(primary_store: any, audit_store: any): void;
|
|
31
|
+
export declare function whenNextTransaction(audit_store: any): any;
|
|
31
32
|
export {};
|
package/server/Server.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ interface Server {
|
|
|
10
10
|
ws?(listener: (ws: WebSocket, request: Request, requestCompletion: Promise<any>) => any, options?: WebSocketOptions): void;
|
|
11
11
|
contentTypes: Map<string, ContentTypeHandler>;
|
|
12
12
|
getUser(username: string, password: string | null, request: Request): any;
|
|
13
|
-
operation(operation: any, authorize?: boolean): Promise<any>;
|
|
13
|
+
operation(operation: any, context: any, authorize?: boolean): Promise<any>;
|
|
14
14
|
}
|
|
15
15
|
interface ServerOptions {
|
|
16
16
|
port?: number;
|