@red-hat-developer-hub/backstage-plugin-extensions-backend 0.18.1 → 0.19.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 CHANGED
@@ -1,5 +1,18 @@
1
1
  # @red-hat-developer-hub/backstage-plugin-extensions-backend
2
2
 
3
+ ## 0.19.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 2636ed4: Replaced `disabled` field with `enabled` in plugin configuration
8
+ - 90a1446: Backstage version bump to v1.52.1
9
+
10
+ ### Patch Changes
11
+
12
+ - Updated dependencies [2636ed4]
13
+ - Updated dependencies [90a1446]
14
+ - @red-hat-developer-hub/backstage-plugin-extensions-common@0.19.0
15
+
3
16
  ## 0.18.1
4
17
 
5
18
  ### Patch Changes
@@ -87,17 +87,18 @@ class FileInstallationStorage {
87
87
  this.config.set("plugins", updatedPackages);
88
88
  this.save();
89
89
  }
90
- setPackageDisabled(packageName, disabled) {
90
+ setPackageEnabled(packageName, enabled) {
91
91
  let pkg = this.getPackageYamlMap(packageName);
92
92
  if (!pkg) {
93
93
  pkg = new yaml.YAMLMap();
94
94
  pkg.set("package", packageName);
95
95
  this.packages.add(pkg);
96
96
  }
97
- pkg.set("disabled", disabled);
97
+ pkg.set("enabled", enabled);
98
+ pkg.delete("disabled");
98
99
  this.save();
99
100
  }
100
- setPackagesDisabled(packageNames, disabled) {
101
+ setPackagesEnabled(packageNames, enabled) {
101
102
  const packages = this.config.get("plugins");
102
103
  const packageMap = packages.items.reduce(
103
104
  (map, item) => map.set(item.get("package"), item),
@@ -110,7 +111,8 @@ class FileInstallationStorage {
110
111
  item.set("package", packageName);
111
112
  packages.add(item);
112
113
  }
113
- item.set("disabled", disabled);
114
+ item.set("enabled", enabled);
115
+ item.delete("disabled");
114
116
  }
115
117
  this.save();
116
118
  }
@@ -1 +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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"}
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 setPackageEnabled(packageName: string, enabled: boolean): void;\n setPackagesEnabled(packageNames: Set<string>, enabled: 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 setPackageEnabled(packageName: string, enabled: 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('enabled', enabled);\n pkg.delete('disabled');\n this.save();\n }\n\n setPackagesEnabled(packageNames: Set<string>, enabled: 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('enabled', enabled);\n item.delete('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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"}
@@ -111,15 +111,12 @@ class InstallationDataService {
111
111
  const dynamicArtifacts = await this.getPluginDynamicArtifacts(plugin);
112
112
  this.installationStorage.updatePackages(dynamicArtifacts, newConfig);
113
113
  }
114
- setPackageDisabled(packageDynamicArtifact, disabled) {
115
- this.installationStorage.setPackageDisabled(
116
- packageDynamicArtifact,
117
- disabled
118
- );
114
+ setPackageEnabled(packageDynamicArtifact, enabled) {
115
+ this.installationStorage.setPackageEnabled(packageDynamicArtifact, enabled);
119
116
  }
120
- async setPluginDisabled(plugin, disabled) {
117
+ async setPluginEnabled(plugin, enabled) {
121
118
  const dynamicArtifacts = await this.getPluginDynamicArtifacts(plugin);
122
- this.installationStorage.setPackagesDisabled(dynamicArtifacts, disabled);
119
+ this.installationStorage.setPackagesEnabled(dynamicArtifacts, enabled);
123
120
  }
124
121
  }
125
122
 
@@ -1 +1 @@
1
- {"version":3,"file":"InstallationDataService.cjs.js","sources":["../../src/installation/InstallationDataService.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 {\n ExtensionsApi,\n ExtensionsPlugin,\n} from '@red-hat-developer-hub/backstage-plugin-extensions-common';\nimport { DEFAULT_NAMESPACE } from '@backstage/catalog-model';\nimport {\n FileInstallationStorage,\n InstallationStorage,\n} from './FileInstallationStorage';\nimport type { Config } from '@backstage/config';\nimport {\n InstallationInitError,\n InstallationInitErrorReason,\n InstallationInitErrorReasonKeys,\n} from '../errors/InstallationInitError';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { ConfigFormatError } from '../errors/ConfigFormatError';\n\nexport class InstallationDataService {\n private constructor(\n private readonly extensionsApi: ExtensionsApi,\n private readonly _installationStorage?: InstallationStorage,\n private readonly initializationError?: InstallationInitError,\n ) {}\n\n private get installationStorage(): InstallationStorage {\n if (!this._installationStorage) {\n throw new Error('Installation storage is not initialized', {\n cause: this.initializationError,\n });\n }\n return this._installationStorage;\n }\n\n static fromConfig(deps: {\n config: Config;\n extensionsApi: ExtensionsApi;\n logger: LoggerService;\n }): InstallationDataService {\n const { config, extensionsApi, logger } = deps;\n\n const serviceWithInitializationError = (\n reason: InstallationInitErrorReasonKeys,\n message: string,\n cause?: Error,\n ): InstallationDataService => {\n if (\n reason ===\n InstallationInitErrorReason.INSTALLATION_DISABLED_IN_PRODUCTION ||\n reason === InstallationInitErrorReason.INSTALLATION_DISABLED\n ) {\n logger.warn(message);\n } else {\n logger.error(\n `Installation feature is disabled. Error while loading data: ${message}`,\n );\n }\n return new InstallationDataService(\n extensionsApi,\n undefined,\n new InstallationInitError(reason, message, cause),\n );\n };\n\n try {\n const node_env = process.env.NODE_ENV ?? 'development';\n if (node_env === 'production') {\n return serviceWithInitializationError(\n InstallationInitErrorReason.INSTALLATION_DISABLED_IN_PRODUCTION,\n 'Installation feature is disabled in production',\n );\n }\n\n const installationEnabled = config.getOptionalBoolean(\n 'extensions.installation.enabled',\n );\n if (!installationEnabled) {\n return serviceWithInitializationError(\n InstallationInitErrorReason.INSTALLATION_DISABLED,\n \"Installation feature is disabled under 'extensions.installation.enabled'\",\n );\n }\n\n const filePath = config.getOptionalString(\n 'extensions.installation.saveToSingleFile.file',\n );\n if (!filePath) {\n return serviceWithInitializationError(\n InstallationInitErrorReason.FILE_CONFIG_VALUE_MISSING,\n \"The 'extensions.installation.saveToSingleFile.file' config value is not being specified in the extensions configuration\",\n );\n }\n\n const storage = new FileInstallationStorage(filePath);\n storage.initialize();\n return new InstallationDataService(extensionsApi, storage);\n } catch (e) {\n let reason: InstallationInitErrorReasonKeys;\n if (e instanceof InstallationInitError) {\n reason = e.reason;\n } else if (e instanceof ConfigFormatError) {\n reason = InstallationInitErrorReason.INVALID_CONFIG;\n } else {\n reason = InstallationInitErrorReason.UNKNOWN;\n }\n return serviceWithInitializationError(\n reason,\n e.message,\n reason === InstallationInitErrorReason.UNKNOWN ? e : undefined,\n );\n }\n }\n\n private async getPluginDynamicArtifacts(\n plugin: ExtensionsPlugin,\n ): Promise<Set<string>> {\n const extensionsPackages = await this.extensionsApi.getPluginPackages(\n plugin.metadata.namespace ?? DEFAULT_NAMESPACE,\n plugin.metadata.name,\n );\n\n return new Set(\n extensionsPackages.flatMap(p =>\n p.spec?.dynamicArtifact ? [p.spec.dynamicArtifact] : [],\n ),\n );\n }\n\n getInitializationError(): InstallationInitError | undefined {\n return this.initializationError;\n }\n\n getPackageConfig(packageDynamicArtifact: string): string | undefined {\n return this.installationStorage.getPackage(packageDynamicArtifact);\n }\n\n async getPluginConfig(plugin: ExtensionsPlugin): Promise<string | undefined> {\n const dynamicArtifacts = await this.getPluginDynamicArtifacts(plugin);\n return this.installationStorage.getPackages(dynamicArtifacts);\n }\n\n updatePackageConfig(packageDynamicArtifact: string, newConfig: string): void {\n this.installationStorage.updatePackage(packageDynamicArtifact, newConfig);\n }\n\n async updatePluginConfig(\n plugin: ExtensionsPlugin,\n newConfig: string,\n ): Promise<void> {\n const dynamicArtifacts = await this.getPluginDynamicArtifacts(plugin);\n this.installationStorage.updatePackages(dynamicArtifacts, newConfig);\n }\n\n setPackageDisabled(packageDynamicArtifact: string, disabled: boolean) {\n this.installationStorage.setPackageDisabled(\n packageDynamicArtifact,\n disabled,\n );\n }\n\n async setPluginDisabled(plugin: ExtensionsPlugin, disabled: boolean) {\n const dynamicArtifacts = await this.getPluginDynamicArtifacts(plugin);\n this.installationStorage.setPackagesDisabled(dynamicArtifacts, disabled);\n }\n}\n"],"names":["InstallationInitErrorReason","InstallationInitError","FileInstallationStorage","ConfigFormatError","DEFAULT_NAMESPACE"],"mappings":"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"}
1
+ {"version":3,"file":"InstallationDataService.cjs.js","sources":["../../src/installation/InstallationDataService.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 {\n ExtensionsApi,\n ExtensionsPlugin,\n} from '@red-hat-developer-hub/backstage-plugin-extensions-common';\nimport { DEFAULT_NAMESPACE } from '@backstage/catalog-model';\nimport {\n FileInstallationStorage,\n InstallationStorage,\n} from './FileInstallationStorage';\nimport type { Config } from '@backstage/config';\nimport {\n InstallationInitError,\n InstallationInitErrorReason,\n InstallationInitErrorReasonKeys,\n} from '../errors/InstallationInitError';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { ConfigFormatError } from '../errors/ConfigFormatError';\n\nexport class InstallationDataService {\n private constructor(\n private readonly extensionsApi: ExtensionsApi,\n private readonly _installationStorage?: InstallationStorage,\n private readonly initializationError?: InstallationInitError,\n ) {}\n\n private get installationStorage(): InstallationStorage {\n if (!this._installationStorage) {\n throw new Error('Installation storage is not initialized', {\n cause: this.initializationError,\n });\n }\n return this._installationStorage;\n }\n\n static fromConfig(deps: {\n config: Config;\n extensionsApi: ExtensionsApi;\n logger: LoggerService;\n }): InstallationDataService {\n const { config, extensionsApi, logger } = deps;\n\n const serviceWithInitializationError = (\n reason: InstallationInitErrorReasonKeys,\n message: string,\n cause?: Error,\n ): InstallationDataService => {\n if (\n reason ===\n InstallationInitErrorReason.INSTALLATION_DISABLED_IN_PRODUCTION ||\n reason === InstallationInitErrorReason.INSTALLATION_DISABLED\n ) {\n logger.warn(message);\n } else {\n logger.error(\n `Installation feature is disabled. Error while loading data: ${message}`,\n );\n }\n return new InstallationDataService(\n extensionsApi,\n undefined,\n new InstallationInitError(reason, message, cause),\n );\n };\n\n try {\n const node_env = process.env.NODE_ENV ?? 'development';\n if (node_env === 'production') {\n return serviceWithInitializationError(\n InstallationInitErrorReason.INSTALLATION_DISABLED_IN_PRODUCTION,\n 'Installation feature is disabled in production',\n );\n }\n\n const installationEnabled = config.getOptionalBoolean(\n 'extensions.installation.enabled',\n );\n if (!installationEnabled) {\n return serviceWithInitializationError(\n InstallationInitErrorReason.INSTALLATION_DISABLED,\n \"Installation feature is disabled under 'extensions.installation.enabled'\",\n );\n }\n\n const filePath = config.getOptionalString(\n 'extensions.installation.saveToSingleFile.file',\n );\n if (!filePath) {\n return serviceWithInitializationError(\n InstallationInitErrorReason.FILE_CONFIG_VALUE_MISSING,\n \"The 'extensions.installation.saveToSingleFile.file' config value is not being specified in the extensions configuration\",\n );\n }\n\n const storage = new FileInstallationStorage(filePath);\n storage.initialize();\n return new InstallationDataService(extensionsApi, storage);\n } catch (e) {\n let reason: InstallationInitErrorReasonKeys;\n if (e instanceof InstallationInitError) {\n reason = e.reason;\n } else if (e instanceof ConfigFormatError) {\n reason = InstallationInitErrorReason.INVALID_CONFIG;\n } else {\n reason = InstallationInitErrorReason.UNKNOWN;\n }\n return serviceWithInitializationError(\n reason,\n e.message,\n reason === InstallationInitErrorReason.UNKNOWN ? e : undefined,\n );\n }\n }\n\n private async getPluginDynamicArtifacts(\n plugin: ExtensionsPlugin,\n ): Promise<Set<string>> {\n const extensionsPackages = await this.extensionsApi.getPluginPackages(\n plugin.metadata.namespace ?? DEFAULT_NAMESPACE,\n plugin.metadata.name,\n );\n\n return new Set(\n extensionsPackages.flatMap(p =>\n p.spec?.dynamicArtifact ? [p.spec.dynamicArtifact] : [],\n ),\n );\n }\n\n getInitializationError(): InstallationInitError | undefined {\n return this.initializationError;\n }\n\n getPackageConfig(packageDynamicArtifact: string): string | undefined {\n return this.installationStorage.getPackage(packageDynamicArtifact);\n }\n\n async getPluginConfig(plugin: ExtensionsPlugin): Promise<string | undefined> {\n const dynamicArtifacts = await this.getPluginDynamicArtifacts(plugin);\n return this.installationStorage.getPackages(dynamicArtifacts);\n }\n\n updatePackageConfig(packageDynamicArtifact: string, newConfig: string): void {\n this.installationStorage.updatePackage(packageDynamicArtifact, newConfig);\n }\n\n async updatePluginConfig(\n plugin: ExtensionsPlugin,\n newConfig: string,\n ): Promise<void> {\n const dynamicArtifacts = await this.getPluginDynamicArtifacts(plugin);\n this.installationStorage.updatePackages(dynamicArtifacts, newConfig);\n }\n\n setPackageEnabled(packageDynamicArtifact: string, enabled: boolean) {\n this.installationStorage.setPackageEnabled(packageDynamicArtifact, enabled);\n }\n\n async setPluginEnabled(plugin: ExtensionsPlugin, enabled: boolean) {\n const dynamicArtifacts = await this.getPluginDynamicArtifacts(plugin);\n this.installationStorage.setPackagesEnabled(dynamicArtifacts, enabled);\n }\n}\n"],"names":["InstallationInitErrorReason","InstallationInitError","FileInstallationStorage","ConfigFormatError","DEFAULT_NAMESPACE"],"mappings":"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"}
@@ -18,6 +18,18 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
18
18
  var express__default = /*#__PURE__*/_interopDefaultCompat(express);
19
19
  var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
20
20
 
21
+ function resolveEnabledField(body) {
22
+ if (body.enabled !== void 0) {
23
+ if (typeof body.enabled !== "boolean") {
24
+ throw new errors.InputError("'enabled' must be a boolean");
25
+ }
26
+ return body.enabled;
27
+ }
28
+ if (typeof body.disabled === "boolean") {
29
+ return !body.disabled;
30
+ }
31
+ throw new errors.InputError("'enabled' must be a present boolean");
32
+ }
21
33
  async function createRouter(options) {
22
34
  const {
23
35
  httpAuth,
@@ -213,13 +225,10 @@ async function createRouter(options) {
213
225
  `Package catalog entity ${extensionsPackage.metadata.name} is missing 'spec.dynamicArtifact'`
214
226
  );
215
227
  }
216
- const disabled = req.body.disabled;
217
- if (typeof disabled !== "boolean") {
218
- throw new errors.InputError("'disabled' must be present boolean");
219
- }
220
- installationDataService.setPackageDisabled(
228
+ const enabled = resolveEnabledField(req.body);
229
+ installationDataService.setPackageEnabled(
221
230
  extensionsPackage.spec.dynamicArtifact,
222
- disabled
231
+ enabled
223
232
  );
224
233
  res.status(200).json({ status: "OK" });
225
234
  }
@@ -328,11 +337,8 @@ async function createRouter(options) {
328
337
  req,
329
338
  backstagePluginExtensionsCommon.extensionsPluginWritePermission
330
339
  );
331
- const disabled = req.body.disabled;
332
- if (typeof disabled !== "boolean") {
333
- throw new errors.InputError("'disabled' must be present boolean");
334
- }
335
- await installationDataService.setPluginDisabled(plugin, disabled);
340
+ const enabled = resolveEnabledField(req.body);
341
+ await installationDataService.setPluginEnabled(plugin, enabled);
336
342
  res.status(200).json({ status: "OK" });
337
343
  }
338
344
  );
@@ -1 +1 @@
1
- {"version":3,"file":"router.cjs.js","sources":["../src/router.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 express, { Request, Response, NextFunction } from 'express';\nimport Router from 'express-promise-router';\nimport { InputError, NotAllowedError } from '@backstage/errors';\nimport type { Config } from '@backstage/config';\n\nimport {\n HttpAuthService,\n PermissionsService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport {\n AuthorizeResult,\n BasicPermission,\n PolicyDecision,\n ResourcePermission,\n} from '@backstage/plugin-permission-common';\n\nimport {\n decodeGetEntitiesRequest,\n decodeGetEntityFacetsRequest,\n extensionsPluginWritePermission,\n extensionsPluginReadPermission,\n ExtensionsApi,\n ExtensionsPlugin,\n RESOURCE_TYPE_EXTENSIONS_PLUGIN,\n extensionsPermissions,\n} from '@red-hat-developer-hub/backstage-plugin-extensions-common';\nimport { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';\nimport { createSearchParams } from './utils/createSearchParams';\nimport { removeVerboseSpecContent } from './utils/removeVerboseSpecContent';\nimport { rules as extensionRules } from './permissions/rules';\nimport { matches } from './utils/permissionUtils';\nimport { InstallationDataService } from './installation/InstallationDataService';\nimport { ConfigFormatError } from './errors/ConfigFormatError';\n\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport {\n BaseDynamicPlugin,\n DynamicPluginProvider,\n} from '@backstage/backend-dynamic-feature-service';\n\nexport type ExtensionsRouterOptions = {\n httpAuth: HttpAuthService;\n extensionsApi: ExtensionsApi;\n permissions: PermissionsService;\n installationDataService: InstallationDataService;\n pluginProvider: DynamicPluginProvider;\n logger: LoggerService;\n config: Config;\n};\n\nexport async function createRouter(\n options: ExtensionsRouterOptions,\n): Promise<express.Router> {\n const {\n httpAuth,\n extensionsApi,\n permissions,\n installationDataService,\n pluginProvider,\n logger,\n config,\n } = options;\n\n const requireInitializedInstallationDataService = (\n _req: Request,\n _res: Response,\n next: NextFunction,\n ) => {\n const error = installationDataService.getInitializationError();\n if (error) {\n throw error;\n }\n next();\n };\n\n const router = Router();\n const permissionsIntegrationRouter = createPermissionIntegrationRouter({\n resourceType: RESOURCE_TYPE_EXTENSIONS_PLUGIN,\n permissions: extensionsPermissions,\n rules: Object.values(extensionRules) as any,\n });\n router.use(express.json());\n router.use(permissionsIntegrationRouter);\n\n const authorizeConditional = async (\n request: Request,\n permission: ResourcePermission<'extensions-plugin'> | BasicPermission,\n ) => {\n const credentials = await httpAuth.credentials(request);\n let decision: PolicyDecision;\n // No permission configured, always allow.\n if (!permission) {\n return { result: AuthorizeResult.ALLOW };\n }\n\n if (permission.type === 'resource') {\n decision = (\n await permissions.authorizeConditional([{ permission }], {\n credentials,\n })\n )[0];\n } else {\n decision = (\n await permissions.authorize([{ permission }], {\n credentials,\n })\n )[0];\n }\n\n return decision;\n };\n\n const getAuthorizedPlugin = async (\n request: Request,\n permission: ResourcePermission<'extensions-plugin'> | BasicPermission,\n ) => {\n const decision = await authorizeConditional(request, permission);\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(\n `Not allowed to ${permission.attributes.action} the configuration of ${request.params.namespace}:${request.params.name}`,\n );\n }\n\n const plugin = await extensionsApi.getPluginByName(\n request.params.namespace,\n request.params.name,\n );\n\n const hasAccess =\n decision.result === AuthorizeResult.ALLOW ||\n (decision.result === AuthorizeResult.CONDITIONAL &&\n matches(plugin, decision.conditions));\n if (!hasAccess) {\n throw new NotAllowedError(\n `Not allowed to ${permission.attributes.action} the configuration of ${request.params.namespace}:${request.params.name}`,\n );\n }\n\n return plugin;\n };\n\n const getAuthorizedPackage = async (\n request: Request,\n permission: ResourcePermission<'extensions-plugin'> | BasicPermission,\n ) => {\n const decision = await authorizeConditional(request, permission);\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(\n `Not allowed to ${permission.attributes.action} the configuration of ${request.params.namespace}:${request.params.name}`,\n );\n }\n\n const packagePlugins = await extensionsApi.getPackagePlugins(\n request.params.namespace,\n request.params.name,\n );\n const hasAccess =\n decision.result === AuthorizeResult.ALLOW ||\n (decision.result === AuthorizeResult.CONDITIONAL &&\n packagePlugins.some(plugin => matches(plugin, decision.conditions)));\n if (!hasAccess) {\n throw new NotAllowedError(\n `Not allowed to ${permission.attributes.action} the configuration of ${request.params.namespace}:${request.params.name}`,\n );\n }\n\n return await extensionsApi.getPackageByName(\n request.params.namespace,\n request.params.name,\n );\n };\n\n router.get('/collections', async (req, res) => {\n const request = decodeGetEntitiesRequest(createSearchParams(req));\n const collections = await extensionsApi.getCollections(request);\n res.json(collections);\n });\n\n router.get('/collections/facets', async (req, res) => {\n const request = decodeGetEntityFacetsRequest(createSearchParams(req));\n const facets = await extensionsApi.getCollectionsFacets(request);\n res.json(facets);\n });\n\n router.get('/collection/:namespace/:name', async (req, res) => {\n const collection = await extensionsApi.getCollectionByName(\n req.params.namespace,\n req.params.name,\n );\n res.json(collection);\n });\n\n router.get('/collection/:namespace/:name/plugins', async (req, res) => {\n const plugins = await extensionsApi.getCollectionPlugins(\n req.params.namespace,\n req.params.name,\n );\n removeVerboseSpecContent(plugins);\n res.json(plugins);\n });\n\n router.get('/packages', async (req, res) => {\n const request = decodeGetEntitiesRequest(createSearchParams(req));\n const packages = await extensionsApi.getPackages(request);\n removeVerboseSpecContent(packages.items);\n res.json(packages);\n });\n\n router.get('/packages/facets', async (req, res) => {\n const request = decodeGetEntityFacetsRequest(createSearchParams(req));\n const facets = await extensionsApi.getPackagesFacets(request);\n res.json(facets);\n });\n\n router.get('/package/:namespace/:name', async (req, res) => {\n res.json(\n await extensionsApi.getPackageByName(\n req.params.namespace,\n req.params.name,\n ),\n );\n });\n\n router.get(\n '/package/:namespace/:name/configuration',\n requireInitializedInstallationDataService,\n async (req, res) => {\n const extensionsPackage = await getAuthorizedPackage(\n req,\n extensionsPluginReadPermission,\n );\n\n if (!extensionsPackage.spec?.dynamicArtifact) {\n throw new Error(\n `Package catalog entity ${extensionsPackage.metadata.name} is missing 'spec.dynamicArtifact'`,\n );\n }\n const result = installationDataService.getPackageConfig(\n extensionsPackage.spec?.dynamicArtifact,\n );\n res.status(200).json({ configYaml: result });\n },\n );\n\n router.post(\n '/package/:namespace/:name/configuration',\n requireInitializedInstallationDataService,\n async (req, res) => {\n const extensionsPackage = await getAuthorizedPackage(\n req,\n extensionsPluginWritePermission,\n );\n if (!extensionsPackage.spec?.dynamicArtifact) {\n throw new Error(\n `Package ${extensionsPackage.metadata.name} is missing 'spec.dynamicArtifact'`,\n );\n }\n\n const newConfig = req.body.configYaml;\n if (!newConfig) {\n throw new InputError(\"'configYaml' object must be present\");\n }\n try {\n installationDataService.updatePackageConfig(\n extensionsPackage.spec.dynamicArtifact,\n newConfig,\n );\n } catch (e) {\n if (e instanceof ConfigFormatError) {\n throw new InputError(e.message);\n }\n throw e;\n }\n res.status(200).json({ status: 'OK' });\n },\n );\n\n router.get('/environment', async (_req, res) => {\n res.status(200).json({\n nodeEnv: process.env.NODE_ENV || 'development',\n });\n });\n\n router.patch(\n '/package/:namespace/:name/configuration/disable',\n requireInitializedInstallationDataService,\n async (req, res) => {\n const extensionsPackage = await getAuthorizedPackage(\n req,\n extensionsPluginWritePermission,\n );\n\n if (!extensionsPackage.spec?.dynamicArtifact) {\n throw new Error(\n `Package catalog entity ${extensionsPackage.metadata.name} is missing 'spec.dynamicArtifact'`,\n );\n }\n\n const disabled = req.body.disabled;\n if (typeof disabled !== 'boolean') {\n throw new InputError(\"'disabled' must be present boolean\");\n }\n installationDataService.setPackageDisabled(\n extensionsPackage.spec.dynamicArtifact,\n disabled,\n );\n res.status(200).json({ status: 'OK' });\n },\n );\n\n router.get('/plugins', async (req, res) => {\n const request = decodeGetEntitiesRequest(createSearchParams(req));\n const plugins = await extensionsApi.getPlugins(request);\n removeVerboseSpecContent(plugins.items);\n res.json(plugins);\n });\n\n router.get('/plugins/facets', async (req, res) => {\n const request = decodeGetEntityFacetsRequest(createSearchParams(req));\n const facets = await extensionsApi.getPluginFacets(request);\n res.json(facets);\n });\n\n router.get('/plugins/configure', async (_req, res) => {\n const isPluginInstallationEnabled =\n config.getOptionalBoolean('extensions.installation.enabled') ?? false;\n res.json({ enabled: isPluginInstallationEnabled });\n });\n\n router.get('/plugin/:namespace/:name', async (req, res) => {\n const plugin = await extensionsApi.getPluginByName(\n req.params.namespace,\n req.params.name,\n );\n res.json(plugin);\n });\n\n router.get(\n '/plugin/:namespace/:name/configuration/authorize',\n async (req, res) => {\n const [readDecision, installDecision] = await Promise.all([\n authorizeConditional(req, extensionsPluginReadPermission),\n authorizeConditional(req, extensionsPluginWritePermission),\n ]);\n if (\n readDecision.result === AuthorizeResult.DENY &&\n installDecision.result === AuthorizeResult.DENY\n ) {\n res.status(200).json({ read: 'DENY', write: 'DENY' });\n return;\n }\n\n let authorizedActions = {};\n let plugin: ExtensionsPlugin;\n\n const evaluateConditional = async (\n decision: PolicyDecision,\n action: string,\n ) => {\n if (decision.result === AuthorizeResult.CONDITIONAL) {\n if (!plugin) {\n plugin = await extensionsApi.getPluginByName(\n req.params.namespace,\n req.params.name,\n );\n }\n if (matches(plugin, decision.conditions)) {\n authorizedActions = { ...authorizedActions, [action]: 'ALLOW' };\n }\n } else if (decision.result === AuthorizeResult.ALLOW) {\n authorizedActions = { ...authorizedActions, [action]: 'ALLOW' };\n }\n };\n\n await Promise.all([\n evaluateConditional(readDecision, 'read'),\n evaluateConditional(installDecision, 'write'),\n ]);\n\n if (Object.keys(authorizedActions).length === 0) {\n res.status(200).json({ read: 'DENY', write: 'DENY' });\n } else {\n res.status(200).json(authorizedActions);\n }\n },\n );\n\n router.get(\n '/plugin/:namespace/:name/configuration',\n requireInitializedInstallationDataService,\n async (req, res) => {\n const plugin = await getAuthorizedPlugin(\n req,\n extensionsPluginReadPermission,\n );\n const result = await installationDataService.getPluginConfig(plugin);\n res.status(200).json({ configYaml: result });\n },\n );\n\n router.post(\n '/plugin/:namespace/:name/configuration',\n requireInitializedInstallationDataService,\n async (req, res) => {\n // installs the plugin\n const plugin = await getAuthorizedPlugin(\n req,\n extensionsPluginWritePermission,\n );\n\n const newConfig = req.body.configYaml;\n if (!newConfig) {\n throw new InputError(\"'configYaml' object must be present\");\n }\n try {\n await installationDataService.updatePluginConfig(plugin, newConfig);\n } catch (e) {\n if (e instanceof ConfigFormatError) {\n throw new InputError(e.message);\n }\n throw e;\n }\n res.status(200).json({ status: 'OK' });\n },\n );\n\n router.patch(\n '/plugin/:namespace/:name/configuration/disable',\n requireInitializedInstallationDataService,\n async (req, res) => {\n const plugin = await getAuthorizedPlugin(\n req,\n extensionsPluginWritePermission,\n );\n const disabled = req.body.disabled;\n if (typeof disabled !== 'boolean') {\n throw new InputError(\"'disabled' must be present boolean\");\n }\n await installationDataService.setPluginDisabled(plugin, disabled);\n res.status(200).json({ status: 'OK' });\n },\n );\n\n router.get('/plugin/:namespace/:name/packages', async (req, res) => {\n const packages = await extensionsApi.getPluginPackages(\n req.params.namespace,\n req.params.name,\n );\n res.json(packages);\n });\n\n const plugins = pluginProvider.plugins();\n const dynamicPlugins = plugins.map(p => {\n // Remove the installer details for the dynamic backend plugins\n if (p.platform === 'node') {\n const { installer, ...rest } = p;\n return rest as BaseDynamicPlugin;\n }\n return p as BaseDynamicPlugin;\n });\n router.get('/loaded-plugins', async (req, response) => {\n await httpAuth.credentials(req, { allow: ['user', 'service'] });\n response.send(dynamicPlugins);\n });\n const middleware = MiddlewareFactory.create({ logger, config });\n\n router.use(middleware.error());\n\n return router;\n}\n"],"names":["Router","createPermissionIntegrationRouter","RESOURCE_TYPE_EXTENSIONS_PLUGIN","extensionsPermissions","extensionRules","express","AuthorizeResult","NotAllowedError","matches","decodeGetEntitiesRequest","createSearchParams","decodeGetEntityFacetsRequest","plugins","removeVerboseSpecContent","extensionsPluginReadPermission","extensionsPluginWritePermission","InputError","ConfigFormatError","MiddlewareFactory"],"mappings":"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"}
1
+ {"version":3,"file":"router.cjs.js","sources":["../src/router.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 express, { Request, Response, NextFunction } from 'express';\nimport Router from 'express-promise-router';\nimport { InputError, NotAllowedError } from '@backstage/errors';\nimport type { Config } from '@backstage/config';\n\nimport {\n HttpAuthService,\n PermissionsService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport {\n AuthorizeResult,\n BasicPermission,\n PolicyDecision,\n ResourcePermission,\n} from '@backstage/plugin-permission-common';\n\nimport {\n decodeGetEntitiesRequest,\n decodeGetEntityFacetsRequest,\n extensionsPluginWritePermission,\n extensionsPluginReadPermission,\n ExtensionsApi,\n ExtensionsPlugin,\n RESOURCE_TYPE_EXTENSIONS_PLUGIN,\n extensionsPermissions,\n} from '@red-hat-developer-hub/backstage-plugin-extensions-common';\nimport { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';\nimport { createSearchParams } from './utils/createSearchParams';\nimport { removeVerboseSpecContent } from './utils/removeVerboseSpecContent';\nimport { rules as extensionRules } from './permissions/rules';\nimport { matches } from './utils/permissionUtils';\nimport { InstallationDataService } from './installation/InstallationDataService';\nimport { ConfigFormatError } from './errors/ConfigFormatError';\n\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport {\n BaseDynamicPlugin,\n DynamicPluginProvider,\n} from '@backstage/backend-dynamic-feature-service';\n\n/**\n * Resolve the effective `enabled` value from a request body that may contain\n * `enabled`, `disabled`, or both. When both are present `enabled` wins.\n * Throws InputError when neither field is a boolean.\n */\nfunction resolveEnabledField(body: Record<string, unknown>): boolean {\n if (body.enabled !== undefined) {\n if (typeof body.enabled !== 'boolean') {\n throw new InputError(\"'enabled' must be a boolean\");\n }\n return body.enabled;\n }\n if (typeof body.disabled === 'boolean') {\n return !body.disabled;\n }\n throw new InputError(\"'enabled' must be a present boolean\");\n}\n\nexport type ExtensionsRouterOptions = {\n httpAuth: HttpAuthService;\n extensionsApi: ExtensionsApi;\n permissions: PermissionsService;\n installationDataService: InstallationDataService;\n pluginProvider: DynamicPluginProvider;\n logger: LoggerService;\n config: Config;\n};\n\nexport async function createRouter(\n options: ExtensionsRouterOptions,\n): Promise<express.Router> {\n const {\n httpAuth,\n extensionsApi,\n permissions,\n installationDataService,\n pluginProvider,\n logger,\n config,\n } = options;\n\n const requireInitializedInstallationDataService = (\n _req: Request,\n _res: Response,\n next: NextFunction,\n ) => {\n const error = installationDataService.getInitializationError();\n if (error) {\n throw error;\n }\n next();\n };\n\n const router = Router();\n const permissionsIntegrationRouter = createPermissionIntegrationRouter({\n resourceType: RESOURCE_TYPE_EXTENSIONS_PLUGIN,\n permissions: extensionsPermissions,\n rules: Object.values(extensionRules) as any,\n });\n router.use(express.json());\n router.use(permissionsIntegrationRouter);\n\n const authorizeConditional = async (\n request: Request,\n permission: ResourcePermission<'extensions-plugin'> | BasicPermission,\n ) => {\n const credentials = await httpAuth.credentials(request);\n let decision: PolicyDecision;\n // No permission configured, always allow.\n if (!permission) {\n return { result: AuthorizeResult.ALLOW };\n }\n\n if (permission.type === 'resource') {\n decision = (\n await permissions.authorizeConditional([{ permission }], {\n credentials,\n })\n )[0];\n } else {\n decision = (\n await permissions.authorize([{ permission }], {\n credentials,\n })\n )[0];\n }\n\n return decision;\n };\n\n const getAuthorizedPlugin = async (\n request: Request,\n permission: ResourcePermission<'extensions-plugin'> | BasicPermission,\n ) => {\n const decision = await authorizeConditional(request, permission);\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(\n `Not allowed to ${permission.attributes.action} the configuration of ${request.params.namespace}:${request.params.name}`,\n );\n }\n\n const plugin = await extensionsApi.getPluginByName(\n request.params.namespace,\n request.params.name,\n );\n\n const hasAccess =\n decision.result === AuthorizeResult.ALLOW ||\n (decision.result === AuthorizeResult.CONDITIONAL &&\n matches(plugin, decision.conditions));\n if (!hasAccess) {\n throw new NotAllowedError(\n `Not allowed to ${permission.attributes.action} the configuration of ${request.params.namespace}:${request.params.name}`,\n );\n }\n\n return plugin;\n };\n\n const getAuthorizedPackage = async (\n request: Request,\n permission: ResourcePermission<'extensions-plugin'> | BasicPermission,\n ) => {\n const decision = await authorizeConditional(request, permission);\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(\n `Not allowed to ${permission.attributes.action} the configuration of ${request.params.namespace}:${request.params.name}`,\n );\n }\n\n const packagePlugins = await extensionsApi.getPackagePlugins(\n request.params.namespace,\n request.params.name,\n );\n const hasAccess =\n decision.result === AuthorizeResult.ALLOW ||\n (decision.result === AuthorizeResult.CONDITIONAL &&\n packagePlugins.some(plugin => matches(plugin, decision.conditions)));\n if (!hasAccess) {\n throw new NotAllowedError(\n `Not allowed to ${permission.attributes.action} the configuration of ${request.params.namespace}:${request.params.name}`,\n );\n }\n\n return await extensionsApi.getPackageByName(\n request.params.namespace,\n request.params.name,\n );\n };\n\n router.get('/collections', async (req, res) => {\n const request = decodeGetEntitiesRequest(createSearchParams(req));\n const collections = await extensionsApi.getCollections(request);\n res.json(collections);\n });\n\n router.get('/collections/facets', async (req, res) => {\n const request = decodeGetEntityFacetsRequest(createSearchParams(req));\n const facets = await extensionsApi.getCollectionsFacets(request);\n res.json(facets);\n });\n\n router.get('/collection/:namespace/:name', async (req, res) => {\n const collection = await extensionsApi.getCollectionByName(\n req.params.namespace,\n req.params.name,\n );\n res.json(collection);\n });\n\n router.get('/collection/:namespace/:name/plugins', async (req, res) => {\n const plugins = await extensionsApi.getCollectionPlugins(\n req.params.namespace,\n req.params.name,\n );\n removeVerboseSpecContent(plugins);\n res.json(plugins);\n });\n\n router.get('/packages', async (req, res) => {\n const request = decodeGetEntitiesRequest(createSearchParams(req));\n const packages = await extensionsApi.getPackages(request);\n removeVerboseSpecContent(packages.items);\n res.json(packages);\n });\n\n router.get('/packages/facets', async (req, res) => {\n const request = decodeGetEntityFacetsRequest(createSearchParams(req));\n const facets = await extensionsApi.getPackagesFacets(request);\n res.json(facets);\n });\n\n router.get('/package/:namespace/:name', async (req, res) => {\n res.json(\n await extensionsApi.getPackageByName(\n req.params.namespace,\n req.params.name,\n ),\n );\n });\n\n router.get(\n '/package/:namespace/:name/configuration',\n requireInitializedInstallationDataService,\n async (req, res) => {\n const extensionsPackage = await getAuthorizedPackage(\n req,\n extensionsPluginReadPermission,\n );\n\n if (!extensionsPackage.spec?.dynamicArtifact) {\n throw new Error(\n `Package catalog entity ${extensionsPackage.metadata.name} is missing 'spec.dynamicArtifact'`,\n );\n }\n const result = installationDataService.getPackageConfig(\n extensionsPackage.spec?.dynamicArtifact,\n );\n res.status(200).json({ configYaml: result });\n },\n );\n\n router.post(\n '/package/:namespace/:name/configuration',\n requireInitializedInstallationDataService,\n async (req, res) => {\n const extensionsPackage = await getAuthorizedPackage(\n req,\n extensionsPluginWritePermission,\n );\n if (!extensionsPackage.spec?.dynamicArtifact) {\n throw new Error(\n `Package ${extensionsPackage.metadata.name} is missing 'spec.dynamicArtifact'`,\n );\n }\n\n const newConfig = req.body.configYaml;\n if (!newConfig) {\n throw new InputError(\"'configYaml' object must be present\");\n }\n try {\n installationDataService.updatePackageConfig(\n extensionsPackage.spec.dynamicArtifact,\n newConfig,\n );\n } catch (e) {\n if (e instanceof ConfigFormatError) {\n throw new InputError(e.message);\n }\n throw e;\n }\n res.status(200).json({ status: 'OK' });\n },\n );\n\n router.get('/environment', async (_req, res) => {\n res.status(200).json({\n nodeEnv: process.env.NODE_ENV || 'development',\n });\n });\n\n router.patch(\n '/package/:namespace/:name/configuration/disable',\n requireInitializedInstallationDataService,\n async (req, res) => {\n const extensionsPackage = await getAuthorizedPackage(\n req,\n extensionsPluginWritePermission,\n );\n\n if (!extensionsPackage.spec?.dynamicArtifact) {\n throw new Error(\n `Package catalog entity ${extensionsPackage.metadata.name} is missing 'spec.dynamicArtifact'`,\n );\n }\n\n const enabled = resolveEnabledField(req.body);\n installationDataService.setPackageEnabled(\n extensionsPackage.spec.dynamicArtifact,\n enabled,\n );\n res.status(200).json({ status: 'OK' });\n },\n );\n\n router.get('/plugins', async (req, res) => {\n const request = decodeGetEntitiesRequest(createSearchParams(req));\n const plugins = await extensionsApi.getPlugins(request);\n removeVerboseSpecContent(plugins.items);\n res.json(plugins);\n });\n\n router.get('/plugins/facets', async (req, res) => {\n const request = decodeGetEntityFacetsRequest(createSearchParams(req));\n const facets = await extensionsApi.getPluginFacets(request);\n res.json(facets);\n });\n\n router.get('/plugins/configure', async (_req, res) => {\n const isPluginInstallationEnabled =\n config.getOptionalBoolean('extensions.installation.enabled') ?? false;\n res.json({ enabled: isPluginInstallationEnabled });\n });\n\n router.get('/plugin/:namespace/:name', async (req, res) => {\n const plugin = await extensionsApi.getPluginByName(\n req.params.namespace,\n req.params.name,\n );\n res.json(plugin);\n });\n\n router.get(\n '/plugin/:namespace/:name/configuration/authorize',\n async (req, res) => {\n const [readDecision, installDecision] = await Promise.all([\n authorizeConditional(req, extensionsPluginReadPermission),\n authorizeConditional(req, extensionsPluginWritePermission),\n ]);\n if (\n readDecision.result === AuthorizeResult.DENY &&\n installDecision.result === AuthorizeResult.DENY\n ) {\n res.status(200).json({ read: 'DENY', write: 'DENY' });\n return;\n }\n\n let authorizedActions = {};\n let plugin: ExtensionsPlugin;\n\n const evaluateConditional = async (\n decision: PolicyDecision,\n action: string,\n ) => {\n if (decision.result === AuthorizeResult.CONDITIONAL) {\n if (!plugin) {\n plugin = await extensionsApi.getPluginByName(\n req.params.namespace,\n req.params.name,\n );\n }\n if (matches(plugin, decision.conditions)) {\n authorizedActions = { ...authorizedActions, [action]: 'ALLOW' };\n }\n } else if (decision.result === AuthorizeResult.ALLOW) {\n authorizedActions = { ...authorizedActions, [action]: 'ALLOW' };\n }\n };\n\n await Promise.all([\n evaluateConditional(readDecision, 'read'),\n evaluateConditional(installDecision, 'write'),\n ]);\n\n if (Object.keys(authorizedActions).length === 0) {\n res.status(200).json({ read: 'DENY', write: 'DENY' });\n } else {\n res.status(200).json(authorizedActions);\n }\n },\n );\n\n router.get(\n '/plugin/:namespace/:name/configuration',\n requireInitializedInstallationDataService,\n async (req, res) => {\n const plugin = await getAuthorizedPlugin(\n req,\n extensionsPluginReadPermission,\n );\n const result = await installationDataService.getPluginConfig(plugin);\n res.status(200).json({ configYaml: result });\n },\n );\n\n router.post(\n '/plugin/:namespace/:name/configuration',\n requireInitializedInstallationDataService,\n async (req, res) => {\n // installs the plugin\n const plugin = await getAuthorizedPlugin(\n req,\n extensionsPluginWritePermission,\n );\n\n const newConfig = req.body.configYaml;\n if (!newConfig) {\n throw new InputError(\"'configYaml' object must be present\");\n }\n try {\n await installationDataService.updatePluginConfig(plugin, newConfig);\n } catch (e) {\n if (e instanceof ConfigFormatError) {\n throw new InputError(e.message);\n }\n throw e;\n }\n res.status(200).json({ status: 'OK' });\n },\n );\n\n router.patch(\n '/plugin/:namespace/:name/configuration/disable',\n requireInitializedInstallationDataService,\n async (req, res) => {\n const plugin = await getAuthorizedPlugin(\n req,\n extensionsPluginWritePermission,\n );\n const enabled = resolveEnabledField(req.body);\n await installationDataService.setPluginEnabled(plugin, enabled);\n res.status(200).json({ status: 'OK' });\n },\n );\n\n router.get('/plugin/:namespace/:name/packages', async (req, res) => {\n const packages = await extensionsApi.getPluginPackages(\n req.params.namespace,\n req.params.name,\n );\n res.json(packages);\n });\n\n const plugins = pluginProvider.plugins();\n const dynamicPlugins = plugins.map(p => {\n // Remove the installer details for the dynamic backend plugins\n if (p.platform === 'node') {\n const { installer, ...rest } = p;\n return rest as BaseDynamicPlugin;\n }\n return p as BaseDynamicPlugin;\n });\n router.get('/loaded-plugins', async (req, response) => {\n await httpAuth.credentials(req, { allow: ['user', 'service'] });\n response.send(dynamicPlugins);\n });\n const middleware = MiddlewareFactory.create({ logger, config });\n\n router.use(middleware.error());\n\n return router;\n}\n"],"names":["InputError","Router","createPermissionIntegrationRouter","RESOURCE_TYPE_EXTENSIONS_PLUGIN","extensionsPermissions","extensionRules","express","AuthorizeResult","NotAllowedError","matches","decodeGetEntitiesRequest","createSearchParams","decodeGetEntityFacetsRequest","plugins","removeVerboseSpecContent","extensionsPluginReadPermission","extensionsPluginWritePermission","ConfigFormatError","MiddlewareFactory"],"mappings":";;;;;;;;;;;;;;;;;;;;AA8DA,SAAS,oBAAoB,IAAA,EAAwC;AACnE,EAAA,IAAI,IAAA,CAAK,YAAY,MAAA,EAAW;AAC9B,IAAA,IAAI,OAAO,IAAA,CAAK,OAAA,KAAY,SAAA,EAAW;AACrC,MAAA,MAAM,IAAIA,kBAAW,6BAA6B,CAAA;AAAA,IACpD;AACA,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EACd;AACA,EAAA,IAAI,OAAO,IAAA,CAAK,QAAA,KAAa,SAAA,EAAW;AACtC,IAAA,OAAO,CAAC,IAAA,CAAK,QAAA;AAAA,EACf;AACA,EAAA,MAAM,IAAIA,kBAAW,qCAAqC,CAAA;AAC5D;AAYA,eAAsB,aACpB,OAAA,EACyB;AACzB,EAAA,MAAM;AAAA,IACJ,QAAA;AAAA,IACA,aAAA;AAAA,IACA,WAAA;AAAA,IACA,uBAAA;AAAA,IACA,cAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF,GAAI,OAAA;AAEJ,EAAA,MAAM,yCAAA,GAA4C,CAChD,IAAA,EACA,IAAA,EACA,IAAA,KACG;AACH,IAAA,MAAM,KAAA,GAAQ,wBAAwB,sBAAA,EAAuB;AAC7D,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,MAAM,KAAA;AAAA,IACR;AACA,IAAA,IAAA,EAAK;AAAA,EACP,CAAA;AAEA,EAAA,MAAM,SAASC,uBAAA,EAAO;AACtB,EAAA,MAAM,+BAA+BC,sDAAA,CAAkC;AAAA,IACrE,YAAA,EAAcC,+DAAA;AAAA,IACd,WAAA,EAAaC,qDAAA;AAAA,IACb,KAAA,EAAO,MAAA,CAAO,MAAA,CAAOC,WAAc;AAAA,GACpC,CAAA;AACD,EAAA,MAAA,CAAO,GAAA,CAAIC,wBAAA,CAAQ,IAAA,EAAM,CAAA;AACzB,EAAA,MAAA,CAAO,IAAI,4BAA4B,CAAA;AAEvC,EAAA,MAAM,oBAAA,GAAuB,OAC3B,OAAA,EACA,UAAA,KACG;AACH,IAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,OAAO,CAAA;AACtD,IAAA,IAAI,QAAA;AAEJ,IAAA,IAAI,CAAC,UAAA,EAAY;AACf,MAAA,OAAO,EAAE,MAAA,EAAQC,sCAAA,CAAgB,KAAA,EAAM;AAAA,IACzC;AAEA,IAAA,IAAI,UAAA,CAAW,SAAS,UAAA,EAAY;AAClC,MAAA,QAAA,GAAA,CACE,MAAM,WAAA,CAAY,oBAAA,CAAqB,CAAC,EAAE,UAAA,EAAY,CAAA,EAAG;AAAA,QACvD;AAAA,OACD,GACD,CAAC,CAAA;AAAA,IACL,CAAA,MAAO;AACL,MAAA,QAAA,GAAA,CACE,MAAM,WAAA,CAAY,SAAA,CAAU,CAAC,EAAE,UAAA,EAAY,CAAA,EAAG;AAAA,QAC5C;AAAA,OACD,GACD,CAAC,CAAA;AAAA,IACL;AAEA,IAAA,OAAO,QAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,mBAAA,GAAsB,OAC1B,OAAA,EACA,UAAA,KACG;AACH,IAAA,MAAM,QAAA,GAAW,MAAM,oBAAA,CAAqB,OAAA,EAAS,UAAU,CAAA;AAE/D,IAAA,IAAI,QAAA,CAAS,MAAA,KAAWA,sCAAA,CAAgB,IAAA,EAAM;AAC5C,MAAA,MAAM,IAAIC,sBAAA;AAAA,QACR,CAAA,eAAA,EAAkB,UAAA,CAAW,UAAA,CAAW,MAAM,CAAA,sBAAA,EAAyB,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,CAAA,EAAI,OAAA,CAAQ,MAAA,CAAO,IAAI,CAAA;AAAA,OACxH;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc,eAAA;AAAA,MACjC,QAAQ,MAAA,CAAO,SAAA;AAAA,MACf,QAAQ,MAAA,CAAO;AAAA,KACjB;AAEA,IAAA,MAAM,SAAA,GACJ,QAAA,CAAS,MAAA,KAAWD,sCAAA,CAAgB,KAAA,IACnC,QAAA,CAAS,MAAA,KAAWA,sCAAA,CAAgB,WAAA,IACnCE,uBAAA,CAAQ,MAAA,EAAQ,QAAA,CAAS,UAAU,CAAA;AACvC,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,MAAM,IAAID,sBAAA;AAAA,QACR,CAAA,eAAA,EAAkB,UAAA,CAAW,UAAA,CAAW,MAAM,CAAA,sBAAA,EAAyB,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,CAAA,EAAI,OAAA,CAAQ,MAAA,CAAO,IAAI,CAAA;AAAA,OACxH;AAAA,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,oBAAA,GAAuB,OAC3B,OAAA,EACA,UAAA,KACG;AACH,IAAA,MAAM,QAAA,GAAW,MAAM,oBAAA,CAAqB,OAAA,EAAS,UAAU,CAAA;AAE/D,IAAA,IAAI,QAAA,CAAS,MAAA,KAAWD,sCAAA,CAAgB,IAAA,EAAM;AAC5C,MAAA,MAAM,IAAIC,sBAAA;AAAA,QACR,CAAA,eAAA,EAAkB,UAAA,CAAW,UAAA,CAAW,MAAM,CAAA,sBAAA,EAAyB,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,CAAA,EAAI,OAAA,CAAQ,MAAA,CAAO,IAAI,CAAA;AAAA,OACxH;AAAA,IACF;AAEA,IAAA,MAAM,cAAA,GAAiB,MAAM,aAAA,CAAc,iBAAA;AAAA,MACzC,QAAQ,MAAA,CAAO,SAAA;AAAA,MACf,QAAQ,MAAA,CAAO;AAAA,KACjB;AACA,IAAA,MAAM,YACJ,QAAA,CAAS,MAAA,KAAWD,sCAAA,CAAgB,KAAA,IACnC,SAAS,MAAA,KAAWA,sCAAA,CAAgB,WAAA,IACnC,cAAA,CAAe,KAAK,CAAA,MAAA,KAAUE,uBAAA,CAAQ,MAAA,EAAQ,QAAA,CAAS,UAAU,CAAC,CAAA;AACtE,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,MAAM,IAAID,sBAAA;AAAA,QACR,CAAA,eAAA,EAAkB,UAAA,CAAW,UAAA,CAAW,MAAM,CAAA,sBAAA,EAAyB,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,CAAA,EAAI,OAAA,CAAQ,MAAA,CAAO,IAAI,CAAA;AAAA,OACxH;AAAA,IACF;AAEA,IAAA,OAAO,MAAM,aAAA,CAAc,gBAAA;AAAA,MACzB,QAAQ,MAAA,CAAO,SAAA;AAAA,MACf,QAAQ,MAAA,CAAO;AAAA,KACjB;AAAA,EACF,CAAA;AAEA,EAAA,MAAA,CAAO,GAAA,CAAI,cAAA,EAAgB,OAAO,GAAA,EAAK,GAAA,KAAQ;AAC7C,IAAA,MAAM,OAAA,GAAUE,wDAAA,CAAyBC,qCAAA,CAAmB,GAAG,CAAC,CAAA;AAChE,IAAA,MAAM,WAAA,GAAc,MAAM,aAAA,CAAc,cAAA,CAAe,OAAO,CAAA;AAC9D,IAAA,GAAA,CAAI,KAAK,WAAW,CAAA;AAAA,EACtB,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,qBAAA,EAAuB,OAAO,GAAA,EAAK,GAAA,KAAQ;AACpD,IAAA,MAAM,OAAA,GAAUC,4DAAA,CAA6BD,qCAAA,CAAmB,GAAG,CAAC,CAAA;AACpE,IAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc,oBAAA,CAAqB,OAAO,CAAA;AAC/D,IAAA,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,EACjB,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,8BAAA,EAAgC,OAAO,GAAA,EAAK,GAAA,KAAQ;AAC7D,IAAA,MAAM,UAAA,GAAa,MAAM,aAAA,CAAc,mBAAA;AAAA,MACrC,IAAI,MAAA,CAAO,SAAA;AAAA,MACX,IAAI,MAAA,CAAO;AAAA,KACb;AACA,IAAA,GAAA,CAAI,KAAK,UAAU,CAAA;AAAA,EACrB,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,sCAAA,EAAwC,OAAO,GAAA,EAAK,GAAA,KAAQ;AACrE,IAAA,MAAME,QAAAA,GAAU,MAAM,aAAA,CAAc,oBAAA;AAAA,MAClC,IAAI,MAAA,CAAO,SAAA;AAAA,MACX,IAAI,MAAA,CAAO;AAAA,KACb;AACA,IAAAC,iDAAA,CAAyBD,QAAO,CAAA;AAChC,IAAA,GAAA,CAAI,KAAKA,QAAO,CAAA;AAAA,EAClB,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,WAAA,EAAa,OAAO,GAAA,EAAK,GAAA,KAAQ;AAC1C,IAAA,MAAM,OAAA,GAAUH,wDAAA,CAAyBC,qCAAA,CAAmB,GAAG,CAAC,CAAA;AAChE,IAAA,MAAM,QAAA,GAAW,MAAM,aAAA,CAAc,WAAA,CAAY,OAAO,CAAA;AACxD,IAAAG,iDAAA,CAAyB,SAAS,KAAK,CAAA;AACvC,IAAA,GAAA,CAAI,KAAK,QAAQ,CAAA;AAAA,EACnB,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,kBAAA,EAAoB,OAAO,GAAA,EAAK,GAAA,KAAQ;AACjD,IAAA,MAAM,OAAA,GAAUF,4DAAA,CAA6BD,qCAAA,CAAmB,GAAG,CAAC,CAAA;AACpE,IAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc,iBAAA,CAAkB,OAAO,CAAA;AAC5D,IAAA,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,EACjB,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,2BAAA,EAA6B,OAAO,GAAA,EAAK,GAAA,KAAQ;AAC1D,IAAA,GAAA,CAAI,IAAA;AAAA,MACF,MAAM,aAAA,CAAc,gBAAA;AAAA,QAClB,IAAI,MAAA,CAAO,SAAA;AAAA,QACX,IAAI,MAAA,CAAO;AAAA;AACb,KACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA;AAAA,IACL,yCAAA;AAAA,IACA,yCAAA;AAAA,IACA,OAAO,KAAK,GAAA,KAAQ;AAClB,MAAA,MAAM,oBAAoB,MAAM,oBAAA;AAAA,QAC9B,GAAA;AAAA,QACAI;AAAA,OACF;AAEA,MAAA,IAAI,CAAC,iBAAA,CAAkB,IAAA,EAAM,eAAA,EAAiB;AAC5C,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,uBAAA,EAA0B,iBAAA,CAAkB,QAAA,CAAS,IAAI,CAAA,kCAAA;AAAA,SAC3D;AAAA,MACF;AACA,MAAA,MAAM,SAAS,uBAAA,CAAwB,gBAAA;AAAA,QACrC,kBAAkB,IAAA,EAAM;AAAA,OAC1B;AACA,MAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,UAAA,EAAY,QAAQ,CAAA;AAAA,IAC7C;AAAA,GACF;AAEA,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,yCAAA;AAAA,IACA,yCAAA;AAAA,IACA,OAAO,KAAK,GAAA,KAAQ;AAClB,MAAA,MAAM,oBAAoB,MAAM,oBAAA;AAAA,QAC9B,GAAA;AAAA,QACAC;AAAA,OACF;AACA,MAAA,IAAI,CAAC,iBAAA,CAAkB,IAAA,EAAM,eAAA,EAAiB;AAC5C,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,QAAA,EAAW,iBAAA,CAAkB,QAAA,CAAS,IAAI,CAAA,kCAAA;AAAA,SAC5C;AAAA,MACF;AAEA,MAAA,MAAM,SAAA,GAAY,IAAI,IAAA,CAAK,UAAA;AAC3B,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,MAAM,IAAIhB,kBAAW,qCAAqC,CAAA;AAAA,MAC5D;AACA,MAAA,IAAI;AACF,QAAA,uBAAA,CAAwB,mBAAA;AAAA,UACtB,kBAAkB,IAAA,CAAK,eAAA;AAAA,UACvB;AAAA,SACF;AAAA,MACF,SAAS,CAAA,EAAG;AACV,QAAA,IAAI,aAAaiB,mCAAA,EAAmB;AAClC,UAAA,MAAM,IAAIjB,iBAAA,CAAW,CAAA,CAAE,OAAO,CAAA;AAAA,QAChC;AACA,QAAA,MAAM,CAAA;AAAA,MACR;AACA,MAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,MAAA,EAAQ,MAAM,CAAA;AAAA,IACvC;AAAA,GACF;AAEA,EAAA,MAAA,CAAO,GAAA,CAAI,cAAA,EAAgB,OAAO,IAAA,EAAM,GAAA,KAAQ;AAC9C,IAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,MACnB,OAAA,EAAS,OAAA,CAAQ,GAAA,CAAI,QAAA,IAAY;AAAA,KAClC,CAAA;AAAA,EACH,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,KAAA;AAAA,IACL,iDAAA;AAAA,IACA,yCAAA;AAAA,IACA,OAAO,KAAK,GAAA,KAAQ;AAClB,MAAA,MAAM,oBAAoB,MAAM,oBAAA;AAAA,QAC9B,GAAA;AAAA,QACAgB;AAAA,OACF;AAEA,MAAA,IAAI,CAAC,iBAAA,CAAkB,IAAA,EAAM,eAAA,EAAiB;AAC5C,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,uBAAA,EAA0B,iBAAA,CAAkB,QAAA,CAAS,IAAI,CAAA,kCAAA;AAAA,SAC3D;AAAA,MACF;AAEA,MAAA,MAAM,OAAA,GAAU,mBAAA,CAAoB,GAAA,CAAI,IAAI,CAAA;AAC5C,MAAA,uBAAA,CAAwB,iBAAA;AAAA,QACtB,kBAAkB,IAAA,CAAK,eAAA;AAAA,QACvB;AAAA,OACF;AACA,MAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,MAAA,EAAQ,MAAM,CAAA;AAAA,IACvC;AAAA,GACF;AAEA,EAAA,MAAA,CAAO,GAAA,CAAI,UAAA,EAAY,OAAO,GAAA,EAAK,GAAA,KAAQ;AACzC,IAAA,MAAM,OAAA,GAAUN,wDAAA,CAAyBC,qCAAA,CAAmB,GAAG,CAAC,CAAA;AAChE,IAAA,MAAME,QAAAA,GAAU,MAAM,aAAA,CAAc,UAAA,CAAW,OAAO,CAAA;AACtD,IAAAC,iDAAA,CAAyBD,SAAQ,KAAK,CAAA;AACtC,IAAA,GAAA,CAAI,KAAKA,QAAO,CAAA;AAAA,EAClB,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,iBAAA,EAAmB,OAAO,GAAA,EAAK,GAAA,KAAQ;AAChD,IAAA,MAAM,OAAA,GAAUD,4DAAA,CAA6BD,qCAAA,CAAmB,GAAG,CAAC,CAAA;AACpE,IAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc,eAAA,CAAgB,OAAO,CAAA;AAC1D,IAAA,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,EACjB,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,oBAAA,EAAsB,OAAO,IAAA,EAAM,GAAA,KAAQ;AACpD,IAAA,MAAM,2BAAA,GACJ,MAAA,CAAO,kBAAA,CAAmB,iCAAiC,CAAA,IAAK,KAAA;AAClE,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,OAAA,EAAS,2BAAA,EAA6B,CAAA;AAAA,EACnD,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,0BAAA,EAA4B,OAAO,GAAA,EAAK,GAAA,KAAQ;AACzD,IAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc,eAAA;AAAA,MACjC,IAAI,MAAA,CAAO,SAAA;AAAA,MACX,IAAI,MAAA,CAAO;AAAA,KACb;AACA,IAAA,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,EACjB,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA;AAAA,IACL,kDAAA;AAAA,IACA,OAAO,KAAK,GAAA,KAAQ;AAClB,MAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA,QACxD,oBAAA,CAAqB,KAAKI,8DAA8B,CAAA;AAAA,QACxD,oBAAA,CAAqB,KAAKC,+DAA+B;AAAA,OAC1D,CAAA;AACD,MAAA,IACE,aAAa,MAAA,KAAWT,sCAAA,CAAgB,QACxC,eAAA,CAAgB,MAAA,KAAWA,uCAAgB,IAAA,EAC3C;AACA,QAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,MAAA,EAAQ,CAAA;AACpD,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,oBAAoB,EAAC;AACzB,MAAA,IAAI,MAAA;AAEJ,MAAA,MAAM,mBAAA,GAAsB,OAC1B,QAAA,EACA,MAAA,KACG;AACH,QAAA,IAAI,QAAA,CAAS,MAAA,KAAWA,sCAAA,CAAgB,WAAA,EAAa;AACnD,UAAA,IAAI,CAAC,MAAA,EAAQ;AACX,YAAA,MAAA,GAAS,MAAM,aAAA,CAAc,eAAA;AAAA,cAC3B,IAAI,MAAA,CAAO,SAAA;AAAA,cACX,IAAI,MAAA,CAAO;AAAA,aACb;AAAA,UACF;AACA,UAAA,IAAIE,uBAAA,CAAQ,MAAA,EAAQ,QAAA,CAAS,UAAU,CAAA,EAAG;AACxC,YAAA,iBAAA,GAAoB,EAAE,GAAG,iBAAA,EAAmB,CAAC,MAAM,GAAG,OAAA,EAAQ;AAAA,UAChE;AAAA,QACF,CAAA,MAAA,IAAW,QAAA,CAAS,MAAA,KAAWF,sCAAA,CAAgB,KAAA,EAAO;AACpD,UAAA,iBAAA,GAAoB,EAAE,GAAG,iBAAA,EAAmB,CAAC,MAAM,GAAG,OAAA,EAAQ;AAAA,QAChE;AAAA,MACF,CAAA;AAEA,MAAA,MAAM,QAAQ,GAAA,CAAI;AAAA,QAChB,mBAAA,CAAoB,cAAc,MAAM,CAAA;AAAA,QACxC,mBAAA,CAAoB,iBAAiB,OAAO;AAAA,OAC7C,CAAA;AAED,MAAA,IAAI,MAAA,CAAO,IAAA,CAAK,iBAAiB,CAAA,CAAE,WAAW,CAAA,EAAG;AAC/C,QAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,MAAA,EAAQ,CAAA;AAAA,MACtD,CAAA,MAAO;AACL,QAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,iBAAiB,CAAA;AAAA,MACxC;AAAA,IACF;AAAA,GACF;AAEA,EAAA,MAAA,CAAO,GAAA;AAAA,IACL,wCAAA;AAAA,IACA,yCAAA;AAAA,IACA,OAAO,KAAK,GAAA,KAAQ;AAClB,MAAA,MAAM,SAAS,MAAM,mBAAA;AAAA,QACnB,GAAA;AAAA,QACAQ;AAAA,OACF;AACA,MAAA,MAAM,MAAA,GAAS,MAAM,uBAAA,CAAwB,eAAA,CAAgB,MAAM,CAAA;AACnE,MAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,UAAA,EAAY,QAAQ,CAAA;AAAA,IAC7C;AAAA,GACF;AAEA,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,wCAAA;AAAA,IACA,yCAAA;AAAA,IACA,OAAO,KAAK,GAAA,KAAQ;AAElB,MAAA,MAAM,SAAS,MAAM,mBAAA;AAAA,QACnB,GAAA;AAAA,QACAC;AAAA,OACF;AAEA,MAAA,MAAM,SAAA,GAAY,IAAI,IAAA,CAAK,UAAA;AAC3B,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,MAAM,IAAIhB,kBAAW,qCAAqC,CAAA;AAAA,MAC5D;AACA,MAAA,IAAI;AACF,QAAA,MAAM,uBAAA,CAAwB,kBAAA,CAAmB,MAAA,EAAQ,SAAS,CAAA;AAAA,MACpE,SAAS,CAAA,EAAG;AACV,QAAA,IAAI,aAAaiB,mCAAA,EAAmB;AAClC,UAAA,MAAM,IAAIjB,iBAAA,CAAW,CAAA,CAAE,OAAO,CAAA;AAAA,QAChC;AACA,QAAA,MAAM,CAAA;AAAA,MACR;AACA,MAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,MAAA,EAAQ,MAAM,CAAA;AAAA,IACvC;AAAA,GACF;AAEA,EAAA,MAAA,CAAO,KAAA;AAAA,IACL,gDAAA;AAAA,IACA,yCAAA;AAAA,IACA,OAAO,KAAK,GAAA,KAAQ;AAClB,MAAA,MAAM,SAAS,MAAM,mBAAA;AAAA,QACnB,GAAA;AAAA,QACAgB;AAAA,OACF;AACA,MAAA,MAAM,OAAA,GAAU,mBAAA,CAAoB,GAAA,CAAI,IAAI,CAAA;AAC5C,MAAA,MAAM,uBAAA,CAAwB,gBAAA,CAAiB,MAAA,EAAQ,OAAO,CAAA;AAC9D,MAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,MAAA,EAAQ,MAAM,CAAA;AAAA,IACvC;AAAA,GACF;AAEA,EAAA,MAAA,CAAO,GAAA,CAAI,mCAAA,EAAqC,OAAO,GAAA,EAAK,GAAA,KAAQ;AAClE,IAAA,MAAM,QAAA,GAAW,MAAM,aAAA,CAAc,iBAAA;AAAA,MACnC,IAAI,MAAA,CAAO,SAAA;AAAA,MACX,IAAI,MAAA,CAAO;AAAA,KACb;AACA,IAAA,GAAA,CAAI,KAAK,QAAQ,CAAA;AAAA,EACnB,CAAC,CAAA;AAED,EAAA,MAAM,OAAA,GAAU,eAAe,OAAA,EAAQ;AACvC,EAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAA,KAAK;AAEtC,IAAA,IAAI,CAAA,CAAE,aAAa,MAAA,EAAQ;AACzB,MAAA,MAAM,EAAE,SAAA,EAAW,GAAG,IAAA,EAAK,GAAI,CAAA;AAC/B,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO,CAAA;AAAA,EACT,CAAC,CAAA;AACD,EAAA,MAAA,CAAO,GAAA,CAAI,iBAAA,EAAmB,OAAO,GAAA,EAAK,QAAA,KAAa;AACrD,IAAA,MAAM,QAAA,CAAS,YAAY,GAAA,EAAK,EAAE,OAAO,CAAC,MAAA,EAAQ,SAAS,CAAA,EAAG,CAAA;AAC9D,IAAA,QAAA,CAAS,KAAK,cAAc,CAAA;AAAA,EAC9B,CAAC,CAAA;AACD,EAAA,MAAM,aAAaE,gCAAA,CAAkB,MAAA,CAAO,EAAE,MAAA,EAAQ,QAAQ,CAAA;AAE9D,EAAA,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,KAAA,EAAO,CAAA;AAE7B,EAAA,OAAO,MAAA;AACT;;;;"}
@@ -30,6 +30,12 @@ function validatePackageFormat(item, packageName) {
30
30
  "Invalid installation configuration, 'package' field in package item must be a non-empty string"
31
31
  );
32
32
  }
33
+ const enabled = item.get("enabled");
34
+ if (enabled && typeof enabled !== "boolean") {
35
+ throw new ConfigFormatError.ConfigFormatError(
36
+ "Invalid installation configuration, optional 'enabled' field in package item must be a boolean"
37
+ );
38
+ }
33
39
  const disabled = item.get("disabled");
34
40
  if (disabled && typeof disabled !== "boolean") {
35
41
  throw new ConfigFormatError.ConfigFormatError(
@@ -1 +1 @@
1
- {"version":3,"file":"configValidation.cjs.js","sources":["../../src/validation/configValidation.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 { Document, isMap, isSeq, type YAMLMap, type YAMLSeq } from 'yaml';\nimport { ConfigFormatError } from '../errors/ConfigFormatError';\nimport type { JsonValue } from '@backstage/types';\n\nexport function validateConfigurationFormat(\n doc: Document,\n): asserts doc is Document & {\n contents: YAMLMap<string, JsonValue>;\n} {\n if (!isMap(doc.contents)) {\n throw new ConfigFormatError(\n 'Invalid installation configuration, expected a map',\n );\n }\n\n const plugins = doc.get('plugins');\n\n if (!isSeq(plugins))\n throw new ConfigFormatError(\n \"Invalid installation configuration, 'plugins' field must be a list\",\n );\n for (const item of plugins.items) {\n validatePackageFormat(item);\n }\n}\n\nexport function validatePackageFormat(\n item: unknown,\n packageName?: string,\n): asserts item is YAMLMap<string, JsonValue> {\n if (!isMap(item)) {\n throw new ConfigFormatError(\n 'Invalid installation configuration, package item must be a map',\n );\n }\n\n const packageToValidate = item.get('package');\n if (\n typeof packageToValidate !== 'string' ||\n packageToValidate.trim() === ''\n ) {\n throw new ConfigFormatError(\n \"Invalid installation configuration, 'package' field in package item must be a non-empty string\",\n );\n }\n\n const disabled = item.get('disabled');\n if (disabled && typeof disabled !== 'boolean') {\n throw new ConfigFormatError(\n \"Invalid installation configuration, optional 'disabled' field in package item must be a boolean\",\n );\n }\n\n const pluginConfig = item.get('pluginConfig');\n if (pluginConfig && !isMap(pluginConfig)) {\n throw new ConfigFormatError(\n \"Invalid installation configuration, optional 'pluginConfig' field in package item must be a map\",\n );\n }\n\n const integrity = item.get('integrity');\n if (integrity && (typeof integrity !== 'string' || integrity.trim() === '')) {\n throw new ConfigFormatError(\n \"Invalid installation configuration, optional 'integrity' field in package item must be a non-empty string\",\n );\n }\n\n if (packageName && packageToValidate !== packageName) {\n throw new ConfigFormatError(\n `Invalid installation configuration, 'package' field value in package item differs from '${packageName}'`,\n );\n }\n}\n\nexport function validatePluginFormat(\n doc: Document,\n pluginPackages: Set<string>,\n): asserts doc is Document & {\n contents: YAMLSeq<YAMLMap<string, JsonValue>>;\n} {\n if (!isSeq(doc.contents))\n throw new ConfigFormatError(\n 'Invalid installation configuration, plugin packages must be a list',\n );\n for (const item of doc.contents.items) {\n validatePackageFormat(item);\n const packageToValidate = item.get('package') as string;\n if (!pluginPackages.has(packageToValidate)) {\n throw new ConfigFormatError(\n `Invalid configuration, package '${packageToValidate}' is not part of plugin configuration`,\n );\n }\n }\n}\n"],"names":["isMap","ConfigFormatError","isSeq"],"mappings":";;;;;AAmBO,SAAS,4BACd,GAAA,EAGA;AACA,EAAA,IAAI,CAACA,UAAA,CAAM,GAAA,CAAI,QAAQ,CAAA,EAAG;AACxB,IAAA,MAAM,IAAIC,mCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,OAAA,GAAU,GAAA,CAAI,GAAA,CAAI,SAAS,CAAA;AAEjC,EAAA,IAAI,CAACC,WAAM,OAAO,CAAA;AAChB,IAAA,MAAM,IAAID,mCAAA;AAAA,MACR;AAAA,KACF;AACF,EAAA,KAAA,MAAW,IAAA,IAAQ,QAAQ,KAAA,EAAO;AAChC,IAAA,qBAAA,CAAsB,IAAI,CAAA;AAAA,EAC5B;AACF;AAEO,SAAS,qBAAA,CACd,MACA,WAAA,EAC4C;AAC5C,EAAA,IAAI,CAACD,UAAA,CAAM,IAAI,CAAA,EAAG;AAChB,IAAA,MAAM,IAAIC,mCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,iBAAA,GAAoB,IAAA,CAAK,GAAA,CAAI,SAAS,CAAA;AAC5C,EAAA,IACE,OAAO,iBAAA,KAAsB,QAAA,IAC7B,iBAAA,CAAkB,IAAA,OAAW,EAAA,EAC7B;AACA,IAAA,MAAM,IAAIA,mCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,UAAU,CAAA;AACpC,EAAA,IAAI,QAAA,IAAY,OAAO,QAAA,KAAa,SAAA,EAAW;AAC7C,IAAA,MAAM,IAAIA,mCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,cAAc,CAAA;AAC5C,EAAA,IAAI,YAAA,IAAgB,CAACD,UAAA,CAAM,YAAY,CAAA,EAAG;AACxC,IAAA,MAAM,IAAIC,mCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,WAAW,CAAA;AACtC,EAAA,IAAI,cAAc,OAAO,SAAA,KAAc,YAAY,SAAA,CAAU,IAAA,OAAW,EAAA,CAAA,EAAK;AAC3E,IAAA,MAAM,IAAIA,mCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,WAAA,IAAe,sBAAsB,WAAA,EAAa;AACpD,IAAA,MAAM,IAAIA,mCAAA;AAAA,MACR,2FAA2F,WAAW,CAAA,CAAA;AAAA,KACxG;AAAA,EACF;AACF;AAEO,SAAS,oBAAA,CACd,KACA,cAAA,EAGA;AACA,EAAA,IAAI,CAACC,UAAA,CAAM,GAAA,CAAI,QAAQ,CAAA;AACrB,IAAA,MAAM,IAAID,mCAAA;AAAA,MACR;AAAA,KACF;AACF,EAAA,KAAA,MAAW,IAAA,IAAQ,GAAA,CAAI,QAAA,CAAS,KAAA,EAAO;AACrC,IAAA,qBAAA,CAAsB,IAAI,CAAA;AAC1B,IAAA,MAAM,iBAAA,GAAoB,IAAA,CAAK,GAAA,CAAI,SAAS,CAAA;AAC5C,IAAA,IAAI,CAAC,cAAA,CAAe,GAAA,CAAI,iBAAiB,CAAA,EAAG;AAC1C,MAAA,MAAM,IAAIA,mCAAA;AAAA,QACR,mCAAmC,iBAAiB,CAAA,qCAAA;AAAA,OACtD;AAAA,IACF;AAAA,EACF;AACF;;;;;;"}
1
+ {"version":3,"file":"configValidation.cjs.js","sources":["../../src/validation/configValidation.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 { Document, isMap, isSeq, type YAMLMap, type YAMLSeq } from 'yaml';\nimport { ConfigFormatError } from '../errors/ConfigFormatError';\nimport type { JsonValue } from '@backstage/types';\n\nexport function validateConfigurationFormat(\n doc: Document,\n): asserts doc is Document & {\n contents: YAMLMap<string, JsonValue>;\n} {\n if (!isMap(doc.contents)) {\n throw new ConfigFormatError(\n 'Invalid installation configuration, expected a map',\n );\n }\n\n const plugins = doc.get('plugins');\n\n if (!isSeq(plugins))\n throw new ConfigFormatError(\n \"Invalid installation configuration, 'plugins' field must be a list\",\n );\n for (const item of plugins.items) {\n validatePackageFormat(item);\n }\n}\n\nexport function validatePackageFormat(\n item: unknown,\n packageName?: string,\n): asserts item is YAMLMap<string, JsonValue> {\n if (!isMap(item)) {\n throw new ConfigFormatError(\n 'Invalid installation configuration, package item must be a map',\n );\n }\n\n const packageToValidate = item.get('package');\n if (\n typeof packageToValidate !== 'string' ||\n packageToValidate.trim() === ''\n ) {\n throw new ConfigFormatError(\n \"Invalid installation configuration, 'package' field in package item must be a non-empty string\",\n );\n }\n\n const enabled = item.get('enabled');\n if (enabled && typeof enabled !== 'boolean') {\n throw new ConfigFormatError(\n \"Invalid installation configuration, optional 'enabled' field in package item must be a boolean\",\n );\n }\n\n const disabled = item.get('disabled');\n if (disabled && typeof disabled !== 'boolean') {\n throw new ConfigFormatError(\n \"Invalid installation configuration, optional 'disabled' field in package item must be a boolean\",\n );\n }\n\n const pluginConfig = item.get('pluginConfig');\n if (pluginConfig && !isMap(pluginConfig)) {\n throw new ConfigFormatError(\n \"Invalid installation configuration, optional 'pluginConfig' field in package item must be a map\",\n );\n }\n\n const integrity = item.get('integrity');\n if (integrity && (typeof integrity !== 'string' || integrity.trim() === '')) {\n throw new ConfigFormatError(\n \"Invalid installation configuration, optional 'integrity' field in package item must be a non-empty string\",\n );\n }\n\n if (packageName && packageToValidate !== packageName) {\n throw new ConfigFormatError(\n `Invalid installation configuration, 'package' field value in package item differs from '${packageName}'`,\n );\n }\n}\n\nexport function validatePluginFormat(\n doc: Document,\n pluginPackages: Set<string>,\n): asserts doc is Document & {\n contents: YAMLSeq<YAMLMap<string, JsonValue>>;\n} {\n if (!isSeq(doc.contents))\n throw new ConfigFormatError(\n 'Invalid installation configuration, plugin packages must be a list',\n );\n for (const item of doc.contents.items) {\n validatePackageFormat(item);\n const packageToValidate = item.get('package') as string;\n if (!pluginPackages.has(packageToValidate)) {\n throw new ConfigFormatError(\n `Invalid configuration, package '${packageToValidate}' is not part of plugin configuration`,\n );\n }\n }\n}\n"],"names":["isMap","ConfigFormatError","isSeq"],"mappings":";;;;;AAmBO,SAAS,4BACd,GAAA,EAGA;AACA,EAAA,IAAI,CAACA,UAAA,CAAM,GAAA,CAAI,QAAQ,CAAA,EAAG;AACxB,IAAA,MAAM,IAAIC,mCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,OAAA,GAAU,GAAA,CAAI,GAAA,CAAI,SAAS,CAAA;AAEjC,EAAA,IAAI,CAACC,WAAM,OAAO,CAAA;AAChB,IAAA,MAAM,IAAID,mCAAA;AAAA,MACR;AAAA,KACF;AACF,EAAA,KAAA,MAAW,IAAA,IAAQ,QAAQ,KAAA,EAAO;AAChC,IAAA,qBAAA,CAAsB,IAAI,CAAA;AAAA,EAC5B;AACF;AAEO,SAAS,qBAAA,CACd,MACA,WAAA,EAC4C;AAC5C,EAAA,IAAI,CAACD,UAAA,CAAM,IAAI,CAAA,EAAG;AAChB,IAAA,MAAM,IAAIC,mCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,iBAAA,GAAoB,IAAA,CAAK,GAAA,CAAI,SAAS,CAAA;AAC5C,EAAA,IACE,OAAO,iBAAA,KAAsB,QAAA,IAC7B,iBAAA,CAAkB,IAAA,OAAW,EAAA,EAC7B;AACA,IAAA,MAAM,IAAIA,mCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,SAAS,CAAA;AAClC,EAAA,IAAI,OAAA,IAAW,OAAO,OAAA,KAAY,SAAA,EAAW;AAC3C,IAAA,MAAM,IAAIA,mCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,UAAU,CAAA;AACpC,EAAA,IAAI,QAAA,IAAY,OAAO,QAAA,KAAa,SAAA,EAAW;AAC7C,IAAA,MAAM,IAAIA,mCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,cAAc,CAAA;AAC5C,EAAA,IAAI,YAAA,IAAgB,CAACD,UAAA,CAAM,YAAY,CAAA,EAAG;AACxC,IAAA,MAAM,IAAIC,mCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,WAAW,CAAA;AACtC,EAAA,IAAI,cAAc,OAAO,SAAA,KAAc,YAAY,SAAA,CAAU,IAAA,OAAW,EAAA,CAAA,EAAK;AAC3E,IAAA,MAAM,IAAIA,mCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,WAAA,IAAe,sBAAsB,WAAA,EAAa;AACpD,IAAA,MAAM,IAAIA,mCAAA;AAAA,MACR,2FAA2F,WAAW,CAAA,CAAA;AAAA,KACxG;AAAA,EACF;AACF;AAEO,SAAS,oBAAA,CACd,KACA,cAAA,EAGA;AACA,EAAA,IAAI,CAACC,UAAA,CAAM,GAAA,CAAI,QAAQ,CAAA;AACrB,IAAA,MAAM,IAAID,mCAAA;AAAA,MACR;AAAA,KACF;AACF,EAAA,KAAA,MAAW,IAAA,IAAQ,GAAA,CAAI,QAAA,CAAS,KAAA,EAAO;AACrC,IAAA,qBAAA,CAAsB,IAAI,CAAA;AAC1B,IAAA,MAAM,iBAAA,GAAoB,IAAA,CAAK,GAAA,CAAI,SAAS,CAAA;AAC5C,IAAA,IAAI,CAAC,cAAA,CAAe,GAAA,CAAI,iBAAiB,CAAA,EAAG;AAC1C,MAAA,MAAM,IAAIA,mCAAA;AAAA,QACR,mCAAmC,iBAAiB,CAAA,qCAAA;AAAA,OACtD;AAAA,IACF;AAAA,EACF;AACF;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@red-hat-developer-hub/backstage-plugin-extensions-backend",
3
- "version": "0.18.1",
3
+ "version": "0.19.0",
4
4
  "main": "dist/index.cjs.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -36,26 +36,26 @@
36
36
  "postpack": "backstage-cli package postpack"
37
37
  },
38
38
  "dependencies": {
39
- "@backstage/backend-defaults": "^0.17.2",
40
- "@backstage/backend-dynamic-feature-service": "^0.8.2",
41
- "@backstage/backend-plugin-api": "^1.9.1",
42
- "@backstage/catalog-client": "^1.15.2",
39
+ "@backstage/backend-defaults": "^0.17.4",
40
+ "@backstage/backend-dynamic-feature-service": "^0.8.3",
41
+ "@backstage/backend-plugin-api": "^1.9.2",
42
+ "@backstage/catalog-client": "^1.16.0",
43
43
  "@backstage/catalog-model": "^1.9.0",
44
44
  "@backstage/errors": "^1.3.1",
45
- "@backstage/plugin-catalog-node": "^2.2.1",
45
+ "@backstage/plugin-catalog-node": "^2.2.2",
46
46
  "@backstage/plugin-permission-common": "^0.9.9",
47
- "@backstage/plugin-permission-node": "^0.11.0",
48
- "@red-hat-developer-hub/backstage-plugin-extensions-common": "^0.18.1",
47
+ "@backstage/plugin-permission-node": "^0.11.1",
48
+ "@red-hat-developer-hub/backstage-plugin-extensions-common": "^0.19.0",
49
49
  "express": "^4.17.1",
50
50
  "express-promise-router": "^4.1.0",
51
51
  "yaml": "^2.7.1",
52
52
  "zod": "^3.22.4"
53
53
  },
54
54
  "devDependencies": {
55
- "@backstage/backend-test-utils": "^1.11.3",
56
- "@backstage/cli": "^0.36.2",
55
+ "@backstage/backend-test-utils": "^1.11.4",
56
+ "@backstage/cli": "^0.36.3",
57
57
  "@backstage/config": "^1.3.8",
58
- "@backstage/plugin-catalog-node": "^2.2.1",
58
+ "@backstage/plugin-catalog-node": "^2.2.2",
59
59
  "@backstage/types": "^1.2.2",
60
60
  "@types/express": "*",
61
61
  "@types/supertest": "^2.0.12",