pangea-server 3.3.81 → 3.3.83

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.
@@ -6,8 +6,10 @@ export declare class AccessToken {
6
6
  getKey(userCtor: UserCtor): string;
7
7
  createToken(userCtor: UserCtor, id: ModelId): string;
8
8
  verifyToken(token: string): Record<string, ModelId>;
9
- getTokenData(userCtor: UserCtor, user: User): {
9
+ getTokenData(userCtor: UserCtor, user: ModelInstance<User>): {
10
10
  accessToken: string;
11
- user: User;
11
+ user: import("sequelize").InferAttributes<User, {
12
+ omit: never;
13
+ }>;
12
14
  };
13
15
  }
@@ -4,14 +4,22 @@ import type { UserCtor, AuthMap } from './auth.types';
4
4
  type AuthHeader = string | undefined;
5
5
  export declare function login<U extends User>(authHeader: AuthHeader, db: Db, accessToken: AccessToken, userCtor: BaseModelCtor<U>, extraWhere?: Where<U>): Promise<{
6
6
  accessToken: string;
7
- user: User;
7
+ user: import("sequelize").InferAttributes<User, {
8
+ omit: never;
9
+ }>;
8
10
  }>;
9
11
  export declare function validateAccessToken(authHeader: AuthHeader, db: Db, accessToken: AccessToken, userCtor: UserCtor): Promise<{
10
12
  accessToken: string;
11
- user: User;
13
+ user: import("sequelize").InferAttributes<User, {
14
+ omit: never;
15
+ }>;
12
16
  }>;
13
- export declare function getUserFromToken(authHeader: AuthHeader, db: Db, accessToken: AccessToken, userCtor: UserCtor): Promise<User | null> | null;
17
+ export declare function getUserFromToken(authHeader: AuthHeader, db: Db, accessToken: AccessToken, userCtor: UserCtor): Promise<import("sequelize").InferAttributes<User, {
18
+ omit: never;
19
+ }> | null> | null;
14
20
  export declare function getUsersFromToken(authHeader: AuthHeader, db: Db, accessToken: AccessToken, authMap: AuthMap): Promise<{
15
- [k: string]: User | null;
21
+ [k: string]: import("sequelize").InferAttributes<User, {
22
+ omit: never;
23
+ }> | null;
16
24
  }>;
17
25
  export {};
@@ -4,7 +4,7 @@ export type UserCtor = BaseModelCtor<User>;
4
4
  export type AuthMap = Record<string, UserCtor>;
5
5
  export type UserType<AM extends AuthMap> = keyof AM;
6
6
  export type AuthUsers<AM extends AuthMap> = {
7
- [K in keyof AM]: InstanceType<AM[K]> | null;
7
+ [K in keyof AM]: ModelInstance<InstanceType<AM[K]>> | null;
8
8
  };
9
9
  export interface AuthCtor<AM extends AuthMap, AU extends AuthUsers<AM>, BA extends BaseAuth<AM>, IR extends any> {
10
10
  new (authUsers: AU, initRes?: IR): BA;
@@ -7,5 +7,7 @@ export declare abstract class BaseAuth<AM extends AuthMap> {
7
7
  notAllowed(): never;
8
8
  isUserAuth<T extends UserType<AM>>(type: T): boolean;
9
9
  getUserAuth<T extends UserType<AM>>(type: T): NonNullable<AuthUsers<AM>[T]>;
10
- getUsersAuth<const T extends readonly UserType<AM>[]>(types: T): { [I in keyof T]: InstanceType<AM[T[I]]> | null; };
10
+ getUsersAuth<const T extends readonly UserType<AM>[]>(types: T): { [I in keyof T]: import("sequelize").InferAttributes<InstanceType<AM[T[I]]>, {
11
+ omit: never;
12
+ }> | null; };
11
13
  }
@@ -2,7 +2,7 @@ import * as seq from 'sequelize-typescript';
2
2
  import { BaseModel } from './models';
3
3
  import { Db as _Db } from './db.class';
4
4
  import type { OptionalFields, OptionalIfNullish } from 'pangea-helpers';
5
- import type { InferCreationAttributes, CreationOptional, NonAttribute, AbstractDataTypeConstructor, AbstractDataType, Transaction, WhereOptions } from 'sequelize';
5
+ import type { InferAttributes, InferCreationAttributes, CreationOptional, NonAttribute, AbstractDataTypeConstructor, AbstractDataType, Transaction, WhereOptions } from 'sequelize';
6
6
  import type { ModelCtor } from 'sequelize-typescript';
7
7
  declare global {
8
8
  type ModelId = number;
@@ -16,6 +16,10 @@ declare global {
16
16
  type Where<BM extends BaseModel> = WhereOptions<BM> & Record<symbol, any>;
17
17
  type InsertParams<BM extends BaseModel> = OptionalIfNullish<OptionalIfOptional<StripRelations<OptionalFields<IncludeHidden<Omit<InferCreationAttributes<BM>, '__brand'>>, Exclude<keyof InferCreationAttributes<BM>, '__brand'> & 'id'>>>>;
18
18
  type UpdateParams<BM extends BaseModel> = Partial<InsertParams<BM>>;
19
+ type UpdateParamsWithId<BM extends BaseModel> = UpdateParams<BM> & {
20
+ id: ModelId;
21
+ };
22
+ type ModelInstance<BM extends BaseModel> = InferAttributes<BM>;
19
23
  type Tx = Transaction;
20
24
  type Db = _Db;
21
25
  }
@@ -33,36 +33,51 @@ type AggregateManyConfig = {
33
33
  group: Group;
34
34
  };
35
35
  type AggregateManyOptions<BM extends BaseModel> = Omit<FindManyOptions<BM>, 'order'>;
36
- type Target<BM extends BaseModel> = Filters<BM> | BM;
37
36
  export declare class Db {
38
37
  private __tx?;
39
38
  constructor(tx: Tx);
40
- findOneOrNull<BM extends BaseModel>(model: BaseModelCtor<BM>, filters: Filters<BM>, options?: FindOneOptions): Promise<BM | null>;
41
- findOne<BM extends BaseModel>(model: BaseModelCtor<BM>, filters: Filters<BM>, options?: FindOneOptions): Promise<BM>;
39
+ findOneOrNull<BM extends BaseModel>(model: BaseModelCtor<BM>, filters: Filters<BM>, options?: FindOneOptions): Promise<import("sequelize").InferAttributes<BM, {
40
+ omit: never;
41
+ }> | null>;
42
+ findOne<BM extends BaseModel>(model: BaseModelCtor<BM>, filters: Filters<BM>, options?: FindOneOptions): Promise<import("sequelize").InferAttributes<BM, {
43
+ omit: never;
44
+ }>>;
42
45
  aggregateOne<BM extends BaseModel>(model: BaseModelCtor<BM>, attributes: Attributes, options?: AggregateOneOptions<BM>): Promise<unknown>;
43
46
  private __getFindOneBaseOptions;
44
- findMany<BM extends BaseModel>(model: BaseModelCtor<BM>, options?: FindManyPagedOptions<BM>): Promise<BM[]>;
47
+ findMany<BM extends BaseModel>(model: BaseModelCtor<BM>, options?: FindManyPagedOptions<BM>): Promise<import("sequelize").InferAttributes<BM, {
48
+ omit: never;
49
+ }>[]>;
45
50
  count<BM extends BaseModel>(model: BaseModelCtor<BM>, options?: FindManyOptions<BM>): Promise<number>;
46
51
  findManyWithCount<BM extends BaseModel>(model: BaseModelCtor<BM>, options?: FindManyPagedOptions<BM>): Promise<{
47
- instances: BM[];
52
+ instances: import("sequelize").InferAttributes<BM, {
53
+ omit: never;
54
+ }>[];
48
55
  totalCount: number;
49
56
  }>;
50
57
  aggregateMany<BM extends BaseModel>(model: BaseModelCtor<BM>, config: AggregateManyConfig, options?: AggregateManyOptions<BM>): Promise<unknown[]>;
51
58
  private __getFindManyBaseOptions;
52
- insertOne<BM extends BaseModel>(model: BaseModelCtor<BM>, params: InsertParams<BM>): Promise<BM>;
59
+ insertOne<BM extends BaseModel>(model: BaseModelCtor<BM>, params: InsertParams<BM>): Promise<import("sequelize").InferAttributes<BM, {
60
+ omit: never;
61
+ }>>;
53
62
  insertMany<BM extends BaseModel>(model: BaseModelCtor<BM>, data: InsertParams<BM>[]): Promise<number>;
54
63
  upsertMany<BM extends BaseModel>(model: BaseModelCtor<BM>, fieldsToUpdate: (keyof BM)[], data: InsertParams<BM>[]): Promise<number>;
55
- updateOne<BM extends BaseModel>(model: BaseModelCtor<BM>, target: Target<BM>, params: UpdateParams<BM>): Promise<BM>;
64
+ updateOne<BM extends BaseModel>(model: BaseModelCtor<BM>, params: UpdateParamsWithId<BM>): Promise<ModelInstance<BM>>;
65
+ updateOne<BM extends BaseModel>(model: BaseModelCtor<BM>, id: ModelId, params: UpdateParams<BM>): Promise<ModelInstance<BM>>;
56
66
  updateMany<BM extends BaseModel>(model: BaseModelCtor<BM>, where: Where<BM>, params: UpdateParams<BM>): Promise<number>;
57
- deleteOne<BM extends BaseModel>(model: BaseModelCtor<BM>, target: Target<BM>): Promise<BM | null>;
67
+ deleteOne<BM extends BaseModel>(model: BaseModelCtor<BM>, id: ModelId): Promise<import("sequelize").InferAttributes<BM, {
68
+ omit: never;
69
+ }> | null>;
58
70
  deleteMany<BM extends BaseModel>(model: BaseModelCtor<BM>, where: Where<BM>): Promise<number>;
59
- destroyOne<BM extends BaseModel>(model: BaseModelCtor<BM>, target: Target<BM>): Promise<BM | null>;
71
+ destroyOne<BM extends BaseModel>(model: BaseModelCtor<BM>, id: ModelId): Promise<import("sequelize").InferAttributes<BM, {
72
+ omit: never;
73
+ }> | null>;
60
74
  destroyMany<BM extends BaseModel>(model: BaseModelCtor<BM>, where: Where<BM>): Promise<number>;
61
75
  private __deleteOne;
62
76
  private __deleteMany;
63
- restoreOne<BM extends BaseModel>(model: BaseModelCtor<BM>, target: Target<BM>): Promise<BM>;
77
+ restoreOne<BM extends BaseModel>(model: BaseModelCtor<BM>, id: ModelId): Promise<import("sequelize").InferAttributes<BM, {
78
+ omit: never;
79
+ }>>;
64
80
  restoreMany<BM extends BaseModel>(model: BaseModelCtor<BM>, where: Where<BM>): Promise<void>;
65
- private __getInstance;
66
81
  query(sql: string | {
67
82
  query: string;
68
83
  values: unknown[];
@@ -13,18 +13,24 @@ class Db {
13
13
  this.__tx = tx;
14
14
  }
15
15
  // find methods
16
- findOneOrNull(model, filters, options = {}) {
16
+ async findOneOrNull(model, filters, options = {}) {
17
17
  const { scopes, order, paranoid = true } = options;
18
18
  const scopedModel = scopes?.length ? model.scope(...scopes) : model;
19
19
  const baseOptions = this.__getFindOneBaseOptions(paranoid);
20
+ let instance;
20
21
  if (typeof filters === 'number') {
21
- return scopedModel.findByPk(filters, { ...baseOptions, ...getInclude(model) });
22
+ instance = await scopedModel.findByPk(filters, { ...baseOptions, ...getInclude(model) });
22
23
  }
23
- return scopedModel.findOne({
24
- ...baseOptions,
25
- ...getInclude(model, { where: filters }),
26
- order: getFinalOrder(order),
27
- });
24
+ else {
25
+ instance = await scopedModel.findOne({
26
+ ...baseOptions,
27
+ ...getInclude(model, { where: filters }),
28
+ order: getFinalOrder(order),
29
+ });
30
+ }
31
+ if (!instance)
32
+ return null;
33
+ return processInstance(model, instance);
28
34
  }
29
35
  async findOne(model, filters, options = {}) {
30
36
  const instance = await this.findOneOrNull(model, filters, options);
@@ -48,6 +54,7 @@ class Db {
48
54
  async findMany(model, options = {}) {
49
55
  const baseOptions = this.__getFindManyBaseOptions(model, options);
50
56
  const { page, pageSize } = options;
57
+ let instances;
51
58
  if (page && pageSize) {
52
59
  const idRows = await model.findAll({
53
60
  ...baseOptions,
@@ -58,9 +65,12 @@ class Db {
58
65
  limit: pageSize,
59
66
  });
60
67
  const ids = idRows.map((row) => row.id);
61
- return model.findAll({ ...baseOptions, where: { id: { [_1.Ops.in]: ids } } });
68
+ instances = await model.findAll({ ...baseOptions, where: { id: { [_1.Ops.in]: ids } } });
69
+ }
70
+ else {
71
+ instances = await model.findAll(baseOptions);
62
72
  }
63
- return model.findAll(baseOptions);
73
+ return processInstances(model, instances);
64
74
  }
65
75
  async count(model, options = {}) {
66
76
  const baseOptions = this.__getFindManyBaseOptions(model, options);
@@ -143,12 +153,12 @@ class Db {
143
153
  return newInstances.length;
144
154
  });
145
155
  }
146
- // update methods
147
- updateOne(model, target, params) {
156
+ updateOne(model, idOrParams, params) {
148
157
  return handleDbError(async () => {
149
- const instance = await this.__getInstance(model, target);
150
- await instance.update(params, { transaction: this.__tx });
151
- return this.findOne(model, instance.id);
158
+ const id = typeof idOrParams === 'number' ? idOrParams : idOrParams.id;
159
+ const finalParams = typeof idOrParams === 'number' ? params : idOrParams;
160
+ await model.update(finalParams, { where: { id }, transaction: this.__tx });
161
+ return this.findOne(model, id);
152
162
  });
153
163
  }
154
164
  updateMany(model, where, params) {
@@ -158,23 +168,22 @@ class Db {
158
168
  });
159
169
  }
160
170
  // delete methods
161
- deleteOne(model, target) {
162
- return this.__deleteOne(model, target, false);
171
+ deleteOne(model, id) {
172
+ return this.__deleteOne(model, id, false);
163
173
  }
164
174
  deleteMany(model, where) {
165
175
  return this.__deleteMany(model, where, false);
166
176
  }
167
- destroyOne(model, target) {
168
- return this.__deleteOne(model, target, true);
177
+ destroyOne(model, id) {
178
+ return this.__deleteOne(model, id, true);
169
179
  }
170
180
  destroyMany(model, where) {
171
181
  return this.__deleteMany(model, where, true);
172
182
  }
173
- __deleteOne(model, target, force) {
183
+ __deleteOne(model, id, force) {
174
184
  return handleDbError(async () => {
175
- const instance = await this.__getInstance(model, target);
176
- await instance.destroy({ force, transaction: this.__tx });
177
- return this.findOneOrNull(model, instance.id, { paranoid: false });
185
+ await model.destroy({ where: { id }, force, transaction: this.__tx });
186
+ return this.findOneOrNull(model, id, { paranoid: false });
178
187
  });
179
188
  }
180
189
  __deleteMany(model, where, force) {
@@ -183,11 +192,10 @@ class Db {
183
192
  });
184
193
  }
185
194
  // restore methods
186
- restoreOne(model, target) {
195
+ restoreOne(model, id) {
187
196
  return handleDbError(async () => {
188
- const instance = await this.__getInstance(model, target, false);
189
- await instance.restore({ transaction: this.__tx });
190
- return this.findOne(model, instance.id);
197
+ await model.restore({ where: { id }, transaction: this.__tx });
198
+ return this.findOne(model, id);
191
199
  });
192
200
  }
193
201
  restoreMany(model, where) {
@@ -196,11 +204,6 @@ class Db {
196
204
  });
197
205
  }
198
206
  // helpers methods
199
- __getInstance(model, target, paranoid = true) {
200
- if (target && typeof target === 'object' && 'id' in target)
201
- return target;
202
- return this.findOne(model, target, { paranoid });
203
- }
204
207
  query(sql) {
205
208
  const dbClient = (0, db_client_1.getDbClient)();
206
209
  return dbClient.query(sql, { transaction: this.__tx });
@@ -301,6 +304,24 @@ function getFinalOrder(order, config = {}) {
301
304
  });
302
305
  return [...finalOrder, ...(!config.attributes ? [['createdAt', 'DESC']] : [])];
303
306
  }
307
+ function processInstance(model, instance) {
308
+ for (const [relName] of Object.entries(model.Relations)) {
309
+ const relInstance = instance[relName];
310
+ if (!relInstance)
311
+ continue;
312
+ const relModel = model.Relations[relName].getModelFn();
313
+ if (Array.isArray(relInstance)) {
314
+ relInstance.forEach((instance) => processInstance(relModel, instance));
315
+ }
316
+ else {
317
+ processInstance(relModel, relInstance);
318
+ }
319
+ }
320
+ return instance.toJSON();
321
+ }
322
+ function processInstances(model, instances) {
323
+ return instances.map((instance) => processInstance(model, instance));
324
+ }
304
325
  async function handleDbError(operation) {
305
326
  try {
306
327
  return await operation();
@@ -55,19 +55,17 @@ function hasInstancesAndTotalCount(obj) {
55
55
  return typeof obj === 'object' && obj !== null && 'instances' in obj && 'totalCount' in obj;
56
56
  }
57
57
  async function setFilesUrls(data) {
58
+ const targets = [];
58
59
  const visited = new WeakSet();
59
- const singleTargets = [];
60
- const arrayTargets = [];
61
- function isTargetKey(key) {
62
- const k = key.toLowerCase();
63
- return k.includes('image') || k.includes('video');
64
- }
65
- function normalizeArray(value) {
66
- if (Array.isArray(value))
67
- return value;
68
- if (typeof value === 'string' && value.length)
69
- return value.split(',').map((v) => v.trim()).filter(Boolean);
70
- return [];
60
+ function getFieldMode(key, val) {
61
+ const lowerKey = key.toLowerCase();
62
+ if (lowerKey.endsWith('url') || lowerKey.endsWith('urls'))
63
+ return;
64
+ if ((lowerKey.endsWith('image') || lowerKey.endsWith('video')) && (typeof val === 'string' || val === null)) {
65
+ return 'single';
66
+ }
67
+ if ((lowerKey.endsWith('images') || lowerKey.endsWith('videos')) && Array.isArray(val))
68
+ return 'plural';
71
69
  }
72
70
  function collect(node) {
73
71
  if (!node)
@@ -81,62 +79,32 @@ async function setFilesUrls(data) {
81
79
  if (visited.has(node))
82
80
  return;
83
81
  visited.add(node);
84
- for (const [key, value] of Object.entries(node)) {
85
- if (isTargetKey(key)) {
86
- if (Array.isArray(value) || typeof value === 'string') {
87
- const arr = normalizeArray(value);
88
- if (arr.length > 1) {
89
- node[key] = arr;
90
- arrayTargets.push({ node, key });
91
- }
92
- else if (arr.length === 1) {
93
- node[key] = arr[0];
94
- singleTargets.push({ node, key });
95
- }
96
- else if (Array.isArray(value)) {
97
- node[key] = [];
98
- arrayTargets.push({ node, key });
99
- }
100
- else {
101
- node[key] = null;
102
- singleTargets.push({ node, key });
103
- }
104
- }
105
- }
106
- collect(value);
107
- }
82
+ Object.entries(node).forEach(([key, val]) => {
83
+ const mode = getFieldMode(key, val);
84
+ if (mode)
85
+ targets.push({ obj: node, key, mode });
86
+ collect(val);
87
+ });
108
88
  }
109
89
  collect(data);
110
- const filesSet = new Set();
111
- singleTargets.forEach(({ node, key }) => {
112
- const val = node[key];
113
- if (typeof val === 'string' && val.length)
114
- filesSet.add(val);
115
- });
116
- arrayTargets.forEach(({ node, key }) => {
117
- const arr = node[key];
118
- if (!Array.isArray(arr))
119
- return;
120
- arr.forEach((v) => {
121
- if (typeof v === 'string' && v.length)
122
- filesSet.add(v);
123
- });
124
- });
125
- const files = Array.from(filesSet);
126
- if (!files.length) {
127
- arrayTargets.forEach(({ node, key }) => (node[`${key}Urls`] = []));
128
- singleTargets.forEach(({ node, key }) => (node[`${key}Url`] = null));
90
+ if (!targets.length)
129
91
  return;
130
- }
131
- const urls = await Promise.all(files.map((file) => helpers_1.FileStorage.GenerateDownloadUrl(file)));
92
+ const allFiles = Array.from(new Set(targets.flatMap(({ obj, key, mode }) => {
93
+ const val = obj[key];
94
+ if (val === null)
95
+ return [];
96
+ return mode === 'single' ? [val] : val;
97
+ })));
132
98
  const map = new Map();
133
- files.forEach((file, i) => map.set(file, urls[i]));
134
- singleTargets.forEach(({ node, key }) => {
135
- const val = node[key];
136
- node[`${key}Url`] = typeof val === 'string' && val.length ? map.get(val) || null : null;
137
- });
138
- arrayTargets.forEach(({ node, key }) => {
139
- const arr = node[key];
140
- node[`${key}Urls`] = Array.isArray(arr) ? arr.map((v) => (v && map.has(v) ? map.get(v) : null)) : [];
99
+ if (allFiles.length) {
100
+ const urls = await Promise.all(allFiles.map((file) => helpers_1.FileStorage.GenerateDownloadUrl(file)));
101
+ allFiles.forEach((file, i) => map.set(file, urls[i]));
102
+ }
103
+ targets.forEach(({ obj, key, mode }) => {
104
+ if (mode === 'single') {
105
+ obj[`${key}Url`] = map.get(obj[key]) || null;
106
+ return;
107
+ }
108
+ obj[`${key}Urls`] = obj[key].map((file) => map.get(file));
141
109
  });
142
110
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pangea-server",
3
3
  "description": "",
4
- "version": "3.3.81",
4
+ "version": "3.3.83",
5
5
  "files": [
6
6
  "dist"
7
7
  ],