@red-hat-developer-hub/backstage-plugin-extensions-backend 0.14.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/CHANGELOG.md ADDED
@@ -0,0 +1,329 @@
1
+ # @red-hat-developer-hub/backstage-plugin-extensions-backend
2
+
3
+ ## 0.14.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 4fafdf3: Renamed plugins from marketplace to extensions
8
+
9
+ - Renamed all packages from `backstage-plugin-marketplace-*` to `backstage-plugin-extensions-*`
10
+ - Updated all internal references, exports, and API endpoints
11
+ - lazy load codeEditor to reduce the frontend plugin bundle size
12
+ - Made catalog entities directory path configurable via `extensions.directory` in app-config.yaml with fallback to `extensions` and `marketplace` directories
13
+
14
+ ### Patch Changes
15
+
16
+ - Updated dependencies [4fafdf3]
17
+ - @red-hat-developer-hub/backstage-plugin-extensions-common@0.14.0
18
+
19
+ ## 0.13.2
20
+
21
+ ### Patch Changes
22
+
23
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.13.2
24
+
25
+ ## 0.13.1
26
+
27
+ ### Patch Changes
28
+
29
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.13.1
30
+
31
+ ## 0.13.0
32
+
33
+ ### Minor Changes
34
+
35
+ - bee615a: Backstage version bump to v1.45.2
36
+
37
+ ### Patch Changes
38
+
39
+ - Updated dependencies [bee615a]
40
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.13.0
41
+
42
+ ## 0.12.2
43
+
44
+ ### Patch Changes
45
+
46
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.12.2
47
+
48
+ ## 0.12.1
49
+
50
+ ### Patch Changes
51
+
52
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.12.1
53
+
54
+ ## 0.12.0
55
+
56
+ ### Minor Changes
57
+
58
+ - f8e6f04: Backstage version bump to v1.44.1
59
+
60
+ ### Patch Changes
61
+
62
+ - Updated dependencies [f8e6f04]
63
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.12.0
64
+
65
+ ## 0.11.0
66
+
67
+ ### Minor Changes
68
+
69
+ - 36a7d6a: **BREAKING** Replace POST with PATCH `/package/:namespace/:name/configuration/disable` endpoint to update packages disabled status
70
+
71
+ ### Patch Changes
72
+
73
+ - 4d79286: added row actions to the installed packages
74
+ updated disablePackage Client API to make PATCH call instead of POST
75
+ - Updated dependencies [4d79286]
76
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.10.1
77
+
78
+ ## 0.10.0
79
+
80
+ ### Minor Changes
81
+
82
+ - b33db25: Backstage version bump to v1.42.5
83
+
84
+ ### Patch Changes
85
+
86
+ - Updated dependencies [b33db25]
87
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.10.0
88
+
89
+ ## 0.9.0
90
+
91
+ ### Minor Changes
92
+
93
+ - fdda9a1: Add internationalization (i18n) support with German, French and Spanish translations in marketplace.
94
+ - dad9806: Integrate plugins-info plugin and add `Installed packages` tab with enhanced UI.
95
+
96
+ BREAKING: The deprecated `InstallationContextProvider` export behavior changed.
97
+
98
+ - We now export a null component `InstallationContextProvider` from `plugin.ts` solely for backward compatibility. It no longer provides context and will be removed in a future release.
99
+ - Migration: There is no replacement API; this was internal-only. Please upgrade to the latest RHDH where features no longer rely on this provider.
100
+
101
+ Also:
102
+
103
+ - New `Installed packages` tab with dual-source mapping and client-side filtering/pagination.
104
+
105
+ ### Patch Changes
106
+
107
+ - Updated dependencies [fdda9a1]
108
+ - Updated dependencies [cbe1174]
109
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.9.0
110
+
111
+ ## 0.8.0
112
+
113
+ ### Minor Changes
114
+
115
+ - 8887468: Backstage version bump to v1.41.1
116
+
117
+ ### Patch Changes
118
+
119
+ - Updated dependencies [8887468]
120
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.8.0
121
+
122
+ ## 0.7.4
123
+
124
+ ### Patch Changes
125
+
126
+ - Updated dependencies [171b7fd]
127
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.7.2
128
+
129
+ ## 0.7.3
130
+
131
+ ### Patch Changes
132
+
133
+ - fb23720: Introduce `spec.integrity` field for Marketplace package
134
+ - Updated dependencies [fb23720]
135
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.7.1
136
+
137
+ ## 0.7.2
138
+
139
+ ### Patch Changes
140
+
141
+ - 7aa3823: Restrict access to configuration endpoints in production
142
+
143
+ ## 0.7.1
144
+
145
+ ### Patch Changes
146
+
147
+ - 8ada066: Update all plugin packages via PATCH `/plugin/:namespace/:name/configuration/disable`
148
+
149
+ ## 0.7.0
150
+
151
+ ### Minor Changes
152
+
153
+ - f70ccb1: Use plugin permissions in package configuration endpoints. `AuthorizeResult` for particular package is based upon if user has ALLOW permission for any of plugins that contain this package. Removes unused `extensions-package` permissions.
154
+
155
+ ### Patch Changes
156
+
157
+ - Updated dependencies [f70ccb1]
158
+ - Updated dependencies [7aac60c]
159
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.7.0
160
+
161
+ ## 0.6.0
162
+
163
+ ### Minor Changes
164
+
165
+ - 3973839: Introduces PUT endpoint for enabling or disabling dynamic plugins: `/plugin/:namespace/:name/configuration/disable` and POST endpoint for enabling or disabling dynamic packages `/package/:namespace/:name/configuration/disable` not already existing in `EXTENSIONS_PLUGIN_CONFIG`.
166
+
167
+ ### Patch Changes
168
+
169
+ - ca2e330: Bump to backstage version 1.39.1
170
+ - 58ae1fe: Added an alert for production environment
171
+ Integrated the fetch configuration and install API calls
172
+ Fixed an import error
173
+ - Updated dependencies [ca2e330]
174
+ - Updated dependencies [3973839]
175
+ - Updated dependencies [58ae1fe]
176
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.6.0
177
+
178
+ ## 0.5.0
179
+
180
+ ### Minor Changes
181
+
182
+ - 7ae0ca0: Introduces POST endpoints for updating dynamic plugins and packages installation configuration: `/package/:namespace/:name/configuration` and `/plugin/:namespace/:name/configuration`.
183
+
184
+ ### Patch Changes
185
+
186
+ - Updated dependencies [7ae0ca0]
187
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.5.0
188
+
189
+ ## 0.4.0
190
+
191
+ ### Minor Changes
192
+
193
+ - 7d138e5: Added extension permissions
194
+ - f56908a: Introduces GET endpoints for dynamic plugins configuration: `/package/:namespace/:name/configuration` and `/plugin/:namespace/:name/configuration`. Introduces optional config value `extensions.installation` which is used for installation configuration.
195
+
196
+ ### Patch Changes
197
+
198
+ - 4413eef: updated `extension` to `extensions`
199
+ update marketplace pluginId to extensions
200
+ - Updated dependencies [4413eef]
201
+ - Updated dependencies [7d138e5]
202
+ - Updated dependencies [f56908a]
203
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.4.0
204
+
205
+ ## 0.3.1
206
+
207
+ ### Patch Changes
208
+
209
+ - 0f6f539: Allows packages API to return 'spec.appConfigExamples' data.
210
+
211
+ ## 0.3.0
212
+
213
+ ### Minor Changes
214
+
215
+ - 6501387: Backstage version bump to v1.36.1
216
+
217
+ ### Patch Changes
218
+
219
+ - Updated dependencies [6501387]
220
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.3.0
221
+
222
+ ## 0.2.0
223
+
224
+ ### Minor Changes
225
+
226
+ - d3bcc76: rename apiVersion and annotations to extensions.backstage.io
227
+
228
+ ### Patch Changes
229
+
230
+ - Updated dependencies [d3bcc76]
231
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.2.0
232
+
233
+ ## 0.1.2
234
+
235
+ ### Patch Changes
236
+
237
+ - a7e38a9: remove core-plugin-api dependency from common
238
+ - Updated dependencies [a7e38a9]
239
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.1.2
240
+
241
+ ## 0.1.1
242
+
243
+ ### Patch Changes
244
+
245
+ - fa70a22: remove unused knex and zod dependency from common package
246
+ - Updated dependencies [fa70a22]
247
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.1.1
248
+
249
+ ## 0.1.0
250
+
251
+ ### Minor Changes
252
+
253
+ - d39d4e3: Initial tech-preview of the marketplace
254
+
255
+ ### Patch Changes
256
+
257
+ - f16dd69: Refactore and update API, UI, and catalog types
258
+ - Updated dependencies [d39d4e3]
259
+ - Updated dependencies [f16dd69]
260
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.1.0
261
+
262
+ ## 0.0.9
263
+
264
+ ### Patch Changes
265
+
266
+ - Updated dependencies [f310add]
267
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.0.9
268
+
269
+ ## 0.0.8
270
+
271
+ ### Patch Changes
272
+
273
+ - 4e0ec06: add optional sorting, filtering, pagination to marketplace api
274
+ - Updated dependencies [4e0ec06]
275
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.0.8
276
+
277
+ ## 0.0.7
278
+
279
+ ### Patch Changes
280
+
281
+ - 9a3c185: replace custom aggregation api endpoint with catalog entity-facets api
282
+ - Updated dependencies [9a3c185]
283
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.0.7
284
+
285
+ ## 0.0.6
286
+
287
+ ### Patch Changes
288
+
289
+ - Updated dependencies [0bcb97f]
290
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.0.6
291
+
292
+ ## 0.0.5
293
+
294
+ ### Patch Changes
295
+
296
+ - 381a250: Upgrade Backstage from 1.32.0 to 1.35.0
297
+ - Updated dependencies [381a250]
298
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.0.5
299
+
300
+ ## 0.0.4
301
+
302
+ ### Patch Changes
303
+
304
+ - 113ff0d: Add new aggregation api in marketplace
305
+ - Updated dependencies [113ff0d]
306
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.0.4
307
+
308
+ ## 0.0.3
309
+
310
+ ### Patch Changes
311
+
312
+ - 58c2d47: Add new endpoints in marketplace.
313
+ - Updated dependencies [58c2d47]
314
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.0.3
315
+
316
+ ## 0.0.2
317
+
318
+ ### Patch Changes
319
+
320
+ - Updated dependencies [8c442b6]
321
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.0.2
322
+
323
+ ## 0.0.1
324
+
325
+ ### Patch Changes
326
+
327
+ - 56f9484: release marketplace plugin
328
+ - Updated dependencies [56f9484]
329
+ - @red-hat-developer-hub/backstage-plugin-marketplace-common@0.0.1
package/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # extensions
2
+
3
+ This plugin backend was templated using the Backstage CLI. You should replace this text with a description of your plugin backend.
4
+
5
+ ## Installation
6
+
7
+ This plugin is installed via the `@red-hat-developer-hub/backstage-plugin-extensions-backend` package. To install it to your backend package, run the following command:
8
+
9
+ ```bash
10
+ # From your root directory
11
+ yarn --cwd packages/backend add @red-hat-developer-hub/backstage-plugin-extensions-backend
12
+ ```
13
+
14
+ Then add the plugin to your backend in `packages/backend/src/index.ts`:
15
+
16
+ ```ts
17
+ const backend = createBackend();
18
+ // ...
19
+ backend.add(
20
+ import('@red-hat-developer-hub/backstage-plugin-extensions-backend'),
21
+ );
22
+ ```
23
+
24
+ ### Plugin Configurations
25
+
26
+ Add the following extensions configuration in your `app-config.yaml` file:
27
+
28
+ ```yaml
29
+ extensions:
30
+ ### Example for how to enable installation to a file.
31
+ installation:
32
+ enabled: true
33
+ saveToSingleFile:
34
+ file: <path-to>/dynamic-plugins.yaml
35
+ ```
36
+
37
+ ## Development
38
+
39
+ This plugin backend can be started in a standalone mode from directly in this
40
+ package with `yarn start`. It is a limited setup that is most convenient when
41
+ developing the plugin backend itself.
42
+
43
+ If you want to run the entire project, including the frontend, run `yarn start` from the root directory.
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ var errors = require('@backstage/errors');
4
+
5
+ class ConfigFormatError extends errors.CustomErrorBase {
6
+ name = "ConfigFormatError";
7
+ }
8
+
9
+ exports.ConfigFormatError = ConfigFormatError;
10
+ //# sourceMappingURL=ConfigFormatError.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigFormatError.cjs.js","sources":["../../src/errors/ConfigFormatError.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { CustomErrorBase } from '@backstage/errors';\n\nexport class ConfigFormatError extends CustomErrorBase {\n name = 'ConfigFormatError' as const;\n}\n"],"names":["CustomErrorBase"],"mappings":";;;;AAiBO,MAAM,0BAA0BA,sBAAgB,CAAA;AAAA,EACrD,IAAO,GAAA,mBAAA;AACT;;;;"}
@@ -0,0 +1,30 @@
1
+ 'use strict';
2
+
3
+ var errors = require('@backstage/errors');
4
+
5
+ const InstallationInitErrorReason = {
6
+ INSTALLATION_DISABLED_IN_PRODUCTION: "INSTALLATION_DISABLED_IN_PRODUCTION",
7
+ INSTALLATION_DISABLED: "INSTALLATION_DISABLED",
8
+ FILE_CONFIG_VALUE_MISSING: "FILE_CONFIG_VALUE_MISSING",
9
+ FILE_NOT_EXISTS: "FILE_NOT_EXISTS",
10
+ INVALID_CONFIG: "INVALID_CONFIG",
11
+ UNKNOWN: "UNKNOWN"
12
+ };
13
+ class InstallationInitError extends errors.CustomErrorBase {
14
+ constructor(reason, message, cause) {
15
+ super(message, cause);
16
+ this.reason = reason;
17
+ this.cause = cause;
18
+ if (this.reason === InstallationInitErrorReason.INSTALLATION_DISABLED_IN_PRODUCTION || this.reason === InstallationInitErrorReason.INSTALLATION_DISABLED) {
19
+ this.statusCode = 503;
20
+ } else {
21
+ this.statusCode = 500;
22
+ }
23
+ }
24
+ name = "InstallationInitError";
25
+ statusCode;
26
+ }
27
+
28
+ exports.InstallationInitError = InstallationInitError;
29
+ exports.InstallationInitErrorReason = InstallationInitErrorReason;
30
+ //# sourceMappingURL=InstallationInitError.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InstallationInitError.cjs.js","sources":["../../src/errors/InstallationInitError.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { CustomErrorBase } from '@backstage/errors';\n\nexport const InstallationInitErrorReason = {\n INSTALLATION_DISABLED_IN_PRODUCTION: 'INSTALLATION_DISABLED_IN_PRODUCTION',\n INSTALLATION_DISABLED: 'INSTALLATION_DISABLED',\n FILE_CONFIG_VALUE_MISSING: 'FILE_CONFIG_VALUE_MISSING',\n FILE_NOT_EXISTS: 'FILE_NOT_EXISTS',\n INVALID_CONFIG: 'INVALID_CONFIG',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\nexport type InstallationInitErrorReasonKeys =\n (typeof InstallationInitErrorReason)[keyof typeof InstallationInitErrorReason];\n\nexport class InstallationInitError extends CustomErrorBase {\n name = 'InstallationInitError' as const;\n readonly statusCode: number;\n\n constructor(\n public reason: InstallationInitErrorReasonKeys,\n message: string,\n public cause?: Error,\n ) {\n super(message, cause);\n if (\n this.reason ===\n InstallationInitErrorReason.INSTALLATION_DISABLED_IN_PRODUCTION ||\n this.reason === InstallationInitErrorReason.INSTALLATION_DISABLED\n ) {\n this.statusCode = 503;\n } else {\n this.statusCode = 500;\n }\n }\n}\n"],"names":["CustomErrorBase"],"mappings":";;;;AAiBO,MAAM,2BAA8B,GAAA;AAAA,EACzC,mCAAqC,EAAA,qCAAA;AAAA,EACrC,qBAAuB,EAAA,uBAAA;AAAA,EACvB,yBAA2B,EAAA,2BAAA;AAAA,EAC3B,eAAiB,EAAA,iBAAA;AAAA,EACjB,cAAgB,EAAA,gBAAA;AAAA,EAChB,OAAS,EAAA;AACX;AAKO,MAAM,8BAA8BA,sBAAgB,CAAA;AAAA,EAIzD,WAAA,CACS,MACP,EAAA,OAAA,EACO,KACP,EAAA;AACA,IAAA,KAAA,CAAM,SAAS,KAAK,CAAA;AAJb,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAEA,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AAGP,IAAA,IACE,KAAK,MACH,KAAA,2BAAA,CAA4B,uCAC9B,IAAK,CAAA,MAAA,KAAW,4BAA4B,qBAC5C,EAAA;AACA,MAAA,IAAA,CAAK,UAAa,GAAA,GAAA;AAAA,KACb,MAAA;AACL,MAAA,IAAA,CAAK,UAAa,GAAA,GAAA;AAAA;AACpB;AACF,EAlBA,IAAO,GAAA,uBAAA;AAAA,EACE,UAAA;AAkBX;;;;;"}
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var plugin = require('./plugin.cjs.js');
6
+
7
+
8
+
9
+ exports.default = plugin.extensionsPlugin;
10
+ exports.extensionsPlugin = plugin.extensionsPlugin;
11
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
@@ -0,0 +1,10 @@
1
+ import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
2
+
3
+ /**
4
+ * Extensions backend plugin
5
+ *
6
+ * @public
7
+ */
8
+ declare const extensionsPlugin: _backstage_backend_plugin_api.BackendFeature;
9
+
10
+ export { extensionsPlugin as default, extensionsPlugin };
@@ -0,0 +1,120 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs');
4
+ var yaml = require('yaml');
5
+ var configValidation = require('../validation/configValidation.cjs.js');
6
+ var InstallationInitError = require('../errors/InstallationInitError.cjs.js');
7
+
8
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
9
+
10
+ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
11
+
12
+ class FileInstallationStorage {
13
+ configFile;
14
+ config;
15
+ constructor(configFile) {
16
+ this.configFile = configFile;
17
+ this.config = new yaml.Document();
18
+ }
19
+ get packages() {
20
+ return this.config.get("plugins");
21
+ }
22
+ toStringYaml(mapNodes) {
23
+ const tempDoc = new yaml.Document(mapNodes);
24
+ return tempDoc.toString({ lineWidth: 0 });
25
+ }
26
+ getPackageYamlMap(packageName) {
27
+ return this.packages.items.find(
28
+ (p) => yaml.isMap(p) && p.get("package") === packageName
29
+ );
30
+ }
31
+ save() {
32
+ fs__default.default.writeFileSync(this.configFile, this.config.toString({ lineWidth: 0 }));
33
+ }
34
+ initialize() {
35
+ if (!fs__default.default.existsSync(this.configFile)) {
36
+ throw new InstallationInitError.InstallationInitError(
37
+ InstallationInitError.InstallationInitErrorReason.FILE_NOT_EXISTS,
38
+ `The file ${this.configFile} is missing`
39
+ );
40
+ }
41
+ const rawContent = fs__default.default.readFileSync(this.configFile, "utf-8");
42
+ const parsedContent = yaml.parseDocument(rawContent);
43
+ configValidation.validateConfigurationFormat(parsedContent);
44
+ this.config = parsedContent;
45
+ }
46
+ getConfigYaml() {
47
+ return this.config.toString({ lineWidth: 0 });
48
+ }
49
+ getPackage(packageName) {
50
+ const res = this.getPackageYamlMap(packageName);
51
+ return res ? this.toStringYaml([res]) : res;
52
+ }
53
+ getPackages(packageNames) {
54
+ const res = [];
55
+ for (const packageName of packageNames) {
56
+ const packageMap = this.getPackageYamlMap(packageName);
57
+ if (packageMap) {
58
+ res.push(packageMap);
59
+ }
60
+ }
61
+ return res.length === 0 ? undefined : this.toStringYaml(res);
62
+ }
63
+ updatePackage(packageName, newConfig) {
64
+ const newNode = yaml.parseDocument(newConfig).contents;
65
+ configValidation.validatePackageFormat(newNode, packageName);
66
+ const existingPackage = this.packages.items.find(
67
+ (item) => item.get("package") === packageName
68
+ );
69
+ if (existingPackage) {
70
+ existingPackage.items = newNode.items;
71
+ } else {
72
+ this.packages.items.push(newNode);
73
+ }
74
+ this.save();
75
+ }
76
+ updatePackages(packageNames, newConfig) {
77
+ const newNodes = yaml.parseDocument(newConfig);
78
+ configValidation.validatePluginFormat(newNodes, packageNames);
79
+ const updatedPackages = new yaml.YAMLSeq();
80
+ for (const item of this.packages.items) {
81
+ const name = item.get("package");
82
+ if (!packageNames.has(name)) {
83
+ updatedPackages.items.push(item);
84
+ }
85
+ }
86
+ updatedPackages.items.push(...newNodes.contents.items);
87
+ this.config.set("plugins", updatedPackages);
88
+ this.save();
89
+ }
90
+ setPackageDisabled(packageName, disabled) {
91
+ let pkg = this.getPackageYamlMap(packageName);
92
+ if (!pkg) {
93
+ pkg = new yaml.YAMLMap();
94
+ pkg.set("package", packageName);
95
+ this.packages.add(pkg);
96
+ }
97
+ pkg.set("disabled", disabled);
98
+ this.save();
99
+ }
100
+ setPackagesDisabled(packageNames, disabled) {
101
+ const packages = this.config.get("plugins");
102
+ const packageMap = packages.items.reduce(
103
+ (map, item) => map.set(item.get("package"), item),
104
+ /* @__PURE__ */ new Map()
105
+ );
106
+ for (const packageName of packageNames) {
107
+ let item = packageMap.get(packageName);
108
+ if (!item) {
109
+ item = new yaml.YAMLMap();
110
+ item.set("package", packageName);
111
+ packages.add(item);
112
+ }
113
+ item.set("disabled", disabled);
114
+ }
115
+ this.save();
116
+ }
117
+ }
118
+
119
+ exports.FileInstallationStorage = FileInstallationStorage;
120
+ //# sourceMappingURL=FileInstallationStorage.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileInstallationStorage.cjs.js","sources":["../../src/installation/FileInstallationStorage.ts"],"sourcesContent":["/*\n * Copyright The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport fs from 'fs';\n\nimport { Document, isMap, parseDocument, YAMLMap, YAMLSeq } from 'yaml';\nimport {\n validateConfigurationFormat,\n validatePackageFormat,\n validatePluginFormat,\n} from '../validation/configValidation';\nimport {\n InstallationInitError,\n InstallationInitErrorReason,\n} from '../errors/InstallationInitError';\nimport type { JsonValue } from '@backstage/types';\n\nexport interface InstallationStorage {\n initialize?(): void;\n getPackage(packageName: string): string | undefined;\n updatePackage(packageName: string, newConfig: string): void;\n getPackages(packageNames: Set<string>): string | undefined;\n updatePackages(packageNames: Set<string>, newConfig: string): void;\n setPackageDisabled(packageName: string, disabled: boolean): void;\n setPackagesDisabled(packageNames: Set<string>, disabled: boolean): void;\n}\n\nexport class FileInstallationStorage implements InstallationStorage {\n private readonly configFile: string;\n private config: Document;\n\n constructor(configFile: string) {\n this.configFile = configFile;\n this.config = new Document();\n }\n\n private get packages(): YAMLSeq<YAMLMap<string, JsonValue>> {\n return this.config.get('plugins') as YAMLSeq<YAMLMap<string, JsonValue>>;\n }\n\n private toStringYaml(mapNodes: YAMLMap<string, JsonValue>[]): string {\n const tempDoc = new Document(mapNodes);\n return tempDoc.toString({ lineWidth: 0 });\n }\n\n private getPackageYamlMap(\n packageName: string,\n ): YAMLMap<string, JsonValue> | undefined {\n return this.packages.items.find(\n p => isMap(p) && p.get('package') === packageName,\n );\n }\n\n private save() {\n fs.writeFileSync(this.configFile, this.config.toString({ lineWidth: 0 }));\n }\n\n initialize(): void {\n if (!fs.existsSync(this.configFile)) {\n throw new InstallationInitError(\n InstallationInitErrorReason.FILE_NOT_EXISTS,\n `The file ${this.configFile} is missing`,\n );\n }\n const rawContent = fs.readFileSync(this.configFile, 'utf-8');\n const parsedContent = parseDocument(rawContent);\n validateConfigurationFormat(parsedContent);\n this.config = parsedContent;\n }\n\n getConfigYaml(): string {\n return this.config.toString({ lineWidth: 0 });\n }\n\n getPackage(packageName: string): string | undefined {\n const res = this.getPackageYamlMap(packageName);\n return res ? this.toStringYaml([res]) : res;\n }\n\n getPackages(packageNames: Set<string>): string | undefined {\n const res = [];\n for (const packageName of packageNames) {\n const packageMap = this.getPackageYamlMap(packageName);\n if (packageMap) {\n res.push(packageMap);\n }\n }\n return res.length === 0 ? undefined : this.toStringYaml(res);\n }\n\n updatePackage(packageName: string, newConfig: string): void {\n const newNode = parseDocument(newConfig).contents;\n validatePackageFormat(newNode, packageName);\n\n const existingPackage = this.packages.items.find(\n item => item.get('package') === packageName,\n );\n if (existingPackage) {\n existingPackage.items = newNode.items;\n } else {\n this.packages.items.push(newNode);\n }\n this.save();\n }\n\n updatePackages(packageNames: Set<string>, newConfig: string): void {\n const newNodes = parseDocument(newConfig);\n validatePluginFormat(newNodes, packageNames);\n\n const updatedPackages = new YAMLSeq<YAMLMap<string, JsonValue>>();\n for (const item of this.packages.items) {\n const name = item.get('package') as string;\n if (!packageNames.has(name)) {\n updatedPackages.items.push(item); // keep unchanged package of different plugin\n }\n }\n updatedPackages.items.push(...newNodes.contents.items);\n\n this.config.set('plugins', updatedPackages);\n this.save();\n }\n\n setPackageDisabled(packageName: string, disabled: boolean) {\n let pkg = this.getPackageYamlMap(packageName);\n if (!pkg) {\n pkg = new YAMLMap<string, JsonValue>();\n pkg.set('package', packageName);\n this.packages.add(pkg);\n }\n pkg.set('disabled', disabled);\n this.save();\n }\n\n setPackagesDisabled(packageNames: Set<string>, disabled: boolean) {\n const packages = this.config.get('plugins') as YAMLSeq<\n YAMLMap<string, JsonValue>\n >;\n const packageMap = packages.items.reduce(\n (map, item) => map.set(item.get('package') as string, item),\n new Map<string, YAMLMap<string, JsonValue>>(),\n );\n for (const packageName of packageNames) {\n let item = packageMap.get(packageName);\n if (!item) {\n item = new YAMLMap<string, JsonValue>();\n item.set('package', packageName);\n packages.add(item);\n }\n item.set('disabled', disabled);\n }\n\n this.save();\n }\n}\n"],"names":["Document","isMap","fs","InstallationInitError","InstallationInitErrorReason","parseDocument","validateConfigurationFormat","validatePackageFormat","validatePluginFormat","YAMLSeq","YAMLMap"],"mappings":"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"}