@tmlmobilidade/interfaces 20251003.1758.39 → 20251006.1126.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './src/aggregation-pipeline.js';
2
+ export * from './src/enrich-user-refs.js';
2
3
  export * from './src/interfaces/index.js';
3
4
  export * from './src/mongo-collection.js';
4
5
  export * from './src/mongo-transaction.js';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  /* * */
2
2
  export * from './src/aggregation-pipeline.js';
3
+ export * from './src/enrich-user-refs.js';
3
4
  export * from './src/interfaces/index.js';
4
5
  export * from './src/mongo-collection.js';
5
6
  export * from './src/mongo-transaction.js';
@@ -0,0 +1,4 @@
1
+ type AnyDoc = Record<string, any>;
2
+ export declare function enrichUserRefs<T extends AnyDoc>(doc: T): Promise<T>;
3
+ export declare function enrichUserRefsMany<T extends AnyDoc>(docs: T[]): Promise<T[]>;
4
+ export {};
@@ -0,0 +1,75 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { users } from './interfaces/auth/users.js';
3
+ import { UserDisplayFields } from '@tmlmobilidade/types';
4
+ const isUserRefKey = (k) => k === 'created_by' || k === 'updated_by';
5
+ const isEligibleId = (v) => typeof v === 'string' && v && v !== 'system';
6
+ function collectUserIds(input, out) {
7
+ if (Array.isArray(input)) {
8
+ for (const item of input)
9
+ collectUserIds(item, out);
10
+ return;
11
+ }
12
+ if (input && typeof input === 'object') {
13
+ for (const [k, v] of Object.entries(input)) {
14
+ if (isUserRefKey(k) && isEligibleId(v))
15
+ out.add(v);
16
+ collectUserIds(v, out);
17
+ }
18
+ }
19
+ }
20
+ function replaceRefs(input, map) {
21
+ if (Array.isArray(input)) {
22
+ return input.map(item => replaceRefs(item, map));
23
+ }
24
+ if (input && typeof input === 'object') {
25
+ const obj = input;
26
+ const out = Array.isArray(obj) ? [] : {};
27
+ for (const [k, v] of Object.entries(obj)) {
28
+ if (isUserRefKey(k) && typeof v === 'string' && v !== 'system') {
29
+ const found = map.get(v);
30
+ out[k] = found ?? v; // fallback to original id if user not found
31
+ }
32
+ else {
33
+ out[k] = replaceRefs(v, map);
34
+ }
35
+ }
36
+ return out;
37
+ }
38
+ return input;
39
+ }
40
+ async function fetchUsersMap(ids) {
41
+ if (ids.size === 0)
42
+ return new Map();
43
+ const coll = await users.getCollection();
44
+ // Only fetch UserDisplay fields
45
+ const projection = Object.keys(UserDisplayFields).reduce((acc, field) => {
46
+ acc[field] = 1;
47
+ return acc;
48
+ }, {});
49
+ const result = await coll.find({ _id: { $in: Array.from(ids) } }, { projection }).toArray();
50
+ const map = new Map();
51
+ for (const u of result) {
52
+ map.set(u._id, {
53
+ _id: u._id,
54
+ avatar: u.avatar ?? undefined,
55
+ email: u.email,
56
+ first_name: u.first_name,
57
+ last_name: u.last_name,
58
+ phone: u.phone ?? undefined,
59
+ });
60
+ }
61
+ return map;
62
+ }
63
+ export async function enrichUserRefs(doc) {
64
+ const ids = new Set();
65
+ collectUserIds(doc, ids);
66
+ const map = await fetchUsersMap(ids);
67
+ return replaceRefs(doc, map);
68
+ }
69
+ export async function enrichUserRefsMany(docs) {
70
+ const ids = new Set();
71
+ for (const d of docs)
72
+ collectUserIds(d, ids);
73
+ const map = await fetchUsersMap(ids);
74
+ return docs.map(d => replaceRefs(d, map));
75
+ }
@@ -2,7 +2,6 @@ import { MongoCollectionClass } from '../../mongo-collection.js';
2
2
  import { CreateUserDto, UpdateUserDto, User } from '@tmlmobilidade/types';
3
3
  import { Filter, FindOptions, IndexDescription, WithId } from 'mongodb';
4
4
  import { z } from 'zod';
5
- type NewType = string;
6
5
  declare class UsersClass extends MongoCollectionClass<User, CreateUserDto, UpdateUserDto> {
7
6
  private static _instance;
8
7
  protected createSchema: z.ZodSchema;
@@ -32,7 +31,7 @@ declare class UsersClass extends MongoCollectionClass<User, CreateUserDto, Updat
32
31
  * @param includePasswordHash - Whether to include the password hash in the result
33
32
  * @returns A promise that resolves to the matching user documents or null if not found
34
33
  */
35
- findByOrganization(id: NewType, includePasswordHash?: boolean): Promise<{
34
+ findByOrganization(id: string, includePasswordHash?: boolean): Promise<{
36
35
  created_at: number & {
37
36
  __brand: "UnixTimestamp";
38
37
  };
@@ -41,16 +40,16 @@ declare class UsersClass extends MongoCollectionClass<User, CreateUserDto, Updat
41
40
  };
42
41
  created_by?: string | undefined | undefined;
43
42
  updated_by?: string | undefined | undefined;
44
- phone?: string | null | undefined | undefined;
45
- email: string;
46
- permissions: import("@tmlmobilidade/types").Permission<unknown>[];
47
43
  active_notifications: string[];
48
44
  avatar?: string | null | undefined | undefined;
49
45
  bio?: string | null | undefined | undefined;
46
+ email: string;
50
47
  email_verified?: import("@tmlmobilidade/types").UnixTimestamp | null | undefined;
51
48
  first_name: string;
52
49
  last_name: string;
53
50
  organization_id?: string | null | undefined | undefined;
51
+ permissions: import("@tmlmobilidade/types").Permission<unknown>[];
52
+ phone?: string | null | undefined | undefined;
54
53
  preferences?: Record<string, Record<string, string | number | boolean | string[] | number[]>> | null | undefined;
55
54
  role_ids: string[];
56
55
  session_ids: string[];
@@ -74,16 +73,16 @@ declare class UsersClass extends MongoCollectionClass<User, CreateUserDto, Updat
74
73
  };
75
74
  created_by?: string | undefined | undefined;
76
75
  updated_by?: string | undefined | undefined;
77
- phone?: string | null | undefined | undefined;
78
- email: string;
79
- permissions: import("@tmlmobilidade/types").Permission<unknown>[];
80
76
  active_notifications: string[];
81
77
  avatar?: string | null | undefined | undefined;
82
78
  bio?: string | null | undefined | undefined;
79
+ email: string;
83
80
  email_verified?: import("@tmlmobilidade/types").UnixTimestamp | null | undefined;
84
81
  first_name: string;
85
82
  last_name: string;
86
83
  organization_id?: string | null | undefined | undefined;
84
+ permissions: import("@tmlmobilidade/types").Permission<unknown>[];
85
+ phone?: string | null | undefined | undefined;
87
86
  preferences?: Record<string, Record<string, string | number | boolean | string[] | number[]>> | null | undefined;
88
87
  role_ids: string[];
89
88
  session_ids: string[];
@@ -2,6 +2,7 @@
2
2
  import { MongoCollectionClass } from '../../mongo-collection.js';
3
3
  import { UpdateUserSchema, UserSchema } from '@tmlmobilidade/types';
4
4
  import { AsyncSingletonProxy } from '@tmlmobilidade/utils';
5
+ /* * */
5
6
  class UsersClass extends MongoCollectionClass {
6
7
  static _instance;
7
8
  createSchema = UserSchema;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmlmobilidade/interfaces",
3
- "version": "20251003.1758.39",
3
+ "version": "20251006.1126.43",
4
4
  "author": "João de Vasconcelos & Jusi Monteiro",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "homepage": "https://github.com/tmlmobilidade/services#readme",
@@ -36,8 +36,8 @@
36
36
  "lint:fix": "eslint --fix"
37
37
  },
38
38
  "dependencies": {
39
- "@aws-sdk/client-s3": "3.899.0",
40
- "@aws-sdk/s3-request-presigner": "3.899.0",
39
+ "@aws-sdk/client-s3": "3.901.0",
40
+ "@aws-sdk/s3-request-presigner": "3.901.0",
41
41
  "@tmlmobilidade/connectors": "*",
42
42
  "@tmlmobilidade/emails": "*",
43
43
  "@tmlmobilidade/lib": "*",
@@ -54,7 +54,7 @@
54
54
  "devDependencies": {
55
55
  "@carrismetropolitana/eslint": "20250622.1204.50",
56
56
  "@types/luxon": "3.7.1",
57
- "@types/node": "24.6.1",
57
+ "@types/node": "24.7.0",
58
58
  "resolve-tspaths": "0.8.23",
59
59
  "rimraf": "6.0.1",
60
60
  "typescript": "5.9.3"