@rsdk/metadata 3.1.0-next.0 → 3.1.0-next.2
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 +1 -0
- package/dist/metadata.d.ts +6 -1
- package/dist/resource-aggregator.d.ts +32 -0
- package/dist/resource-aggregator.js +69 -0
- package/dist/resource-extractor.d.ts +5 -0
- package/dist/resource-extractor.js +2 -0
- package/dist/rsdk-metadata-provider.d.ts +4 -4
- package/dist/rsdk-metadata-provider.js +26 -21
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
package/dist/metadata.d.ts
CHANGED
|
@@ -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
|
+
}
|
|
@@ -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(
|
|
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
|
-
|
|
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(
|
|
17
|
+
static async create(modules, extractors) {
|
|
17
18
|
const resources = [];
|
|
18
|
-
await this.extractResources(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
3
|
+
"version": "3.1.0-next.2",
|
|
4
4
|
"license": "Apache License 2.0",
|
|
5
5
|
"description": "Rsdk stack metadata management",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -18,5 +18,5 @@
|
|
|
18
18
|
"@rsdk/nest-tools": "^3.1.0-next.0",
|
|
19
19
|
"reflect-metadata": "^0.1.13"
|
|
20
20
|
},
|
|
21
|
-
"gitHead": "
|
|
21
|
+
"gitHead": "28db120cf1b53317241e1b14d936eae785723601"
|
|
22
22
|
}
|