@techdocs/cli 1.11.5-next.1 → 1.12.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.
Files changed (102) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/commands/generate/generate.cjs.js +32 -2
  3. package/dist/commands/generate/generate.cjs.js.map +1 -1
  4. package/dist/commands/index.cjs.js +9 -1
  5. package/dist/commands/index.cjs.js.map +1 -1
  6. package/dist/commands/publish/publish.cjs.js +47 -0
  7. package/dist/commands/publish/publish.cjs.js.map +1 -1
  8. package/dist/embedded-app/.config-schema.json +51 -46
  9. package/dist/embedded-app/index.html +1 -1
  10. package/dist/embedded-app/index.html.tmpl +1 -1
  11. package/dist/embedded-app/static/123.91ba1b809deb.chunk.js +2 -0
  12. package/dist/embedded-app/static/123.91ba1b809deb.chunk.js.map +1 -0
  13. package/dist/embedded-app/static/1659.a99e4eb674e0.chunk.js +2 -0
  14. package/dist/embedded-app/static/1659.a99e4eb674e0.chunk.js.map +1 -0
  15. package/dist/embedded-app/static/1749.99ba95728e00.chunk.js +2 -0
  16. package/dist/embedded-app/static/1749.99ba95728e00.chunk.js.map +1 -0
  17. package/dist/embedded-app/static/1994.7736057c2e9f.chunk.js +2 -0
  18. package/dist/embedded-app/static/1994.7736057c2e9f.chunk.js.map +1 -0
  19. package/dist/embedded-app/static/{2055.fd3ccf91ac47.chunk.js → 2055.d938e6121e5f.chunk.js} +4 -4
  20. package/dist/embedded-app/static/2055.d938e6121e5f.chunk.js.map +1 -0
  21. package/dist/embedded-app/static/{2295.e8be8ba6c18d.chunk.js → 2295.aaedbca4c1c5.chunk.js} +2 -2
  22. package/dist/embedded-app/static/2295.aaedbca4c1c5.chunk.js.map +1 -0
  23. package/dist/embedded-app/static/2360.806f2e1ab212.chunk.js +2 -0
  24. package/dist/embedded-app/static/2360.806f2e1ab212.chunk.js.map +1 -0
  25. package/dist/embedded-app/static/3554.78dd0c182f6c.chunk.js +2 -0
  26. package/dist/embedded-app/static/3554.78dd0c182f6c.chunk.js.map +1 -0
  27. package/dist/embedded-app/static/4587.d1220800a7d6.chunk.js +2 -0
  28. package/dist/embedded-app/static/4587.d1220800a7d6.chunk.js.map +1 -0
  29. package/dist/embedded-app/static/4591.d741c025cb8a.chunk.js +2 -0
  30. package/dist/embedded-app/static/4591.d741c025cb8a.chunk.js.map +1 -0
  31. package/dist/embedded-app/static/4609.b1c67dc7cac2.chunk.js +531 -0
  32. package/dist/embedded-app/static/4609.b1c67dc7cac2.chunk.js.map +1 -0
  33. package/dist/embedded-app/static/4648.cd5b8df48435.chunk.js +2 -0
  34. package/dist/embedded-app/static/4648.cd5b8df48435.chunk.js.map +1 -0
  35. package/dist/embedded-app/static/6138.f15d6245c80d.chunk.js +2 -0
  36. package/dist/embedded-app/static/6138.f15d6245c80d.chunk.js.map +1 -0
  37. package/dist/embedded-app/static/6206.3e7f13e11c59.chunk.js +2 -0
  38. package/dist/embedded-app/static/6206.3e7f13e11c59.chunk.js.map +1 -0
  39. package/dist/embedded-app/static/6949.beeb90ede97f.chunk.js +4 -0
  40. package/dist/embedded-app/static/6949.beeb90ede97f.chunk.js.map +1 -0
  41. package/dist/embedded-app/static/7203.8b3d94b34b16.chunk.js +2 -0
  42. package/dist/embedded-app/static/7203.8b3d94b34b16.chunk.js.map +1 -0
  43. package/dist/embedded-app/static/8877.ab3d98868650.chunk.js +2 -0
  44. package/dist/embedded-app/static/8877.ab3d98868650.chunk.js.map +1 -0
  45. package/dist/embedded-app/static/9050.bd63e0a33f06.chunk.js +2 -0
  46. package/dist/embedded-app/static/9050.bd63e0a33f06.chunk.js.map +1 -0
  47. package/dist/embedded-app/static/9230.422824f655e0.chunk.js +2 -0
  48. package/dist/embedded-app/static/9230.422824f655e0.chunk.js.map +1 -0
  49. package/dist/embedded-app/static/main.9b48363c4ffa.js +2 -0
  50. package/dist/embedded-app/static/main.9b48363c4ffa.js.map +1 -0
  51. package/dist/embedded-app/static/module-remix-run.32d1d7665115.js +2 -0
  52. package/dist/embedded-app/static/module-remix-run.32d1d7665115.js.map +1 -0
  53. package/dist/embedded-app/static/{runtime.c8854f4ed6f8.js → runtime.720cb48cd7ae.js} +2 -2
  54. package/dist/embedded-app/static/{runtime.c8854f4ed6f8.js.map → runtime.720cb48cd7ae.js.map} +1 -1
  55. package/dist/embedded-app/static/vendor.470d3e8ecef1.js +2 -0
  56. package/dist/embedded-app/static/vendor.470d3e8ecef1.js.map +1 -0
  57. package/dist/lib/etag.cjs.js +40 -0
  58. package/dist/lib/etag.cjs.js.map +1 -0
  59. package/dist/package.json.cjs.js +1 -1
  60. package/package.json +8 -7
  61. package/dist/embedded-app/static/123.449f4a83fd2b.chunk.js +0 -2
  62. package/dist/embedded-app/static/123.449f4a83fd2b.chunk.js.map +0 -1
  63. package/dist/embedded-app/static/1659.41bf35e59592.chunk.js +0 -2
  64. package/dist/embedded-app/static/1659.41bf35e59592.chunk.js.map +0 -1
  65. package/dist/embedded-app/static/1749.75c83d8a41f6.chunk.js +0 -2
  66. package/dist/embedded-app/static/1749.75c83d8a41f6.chunk.js.map +0 -1
  67. package/dist/embedded-app/static/1994.78042a47b6c6.chunk.js +0 -2
  68. package/dist/embedded-app/static/1994.78042a47b6c6.chunk.js.map +0 -1
  69. package/dist/embedded-app/static/2055.fd3ccf91ac47.chunk.js.map +0 -1
  70. package/dist/embedded-app/static/2295.e8be8ba6c18d.chunk.js.map +0 -1
  71. package/dist/embedded-app/static/2360.82e9c38bff17.chunk.js +0 -2
  72. package/dist/embedded-app/static/2360.82e9c38bff17.chunk.js.map +0 -1
  73. package/dist/embedded-app/static/3554.bb882f8e4aea.chunk.js +0 -2
  74. package/dist/embedded-app/static/3554.bb882f8e4aea.chunk.js.map +0 -1
  75. package/dist/embedded-app/static/4587.96f03715ec4f.chunk.js +0 -2
  76. package/dist/embedded-app/static/4587.96f03715ec4f.chunk.js.map +0 -1
  77. package/dist/embedded-app/static/4591.5563e3a7aea4.chunk.js +0 -2
  78. package/dist/embedded-app/static/4591.5563e3a7aea4.chunk.js.map +0 -1
  79. package/dist/embedded-app/static/4609.152f14ef4904.chunk.js +0 -531
  80. package/dist/embedded-app/static/4609.152f14ef4904.chunk.js.map +0 -1
  81. package/dist/embedded-app/static/4648.c047b78345c6.chunk.js +0 -2
  82. package/dist/embedded-app/static/4648.c047b78345c6.chunk.js.map +0 -1
  83. package/dist/embedded-app/static/6138.113ed7a1d8cd.chunk.js +0 -2
  84. package/dist/embedded-app/static/6138.113ed7a1d8cd.chunk.js.map +0 -1
  85. package/dist/embedded-app/static/6206.b2713857572e.chunk.js +0 -2
  86. package/dist/embedded-app/static/6206.b2713857572e.chunk.js.map +0 -1
  87. package/dist/embedded-app/static/6949.62c7fa0aab7f.chunk.js +0 -4
  88. package/dist/embedded-app/static/6949.62c7fa0aab7f.chunk.js.map +0 -1
  89. package/dist/embedded-app/static/7203.6e3ffa800885.chunk.js +0 -2
  90. package/dist/embedded-app/static/7203.6e3ffa800885.chunk.js.map +0 -1
  91. package/dist/embedded-app/static/8877.58093d2c2ba0.chunk.js +0 -2
  92. package/dist/embedded-app/static/8877.58093d2c2ba0.chunk.js.map +0 -1
  93. package/dist/embedded-app/static/9050.0c0d51ee0fd8.chunk.js +0 -2
  94. package/dist/embedded-app/static/9050.0c0d51ee0fd8.chunk.js.map +0 -1
  95. package/dist/embedded-app/static/9230.ba752de28896.chunk.js +0 -2
  96. package/dist/embedded-app/static/9230.ba752de28896.chunk.js.map +0 -1
  97. package/dist/embedded-app/static/main.82ddbc06e504.js +0 -2
  98. package/dist/embedded-app/static/main.82ddbc06e504.js.map +0 -1
  99. package/dist/embedded-app/static/module-remix-run.0c80eb31316a.js +0 -2
  100. package/dist/embedded-app/static/module-remix-run.0c80eb31316a.js.map +0 -1
  101. package/dist/embedded-app/static/vendor.3bc2778face5.js +0 -2
  102. package/dist/embedded-app/static/vendor.3bc2778face5.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"static/6206.b2713857572e.chunk.js","sources":["webpack://techdocs-cli-embedded-app/../catalog-model/src/model/jsonSchema/getAjv.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/createCatalogModelLayer.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/jsonSchema/util.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/jsonSchema/validateMetaSchema.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/jsonSchema/zod.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/declareAnnotation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/declareKind.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/jsonSchema/reduceKindSchema.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/jsonSchema/validateKindRootSchemaSemantics.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/declareKindVersion.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/addKindVersion.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/declareLabel.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/declareRelation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/removeAnnotation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/removeKind.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/removeLabel.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/removeTag.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/declareTag.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/updateAnnotation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/updateKind.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/updateKindVersion.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/updateLabel.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/updateRelation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/operations/updateTag.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/types.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/createCatalogModelLayerBuilder.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/addKind.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/updateKind.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/removeKind.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/addRelationPair.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/updateRelationPair.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/addAnnotation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/updateAnnotation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/removeAnnotation.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/addLabel.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/updateLabel.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/removeLabel.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/addTag.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/updateTag.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/model/modelActions/removeTag.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/kinds/relations.ts","webpack://techdocs-cli-embedded-app/../ui/src/components/Card/Card.module.css?7524","webpack://techdocs-cli-embedded-app/../ui/src/components/Card/definition.ts","webpack://techdocs-cli-embedded-app/../ui/src/components/Card/Card.tsx","webpack://techdocs-cli-embedded-app/../ui/src/components/Grid/Grid.module.css?1013","webpack://techdocs-cli-embedded-app/../ui/src/components/Grid/definition.ts","webpack://techdocs-cli-embedded-app/../ui/src/components/Grid/Grid.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityInfoCard/EntityInfoCard.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/utils/getEntityRelations.ts","webpack://techdocs-cli-embedded-app/json|/home/runner/work/publishing/publishing/packages/catalog-model/src/schema/Entity.schema.json","webpack://techdocs-cli-embedded-app/json|/home/runner/work/publishing/publishing/packages/catalog-model/src/schema/EntityEnvelope.schema.json","webpack://techdocs-cli-embedded-app/json|/home/runner/work/publishing/publishing/packages/catalog-model/src/schema/EntityMeta.schema.json","webpack://techdocs-cli-embedded-app/json|/home/runner/work/publishing/publishing/packages/catalog-model/src/schema/shared/common.schema.json","webpack://techdocs-cli-embedded-app/../catalog-model/src/validation/ajv.ts","webpack://techdocs-cli-embedded-app/../catalog-model/src/validation/entityKindSchemaValidator.ts","webpack://techdocs-cli-embedded-app/json|/home/runner/work/publishing/publishing/plugins/scaffolder-common/src/Template.v1beta3.schema.json","webpack://techdocs-cli-embedded-app/../../plugins/scaffolder-common/src/permissions.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/AboutCard/AboutField.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/AboutCard/AboutContent.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/AboutCard/AboutCard.tsx","webpack://techdocs-cli-embedded-app/../../plugins/scaffolder-common/src/TemplateEntityV1beta3.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/AboutCard/hooks.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/EntityLinksCard/IconLink.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/EntityLinksCard/useDynamicColumns.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/EntityLinksCard/LinksGridList.tsx"],"sourcesContent":["/*\n * Copyright 2026 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 Ajv from 'ajv';\nimport ajvErrors from 'ajv-errors';\n\n/**\n * Gets a singleton instance of Ajv.\n */\nexport const getAjv = (() => {\n let instance: Ajv | undefined = undefined;\n\n return () => {\n if (!instance) {\n instance = new Ajv({\n allowUnionTypes: true,\n allErrors: true,\n validateSchema: true,\n });\n ajvErrors(instance);\n }\n return instance;\n };\n})();\n","/*\n * Copyright 2026 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 CatalogModelLayerBuilder,\n createCatalogModelLayerBuilder,\n} from './createCatalogModelLayerBuilder';\nimport { CatalogModelLayer } from './types';\n\n/**\n * Creates a catalog model layer using a builder pattern.\n *\n * @alpha\n * @remarks\n *\n * Plugins can create such catalog model layers to declare various\n * contributions to the overall catalog model, and registering them with the\n * catalog which then forms a complete picture out of them.\n */\nexport function createCatalogModelLayer(options: {\n /**\n * The unique ID of the model layer.\n *\n * @remarks\n * @example `example.com/MyCustomKind`\n *\n * This identifier is used for purposes of deduplication and tracking. It is\n * expected to be stable and descriptive. Prefer prefixing the ID with a\n * matching domain name. The backstage.io domain name is reserved for use by\n * the Backstage project itself.\n */\n layerId: string;\n builder: (model: CatalogModelLayerBuilder) => void;\n}): CatalogModelLayer {\n const b = createCatalogModelLayerBuilder({\n layerId: options.layerId,\n });\n options.builder(b);\n return b.build();\n}\n","/*\n * Copyright 2026 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 { JsonObject } from '@backstage/types';\n\n/**\n * Asserts that the value is a JSON object shallowly.\n */\nexport function isJsonObject(value?: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Asserts that the value is a JSON object recursively containing only JSON safe\n * values and no circular references.\n */\nexport function isJsonObjectDeep(value: unknown): value is JsonObject {\n if (!isJsonObject(value)) {\n return false;\n }\n const seen = new Set<unknown>();\n return Object.values(value).every(v => isJsonValueDeep(v, seen));\n}\n\nfunction isJsonValueDeep(value: unknown, seen: Set<unknown>): boolean {\n if (\n value === null ||\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return true;\n }\n if (typeof value !== 'object') {\n return false;\n }\n if (seen.has(value)) {\n return false;\n }\n seen.add(value);\n if (Array.isArray(value)) {\n return value.every(v => isJsonValueDeep(v, seen));\n }\n if (isJsonObject(value)) {\n return Object.values(value).every(v => isJsonValueDeep(v, seen));\n }\n return false;\n}\n","/*\n * Copyright 2026 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 { type SchemaObject } from 'ajv';\nimport { isJsonObject } from './util';\nimport { InputError } from '@backstage/errors';\nimport { getAjv } from './getAjv';\n\n/**\n * Validates that the schema is valid according to known JSON Schema meta\n * schemas - does not perform any semantic validation beyond that.\n */\nexport function validateMetaSchema(schema: unknown): schema is SchemaObject {\n if (!isJsonObject(schema) || typeof schema.then === 'function') {\n throw new InputError('Invalid JSON schema: must be an object');\n }\n\n const ajv = getAjv();\n try {\n const result = ajv.validateSchema(schema);\n if (typeof result !== 'boolean') {\n // Should not happen; the function is expected to return a promise only\n // for async schemas, but since that's not enforced at the typescript\n // level we add the extra check just to be sure\n throw new InputError('Expected synchronous validation result');\n }\n } catch (error) {\n throw new InputError(`Invalid JSON schema: ${error}`);\n }\n\n // The full set of errors is typically too complex to report; just pick the\n // first one.\n const error = ajv.errors?.[0];\n if (error) {\n let message = error.message;\n if (Array.isArray(error?.params?.allowedValues)) {\n message += `, expected one of: ${error.params.allowedValues.join(', ')}`;\n }\n throw new InputError(\n `Invalid JSON schema, error at path ${error.instancePath}: ${message}`,\n );\n }\n\n return true;\n}\n","/*\n * Copyright 2026 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 { isError } from '@backstage/errors';\nimport { JsonObject } from '@backstage/types';\nimport { z } from 'zod/v3';\nimport { isJsonObjectDeep } from './util';\nimport { validateMetaSchema } from './validateMetaSchema';\n\nexport const jsonObjectSchema = z\n .record(z.string(), z.unknown())\n .refine((x): x is JsonObject => isJsonObjectDeep(x), {\n message: 'Invalid JSON schema',\n });\n\nexport const jsonSchemaSchema = z\n .record(z.string(), z.unknown())\n .superRefine((x, ctx): x is JsonObject => {\n try {\n return validateMetaSchema(x);\n } catch (error) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: isError(error) ? error.message : 'Invalid JSON schema',\n });\n return false;\n }\n });\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\nimport { jsonSchemaSchema } from '../jsonSchema/zod';\n\n/**\n * Declare the existence of a well-known annotation and its properties.\n */\nexport const opDeclareAnnotationV1Schema = z.strictObject({\n op: z.literal('declareAnnotation.v1'),\n /**\n * The name of the annotation, e.g. \"backstage.io/techdocs-ref\".\n */\n name: z.string(),\n\n /**\n * The properties that apply to this annotation.\n */\n properties: z.strictObject({\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title: z.string().optional(),\n /**\n * A human-readable description of the annotation.\n */\n description: z.string(),\n /**\n * The JSON schema that values of this annotation must conform to.\n *\n * @remarks\n *\n * If not provided, the annotation is assumed to be a simple string with no\n * particular schema.\n */\n schema: z\n .strictObject({\n jsonSchema: jsonSchemaSchema,\n })\n .optional(),\n }),\n});\n\n/** {@inheritDoc opDeclareAnnotationV1Schema} */\nexport type OpDeclareAnnotationV1 = z.infer<typeof opDeclareAnnotationV1Schema>;\n\n/**\n * Creates a validated {@link OpDeclareAnnotationV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpDeclareAnnotationV1}.\n */\nexport function createDeclareAnnotationOp(\n input: Omit<OpDeclareAnnotationV1, 'op'> & { op?: never },\n): OpDeclareAnnotationV1 {\n return opDeclareAnnotationV1Schema.parse({\n ...input,\n op: 'declareAnnotation.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Make a declaration about the properties of a certain kind.\n */\nexport const opDeclareKindV1Schema = z.strictObject({\n op: z.literal('declareKind.v1'),\n\n /**\n * The kind to declare, e.g. \"Component\".\n */\n kind: z.string(),\n /**\n * The apiVersion group of the kind, e.g. \"backstage.io\".\n */\n group: z.string(),\n\n /**\n * Properties that apply for this kind\n */\n properties: z.strictObject({\n /**\n * The singular form of the human-readable kind, e.g. \"component\".\n */\n singular: z.string(),\n /**\n * The plural form of the human-readable kind, e.g. \"components\".\n */\n plural: z.string(),\n /**\n * Short description of the kind.\n */\n description: z.string(),\n }),\n});\n\n/** {@inheritDoc opDeclareKindV1Schema} */\nexport type OpDeclareKindV1 = z.infer<typeof opDeclareKindV1Schema>;\n\n/**\n * Creates a validated {@link OpDeclareKindV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpDeclareKindV1}.\n */\nexport function createDeclareKindOp(\n input: Omit<OpDeclareKindV1, 'op'> & { op?: never },\n): OpDeclareKindV1 {\n return opDeclareKindV1Schema.parse({ ...input, op: 'declareKind.v1' });\n}\n","/*\n * Copyright 2026 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 { JsonObject } from '@backstage/types';\nimport { z } from 'zod/v3';\nimport { CatalogModelKindRootSchema } from './validateKindRootSchemaSemantics';\n\n/**\n * The expected shape of the standard full kind schemas, which use an allOf\n * with a $ref to Entity and a second element with the kind-specific schema.\n */\nconst fullKindSchema = z\n .object({\n allOf: z.tuple([\n z.object({ $ref: z.literal('Entity') }),\n z\n .object({\n type: z.literal('object'),\n properties: z\n .object({\n apiVersion: z.record(z.string(), z.unknown()).optional(),\n kind: z.record(z.string(), z.unknown()).optional(),\n })\n .passthrough(),\n })\n .passthrough(),\n ]),\n })\n .passthrough();\n\n/**\n * Reduces a full kind JSON schema to the form expected by the catalog model\n * layer system. The full schemas use an allOf with a $ref to Entity and\n * kind/apiVersion constraints that are not needed in the reduced form.\n *\n * If the schema does not match the expected shape, it is returned unchanged.\n */\nexport function reduceKindSchema(\n schema: JsonObject,\n): CatalogModelKindRootSchema {\n const parsed = fullKindSchema.safeParse(schema);\n if (!parsed.success) {\n return schema as CatalogModelKindRootSchema;\n }\n\n const { allOf, ...rest } = parsed.data;\n const { type, properties: allProperties, ...kindRest } = allOf[1];\n const { apiVersion, kind, ...properties } = allProperties;\n\n return {\n ...rest,\n type,\n ...kindRest,\n properties,\n } as CatalogModelKindRootSchema;\n}\n","/*\n * Copyright 2026 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 { InputError } from '@backstage/errors';\nimport { JsonObject, JsonValue } from '@backstage/types';\nimport { isJsonObject, isJsonObjectDeep } from './util';\n\nconst FORBIDDEN_SCHEMA_ROOT_FIELDS = [\n 'kind',\n 'apiVersion',\n 'metadata',\n '$ref',\n] as const;\nconst FORBIDDEN_SCHEMA_STRUCTURAL_FIELDS = [\n 'allOf',\n 'oneOf',\n 'anyOf',\n 'if',\n 'else',\n 'then',\n 'not',\n '$ref',\n] as const;\n\n/**\n * When declaring the JSON schema model for a kind, this is the type that you\n * should abide by.\n *\n * @alpha\n * @remarks\n *\n * It forbids some patterns that would make the schema hard or impossible to\n * inspect / merge properly.\n */\nexport interface CatalogModelKindRootSchema extends JsonObject {\n type: 'object';\n\n // NOTE: These should match the FORBIDDEN_SCHEMA_STRUCTURAL_FIELDS list above\n allOf?: never;\n anyOf?: never;\n oneOf?: never;\n if?: never;\n then?: never;\n else?: never;\n not?: never;\n $ref?: never;\n\n properties?:\n | undefined\n | {\n // NOTE: These should match the FORBIDDEN_SCHEMA_ROOT_FIELDS list above\n kind?: never;\n apiVersion?: never;\n metadata?: never;\n $ref?: never;\n\n [key: string]:\n | undefined\n | {\n // NOTE: These should match the FORBIDDEN_SCHEMA_STRUCTURAL_FIELDS list above\n allOf?: never;\n anyOf?: never;\n oneOf?: never;\n if?: never;\n then?: never;\n else?: never;\n not?: never;\n $ref?: never;\n\n [key: string]: JsonValue | undefined;\n };\n };\n\n [key: string]: JsonValue | undefined;\n}\n\n/**\n * Validates that the semantics of a schema describing a kind follows semantic\n * rules.\n *\n * @remarks\n *\n * It's expected that the input is a valid JSON Schema, as in having been\n * validated by `validateMetaSchema` already.\n *\n * The schema must not try to explicitly declare certain readonly root fields,\n * and neither the root nor the top level keys of fields may use certain\n * structural keywords that makes the schema hard or impossible to inspect /\n * merge properly.\n *\n * @param schema - The schema to validate.\n */\nexport function validateKindRootSchemaSemantics(\n schema: unknown,\n): schema is CatalogModelKindRootSchema {\n if (!isJsonObjectDeep(schema)) {\n throw new InputError('Schema must be an object');\n }\n\n for (const field of FORBIDDEN_SCHEMA_STRUCTURAL_FIELDS) {\n if (field in schema) {\n throw new InputError(\n `Schema must not use \"${field}\" keyword in the root`,\n );\n }\n }\n\n const rootProperties = schema.properties;\n if (!isJsonObject(rootProperties)) {\n throw new InputError(\n 'Schema must have a \"properties\" field that is an object',\n );\n }\n\n for (const field of FORBIDDEN_SCHEMA_ROOT_FIELDS) {\n if (field in rootProperties) {\n throw new InputError(\n `Schema must not try to declare the reserved root field \"${field}\"`,\n );\n }\n }\n\n for (const [fieldName, fieldSchema] of Object.entries(rootProperties)) {\n if (!isJsonObject(fieldSchema)) {\n throw new InputError(\n `Schema for root field \"${fieldName}\" must be an object`,\n );\n }\n for (const field of FORBIDDEN_SCHEMA_STRUCTURAL_FIELDS) {\n if (field in fieldSchema) {\n throw new InputError(\n `Schema for root field \"${fieldName}\" must not use \"${field}\" keyword`,\n );\n }\n }\n }\n\n return true;\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\nimport { jsonSchemaSchema } from '../jsonSchema/zod';\n\nconst relationFieldSchema = z.strictObject({\n /**\n * What field that shall be used to generate relations.\n *\n * @remarks\n *\n * The field value is expected to be a string or string array at runtime.\n */\n selector: z.strictObject({\n /**\n * A dot separated path on the common catalog form, e.g. `spec.owner`.\n */\n path: z.string(),\n }),\n /**\n * The relation type that this field generates, e.g. \"ownedBy\".\n */\n relation: z.string(),\n /**\n * If the given shorthand ref did not have a kind, use this kind as the\n * default. If no default kind is specified, the ref must contain a kind.\n */\n defaultKind: z.string().optional(),\n /**\n * If the given shorthand ref did not have a namespace, either inherit the\n * namespace of the entity itself, or choose the default namespace.\n */\n defaultNamespace: z.enum(['default', 'inherit']).optional(),\n /**\n * Only allow relations to be specified to the given kinds. This list must\n * include the default kind, if any. If no allowed kinds are specified,\n * all kinds are allowed.\n */\n allowedKinds: z.array(z.string()).optional(),\n});\n\n/**\n * Make a declaration about the version of a certain kind.\n */\nexport const opDeclareKindVersionV1Schema = z.strictObject({\n op: z.literal('declareKindVersion.v1'),\n\n /**\n * The kind that this version belongs to.\n */\n kind: z.string(),\n /**\n * The specific version name, e.g. \"v1alpha1\". This and the kind group form\n * the full apiVersion.\n */\n name: z.string(),\n /**\n * The spec type that this version applies to, if any.\n *\n * @remarks\n *\n * This can be used to make kinds whose spec effectively are discriminated\n * unions. If you don't specify this, the schema will apply to a spec that has\n * no type given at all, or to those where the type is not among the set of\n * any other known declared spec types.\n */\n specType: z.string().optional(),\n\n /**\n * The properties that apply to this version.\n */\n properties: z.strictObject({\n /**\n * A short description of this particular version (and type, where applicable).\n */\n description: z.string().optional(),\n\n /**\n * The fields that shall be used to generate relations, if any.\n */\n relationFields: z.array(relationFieldSchema).optional(),\n\n /**\n * The JSON schema of the version.\n */\n schema: z.strictObject({\n jsonSchema: jsonSchemaSchema,\n }),\n }),\n});\n\n/** {@inheritDoc opDeclareKindVersionV1Schema} */\nexport type OpDeclareKindVersionV1 = z.infer<\n typeof opDeclareKindVersionV1Schema\n>;\n\n/**\n * Creates a validated {@link OpDeclareKindVersionV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpDeclareKindVersionV1}.\n */\nexport function createDeclareKindVersionOp(\n input: Omit<OpDeclareKindVersionV1, 'op'> & { op?: never },\n): OpDeclareKindVersionV1 {\n return opDeclareKindVersionV1Schema.parse({\n ...input,\n op: 'declareKindVersion.v1',\n });\n}\n","/*\n * Copyright 2026 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 { reduceKindSchema } from '../jsonSchema/reduceKindSchema';\nimport { validateKindRootSchemaSemantics } from '../jsonSchema/validateKindRootSchemaSemantics';\nimport { validateMetaSchema } from '../jsonSchema/validateMetaSchema';\nimport { CatalogModelOp } from '../operations';\nimport { createDeclareKindVersionOp } from '../operations/declareKindVersion';\nimport type { CatalogModelKindVersionDefinition } from './addKind';\n\n/**\n * The definition for adding one or more versions to an already-declared kind.\n *\n * @alpha\n */\nexport interface CatalogModelAddKindVersionDefinition {\n /**\n * The kind to add versions to, e.g. \"API\".\n */\n kind: string;\n\n /**\n * The versions to add.\n */\n versions: CatalogModelKindVersionDefinition[];\n}\n\nexport function opsFromCatalogModelAddKindVersion(\n definition: CatalogModelAddKindVersionDefinition,\n): CatalogModelOp[] {\n const ops: CatalogModelOp[] = [];\n\n for (const version of definition.versions) {\n const jsonSchema = reduceKindSchema(version.schema.jsonSchema);\n validateMetaSchema(jsonSchema);\n validateKindRootSchemaSemantics(jsonSchema);\n const names = Array.isArray(version.name) ? version.name : [version.name];\n for (const name of names) {\n const specTypes = version.specType\n ? [version.specType].flat()\n : [undefined];\n for (const specType of specTypes) {\n ops.push(\n createDeclareKindVersionOp({\n kind: definition.kind,\n name,\n specType: specType,\n properties: {\n description: version.description,\n relationFields: version.relationFields,\n schema: {\n jsonSchema: jsonSchema as any,\n },\n },\n }),\n );\n }\n }\n }\n\n return ops;\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\nimport { jsonSchemaSchema } from '../jsonSchema/zod';\n\n/**\n * Declare the existence of a well-known label and its properties.\n */\nexport const opDeclareLabelV1Schema = z.strictObject({\n op: z.literal('declareLabel.v1'),\n /**\n * The name of the label, e.g. \"backstage.io/source-location\".\n */\n name: z.string(),\n\n /**\n * The properties that apply to this label.\n */\n properties: z.strictObject({\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title: z.string().optional(),\n /**\n * A human-readable description of the label.\n */\n description: z.string(),\n /**\n * The JSON schema that values of this label must conform to.\n *\n * @remarks\n *\n * If not provided, the label is assumed to be a simple string with no\n * particular schema.\n */\n schema: z\n .strictObject({\n jsonSchema: jsonSchemaSchema,\n })\n .optional(),\n }),\n});\n\n/** {@inheritDoc opDeclareLabelV1Schema} */\nexport type OpDeclareLabelV1 = z.infer<typeof opDeclareLabelV1Schema>;\n\n/**\n * Creates a validated {@link OpDeclareLabelV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpDeclareLabelV1}.\n */\nexport function createDeclareLabelOp(\n input: Omit<OpDeclareLabelV1, 'op'> & { op?: never },\n): OpDeclareLabelV1 {\n return opDeclareLabelV1Schema.parse({\n ...input,\n op: 'declareLabel.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Make a declaration about the properties of a certain relation type between a\n * given pair of kinds.\n *\n * @remarks\n *\n * Note that this is NOT the same as declaring that a certain field is a\n * relation type - it declares that IF a relation was generated between two\n * kinds for any reason, then these properties apply to it.\n */\nexport const opDeclareRelationV1Schema = z.strictObject({\n op: z.literal('declareRelation.v1'),\n /**\n * The kind that this relation originates from, e.g. \"Component\".\n */\n fromKind: z.string(),\n /**\n * The technical type of the relation, e.g. \"ownedBy\".\n */\n type: z.string(),\n /**\n * The kind that this relation points to, e.g. \"Group\".\n */\n toKind: z.string(),\n\n /**\n * The properties that apply to this relation.\n */\n properties: z.strictObject({\n /**\n * The technical type of the reverse relation, e.g. \"ownerOf\".\n */\n reverseType: z.string(),\n /**\n * A human-readable title for the relation type, e.g. \"owned by\".\n */\n title: z.string(),\n /**\n * A human-readable description of the relation.\n */\n description: z.string(),\n }),\n});\n\n/** {@inheritDoc opDeclareRelationV1Schema} */\nexport type OpDeclareRelationV1 = z.infer<typeof opDeclareRelationV1Schema>;\n\n/**\n * Creates a validated {@link OpDeclareRelationV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpDeclareRelationV1}.\n */\nexport function createDeclareRelationOp(\n input: Omit<OpDeclareRelationV1, 'op'> & { op?: never },\n): OpDeclareRelationV1 {\n return opDeclareRelationV1Schema.parse({\n ...input,\n op: 'declareRelation.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Remove an annotation from the model.\n */\nexport const opRemoveAnnotationV1Schema = z.strictObject({\n op: z.literal('removeAnnotation.v1'),\n\n /**\n * The name of the annotation to remove, e.g. \"backstage.io/techdocs-ref\".\n */\n name: z.string(),\n});\n\n/** {@inheritDoc opRemoveAnnotationV1Schema} */\nexport type OpRemoveAnnotationV1 = z.infer<typeof opRemoveAnnotationV1Schema>;\n\n/**\n * Creates a validated {@link OpRemoveAnnotationV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpRemoveAnnotationV1}.\n */\nexport function createRemoveAnnotationOp(\n input: Omit<OpRemoveAnnotationV1, 'op'> & { op?: never },\n): OpRemoveAnnotationV1 {\n return opRemoveAnnotationV1Schema.parse({\n ...input,\n op: 'removeAnnotation.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Remove a kind entirely from the model.\n */\nexport const opRemoveKindV1Schema = z.strictObject({\n op: z.literal('removeKind.v1'),\n\n /**\n * The kind to remove, e.g. \"Component\".\n */\n kind: z.string(),\n});\n\n/** {@inheritDoc opRemoveKindV1Schema} */\nexport type OpRemoveKindV1 = z.infer<typeof opRemoveKindV1Schema>;\n\n/**\n * Creates a validated {@link OpRemoveKindV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpRemoveKindV1}.\n */\nexport function createRemoveKindOp(\n input: Omit<OpRemoveKindV1, 'op'> & { op?: never },\n): OpRemoveKindV1 {\n return opRemoveKindV1Schema.parse({ ...input, op: 'removeKind.v1' });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Remove a label from the model.\n */\nexport const opRemoveLabelV1Schema = z.strictObject({\n op: z.literal('removeLabel.v1'),\n\n /**\n * The name of the label to remove, e.g. \"backstage.io/source-location\".\n */\n name: z.string(),\n});\n\n/** {@inheritDoc opRemoveLabelV1Schema} */\nexport type OpRemoveLabelV1 = z.infer<typeof opRemoveLabelV1Schema>;\n\n/**\n * Creates a validated {@link OpRemoveLabelV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpRemoveLabelV1}.\n */\nexport function createRemoveLabelOp(\n input: Omit<OpRemoveLabelV1, 'op'> & { op?: never },\n): OpRemoveLabelV1 {\n return opRemoveLabelV1Schema.parse({ ...input, op: 'removeLabel.v1' });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Remove a tag from the model.\n */\nexport const opRemoveTagV1Schema = z.strictObject({\n op: z.literal('removeTag.v1'),\n\n /**\n * The name of the tag to remove, e.g. \"java\".\n */\n name: z.string(),\n});\n\n/** {@inheritDoc opRemoveTagV1Schema} */\nexport type OpRemoveTagV1 = z.infer<typeof opRemoveTagV1Schema>;\n\n/**\n * Creates a validated {@link OpRemoveTagV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpRemoveTagV1}.\n */\nexport function createRemoveTagOp(\n input: Omit<OpRemoveTagV1, 'op'> & { op?: never },\n): OpRemoveTagV1 {\n return opRemoveTagV1Schema.parse({ ...input, op: 'removeTag.v1' });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Declare the existence of a well-known tag and its properties.\n */\nexport const opDeclareTagV1Schema = z.strictObject({\n op: z.literal('declareTag.v1'),\n /**\n * The name of the tag, e.g. \"java\".\n */\n name: z.string(),\n\n /**\n * The properties that apply to this tag.\n */\n properties: z.strictObject({\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title: z.string().optional(),\n /**\n * A human-readable description of the tag.\n */\n description: z.string(),\n }),\n});\n\n/** {@inheritDoc opDeclareTagV1Schema} */\nexport type OpDeclareTagV1 = z.infer<typeof opDeclareTagV1Schema>;\n\n/**\n * Creates a validated {@link OpDeclareTagV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpDeclareTagV1}.\n */\nexport function createDeclareTagOp(\n input: Omit<OpDeclareTagV1, 'op'> & { op?: never },\n): OpDeclareTagV1 {\n return opDeclareTagV1Schema.parse({\n ...input,\n op: 'declareTag.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\nimport { jsonSchemaSchema } from '../jsonSchema/zod';\n\n/**\n * Update the properties of an existing annotation.\n */\nexport const opUpdateAnnotationV1Schema = z.strictObject({\n op: z.literal('updateAnnotation.v1'),\n\n /**\n * The name of the annotation, e.g. \"backstage.io/techdocs-ref\".\n */\n name: z.string(),\n\n /**\n * The properties that apply to this annotation.\n */\n properties: z.strictObject({\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title: z.string().optional(),\n /**\n * A human-readable description of the annotation.\n */\n description: z.string().optional(),\n /**\n * The JSON schema that values of this annotation must conform to.\n *\n * @remarks\n *\n * If not provided, the annotation is assumed to be a simple string with no\n * particular schema.\n */\n schema: z\n .strictObject({\n jsonSchema: jsonSchemaSchema,\n })\n .optional(),\n }),\n});\n\n/** {@inheritDoc opUpdateAnnotationV1Schema} */\nexport type OpUpdateAnnotationV1 = z.infer<typeof opUpdateAnnotationV1Schema>;\n\n/**\n * Creates a validated {@link OpUpdateAnnotationV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpUpdateAnnotationV1}.\n */\nexport function createUpdateAnnotationOp(\n input: Omit<OpUpdateAnnotationV1, 'op'> & { op?: never },\n): OpUpdateAnnotationV1 {\n return opUpdateAnnotationV1Schema.parse({\n ...input,\n op: 'updateAnnotation.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Make a declaration about the properties of a certain kind.\n */\nexport const opUpdateKindV1Schema = z.strictObject({\n op: z.literal('updateKind.v1'),\n\n /**\n * The kind to update, e.g. \"Component\".\n */\n kind: z.string(),\n\n /**\n * Updated properties that apply for this kind\n */\n properties: z.strictObject({\n /**\n * The singular form of the human-readable kind, e.g. \"component\".\n */\n singular: z.string().optional(),\n /**\n * The plural form of the human-readable kind, e.g. \"components\".\n */\n plural: z.string().optional(),\n /**\n * Short description of the kind.\n */\n description: z.string().optional(),\n }),\n});\n\n/** {@inheritDoc opUpdateKindV1Schema} */\nexport type OpUpdateKindV1 = z.infer<typeof opUpdateKindV1Schema>;\n\n/**\n * Creates a validated {@link OpUpdateKindV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpUpdateKindV1}.\n */\nexport function createUpdateKindOp(\n input: Omit<OpUpdateKindV1, 'op'> & { op?: never },\n): OpUpdateKindV1 {\n return opUpdateKindV1Schema.parse({ ...input, op: 'updateKind.v1' });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\nimport { jsonSchemaSchema } from '../jsonSchema/zod';\n\nconst relationFieldSchema = z.strictObject({\n /**\n * What field that shall be used to generate relations.\n *\n * @remarks\n *\n * The field value is expected to be a string or string array at runtime.\n */\n selector: z.strictObject({\n /**\n * A dot separated path on the common catalog form, e.g. `spec.owner`.\n */\n path: z.string(),\n }),\n /**\n * The relation type that this field generates, e.g. \"ownedBy\".\n */\n relation: z.string(),\n /**\n * If the given shorthand ref did not have a kind, use this kind as the\n * default. If no default kind is specified, the ref must contain a kind.\n */\n defaultKind: z.string().optional(),\n /**\n * If the given shorthand ref did not have a namespace, either inherit the\n * namespace of the entity itself, or choose the default namespace.\n */\n defaultNamespace: z.enum(['default', 'inherit']).optional(),\n /**\n * Only allow relations to be specified to the given kinds. This list must\n * include the default kind, if any. If no allowed kinds are specified,\n * all kinds are allowed.\n */\n allowedKinds: z.array(z.string()).optional(),\n});\n\n/**\n * Make an update to a pre-existing version of a certain kind.\n */\nexport const opUpdateKindVersionV1Schema = z.strictObject({\n op: z.literal('updateKindVersion.v1'),\n\n /**\n * The kind that this version belongs to.\n */\n kind: z.string(),\n /**\n * The specific version name, e.g. \"v1alpha1\". This and the kind group form\n * the full apiVersion.\n */\n name: z.string(),\n /**\n * The spec type that this version applies to, if any.\n *\n * @remarks\n *\n * This can be used to make kinds whose spec effectively are discriminated\n * unions. If you don't specify this, the schema will apply to a spec that has\n * no type given at all, or to those where the type is not among the set of\n * any other known declared spec types.\n */\n specType: z.string().optional(),\n\n /**\n * The properties that apply to this version update.\n */\n properties: z.strictObject({\n /**\n * A short description of this particular version (and type, where\n * applicable). Specify this if you want to override the default value.\n */\n description: z.string().optional(),\n\n /**\n * The fields that shall be used to generate relations, if any. Specify this\n * if you want to override the default value.\n */\n relationFields: z.array(relationFieldSchema).optional(),\n\n /**\n * The JSON schema of the version. Specify this if you want to override the\n * default value.\n *\n * @remarks\n *\n * This schema gets deep merged with the default one for this version. It\n * can therefore be used for both amending and changing existing fields.\n */\n schema: z\n .strictObject({\n jsonSchema: jsonSchemaSchema,\n })\n .optional(),\n }),\n});\n\n/** {@inheritDoc opUpdateKindVersionV1Schema} */\nexport type OpUpdateKindVersionV1 = z.infer<typeof opUpdateKindVersionV1Schema>;\n\n/**\n * Creates a validated {@link OpUpdateKindVersionV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpUpdateKindVersionV1}.\n */\nexport function createUpdateKindVersionOp(\n input: Omit<OpUpdateKindVersionV1, 'op'> & { op?: never },\n): OpUpdateKindVersionV1 {\n return opUpdateKindVersionV1Schema.parse({\n ...input,\n op: 'updateKindVersion.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\nimport { jsonSchemaSchema } from '../jsonSchema/zod';\n\n/**\n * Update the properties of an existing label.\n */\nexport const opUpdateLabelV1Schema = z.strictObject({\n op: z.literal('updateLabel.v1'),\n\n /**\n * The name of the label, e.g. \"backstage.io/source-location\".\n */\n name: z.string(),\n\n /**\n * The properties that apply to this label.\n */\n properties: z.strictObject({\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title: z.string().optional(),\n /**\n * A human-readable description of the label.\n */\n description: z.string().optional(),\n /**\n * The JSON schema that values of this label must conform to.\n *\n * @remarks\n *\n * If not provided, the label is assumed to be a simple string with no\n * particular schema.\n */\n schema: z\n .strictObject({\n jsonSchema: jsonSchemaSchema,\n })\n .optional(),\n }),\n});\n\n/** {@inheritDoc opUpdateLabelV1Schema} */\nexport type OpUpdateLabelV1 = z.infer<typeof opUpdateLabelV1Schema>;\n\n/**\n * Creates a validated {@link OpUpdateLabelV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpUpdateLabelV1}.\n */\nexport function createUpdateLabelOp(\n input: Omit<OpUpdateLabelV1, 'op'> & { op?: never },\n): OpUpdateLabelV1 {\n return opUpdateLabelV1Schema.parse({\n ...input,\n op: 'updateLabel.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Update the properties of a certain relation type between a given pair of\n * kinds.\n *\n * @remarks\n *\n * Note that this is NOT the same as updating the properties of a certain field\n * that is a relation type - it updates the properties of a relation that was\n * generated between two kinds for any reason.\n */\nexport const opUpdateRelationV1Schema = z.strictObject({\n op: z.literal('updateRelation.v1'),\n\n /**\n * The kind that this relation originates from, e.g. \"Component\".\n */\n fromKind: z.string(),\n /**\n * The technical type of the relation, e.g. \"ownedBy\".\n */\n type: z.string(),\n /**\n * The kind that this relation points to, e.g. \"Group\".\n */\n toKind: z.string(),\n\n /**\n * The properties that apply to this relation.\n */\n properties: z.strictObject({\n /**\n * The technical type of the reverse relation, e.g. \"ownerOf\".\n */\n reverseType: z.string().optional(),\n /**\n * A human-readable title for the relation type, e.g. \"owned by\".\n */\n title: z.string().optional(),\n /**\n * A human-readable description of the relation.\n */\n description: z.string().optional(),\n }),\n});\n\n/** {@inheritDoc opUpdateRelationV1Schema} */\nexport type OpUpdateRelationV1 = z.infer<typeof opUpdateRelationV1Schema>;\n\n/**\n * Creates a validated {@link OpUpdateRelationV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpUpdateRelationV1}.\n */\nexport function createUpdateRelationOp(\n input: Omit<OpUpdateRelationV1, 'op'> & { op?: never },\n): OpUpdateRelationV1 {\n return opUpdateRelationV1Schema.parse({\n ...input,\n op: 'updateRelation.v1',\n });\n}\n","/*\n * Copyright 2026 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 { z } from 'zod/v3';\n\n/**\n * Update the properties of an existing tag.\n */\nexport const opUpdateTagV1Schema = z.strictObject({\n op: z.literal('updateTag.v1'),\n\n /**\n * The name of the tag, e.g. \"java\".\n */\n name: z.string(),\n\n /**\n * The properties that apply to this tag.\n */\n properties: z.strictObject({\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title: z.string().optional(),\n /**\n * A human-readable description of the tag.\n */\n description: z.string().optional(),\n }),\n});\n\n/** {@inheritDoc opUpdateTagV1Schema} */\nexport type OpUpdateTagV1 = z.infer<typeof opUpdateTagV1Schema>;\n\n/**\n * Creates a validated {@link OpUpdateTagV1} operation instance.\n *\n * @remarks\n *\n * The `op` field is filled in automatically. The input is verified against the\n * schema before returning, ensuring that the resulting op is reliably valid.\n *\n * @param input - All fields of the op except `op` itself.\n * @returns A fully validated {@link OpUpdateTagV1}.\n */\nexport function createUpdateTagOp(\n input: Omit<OpUpdateTagV1, 'op'> & { op?: never },\n): OpUpdateTagV1 {\n return opUpdateTagV1Schema.parse({ ...input, op: 'updateTag.v1' });\n}\n","/*\n * Copyright 2026 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 { OpaqueType } from '@internal/opaque';\nimport { CatalogModelOp } from './operations';\nimport { JsonObject } from '@backstage/types';\n\n// #region CatalogModelLayer\n\n/**\n * An opaque type that represents a set of catalog model layers.\n *\n * @alpha\n */\nexport interface CatalogModelLayer {\n readonly $$type: '@backstage/CatalogModelLayer';\n /**\n * The unique ID of the model layer.\n *\n * @remarks\n * @example `catalog.backstage.io/kind-api`\n *\n * This identifier is used for purposes of deduplication and tracking. It is\n * expected to be stable and descriptive. Prefer prefixing the ID with a\n * matching domain name. The backstage.io domain name is reserved for use by\n * the Backstage project itself.\n */\n readonly layerId: string;\n}\n\n/**\n * The opaque type that represents a catalog model layer.\n *\n * @internal\n * @remarks\n *\n * Model layers are essentially an array of operations. Several such model\n * layers are merged together to form a final outcome.\n */\nexport const OpaqueCatalogModelLayer = OpaqueType.create<{\n public: CatalogModelLayer;\n versions: {\n readonly version: 'v1';\n readonly layerId: string;\n readonly ops: Array<CatalogModelOp>;\n };\n}>({\n type: '@backstage/CatalogModelLayer',\n versions: ['v1'],\n});\n\n// #endregion\n\n// #region CatalogModel\n\n/**\n * A compiled catalog model.\n *\n * @alpha\n */\nexport interface CatalogModel {\n /**\n * Lists all kinds in the model.\n */\n listKinds(): CatalogModelKindSummary[];\n\n /**\n * Lists all relations in the model.\n */\n listRelations(): CatalogModelRelationSummary[];\n\n /**\n * Returns summaries of the shared metadata fields in the model, including\n * all declared annotations, labels, and tags.\n */\n getMetadata(): {\n annotations: CatalogModelAnnotationSummary[];\n labels: CatalogModelLabelSummary[];\n tags: CatalogModelTagSummary[];\n };\n\n /**\n * Look up a kind in the model.\n *\n * @returns The kind if found, or `undefined` if no matching kind exists.\n * @throws TypeError if the kind exists in the model, but not for this apiVersion or type.\n */\n getKind(options: {\n kind: string;\n apiVersion: string;\n spec?: { type?: string };\n }): CatalogModelKind | undefined;\n\n /**\n * Look up all relations that originate from a given kind.\n *\n * @param kind - The kind name, e.g. \"Component\".\n * @returns The relations originating from the kind, or `undefined` if the\n * kind is not known.\n */\n getRelations(options: { kind: string }): CatalogModelRelation[] | undefined;\n}\n\n// #endregion\n\n// #region CatalogModelKind\n\n/**\n * A compiled catalog model kind.\n *\n * @alpha\n */\nexport interface CatalogModelKind {\n /**\n * A human-readable description of the kind.\n */\n description: string;\n\n /**\n * The API version(s) of the kind that this schema applies to, e.g.\n * \"backstage.io/v1alpha1\".\n */\n apiVersions: string[];\n\n /**\n * The names used for this kind.\n */\n names: {\n /**\n * The name of the kind with proper casing, e.g. \"Component\".\n */\n kind: string;\n\n /**\n * The singular form of the kind name, e.g. \"component\".\n */\n singular: string;\n\n /**\n * The plural form of the kind name, e.g. \"components\".\n */\n plural: string;\n };\n\n /**\n * The relation fields declared for this kind, with full dot-separated paths\n * into the entity (e.g. \"spec.owner\").\n */\n relationFields: Array<{\n /**\n * The full dot-separated path to the field in the entity, e.g. \"spec.owner\".\n */\n path: string;\n /**\n * The relation type that this field generates, e.g. \"ownedBy\".\n */\n relation: string;\n /**\n * The default kind for parsing shorthand entity refs.\n */\n defaultKind?: string;\n /**\n * The default namespace for parsing shorthand entity refs.\n */\n defaultNamespace?: 'inherit' | 'default';\n /**\n * The kinds that are allowed as targets for this relation field.\n */\n allowedKinds?: string[];\n }>;\n\n /**\n * The JSON schema of the kind.\n *\n * @remarks\n *\n * This can be used for validation of entities. Note that it is up to the\n * caller to ensure that the kind and apiVersion match what you are validating\n * against.\n */\n jsonSchema: JsonObject;\n}\n\n// #endregion\n\n// #region CatalogModelKindSummary\n\n/**\n * A summary of a catalog model kind, without version-specific details such as\n * schemas and relation fields.\n *\n * @alpha\n */\nexport interface CatalogModelKindSummary {\n /**\n * A human-readable description of the kind.\n */\n description: string;\n\n /**\n * The names used for this kind.\n */\n names: {\n /**\n * The name of the kind with proper casing, e.g. \"Component\".\n */\n kind: string;\n\n /**\n * The singular form of the kind name, e.g. \"component\".\n */\n singular: string;\n\n /**\n * The plural form of the kind name, e.g. \"components\".\n */\n plural: string;\n };\n\n /**\n * The available versions and spec types for this kind.\n *\n * @remarks\n *\n * Each entry represents a unique apiVersion/specType combination that can be\n * passed to {@link CatalogModel.getKind} to retrieve the full kind details.\n */\n versions: Array<{\n /**\n * The API version, e.g. \"backstage.io/v1alpha1\".\n */\n apiVersion: string;\n /**\n * The spec type, if any, e.g. \"service\". Undefined means the default\n * (untyped) version.\n */\n specType?: string;\n }>;\n}\n\n// #endregion\n\n// #region CatalogModelRelation\n\n/**\n * A compiled catalog model relation.\n *\n * @alpha\n */\nexport interface CatalogModelRelation {\n /**\n * The kinds that this relation can originate from.\n */\n fromKind: string[];\n /**\n * The kinds that this relation can point to.\n */\n toKind: string[];\n /**\n * A human-readable description of the relation.\n */\n description: string;\n /**\n * The forward direction of this relation.\n */\n forward: {\n type: string;\n title: string;\n };\n /**\n * The reverse direction of this relation.\n */\n reverse: {\n type: string;\n title: string;\n };\n}\n\n// #endregion\n\n// #region CatalogModelAnnotationSummary\n\n/**\n * A summary of a catalog model annotation.\n *\n * @alpha\n */\nexport interface CatalogModelAnnotationSummary {\n /**\n * The annotation key, e.g. \"backstage.io/managed-by-location\".\n */\n name: string;\n /**\n * A short human-readable title for the annotation.\n */\n title?: string;\n /**\n * A human-readable description of the annotation.\n */\n description: string;\n}\n\n// #endregion\n\n// #region CatalogModelLabelSummary\n\n/**\n * A summary of a catalog model label.\n *\n * @alpha\n */\nexport interface CatalogModelLabelSummary {\n /**\n * The label key, e.g. \"backstage.io/orphan\".\n */\n name: string;\n /**\n * A short human-readable title for the label.\n */\n title?: string;\n /**\n * A human-readable description of the label.\n */\n description: string;\n}\n\n// #endregion\n\n// #region CatalogModelTagSummary\n\n/**\n * A summary of a catalog model tag.\n *\n * @alpha\n */\nexport interface CatalogModelTagSummary {\n /**\n * The tag value, e.g. \"java\".\n */\n name: string;\n /**\n * A short human-readable title for the tag.\n */\n title?: string;\n /**\n * A human-readable description of the tag.\n */\n description: string;\n}\n\n// #endregion\n\n// #region CatalogModelRelationSummary\n\n/**\n * A summary of a catalog model relation.\n *\n * @alpha\n */\nexport interface CatalogModelRelationSummary {\n /**\n * The kinds that this relation can originate from.\n */\n fromKind: string[];\n /**\n * The kinds that this relation can point to.\n */\n toKind: string[];\n /**\n * A human-readable description of the relation.\n */\n description: string;\n /**\n * The forward direction of this relation.\n */\n forward: {\n type: string;\n title: string;\n };\n /**\n * The reverse direction of this relation.\n */\n reverse: {\n type: string;\n title: string;\n };\n}\n\n// #endregion\n","/*\n * Copyright 2026 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 type CatalogModelAnnotationDefinition,\n opsFromCatalogModelAnnotation,\n} from './modelActions/addAnnotation';\nimport {\n type CatalogModelKindDefinition,\n opsFromCatalogModelKind,\n} from './modelActions/addKind';\nimport {\n type CatalogModelAddKindVersionDefinition,\n opsFromCatalogModelAddKindVersion,\n} from './modelActions/addKindVersion';\nimport {\n type CatalogModelLabelDefinition,\n opsFromCatalogModelLabel,\n} from './modelActions/addLabel';\nimport {\n type CatalogModelRelationPairDefinition,\n opsFromCatalogModelRelationPair,\n} from './modelActions/addRelationPair';\nimport {\n type CatalogModelRemoveAnnotationDefinition,\n opsFromCatalogModelRemoveAnnotation,\n} from './modelActions/removeAnnotation';\nimport {\n type CatalogModelRemoveKindDefinition,\n opsFromCatalogModelRemoveKind,\n} from './modelActions/removeKind';\nimport {\n type CatalogModelRemoveLabelDefinition,\n opsFromCatalogModelRemoveLabel,\n} from './modelActions/removeLabel';\nimport {\n type CatalogModelRemoveTagDefinition,\n opsFromCatalogModelRemoveTag,\n} from './modelActions/removeTag';\nimport {\n type CatalogModelTagDefinition,\n opsFromCatalogModelTag,\n} from './modelActions/addTag';\nimport {\n type CatalogModelUpdateAnnotationDefinition,\n opsFromCatalogModelUpdateAnnotation,\n} from './modelActions/updateAnnotation';\nimport {\n CatalogModelUpdateKindDefinition,\n opsFromCatalogModelUpdateKind,\n} from './modelActions/updateKind';\nimport {\n type CatalogModelUpdateLabelDefinition,\n opsFromCatalogModelUpdateLabel,\n} from './modelActions/updateLabel';\nimport {\n CatalogModelUpdateRelationPairDefinition,\n opsFromCatalogModelUpdateRelationPair,\n} from './modelActions/updateRelationPair';\nimport {\n type CatalogModelUpdateTagDefinition,\n opsFromCatalogModelUpdateTag,\n} from './modelActions/updateTag';\nimport { CatalogModelOp } from './operations';\nimport { CatalogModelLayer, OpaqueCatalogModelLayer } from './types';\n\n/**\n * A builder for catalog model layers.\n *\n * @alpha\n *\n * Plugins can use this builder to declare various contributions to the overall\n * catalog model, and registering the outcome with the catalog which then forms\n * a complete picture out of them.\n */\nexport interface CatalogModelLayerBuilder {\n /**\n * Adds a new kind to the model.\n */\n addKind(kind: CatalogModelKindDefinition): void;\n /**\n * Adds one or more versions to an already-declared kind.\n */\n addKindVersion(definition: CatalogModelAddKindVersionDefinition): void;\n /**\n * Updates an existing kind in the model.\n */\n updateKind(kind: CatalogModelUpdateKindDefinition): void;\n /**\n * Removes a kind entirely from the model.\n */\n removeKind(kind: CatalogModelRemoveKindDefinition): void;\n\n /**\n * Adds a new relation pair to the model.\n */\n addRelationPair(relation: CatalogModelRelationPairDefinition): void;\n /**\n * Updates an existing relation pair in the model.\n */\n updateRelationPair(relation: CatalogModelUpdateRelationPairDefinition): void;\n\n /**\n * Adds a new annotation to the model.\n */\n addAnnotation(annotation: CatalogModelAnnotationDefinition): void;\n /**\n * Updates an existing annotation in the model.\n */\n updateAnnotation(annotation: CatalogModelUpdateAnnotationDefinition): void;\n /**\n * Removes an annotation from the model.\n */\n removeAnnotation(annotation: CatalogModelRemoveAnnotationDefinition): void;\n\n /**\n * Adds a new label to the model.\n */\n addLabel(label: CatalogModelLabelDefinition): void;\n /**\n * Updates an existing label in the model.\n */\n updateLabel(label: CatalogModelUpdateLabelDefinition): void;\n /**\n * Removes a label from the model.\n */\n removeLabel(label: CatalogModelRemoveLabelDefinition): void;\n\n /**\n * Adds a new tag to the model.\n */\n addTag(tag: CatalogModelTagDefinition): void;\n /**\n * Updates an existing tag in the model.\n */\n updateTag(tag: CatalogModelUpdateTagDefinition): void;\n /**\n * Removes a tag from the model.\n */\n removeTag(tag: CatalogModelRemoveTagDefinition): void;\n\n /**\n * Imports all operations from another catalog model layer into this one.\n */\n import(layer: CatalogModelLayer): void;\n}\n\n/**\n * The default implementation of the catalog model layer builder.\n */\nexport class DefaultCatalogModelLayerBuilder\n implements CatalogModelLayerBuilder\n{\n readonly #layerId: string;\n readonly #ops: CatalogModelOp[];\n\n constructor(options: { layerId: string }) {\n this.#layerId = options.layerId;\n this.#ops = [];\n }\n\n addKind(kind: CatalogModelKindDefinition): void {\n const ops = opsFromCatalogModelKind(kind);\n this.#ops.push(...ops);\n }\n\n addKindVersion(definition: CatalogModelAddKindVersionDefinition): void {\n const ops = opsFromCatalogModelAddKindVersion(definition);\n this.#ops.push(...ops);\n }\n\n updateKind(kind: CatalogModelUpdateKindDefinition): void {\n const ops = opsFromCatalogModelUpdateKind(kind);\n this.#ops.push(...ops);\n }\n\n removeKind(kind: CatalogModelRemoveKindDefinition): void {\n const ops = opsFromCatalogModelRemoveKind(kind);\n this.#ops.push(...ops);\n }\n\n addRelationPair(relation: CatalogModelRelationPairDefinition): void {\n const ops = opsFromCatalogModelRelationPair(relation);\n this.#ops.push(...ops);\n }\n\n updateRelationPair(relation: CatalogModelUpdateRelationPairDefinition): void {\n const ops = opsFromCatalogModelUpdateRelationPair(relation);\n this.#ops.push(...ops);\n }\n\n addAnnotation(annotation: CatalogModelAnnotationDefinition): void {\n const ops = opsFromCatalogModelAnnotation(annotation);\n this.#ops.push(...ops);\n }\n\n updateAnnotation(annotation: CatalogModelUpdateAnnotationDefinition): void {\n const ops = opsFromCatalogModelUpdateAnnotation(annotation);\n this.#ops.push(...ops);\n }\n\n removeAnnotation(annotation: CatalogModelRemoveAnnotationDefinition): void {\n const ops = opsFromCatalogModelRemoveAnnotation(annotation);\n this.#ops.push(...ops);\n }\n\n addLabel(label: CatalogModelLabelDefinition): void {\n const ops = opsFromCatalogModelLabel(label);\n this.#ops.push(...ops);\n }\n\n updateLabel(label: CatalogModelUpdateLabelDefinition): void {\n const ops = opsFromCatalogModelUpdateLabel(label);\n this.#ops.push(...ops);\n }\n\n removeLabel(label: CatalogModelRemoveLabelDefinition): void {\n const ops = opsFromCatalogModelRemoveLabel(label);\n this.#ops.push(...ops);\n }\n\n addTag(tag: CatalogModelTagDefinition): void {\n const ops = opsFromCatalogModelTag(tag);\n this.#ops.push(...ops);\n }\n\n updateTag(tag: CatalogModelUpdateTagDefinition): void {\n const ops = opsFromCatalogModelUpdateTag(tag);\n this.#ops.push(...ops);\n }\n\n removeTag(tag: CatalogModelRemoveTagDefinition): void {\n const ops = opsFromCatalogModelRemoveTag(tag);\n this.#ops.push(...ops);\n }\n\n import(layer: CatalogModelLayer): void {\n const internal = OpaqueCatalogModelLayer.toInternal(layer);\n this.#ops.push(...internal.ops);\n }\n\n build(): CatalogModelLayer {\n return OpaqueCatalogModelLayer.createInstance('v1', {\n layerId: this.#layerId,\n ops: this.#ops.slice(),\n });\n }\n}\n\n/**\n * Creates a builder for a catalog model layer.\n *\n * @alpha\n * @remarks\n *\n * Plugins can use the resulting builder to declare various contributions to the\n * overall catalog model, and registering it with the catalog which then forms a\n * complete picture out of them.\n */\nexport function createCatalogModelLayerBuilder(options: {\n layerId: string;\n}): CatalogModelLayerBuilder & { build(): CatalogModelLayer } {\n return new DefaultCatalogModelLayerBuilder(options);\n}\n","/*\n * Copyright 2026 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 { JsonObject } from '@backstage/types';\nimport { CatalogModelOp } from '../operations';\nimport { createDeclareKindOp } from '../operations/declareKind';\nimport { opsFromCatalogModelAddKindVersion } from './addKindVersion';\n\n/**\n * The definition of a catalog model kind, roughly resembling a JSON Schema.\n *\n * @alpha\n */\nexport interface CatalogModelKindDefinition {\n /**\n * The apiVersion group of the kind, e.g. \"backstage.io\".\n */\n group: string;\n\n /**\n * The names used for this kind.\n */\n names: {\n /**\n * The name of the kind with proper casing, e.g. \"Component\".\n */\n kind: string;\n\n /**\n * The singular form of the kind name, e.g. \"component\".\n */\n singular: string;\n\n /**\n * The plural form of the kind name, e.g. \"components\".\n */\n plural: string;\n };\n\n /**\n * A short description of the kind.\n *\n * @remarks\n *\n * For kinds that have wide applicability over for example several different\n * spec types, this description should be a generic one and the types\n * themselves can be more precise.\n */\n description: string;\n\n /**\n * Declare one or more versions of the kind's actual schema shape.\n */\n versions?: CatalogModelKindVersionDefinition[];\n}\n\n/**\n * The definition of one or more specific versions of a catalog model kind.\n *\n * @alpha\n */\nexport interface CatalogModelKindVersionDefinition {\n /**\n * The specific version name or names, e.g. \"v1alpha1\" or\n * [\"v1alpha1\", \"v1beta1\"]. The kind group and the version name form the\n * full apiVersion, e.g. \"backstage.io/v1alpha1\".\n */\n name: string | string[];\n\n /**\n * The spec type or types that this version applies to.\n *\n * @remarks\n *\n * This can be used to make kinds whose spec effectively are discriminated\n * unions. If you don't specify this, the schema will apply to a spec that\n * has no type given at all, or to those where the type is not among the set\n * of any other known declared spec types.\n *\n * TODO: Should this be more like `matcher: { [path: string]: string }`, or\n * even a full JSON Schema that can be used in an \"if\"?\n */\n specType?: string | string[];\n\n /**\n * A short description of this particular version (and type, where applicable).\n */\n description?: string;\n\n /**\n * The fields that shall be used to generate relations, if any.\n *\n * TODO: Should this be not an array, to be more easily mergeable? Or should\n * we just have a custom merge strategy for them\n */\n relationFields?: CatalogModelKindRelationFieldDefinition[];\n\n schema: {\n jsonSchema: JsonObject;\n };\n}\n\n/**\n * @alpha\n */\nexport interface CatalogModelKindRelationFieldDefinition {\n /**\n * What field that shall be used to generate relations.\n *\n * @remarks\n *\n * The field value is expected to be a string or string array at runtime.\n */\n selector: { path: string };\n /**\n * The relation type that this field generates, e.g. \"ownedBy\".\n */\n relation: string;\n /**\n * If the given shorthand ref did not have a kind, use this kind as the\n * default. If no default kind is specified, the ref must contain a kind.\n */\n defaultKind?: string;\n /**\n * If the given shorthand ref did not have a namespace, either inherit the\n * namespace of the entity itself, or choose the default namespace. If no\n * default namespace is specified, the namespace of the entity itself is used.\n */\n defaultNamespace?: 'default' | 'inherit';\n /**\n * Only allow relations to be specified to the given kinds. This list must\n * include the default kind, if any. If no allowed kinds are specified, all\n * kinds are.\n */\n allowedKinds?: string[];\n}\n\nexport function opsFromCatalogModelKind(\n kind: CatalogModelKindDefinition,\n): CatalogModelOp[] {\n const ops: CatalogModelOp[] = [];\n\n ops.push(\n createDeclareKindOp({\n kind: kind.names.kind,\n group: kind.group,\n properties: {\n singular: kind.names.singular,\n plural: kind.names.plural,\n description: kind.description,\n },\n }),\n );\n\n ops.push(\n ...opsFromCatalogModelAddKindVersion({\n kind: kind.names.kind,\n versions: kind.versions ?? [],\n }),\n );\n\n return ops;\n}\n","/*\n * Copyright 2026 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 { JsonObject } from '@backstage/types';\nimport { reduceKindSchema } from '../jsonSchema/reduceKindSchema';\nimport { validateMetaSchema } from '../jsonSchema/validateMetaSchema';\nimport { CatalogModelOp } from '../operations';\nimport { createUpdateKindOp } from '../operations/updateKind';\nimport { createUpdateKindVersionOp } from '../operations/updateKindVersion';\nimport { CatalogModelKindRelationFieldDefinition } from './addKind';\n\n/**\n * The definition of updates to a catalog model kind.\n *\n * @alpha\n */\nexport interface CatalogModelUpdateKindDefinition {\n /**\n * The names used for this kind.\n */\n names: {\n /**\n * The name of the kind with proper casing, e.g. \"Component\".\n */\n kind: string;\n\n /**\n * The singular form of the kind name, e.g. \"component\". Specify this if you\n * want to override the default value.\n */\n singular?: string;\n\n /**\n * The plural form of the kind name, e.g. \"components\". Specify this if you\n * want to override the default value.\n */\n plural?: string;\n };\n\n /**\n * A short description of the kind. Specify this if you want to override the\n * default value.\n */\n description?: string;\n\n /**\n * Update one or more versions of the kind's actual schema shape.\n */\n versions?: CatalogModelUpdateKindVersionDefinition[];\n}\n\n/**\n * The definition of updates to a specific version of a catalog model kind.\n *\n * @alpha\n */\nexport interface CatalogModelUpdateKindVersionDefinition {\n /**\n * The specific version name or names to update, e.g. \"v1alpha1\" or\n * [\"v1alpha1\", \"v1beta1\"].\n */\n name: string | string[];\n\n /**\n * The spec type or types that this version update applies to.\n */\n specType?: string | string[];\n\n /**\n * A short description of this particular version (and type, where\n * applicable). Specify this if you want to override the default value.\n */\n description?: string;\n\n /**\n * The fields that shall be used to generate relations, if any. Specify this\n * if you want to override the default value.\n */\n relationFields?: CatalogModelKindRelationFieldDefinition[];\n\n /**\n * The JSON schema to deep merge with the existing schema for this version.\n */\n schema?: {\n jsonSchema: JsonObject;\n };\n}\n\nexport function opsFromCatalogModelUpdateKind(\n kind: CatalogModelUpdateKindDefinition,\n): CatalogModelOp[] {\n const ops: CatalogModelOp[] = [];\n\n if (kind.names.singular || kind.names.plural || kind.description) {\n ops.push(\n createUpdateKindOp({\n kind: kind.names.kind,\n properties: {\n singular: kind.names.singular,\n plural: kind.names.plural,\n description: kind.description,\n },\n }),\n );\n }\n\n for (const version of kind.versions ?? []) {\n const jsonSchema = version.schema\n ? reduceKindSchema(version.schema.jsonSchema)\n : undefined;\n if (jsonSchema) {\n validateMetaSchema(jsonSchema);\n }\n const names = Array.isArray(version.name) ? version.name : [version.name];\n for (const name of names) {\n const specTypes = version.specType?.length\n ? [version.specType].flat()\n : [undefined];\n for (const specType of specTypes) {\n ops.push(\n createUpdateKindVersionOp({\n kind: kind.names.kind,\n name,\n specType: specType,\n properties: {\n description: version.description,\n relationFields: version.relationFields,\n schema: jsonSchema\n ? { jsonSchema: jsonSchema as any }\n : undefined,\n },\n }),\n );\n }\n }\n }\n\n return ops;\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createRemoveKindOp } from '../operations/removeKind';\n\n/**\n * The definition of a kind removal from the catalog model.\n *\n * @alpha\n */\nexport interface CatalogModelRemoveKindDefinition {\n /**\n * The kind to remove, e.g. \"Component\".\n */\n kind: string;\n}\n\nexport function opsFromCatalogModelRemoveKind(\n definition: CatalogModelRemoveKindDefinition,\n): CatalogModelOp[] {\n return [createRemoveKindOp({ kind: definition.kind })];\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createDeclareRelationOp } from '../operations/declareRelation';\n\n/**\n * The definition of a catalog model relation.\n *\n * @alpha\n */\nexport interface CatalogModelRelationPairDefinition {\n /**\n * The kind(s) that this relation originates from, e.g. \"Component\" or\n * [\"Component\", \"Resource\"].\n */\n fromKind: string | string[];\n\n /**\n * The kind(s) that this relation points to, e.g. \"Group\" or\n * [\"Group\", \"User\"].\n */\n toKind: string | string[];\n\n /**\n * A human-readable description of the relation.\n */\n description: string;\n\n /**\n * The names for the forward direction (from the current entity toward\n * the one being referenced).\n */\n forward: {\n /**\n * The technical type of the relation, e.g. \"ownedBy\"\n */\n type: string;\n /**\n * A human-readable title for the relation type, e.g. \"owned by\".\n */\n title: string;\n };\n\n /**\n * The names for the reverse direction (from the one being referenced\n * toward the current entity).\n */\n reverse: {\n /**\n * The technical type of the relation, e.g. \"ownerOf\"\n */\n type: string;\n /**\n * A human-readable title for the relation type, e.g. \"owner of\".\n */\n title: string;\n };\n}\n\nexport function opsFromCatalogModelRelationPair(\n relationPair: CatalogModelRelationPairDefinition,\n): CatalogModelOp[] {\n const ops: CatalogModelOp[] = [];\n\n // Duplicate across kinds, and both directions\n for (const firstKind of [relationPair.fromKind].flat()) {\n for (const secondKind of [relationPair.toKind].flat()) {\n ops.push(\n createDeclareRelationOp({\n fromKind: firstKind,\n type: relationPair.forward.type,\n toKind: secondKind,\n properties: {\n reverseType: relationPair.reverse.type,\n title: relationPair.forward.title,\n description: relationPair.description,\n },\n }),\n );\n ops.push(\n createDeclareRelationOp({\n fromKind: secondKind,\n type: relationPair.reverse.type,\n toKind: firstKind,\n properties: {\n reverseType: relationPair.forward.type,\n title: relationPair.reverse.title,\n description: relationPair.description,\n },\n }),\n );\n }\n }\n\n return ops;\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createUpdateRelationOp } from '../operations/updateRelation';\n\n/**\n * The definition of a catalog model relation.\n *\n * @alpha\n */\nexport interface CatalogModelUpdateRelationPairDefinition {\n /**\n * The kind(s) that this relation originates from, e.g. \"Component\" or\n * [\"Component\", \"Resource\"].\n */\n fromKind: string | string[];\n\n /**\n * The kind(s) that this relation points to, e.g. \"Group\" or\n * [\"Group\", \"User\"].\n */\n toKind: string | string[];\n\n /**\n * A human-readable description of the relation. Specify this if you want\n * to override the default value.\n */\n description?: string;\n\n /**\n * The names for the forward direction (from the current entity toward the one\n * being referenced).\n */\n forward: {\n /**\n * The technical type of the relation, e.g. \"ownedBy\"\n */\n type: string;\n /**\n * A human-readable title for the relation type, e.g. \"owned by\".\n * Specify this if you want to override the default value.\n */\n title?: string;\n };\n\n /**\n * The names for the reverse direction (from the one being referenced toward\n * the current entity).\n */\n reverse: {\n /**\n * The technical type of the relation, e.g. \"ownerOf\". Specify this if you\n * want to override the default value.\n */\n type?: string;\n /**\n * A human-readable title for the relation type, e.g. \"owner of\".\n * Specify this if you want to override the default value.\n */\n title?: string;\n };\n}\n\nexport function opsFromCatalogModelUpdateRelationPair(\n relationPair: CatalogModelUpdateRelationPairDefinition,\n): CatalogModelOp[] {\n const ops: CatalogModelOp[] = [];\n\n // Duplicate across kinds, and both directions\n for (const firstKind of [relationPair.fromKind].flat()) {\n for (const secondKind of [relationPair.toKind].flat()) {\n ops.push(\n createUpdateRelationOp({\n fromKind: firstKind,\n type: relationPair.forward.type,\n toKind: secondKind,\n properties: {\n reverseType: relationPair.reverse.type,\n title: relationPair.forward.title,\n description: relationPair.description,\n },\n }),\n );\n if (relationPair.reverse.type) {\n ops.push(\n createUpdateRelationOp({\n fromKind: secondKind,\n type: relationPair.reverse.type,\n toKind: firstKind,\n properties: {\n reverseType: relationPair.forward.type,\n title: relationPair.reverse.title,\n description: relationPair.description,\n },\n }),\n );\n }\n }\n }\n\n return ops;\n}\n","/*\n * Copyright 2026 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 { InputError } from '@backstage/errors';\nimport { validateMetaSchema } from '../jsonSchema/validateMetaSchema';\nimport { CatalogModelOp } from '../operations';\nimport { createDeclareAnnotationOp } from '../operations/declareAnnotation';\nimport { JsonObject } from '@backstage/types';\n\n/**\n * The definition of a catalog model annotation.\n *\n * @alpha\n */\nexport interface CatalogModelAnnotationDefinition {\n /**\n * The name of the annotation, e.g. \"backstage.io/techdocs-ref\".\n */\n name: string;\n\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title?: string;\n\n /**\n * A human-readable description of the annotation.\n */\n description: string;\n\n /**\n * The JSON schema that values of this annotation must conform to.\n *\n * @remarks\n *\n * If not provided, the annotation is assumed to be a simple string with no\n * particular schema.\n */\n schema?: {\n jsonSchema: JsonObject;\n };\n}\n\nexport function opsFromCatalogModelAnnotation(\n annotation: CatalogModelAnnotationDefinition,\n): CatalogModelOp[] {\n if (annotation.schema?.jsonSchema) {\n validateMetaSchema(annotation.schema.jsonSchema);\n if (annotation.schema.jsonSchema.type !== 'string') {\n throw new InputError(\n `Annotation \"${annotation.name}\" schema must have \"type\": \"string\" at the root, only string values are supported`,\n );\n }\n }\n return [\n createDeclareAnnotationOp({\n name: annotation.name,\n properties: {\n title: annotation.title,\n description: annotation.description,\n schema: annotation.schema,\n },\n }),\n ];\n}\n","/*\n * Copyright 2026 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 { InputError } from '@backstage/errors';\nimport { validateMetaSchema } from '../jsonSchema/validateMetaSchema';\nimport { CatalogModelOp } from '../operations';\nimport { createUpdateAnnotationOp } from '../operations/updateAnnotation';\nimport { JsonObject } from '@backstage/types';\n\n/**\n * The definition of updates to a catalog model annotation.\n *\n * @alpha\n */\nexport interface CatalogModelUpdateAnnotationDefinition {\n /**\n * The name of the annotation, e.g. \"backstage.io/techdocs-ref\".\n */\n name: string;\n\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title?: string;\n\n /**\n * A human-readable description of the annotation.\n */\n description?: string;\n\n /**\n * The JSON schema that values of this annotation must conform to.\n *\n * @remarks\n *\n * If not provided, the annotation is assumed to be a simple string with no\n * particular schema.\n */\n schema?: {\n jsonSchema: JsonObject;\n };\n}\n\nexport function opsFromCatalogModelUpdateAnnotation(\n annotation: CatalogModelUpdateAnnotationDefinition,\n): CatalogModelOp[] {\n if (annotation.schema) {\n validateMetaSchema(annotation.schema.jsonSchema);\n if (annotation.schema.jsonSchema.type !== 'string') {\n throw new InputError(\n `Annotation \"${annotation.name}\" schema must have \"type\": \"string\" at the root, only string values are supported`,\n );\n }\n }\n return [\n createUpdateAnnotationOp({\n name: annotation.name,\n properties: {\n title: annotation.title,\n description: annotation.description,\n schema: annotation.schema,\n },\n }),\n ];\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createRemoveAnnotationOp } from '../operations/removeAnnotation';\n\n/**\n * The definition of an annotation removal from the catalog model.\n *\n * @alpha\n */\nexport interface CatalogModelRemoveAnnotationDefinition {\n /**\n * The name of the annotation to remove, e.g. \"backstage.io/techdocs-ref\".\n */\n name: string;\n}\n\nexport function opsFromCatalogModelRemoveAnnotation(\n definition: CatalogModelRemoveAnnotationDefinition,\n): CatalogModelOp[] {\n return [createRemoveAnnotationOp({ name: definition.name })];\n}\n","/*\n * Copyright 2026 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 { InputError } from '@backstage/errors';\nimport { validateMetaSchema } from '../jsonSchema/validateMetaSchema';\nimport { CatalogModelOp } from '../operations';\nimport { createDeclareLabelOp } from '../operations/declareLabel';\nimport { JsonObject } from '@backstage/types';\n\n/**\n * The definition of a catalog model label.\n *\n * @alpha\n */\nexport interface CatalogModelLabelDefinition {\n /**\n * The name of the label, e.g. \"backstage.io/source-location\".\n */\n name: string;\n\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title?: string;\n\n /**\n * A human-readable description of the label.\n */\n description: string;\n\n /**\n * The JSON schema that values of this label must conform to.\n *\n * @remarks\n *\n * If not provided, the label is assumed to be a simple string with no\n * particular schema.\n */\n schema?: {\n jsonSchema: JsonObject;\n };\n}\n\nexport function opsFromCatalogModelLabel(\n label: CatalogModelLabelDefinition,\n): CatalogModelOp[] {\n if (label.schema?.jsonSchema) {\n validateMetaSchema(label.schema.jsonSchema);\n if (label.schema.jsonSchema.type !== 'string') {\n throw new InputError(\n `Label \"${label.name}\" schema must have \"type\": \"string\" at the root, only string values are supported`,\n );\n }\n }\n return [\n createDeclareLabelOp({\n name: label.name,\n properties: {\n title: label.title,\n description: label.description,\n schema: label.schema,\n },\n }),\n ];\n}\n","/*\n * Copyright 2026 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 { InputError } from '@backstage/errors';\nimport { validateMetaSchema } from '../jsonSchema/validateMetaSchema';\nimport { CatalogModelOp } from '../operations';\nimport { createUpdateLabelOp } from '../operations/updateLabel';\nimport { JsonObject } from '@backstage/types';\n\n/**\n * The definition of updates to a catalog model label.\n *\n * @alpha\n */\nexport interface CatalogModelUpdateLabelDefinition {\n /**\n * The name of the label, e.g. \"backstage.io/source-location\".\n */\n name: string;\n\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title?: string;\n\n /**\n * A human-readable description of the label.\n */\n description?: string;\n\n /**\n * The JSON schema that values of this label must conform to.\n *\n * @remarks\n *\n * If not provided, the label is assumed to be a simple string with no\n * particular schema.\n */\n schema?: {\n jsonSchema: JsonObject;\n };\n}\n\nexport function opsFromCatalogModelUpdateLabel(\n label: CatalogModelUpdateLabelDefinition,\n): CatalogModelOp[] {\n if (label.schema) {\n validateMetaSchema(label.schema.jsonSchema);\n if (label.schema.jsonSchema.type !== 'string') {\n throw new InputError(\n `Label \"${label.name}\" schema must have \"type\": \"string\" at the root, only string values are supported`,\n );\n }\n }\n return [\n createUpdateLabelOp({\n name: label.name,\n properties: {\n title: label.title,\n description: label.description,\n schema: label.schema,\n },\n }),\n ];\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createRemoveLabelOp } from '../operations/removeLabel';\n\n/**\n * The definition of a label removal from the catalog model.\n *\n * @alpha\n */\nexport interface CatalogModelRemoveLabelDefinition {\n /**\n * The name of the label to remove, e.g. \"backstage.io/source-location\".\n */\n name: string;\n}\n\nexport function opsFromCatalogModelRemoveLabel(\n definition: CatalogModelRemoveLabelDefinition,\n): CatalogModelOp[] {\n return [createRemoveLabelOp({ name: definition.name })];\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createDeclareTagOp } from '../operations/declareTag';\n\n/**\n * The definition of a catalog model tag.\n *\n * @alpha\n */\nexport interface CatalogModelTagDefinition {\n /**\n * The name of the tag, e.g. \"java\".\n */\n name: string;\n\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title?: string;\n\n /**\n * A human-readable description of the tag.\n */\n description: string;\n}\n\nexport function opsFromCatalogModelTag(\n tag: CatalogModelTagDefinition,\n): CatalogModelOp[] {\n return [\n createDeclareTagOp({\n name: tag.name,\n properties: {\n title: tag.title,\n description: tag.description,\n },\n }),\n ];\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createUpdateTagOp } from '../operations/updateTag';\n\n/**\n * The definition of updates to a catalog model tag.\n *\n * @alpha\n */\nexport interface CatalogModelUpdateTagDefinition {\n /**\n * The name of the tag, e.g. \"java\".\n */\n name: string;\n\n /**\n * A human-readable title that can be used for display purposes instead of\n * the technical name.\n */\n title?: string;\n\n /**\n * A human-readable description of the tag.\n */\n description?: string;\n}\n\nexport function opsFromCatalogModelUpdateTag(\n tag: CatalogModelUpdateTagDefinition,\n): CatalogModelOp[] {\n return [\n createUpdateTagOp({\n name: tag.name,\n properties: {\n title: tag.title,\n description: tag.description,\n },\n }),\n ];\n}\n","/*\n * Copyright 2026 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 { CatalogModelOp } from '../operations';\nimport { createRemoveTagOp } from '../operations/removeTag';\n\n/**\n * The definition of a tag removal from the catalog model.\n *\n * @alpha\n */\nexport interface CatalogModelRemoveTagDefinition {\n /**\n * The name of the tag to remove, e.g. \"java\".\n */\n name: string;\n}\n\nexport function opsFromCatalogModelRemoveTag(\n definition: CatalogModelRemoveTagDefinition,\n): CatalogModelOp[] {\n return [createRemoveTagOp({ name: definition.name })];\n}\n","/*\n * Copyright 2020 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 { createCatalogModelLayer } from '../model/createCatalogModelLayer';\n\n/*\nNaming rules for relations in priority order:\n\n1. Use at most two words. One main verb and a specifier, e.g. \"ownerOf\"\n2. Reading out \"<source-kind> <type> <target-kind>\" should make sense in English.\n3. Maintain symmetry between pairs, e.g. \"ownedBy\" and \"ownerOf\" rather than \"owns\".\n*/\n\n/**\n * An ownership relation where the owner is usually an organizational\n * entity (user or group), and the other entity can be anything. Reversed\n * direction of {@link RELATION_OWNER_OF}.\n *\n * @public\n */\nexport const RELATION_OWNED_BY = 'ownedBy';\n\n/**\n * A relationship from an owner to the owned entity. Reversed direction of\n * {@link RELATION_OWNED_BY}.\n *\n * @public\n */\nexport const RELATION_OWNER_OF = 'ownerOf';\n\n/**\n * A relation with an API entity, typically from a component. Reversed direction of\n * {@link RELATION_API_CONSUMED_BY}.\n *\n * @public\n */\nexport const RELATION_CONSUMES_API = 'consumesApi';\n\n/**\n * A relation of an API being consumed, typically by a component. Reversed direction of\n * {@link RELATION_CONSUMES_API}.\n *\n * @public\n */\nexport const RELATION_API_CONSUMED_BY = 'apiConsumedBy';\n\n/**\n * A relation from an API provider entity (typically a component) to the API. Reversed direction of\n * {@link RELATION_API_PROVIDED_BY}.\n *\n * @public\n */\nexport const RELATION_PROVIDES_API = 'providesApi';\n\n/**\n * A relation from an API to its provider entity (typically a component). Reversed direction of\n * {@link RELATION_PROVIDES_API}.\n *\n * @public\n */\nexport const RELATION_API_PROVIDED_BY = 'apiProvidedBy';\n\n/**\n * A relation denoting a dependency on another entity. Reversed direction of\n * {@link RELATION_DEPENDENCY_OF}.\n *\n * @public\n */\nexport const RELATION_DEPENDS_ON = 'dependsOn';\n\n/**\n * A relation denoting a reverse dependency by another entity. Reversed direction of\n * {@link RELATION_DEPENDS_ON}.\n *\n * @public\n */\nexport const RELATION_DEPENDENCY_OF = 'dependencyOf';\n\n/**\n * A parent/child relation to build up a tree, used for example to describe\n * the organizational structure between groups. Reversed direction of\n * {@link RELATION_CHILD_OF}.\n *\n * @public\n */\nexport const RELATION_PARENT_OF = 'parentOf';\n\n/**\n * A relation from a child to a parent entity, used for example to describe\n * the organizational structure between groups. Reversed direction of\n * {@link RELATION_PARENT_OF}.\n *\n * @public\n */\nexport const RELATION_CHILD_OF = 'childOf';\n\n/**\n * A membership relation, typically for users in a group. Reversed direction of\n * {@link RELATION_HAS_MEMBER}.\n *\n * @public\n */\nexport const RELATION_MEMBER_OF = 'memberOf';\n\n/**\n * A relation from a group to its member, typically a user in a group. Reversed direction of\n * {@link RELATION_MEMBER_OF}.\n *\n * @public\n */\nexport const RELATION_HAS_MEMBER = 'hasMember';\n\n/**\n * A part/whole relation, typically for components in a system and systems\n * in a domain. Reversed direction of {@link RELATION_HAS_PART}.\n *\n * @public\n */\nexport const RELATION_PART_OF = 'partOf';\n\n/**\n * A relation from a containing entity to a contained entity. Reversed direction of\n * {@link RELATION_PART_OF}.\n *\n * @public\n */\nexport const RELATION_HAS_PART = 'hasPart';\n\n/**\n * Extends the catalog model with the well-known Backstage relation pairs.\n */\nexport const wellKnownRelationsModel = createCatalogModelLayer({\n layerId: 'catalog.backstage.io/well-known-relations',\n builder: model => {\n model.addRelationPair({\n fromKind: [\n 'API',\n 'Component',\n 'Domain',\n 'Group',\n 'Location',\n 'Resource',\n 'System',\n 'User',\n ],\n toKind: ['Group', 'User'],\n description:\n 'An ownership relation where the owner is usually an organizational entity (user or group), and the other entity can be anything.',\n forward: { type: 'ownedBy', title: 'owned by' },\n reverse: { type: 'ownerOf', title: 'owner of' },\n });\n\n model.addRelationPair({\n fromKind: 'Component',\n toKind: 'API',\n description:\n 'A relation from a component to an API it provides for consumption by others.',\n forward: { type: 'providesApi', title: 'provides API' },\n reverse: { type: 'apiProvidedBy', title: 'API provided by' },\n });\n\n model.addRelationPair({\n fromKind: 'Component',\n toKind: 'API',\n description: 'A relation from a component to an API it consumes.',\n forward: { type: 'consumesApi', title: 'consumes API' },\n reverse: { type: 'apiConsumedBy', title: 'API consumed by' },\n });\n\n model.addRelationPair({\n fromKind: ['Component', 'Resource'],\n toKind: ['Component', 'Resource'],\n description:\n 'A dependency relation expressing that an entity needs another entity to function.',\n forward: { type: 'dependsOn', title: 'depends on' },\n reverse: { type: 'dependencyOf', title: 'dependency of' },\n });\n\n model.addRelationPair({\n fromKind: 'Group',\n toKind: 'Group',\n description:\n 'A parent/child relation to build up a tree, used for example to describe the organizational structure between groups.',\n forward: { type: 'parentOf', title: 'parent of' },\n reverse: { type: 'childOf', title: 'child of' },\n });\n\n model.addRelationPair({\n fromKind: 'User',\n toKind: 'Group',\n description: 'A membership relation, typically for users in a group.',\n forward: { type: 'memberOf', title: 'member of' },\n reverse: { type: 'hasMember', title: 'has member' },\n });\n\n model.addRelationPair({\n fromKind: ['Component', 'API', 'Resource'],\n toKind: ['Component', 'System'],\n description:\n 'A part/whole relation where a component, API, or resource belongs to a system or a component is a subcomponent of another.',\n forward: { type: 'partOf', title: 'part of' },\n reverse: { type: 'hasPart', title: 'has part' },\n });\n\n model.addRelationPair({\n fromKind: 'System',\n toKind: 'Domain',\n description: 'A part/whole relation where a system belongs to a domain.',\n forward: { type: 'partOf', title: 'part of' },\n reverse: { type: 'hasPart', title: 'has part' },\n });\n\n model.addRelationPair({\n fromKind: 'Domain',\n toKind: 'Domain',\n description:\n 'A part/whole relation where a domain is a subdomain of another domain.',\n forward: { type: 'partOf', title: 'part of' },\n reverse: { type: 'hasPart', title: 'has part' },\n });\n },\n});\n","// extracted by css-extract-rspack-plugin\nexport default {\"bui-Card\":\"vwbKbDh04mMaiBi3\",\"bui-CardHeader\":\"XFUmGkj6WID_JnEz\",\"bui-CardBody\":\"bDKBEHaUGVdvGxpS\",\"bui-CardFooter\":\"htqU_uAkxL89C8of\",\"bui-CardTrigger\":\"YH9iVtgxrw5b0cYJ\",\"bui-card-body-shadow\":\"bJ7HlUi_25Q2Dxr7\"};","/*\n * Copyright 2024 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 { defineComponent } from '../../hooks/useDefinition';\nimport type {\n CardOwnProps,\n CardHeaderOwnProps,\n CardBodyOwnProps,\n CardFooterOwnProps,\n} from './types';\nimport styles from './Card.module.css';\n\n/**\n * Component definition for Card\n * @public\n */\nexport const CardDefinition = defineComponent<CardOwnProps>()({\n styles,\n classNames: {\n root: 'bui-Card',\n trigger: 'bui-CardTrigger',\n },\n propDefs: {\n children: {},\n className: {},\n onPress: {},\n href: {},\n label: {},\n target: {},\n rel: {},\n download: {},\n style: {},\n },\n utilityProps: ['grow', 'shrink', 'basis'],\n});\n\n/**\n * Component definition for CardHeader\n * @public\n */\nexport const CardHeaderDefinition = defineComponent<CardHeaderOwnProps>()({\n styles,\n classNames: {\n root: 'bui-CardHeader',\n },\n propDefs: {\n children: {},\n className: {},\n },\n});\n\n/**\n * Component definition for CardBody\n * @public\n */\nexport const CardBodyDefinition = defineComponent<CardBodyOwnProps>()({\n styles,\n classNames: {\n root: 'bui-CardBody',\n },\n propDefs: {\n children: {},\n className: {},\n },\n});\n\n/**\n * Component definition for CardFooter\n * @public\n */\nexport const CardFooterDefinition = defineComponent<CardFooterOwnProps>()({\n styles,\n classNames: {\n root: 'bui-CardFooter',\n },\n propDefs: {\n children: {},\n className: {},\n },\n});\n","/*\n * Copyright 2024 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 { forwardRef, useCallback, useRef } from 'react';\nimport { Button as RAButton } from 'react-aria-components';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport {\n CardDefinition,\n CardHeaderDefinition,\n CardBodyDefinition,\n CardFooterDefinition,\n} from './definition';\nimport type {\n CardProps,\n CardHeaderProps,\n CardBodyProps,\n CardFooterProps,\n} from './types';\nimport { Box } from '../Box/Box';\nimport { Link } from '../Link';\n\nconst INTERACTIVE_ELEMENT_SELECTOR =\n 'a[href],button,input,select,textarea,[role=\"button\"],[role=\"link\"],[tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * Card component.\n *\n * @public\n */\nexport const Card = forwardRef<HTMLDivElement, CardProps>((props, ref) => {\n const { ownProps, restProps, dataAttributes, utilityStyle } = useDefinition(\n CardDefinition,\n props,\n );\n const {\n classes,\n children,\n onPress,\n href,\n label,\n target: linkTarget,\n rel,\n download,\n } = ownProps;\n const isInteractive = !!(onPress || href);\n\n const triggerRef = useRef<HTMLAnchorElement | HTMLButtonElement>(null);\n\n const handleClick = useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n if (!isInteractive || !triggerRef.current) return;\n\n // Don't delegate if the click target is the trigger itself\n if (triggerRef.current.contains(e.target as Node)) return;\n\n // Don't delegate if the user clicked a nested interactive element\n const targetNode = e.target as Node | null;\n const targetElement =\n targetNode instanceof Element ? targetNode : targetNode?.parentElement;\n if (targetElement?.closest(INTERACTIVE_ELEMENT_SELECTOR)) return;\n\n // Don't delegate if the user is selecting text\n if (window.getSelection()?.toString()) return;\n\n triggerRef.current.dispatchEvent(\n new MouseEvent('click', {\n bubbles: true,\n cancelable: true,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n altKey: e.altKey,\n }),\n );\n },\n [isInteractive],\n );\n\n return (\n <Box\n as=\"article\"\n bg=\"neutral\"\n ref={ref}\n className={classes.root}\n data-interactive={isInteractive || undefined}\n {...dataAttributes}\n {...restProps}\n onClick={isInteractive ? handleClick : undefined}\n style={{ ...utilityStyle, ...ownProps.style }}\n >\n {href && (\n <Link\n ref={triggerRef as React.Ref<HTMLAnchorElement>}\n className={classes.trigger}\n href={href}\n target={linkTarget}\n rel={rel}\n download={download}\n aria-label={label}\n />\n )}\n {onPress && !href && (\n <RAButton\n ref={triggerRef as React.Ref<HTMLButtonElement>}\n className={classes.trigger}\n onPress={onPress}\n aria-label={label}\n />\n )}\n {children}\n </Box>\n );\n});\n\nCard.displayName = 'Card';\n\n/**\n * CardHeader component.\n *\n * @public\n */\nexport const CardHeader = forwardRef<HTMLDivElement, CardHeaderProps>(\n (props, ref) => {\n const { ownProps, restProps } = useDefinition(CardHeaderDefinition, props);\n const { classes, children } = ownProps;\n\n return (\n <div ref={ref} className={classes.root} {...restProps}>\n {children}\n </div>\n );\n },\n);\n\nCardHeader.displayName = 'CardHeader';\n\n/**\n * CardBody component.\n *\n * @public\n */\nexport const CardBody = forwardRef<HTMLDivElement, CardBodyProps>(\n (props, ref) => {\n const { ownProps, restProps } = useDefinition(CardBodyDefinition, props);\n const { classes, children } = ownProps;\n\n return (\n <div ref={ref} className={classes.root} {...restProps}>\n {children}\n </div>\n );\n },\n);\n\nCardBody.displayName = 'CardBody';\n\n/**\n * CardFooter component.\n *\n * @public\n */\nexport const CardFooter = forwardRef<HTMLDivElement, CardFooterProps>(\n (props, ref) => {\n const { ownProps, restProps } = useDefinition(CardFooterDefinition, props);\n const { classes, children } = ownProps;\n\n return (\n <div ref={ref} className={classes.root} {...restProps}>\n {children}\n </div>\n );\n },\n);\n\nCardFooter.displayName = 'CardFooter';\n","// extracted by css-extract-rspack-plugin\nexport default {\"bui-Grid\":\"lOUUwZ1G_vYgdngG\"};","/*\n * Copyright 2024 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 { defineComponent } from '../../hooks/useDefinition';\nimport type { GridOwnProps, GridItemOwnProps } from './types';\nimport styles from './Grid.module.css';\n\n/**\n * Component definition for Grid\n * @public\n */\nexport const GridDefinition = defineComponent<GridOwnProps>()({\n styles,\n classNames: {\n root: 'bui-Grid',\n },\n bg: 'provider',\n propDefs: {\n bg: { dataAttribute: true },\n children: {},\n className: {},\n style: {},\n },\n utilityProps: [\n 'columns',\n 'gap',\n 'm',\n 'mb',\n 'ml',\n 'mr',\n 'mt',\n 'mx',\n 'my',\n 'p',\n 'pb',\n 'pl',\n 'pr',\n 'pt',\n 'px',\n 'py',\n 'grow',\n 'shrink',\n 'basis',\n ],\n});\n\n/**\n * Component definition for GridItem\n * @public\n */\nexport const GridItemDefinition = defineComponent<GridItemOwnProps>()({\n styles,\n classNames: {\n root: 'bui-GridItem',\n },\n bg: 'provider',\n propDefs: {\n bg: { dataAttribute: true },\n children: {},\n className: {},\n style: {},\n },\n utilityProps: ['colSpan', 'colEnd', 'colStart', 'rowSpan'],\n});\n","/*\n * Copyright 2024 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 { forwardRef } from 'react';\nimport type { GridItemProps, GridProps } from './types';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { GridDefinition, GridItemDefinition } from './definition';\n\nconst GridRoot = forwardRef<HTMLDivElement, GridProps>((props, ref) => {\n const { ownProps, dataAttributes, utilityStyle, restProps } = useDefinition(\n GridDefinition,\n { columns: 'auto', gap: '4', ...props },\n );\n const { classes, childrenWithBgProvider } = ownProps;\n\n return (\n <div\n ref={ref}\n className={classes.root}\n style={{ ...utilityStyle, ...ownProps.style }}\n {...dataAttributes}\n {...restProps}\n >\n {childrenWithBgProvider}\n </div>\n );\n});\n\nconst GridItem = forwardRef<HTMLDivElement, GridItemProps>((props, ref) => {\n const { ownProps, dataAttributes, utilityStyle, restProps } = useDefinition(\n GridItemDefinition,\n props,\n );\n const { classes, childrenWithBgProvider } = ownProps;\n\n return (\n <div\n ref={ref}\n className={classes.root}\n style={{ ...utilityStyle, ...ownProps.style }}\n {...dataAttributes}\n {...restProps}\n >\n {childrenWithBgProvider}\n </div>\n );\n});\n\n/** @public */\nexport const Grid = {\n Root: GridRoot,\n Item: GridItem,\n};\n","/*\n * Copyright 2026 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 { ReactNode } from 'react';\nimport {\n Card,\n CardHeader,\n CardBody,\n CardFooter,\n Text,\n Flex,\n} from '@backstage/ui';\nimport { makeStyles } from '@material-ui/core/styles';\nimport classNames from 'classnames';\n\nconst useStyles = makeStyles({\n root: {\n height: '100%',\n },\n title: {\n minWidth: 0,\n overflow: 'hidden',\n },\n footer: {\n display: 'flex',\n justifyContent: 'flex-end',\n },\n});\n\n/** @public */\nexport interface EntityInfoCardProps {\n title?: ReactNode;\n headerActions?: ReactNode;\n footerActions?: ReactNode;\n children?: ReactNode;\n className?: string;\n}\n\n/** @public */\nexport function EntityInfoCard(props: EntityInfoCardProps) {\n const { title, headerActions, footerActions, children, className } = props;\n const classes = useStyles();\n\n return (\n <Card className={classNames(classes.root, className)}>\n {title && (\n <CardHeader>\n <Flex justify=\"between\" align=\"center\">\n <Text\n as=\"h3\"\n variant=\"title-x-small\"\n weight=\"bold\"\n className={classes.title}\n >\n {title}\n </Text>\n {headerActions && (\n <Flex align=\"center\" gap=\"1\">\n {headerActions}\n </Flex>\n )}\n </Flex>\n </CardHeader>\n )}\n <CardBody>{children}</CardBody>\n {footerActions && (\n <CardFooter className={classes.footer}>{footerActions}</CardFooter>\n )}\n </Card>\n );\n}\n","/*\n * Copyright 2022 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 */\nimport {\n Entity,\n CompoundEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { Fragment } from 'react';\nimport { EntityRefLink } from './EntityRefLink';\nimport { LinkProps } from '@backstage/core-components';\n\n/**\n * Props for {@link EntityRefLink}.\n *\n * @public\n */\nexport type EntityRefLinksProps<\n TRef extends string | CompoundEntityRef | Entity,\n> = {\n defaultKind?: string;\n entityRefs: TRef[];\n hideIcons?: boolean;\n /** @deprecated This option is no longer used; presentation is handled by entityPresentationApiRef instead */\n fetchEntities?: boolean;\n /** @deprecated This option is no longer used; presentation is handled by entityPresentationApiRef instead */\n getTitle?(entity: TRef): string | undefined;\n} & Omit<LinkProps, 'to'>;\n\n/**\n * Shows a list of clickable links to entities.\n *\n * @public\n */\nexport function EntityRefLinks<\n TRef extends string | CompoundEntityRef | Entity,\n>(props: EntityRefLinksProps<TRef>) {\n const { entityRefs, hideIcons, ...linkProps } = props;\n\n return (\n <>\n {entityRefs.map((r: TRef, i: number) => {\n const entityRefString =\n typeof r === 'string' ? r : stringifyEntityRef(r);\n return (\n <Fragment key={`${i}.${entityRefString}`}>\n {i > 0 && ', '}\n <EntityRefLink {...linkProps} entityRef={r} hideIcon={hideIcons} />\n </Fragment>\n );\n })}\n </>\n );\n}\n","/*\n * Copyright 2020 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 Entity,\n CompoundEntityRef,\n parseEntityRef,\n} from '@backstage/catalog-model';\n\n// TODO(freben): This should be returning entity refs instead\n/**\n * Get the related entity references.\n *\n * @public\n */\nexport function getEntityRelations(\n entity: Entity | undefined,\n relationType: string,\n filter?: { kind: string },\n): CompoundEntityRef[] {\n let entityNames =\n entity?.relations\n ?.filter(r => r.type === relationType)\n .map(r => parseEntityRef(r.targetRef)) || [];\n\n if (filter?.kind) {\n entityNames = entityNames.filter(\n e =>\n e.kind.toLocaleLowerCase('en-US') ===\n filter.kind.toLocaleLowerCase('en-US'),\n );\n }\n\n return entityNames;\n}\n","var __rspack_ns_object = JSON.parse('{\"$schema\":\"http://json-schema.org/draft-07/schema\",\"$id\":\"Entity\",\"description\":\"The parts of the format that\\'s common to all versions/kinds of entity.\",\"examples\":[{\"apiVersion\":\"backstage.io/v1alpha1\",\"kind\":\"Component\",\"metadata\":{\"name\":\"LoremService\",\"description\":\"Creates Lorems like a pro.\",\"labels\":{\"product_name\":\"Random value Generator\"},\"annotations\":{\"docs\":\"https://github.com/..../tree/develop/doc\"}},\"spec\":{\"type\":\"service\",\"lifecycle\":\"production\",\"owner\":\"tools\"}}],\"type\":\"object\",\"required\":[\"apiVersion\",\"kind\",\"metadata\"],\"additionalProperties\":false,\"properties\":{\"apiVersion\":{\"type\":\"string\",\"description\":\"The version of specification format for this particular entity that this is written against.\",\"minLength\":1,\"examples\":[\"backstage.io/v1alpha1\",\"my-company.net/v1\",\"1.0\"]},\"kind\":{\"type\":\"string\",\"description\":\"The high level entity type being described.\",\"minLength\":1,\"examples\":[\"API\",\"Component\",\"Domain\",\"Group\",\"Location\",\"Resource\",\"System\",\"Template\",\"User\"]},\"metadata\":{\"$ref\":\"EntityMeta\"},\"spec\":{\"type\":\"object\",\"description\":\"The specification data describing the entity itself.\"},\"relations\":{\"type\":\"array\",\"description\":\"The relations that this entity has with other entities.\",\"items\":{\"$ref\":\"common#relation\"}},\"status\":{\"$ref\":\"common#status\"}}}')","var __rspack_ns_object = JSON.parse('{\"$schema\":\"http://json-schema.org/draft-07/schema\",\"$id\":\"EntityEnvelope\",\"description\":\"The envelope skeleton parts of an entity - whatever is necessary to be able to give it a ref and pass to further validation / policy checking.\",\"examples\":[{\"apiVersion\":\"backstage.io/v1alpha1\",\"kind\":\"Component\",\"metadata\":{\"name\":\"LoremService\"}}],\"type\":\"object\",\"required\":[\"apiVersion\",\"kind\",\"metadata\"],\"additionalProperties\":true,\"properties\":{\"apiVersion\":{\"type\":\"string\",\"description\":\"The version of specification format for this particular entity that this is written against.\",\"minLength\":1,\"examples\":[\"backstage.io/v1alpha1\",\"my-company.net/v1\",\"1.0\"]},\"kind\":{\"type\":\"string\",\"description\":\"The high level entity type being described.\",\"minLength\":1,\"examples\":[\"API\",\"Component\",\"Domain\",\"Group\",\"Location\",\"Resource\",\"System\",\"Template\",\"User\"]},\"metadata\":{\"type\":\"object\",\"required\":[\"name\"],\"additionalProperties\":true,\"properties\":{\"name\":{\"type\":\"string\",\"description\":\"The name of the entity. Must be unique within the catalog at any given point in time, for any given namespace + kind pair.\",\"examples\":[\"metadata-proxy\"],\"minLength\":1},\"namespace\":{\"type\":\"string\",\"description\":\"The namespace that the entity belongs to.\",\"default\":\"default\",\"examples\":[\"default\",\"admin\"],\"minLength\":1}}}}}')","var __rspack_ns_object = JSON.parse('{\"$schema\":\"http://json-schema.org/draft-07/schema\",\"$id\":\"EntityMeta\",\"description\":\"Metadata fields common to all versions/kinds of entity.\",\"examples\":[{\"uid\":\"e01199ab-08cc-44c2-8e19-5c29ded82521\",\"etag\":\"lsndfkjsndfkjnsdfkjnsd==\",\"name\":\"my-component-yay\",\"namespace\":\"the-namespace\",\"labels\":{\"backstage.io/custom\":\"ValueStuff\"},\"annotations\":{\"example.com/bindings\":\"are-secret\"},\"tags\":[\"java\",\"data\"]}],\"type\":\"object\",\"required\":[\"name\"],\"additionalProperties\":true,\"properties\":{\"uid\":{\"type\":\"string\",\"description\":\"A globally unique ID for the entity. This field can not be set by the user at creation time, and the server will reject an attempt to do so. The field will be populated in read operations. The field can (optionally) be specified when performing update or delete operations, but the server is free to reject requests that do so in such a way that it breaks semantics.\",\"examples\":[\"e01199ab-08cc-44c2-8e19-5c29ded82521\"],\"minLength\":1},\"etag\":{\"type\":\"string\",\"description\":\"An opaque string that changes for each update operation to any part of the entity, including metadata. This field can not be set by the user at creation time, and the server will reject an attempt to do so. The field will be populated in read operations. The field can (optionally) be specified when performing update or delete operations, and the server will then reject the operation if it does not match the current stored value.\",\"examples\":[\"lsndfkjsndfkjnsdfkjnsd==\"],\"minLength\":1},\"name\":{\"type\":\"string\",\"description\":\"The name of the entity. Must be unique within the catalog at any given point in time, for any given namespace + kind pair.\",\"examples\":[\"metadata-proxy\"],\"minLength\":1},\"namespace\":{\"type\":\"string\",\"description\":\"The namespace that the entity belongs to.\",\"default\":\"default\",\"examples\":[\"default\",\"admin\"],\"minLength\":1},\"title\":{\"type\":\"string\",\"description\":\"A display name of the entity, to be presented in user interfaces instead of the name property, when available.\",\"examples\":[\"React SSR Template\"],\"minLength\":1},\"description\":{\"type\":\"string\",\"description\":\"A short (typically relatively few words, on one line) description of the entity.\"},\"labels\":{\"type\":\"object\",\"description\":\"Key/value pairs of identifying information attached to the entity.\",\"additionalProperties\":true,\"patternProperties\":{\"^.+$\":{\"type\":\"string\"}}},\"annotations\":{\"type\":\"object\",\"description\":\"Key/value pairs of non-identifying auxiliary information attached to the entity.\",\"additionalProperties\":true,\"patternProperties\":{\"^.+$\":{\"type\":\"string\"}}},\"tags\":{\"type\":\"array\",\"description\":\"A list of single-valued strings, to for example classify catalog entities in various ways.\",\"items\":{\"type\":\"string\",\"minLength\":1}},\"links\":{\"type\":\"array\",\"description\":\"A list of external hyperlinks related to the entity. Links can provide additional contextual information that may be located outside of Backstage itself. For example, an admin dashboard or external CMS page.\",\"items\":{\"type\":\"object\",\"required\":[\"url\"],\"properties\":{\"url\":{\"type\":\"string\",\"description\":\"A url in a standard uri format.\",\"examples\":[\"https://admin.example-org.com\"],\"minLength\":1},\"title\":{\"type\":\"string\",\"description\":\"A user friendly display name for the link.\",\"examples\":[\"Admin Dashboard\"],\"minLength\":1},\"icon\":{\"type\":\"string\",\"description\":\"A key representing a visual icon to be displayed in the UI.\",\"examples\":[\"dashboard\"],\"minLength\":1},\"type\":{\"type\":\"string\",\"description\":\"An optional value to categorize links into specific groups.\",\"examples\":[\"runbook\",\"documentation\",\"logs\",\"dashboard\"],\"minLength\":1}}}}}}')","var __rspack_ns_object = JSON.parse('{\"$schema\":\"http://json-schema.org/draft-07/schema\",\"$id\":\"common\",\"type\":\"object\",\"description\":\"Common definitions to import from other schemas\",\"definitions\":{\"reference\":{\"$id\":\"#reference\",\"type\":\"object\",\"description\":\"A reference by name to another entity.\",\"required\":[\"kind\",\"namespace\",\"name\"],\"additionalProperties\":false,\"properties\":{\"kind\":{\"type\":\"string\",\"description\":\"The kind field of the entity.\",\"minLength\":1},\"namespace\":{\"type\":\"string\",\"description\":\"The metadata.namespace field of the entity.\",\"minLength\":1},\"name\":{\"type\":\"string\",\"description\":\"The metadata.name field of the entity.\",\"minLength\":1}}},\"relation\":{\"$id\":\"#relation\",\"type\":\"object\",\"description\":\"A directed relation from one entity to another.\",\"required\":[\"type\",\"targetRef\"],\"additionalProperties\":false,\"properties\":{\"type\":{\"type\":\"string\",\"minLength\":1,\"pattern\":\"^\\\\\\\\w+$\",\"description\":\"The type of relation.\"},\"target\":{\"$ref\":\"#reference\",\"deprecated\":true},\"targetRef\":{\"type\":\"string\",\"minLength\":1,\"description\":\"The entity ref of the target of this relation.\"}}},\"status\":{\"$id\":\"#status\",\"type\":\"object\",\"description\":\"The current status of the entity, as claimed by various sources.\",\"required\":[],\"additionalProperties\":true,\"properties\":{\"items\":{\"type\":\"array\",\"items\":{\"$ref\":\"#statusItem\"}}}},\"statusItem\":{\"$id\":\"#statusItem\",\"type\":\"object\",\"description\":\"A specific status item on a well known format.\",\"required\":[\"type\",\"level\",\"message\"],\"additionalProperties\":true,\"properties\":{\"type\":{\"type\":\"string\",\"minLength\":1},\"level\":{\"$ref\":\"#statusLevel\",\"description\":\"The status level / severity of the status item.\"},\"message\":{\"type\":\"string\",\"description\":\"A brief message describing the status, intended for human consumption.\"},\"error\":{\"$ref\":\"#error\",\"description\":\"An optional serialized error object related to the status.\"}}},\"statusLevel\":{\"$id\":\"#statusLevel\",\"type\":\"string\",\"description\":\"A status level / severity.\",\"enum\":[\"info\",\"warning\",\"error\"]},\"error\":{\"$id\":\"#error\",\"type\":\"object\",\"description\":\"A serialized error object.\",\"required\":[\"name\",\"message\"],\"additionalProperties\":true,\"properties\":{\"name\":{\"type\":\"string\",\"examples\":[\"Error\",\"InputError\"],\"description\":\"The type name of the error\",\"minLength\":1},\"message\":{\"type\":\"string\",\"description\":\"The message of the error\"},\"code\":{\"type\":\"string\",\"description\":\"An error code associated with the error\"},\"stack\":{\"type\":\"string\",\"description\":\"An error stack trace\"}}}}}')","/*\n * Copyright 2021 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 Ajv, { Schema, ValidateFunction } from 'ajv';\nimport entitySchema from '../schema/Entity.schema.json';\nimport entityEnvelopeSchema from '../schema/EntityEnvelope.schema.json';\nimport entityMetaSchema from '../schema/EntityMeta.schema.json';\nimport commonSchema from '../schema/shared/common.schema.json';\n\n// A local cache of compiled schemas, to avoid duplicate work.\n// The keys are JSON stringified versions of the schema\nconst compiledSchemaCache = new Map<string, ValidateFunction<unknown>>();\n\n// The core schemas that others can depend on\nconst refDependencyCandidates = [\n entityEnvelopeSchema,\n entitySchema,\n entityMetaSchema,\n commonSchema,\n];\n\nexport function throwAjvError(\n errors: ValidateFunction<unknown>['errors'],\n): never {\n if (!errors?.length) {\n throw new TypeError('Unknown error');\n }\n\n const error = errors[0];\n throw new TypeError(\n `${error.instancePath || '<root>'} ${error.message}${\n error.params\n ? ` - ${Object.entries(error.params)\n .map(([key, val]) => `${key}: ${val}`)\n .join(', ')}`\n : ''\n }`,\n );\n}\n\n// Compiles the given schema, and makes sure to also grab any core dependencies\n// that it depends on\nexport function compileAjvSchema(\n schema: Schema,\n options: { disableCache?: boolean } = {},\n): ValidateFunction<unknown> {\n const disableCache = options?.disableCache ?? false;\n const cacheKey = disableCache ? '' : JSON.stringify(schema);\n\n if (!disableCache) {\n const cached = compiledSchemaCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n }\n\n const extraSchemas = getExtraSchemas(schema);\n const ajv = new Ajv({\n allowUnionTypes: true,\n allErrors: true,\n validateSchema: true,\n });\n if (extraSchemas.length) {\n ajv.addSchema(extraSchemas, undefined, undefined, true);\n }\n const compiled = ajv.compile(schema);\n\n if (!disableCache) {\n compiledSchemaCache.set(cacheKey, compiled);\n }\n\n return compiled;\n}\n\n// Find refs in the given schema and recursively in all known schemas it\n// targets, collecting that list of schemas as we go\nfunction getExtraSchemas(schema: Schema): Schema[] {\n if (typeof schema !== 'object') {\n return [];\n }\n\n const seen = new Set<string>();\n if (schema.$id) {\n seen.add(schema.$id);\n }\n\n const selected = new Array<Schema>();\n\n const todo: Schema[] = [schema];\n while (todo.length) {\n const current = todo.pop()!;\n\n for (const ref of getAllRefs(current)) {\n if (!seen.has(ref)) {\n seen.add(ref);\n\n const match = refDependencyCandidates.find(c => c.$id === ref);\n if (match) {\n selected.push(match);\n todo.push(match);\n }\n }\n }\n }\n\n return selected;\n}\n\n// Naively step through the entire schema looking for \"$ref\": \"x\" pairs. The\n// resulting iterator may contain duplicates. Ignores fragments, i.e. for a ref\n// of \"a#b\", it will just yield \"a\".\nfunction* getAllRefs(schema: Schema): Iterable<string> {\n const todo: any[] = [schema];\n while (todo.length) {\n const current = todo.pop()!;\n if (typeof current === 'object' && current) {\n for (const [key, value] of Object.entries(current)) {\n if (key === '$ref' && typeof value === 'string') {\n yield value.split('#')[0];\n } else {\n todo.push(value);\n }\n }\n }\n }\n}\n","/*\n * Copyright 2021 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 { Schema } from 'ajv';\nimport { Entity } from '../entity/Entity';\nimport { compileAjvSchema, throwAjvError } from './ajv';\n\n/**\n * Creates a validation function that takes some arbitrary data, and either\n * returns that data cast to a `T` if it matches that schema, or `false` if the\n * schema apiVersion/kind didn't apply to that data, or throws a\n * {@link globals#TypeError} describing actual errors.\n *\n * @remarks\n *\n * This validator is highly specialized, in that it has special treatment of\n * the `kind` and `apiVersion` root keys. This only works if your schema has\n * their rule set to `\"enum\"`:\n *\n * ```\n * \"apiVersion\": {\n * \"enum\": [\"backstage.io/v1alpha1\", \"backstage.io/v1beta1\"]\n * },\n * \"kind\": {\n * \"enum\": [\"Group\"]\n * },\n * ```\n *\n * In the above example, the created validator will return `false` if and only\n * if the kind and/or apiVersion mismatch.\n *\n * Note that this validator is only meant for applying the base schema checks;\n * it does not take custom policies or additional processor based validation\n * into account.\n *\n * The given schema may contain `$ref` references to the following, which are\n * resolved automatically for you:\n *\n * - {@link Entity}\n *\n * - {@link EntityEnvelope}\n *\n * - {@link EntityMeta}\n *\n * - `common#<id>`\n * @see {@link https://github.com/backstage/backstage/tree/master/packages/catalog-model/src/schema}\n *\n * @public\n */\nexport function entityKindSchemaValidator<T extends Entity>(\n schema: unknown,\n): (data: unknown) => T | false {\n const validate = compileAjvSchema(schema as Schema);\n\n return data => {\n const result = validate(data);\n if (result === true) {\n return data as T;\n }\n\n // Only in the case where kind and/or apiVersion have enum mismatches AND\n // have NO other errors, we call it a soft error.\n const softCandidates = validate.errors?.filter(e =>\n ['/kind', '/apiVersion'].includes(e.instancePath),\n );\n if (\n softCandidates?.length &&\n softCandidates.every(e => e.keyword === 'enum')\n ) {\n return false;\n }\n\n throw throwAjvError(validate.errors);\n };\n}\n","var __rspack_ns_object = JSON.parse('{\"$schema\":\"http://json-schema.org/draft-07/schema\",\"$id\":\"TemplateV1beta3\",\"description\":\"A Template describes a scaffolding task for use with the Scaffolder. It describes the required parameters as well as a series of steps that will be taken to execute the scaffolding task.\",\"examples\":[{\"apiVersion\":\"scaffolder.backstage.io/v1beta3\",\"kind\":\"Template\",\"metadata\":{\"name\":\"react-ssr-template\",\"title\":\"React SSR Template\",\"description\":\"Next.js application skeleton for creating isomorphic web applications.\",\"tags\":[\"recommended\",\"react\"]},\"spec\":{\"owner\":\"artist-relations-team\",\"type\":\"website\",\"lifecycle\":\"production\",\"parameters\":{\"required\":[\"name\",\"description\",\"repoUrl\"],\"backstage:permissions\":{\"tags\":[\"one\",\"two\"]},\"properties\":{\"name\":{\"title\":\"Name\",\"type\":\"string\",\"description\":\"Unique name of the component\"},\"description\":{\"title\":\"Description\",\"type\":\"string\",\"description\":\"Description of the component\"},\"repoUrl\":{\"title\":\"Pick a repository\",\"type\":\"string\",\"ui:field\":\"RepoUrlPicker\"}}},\"steps\":[{\"id\":\"fetch\",\"name\":\"Fetch\",\"action\":\"fetch:plain\",\"parameters\":{\"url\":\"./template\"},\"backstage:permissions\":{\"tags\":[\"one\",\"two\"]}},{\"id\":\"publish\",\"name\":\"Publish to GitHub\",\"action\":\"publish:github\",\"parameters\":{\"repoUrl\":\"${{ parameters.repoUrl }}\"},\"if\":\"${{ parameters.repoUrl }}\"}],\"output\":{\"catalogInfoUrl\":\"${{ steps.publish.output.catalogInfoUrl }}\"}}}],\"allOf\":[{\"$ref\":\"Entity\"},{\"type\":\"object\",\"required\":[\"spec\"],\"properties\":{\"apiVersion\":{\"enum\":[\"scaffolder.backstage.io/v1beta3\"]},\"kind\":{\"enum\":[\"Template\"]},\"spec\":{\"type\":\"object\",\"required\":[\"type\",\"steps\"],\"properties\":{\"type\":{\"type\":\"string\",\"description\":\"The type of component created by the template. The software catalog accepts any type value, but an organization should take great care to establish a proper taxonomy for these. Tools including Backstage itself may read this field and behave differently depending on its value. For example, a website type component may present tooling in the Backstage interface that is specific to just websites.\",\"examples\":[\"service\",\"website\",\"library\"],\"minLength\":1},\"owner\":{\"type\":\"string\",\"description\":\"The user (or group) owner of the template\",\"minLength\":1},\"lifecycle\":{\"type\":\"string\",\"description\":\"The lifecycle state of the template.\",\"examples\":[\"experimental\",\"production\",\"deprecated\"],\"minLength\":1},\"parameters\":{\"oneOf\":[{\"type\":\"object\",\"description\":\"The JSONSchema describing the inputs for the template.\",\"properties\":{\"backstage:permissions\":{\"type\":\"object\",\"description\":\"Object used for authorizing the parameter\",\"properties\":{\"tags\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}}}}},{\"type\":\"array\",\"description\":\"A list of separate forms to collect parameters.\",\"items\":{\"type\":\"object\",\"description\":\"The JSONSchema describing the inputs for the template.\",\"properties\":{\"backstage:permissions\":{\"type\":\"object\",\"description\":\"Object used for authorizing the parameter\",\"properties\":{\"tags\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}}}}}}]},\"secrets\":{\"type\":\"object\",\"description\":\"Configuration for secrets that are passed during task creation.\",\"properties\":{\"schema\":{\"type\":\"object\",\"description\":\"A JSONSchema for validating secrets passed during task creation.\"}}},\"presentation\":{\"type\":\"object\",\"description\":\"A way to redefine the presentation of the scaffolder.\",\"properties\":{\"buttonLabels\":{\"type\":\"object\",\"description\":\"A way to redefine the labels for actionable buttons.\",\"properties\":{\"backButtonText\":{\"type\":\"string\",\"description\":\"A button which return the user to one step back.\"},\"createButtonText\":{\"type\":\"string\",\"description\":\"A button which start the execution of the template.\"},\"reviewButtonText\":{\"type\":\"string\",\"description\":\"A button which open the review step to verify the input prior to start the execution.\"}}}}},\"EXPERIMENTAL_recovery\":{\"type\":\"object\",\"description\":\"A task recovery section.\",\"properties\":{\"EXPERIMENTAL_strategy\":{\"type\":\"string\",\"description\":\"Recovery strategy for your task (none or startOver). By default none\"}}},\"formDecorators\":{\"type\":\"array\",\"description\":\"A list of decorators and their inputs that the form should trigger before submitting the job\",\"items\":{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"string\",\"description\":\"The form decorator ID\"},\"input\":{\"type\":\"object\",\"description\":\"An object describing the inputs to the form decorator.\"}}}},\"EXPERIMENTAL_formDecorators\":{\"type\":\"array\",\"deprecated\":true,\"description\":\"Deprecated, use formDecorators instead.\",\"items\":{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"string\",\"description\":\"The form decorator ID\"},\"input\":{\"type\":\"object\",\"description\":\"An object describing the inputs to the form decorator.\"}}}},\"steps\":{\"type\":\"array\",\"description\":\"A list of steps to execute.\",\"items\":{\"type\":\"object\",\"description\":\"A description of the step to execute.\",\"required\":[\"action\"],\"properties\":{\"id\":{\"type\":\"string\",\"description\":\"The ID of the step, which can be used to refer to its outputs.\"},\"name\":{\"type\":\"string\",\"description\":\"The name of the step, which will be displayed in the UI during the scaffolding process.\"},\"action\":{\"type\":\"string\",\"description\":\"The name of the action to execute.\"},\"input\":{\"type\":\"object\",\"description\":\"A templated object describing the inputs to the action.\"},\"if\":{\"type\":[\"string\",\"boolean\"],\"description\":\"A templated condition that skips the step when evaluated to false. If the condition is true or not defined, the step is executed. The condition is true, if the input is not `false`, `undefined`, `null`, `\\\\\"\\\\\"`, `0`, or `[]`.\"},\"backstage:permissions\":{\"type\":\"object\",\"description\":\"Object used for authorizing the step\",\"properties\":{\"tags\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}}}}}},\"output\":{\"type\":\"object\",\"description\":\"A templated object describing the outputs of the scaffolding task.\",\"properties\":{\"links\":{\"type\":\"array\",\"description\":\"A list of external hyperlinks, typically pointing to resources created or updated by the template\",\"items\":{\"type\":\"object\",\"required\":[],\"properties\":{\"if\":{\"type\":[\"string\",\"boolean\"],\"description\":\"A templated condition that excludes this link when evaluated to false. If the condition is true or not defined, the link is included. The condition is true, if the input is not `false`, `undefined`, `null`, `\\\\\"\\\\\"`, `0`, or `[]`.\"},\"url\":{\"type\":\"string\",\"description\":\"A url in a standard uri format.\",\"examples\":[\"https://github.com/my-org/my-new-repo\"],\"minLength\":1},\"entityRef\":{\"type\":\"string\",\"description\":\"An entity reference to an entity in the catalog.\",\"examples\":[\"Component:default/my-app\"],\"minLength\":1},\"title\":{\"type\":\"string\",\"description\":\"A user friendly display name for the link.\",\"examples\":[\"View new repo\"],\"minLength\":1},\"icon\":{\"type\":\"string\",\"description\":\"A key representing a visual icon to be displayed in the UI.\",\"examples\":[\"dashboard\"],\"minLength\":1}}}},\"text\":{\"type\":\"array\",\"description\":\"A list of Markdown text blobs, like output data from the template.\",\"items\":{\"type\":\"object\",\"required\":[],\"properties\":{\"if\":{\"type\":[\"string\",\"boolean\"],\"description\":\"A templated condition that excludes this text when evaluated to false. If the condition is true or not defined, the text is included. The condition is true, if the input is not `false`, `undefined`, `null`, `\\\\\"\\\\\"`, `0`, or `[]`.\"},\"title\":{\"type\":\"string\",\"description\":\"A user friendly display name for the text.\",\"examples\":[\"Output Content\"],\"minLength\":1},\"icon\":{\"type\":\"string\",\"description\":\"A key representing a visual icon to be displayed in the UI.\",\"examples\":[\"dashboard\"],\"minLength\":1},\"content\":{\"type\":\"string\",\"description\":\"The text blob to display in the UI, rendered as Markdown.\",\"examples\":[\"**hey** _I\\'m_ Markdown\"]}}}}},\"additionalProperties\":{\"type\":\"string\"}}}}}}]}')","/*\n * Copyright 2022 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 { createPermission } from '@backstage/plugin-permission-common';\n\n/**\n * Permission resource type which corresponds to a scaffolder templates.\n *\n * @alpha\n */\nexport const RESOURCE_TYPE_SCAFFOLDER_TEMPLATE = 'scaffolder-template';\n\n/**\n * Permission resource type which corresponds to a scaffolder action.\n *\n * @alpha\n */\nexport const RESOURCE_TYPE_SCAFFOLDER_ACTION = 'scaffolder-action';\n\n/**\n * Permission resource type which corresponds to scaffolder tasks\n *\n * @alpha\n */\nexport const RESOURCE_TYPE_SCAFFOLDER_TASK = 'scaffolder-task';\n\n/**\n * This permission is used to authorize actions that involve executing\n * an action from a template.\n *\n * @alpha\n */\nexport const actionExecutePermission = createPermission({\n name: 'scaffolder.action.execute',\n attributes: {},\n resourceType: RESOURCE_TYPE_SCAFFOLDER_ACTION,\n});\n\n/**\n * This permission is used to authorize actions that involve reading\n * one or more parameters from a template.\n *\n * If this permission is not authorized, it will appear that the\n * parameter does not exist in the template — both in the frontend\n * and in API responses.\n *\n * @alpha\n */\nexport const templateParameterReadPermission = createPermission({\n name: 'scaffolder.template.parameter.read',\n attributes: {\n action: 'read',\n },\n resourceType: RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n});\n\n/**\n * This permission is used to authorize actions that involve reading\n * one or more steps from a template.\n *\n * If this permission is not authorized, it will appear that the\n * step does not exist in the template — both in the frontend\n * and in API responses. Steps will also not be executed.\n *\n * @alpha\n */\nexport const templateStepReadPermission = createPermission({\n name: 'scaffolder.template.step.read',\n attributes: {\n action: 'read',\n },\n resourceType: RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n});\n\n/**\n * This permission is used to authorize dry runs of inline scaffolder\n * templates.\n *\n * @alpha\n */\nexport const templateDryRunPermission = createPermission({\n name: 'scaffolder.template.dry-run',\n attributes: {},\n});\n\n/**\n * This permission is used to authorize actions that involve reading one or more tasks in the scaffolder,\n * and reading logs of tasks\n *\n * @alpha\n */\nexport const taskReadPermission = createPermission({\n name: 'scaffolder.task.read',\n attributes: {\n action: 'read',\n },\n resourceType: RESOURCE_TYPE_SCAFFOLDER_TASK,\n});\n\n/**\n * This permission is used to authorize actions that involve the creation of tasks in the scaffolder.\n *\n * @alpha\n */\nexport const taskCreatePermission = createPermission({\n name: 'scaffolder.task.create',\n attributes: {\n action: 'create',\n },\n});\n\n/**\n * This permission is used to authorize actions that involve the cancellation of tasks in the scaffolder.\n *\n * @alpha\n */\nexport const taskCancelPermission = createPermission({\n name: 'scaffolder.task.cancel',\n attributes: {},\n resourceType: RESOURCE_TYPE_SCAFFOLDER_TASK,\n});\n\n/**\n * This permission is used to authorize template management features.\n *\n * @alpha\n */\nexport const templateManagementPermission = createPermission({\n name: 'scaffolder.template.management',\n attributes: {},\n});\n\n/**\n * List of the scaffolder permissions that are associated with template steps and parameters.\n * @alpha\n */\nexport const scaffolderTemplatePermissions = [\n templateParameterReadPermission,\n templateStepReadPermission,\n];\n\n/**\n * List of the scaffolder permissions that are associated with scaffolder actions.\n * @alpha\n */\nexport const scaffolderActionPermissions = [actionExecutePermission];\n\n/**\n * List of the scaffolder permissions that are associated with scaffolder tasks.\n * @alpha\n */\nexport const scaffolderTaskPermissions = [\n taskCancelPermission,\n taskCreatePermission,\n taskReadPermission,\n];\n\n/**\n * List of all the scaffolder permissions\n * @alpha\n */\nexport const scaffolderPermissions = [\n ...scaffolderTemplatePermissions,\n ...scaffolderActionPermissions,\n ...scaffolderTaskPermissions,\n templateDryRunPermission,\n templateManagementPermission,\n];\n","/*\n * Copyright 2020 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 { useElementFilter } from '@backstage/core-plugin-api';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { ReactNode } from 'react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { catalogTranslationRef } from '../../alpha/translation';\n\nconst useStyles = makeStyles(theme => ({\n value: {\n fontWeight: 'bold',\n overflow: 'hidden',\n lineHeight: '24px',\n wordBreak: 'break-word',\n },\n label: {\n color: theme.palette.text.secondary,\n textTransform: 'uppercase',\n fontSize: '10px',\n fontWeight: 'bold',\n letterSpacing: 0.5,\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n },\n}));\n\n/**\n * Props for {@link AboutField}.\n *\n * @public\n */\nexport interface AboutFieldProps {\n label: string;\n value?: string;\n children?: ReactNode;\n className?: string;\n}\n\n/** @public */\nexport function AboutField(props: AboutFieldProps) {\n const { label, value, children, className } = props;\n const classes = useStyles();\n const { t } = useTranslationRef(catalogTranslationRef);\n\n const childElements = useElementFilter(children, c => c.getElements());\n\n // Content is either children or a string prop `value`\n const content =\n childElements.length > 0 ? (\n childElements\n ) : (\n <Typography variant=\"body2\" className={classes.value}>\n {value || t('aboutCard.unknown')}\n </Typography>\n );\n return (\n <div className={className}>\n <Typography variant=\"inherit\" component=\"h2\" className={classes.label}>\n {label}\n </Typography>\n {content}\n </div>\n );\n}\n","/*\n * Copyright 2020 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 Entity,\n getEntitySourceLocation,\n RELATION_OWNED_BY,\n RELATION_PART_OF,\n} from '@backstage/catalog-model';\nimport {\n EntityRefLinks,\n getEntityRelations,\n} from '@backstage/plugin-catalog-react';\nimport { JsonArray } from '@backstage/types';\nimport Chip from '@material-ui/core/Chip';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { Grid } from '@backstage/ui';\nimport { MarkdownContent } from '@backstage/core-components';\nimport { AboutField } from './AboutField';\nimport { LinksGridList } from '../EntityLinksCard/LinksGridList';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { catalogTranslationRef } from '../../alpha/translation';\n\nconst useStyles = makeStyles({\n description: {\n wordBreak: 'break-word',\n },\n});\n\n/**\n * Props for {@link AboutContent}.\n *\n * @public\n */\nexport interface AboutContentProps {\n entity: Entity;\n}\n\nfunction getLocationTargetHref(\n target: string,\n type: string,\n entitySourceLocation: {\n type: string;\n target: string;\n },\n): string {\n if (type === 'url' || target.includes('://')) {\n return target;\n }\n\n const srcLocationUrl =\n entitySourceLocation.type === 'file'\n ? `file://${entitySourceLocation.target}`\n : entitySourceLocation.target;\n\n if (type === 'file' || entitySourceLocation.type === 'file') {\n return new URL(target, srcLocationUrl).href;\n }\n\n return srcLocationUrl;\n}\n\n/** @public */\nexport function AboutContent(props: AboutContentProps) {\n const { entity } = props;\n const classes = useStyles();\n const { t } = useTranslationRef(catalogTranslationRef);\n\n const isSystem = entity.kind.toLocaleLowerCase('en-US') === 'system';\n const isResource = entity.kind.toLocaleLowerCase('en-US') === 'resource';\n const isComponent = entity.kind.toLocaleLowerCase('en-US') === 'component';\n const isAPI = entity.kind.toLocaleLowerCase('en-US') === 'api';\n const isTemplate = entity.kind.toLocaleLowerCase('en-US') === 'template';\n const isLocation = entity.kind.toLocaleLowerCase('en-US') === 'location';\n const isGroup = entity.kind.toLocaleLowerCase('en-US') === 'group';\n\n const partOfSystemRelations = getEntityRelations(entity, RELATION_PART_OF, {\n kind: 'system',\n });\n const partOfComponentRelations = getEntityRelations(\n entity,\n RELATION_PART_OF,\n {\n kind: 'component',\n },\n );\n const partOfDomainRelations = getEntityRelations(entity, RELATION_PART_OF, {\n kind: 'domain',\n });\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n\n let entitySourceLocation:\n | {\n type: string;\n target: string;\n }\n | undefined;\n try {\n entitySourceLocation = getEntitySourceLocation(entity);\n } catch (e) {\n entitySourceLocation = undefined;\n }\n\n const columns = { initial: '1', sm: '2', lg: '3' } as const;\n\n return (\n <Grid.Root columns={columns} gap=\"3\">\n <Grid.Item colSpan={columns}>\n <AboutField label={t('aboutCard.descriptionField.label')}>\n <MarkdownContent\n className={classes.description}\n content={\n entity?.metadata?.description ||\n t('aboutCard.descriptionField.value')\n }\n />\n </AboutField>\n </Grid.Item>\n <AboutField\n label={t('aboutCard.ownerField.label')}\n value={t('aboutCard.ownerField.value')}\n className={classes.description}\n >\n {ownedByRelations.length > 0 && (\n <EntityRefLinks entityRefs={ownedByRelations} defaultKind=\"group\" />\n )}\n </AboutField>\n {(isSystem || partOfDomainRelations.length > 0) && (\n <AboutField\n label={t('aboutCard.domainField.label')}\n value={t('aboutCard.domainField.value')}\n >\n {partOfDomainRelations.length > 0 && (\n <EntityRefLinks\n entityRefs={partOfDomainRelations}\n defaultKind=\"domain\"\n />\n )}\n </AboutField>\n )}\n {(isAPI ||\n isComponent ||\n isResource ||\n partOfSystemRelations.length > 0) && (\n <AboutField\n label={t('aboutCard.systemField.label')}\n value={t('aboutCard.systemField.value')}\n >\n {partOfSystemRelations.length > 0 && (\n <EntityRefLinks\n entityRefs={partOfSystemRelations}\n defaultKind=\"system\"\n />\n )}\n </AboutField>\n )}\n {isComponent && partOfComponentRelations.length > 0 && (\n <AboutField\n label={t('aboutCard.parentComponentField.label')}\n value={t('aboutCard.parentComponentField.value')}\n >\n <EntityRefLinks\n entityRefs={partOfComponentRelations}\n defaultKind=\"component\"\n />\n </AboutField>\n )}\n <AboutField\n label={t('aboutCard.tagsField.label')}\n value={t('aboutCard.tagsField.value')}\n >\n {(entity?.metadata?.tags || []).map(tag => (\n <Chip key={tag} size=\"small\" label={tag} />\n ))}\n </AboutField>\n <AboutField label={t('aboutCard.kindField.label')} value={entity.kind} />\n {(isAPI ||\n isComponent ||\n isResource ||\n isTemplate ||\n isGroup ||\n isLocation ||\n typeof entity?.spec?.type === 'string') && (\n <AboutField\n label={t('aboutCard.typeField.label')}\n value={entity?.spec?.type as string}\n />\n )}\n {(isAPI ||\n isComponent ||\n typeof entity?.spec?.lifecycle === 'string') && (\n <AboutField\n label={t('aboutCard.lifecycleField.label')}\n value={entity?.spec?.lifecycle as string}\n />\n )}\n {isLocation && (entity?.spec?.targets || entity?.spec?.target) && (\n <Grid.Item colSpan={columns}>\n <AboutField label={t('aboutCard.targetsField.label')}>\n <LinksGridList\n cols={1}\n items={(\n (entity.spec.targets as JsonArray) || [entity.spec.target]\n )\n .map(target => target as string)\n .map(target => ({\n text: target,\n href: getLocationTargetHref(\n target,\n (entity?.spec?.type || t('aboutCard.unknown')) as string,\n entitySourceLocation!,\n ),\n }))}\n />\n </AboutField>\n </Grid.Item>\n )}\n </Grid.Root>\n );\n}\n","/*\n * Copyright 2020 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 { useCallback } from 'react';\n\nimport IconButton from '@material-ui/core/IconButton';\nimport CachedIcon from '@material-ui/icons/Cached';\nimport EditIcon from '@material-ui/icons/Edit';\nimport DocsIcon from '@material-ui/icons/Description';\nimport CreateComponentIcon from '@material-ui/icons/AddCircleOutline';\n\nimport {\n AppIcon,\n HeaderIconLinkRow,\n IconLinkVerticalProps,\n Link,\n} from '@backstage/core-components';\nimport { EntityInfoCard } from '@backstage/plugin-catalog-react';\nimport {\n alertApiRef,\n errorApiRef,\n useApp,\n useApi,\n useRouteRef,\n} from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nimport {\n DEFAULT_NAMESPACE,\n ANNOTATION_EDIT_URL,\n ANNOTATION_LOCATION,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { catalogApiRef, useEntity } from '@backstage/plugin-catalog-react';\nimport { useEntityPermission } from '@backstage/plugin-catalog-react/alpha';\nimport { catalogEntityRefreshPermission } from '@backstage/plugin-catalog-common/alpha';\n\nimport {\n TECHDOCS_ANNOTATION,\n TECHDOCS_EXTERNAL_ANNOTATION,\n} from '@backstage/plugin-techdocs-common';\nimport { buildTechDocsURL } from '@backstage/plugin-techdocs-react';\n\nimport { isTemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';\nimport { taskCreatePermission } from '@backstage/plugin-scaffolder-common/alpha';\n\nimport { usePermission } from '@backstage/plugin-permission-react';\n\nimport { createFromTemplateRouteRef, viewTechDocRouteRef } from '../../routes';\nimport { catalogTranslationRef } from '../../alpha/translation';\nimport { useSourceTemplateCompoundEntityRef } from './hooks';\nimport { AboutContent } from './AboutContent';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { useCatalogSourceIconLinkProps } from './useCatalogSourceIconLinkProps';\n\nconst useStyles = makeStyles({\n linkContainer: {\n border: '1px solid var(--bui-border-1)',\n borderLeft: 'none',\n borderRight: 'none',\n marginBottom: 'var(--bui-space-6)',\n },\n});\n\n// TODO: This hook is duplicated from the TechDocs plugin for backwards compatibility\n// Remove it when the the legacy frontend system support is dropped.\nfunction useTechdocsReaderIconLinkProps(): IconLinkVerticalProps {\n const { entity } = useEntity();\n const viewTechdocLink = useRouteRef(viewTechDocRouteRef);\n const { t } = useTranslationRef(catalogTranslationRef);\n\n return {\n label: t('aboutCard.viewTechdocs'),\n disabled:\n !(\n entity.metadata.annotations?.[TECHDOCS_ANNOTATION] ||\n entity.metadata.annotations?.[TECHDOCS_EXTERNAL_ANNOTATION]\n ) || !viewTechdocLink,\n icon: <DocsIcon />,\n href: buildTechDocsURL(entity, viewTechdocLink),\n };\n}\n\n// TODO: This hook is duplicated from the Scaffolder plugin for backwards compatibility\n// Remove it when the the legacy frontend system support is dropped.\nfunction useScaffolderTemplateIconLinkProps(): IconLinkVerticalProps {\n const app = useApp();\n const { entity } = useEntity();\n const templateRoute = useRouteRef(createFromTemplateRouteRef);\n const { t } = useTranslationRef(catalogTranslationRef);\n const Icon = app.getSystemIcon('scaffolder') ?? CreateComponentIcon;\n const { allowed: canCreateTemplateTask } = usePermission({\n permission: taskCreatePermission,\n });\n\n return {\n label: t('aboutCard.launchTemplate'),\n icon: <Icon />,\n disabled: !templateRoute || !canCreateTemplateTask,\n href:\n templateRoute &&\n templateRoute({\n templateName: entity.metadata.name,\n namespace: entity.metadata.namespace || DEFAULT_NAMESPACE,\n }),\n };\n}\n\nfunction DefaultAboutCardSubheader() {\n const { entity } = useEntity();\n const catalogSourceIconLink = useCatalogSourceIconLinkProps();\n const techdocsreaderIconLink = useTechdocsReaderIconLinkProps();\n const scaffolderTemplateIconLink = useScaffolderTemplateIconLinkProps();\n\n const links = [catalogSourceIconLink, techdocsreaderIconLink];\n if (isTemplateEntityV1beta3(entity)) {\n links.push(scaffolderTemplateIconLink);\n }\n\n return <HeaderIconLinkRow links={links} />;\n}\n\nexport interface InternalAboutCardProps {\n /** Icon link row rendered at the top of the card body. */\n iconLinks?: JSX.Element;\n}\n\nexport function InternalAboutCard(props: InternalAboutCardProps) {\n const { iconLinks } = props;\n const classes = useStyles();\n const { entity } = useEntity();\n const catalogApi = useApi(catalogApiRef);\n const alertApi = useApi(alertApiRef);\n const errorApi = useApi(errorApiRef);\n const templateRoute = useRouteRef(createFromTemplateRouteRef);\n const sourceTemplateRef = useSourceTemplateCompoundEntityRef(entity);\n const { allowed: canRefresh } = useEntityPermission(\n catalogEntityRefreshPermission,\n );\n const { t } = useTranslationRef(catalogTranslationRef);\n\n const entityMetadataEditUrl =\n entity.metadata.annotations?.[ANNOTATION_EDIT_URL];\n\n const entityLocation = entity.metadata.annotations?.[ANNOTATION_LOCATION];\n // Limiting the ability to manually refresh to the less expensive locations\n const allowRefresh =\n entityLocation?.startsWith('url:') || entityLocation?.startsWith('file:');\n const refreshEntity = useCallback(async () => {\n try {\n await catalogApi.refreshEntity(stringifyEntityRef(entity));\n alertApi.post({\n message: t('aboutCard.refreshScheduledMessage'),\n severity: 'info',\n display: 'transient',\n });\n } catch (e) {\n errorApi.post(e);\n }\n }, [catalogApi, entity, alertApi, t, errorApi]);\n\n return (\n <EntityInfoCard\n title={t('aboutCard.title')}\n headerActions={\n <>\n {allowRefresh && canRefresh && (\n <IconButton\n aria-label={t('aboutCard.refreshButtonAriaLabel')}\n title={t('aboutCard.refreshButtonTitle')}\n onClick={refreshEntity}\n >\n <CachedIcon />\n </IconButton>\n )}\n <IconButton\n component={Link}\n aria-label={t('aboutCard.editButtonAriaLabel')}\n disabled={!entityMetadataEditUrl}\n title={t('aboutCard.editButtonTitle')}\n to={entityMetadataEditUrl ?? '#'}\n >\n <EditIcon />\n </IconButton>\n {sourceTemplateRef && templateRoute && (\n <IconButton\n component={Link}\n title={t('aboutCard.createSimilarButtonTitle')}\n to={templateRoute({\n namespace: sourceTemplateRef.namespace,\n templateName: sourceTemplateRef.name,\n })}\n >\n <AppIcon id=\"scaffolder\" />\n </IconButton>\n )}\n </>\n }\n >\n <div className={classes.linkContainer}>\n {iconLinks ?? <DefaultAboutCardSubheader />}\n </div>\n <AboutContent entity={entity} />\n </EntityInfoCard>\n );\n}\n\n/**\n * Exported publicly via the EntityAboutCard\n *\n * NOTE: We generally do not accept pull requests to extend this class with props\n * and customizability. If you need to tweak it, consider making a bespoke card\n * in your own repository instead, that is perfect for your own needs.\n */\nexport function AboutCard() {\n return <InternalAboutCard />;\n}\n","/*\n * Copyright 2020 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 Entity,\n entityKindSchemaValidator,\n KindValidator,\n} from '@backstage/catalog-model';\nimport { JsonObject } from '@backstage/types';\nimport schema from './Template.v1beta3.schema.json';\n\n/**\n * Backstage catalog Template kind Entity. Templates are used by the Scaffolder\n * plugin to create new entities, such as Components.\n *\n * @public\n */\nexport interface TemplateEntityV1beta3 extends Entity {\n /**\n * The apiVersion string of the TaskSpec.\n */\n apiVersion: 'scaffolder.backstage.io/v1beta3';\n /**\n * The kind of the entity\n */\n kind: 'Template';\n /**\n * The specification of the Template Entity\n */\n spec: {\n /**\n * The type that the Template will create. For example service, website or library.\n */\n type: string;\n\n /**\n * Template specific configuration of the presentation layer.\n */\n presentation?: TemplatePresentationV1beta3;\n\n /**\n * Recovery strategy for the template\n */\n EXPERIMENTAL_recovery?: TemplateRecoveryV1beta3;\n\n /**\n * Form decorators to be run before submission.\n */\n formDecorators?: { id: string; input?: JsonObject }[];\n\n /**\n * Form decorators to be run before submission.\n *\n * @deprecated Use `spec.formDecorators` instead.\n */\n EXPERIMENTAL_formDecorators?: { id: string; input?: JsonObject }[];\n\n /**\n * This is a JSONSchema or an array of JSONSchema's which is used to render a form in the frontend\n * to collect user input and validate it against that schema. This can then be used in the `steps` part below to template\n * variables passed from the user into each action in the template.\n */\n parameters?: TemplateParametersV1beta3 | TemplateParametersV1beta3[];\n /**\n * Configuration for secrets that are passed during task creation.\n * The schema field contains a JSONSchema used to validate secrets.\n */\n secrets?: {\n schema?: JsonObject;\n };\n /**\n * A list of steps to be executed in sequence which are defined by the template. These steps are a list of the underlying\n * javascript action and some optional input parameters that may or may not have been collected from the end user.\n */\n steps: Array<TemplateEntityStepV1beta3>;\n /**\n * The output is an object where template authors can pull out information from template actions and return them in a known standard way.\n */\n output?: { [name: string]: string };\n /**\n * The owner entityRef of the TemplateEntity\n */\n owner?: string;\n /**\n * Specifies the lifecycle phase of the TemplateEntity\n */\n lifecycle?: string;\n };\n}\n\n/**\n * Depends on how you designed your task you might tailor the behaviour for each of them.\n *\n * @public\n */\nexport interface TemplateRecoveryV1beta3 extends JsonObject {\n /**\n *\n * none - not recover, let the task be marked as failed\n * startOver - do recover, start the execution of the task from the first step.\n *\n * @public\n */\n EXPERIMENTAL_strategy?: 'none' | 'startOver';\n}\n\n/**\n * The presentation of the template.\n *\n * @public\n */\nexport interface TemplatePresentationV1beta3 extends JsonObject {\n /**\n * Overrides default buttons' text\n */\n buttonLabels?: {\n /**\n * The text for the button which leads to the previous template page\n */\n backButtonText?: string;\n /**\n * The text for the button which starts the execution of the template\n */\n createButtonText?: string;\n /**\n * The text for the button which opens template's review/summary\n */\n reviewButtonText?: string;\n };\n}\n\n/**\n * Step that is part of a Template Entity.\n *\n * @public\n */\nexport interface TemplateEntityStepV1beta3 extends JsonObject {\n id?: string;\n name?: string;\n action: string;\n input?: JsonObject;\n if?: string | boolean;\n 'backstage:permissions'?: TemplatePermissionsV1beta3;\n}\n\n/**\n * The shape of each entry of parameters which gets rendered\n * as a separate step in the wizard input\n *\n * @public\n */\nexport type TemplateParameterSchema = {\n title: string;\n description?: string;\n presentation?: TemplatePresentationV1beta3;\n steps: Array<{\n title: string;\n description?: string;\n schema: JsonObject;\n }>;\n formDecorators?: { id: string; input?: JsonObject }[];\n /**\n * @deprecated Use {@link TemplateParameterSchema.formDecorators} instead.\n */\n EXPERIMENTAL_formDecorators?: { id: string; input?: JsonObject }[];\n};\n\n/**\n * Parameter that is part of a Template Entity.\n *\n * @public\n */\nexport interface TemplateParametersV1beta3 extends JsonObject {\n 'backstage:permissions'?: TemplatePermissionsV1beta3;\n}\n\n/**\n * Access control properties for parts of a template.\n *\n * @public\n */\nexport interface TemplatePermissionsV1beta3 extends JsonObject {\n tags?: string[];\n}\n\nconst validator = entityKindSchemaValidator(schema);\n\n/**\n * Entity data validator for {@link TemplateEntityV1beta3}.\n *\n * @public\n */\nexport const templateEntityV1beta3Validator: KindValidator = {\n // TODO(freben): Emulate the old KindValidator until we fix that type\n async check(data: Entity) {\n return validator(data) === data;\n },\n};\n\n/**\n * Typeguard for filtering entities and ensuring v1beta3 entities\n * @public\n */\nexport const isTemplateEntityV1beta3 = (\n entity: Entity,\n): entity is TemplateEntityV1beta3 =>\n entity.apiVersion === 'scaffolder.backstage.io/v1beta3' &&\n entity.kind === 'Template';\n","/*\n * Copyright 2020 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 */\nimport {\n CompoundEntityRef,\n Entity,\n parseEntityRef,\n} from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport useAsync from 'react-use/lib/useAsync';\n\n// todo: should this be a constant in a scaffolder package?\nconst SOURCE_TEMPLATE_ANNOTATION = 'backstage.io/source-template';\n\n/**\n * Returns the compound entity ref of the source template that was used to\n * create this entity (assuming that it still exists and the user has access\n * to it).\n */\nexport const useSourceTemplateCompoundEntityRef = (entity: Entity) => {\n const catalogApi = useApi(catalogApiRef);\n const { value: sourceTemplateRef } = useAsync(async () => {\n const refCandidate =\n entity.metadata.annotations?.[SOURCE_TEMPLATE_ANNOTATION];\n let compoundRefCandidate: CompoundEntityRef | undefined;\n\n if (!refCandidate) {\n return undefined;\n }\n\n try {\n // Check for access and that this template still exists.\n const template = await catalogApi.getEntityByRef(refCandidate);\n compoundRefCandidate = parseEntityRef(refCandidate);\n\n return template !== undefined ? compoundRefCandidate : undefined;\n } catch {\n return undefined;\n }\n }, [catalogApi, entity]);\n\n return sourceTemplateRef;\n};\n","/*\n * Copyright 2020 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 Box from '@material-ui/core/Box';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport LanguageIcon from '@material-ui/icons/Language';\nimport { Link } from '@backstage/core-components';\nimport { IconComponent } from '@backstage/core-plugin-api';\n\nconst useStyles = makeStyles({\n svgIcon: {\n display: 'inline-block',\n '& svg': {\n display: 'inline-block',\n fontSize: 'inherit',\n verticalAlign: 'baseline',\n },\n },\n});\n\nexport function IconLink(props: {\n href: string;\n text?: string;\n Icon?: IconComponent;\n}) {\n const { href, text, Icon } = props;\n const classes = useStyles();\n\n return (\n <Box display=\"flex\">\n <Box mr={1} className={classes.svgIcon}>\n <Typography component=\"div\">\n {Icon ? <Icon /> : <LanguageIcon />}\n </Typography>\n </Box>\n <Box flexGrow=\"1\">\n <Link to={href} target=\"_blank\" rel=\"noopener\">\n {text || href}\n </Link>\n </Box>\n </Box>\n );\n}\n","/*\n * Copyright 2020 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 useMediaQuery from '@material-ui/core/useMediaQuery';\nimport { Theme } from '@material-ui/core/styles';\nimport { Breakpoint, ColumnBreakpoints } from './types';\n\nconst colDefaults: ColumnBreakpoints = {\n xs: 1,\n sm: 1,\n md: 1,\n lg: 2,\n xl: 3,\n};\n\nexport function useDynamicColumns(\n cols: ColumnBreakpoints | number | undefined,\n): number {\n const matches: (Breakpoint | null)[] = [\n useMediaQuery((theme: Theme) => theme.breakpoints.up('xl')) ? 'xl' : null,\n useMediaQuery((theme: Theme) => theme.breakpoints.up('lg')) ? 'lg' : null,\n useMediaQuery((theme: Theme) => theme.breakpoints.up('md')) ? 'md' : null,\n useMediaQuery((theme: Theme) => theme.breakpoints.up('sm')) ? 'sm' : null,\n useMediaQuery((theme: Theme) => theme.breakpoints.up('xs')) ? 'xs' : null,\n ];\n\n let numOfCols = 1;\n\n if (typeof cols === 'number') {\n numOfCols = cols;\n } else {\n const breakpoint = matches.find(k => k !== null) ?? 'xs';\n numOfCols = cols?.[breakpoint] ?? colDefaults[breakpoint];\n }\n\n return numOfCols;\n}\n","/*\n * Copyright 2020 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 { Grid, type Columns } from '@backstage/ui';\nimport { IconLink } from './IconLink';\nimport { ColumnBreakpoints } from './types';\nimport { useDynamicColumns } from './useDynamicColumns';\nimport { IconComponent } from '@backstage/core-plugin-api';\n\nexport interface LinksGridListItem {\n href: string;\n text?: string;\n Icon?: IconComponent;\n}\n\ninterface LinksGridListProps {\n items: LinksGridListItem[];\n cols?: ColumnBreakpoints | number;\n}\n\nexport function LinksGridList(props: LinksGridListProps) {\n const { items, cols = undefined } = props;\n const numOfCols = useDynamicColumns(cols);\n\n return (\n <Grid.Root\n columns={String(Math.min(Math.max(numOfCols, 1), 12)) as Columns}\n gap=\"2\"\n >\n {items.map(({ text, href, Icon }, i) => (\n <IconLink key={i} href={href} text={text ?? href} Icon={Icon} />\n ))}\n </Grid.Root>\n );\n}\n"],"names":["instance","b","options","isJsonObject","value","Array","isJsonObjectDeep","seen","Set","Object","v","isJsonValueDeep","validateMetaSchema","schema","InputError","ajv","Ajv","ajvErrors","result","error","message","z","x","jsonSchemaSchema","ctx","isError","opDeclareAnnotationV1Schema","opDeclareKindV1Schema","fullKindSchema","reduceKindSchema","parsed","allOf","rest","type","allProperties","kindRest","apiVersion","kind","properties","FORBIDDEN_SCHEMA_ROOT_FIELDS","FORBIDDEN_SCHEMA_STRUCTURAL_FIELDS","relationFieldSchema","opDeclareKindVersionV1Schema","opsFromCatalogModelAddKindVersion","definition","ops","version","jsonSchema","name","validateKindRootSchemaSemantics","field","rootProperties","fieldName","fieldSchema","specType","undefined","input","opDeclareLabelV1Schema","opDeclareRelationV1Schema","createDeclareRelationOp","opRemoveAnnotationV1Schema","opRemoveKindV1Schema","opRemoveLabelV1Schema","opRemoveTagV1Schema","opDeclareTagV1Schema","opUpdateAnnotationV1Schema","opUpdateKindV1Schema","opUpdateKindVersionV1Schema","opUpdateLabelV1Schema","opUpdateRelationV1Schema","createUpdateRelationOp","opUpdateTagV1Schema","OpaqueCatalogModelLayer","OpaqueType","DefaultCatalogModelLayerBuilder","opsFromCatalogModelUpdateKind","relation","opsFromCatalogModelRelationPair","relationPair","firstKind","secondKind","opsFromCatalogModelUpdateRelationPair","annotation","opsFromCatalogModelAnnotation","opsFromCatalogModelUpdateAnnotation","label","opsFromCatalogModelLabel","opsFromCatalogModelUpdateLabel","tag","layer","internal","RELATION_OWNED_BY","RELATION_DEPENDS_ON","RELATION_PART_OF","RELATION_HAS_PART","model","CardDefinition","defineComponent","styles","CardHeaderDefinition","CardBodyDefinition","CardFooterDefinition","Card","forwardRef","props","ref","ownProps","restProps","dataAttributes","utilityStyle","useDefinition","classes","children","onPress","href","linkTarget","rel","download","isInteractive","triggerRef","useRef","handleClick","useCallback","e","targetNode","targetElement","Element","window","MouseEvent","Box","Link","RAButton","CardHeader","CardBody","CardFooter","GridDefinition","GridItemDefinition","Grid","childrenWithBgProvider","useStyles","makeStyles","EntityInfoCard","title","headerActions","footerActions","className","classNames","Flex","Text","EntityRefLinks","entityRefs","hideIcons","linkProps","r","i","entityRefString","stringifyEntityRef","Fragment","EntityRefLink","getEntityRelations","entity","relationType","filter","entityNames","parseEntityRef","JSON","compiledSchemaCache","Map","refDependencyCandidates","entityEnvelopeSchema","entitySchema","entityMetaSchema","commonSchema","compileAjvSchema","disableCache","cacheKey","cached","extraSchemas","getExtraSchemas","selected","todo","getAllRefs","current","key","match","c","compiled","RESOURCE_TYPE_SCAFFOLDER_TEMPLATE","RESOURCE_TYPE_SCAFFOLDER_TASK","createPermission","taskCreatePermission","theme","AboutField","t","useTranslationRef","catalogTranslationRef","childElements","useElementFilter","content","Typography","AboutContent","entitySourceLocation","isSystem","isResource","isComponent","isAPI","isTemplate","isLocation","isGroup","partOfSystemRelations","partOfComponentRelations","partOfDomainRelations","ownedByRelations","getEntitySourceLocation","columns","MarkdownContent","Chip","LinksGridList","target","getLocationTargetHref","srcLocationUrl","URL","DefaultAboutCardSubheader","useEntity","catalogSourceIconLink","useCatalogSourceIconLinkProps","techdocsreaderIconLink","useTechdocsReaderIconLinkProps","viewTechdocLink","useRouteRef","viewTechDocRouteRef","TECHDOCS_ANNOTATION","TECHDOCS_EXTERNAL_ANNOTATION","DocsIcon","buildTechDocsURL","scaffolderTemplateIconLink","useScaffolderTemplateIconLinkProps","app","useApp","templateRoute","createFromTemplateRouteRef","Icon","CreateComponentIcon","canCreateTemplateTask","usePermission","DEFAULT_NAMESPACE","links","isTemplateEntityV1beta3","HeaderIconLinkRow","InternalAboutCard","iconLinks","catalogApi","useApi","catalogApiRef","alertApi","alertApiRef","errorApi","errorApiRef","sourceTemplateRef","useSourceTemplateCompoundEntityRef","useAsync","compoundRefCandidate","refCandidate","template","canRefresh","useEntityPermission","catalogEntityRefreshPermission","entityMetadataEditUrl","ANNOTATION_EDIT_URL","entityLocation","ANNOTATION_LOCATION","allowRefresh","refreshEntity","IconButton","CachedIcon","EditIcon","AppIcon","IconLink","text","LanguageIcon","colDefaults","items","cols","numOfCols","useDynamicColumns","matches","useMediaQuery","breakpoint","k","String","Math"],"mappings":"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"}