@tmlmobilidade/go-interfaces-godb 20260717.1316.58

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.
@@ -0,0 +1,16 @@
1
+ import type { MongoClient } from '@tmlmobilidade/go-clients-mongo';
2
+ import type { Agency, CreateAgencyDto, CreateFileDto, CreateFileExportDto, CreateOrganizationDto, CreateRoleDto, CreateSessionDto, CreateUserDto, CreateVerificationTokenDto, File, FileExport, Organization, Role, Session, UpdateAgencyDto, UpdateFileDto, UpdateOrganizationDto, UpdateRoleDto, UpdateSessionDto, UpdateUserDto, UpdateVerificationTokenDto, User, VerificationToken } from '@tmlmobilidade/types';
3
+ import { MongoInterfaceTemplate } from '../interface.template.js';
4
+ export declare class CoreDatabase {
5
+ readonly agencies: MongoInterfaceTemplate<Agency, CreateAgencyDto, UpdateAgencyDto>;
6
+ readonly exports: MongoInterfaceTemplate<FileExport, CreateFileExportDto<any>, Partial<FileExport>>;
7
+ readonly files: MongoInterfaceTemplate<File, CreateFileDto, UpdateFileDto>;
8
+ readonly organizations: MongoInterfaceTemplate<Organization, CreateOrganizationDto, UpdateOrganizationDto>;
9
+ readonly roles: MongoInterfaceTemplate<Role, CreateRoleDto, UpdateRoleDto>;
10
+ readonly sessions: MongoInterfaceTemplate<Session, CreateSessionDto, UpdateSessionDto>;
11
+ readonly users: MongoInterfaceTemplate<User, CreateUserDto, UpdateUserDto>;
12
+ readonly verificationTokens: MongoInterfaceTemplate<VerificationToken, CreateVerificationTokenDto, UpdateVerificationTokenDto>;
13
+ private readonly database;
14
+ private readonly databaseName;
15
+ constructor(instance: MongoClient);
16
+ }
@@ -0,0 +1,33 @@
1
+ /* * */
2
+ import { MongoInterfaceTemplate } from '../interface.template.js';
3
+ import { CreateAgencySchema, CreateFileExportSchema, CreateFileSchema, CreateOrganizationSchema, CreateRoleSchema, CreateSessionSchema, CreateUserSchema, CreateVerificationTokenSchema, UpdateAgencySchema, UpdateFileExportSchema, UpdateFileSchema, UpdateOrganizationSchema, UpdateRoleSchema, UpdateSessionSchema, UpdateUserSchema, UpdateVerificationTokenSchema } from '@tmlmobilidade/types';
4
+ /* * */
5
+ export class CoreDatabase {
6
+ //
7
+ //
8
+ // Collections
9
+ agencies;
10
+ exports;
11
+ files;
12
+ organizations;
13
+ roles;
14
+ sessions;
15
+ users;
16
+ verificationTokens;
17
+ //
18
+ database;
19
+ databaseName = 'core';
20
+ constructor(instance) {
21
+ // Create the database instance
22
+ this.database = instance.db(this.databaseName);
23
+ // Create collection interfaces
24
+ this.agencies = new MongoInterfaceTemplate('agencies', this.database, CreateAgencySchema, UpdateAgencySchema);
25
+ this.exports = new MongoInterfaceTemplate('exports', this.database, CreateFileExportSchema, UpdateFileExportSchema);
26
+ this.organizations = new MongoInterfaceTemplate('organizations', this.database, CreateOrganizationSchema, UpdateOrganizationSchema);
27
+ this.roles = new MongoInterfaceTemplate('roles', this.database, CreateRoleSchema, UpdateRoleSchema);
28
+ this.sessions = new MongoInterfaceTemplate('sessions', this.database, CreateSessionSchema, UpdateSessionSchema);
29
+ this.users = new MongoInterfaceTemplate('users', this.database, CreateUserSchema, UpdateUserSchema);
30
+ this.verificationTokens = new MongoInterfaceTemplate('verificationTokens', this.database, CreateVerificationTokenSchema, UpdateVerificationTokenSchema);
31
+ this.files = new MongoInterfaceTemplate('files', this.database, CreateFileSchema, UpdateFileSchema);
32
+ }
33
+ }
@@ -0,0 +1,9 @@
1
+ import type { MongoClient } from '@tmlmobilidade/go-clients-mongo';
2
+ import { MongoInterfaceTemplate } from '../interface.template.js';
3
+ import { CreateStopDto, Stop, UpdateStopDto } from '@tmlmobilidade/types';
4
+ export declare class InfrastructureDatabase {
5
+ readonly stops: MongoInterfaceTemplate<Stop, CreateStopDto, UpdateStopDto>;
6
+ private readonly database;
7
+ private readonly databaseName;
8
+ constructor(instance: MongoClient);
9
+ }
@@ -0,0 +1,19 @@
1
+ /* * */
2
+ import { MongoInterfaceTemplate } from '../interface.template.js';
3
+ import { CreateStopSchema, UpdateStopSchema } from '@tmlmobilidade/types';
4
+ /* * */
5
+ export class InfrastructureDatabase {
6
+ //
7
+ //
8
+ // Collections
9
+ stops;
10
+ //
11
+ database;
12
+ databaseName = 'infrastructure';
13
+ constructor(instance) {
14
+ // Create the database instance
15
+ this.database = instance.db(this.databaseName);
16
+ // Create collection interfaces
17
+ this.stops = new MongoInterfaceTemplate('stops', this.database, CreateStopSchema, UpdateStopSchema);
18
+ }
19
+ }
@@ -0,0 +1,12 @@
1
+ import type { MongoClient } from '@tmlmobilidade/go-clients-mongo';
2
+ import { MongoInterfaceTemplate } from '../interface.template.js';
3
+ import { District, Locality, Municipality, Parish } from '@tmlmobilidade/types';
4
+ export declare class LocationsDatabase {
5
+ readonly districts: MongoInterfaceTemplate<District, null, null>;
6
+ readonly localities: MongoInterfaceTemplate<Locality, null, null>;
7
+ readonly municipalities: MongoInterfaceTemplate<Municipality, null, null>;
8
+ readonly parishes: MongoInterfaceTemplate<Parish, null, null>;
9
+ private readonly database;
10
+ private readonly databaseName;
11
+ constructor(instance: MongoClient);
12
+ }
@@ -0,0 +1,24 @@
1
+ /* * */
2
+ import { MongoInterfaceTemplate } from '../interface.template.js';
3
+ /* * */
4
+ export class LocationsDatabase {
5
+ //
6
+ //
7
+ // Collections
8
+ districts;
9
+ localities;
10
+ municipalities;
11
+ parishes;
12
+ //
13
+ database;
14
+ databaseName = 'locations';
15
+ constructor(instance) {
16
+ // Create the database instance
17
+ this.database = instance.db(this.databaseName);
18
+ // Create collection interfaces
19
+ this.districts = new MongoInterfaceTemplate('districts', this.database, null, null);
20
+ this.localities = new MongoInterfaceTemplate('localities', this.database, null, null);
21
+ this.municipalities = new MongoInterfaceTemplate('municipalities', this.database, null, null);
22
+ this.parishes = new MongoInterfaceTemplate('parishes', this.database, null, null);
23
+ }
24
+ }
@@ -0,0 +1,18 @@
1
+ import type { Db, MongoClient } from '@tmlmobilidade/go-clients-mongo';
2
+ import { MongoInterfaceTemplate } from '../interface.template.js';
3
+ import { Annotation, CreateAnnotationDto, CreateEventDto, CreateFareDto, CreateHolidayDto, CreateLineDto, CreatePatternDto, CreateRouteDto, CreateTypologyDto, CreateYearPeriodDto, CreateZoneDto, Event, Fare, Holiday, Line, Pattern, Route, Typology, UpdateAnnotationDto, UpdateEventDto, UpdateFareDto, UpdateHolidayDto, UpdateLineDto, UpdatePatternDto, UpdateRouteDto, UpdateTypologyDto, UpdateYearPeriodDto, UpdateZoneDto, YearPeriod, Zone } from '@tmlmobilidade/types';
4
+ export declare class OfferDatabase {
5
+ readonly annotations: MongoInterfaceTemplate<Annotation, CreateAnnotationDto, UpdateAnnotationDto>;
6
+ readonly events: MongoInterfaceTemplate<Event, CreateEventDto, UpdateEventDto>;
7
+ readonly fares: MongoInterfaceTemplate<Fare, CreateFareDto, UpdateFareDto>;
8
+ readonly holidays: MongoInterfaceTemplate<Holiday, CreateHolidayDto, UpdateHolidayDto>;
9
+ readonly lines: MongoInterfaceTemplate<Line, CreateLineDto, UpdateLineDto>;
10
+ readonly patterns: MongoInterfaceTemplate<Pattern, CreatePatternDto, UpdatePatternDto>;
11
+ readonly routes: MongoInterfaceTemplate<Route, CreateRouteDto, UpdateRouteDto>;
12
+ readonly typologies: MongoInterfaceTemplate<Typology, CreateTypologyDto, UpdateTypologyDto>;
13
+ readonly yearPeriods: MongoInterfaceTemplate<YearPeriod, CreateYearPeriodDto, UpdateYearPeriodDto>;
14
+ readonly zones: MongoInterfaceTemplate<Zone, CreateZoneDto, UpdateZoneDto>;
15
+ readonly database: Db;
16
+ readonly databaseName = "offer";
17
+ constructor(instance: MongoClient);
18
+ }
@@ -0,0 +1,37 @@
1
+ /* * */
2
+ import { MongoInterfaceTemplate } from '../interface.template.js';
3
+ import { CreateAnnotationSchema, CreateEventSchema, CreateFareSchema, CreateHolidaySchema, CreateLineSchema, CreatePatternSchema, CreateRouteSchema, CreateTypologySchema, CreateYearPeriodSchema, CreateZoneSchema, UpdateAnnotationSchema, UpdateEventSchema, UpdateFareSchema, UpdateHolidaySchema, UpdateLineSchema, UpdatePatternSchema, UpdateRouteSchema, UpdateTypologySchema, UpdateYearPeriodSchema, UpdateZoneSchema } from '@tmlmobilidade/types';
4
+ /* * */
5
+ export class OfferDatabase {
6
+ //
7
+ //
8
+ // Collections
9
+ annotations;
10
+ events;
11
+ fares;
12
+ holidays;
13
+ lines;
14
+ patterns;
15
+ routes;
16
+ typologies;
17
+ yearPeriods;
18
+ zones;
19
+ //
20
+ database;
21
+ databaseName = 'offer';
22
+ constructor(instance) {
23
+ // Create the database instance
24
+ this.database = instance.db(this.databaseName);
25
+ // Create collection interfaces
26
+ this.annotations = new MongoInterfaceTemplate('annotations', this.database, CreateAnnotationSchema, UpdateAnnotationSchema);
27
+ this.events = new MongoInterfaceTemplate('events', this.database, CreateEventSchema, UpdateEventSchema);
28
+ this.fares = new MongoInterfaceTemplate('fares', this.database, CreateFareSchema, UpdateFareSchema);
29
+ this.holidays = new MongoInterfaceTemplate('holidays', this.database, CreateHolidaySchema, UpdateHolidaySchema);
30
+ this.lines = new MongoInterfaceTemplate('lines', this.database, CreateLineSchema, UpdateLineSchema);
31
+ this.patterns = new MongoInterfaceTemplate('patterns', this.database, CreatePatternSchema, UpdatePatternSchema);
32
+ this.routes = new MongoInterfaceTemplate('routes', this.database, CreateRouteSchema, UpdateRouteSchema);
33
+ this.typologies = new MongoInterfaceTemplate('typologies', this.database, CreateTypologySchema, UpdateTypologySchema);
34
+ this.yearPeriods = new MongoInterfaceTemplate('yearPeriods', this.database, CreateYearPeriodSchema, UpdateYearPeriodSchema);
35
+ this.zones = new MongoInterfaceTemplate('zones', this.database, CreateZoneSchema, UpdateZoneSchema);
36
+ }
37
+ }
@@ -0,0 +1,17 @@
1
+ import type { MongoClient } from '@tmlmobilidade/go-clients-mongo';
2
+ import { MongoInterfaceTemplate } from '../interface.template.js';
3
+ import { CreateGtfsValidationDto, CreatePlanDto, CreateRideAcceptanceDto, CreateRideDto, CreateSamDto, CreateVehicleDto, GtfsValidation, HashedPattern, HashedShape, HashedTrip, Plan, Ride, RideAcceptance, Sam, UpdateGtfsValidationDto, UpdatePlanDto, UpdateRideAcceptanceDto, UpdateRideDto, UpdateSamDto, UpdateVehicleDto, Vehicle } from '@tmlmobilidade/types';
4
+ export declare class OperationDatabase {
5
+ readonly gtfsValidations: MongoInterfaceTemplate<GtfsValidation, CreateGtfsValidationDto, UpdateGtfsValidationDto>;
6
+ readonly hashedPatterns: MongoInterfaceTemplate<HashedPattern, HashedPattern, HashedPattern>;
7
+ readonly hashedShapes: MongoInterfaceTemplate<HashedShape, HashedShape, HashedShape>;
8
+ readonly hashedTrips: MongoInterfaceTemplate<HashedTrip, HashedTrip, HashedTrip>;
9
+ readonly plans: MongoInterfaceTemplate<Plan, CreatePlanDto, UpdatePlanDto>;
10
+ readonly rideAcceptances: MongoInterfaceTemplate<RideAcceptance, CreateRideAcceptanceDto, UpdateRideAcceptanceDto>;
11
+ readonly rides: MongoInterfaceTemplate<Ride, CreateRideDto, UpdateRideDto>;
12
+ readonly sams: MongoInterfaceTemplate<Sam, CreateSamDto, UpdateSamDto>;
13
+ readonly vehicles: MongoInterfaceTemplate<Vehicle, CreateVehicleDto, UpdateVehicleDto>;
14
+ private readonly database;
15
+ private readonly databaseName;
16
+ constructor(instance: MongoClient);
17
+ }
@@ -0,0 +1,35 @@
1
+ /* * */
2
+ import { MongoInterfaceTemplate } from '../interface.template.js';
3
+ import { CreateGtfsValidationSchema, CreatePlanSchema, CreateRideAcceptanceSchema, CreateRideSchema, CreateSamSchema, CreateVehicleSchema, DocumentSchema, HashedPatternSchema, HashedTripSchema, UpdateGtfsValidationSchema, UpdatePlanSchema, UpdateRideAcceptanceSchema, UpdateRideSchema, UpdateSamSchema, UpdateVehicleSchema } from '@tmlmobilidade/types';
4
+ /* * */
5
+ export class OperationDatabase {
6
+ //
7
+ //
8
+ // Collections
9
+ gtfsValidations;
10
+ hashedPatterns;
11
+ hashedShapes;
12
+ hashedTrips;
13
+ plans;
14
+ rideAcceptances;
15
+ rides;
16
+ sams;
17
+ vehicles;
18
+ //
19
+ database;
20
+ databaseName = 'operation';
21
+ constructor(instance) {
22
+ // Create the database instance
23
+ this.database = instance.db(this.databaseName);
24
+ // Create collection interfaces
25
+ this.gtfsValidations = new MongoInterfaceTemplate('gtfsValidations', this.database, CreateGtfsValidationSchema, UpdateGtfsValidationSchema);
26
+ this.hashedPatterns = new MongoInterfaceTemplate('hashedPatterns', this.database, HashedPatternSchema, HashedPatternSchema);
27
+ this.hashedShapes = new MongoInterfaceTemplate('hashedShapes', this.database, DocumentSchema, DocumentSchema);
28
+ this.hashedTrips = new MongoInterfaceTemplate('hashedTrips', this.database, HashedTripSchema, HashedTripSchema);
29
+ this.plans = new MongoInterfaceTemplate('plans', this.database, CreatePlanSchema, UpdatePlanSchema);
30
+ this.rideAcceptances = new MongoInterfaceTemplate('rideAcceptances', this.database, CreateRideAcceptanceSchema, UpdateRideAcceptanceSchema);
31
+ this.rides = new MongoInterfaceTemplate('rides', this.database, CreateRideSchema, UpdateRideSchema);
32
+ this.sams = new MongoInterfaceTemplate('sams', this.database, CreateSamSchema, UpdateSamSchema);
33
+ this.vehicles = new MongoInterfaceTemplate('vehicles', this.database, CreateVehicleSchema, UpdateVehicleSchema);
34
+ }
35
+ }
@@ -0,0 +1,23 @@
1
+ import { CoreDatabase } from './databases/core.js';
2
+ import { InfrastructureDatabase } from './databases/infrastructure.js';
3
+ import { LocationsDatabase } from './databases/locations.js';
4
+ import { OfferDatabase } from './databases/offer.js';
5
+ import { OperationDatabase } from './databases/operation.js';
6
+ declare class GoDBClass {
7
+ private static _instance;
8
+ private mongoClient;
9
+ readonly core: CoreDatabase;
10
+ readonly infrastructure: InfrastructureDatabase;
11
+ readonly locations: LocationsDatabase;
12
+ readonly offer: OfferDatabase;
13
+ readonly operation: OperationDatabase;
14
+ /**
15
+ * Establishes a connection to the Mongo database and initializes the collection.
16
+ * @param options Optional Mongo client connection options.
17
+ * @throws Error if the environment variable for the database URI is missing or if the connection fails.
18
+ */
19
+ static getInstance(): Promise<GoDBClass>;
20
+ private constructor();
21
+ }
22
+ export declare const goDb: GoDBClass;
23
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,47 @@
1
+ /* * */
2
+ import { MongoDatabaseClient } from '@tmlmobilidade/go-clients-mongo';
3
+ import { asyncSingletonProxy } from '@tmlmobilidade/utils';
4
+ import { CoreDatabase } from './databases/core.js';
5
+ import { InfrastructureDatabase } from './databases/infrastructure.js';
6
+ import { LocationsDatabase } from './databases/locations.js';
7
+ import { OfferDatabase } from './databases/offer.js';
8
+ import { OperationDatabase } from './databases/operation.js';
9
+ /* * */
10
+ class GoDBClass {
11
+ //
12
+ //
13
+ //
14
+ static _instance;
15
+ mongoClient;
16
+ //
17
+ // Databases
18
+ core;
19
+ infrastructure;
20
+ locations;
21
+ offer;
22
+ operation;
23
+ /**
24
+ * Establishes a connection to the Mongo database and initializes the collection.
25
+ * @param options Optional Mongo client connection options.
26
+ * @throws Error if the environment variable for the database URI is missing or if the connection fails.
27
+ */
28
+ static async getInstance() {
29
+ if (!GoDBClass._instance) {
30
+ const mongoClient = await MongoDatabaseClient.getClient({ prefix: 'GODB' });
31
+ GoDBClass._instance = new GoDBClass(mongoClient);
32
+ }
33
+ return GoDBClass._instance;
34
+ }
35
+ //
36
+ // Constructor
37
+ //
38
+ // Constructor
39
+ constructor(mongoClient) {
40
+ this.core = new CoreDatabase(mongoClient);
41
+ this.infrastructure = new InfrastructureDatabase(mongoClient);
42
+ this.locations = new LocationsDatabase(mongoClient);
43
+ this.offer = new OfferDatabase(mongoClient);
44
+ this.operation = new OperationDatabase(mongoClient);
45
+ }
46
+ }
47
+ export const goDb = asyncSingletonProxy(GoDBClass);
@@ -0,0 +1,189 @@
1
+ import type { AggregationPipeline } from '@tmlmobilidade/go-clients-mongo';
2
+ import type { AggregateOptions, AggregationCursor, BulkWriteOptions, Collection, Db, DeleteOptions, DeleteResult, Document, Filter, FindOptions, Flatten, InsertManyResult, InsertOneOptions, InsertOneResult, UpdateOptions, UpdateResult, WithId } from '@tmlmobilidade/go-clients-mongo';
3
+ import { UnixTimestamp } from '@tmlmobilidade/go-types-shared';
4
+ import z from 'zod';
5
+ export declare class MongoInterfaceTemplate<T extends Document, TCreate, TUpdate> {
6
+ private readonly createSchema;
7
+ private readonly mongoCollection;
8
+ private readonly updateSchema;
9
+ /**
10
+ * @param collectionName - The name of the collection to create the interface for.
11
+ * @param databaseName - The name of the database to create the interface for.
12
+ * @param createSchema - The schema to use for creating documents.
13
+ * @param updateSchema - The schema to use for updating documents.
14
+ */
15
+ constructor(collectionName: string, database: Db, createSchema: null | z.ZodSchema, updateSchema: null | z.ZodSchema);
16
+ /**
17
+ * Gets the MongoDB collection instance.
18
+ * @returns The MongoDB collection instance
19
+ */
20
+ getCollection(): Promise<Collection<T>>;
21
+ /**
22
+ * Finds all distinct values for a key in the collection.
23
+ * @param key The key to find distinct values for.
24
+ * @returns A promise that resolves to an array of distinct values for the given key.
25
+ */
26
+ distinct<Key extends keyof WithId<T>>(key: Key, filter?: Filter<T>): Promise<Array<Flatten<WithId<T>[Key]>>>;
27
+ /**
28
+ * Checks if a document with the given key and value exists in the collection.
29
+ * @param key The key to check for existence.
30
+ * @param value The value of the key to check for existence.
31
+ * @returns A promise that resolves to true if the document exists, false otherwise.
32
+ */
33
+ exists<K extends keyof T>(key: K, value: T[K]): Promise<boolean>;
34
+ /**
35
+ * Checks if a document with the given ID exists in the collection.
36
+ * @param id The ID of the document to check for existence.
37
+ * @returns A promise that resolves to true if the document exists, false otherwise.
38
+ */
39
+ existsById(id: T['_id']): Promise<boolean>;
40
+ /**
41
+ * Finds multiple documents matching the filter criteria with optional pagination and sorting.
42
+ * @param filter (Optional) filter criteria to match documents.
43
+ * @param options (Optional) find options.
44
+ * @returns A promise that resolves to an array of matching documents.
45
+ */
46
+ findMany(filter?: Filter<T>, options?: FindOptions): Promise<WithId<T>[]>;
47
+ /**
48
+ * Finds a document by its ID.
49
+ * @param id The ID of the document to find.
50
+ * @param options Optional find options.
51
+ * @returns A promise that resolves to the matching document or null if not found.
52
+ */
53
+ findById(id: T['_id'], options?: FindOptions): Promise<null | WithId<T>>;
54
+ /**
55
+ * Finds a single document matching the filter criteria.
56
+ * @param filter The filter criteria to match the document.
57
+ * @param options (Optional) find options.
58
+ * @returns A promise that resolves to the matching document or null if not found.
59
+ */
60
+ findOne(filter: Filter<T>, options?: FindOptions): Promise<null | WithId<T>>;
61
+ /**
62
+ * Inserts multiple documents into the collection.
63
+ * @param docs - The documents to insert
64
+ * @param options - The options for the insert operation
65
+ * @returns A promise that resolves to the result of the insert operation
66
+ */
67
+ insertMany(docs: (TCreate & {
68
+ _id?: T['_id'];
69
+ created_at?: UnixTimestamp;
70
+ created_by?: string;
71
+ updated_at?: UnixTimestamp;
72
+ updated_by?: string;
73
+ })[], { options, unsafe }?: {
74
+ options?: BulkWriteOptions;
75
+ unsafe?: boolean;
76
+ }): Promise<InsertManyResult<T>>;
77
+ /**
78
+ * Inserts a single document into the collection.
79
+ * @param doc The document to insert.
80
+ * @param options The options for the insert operation.
81
+ * @returns A promise that resolves to the result of the insert operation.
82
+ */
83
+ insertOne<TReturnDocument extends boolean = true>(doc: TCreate & {
84
+ _id?: T['_id'];
85
+ created_at?: UnixTimestamp;
86
+ created_by?: string;
87
+ updated_at?: UnixTimestamp;
88
+ updated_by?: string;
89
+ }, { options, unsafe }?: {
90
+ options?: InsertOneOptions & {
91
+ returnResult?: TReturnDocument;
92
+ };
93
+ unsafe?: boolean;
94
+ }): Promise<TReturnDocument extends true ? WithId<T> : InsertOneResult<T>>;
95
+ /**
96
+ * Checks if a document with the given ID is locked or not.
97
+ * @param id The ID of the document to check.
98
+ * @returns A promise that resolves to the result of the check operation.
99
+ */
100
+ isLocked(filter: Filter<T>): Promise<boolean>;
101
+ /**
102
+ * Checks if a document with the given ID is locked or not.
103
+ * @param id The ID of the document to check.
104
+ * @returns A promise that resolves to the result of the check operation.
105
+ */
106
+ isLockedById(id: T['_id']): Promise<boolean>;
107
+ /**
108
+ * Toggle the lock status of a document by its ID.
109
+ * @param id The ID of the document to toggle lock status.
110
+ * @param forceValue Optional boolean to explicitly set the lock status.
111
+ * @returns A promise that resolves to the result of the update operation.
112
+ */
113
+ toggleLockById(id: T['_id'], forceValue?: boolean): Promise<void>;
114
+ /**
115
+ * Updates a document by its ID.
116
+ * @param id The ID of the document to update.
117
+ * @param updateFields The fields to update in the document.
118
+ * @param options Optional options for the update operation.
119
+ * @returns A promise that resolves to the result of the update operation.
120
+ */
121
+ updateById<TReturnDocument extends boolean = true>(id: T['_id'], updateFields: TUpdate, options?: UpdateOptions & {
122
+ forceIfLocked?: boolean;
123
+ returnResult?: TReturnDocument;
124
+ }): Promise<TReturnDocument extends true ? WithId<T> : UpdateResult<T>>;
125
+ /**
126
+ * Updates multiple documents matching the filter criteria.
127
+ * @param filter - The filter criteria to match documents to update
128
+ * @param updateFields - The fields to update in the documents
129
+ * @param options - The options for the update operation
130
+ * @returns A promise that resolves to the result of the update operation
131
+ */
132
+ updateMany<TReturnDocument extends boolean = true>(filter: Filter<T>, updateFields: TUpdate & {
133
+ updated_at?: UnixTimestamp;
134
+ updated_by?: string;
135
+ }, options?: UpdateOptions & {
136
+ returnResults?: TReturnDocument;
137
+ }): Promise<TReturnDocument extends true ? WithId<T>[] : UpdateResult<T>>;
138
+ /**
139
+ * Updates a single document matching the filter criteria.
140
+ * @param filter The filter criteria to match the document to update.
141
+ * @param updateFields The fields to update in the document.
142
+ * @param options The options for the update operation.
143
+ * @returns A promise that resolves to the result of the update operation.
144
+ */
145
+ updateOne<TReturnDocument extends boolean = true>(filter: Filter<T>, updateFields: TUpdate, options?: UpdateOptions & {
146
+ forceIfLocked?: boolean;
147
+ returnResult?: TReturnDocument;
148
+ }): Promise<TReturnDocument extends true ? WithId<T> : UpdateResult<T>>;
149
+ /**
150
+ * Counts documents matching the filter criteria.
151
+ * @param filter The filter criteria to match documents.
152
+ * @returns A promise that resolves to the count of matching documents.
153
+ */
154
+ count(filter?: Filter<T>): Promise<number>;
155
+ /**
156
+ * Deletes a single document by its ID.
157
+ * @param id The ID of the document to delete.
158
+ * @returns A promise that resolves to the result of the delete operation.
159
+ */
160
+ deleteById(id: T['_id'], options?: DeleteOptions & {
161
+ forceIfLocked?: boolean;
162
+ }): Promise<DeleteResult>;
163
+ /**
164
+ * Deletes multiple documents matching the filter criteria.
165
+ * @param filter The filter criteria to match documents to delete.
166
+ * @returns A promise that resolves to the result of the delete many operation.
167
+ */
168
+ deleteMany(filter: Filter<T>): Promise<DeleteResult>;
169
+ /**
170
+ * Deletes a single document matching the filter criteria.
171
+ * @param filter The filter criteria to match the document to delete.
172
+ * @returns A promise that resolves to the result of the delete operation.
173
+ */
174
+ deleteOne(filter: Filter<T>, options?: DeleteOptions & {
175
+ forceIfLocked?: boolean;
176
+ }): Promise<DeleteResult>;
177
+ /**
178
+ * Aggregates documents in the collection.
179
+ * @param pipeline The aggregation pipeline to execute.
180
+ * @param options The options for the aggregation operation.
181
+ * @returns A promise that resolves to an array of aggregated documents.
182
+ */
183
+ aggregate(pipeline: AggregationPipeline<T>, options?: AggregateOptions & {
184
+ returnResult?: true;
185
+ }): Promise<T[]>;
186
+ aggregate(pipeline: AggregationPipeline<T>, options: AggregateOptions & {
187
+ returnResult: false;
188
+ }): Promise<AggregationCursor<T>>;
189
+ }
@@ -0,0 +1,376 @@
1
+ /* * */
2
+ import { HTTP_STATUS, HttpException } from '@tmlmobilidade/consts';
3
+ import { Dates } from '@tmlmobilidade/dates';
4
+ import { generateRandomString } from '@tmlmobilidade/strings';
5
+ /* * */
6
+ export class MongoInterfaceTemplate {
7
+ //
8
+ createSchema = null;
9
+ mongoCollection;
10
+ updateSchema = null;
11
+ /**
12
+ * @param collectionName - The name of the collection to create the interface for.
13
+ * @param databaseName - The name of the database to create the interface for.
14
+ * @param createSchema - The schema to use for creating documents.
15
+ * @param updateSchema - The schema to use for updating documents.
16
+ */
17
+ constructor(collectionName, database, createSchema, updateSchema) {
18
+ this.mongoCollection = database.collection(collectionName);
19
+ this.createSchema = createSchema;
20
+ this.updateSchema = updateSchema;
21
+ }
22
+ /**
23
+ * Gets the MongoDB collection instance.
24
+ * @returns The MongoDB collection instance
25
+ */
26
+ async getCollection() {
27
+ return this.mongoCollection;
28
+ }
29
+ /**
30
+ * Finds all distinct values for a key in the collection.
31
+ * @param key The key to find distinct values for.
32
+ * @returns A promise that resolves to an array of distinct values for the given key.
33
+ */
34
+ async distinct(key, filter = {}) {
35
+ return this.mongoCollection.distinct(key, filter);
36
+ }
37
+ /**
38
+ * Checks if a document with the given key and value exists in the collection.
39
+ * @param key The key to check for existence.
40
+ * @param value The value of the key to check for existence.
41
+ * @returns A promise that resolves to true if the document exists, false otherwise.
42
+ */
43
+ async exists(key, value) {
44
+ const filter = { [key]: value };
45
+ const doc = await this.mongoCollection.findOne(filter, { projection: { [key]: 1 } });
46
+ return !!doc;
47
+ }
48
+ /**
49
+ * Checks if a document with the given ID exists in the collection.
50
+ * @param id The ID of the document to check for existence.
51
+ * @returns A promise that resolves to true if the document exists, false otherwise.
52
+ */
53
+ async existsById(id) {
54
+ const foundDoc = await this.mongoCollection.findOne({ _id: id }, { projection: { _id: 1 } });
55
+ return !!foundDoc;
56
+ }
57
+ /**
58
+ * Finds multiple documents matching the filter criteria with optional pagination and sorting.
59
+ * @param filter (Optional) filter criteria to match documents.
60
+ * @param options (Optional) find options.
61
+ * @returns A promise that resolves to an array of matching documents.
62
+ */
63
+ async findMany(filter, options) {
64
+ return await this.mongoCollection.find(filter ?? {}, options).toArray();
65
+ }
66
+ /**
67
+ * Finds a document by its ID.
68
+ * @param id The ID of the document to find.
69
+ * @param options Optional find options.
70
+ * @returns A promise that resolves to the matching document or null if not found.
71
+ */
72
+ async findById(id, options) {
73
+ return this.mongoCollection.findOne({ _id: { $eq: id } }, options);
74
+ }
75
+ /**
76
+ * Finds a single document matching the filter criteria.
77
+ * @param filter The filter criteria to match the document.
78
+ * @param options (Optional) find options.
79
+ * @returns A promise that resolves to the matching document or null if not found.
80
+ */
81
+ async findOne(filter, options) {
82
+ return await this.mongoCollection.findOne(filter, options);
83
+ }
84
+ /**
85
+ * Inserts multiple documents into the collection.
86
+ * @param docs - The documents to insert
87
+ * @param options - The options for the insert operation
88
+ * @returns A promise that resolves to the result of the insert operation
89
+ */
90
+ async insertMany(docs, { options, unsafe = false } = {}) {
91
+ const newDocuments = [];
92
+ const usedIds = new Set((await this.mongoCollection.find({ _id: { $in: docs.map(doc => doc._id).filter(Boolean) } }, { projection: { _id: 1 } }).toArray()).map(doc => doc._id));
93
+ for (const doc of docs) {
94
+ let id = doc._id;
95
+ if (!id || usedIds.has(id)) {
96
+ do {
97
+ id = generateRandomString({ length: 5 });
98
+ } while (usedIds.has(id));
99
+ }
100
+ usedIds.add(id);
101
+ newDocuments.push({
102
+ ...doc,
103
+ _id: id,
104
+ created_at: doc.created_at || Dates.now('utc').unix_timestamp,
105
+ created_by: doc.created_by || 'system',
106
+ updated_at: doc.updated_at || Dates.now('utc').unix_timestamp,
107
+ updated_by: doc.updated_by || 'system',
108
+ });
109
+ }
110
+ const parsedDocuments = [];
111
+ for (const newDocument of newDocuments) {
112
+ let parsedDocument = newDocument;
113
+ if (!unsafe) {
114
+ try {
115
+ if (!this.createSchema) {
116
+ throw new Error('No schema defined for insert operation. This is either an internal interface error or you should pass unsafe=true to the insert operation.');
117
+ }
118
+ parsedDocument = this.createSchema.parse(newDocument);
119
+ }
120
+ catch (error) {
121
+ throw new HttpException(HTTP_STATUS.BAD_REQUEST, error.message, { cause: error });
122
+ }
123
+ }
124
+ parsedDocuments.push(parsedDocument);
125
+ }
126
+ return await this.mongoCollection.insertMany(parsedDocuments, options);
127
+ }
128
+ /**
129
+ * Inserts a single document into the collection.
130
+ * @param doc The document to insert.
131
+ * @param options The options for the insert operation.
132
+ * @returns A promise that resolves to the result of the insert operation.
133
+ */
134
+ async insertOne(doc, { options, unsafe = false } = {}) {
135
+ // Setup a copy of the document to be inserted with defaults
136
+ let parsedDocument = {
137
+ ...doc,
138
+ created_at: doc.created_at || Dates.now('utc').unix_timestamp,
139
+ created_by: doc.created_by || 'system',
140
+ updated_at: doc.updated_at || Dates.now('utc').unix_timestamp,
141
+ updated_by: doc.updated_by || 'system',
142
+ };
143
+ // Validate the document against the create schema if unsafe is false
144
+ if (!unsafe) {
145
+ try {
146
+ if (!this.createSchema)
147
+ throw new Error('No schema defined for insert operation. This is either an internal interface error or you should pass unsafe=true to the insert operation.');
148
+ parsedDocument = this.createSchema.parse(parsedDocument);
149
+ }
150
+ catch (error) {
151
+ throw new HttpException(HTTP_STATUS.BAD_REQUEST, error.message, { cause: error });
152
+ }
153
+ }
154
+ // Add the ID if it is missing from the original document
155
+ if (!doc._id) {
156
+ parsedDocument._id = generateRandomString({ length: 5 });
157
+ while (await this.findById(parsedDocument._id)) {
158
+ parsedDocument._id = generateRandomString({ length: 5 });
159
+ }
160
+ }
161
+ // Attempt to insert the document into the collection
162
+ const result = await this.mongoCollection.insertOne(parsedDocument, options);
163
+ // Check if the insert operation was acknowledged
164
+ if (!result.acknowledged)
165
+ throw new HttpException(HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Failed to insert document', result);
166
+ // If returnResult is false, return the insert result directly
167
+ if (options?.returnResult === false)
168
+ return result;
169
+ // Otherwise, fetch and return the inserted document
170
+ const insertedDoc = await this.findOne({ _id: { $eq: result.insertedId } }, options);
171
+ if (!insertedDoc)
172
+ throw new HttpException(HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Failed to find inserted document', result);
173
+ return insertedDoc;
174
+ }
175
+ /**
176
+ * Checks if a document with the given ID is locked or not.
177
+ * @param id The ID of the document to check.
178
+ * @returns A promise that resolves to the result of the check operation.
179
+ */
180
+ async isLocked(filter) {
181
+ // Fetch the document by its ID from the database
182
+ const foundDoc = await this.findOne(filter);
183
+ // If the document has a is_locked field and it resolves to a truthy value,
184
+ // then the document is considered locked.
185
+ if (foundDoc?.is_locked)
186
+ return true;
187
+ // Otherwise, the document is not locked.
188
+ return false;
189
+ }
190
+ /**
191
+ * Checks if a document with the given ID is locked or not.
192
+ * @param id The ID of the document to check.
193
+ * @returns A promise that resolves to the result of the check operation.
194
+ */
195
+ async isLockedById(id) {
196
+ // Fetch the document by its ID from the database
197
+ const foundDoc = await this.findById(id);
198
+ // If the document has an is_locked field and it resolves
199
+ // to a truthy value, then the document is considered locked.
200
+ if (foundDoc?.is_locked)
201
+ return true;
202
+ // Otherwise, the document is not locked.
203
+ return false;
204
+ }
205
+ /**
206
+ * Toggle the lock status of a document by its ID.
207
+ * @param id The ID of the document to toggle lock status.
208
+ * @param forceValue Optional boolean to explicitly set the lock status.
209
+ * @returns A promise that resolves to the result of the update operation.
210
+ */
211
+ async toggleLockById(id, forceValue) {
212
+ // Get the current document from the database
213
+ const foundDoc = await this.findById(id);
214
+ if (!foundDoc)
215
+ throw new Error('Document not found');
216
+ // Determine the new lock status
217
+ const newLockStatus = forceValue !== undefined ? forceValue : !foundDoc.is_locked;
218
+ // Update the document with the new lock status
219
+ await this.mongoCollection.updateOne({ _id: { $eq: id } }, { $set: { is_locked: newLockStatus } });
220
+ }
221
+ /**
222
+ * Updates a document by its ID.
223
+ * @param id The ID of the document to update.
224
+ * @param updateFields The fields to update in the document.
225
+ * @param options Optional options for the update operation.
226
+ * @returns A promise that resolves to the result of the update operation.
227
+ */
228
+ async updateById(id, updateFields, options) {
229
+ // If forceIfLocked is not set then check if the document is locked.
230
+ // If it is locked, then throw an error to prevent the operation.
231
+ if (!options?.forceIfLocked) {
232
+ const isLocked = await this.isLockedById(id);
233
+ if (isLocked)
234
+ throw new HttpException(HTTP_STATUS.FORBIDDEN, 'Document is locked and cannot be updated');
235
+ }
236
+ // Perform the update operation
237
+ return this.updateOne({ _id: { $eq: id } }, updateFields, options);
238
+ }
239
+ /**
240
+ * Updates multiple documents matching the filter criteria.
241
+ * @param filter - The filter criteria to match documents to update
242
+ * @param updateFields - The fields to update in the documents
243
+ * @param options - The options for the update operation
244
+ * @returns A promise that resolves to the result of the update operation
245
+ */
246
+ async updateMany(filter, updateFields, options) {
247
+ let parsedUpdateFields = {
248
+ ...updateFields,
249
+ updated_at: updateFields.updated_at || Dates.now('utc').unix_timestamp,
250
+ updated_by: updateFields.updated_by || 'system',
251
+ };
252
+ if (this.updateSchema) {
253
+ try {
254
+ parsedUpdateFields = this.updateSchema.parse(updateFields);
255
+ }
256
+ catch (error) {
257
+ throw new HttpException(HTTP_STATUS.BAD_REQUEST, error.message, { cause: error });
258
+ }
259
+ }
260
+ const result = await this.mongoCollection.updateMany(filter, { $set: { ...parsedUpdateFields, updated_at: Dates.now('utc').unix_timestamp } }, options);
261
+ if (options?.returnResults === false)
262
+ return result;
263
+ if (!result.acknowledged) {
264
+ throw new HttpException(HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Failed to update documents', result);
265
+ }
266
+ const updatedDocuments = await this.findMany(filter, options);
267
+ if (!updatedDocuments) {
268
+ throw new HttpException(HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Failed to find updated documents', result);
269
+ }
270
+ return updatedDocuments;
271
+ }
272
+ /**
273
+ * Updates a single document matching the filter criteria.
274
+ * @param filter The filter criteria to match the document to update.
275
+ * @param updateFields The fields to update in the document.
276
+ * @param options The options for the update operation.
277
+ * @returns A promise that resolves to the result of the update operation.
278
+ */
279
+ async updateOne(filter, updateFields, options) {
280
+ // If forceIfLocked is not set then check if the document is locked.
281
+ // If it is locked, then throw an error to prevent the operation.
282
+ if (!options?.forceIfLocked) {
283
+ const isLocked = await this.isLocked(filter);
284
+ if (isLocked)
285
+ throw new HttpException(HTTP_STATUS.FORBIDDEN, 'Document is locked and cannot be updated');
286
+ }
287
+ // Perform the update operation
288
+ let parsedUpdateFields = updateFields;
289
+ if (this.updateSchema) {
290
+ try {
291
+ parsedUpdateFields = this.updateSchema.parse(updateFields);
292
+ }
293
+ catch (error) {
294
+ throw new HttpException(HTTP_STATUS.BAD_REQUEST, error.message, { cause: error });
295
+ }
296
+ }
297
+ const result = await this.mongoCollection.updateOne(filter, { $set: { ...parsedUpdateFields, updated_at: Dates.now('utc').unix_timestamp } }, options);
298
+ if (options?.returnResult === false)
299
+ return result;
300
+ if (!result.acknowledged) {
301
+ throw new HttpException(HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Failed to update documents', result);
302
+ }
303
+ const updatedDocument = await this.findOne(filter, options);
304
+ if (!updatedDocument)
305
+ throw new HttpException(HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Failed to find updated document', result);
306
+ return updatedDocument;
307
+ }
308
+ /**
309
+ * Counts documents matching the filter criteria.
310
+ * @param filter The filter criteria to match documents.
311
+ * @returns A promise that resolves to the count of matching documents.
312
+ */
313
+ async count(filter) {
314
+ return await this.mongoCollection.countDocuments(filter);
315
+ }
316
+ /**
317
+ * Deletes a single document by its ID.
318
+ * @param id The ID of the document to delete.
319
+ * @returns A promise that resolves to the result of the delete operation.
320
+ */
321
+ async deleteById(id, options) {
322
+ // If forceIfLocked is not set then check if the document is locked.
323
+ // If it is locked, then throw an error to prevent the operation.
324
+ if (!options?.forceIfLocked) {
325
+ const isLocked = await this.isLockedById(id);
326
+ if (isLocked)
327
+ throw new HttpException(HTTP_STATUS.FORBIDDEN, 'Document is locked and cannot be deleted');
328
+ }
329
+ // Perform the delete operation
330
+ const result = await this.deleteOne({ _id: { $eq: id } }, options);
331
+ // Check if the delete operation was acknowledged
332
+ if (!result.acknowledged)
333
+ throw new HttpException(HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Failed to delete documents', result);
334
+ // Return the result of the delete operation
335
+ return result;
336
+ }
337
+ /**
338
+ * Deletes multiple documents matching the filter criteria.
339
+ * @param filter The filter criteria to match documents to delete.
340
+ * @returns A promise that resolves to the result of the delete many operation.
341
+ */
342
+ async deleteMany(filter) {
343
+ const result = await this.mongoCollection.deleteMany(filter);
344
+ if (!result.acknowledged)
345
+ throw new HttpException(HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Failed to delete documents', result);
346
+ return result;
347
+ }
348
+ /**
349
+ * Deletes a single document matching the filter criteria.
350
+ * @param filter The filter criteria to match the document to delete.
351
+ * @returns A promise that resolves to the result of the delete operation.
352
+ */
353
+ async deleteOne(filter, options) {
354
+ // If forceIfLocked is not set then check if the document is locked.
355
+ // If it is locked, then throw an error to prevent the operation.
356
+ if (!options?.forceIfLocked) {
357
+ const isLocked = await this.isLocked(filter);
358
+ if (isLocked)
359
+ throw new HttpException(HTTP_STATUS.FORBIDDEN, 'Document is locked and cannot be deleted');
360
+ }
361
+ // Perform the delete operation
362
+ const result = await this.mongoCollection.deleteOne(filter, options);
363
+ if (!result.acknowledged)
364
+ throw new HttpException(HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Failed to delete document', result);
365
+ return result;
366
+ }
367
+ async aggregate(pipeline, options) {
368
+ // Perform the aggregation pipeline
369
+ const aggregationResult = this.mongoCollection.aggregate(pipeline, options);
370
+ // If returnResult is false, return the cursor directly
371
+ if (options?.returnResult === false)
372
+ return aggregationResult;
373
+ // Otherwise, return the aggregated documents as an array
374
+ return aggregationResult.toArray();
375
+ }
376
+ }
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@tmlmobilidade/go-interfaces-godb",
3
+ "version": "20260717.1316.58",
4
+ "author": {
5
+ "email": "iso@tmlmobilidade.pt",
6
+ "name": "TML-ISO"
7
+ },
8
+ "license": "AGPL-3.0-or-later",
9
+ "homepage": "https://go.tmlmobilidade.pt",
10
+ "bugs": {
11
+ "url": "https://github.com/tmlmobilidade/go/issues"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/tmlmobilidade/go.git"
16
+ },
17
+ "keywords": [
18
+ "public transit",
19
+ "tml",
20
+ "transportes metropolitanos de lisboa",
21
+ "go"
22
+ ],
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "type": "module",
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "main": "./dist/index.js",
31
+ "types": "./dist/index.d.ts",
32
+ "scripts": {
33
+ "build": "tsc && resolve-tspaths",
34
+ "lint": "eslint ./src/ && tsc --noEmit",
35
+ "lint:fix": "eslint ./src/ --fix",
36
+ "watch": "tsc-watch --onSuccess 'resolve-tspaths'"
37
+ },
38
+ "dependencies": {
39
+ "@tmlmobilidade/consts": "*",
40
+ "@tmlmobilidade/dates": "*",
41
+ "@tmlmobilidade/go-clients-mongo": "*",
42
+ "@tmlmobilidade/go-types-shared": "*",
43
+ "@tmlmobilidade/logger": "*",
44
+ "@tmlmobilidade/strings": "*",
45
+ "@tmlmobilidade/types": "*",
46
+ "@tmlmobilidade/utils": "*",
47
+ "bcryptjs": "3.0.3",
48
+ "luxon": "3.7.2",
49
+ "zod": "3.25.76"
50
+ },
51
+ "devDependencies": {
52
+ "@tmlmobilidade/tsconfig": "*",
53
+ "@types/luxon": "3.7.2",
54
+ "@types/node": "26.1.1",
55
+ "resolve-tspaths": "0.8.23",
56
+ "tsc-watch": "7.2.1",
57
+ "typescript": "6.0.3"
58
+ }
59
+ }