@rsdk/metadata 3.1.0-next.0 → 3.1.0

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,3 +1,4 @@
1
1
  import 'reflect-metadata';
2
+ export { ResourceExtractor } from './resource-extractor';
2
3
  export { RsdkMetadataProvider } from './rsdk-metadata-provider';
3
4
  export { RsdkMetadata, Resource } from './metadata';
@@ -1,6 +1,11 @@
1
1
  /**
2
2
  * Абстракция для изоляции значений метаданных...
3
3
  * От метаданных rsdk...
4
+ * Важное понятие - сигнатура/signature(подпись)
5
+ * Представляет собой композит значений полей `key` и `scope`
6
+ * Значения со значением поля `key="x"` будет считаться идентичным любому другому ресурсу с таким же значением, при условии равенства поля `scope`.
7
+ * Если поле `scope` не указано, ресурс будет равен только ресурсу с таким же ключом и без `scope` соответственно
8
+ * TODO: Стоит добавить хелпер `ResourceSignature` для упрощения взаимодействия и прозрачности работы с ним
4
9
  */
5
10
  export type Resource<T> = {
6
11
  /**
@@ -15,7 +20,7 @@ export type Resource<T> = {
15
20
  * В чём собственно дело
16
21
  * У нас есть ряд вещей которые необходимо объявить по принципу at-most-once.
17
22
  * Но так как они все переиспользуемые они декларируются везде где они нужны.
18
- * Для того чтобы высекать такие вещи в ряде случаев сделано это поле, работает просто по сравнению `===`
23
+ * Для того чтобы высекать такие вещи в ряде случаев сделано это поле, работает просто по сравнению через `===`
19
24
  * Если значение с таким же скоупом уже есть, все последующие будут отброшены
20
25
  */
21
26
  key?: unknown;
@@ -0,0 +1,32 @@
1
+ import type { Resource } from './metadata';
2
+ /**
3
+ * Хелпер для работы с массивами ресурсов
4
+ */
5
+ export declare class ResourceAggregator {
6
+ readonly resources: Resource<unknown>[];
7
+ private readonly map;
8
+ private readonly keys;
9
+ /**
10
+ * Проверка есть ли уже такой ресурс в агрегаторе
11
+ * @param resource
12
+ */
13
+ isDuplicate(resource: Resource<unknown>): boolean;
14
+ /**
15
+ * Добавить новый ресурс
16
+ * Если ресурс с такой же сигнатурой уже будет найден, он будет пропущен
17
+ * @param resources
18
+ */
19
+ add(...resources: Resource<unknown>[]): void;
20
+ /**
21
+ * Внутренний метод добавления, не делает никаких проверок на существование с такой же сигнатурой
22
+ * @param resource
23
+ * @private
24
+ */
25
+ private handle;
26
+ /**
27
+ * Добавляет сигнатуру в "существующие" в списке
28
+ * @param resource
29
+ * @private
30
+ */
31
+ private handleSignature;
32
+ }
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResourceAggregator = void 0;
4
+ /**
5
+ * Хелпер для работы с массивами ресурсов
6
+ */
7
+ class ResourceAggregator {
8
+ resources = [];
9
+ map = new Map();
10
+ keys = new Set();
11
+ /**
12
+ * Проверка есть ли уже такой ресурс в агрегаторе
13
+ * @param resource
14
+ */
15
+ isDuplicate(resource) {
16
+ const hasKey = Object.hasOwn(resource, 'key');
17
+ if (!hasKey) {
18
+ return false;
19
+ }
20
+ const hasScope = Object.hasOwn(resource, 'scope');
21
+ if (hasScope) {
22
+ const keys = this.map.get(resource.scope);
23
+ return Boolean(keys?.some((key) => key === resource.key));
24
+ }
25
+ return this.keys.has(resource.key);
26
+ }
27
+ /**
28
+ * Добавить новый ресурс
29
+ * Если ресурс с такой же сигнатурой уже будет найден, он будет пропущен
30
+ * @param resources
31
+ */
32
+ add(...resources) {
33
+ for (const resource of resources) {
34
+ const isDuplicate = this.isDuplicate(resource);
35
+ if (isDuplicate) {
36
+ continue;
37
+ }
38
+ this.handle(resource);
39
+ }
40
+ }
41
+ /**
42
+ * Внутренний метод добавления, не делает никаких проверок на существование с такой же сигнатурой
43
+ * @param resource
44
+ * @private
45
+ */
46
+ handle(resource) {
47
+ this.handleSignature(resource);
48
+ this.resources.push(resource);
49
+ }
50
+ /**
51
+ * Добавляет сигнатуру в "существующие" в списке
52
+ * @param resource
53
+ * @private
54
+ */
55
+ handleSignature(resource) {
56
+ const hasKey = Object.hasOwn(resource, 'key');
57
+ if (!hasKey) {
58
+ return;
59
+ }
60
+ const hasScope = Object.hasOwn(resource, 'scope');
61
+ if (hasScope) {
62
+ const keys = this.map.get(resource.scope) ?? [];
63
+ this.map.set(resource.scope, [...keys, resource.key]);
64
+ return;
65
+ }
66
+ this.keys.add(resource.key);
67
+ }
68
+ }
69
+ exports.ResourceAggregator = ResourceAggregator;
@@ -0,0 +1,5 @@
1
+ import type { ClassProvider, DynamicModule, ExistingProvider, FactoryProvider, InjectionToken, ValueProvider } from '@nestjs/common';
2
+ import type { Resource } from './metadata';
3
+ export interface ResourceExtractor {
4
+ extract(value: DynamicModule | ClassProvider<any> | ValueProvider<any> | FactoryProvider<any> | ExistingProvider<any> | InjectionToken): Resource<unknown>[];
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -2,6 +2,7 @@ import type { ClassProvider, DynamicModule, ExistingProvider, FactoryProvider, I
2
2
  import type { NestModuleDefinition } from '@rsdk/common.nestjs';
3
3
  import type { Promisable } from 'type-fest';
4
4
  import type { Resource } from './metadata';
5
+ import type { ResourceExtractor } from './resource-extractor';
5
6
  /**
6
7
  * Провайдер агрегирующий в себе ресурсы из метаданных
7
8
  * По задумке должен выступать лишь в роли фасада/агрегатора который знает о структуре ресурсов и её значении
@@ -10,17 +11,16 @@ import type { Resource } from './metadata';
10
11
  export declare class RsdkMetadataProvider {
11
12
  private readonly resources;
12
13
  protected constructor(resources: Resource<any>[]);
13
- static create(...rootModule: Promisable<NestModuleDefinition>[]): Promise<RsdkMetadataProvider>;
14
+ static create(modules: Promisable<NestModuleDefinition>[], extractors?: ResourceExtractor[]): Promise<RsdkMetadataProvider>;
14
15
  static getMetadataSource(nestDefinition: DynamicModule | Type | ClassProvider | ValueProvider | FactoryProvider | ExistingProvider): IterableIterator<InjectionToken | DynamicModule | Type | ClassProvider | ValueProvider | FactoryProvider | ExistingProvider>;
15
- private static extractResources;
16
16
  /**
17
17
  * Есть ли уже этот ресурс в массиве
18
18
  * Проверка осуществляется на основе `key` и `scope` у `Resource`
19
19
  * @param resources
20
20
  * @param definitionResource
21
- * @private
22
21
  */
23
- private static isDuplicate;
22
+ static isDuplicate(resources: Resource<any>[], definitionResource: Resource<unknown>): boolean;
23
+ private static extractResources;
24
24
  get<T>(scope?: string): Resource<T>[];
25
25
  add(...moduleDef: Promisable<NestModuleDefinition>[]): Promise<void>;
26
26
  }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RsdkMetadataProvider = void 0;
4
4
  const nest_tools_1 = require("@rsdk/nest-tools");
5
5
  const metadata_1 = require("./metadata");
6
+ const resource_aggregator_1 = require("./resource-aggregator");
6
7
  /**
7
8
  * Провайдер агрегирующий в себе ресурсы из метаданных
8
9
  * По задумке должен выступать лишь в роли фасада/агрегатора который знает о структуре ресурсов и её значении
@@ -13,9 +14,9 @@ class RsdkMetadataProvider {
13
14
  constructor(resources) {
14
15
  this.resources = resources;
15
16
  }
16
- static async create(...rootModule) {
17
+ static async create(modules, extractors) {
17
18
  const resources = [];
18
- await this.extractResources(rootModule, resources);
19
+ await this.extractResources(modules, resources, extractors);
19
20
  return new RsdkMetadataProvider(resources);
20
21
  }
21
22
  static *getMetadataSource(nestDefinition) {
@@ -30,7 +31,17 @@ class RsdkMetadataProvider {
30
31
  }
31
32
  yield nestDefinition;
32
33
  }
33
- static async extractResources(rootModule, resources) {
34
+ /**
35
+ * Есть ли уже этот ресурс в массиве
36
+ * Проверка осуществляется на основе `key` и `scope` у `Resource`
37
+ * @param resources
38
+ * @param definitionResource
39
+ */
40
+ static isDuplicate(resources, definitionResource) {
41
+ return resources.some((resource) => metadata_1.RsdkMetadata.isEqual(resource, definitionResource));
42
+ }
43
+ static async extractResources(rootModule, resources, extractors) {
44
+ const agg = new resource_aggregator_1.ResourceAggregator();
34
45
  for await (const rootModuleElement of rootModule) {
35
46
  const nestDefinitionIterator = new nest_tools_1.NestDefinitionIterator(rootModuleElement);
36
47
  for await (const _nestDefinition of nestDefinitionIterator.iterate()) {
@@ -39,29 +50,23 @@ class RsdkMetadataProvider {
39
50
  continue;
40
51
  }
41
52
  const definitionResources = metadata_1.RsdkMetadata.get(value);
42
- if (!definitionResources) {
53
+ const extractedResources = extractors?.reduce((acc, extractor) => {
54
+ const resources = extractor.extract(value);
55
+ acc.push(...resources);
56
+ return acc;
57
+ }, []);
58
+ const foundedResources = [
59
+ ...(definitionResources ?? []),
60
+ ...(extractedResources ?? []),
61
+ ];
62
+ if (!foundedResources?.length) {
43
63
  continue;
44
64
  }
45
- for (const definitionResource of definitionResources) {
46
- const isDuplicate = this.isDuplicate(resources, definitionResource);
47
- if (isDuplicate) {
48
- continue;
49
- }
50
- resources.push(definitionResource);
51
- }
65
+ agg.add(...foundedResources);
52
66
  }
53
67
  }
54
68
  }
55
- }
56
- /**
57
- * Есть ли уже этот ресурс в массиве
58
- * Проверка осуществляется на основе `key` и `scope` у `Resource`
59
- * @param resources
60
- * @param definitionResource
61
- * @private
62
- */
63
- static isDuplicate(resources, definitionResource) {
64
- return resources.some((resource) => metadata_1.RsdkMetadata.isEqual(resource, definitionResource));
69
+ resources.push(...agg.resources);
65
70
  }
66
71
  get(scope) {
67
72
  if (scope === undefined) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsdk/metadata",
3
- "version": "3.1.0-next.0",
3
+ "version": "3.1.0",
4
4
  "license": "Apache License 2.0",
5
5
  "description": "Rsdk stack metadata management",
6
6
  "main": "dist/index.js",
@@ -13,10 +13,10 @@
13
13
  "peerDependencies": {
14
14
  "@nestjs/common": "^10.1.3",
15
15
  "@nestjs/core": "^10.1.3",
16
- "@rsdk/common": "^3.1.0-next.0",
17
- "@rsdk/logging": "^3.1.0-next.0",
18
- "@rsdk/nest-tools": "^3.1.0-next.0",
16
+ "@rsdk/common": "^3.1.0",
17
+ "@rsdk/logging": "^3.1.0",
18
+ "@rsdk/nest-tools": "^3.1.0",
19
19
  "reflect-metadata": "^0.1.13"
20
20
  },
21
- "gitHead": "55598931db264fb6d5b5c4787c48298ed86bbc0d"
21
+ "gitHead": "428640441ec53822ea1c1be7b085bb9dad04689d"
22
22
  }