@hartl-services/medusa-base 0.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/.medusa/server/src/admin/index.js +267 -0
- package/.medusa/server/src/admin/index.mjs +266 -0
- package/.medusa/server/src/api/admin/plugin-features/route.js +20 -0
- package/.medusa/server/src/api/middlewares.js +25 -0
- package/.medusa/server/src/api/plugin-features-http.js +20 -0
- package/.medusa/server/src/api/store/plugin-features/[plugin_key]/route.js +13 -0
- package/.medusa/server/src/api/store/plugin-features/route.js +13 -0
- package/.medusa/server/src/api/wire-response.js +10 -0
- package/.medusa/server/src/modules/plugin-features/index.js +14 -0
- package/.medusa/server/src/modules/plugin-features/migrations/Migration20260928155256.js +16 -0
- package/.medusa/server/src/modules/plugin-features/models/plugin-feature-state.js +29 -0
- package/.medusa/server/src/modules/plugin-features/service.js +141 -0
- package/.medusa/server/src/public/constants.js +6 -0
- package/.medusa/server/src/public/descriptor.js +54 -0
- package/.medusa/server/src/public/effective-features.js +74 -0
- package/.medusa/server/src/public/enforcement.js +51 -0
- package/.medusa/server/src/public/index.js +13 -0
- package/.medusa/server/src/public/types.js +3 -0
- package/.medusa/server/src/utils/discover-plugin-features.js +51 -0
- package/LICENSE +21 -0
- package/README.md +166 -0
- package/dist/public/constants.d.ts +2 -0
- package/dist/public/constants.js +5 -0
- package/dist/public/descriptor.d.ts +11 -0
- package/dist/public/descriptor.js +53 -0
- package/dist/public/effective-features.d.ts +28 -0
- package/dist/public/effective-features.js +73 -0
- package/dist/public/enforcement.d.ts +13 -0
- package/dist/public/enforcement.js +50 -0
- package/dist/public/index.d.ts +5 -0
- package/dist/public/index.js +12 -0
- package/dist/public/types.d.ts +29 -0
- package/dist/public/types.js +2 -0
- package/package.json +82 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Migration20260928155256 = void 0;
|
|
4
|
+
const migrations_1 = require("@medusajs/framework/mikro-orm/migrations");
|
|
5
|
+
class Migration20260928155256 extends migrations_1.Migration {
|
|
6
|
+
async up() {
|
|
7
|
+
this.addSql(`create table if not exists "plugin_feature_state" ("id" text not null, "plugin_key" text not null, "enabled" boolean not null, "features" jsonb not null, "version" integer not null default 1, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "plugin_feature_state_pkey" primary key ("id"));`);
|
|
8
|
+
this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_plugin_feature_state_deleted_at" ON "plugin_feature_state" ("deleted_at") WHERE deleted_at IS NULL;`);
|
|
9
|
+
this.addSql(`CREATE UNIQUE INDEX IF NOT EXISTS "IDX_plugin_feature_state_plugin_key" ON "plugin_feature_state" ("plugin_key") WHERE deleted_at IS NULL;`);
|
|
10
|
+
}
|
|
11
|
+
async down() {
|
|
12
|
+
this.addSql(`drop table if exists "plugin_feature_state" cascade;`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.Migration20260928155256 = Migration20260928155256;
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWlncmF0aW9uMjAyNjA5MjgxNTUyNTYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9wbHVnaW4tZmVhdHVyZXMvbWlncmF0aW9ucy9NaWdyYXRpb24yMDI2MDkyODE1NTI1Ni50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5RUFBcUU7QUFFckUsTUFBYSx1QkFBd0IsU0FBUSxzQkFBUztJQUUzQyxLQUFLLENBQUMsRUFBRTtRQUNmLElBQUksQ0FBQyxNQUFNLENBQUMsOFhBQThYLENBQUMsQ0FBQztRQUM1WSxJQUFJLENBQUMsTUFBTSxDQUFDLHFJQUFxSSxDQUFDLENBQUM7UUFDbkosSUFBSSxDQUFDLE1BQU0sQ0FBQyw0SUFBNEksQ0FBQyxDQUFDO0lBQzVKLENBQUM7SUFFUSxLQUFLLENBQUMsSUFBSTtRQUNqQixJQUFJLENBQUMsTUFBTSxDQUFDLHNEQUFzRCxDQUFDLENBQUM7SUFDdEUsQ0FBQztDQUVGO0FBWkQsMERBWUMifQ==
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
/**
|
|
5
|
+
* One row per plugin with configured toggle values. No row means every value
|
|
6
|
+
* is its declared default.
|
|
7
|
+
*/
|
|
8
|
+
const PluginFeatureState = utils_1.model
|
|
9
|
+
.define({
|
|
10
|
+
name: "plugin_feature_state",
|
|
11
|
+
tableName: "plugin_feature_state",
|
|
12
|
+
}, {
|
|
13
|
+
id: utils_1.model.id({ prefix: "plgfeat" }).primaryKey(),
|
|
14
|
+
plugin_key: utils_1.model.text(),
|
|
15
|
+
enabled: utils_1.model.boolean(),
|
|
16
|
+
/** Configured values `{ [featureKey]: boolean }`, declared keys only. */
|
|
17
|
+
features: utils_1.model.json(),
|
|
18
|
+
version: utils_1.model.number().default(1),
|
|
19
|
+
})
|
|
20
|
+
.indexes([
|
|
21
|
+
{
|
|
22
|
+
name: "IDX_plugin_feature_state_plugin_key",
|
|
23
|
+
on: ["plugin_key"],
|
|
24
|
+
unique: true,
|
|
25
|
+
where: "deleted_at IS NULL",
|
|
26
|
+
},
|
|
27
|
+
]);
|
|
28
|
+
exports.default = PluginFeatureState;
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWZlYXR1cmUtc3RhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9wbHVnaW4tZmVhdHVyZXMvbW9kZWxzL3BsdWdpbi1mZWF0dXJlLXN0YXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEscURBQWlEO0FBRWpEOzs7R0FHRztBQUNILE1BQU0sa0JBQWtCLEdBQUcsYUFBSztLQUM3QixNQUFNLENBQ0w7SUFDRSxJQUFJLEVBQUUsc0JBQXNCO0lBQzVCLFNBQVMsRUFBRSxzQkFBc0I7Q0FDbEMsRUFDRDtJQUNFLEVBQUUsRUFBRSxhQUFLLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsVUFBVSxFQUFFO0lBQ2hELFVBQVUsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFO0lBQ3hCLE9BQU8sRUFBRSxhQUFLLENBQUMsT0FBTyxFQUFFO0lBQ3hCLHlFQUF5RTtJQUN6RSxRQUFRLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRTtJQUN0QixPQUFPLEVBQUUsYUFBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7Q0FDbkMsQ0FDRjtLQUNBLE9BQU8sQ0FBQztJQUNQO1FBQ0UsSUFBSSxFQUFFLHFDQUFxQztRQUMzQyxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUM7UUFDbEIsTUFBTSxFQUFFLElBQUk7UUFDWixLQUFLLEVBQUUsb0JBQW9CO0tBQzVCO0NBQ0YsQ0FBQyxDQUFBO0FBRUosa0JBQWUsa0JBQWtCLENBQUEifQ==
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
19
|
+
const effective_features_1 = require("../../public/effective-features");
|
|
20
|
+
const plugin_feature_state_1 = __importDefault(require("./models/plugin-feature-state"));
|
|
21
|
+
const toStored = (row) => {
|
|
22
|
+
const features = {};
|
|
23
|
+
if (row.features && typeof row.features === "object") {
|
|
24
|
+
for (const [key, value] of Object.entries(row.features)) {
|
|
25
|
+
if (typeof value === "boolean") {
|
|
26
|
+
features[key] = value;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return { enabled: row.enabled, features, version: Number(row.version) };
|
|
31
|
+
};
|
|
32
|
+
const describe = (descriptor, stored) => {
|
|
33
|
+
const states = (0, effective_features_1.resolvePluginFeatureStates)(descriptor, stored);
|
|
34
|
+
return {
|
|
35
|
+
plugin_key: descriptor.plugin_key,
|
|
36
|
+
label: descriptor.label,
|
|
37
|
+
description: descriptor.description ?? null,
|
|
38
|
+
default_enabled: descriptor.default_enabled ?? true,
|
|
39
|
+
enabled: states.enabled,
|
|
40
|
+
version: stored?.version ?? 0,
|
|
41
|
+
features: states.features.map((state) => ({
|
|
42
|
+
key: state.definition.key,
|
|
43
|
+
label: state.definition.label,
|
|
44
|
+
description: state.definition.description ?? null,
|
|
45
|
+
parent_key: state.definition.parent_key ?? null,
|
|
46
|
+
default_enabled: state.definition.default_enabled,
|
|
47
|
+
enabled: state.enabled,
|
|
48
|
+
effective_enabled: state.effective_enabled,
|
|
49
|
+
})),
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Persists configured toggle values per plugin. The descriptor (declared by
|
|
54
|
+
* the owning plugin) is always passed in; this module never imports plugins.
|
|
55
|
+
*/
|
|
56
|
+
class PluginFeaturesModuleService extends (0, utils_1.MedusaService)({
|
|
57
|
+
PluginFeatureState: plugin_feature_state_1.default,
|
|
58
|
+
}) {
|
|
59
|
+
async retrieveEffectiveFeatures(descriptor, sharedContext = {}) {
|
|
60
|
+
const stored = await this.retrieveStored(descriptor.plugin_key, sharedContext);
|
|
61
|
+
return (0, effective_features_1.resolveEffectivePluginFeatures)(descriptor, stored);
|
|
62
|
+
}
|
|
63
|
+
async describePluginFeatures(descriptor, sharedContext = {}) {
|
|
64
|
+
const stored = await this.retrieveStored(descriptor.plugin_key, sharedContext);
|
|
65
|
+
return describe(descriptor, stored);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Optimistic concurrency: `expected_version` 0 inserts the first row, any
|
|
69
|
+
* other value updates exactly that version. A lost race is `CONFLICT`.
|
|
70
|
+
*/
|
|
71
|
+
async updatePluginFeatures(descriptor, input, sharedContext = {}) {
|
|
72
|
+
const features = (0, effective_features_1.validateFeatureUpdate)(descriptor, input.features);
|
|
73
|
+
if (!Number.isInteger(input.expected_version) || input.expected_version < 0) {
|
|
74
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "expected_version muss eine nicht-negative ganze Zahl sein.");
|
|
75
|
+
}
|
|
76
|
+
const manager = sharedContext.transactionManager;
|
|
77
|
+
if (!manager) {
|
|
78
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Für die Aktualisierung der Funktionsschalter fehlt die Transaktion.");
|
|
79
|
+
}
|
|
80
|
+
const featuresJson = JSON.stringify(features);
|
|
81
|
+
const rows = input.expected_version === 0
|
|
82
|
+
? await manager.execute(`insert into "plugin_feature_state"
|
|
83
|
+
("id", "plugin_key", "enabled", "features", "version",
|
|
84
|
+
"created_at", "updated_at")
|
|
85
|
+
values (?, ?, ?, ?::jsonb, 1, now(), now())
|
|
86
|
+
on conflict do nothing
|
|
87
|
+
returning "enabled", "features", "version"`, [
|
|
88
|
+
(0, utils_1.generateEntityId)(undefined, "plgfeat"),
|
|
89
|
+
descriptor.plugin_key,
|
|
90
|
+
input.enabled,
|
|
91
|
+
featuresJson,
|
|
92
|
+
], "all")
|
|
93
|
+
: await manager.execute(`update "plugin_feature_state"
|
|
94
|
+
set "enabled" = ?,
|
|
95
|
+
"features" = ?::jsonb,
|
|
96
|
+
"version" = ?,
|
|
97
|
+
"updated_at" = now()
|
|
98
|
+
where "plugin_key" = ?
|
|
99
|
+
and "version" = ?
|
|
100
|
+
and "deleted_at" is null
|
|
101
|
+
returning "enabled", "features", "version"`, [
|
|
102
|
+
input.enabled,
|
|
103
|
+
featuresJson,
|
|
104
|
+
input.expected_version + 1,
|
|
105
|
+
descriptor.plugin_key,
|
|
106
|
+
input.expected_version,
|
|
107
|
+
], "all");
|
|
108
|
+
const saved = rows[0];
|
|
109
|
+
if (!saved) {
|
|
110
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, `Die Funktionsschalter für Plugin "${descriptor.plugin_key}" wurden zwischenzeitlich geändert.`);
|
|
111
|
+
}
|
|
112
|
+
return describe(descriptor, toStored(saved));
|
|
113
|
+
}
|
|
114
|
+
async retrieveStored(pluginKey, sharedContext) {
|
|
115
|
+
const [row] = await this.listPluginFeatureStates({ plugin_key: pluginKey }, { take: 1 }, sharedContext);
|
|
116
|
+
return row ? toStored(row) : null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
__decorate([
|
|
120
|
+
(0, utils_1.InjectManager)(),
|
|
121
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
122
|
+
__metadata("design:type", Function),
|
|
123
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
124
|
+
__metadata("design:returntype", Promise)
|
|
125
|
+
], PluginFeaturesModuleService.prototype, "retrieveEffectiveFeatures", null);
|
|
126
|
+
__decorate([
|
|
127
|
+
(0, utils_1.InjectManager)(),
|
|
128
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
129
|
+
__metadata("design:type", Function),
|
|
130
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
131
|
+
__metadata("design:returntype", Promise)
|
|
132
|
+
], PluginFeaturesModuleService.prototype, "describePluginFeatures", null);
|
|
133
|
+
__decorate([
|
|
134
|
+
(0, utils_1.InjectTransactionManager)(),
|
|
135
|
+
__param(2, (0, utils_1.MedusaContext)()),
|
|
136
|
+
__metadata("design:type", Function),
|
|
137
|
+
__metadata("design:paramtypes", [Object, Object, Object]),
|
|
138
|
+
__metadata("design:returntype", Promise)
|
|
139
|
+
], PluginFeaturesModuleService.prototype, "updatePluginFeatures", null);
|
|
140
|
+
exports.default = PluginFeaturesModuleService;
|
|
141
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL3BsdWdpbi1mZWF0dXJlcy9zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUEscURBT2tDO0FBRWxDLHdFQUl3QztBQU14Qyx5RkFBOEQ7QUFzQjlELE1BQU0sUUFBUSxHQUFHLENBQ2YsR0FBMkIsRUFDaUIsRUFBRTtJQUM5QyxNQUFNLFFBQVEsR0FBNEIsRUFBRSxDQUFBO0lBQzVDLElBQUksR0FBRyxDQUFDLFFBQVEsSUFBSSxPQUFPLEdBQUcsQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDckQsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDeEQsSUFBSSxPQUFPLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDL0IsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQTtZQUN2QixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUE7QUFDekUsQ0FBQyxDQUFBO0FBRUQsTUFBTSxRQUFRLEdBQUcsQ0FDZixVQUFtQyxFQUNuQyxNQUEyRCxFQUN0QyxFQUFFO0lBQ3ZCLE1BQU0sTUFBTSxHQUFHLElBQUEsK0NBQTBCLEVBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBRTdELE9BQU87UUFDTCxVQUFVLEVBQUUsVUFBVSxDQUFDLFVBQVU7UUFDakMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxLQUFLO1FBQ3ZCLFdBQVcsRUFBRSxVQUFVLENBQUMsV0FBVyxJQUFJLElB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
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PLUGIN_FEATURES_MODULE = void 0;
|
|
4
|
+
/** Container key of the base plugin's module (`Module("plugin_features", …)`). */
|
|
5
|
+
exports.PLUGIN_FEATURES_MODULE = "plugin_features";
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3B1YmxpYy9jb25zdGFudHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsa0ZBQWtGO0FBQ3JFLFFBQUEsc0JBQXNCLEdBQUcsaUJBQTBCLENBQUEifQ==
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validatePluginFeatureDescriptor = validatePluginFeatureDescriptor;
|
|
4
|
+
exports.definePluginFeatures = definePluginFeatures;
|
|
5
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
6
|
+
const KEY_PATTERN = /^[a-z][a-z0-9_]{0,62}$/;
|
|
7
|
+
const invalid = (pluginKey, message) => new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Ungültige Funktionsschalter für Plugin "${pluginKey}": ${message}`);
|
|
8
|
+
/**
|
|
9
|
+
* Checks key format, unique feature keys, existing parents and the single
|
|
10
|
+
* allowed nesting level. Throws `INVALID_DATA`.
|
|
11
|
+
*/
|
|
12
|
+
function validatePluginFeatureDescriptor(descriptor) {
|
|
13
|
+
const pluginKey = String(descriptor.plugin_key);
|
|
14
|
+
if (!KEY_PATTERN.test(pluginKey)) {
|
|
15
|
+
throw invalid(pluginKey, "plugin_key hat ein ungültiges Format.");
|
|
16
|
+
}
|
|
17
|
+
if (typeof descriptor.label !== "string" || !descriptor.label.trim()) {
|
|
18
|
+
throw invalid(pluginKey, "label fehlt.");
|
|
19
|
+
}
|
|
20
|
+
const byKey = new Map();
|
|
21
|
+
for (const feature of descriptor.features) {
|
|
22
|
+
if (!KEY_PATTERN.test(feature.key)) {
|
|
23
|
+
throw invalid(pluginKey, `Feature-Key "${feature.key}" hat ein ungültiges Format.`);
|
|
24
|
+
}
|
|
25
|
+
if (byKey.has(feature.key)) {
|
|
26
|
+
throw invalid(pluginKey, `Feature-Key "${feature.key}" ist doppelt.`);
|
|
27
|
+
}
|
|
28
|
+
if (typeof feature.label !== "string" || !feature.label.trim()) {
|
|
29
|
+
throw invalid(pluginKey, `Feature "${feature.key}" hat kein label.`);
|
|
30
|
+
}
|
|
31
|
+
byKey.set(feature.key, feature);
|
|
32
|
+
}
|
|
33
|
+
for (const feature of descriptor.features) {
|
|
34
|
+
if (feature.parent_key === undefined) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const parent = byKey.get(feature.parent_key);
|
|
38
|
+
if (!parent || parent.key === feature.key) {
|
|
39
|
+
throw invalid(pluginKey, `Parent "${feature.parent_key}" von Feature "${feature.key}" existiert nicht.`);
|
|
40
|
+
}
|
|
41
|
+
if (parent.parent_key !== undefined) {
|
|
42
|
+
throw invalid(pluginKey, `Feature "${feature.key}" ist zu tief verschachtelt; erlaubt ist eine Ebene.`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Declares a plugin's feature switches. Validates at import time so a broken
|
|
48
|
+
* declaration fails the boot instead of a request.
|
|
49
|
+
*/
|
|
50
|
+
function definePluginFeatures(descriptor) {
|
|
51
|
+
validatePluginFeatureDescriptor(descriptor);
|
|
52
|
+
return descriptor;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVzY3JpcHRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9wdWJsaWMvZGVzY3JpcHRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWdCQSwwRUE0Q0M7QUFNRCxvREFLQztBQXZFRCxxREFBdUQ7QUFJdkQsTUFBTSxXQUFXLEdBQUcsd0JBQXdCLENBQUE7QUFFNUMsTUFBTSxPQUFPLEdBQUcsQ0FBQyxTQUFpQixFQUFFLE9BQWUsRUFBZSxFQUFFLENBQ2xFLElBQUksbUJBQVcsQ0FDYixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLDJDQUEyQyxTQUFTLE1BQU0sT0FBTyxFQUFFLENBQ3BFLENBQUE7QUFFSDs7O0dBR0c7QUFDSCxTQUFnQiwrQkFBK0IsQ0FDN0MsVUFBbUM7SUFFbkMsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUUvQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ2pDLE1BQU0sT0FBTyxDQUFDLFNBQVMsRUFBRSx1Q0FBdUMsQ0FBQyxDQUFBO0lBQ25FLENBQUM7SUFDRCxJQUFJLE9BQU8sVUFBVSxDQUFDLEtBQUssS0FBSyxRQUFRLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7UUFDckUsTUFBTSxPQUFPLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxDQUFBO0lBQzFDLENBQUM7SUFFRCxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsRUFBdUQsQ0FBQTtJQUM1RSxLQUFLLE1BQU0sT0FBTyxJQUFJLFVBQVUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMxQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNuQyxNQUFNLE9BQU8sQ0FBQyxTQUFTLEVBQUUsZ0JBQWdCLE9BQU8sQ0FBQyxHQUFHLDhCQUE4QixDQUFDLENBQUE7UUFDckYsQ0FBQztRQUNELElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUMzQixNQUFNLE9BQU8sQ0FBQyxTQUFTLEVBQUUsZ0JBQWdCLE9BQU8sQ0FBQyxHQUFHLGdCQUFnQixDQUFDLENBQUE7UUFDdkUsQ0FBQztRQUNELElBQUksT0FBTyxPQUFPLENBQUMsS0FBSyxLQUFLLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztZQUMvRCxNQUFNLE9BQU8sQ0FBQyxTQUFTLEVBQUUsWUFBWSxPQUFPLENBQUMsR0FBRyxtQkFBbUIsQ0FBQyxDQUFBO1FBQ3RFLENBQUM7UUFDRCxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFDakMsQ0FBQztJQUVELEtBQUssTUFBTSxPQUFPLElBQUksVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzFDLElBQUksT0FBTyxDQUFDLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNyQyxTQUFRO1FBQ1YsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBQzVDLElBQUksQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLEdBQUcsS0FBSyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDMUMsTUFBTSxPQUFPLENBQ1gsU0FBUyxFQUNULFdBQVcsT0FBTyxDQUFDLFVBQVUsa0JBQWtCLE9BQU8sQ0FBQyxHQUFHLG9CQUFvQixDQUMvRSxDQUFBO1FBQ0gsQ0FBQztRQUNELElBQUksTUFBTSxDQUFDLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNwQyxNQUFNLE9BQU8sQ0FDWCxTQUFTLEVBQ1QsWUFBWSxPQUFPLENBQUMsR0FBRyxzREFBc0QsQ0FDOUUsQ0FBQTtRQUNILENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQWdCLG9CQUFvQixDQUNsQyxVQUFzQztJQUV0QywrQkFBK0IsQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUMzQyxPQUFPLFVBQVUsQ0FBQTtBQUNuQixDQUFDIn0=
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolvePluginFeatureStates = resolvePluginFeatureStates;
|
|
4
|
+
exports.resolveEffectivePluginFeatures = resolveEffectivePluginFeatures;
|
|
5
|
+
exports.validateFeatureUpdate = validateFeatureUpdate;
|
|
6
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
7
|
+
/**
|
|
8
|
+
* Configured and effective values of every declared feature.
|
|
9
|
+
* `effective(f) = pluginEnabled && configured(f) && effective(parent(f))`.
|
|
10
|
+
* Stored keys the descriptor no longer declares are ignored; declared keys
|
|
11
|
+
* without a stored value fall back to their default.
|
|
12
|
+
*/
|
|
13
|
+
function resolvePluginFeatureStates(descriptor, stored) {
|
|
14
|
+
const pluginEnabled = stored
|
|
15
|
+
? stored.enabled
|
|
16
|
+
: descriptor.default_enabled ?? true;
|
|
17
|
+
const configured = new Map();
|
|
18
|
+
for (const feature of descriptor.features) {
|
|
19
|
+
const value = stored?.features[feature.key];
|
|
20
|
+
configured.set(feature.key, typeof value === "boolean" ? value : feature.default_enabled);
|
|
21
|
+
}
|
|
22
|
+
const effective = (feature) => {
|
|
23
|
+
if (!pluginEnabled || configured.get(feature.key) !== true) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
if (feature.parent_key === undefined) {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
// Validated descriptors allow one nesting level, so the parent is a root.
|
|
30
|
+
return configured.get(feature.parent_key) === true;
|
|
31
|
+
};
|
|
32
|
+
return {
|
|
33
|
+
enabled: pluginEnabled,
|
|
34
|
+
features: descriptor.features.map((definition) => ({
|
|
35
|
+
definition,
|
|
36
|
+
enabled: configured.get(definition.key) === true,
|
|
37
|
+
effective_enabled: effective(definition),
|
|
38
|
+
})),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** Pure rule shared by service and tests. `stored === null` means no row. */
|
|
42
|
+
function resolveEffectivePluginFeatures(descriptor, stored) {
|
|
43
|
+
const states = resolvePluginFeatureStates(descriptor, stored);
|
|
44
|
+
const features = {};
|
|
45
|
+
for (const state of states.features) {
|
|
46
|
+
features[state.definition.key] = state.effective_enabled;
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
plugin_key: descriptor.plugin_key,
|
|
50
|
+
enabled: states.enabled,
|
|
51
|
+
features,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Rejects configured values for keys the descriptor does not declare and
|
|
56
|
+
* returns the values to persist (declared keys only; missing keys keep their
|
|
57
|
+
* default).
|
|
58
|
+
*/
|
|
59
|
+
function validateFeatureUpdate(descriptor, features) {
|
|
60
|
+
const declared = new Set(descriptor.features.map((feature) => feature.key));
|
|
61
|
+
const unknown = Object.keys(features).filter((key) => !declared.has(key));
|
|
62
|
+
if (unknown.length) {
|
|
63
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Unbekannte Funktionsschalter für Plugin "${descriptor.plugin_key}": ${unknown.join(", ")}.`);
|
|
64
|
+
}
|
|
65
|
+
const result = {};
|
|
66
|
+
for (const feature of descriptor.features) {
|
|
67
|
+
const value = features[feature.key];
|
|
68
|
+
if (typeof value === "boolean") {
|
|
69
|
+
result[feature.key] = value;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWZmZWN0aXZlLWZlYXR1cmVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3B1YmxpYy9lZmZlY3RpdmUtZmVhdHVyZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUE2QkEsZ0VBb0NDO0FBR0Qsd0VBZUM7QUFPRCxzREFzQkM7QUFoSEQscURBQXVEO0FBdUJ2RDs7Ozs7R0FLRztBQUNILFNBQWdCLDBCQUEwQixDQUN4QyxVQUFtQyxFQUNuQyxNQUFtQztJQUVuQyxNQUFNLGFBQWEsR0FBRyxNQUFNO1FBQzFCLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTztRQUNoQixDQUFDLENBQUMsVUFBVSxDQUFDLGVBQWUsSUFBSSxJQUFJLENBQUE7SUFFdEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxHQUFHLEVBQW1CLENBQUE7SUFDN0MsS0FBSyxNQUFNLE9BQU8sSUFBSSxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDMUMsTUFBTSxLQUFLLEdBQUcsTUFBTSxFQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDM0MsVUFBVSxDQUFDLEdBQUcsQ0FDWixPQUFPLENBQUMsR0FBRyxFQUNYLE9BQU8sS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUM3RCxDQUFBO0lBQ0gsQ0FBQztJQUVELE1BQU0sU0FBUyxHQUFHLENBQUMsT0FBZ0MsRUFBVyxFQUFFO1FBQzlELElBQUksQ0FBQyxhQUFhLElBQUksVUFBVSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7WUFDM0QsT0FBTyxLQUFLLENBQUE7UUFDZCxDQUFDO1FBQ0QsSUFBSSxPQUFPLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3JDLE9BQU8sSUFBSSxDQUFBO1FBQ2IsQ0FBQztRQUNELDBFQUEwRTtRQUMxRSxPQUFPLFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxLQUFLLElBQUksQ0FBQTtJQUNwRCxDQUFDLENBQUE7SUFFRCxPQUFPO1FBQ0wsT0FBTyxFQUFFLGFBQWE7UUFDdEIsUUFBUSxFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ2pELFVBQVU7WUFDVixPQUFPLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEtBQUssSUFBSTtZQUNoRCxpQkFBaUIsRUFBRSxTQUFTLENBQUMsVUFBVSxDQUFDO1NBQ3pDLENBQUMsQ0FBQztLQUNKLENBQUE7QUFDSCxDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLFNBQWdCLDhCQUE4QixDQUM1QyxVQUFtQyxFQUNuQyxNQUFtQztJQUVuQyxNQUFNLE1BQU0sR0FBRywwQkFBMEIsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUE7SUFDN0QsTUFBTSxRQUFRLEdBQTRCLEVBQUUsQ0FBQTtJQUM1QyxLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNwQyxRQUFRLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUMsaUJBQWlCLENBQUE7SUFDMUQsQ0FBQztJQUVELE9BQU87UUFDTCxVQUFVLEVBQUUsVUFBVSxDQUFDLFVBQVU7UUFDakMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPO1FBQ3ZCLFFBQVE7S0FDVCxDQUFBO0FBQ0gsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixxQkFBcUIsQ0FDbkMsVUFBbUMsRUFDbkMsUUFBaUM7SUFFakMsTUFBTSxRQUFRLEdBQUcsSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0lBQzNFLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtJQUV6RSxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNuQixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5Qiw0Q0FBNEMsVUFBVSxDQUFDLFVBQVUsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQzdGLENBQUE7SUFDSCxDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQTRCLEVBQUUsQ0FBQTtJQUMxQyxLQUFLLE1BQU0sT0FBTyxJQUFJLFVBQVUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMxQyxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ25DLElBQUksT0FBTyxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDL0IsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUE7UUFDN0IsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQTtBQUNmLENBQUMifQ==
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isPluginFeatureEnabled = isPluginFeatureEnabled;
|
|
4
|
+
exports.requirePluginFeature = requirePluginFeature;
|
|
5
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
6
|
+
const constants_1 = require("./constants");
|
|
7
|
+
const resolveReader = (container) => {
|
|
8
|
+
if (!container.hasRegistration(constants_1.PLUGIN_FEATURES_MODULE)) {
|
|
9
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "@hartl-services/medusa-base ist nicht in medusa-config registriert.");
|
|
10
|
+
}
|
|
11
|
+
return container.resolve(constants_1.PLUGIN_FEATURES_MODULE);
|
|
12
|
+
};
|
|
13
|
+
const allEnabled = (effective, keys) => effective.enabled && keys.every((key) => effective.features[key] === true);
|
|
14
|
+
/**
|
|
15
|
+
* For subscribers, jobs and workflow steps. No keys = plugin switch only;
|
|
16
|
+
* several keys = all must be enabled. Read failures propagate.
|
|
17
|
+
*/
|
|
18
|
+
async function isPluginFeatureEnabled(container, descriptor, ...keys) {
|
|
19
|
+
const effective = await resolveReader(container).retrieveEffectiveFeatures(descriptor);
|
|
20
|
+
return allEnabled(effective, keys);
|
|
21
|
+
}
|
|
22
|
+
// Keyed by the request object, so one request reads each plugin's toggles once
|
|
23
|
+
// even when several gate middlewares match it.
|
|
24
|
+
const requestMemo = new WeakMap();
|
|
25
|
+
const effectiveForRequest = (req, descriptor) => {
|
|
26
|
+
let perRequest = requestMemo.get(req);
|
|
27
|
+
if (!perRequest) {
|
|
28
|
+
perRequest = new Map();
|
|
29
|
+
requestMemo.set(req, perRequest);
|
|
30
|
+
}
|
|
31
|
+
let pending = perRequest.get(descriptor.plugin_key);
|
|
32
|
+
if (!pending) {
|
|
33
|
+
pending = resolveReader(req.scope).retrieveEffectiveFeatures(descriptor);
|
|
34
|
+
perRequest.set(descriptor.plugin_key, pending);
|
|
35
|
+
}
|
|
36
|
+
return pending;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Middleware for `defineMiddlewares`. A disabled plugin or feature answers
|
|
40
|
+
* with `NOT_FOUND` (404); all given keys must be enabled.
|
|
41
|
+
*/
|
|
42
|
+
function requirePluginFeature(descriptor, ...keys) {
|
|
43
|
+
return async (req, _res, next) => {
|
|
44
|
+
const effective = await effectiveForRequest(req, descriptor);
|
|
45
|
+
if (!allEnabled(effective, keys)) {
|
|
46
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Diese Funktion ist in diesem Shop nicht aktiviert.");
|
|
47
|
+
}
|
|
48
|
+
next();
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5mb3JjZW1lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvcHVibGljL2VuZm9yY2VtZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBdUNBLHdEQVFDO0FBK0JELG9EQW9CQztBQTNGRCxxREFBdUQ7QUFFdkQsMkNBQW9EO0FBVXBELE1BQU0sYUFBYSxHQUFHLENBQUMsU0FBMEIsRUFBdUIsRUFBRTtJQUN4RSxJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxrQ0FBc0IsQ0FBQyxFQUFFLENBQUM7UUFDdkQsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUNsQyxxRUFBcUUsQ0FDdEUsQ0FBQTtJQUNILENBQUM7SUFDRCxPQUFPLFNBQVMsQ0FBQyxPQUFPLENBQXNCLGtDQUFzQixDQUFDLENBQUE7QUFDdkUsQ0FBQyxDQUFBO0FBRUQsTUFBTSxVQUFVLEdBQUcsQ0FDakIsU0FBa0MsRUFDbEMsSUFBdUIsRUFDZCxFQUFFLENBQ1gsU0FBUyxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFBO0FBRTVFOzs7R0FHRztBQUNJLEtBQUssVUFBVSxzQkFBc0IsQ0FDMUMsU0FBMEIsRUFDMUIsVUFBc0MsRUFDdEMsR0FBRyxJQUFTO0lBRVosTUFBTSxTQUFTLEdBQ2IsTUFBTSxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUMseUJBQXlCLENBQUMsVUFBVSxDQUFDLENBQUE7SUFDdEUsT0FBTyxVQUFVLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFBO0FBQ3BDLENBQUM7QUFFRCwrRUFBK0U7QUFDL0UsK0NBQStDO0FBQy9DLE1BQU0sV0FBVyxHQUFHLElBQUksT0FBTyxFQUc1QixDQUFBO0FBRUgsTUFBTSxtQkFBbUIsR0FBRyxDQUMxQixHQUFrQixFQUNsQixVQUFtQyxFQUNELEVBQUU7SUFDcEMsSUFBSSxVQUFVLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUNyQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDaEIsVUFBVSxHQUFHLElBQUksR0FBRyxFQUFFLENBQUE7UUFDdEIsV0FBVyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDLENBQUE7SUFDbEMsQ0FBQztJQUVELElBQUksT0FBTyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQ25ELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNiLE9BQU8sR0FBRyxhQUFhLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLHlCQUF5QixDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBQ3hFLFVBQVUsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQTtJQUNoRCxDQUFDO0lBQ0QsT0FBTyxPQUFPLENBQUE7QUFDaEIsQ0FBQyxDQUFBO0FBRUQ7OztHQUdHO0FBQ0gsU0FBZ0Isb0JBQW9CLENBQ2xDLFVBQXNDLEVBQ3RDLEdBQUcsSUFBUztJQUVaLE9BQU8sS0FBSyxFQUNWLEdBQWtCLEVBQ2xCLElBQW9CLEVBQ3BCLElBQXdCLEVBQ1QsRUFBRTtRQUNqQixNQUFNLFNBQVMsR0FBRyxNQUFNLG1CQUFtQixDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsQ0FBQTtRQUU1RCxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ2pDLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQzNCLG9EQUFvRCxDQUNyRCxDQUFBO1FBQ0gsQ0FBQztRQUVELElBQUksRUFBRSxDQUFBO0lBQ1IsQ0FBQyxDQUFBO0FBQ0gsQ0FBQyJ9
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.requirePluginFeature = exports.isPluginFeatureEnabled = exports.resolveEffectivePluginFeatures = exports.definePluginFeatures = exports.PLUGIN_FEATURES_MODULE = void 0;
|
|
4
|
+
var constants_1 = require("./constants");
|
|
5
|
+
Object.defineProperty(exports, "PLUGIN_FEATURES_MODULE", { enumerable: true, get: function () { return constants_1.PLUGIN_FEATURES_MODULE; } });
|
|
6
|
+
var descriptor_1 = require("./descriptor");
|
|
7
|
+
Object.defineProperty(exports, "definePluginFeatures", { enumerable: true, get: function () { return descriptor_1.definePluginFeatures; } });
|
|
8
|
+
var effective_features_1 = require("./effective-features");
|
|
9
|
+
Object.defineProperty(exports, "resolveEffectivePluginFeatures", { enumerable: true, get: function () { return effective_features_1.resolveEffectivePluginFeatures; } });
|
|
10
|
+
var enforcement_1 = require("./enforcement");
|
|
11
|
+
Object.defineProperty(exports, "isPluginFeatureEnabled", { enumerable: true, get: function () { return enforcement_1.isPluginFeatureEnabled; } });
|
|
12
|
+
Object.defineProperty(exports, "requirePluginFeature", { enumerable: true, get: function () { return enforcement_1.requirePluginFeature; } });
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvcHVibGljL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlDQUFvRDtBQUEzQyxtSEFBQSxzQkFBc0IsT0FBQTtBQUMvQiwyQ0FBbUQ7QUFBMUMsa0hBQUEsb0JBQW9CLE9BQUE7QUFDN0IsMkRBQXFFO0FBQTVELG9JQUFBLDhCQUE4QixPQUFBO0FBQ3ZDLDZDQUE0RTtBQUFuRSxxSEFBQSxzQkFBc0IsT0FBQTtBQUFFLG1IQUFBLG9CQUFvQixPQUFBIn0=
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvcHVibGljL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.discoverPluginFeatureDescriptors = discoverPluginFeatureDescriptors;
|
|
4
|
+
exports.findPluginFeatureDescriptor = findPluginFeatureDescriptor;
|
|
5
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
6
|
+
const descriptor_1 = require("../public/descriptor");
|
|
7
|
+
// Keyed by the app's config object: stable for the process lifetime, unlike
|
|
8
|
+
// `req.scope`, which is a new scope per request.
|
|
9
|
+
const discovered = new WeakMap();
|
|
10
|
+
const readDescriptor = (service) => service !== null && typeof service === "object" && "pluginFeatures" in service
|
|
11
|
+
? service.pluginFeatures
|
|
12
|
+
: undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Finds every registered module whose service declares `pluginFeatures`.
|
|
15
|
+
* Fails closed: an invalid or duplicate declaration is `UNEXPECTED_STATE`.
|
|
16
|
+
*/
|
|
17
|
+
function discoverPluginFeatureDescriptors(container) {
|
|
18
|
+
const configModule = container.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
19
|
+
const memo = discovered.get(configModule);
|
|
20
|
+
if (memo) {
|
|
21
|
+
return memo;
|
|
22
|
+
}
|
|
23
|
+
const byPluginKey = new Map();
|
|
24
|
+
for (const moduleKey of Object.keys(configModule.modules ?? {})) {
|
|
25
|
+
if (!container.hasRegistration(moduleKey)) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const candidate = readDescriptor(container.resolve(moduleKey));
|
|
29
|
+
if (candidate === undefined) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const descriptor = candidate;
|
|
33
|
+
try {
|
|
34
|
+
(0, descriptor_1.validatePluginFeatureDescriptor)(descriptor);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Modul "${moduleKey}" deklariert ungültige Funktionsschalter: ${error instanceof Error ? error.message : String(error)}`);
|
|
38
|
+
}
|
|
39
|
+
if (byPluginKey.has(descriptor.plugin_key)) {
|
|
40
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Plugin-Key "${descriptor.plugin_key}" wird von mehreren Modulen deklariert.`);
|
|
41
|
+
}
|
|
42
|
+
byPluginKey.set(descriptor.plugin_key, descriptor);
|
|
43
|
+
}
|
|
44
|
+
const result = [...byPluginKey.values()].sort((left, right) => left.plugin_key.localeCompare(right.plugin_key));
|
|
45
|
+
discovered.set(configModule, result);
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
function findPluginFeatureDescriptor(container, pluginKey) {
|
|
49
|
+
return discoverPluginFeatureDescriptors(container).find((descriptor) => descriptor.plugin_key === pluginKey);
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzY292ZXItcGx1Z2luLWZlYXR1cmVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL2Rpc2NvdmVyLXBsdWdpbi1mZWF0dXJlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQXVCQSw0RUFnREM7QUFFRCxrRUFPQztBQS9FRCxxREFBa0Y7QUFFbEYscURBQXNFO0FBT3RFLDRFQUE0RTtBQUM1RSxpREFBaUQ7QUFDakQsTUFBTSxVQUFVLEdBQUcsSUFBSSxPQUFPLEVBQXFDLENBQUE7QUFFbkUsTUFBTSxjQUFjLEdBQUcsQ0FBQyxPQUFnQixFQUFXLEVBQUUsQ0FDbkQsT0FBTyxLQUFLLElBQUksSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRLElBQUksZ0JBQWdCLElBQUksT0FBTztJQUM1RSxDQUFDLENBQUUsT0FBdUMsQ0FBQyxjQUFjO0lBQ3pELENBQUMsQ0FBQyxTQUFTLENBQUE7QUFFZjs7O0dBR0c7QUFDSCxTQUFnQixnQ0FBZ0MsQ0FDOUMsU0FBMEI7SUFFMUIsTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FDcEMsaUNBQXlCLENBQUMsYUFBYSxDQUN4QyxDQUFBO0lBQ0QsTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQTtJQUN6QyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ1QsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRUQsTUFBTSxXQUFXLEdBQUcsSUFBSSxHQUFHLEVBQW1DLENBQUE7SUFDOUQsS0FBSyxNQUFNLFNBQVMsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUNoRSxJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQzFDLFNBQVE7UUFDVixDQUFDO1FBRUQsTUFBTSxTQUFTLEdBQUcsY0FBYyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQVUsU0FBUyxDQUFDLENBQUMsQ0FBQTtRQUN2RSxJQUFJLFNBQVMsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUM1QixTQUFRO1FBQ1YsQ0FBQztRQUVELE1BQU0sVUFBVSxHQUFHLFNBQW9DLENBQUE7UUFDdkQsSUFBSSxDQUFDO1lBQ0gsSUFBQSw0Q0FBK0IsRUFBQyxVQUFVLENBQUMsQ0FBQTtRQUM3QyxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFDbEMsVUFBVSxTQUFTLDZDQUNqQixLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUN2RCxFQUFFLENBQ0gsQ0FBQTtRQUNILENBQUM7UUFFRCxJQUFJLFdBQVcsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDM0MsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUNsQyxlQUFlLFVBQVUsQ0FBQyxVQUFVLHlDQUF5QyxDQUM5RSxDQUFBO1FBQ0gsQ0FBQztRQUNELFdBQVcsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQTtJQUNwRCxDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUM1RCxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQ2hELENBQUE7SUFDRCxVQUFVLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUNwQyxPQUFPLE1BQU0sQ0FBQTtBQUNmLENBQUM7QUFFRCxTQUFnQiwyQkFBMkIsQ0FDekMsU0FBMEIsRUFDMUIsU0FBaUI7SUFFakIsT0FBTyxnQ0FBZ0MsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQ3JELENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsVUFBVSxLQUFLLFNBQVMsQ0FDcEQsQ0FBQTtBQUNILENBQUMifQ==
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Hartl Services GmbH
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|