medusa-product-helper 0.0.16 → 0.0.19
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/.medusa/server/src/admin/index.js +59 -117
- package/.medusa/server/src/admin/index.mjs +59 -117
- package/.medusa/server/src/api/store/product-helper/products/route.js +137 -7
- package/.medusa/server/src/api/store/product-helper/products/validators.js +11 -1
- package/.medusa/server/src/providers/filter-providers/availability-provider.js +53 -67
- package/.medusa/server/src/providers/filter-providers/base-filter-provider.js +1 -19
- package/.medusa/server/src/providers/filter-providers/base-product-provider.js +37 -100
- package/.medusa/server/src/providers/filter-providers/category-provider.js +15 -34
- package/.medusa/server/src/providers/filter-providers/collection-provider.js +15 -32
- package/.medusa/server/src/providers/filter-providers/index.js +13 -49
- package/.medusa/server/src/providers/filter-providers/metadata-provider.js +43 -58
- package/.medusa/server/src/providers/filter-providers/price-range-provider.js +66 -79
- package/.medusa/server/src/providers/filter-providers/promotion-provider.js +106 -169
- package/.medusa/server/src/providers/filter-providers/promotion-window-provider.js +53 -93
- package/.medusa/server/src/providers/filter-providers/rating-provider.js +47 -70
- package/.medusa/server/src/services/dynamic-filter-service.js +822 -736
- package/.medusa/server/src/services/filter-provider-loader.js +91 -139
- package/.medusa/server/src/services/filter-provider-registry.js +8 -107
- package/.medusa/server/src/services/product-filter-service.js +183 -172
- package/.medusa/server/src/shared/product-metadata/utils.js +66 -116
- package/.medusa/server/src/utils/query-builders/product-filters.js +89 -111
- package/.medusa/server/src/utils/query-parser.js +24 -76
- package/.medusa/server/src/workflows/add-to-wishlist.js +12 -26
- package/.medusa/server/src/workflows/get-wishlist.js +53 -51
- package/.medusa/server/src/workflows/remove-from-wishlist.js +3 -8
- package/package.json +1 -1
|
@@ -1,155 +1,107 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.loadFilterProviders = loadFilterProviders;
|
|
4
7
|
const base_filter_provider_1 = require("../providers/filter-providers/base-filter-provider");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
*
|
|
8
|
-
* This function loads custom filter providers from file paths or module references.
|
|
9
|
-
* Supports both:
|
|
10
|
-
* - File paths (relative to baseDir or absolute)
|
|
11
|
-
* - Module references (npm package names)
|
|
12
|
-
*
|
|
13
|
-
* @param configs - Array of filter provider configurations
|
|
14
|
-
* @param options - Loading options
|
|
15
|
-
* @returns Array of instantiated filter provider instances
|
|
16
|
-
* @throws Error if provider cannot be loaded or instantiated
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```ts
|
|
20
|
-
* // Load from file path
|
|
21
|
-
* const providers = await loadFilterProviders([
|
|
22
|
-
* "./src/providers/margin-provider.ts"
|
|
23
|
-
* ])
|
|
24
|
-
*
|
|
25
|
-
* // Load from module
|
|
26
|
-
* const providers = await loadFilterProviders([
|
|
27
|
-
* "@my-org/custom-filters/margin-provider"
|
|
28
|
-
* ])
|
|
29
|
-
*
|
|
30
|
-
* // Load with options
|
|
31
|
-
* const providers = await loadFilterProviders([
|
|
32
|
-
* { path: "./src/providers/margin-provider.ts", options: { minMargin: 10 } }
|
|
33
|
-
* ])
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
36
10
|
async function loadFilterProviders(configs, options = {}) {
|
|
37
11
|
const providers = [];
|
|
38
12
|
const baseDir = options.baseDir || process.cwd();
|
|
39
13
|
for (const config of configs) {
|
|
40
14
|
try {
|
|
41
|
-
|
|
42
|
-
let providerPath;
|
|
43
|
-
// Resolve config to path
|
|
44
|
-
if (typeof config === "string") {
|
|
45
|
-
providerPath = config;
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
providerPath = config.path;
|
|
49
|
-
}
|
|
50
|
-
// Try to load as module first (npm package)
|
|
51
|
-
try {
|
|
52
|
-
providerModule = await import(providerPath);
|
|
53
|
-
}
|
|
54
|
-
catch (moduleError) {
|
|
55
|
-
// If module import fails, try as file path
|
|
56
|
-
const path = require("path");
|
|
57
|
-
const fs = require("fs");
|
|
58
|
-
// Resolve absolute path
|
|
59
|
-
const absolutePath = path.isAbsolute(providerPath)
|
|
60
|
-
? providerPath
|
|
61
|
-
: path.resolve(baseDir, providerPath);
|
|
62
|
-
// Check if file exists
|
|
63
|
-
if (!fs.existsSync(absolutePath)) {
|
|
64
|
-
throw new Error(`Filter provider file not found: ${absolutePath}`);
|
|
65
|
-
}
|
|
66
|
-
// Try dynamic import with file:// protocol for absolute paths
|
|
67
|
-
try {
|
|
68
|
-
providerModule = await import(absolutePath);
|
|
69
|
-
}
|
|
70
|
-
catch (fileError) {
|
|
71
|
-
// Try with require for CommonJS modules
|
|
72
|
-
try {
|
|
73
|
-
providerModule = require(absolutePath);
|
|
74
|
-
}
|
|
75
|
-
catch (requireError) {
|
|
76
|
-
throw new Error(`Failed to load filter provider from ${providerPath}: ${String(moduleError)}`);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
// Extract provider class from module
|
|
81
|
-
// Support both default export and named export
|
|
82
|
-
let ProviderClass;
|
|
83
|
-
if (providerModule && typeof providerModule === "object") {
|
|
84
|
-
// Try default export first
|
|
85
|
-
if ("default" in providerModule &&
|
|
86
|
-
typeof providerModule.default === "function") {
|
|
87
|
-
ProviderClass = providerModule.default;
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
// Try to find a class that extends BaseFilterProvider
|
|
91
|
-
// Look for exported classes
|
|
92
|
-
for (const [key, value] of Object.entries(providerModule)) {
|
|
93
|
-
if (typeof value === "function" &&
|
|
94
|
-
value.prototype &&
|
|
95
|
-
Object.getPrototypeOf(value.prototype)?.constructor ===
|
|
96
|
-
base_filter_provider_1.BaseFilterProvider) {
|
|
97
|
-
ProviderClass = value;
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if (!ProviderClass) {
|
|
104
|
-
throw new Error(`No filter provider class found in ${providerPath}. ` +
|
|
105
|
-
`Expected a class extending BaseFilterProvider as default export or named export.`);
|
|
106
|
-
}
|
|
107
|
-
// Validate that it's a BaseFilterProvider subclass
|
|
108
|
-
// Check for required static properties
|
|
109
|
-
if (!("identifier" in ProviderClass) ||
|
|
110
|
-
typeof ProviderClass.identifier !== "string") {
|
|
111
|
-
throw new Error(`Class in ${providerPath} does not appear to extend BaseFilterProvider. ` +
|
|
112
|
-
`Missing static 'identifier' property.`);
|
|
113
|
-
}
|
|
114
|
-
// Check for displayName
|
|
115
|
-
if (!("displayName" in ProviderClass) ||
|
|
116
|
-
typeof ProviderClass.displayName !== "string") {
|
|
117
|
-
throw new Error(`Class in ${providerPath} does not appear to extend BaseFilterProvider. ` +
|
|
118
|
-
`Missing static 'displayName' property.`);
|
|
119
|
-
}
|
|
120
|
-
// Instantiate provider
|
|
121
|
-
// If config has options, pass them to constructor (if supported)
|
|
122
|
-
const providerConfig = typeof config === "object" && config.options
|
|
123
|
-
? config.options
|
|
124
|
-
: undefined;
|
|
125
|
-
// Instantiate provider
|
|
126
|
-
// We've validated that ProviderClass extends BaseFilterProvider and has required properties
|
|
127
|
-
// TypeScript sees it as abstract, but at runtime it's a concrete class
|
|
128
|
-
// Use type assertion to allow instantiation
|
|
129
|
-
let provider;
|
|
130
|
-
if (providerConfig) {
|
|
131
|
-
// Try to instantiate with options
|
|
132
|
-
try {
|
|
133
|
-
// @ts-expect-error - ProviderClass is validated at runtime to be a concrete subclass
|
|
134
|
-
provider = new ProviderClass(providerConfig);
|
|
135
|
-
}
|
|
136
|
-
catch {
|
|
137
|
-
// If constructor doesn't accept options, instantiate without
|
|
138
|
-
// @ts-expect-error - ProviderClass is validated at runtime to be a concrete subclass
|
|
139
|
-
provider = new ProviderClass();
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
// @ts-expect-error - ProviderClass is validated at runtime to be a concrete subclass
|
|
144
|
-
provider = new ProviderClass();
|
|
145
|
-
}
|
|
15
|
+
const provider = await loadProvider(config, baseDir);
|
|
146
16
|
providers.push(provider);
|
|
147
17
|
}
|
|
148
18
|
catch (error) {
|
|
149
|
-
|
|
150
|
-
throw new Error(`Failed to load filter provider from config ${JSON.stringify(config)}: ${errorMessage}`);
|
|
19
|
+
throw new Error(`Failed to load filter provider from ${JSON.stringify(config)}: ${error}`);
|
|
151
20
|
}
|
|
152
21
|
}
|
|
153
22
|
return providers;
|
|
154
23
|
}
|
|
155
|
-
|
|
24
|
+
async function loadProvider(config, baseDir) {
|
|
25
|
+
const { providerPath, providerOptions } = parseConfig(config);
|
|
26
|
+
const ProviderClass = await resolveProviderClass(providerPath, baseDir);
|
|
27
|
+
validateProviderClass(ProviderClass, providerPath);
|
|
28
|
+
return instantiateProvider(ProviderClass, providerOptions);
|
|
29
|
+
}
|
|
30
|
+
function parseConfig(config) {
|
|
31
|
+
if (typeof config === "string") {
|
|
32
|
+
return { providerPath: config };
|
|
33
|
+
}
|
|
34
|
+
return { providerPath: config.path, providerOptions: config.options };
|
|
35
|
+
}
|
|
36
|
+
async function resolveProviderClass(providerPath, baseDir) {
|
|
37
|
+
// Try module import first
|
|
38
|
+
try {
|
|
39
|
+
const module = await import(providerPath);
|
|
40
|
+
return extractProviderClass(module, providerPath);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Fall back to file import
|
|
44
|
+
const absolutePath = path_1.default.isAbsolute(providerPath)
|
|
45
|
+
? providerPath
|
|
46
|
+
: path_1.default.resolve(baseDir, providerPath);
|
|
47
|
+
await validateFileExists(absolutePath);
|
|
48
|
+
const module = await importFile(absolutePath);
|
|
49
|
+
return extractProviderClass(module, providerPath);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function validateFileExists(filePath) {
|
|
53
|
+
try {
|
|
54
|
+
await fs_1.promises.access(filePath);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
throw new Error(`Filter provider file not found: ${filePath}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function importFile(filePath) {
|
|
61
|
+
// Try ESM import first
|
|
62
|
+
try {
|
|
63
|
+
return await import(filePath);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Fall back to CommonJS require
|
|
67
|
+
return require(filePath);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function extractProviderClass(module, providerPath) {
|
|
71
|
+
// Try default export
|
|
72
|
+
if (typeof module?.default === "function") {
|
|
73
|
+
return module.default;
|
|
74
|
+
}
|
|
75
|
+
// Try to find a BaseFilterProvider subclass
|
|
76
|
+
for (const value of Object.values(module)) {
|
|
77
|
+
if (isProviderClass(value)) {
|
|
78
|
+
return value;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
throw new Error(`No filter provider class found in ${providerPath}`);
|
|
82
|
+
}
|
|
83
|
+
function isProviderClass(value) {
|
|
84
|
+
return (typeof value === "function" &&
|
|
85
|
+
value.prototype &&
|
|
86
|
+
Object.getPrototypeOf(value.prototype)?.constructor === base_filter_provider_1.BaseFilterProvider &&
|
|
87
|
+
typeof value.identifier === "string" &&
|
|
88
|
+
typeof value.displayName === "string");
|
|
89
|
+
}
|
|
90
|
+
function validateProviderClass(ProviderClass, providerPath) {
|
|
91
|
+
if (!isProviderClass(ProviderClass)) {
|
|
92
|
+
throw new Error(`Class in ${providerPath} does not appear to extend BaseFilterProvider. ` +
|
|
93
|
+
`Missing static 'identifier' and/or 'displayName' properties.`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function instantiateProvider(ProviderClass, options) {
|
|
97
|
+
try {
|
|
98
|
+
// @ts-expect-error - ProviderClass is validated to be a concrete subclass
|
|
99
|
+
return options ? new ProviderClass(options) : new ProviderClass();
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// Constructor doesn't accept options, try without
|
|
103
|
+
// @ts-expect-error - ProviderClass is validated to be a concrete subclass
|
|
104
|
+
return new ProviderClass();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLXByb3ZpZGVyLWxvYWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9zZXJ2aWNlcy9maWx0ZXItcHJvdmlkZXItbG9hZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBU0Esa0RBaUJDO0FBMUJELDZGQUF1RjtBQUV2RiwyQkFBbUM7QUFDbkMsZ0RBQXVCO0FBTWhCLEtBQUssVUFBVSxtQkFBbUIsQ0FDdkMsT0FBK0IsRUFDL0IsVUFBc0MsRUFBRTtJQUV4QyxNQUFNLFNBQVMsR0FBeUIsRUFBRSxDQUFBO0lBQzFDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFBO0lBRWhELEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDO1lBQ0gsTUFBTSxRQUFRLEdBQUcsTUFBTSxZQUFZLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFBO1lBQ3BELFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDMUIsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLElBQUksS0FBSyxDQUFDLHVDQUF1QyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEtBQUssRUFBRSxDQUFDLENBQUE7UUFDNUYsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLFNBQVMsQ0FBQTtBQUNsQixDQUFDO0FBRUQsS0FBSyxVQUFVLFlBQVksQ0FDekIsTUFBNEIsRUFDNUIsT0FBZTtJQUVmLE1BQU0sRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQzdELE1BQU0sYUFBYSxHQUFHLE1BQU0sb0JBQW9CLENBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBRXZFLHFCQUFxQixDQUFDLGFBQWEsRUFBRSxZQUFZLENBQUMs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
|
|
@@ -1,142 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FilterProviderRegistry = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Service for managing filter provider registration and retrieval.
|
|
6
|
-
*
|
|
7
|
-
* The registry maintains a map of filter providers keyed by their identifiers,
|
|
8
|
-
* ensuring uniqueness and providing fast lookup. Providers are registered
|
|
9
|
-
* at plugin initialization and can be retrieved by their identifier when
|
|
10
|
-
* applying filters.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```ts
|
|
14
|
-
* const registry = new FilterProviderRegistry()
|
|
15
|
-
* registry.register(new CategoryFilterProvider())
|
|
16
|
-
*
|
|
17
|
-
* const provider = registry.get("category_id")
|
|
18
|
-
* if (provider) {
|
|
19
|
-
* const filters = provider.apply({}, ["cat_123"])
|
|
20
|
-
* }
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
4
|
class FilterProviderRegistry {
|
|
24
5
|
constructor() {
|
|
25
6
|
this.providers = new Map();
|
|
26
7
|
}
|
|
27
|
-
/**
|
|
28
|
-
* Register a filter provider.
|
|
29
|
-
*
|
|
30
|
-
* Throws an error if a provider with the same identifier is already registered.
|
|
31
|
-
*
|
|
32
|
-
* @param provider - Filter provider instance to register
|
|
33
|
-
* @throws Error if provider identifier is already registered
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```ts
|
|
37
|
-
* registry.register(new CategoryFilterProvider())
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
8
|
register(provider) {
|
|
41
|
-
const
|
|
42
|
-
|
|
9
|
+
const constructor = provider.constructor;
|
|
10
|
+
const identifier = constructor.identifier;
|
|
11
|
+
const displayName = constructor.displayName || "Unknown";
|
|
43
12
|
if (!identifier) {
|
|
44
13
|
throw new Error("Filter provider must have a static 'identifier' property");
|
|
45
14
|
}
|
|
46
15
|
if (this.providers.has(identifier)) {
|
|
47
|
-
const
|
|
48
|
-
const existingDisplayName =
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
`Cannot register ${provider.constructor.displayName || "Unknown"}.`);
|
|
16
|
+
const existing = this.providers.get(identifier);
|
|
17
|
+
const existingDisplayName = existing.constructor.displayName || "Unknown";
|
|
18
|
+
throw new Error(`Filter provider "${identifier}" (${existingDisplayName}) already registered. ` +
|
|
19
|
+
`Cannot register ${displayName}.`);
|
|
52
20
|
}
|
|
53
21
|
this.providers.set(identifier, provider);
|
|
54
22
|
}
|
|
55
|
-
/**
|
|
56
|
-
* Get a provider by identifier.
|
|
57
|
-
*
|
|
58
|
-
* @param identifier - Provider identifier to look up
|
|
59
|
-
* @returns Provider instance if found, undefined otherwise
|
|
60
|
-
*
|
|
61
|
-
* @example
|
|
62
|
-
* ```ts
|
|
63
|
-
* const provider = registry.get("category_id")
|
|
64
|
-
* if (provider) {
|
|
65
|
-
* // Use provider
|
|
66
|
-
* }
|
|
67
|
-
* ```
|
|
68
|
-
*/
|
|
69
23
|
get(identifier) {
|
|
70
24
|
return this.providers.get(identifier);
|
|
71
25
|
}
|
|
72
|
-
/**
|
|
73
|
-
* Check if a provider is registered.
|
|
74
|
-
*
|
|
75
|
-
* @param identifier - Provider identifier to check
|
|
76
|
-
* @returns true if provider is registered, false otherwise
|
|
77
|
-
*
|
|
78
|
-
* @example
|
|
79
|
-
* ```ts
|
|
80
|
-
* if (registry.has("category_id")) {
|
|
81
|
-
* // Provider exists
|
|
82
|
-
* }
|
|
83
|
-
* ```
|
|
84
|
-
*/
|
|
85
26
|
has(identifier) {
|
|
86
27
|
return this.providers.has(identifier);
|
|
87
28
|
}
|
|
88
|
-
/**
|
|
89
|
-
* Get all registered providers.
|
|
90
|
-
*
|
|
91
|
-
* @returns Array of all registered provider instances
|
|
92
|
-
*
|
|
93
|
-
* @example
|
|
94
|
-
* ```ts
|
|
95
|
-
* const allProviders = registry.getAll()
|
|
96
|
-
* allProviders.forEach(provider => {
|
|
97
|
-
* console.log(provider.constructor.identifier)
|
|
98
|
-
* })
|
|
99
|
-
* ```
|
|
100
|
-
*/
|
|
101
29
|
getAll() {
|
|
102
30
|
return Array.from(this.providers.values());
|
|
103
31
|
}
|
|
104
|
-
/**
|
|
105
|
-
* Get all provider identifiers.
|
|
106
|
-
*
|
|
107
|
-
* @returns Array of all registered provider identifiers
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
110
|
-
* ```ts
|
|
111
|
-
* const identifiers = registry.getIdentifiers()
|
|
112
|
-
* // ["category_id", "collection_id", "price_range", ...]
|
|
113
|
-
* ```
|
|
114
|
-
*/
|
|
115
32
|
getIdentifiers() {
|
|
116
33
|
return Array.from(this.providers.keys());
|
|
117
34
|
}
|
|
118
|
-
/**
|
|
119
|
-
* Clear all registered providers.
|
|
120
|
-
*
|
|
121
|
-
* Useful for testing or resetting the registry state.
|
|
122
|
-
*
|
|
123
|
-
* @example
|
|
124
|
-
* ```ts
|
|
125
|
-
* registry.clear()
|
|
126
|
-
* // All providers removed
|
|
127
|
-
* ```
|
|
128
|
-
*/
|
|
129
35
|
clear() {
|
|
130
36
|
this.providers.clear();
|
|
131
37
|
}
|
|
132
|
-
/**
|
|
133
|
-
* Get the number of registered providers.
|
|
134
|
-
*
|
|
135
|
-
* @returns Number of registered providers
|
|
136
|
-
*/
|
|
137
38
|
size() {
|
|
138
39
|
return this.providers.size;
|
|
139
40
|
}
|
|
140
41
|
}
|
|
141
42
|
exports.FilterProviderRegistry = FilterProviderRegistry;
|
|
142
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLXByb3ZpZGVyLXJlZ2lzdHJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3NlcnZpY2VzL2ZpbHRlci1wcm92aWRlci1yZWdpc3RyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxNQUFhLHNCQUFzQjtJQUFuQztRQUNVLGNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBOEIsQ0FBQTtJQStDM0QsQ0FBQztJQTdDQyxRQUFRLENBQUMsUUFBNEI7UUFDbkMsTUFBTSxXQUFXLEdBQUcsUUFBUSxDQUFDLFdBQXdDLENBQUE7UUFDckUsTUFBTSxVQUFVLEdBQUcsV0FBVyxDQUFDLFVBQVUsQ0FBQTtRQUN6QyxNQUFNLFdBQVcsR0FBRyxXQUFXLENBQUMsV0FBVyxJQUFJLFNBQVMsQ0FBQTtRQUV4RCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQywwREFBMEQsQ0FBQyxDQUFBO1FBQzdFLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDbkMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFFLENBQUE7WUFDaEQsTUFBTSxtQkFBbUIsR0FBSSxRQUFRLENBQUMsV0FBeUMsQ0FBQyxXQUFXLElBQUksU0FBUyxDQUFBO1lBRXhHLE1BQU0sSUFBSSxLQUFLLENBQ2Isb0JBQW9CLFVBQVUsTUFBTSxtQkFBbUIsd0JBQXdCO2dCQUMvRSxtQkFBbUIsV0FBVyxHQUFHLENBQ2xDLENBQUE7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFBO0lBQzFDLENBQUM7SUFFRCxHQUFHLENBQUMsVUFBa0I7UUFDcEIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUN2QyxDQUFDO0lBRUQsR0FBRyxDQUFDLFVBQWtCO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUE7SUFDdkMsQ0FBQztJQUVELE1BQU07UUFDSixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFBO0lBQzVDLENBQUM7SUFFRCxjQUFjO1FBQ1osT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUMxQyxDQUFDO0lBRUQsS0FBSztRQUNILElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUE7SUFDeEIsQ0FBQztJQUVELElBQUk7UUFDRixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFBO0lBQzVCLENBQUM7Q0FDRjtBQWhERCx3REFnREMifQ==
|