@backstage/plugin-techdocs-node 2.0.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +54 -5
- package/dist/extensions.cjs.js.map +1 -1
- package/dist/helpers.cjs.js.map +1 -1
- package/dist/index.cjs.js +2 -0
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +19 -4
- package/dist/stages/generate/DockerContainerRunner.cjs.js.map +1 -1
- package/dist/stages/generate/generators.cjs.js +22 -6
- package/dist/stages/generate/generators.cjs.js.map +1 -1
- package/dist/stages/generate/helpers.cjs.js +52 -34
- package/dist/stages/generate/helpers.cjs.js.map +1 -1
- package/dist/stages/generate/index.cjs.js.map +1 -1
- package/dist/stages/generate/mkdocsPatchers.cjs.js +21 -3
- package/dist/stages/generate/mkdocsPatchers.cjs.js.map +1 -1
- package/dist/stages/generate/techdocs.cjs.js +2 -1
- package/dist/stages/generate/techdocs.cjs.js.map +1 -1
- package/dist/stages/prepare/dir.cjs.js.map +1 -1
- package/dist/stages/prepare/preparers.cjs.js.map +1 -1
- package/dist/stages/prepare/url.cjs.js.map +1 -1
- package/dist/stages/publish/awsS3.cjs.js.map +1 -1
- package/dist/stages/publish/azureBlobStorage.cjs.js.map +1 -1
- package/dist/stages/publish/googleStorage.cjs.js.map +1 -1
- package/dist/stages/publish/helpers.cjs.js.map +1 -1
- package/dist/stages/publish/local.cjs.js.map +1 -1
- package/dist/stages/publish/migrations/GoogleMigration.cjs.js.map +1 -1
- package/dist/stages/publish/openStackSwift.cjs.js.map +1 -1
- package/dist/stages/publish/publish.cjs.js.map +1 -1
- package/dist/techdocsTypes.cjs.js +6 -0
- package/dist/techdocsTypes.cjs.js.map +1 -0
- package/package.json +12 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,17 +1,66 @@
|
|
|
1
1
|
# @backstage/plugin-techdocs-node
|
|
2
2
|
|
|
3
|
-
## 2.0
|
|
3
|
+
## 2.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 4d4f987: Add engine abstraction layer for multi-engine TechDocs support. Introduces `--engine` flag, engine config map, generator registry with `backstage.io/techdocs-engine` annotation support, `engine` field in `techdocs_metadata.json`, `serve:raw` command, and live-reload adapter interface. MkDocs remains the default with no behavior change.
|
|
8
|
+
|
|
9
|
+
The built-in generator is now registered under `mkdocs`; the previous `techdocs` key is kept as an alias, so existing `generators.register('techdocs', ...)` calls continue to work. The CLI's `--engine` flag takes precedence over the `backstage.io/techdocs-engine` annotation for all commands, and `serve:mkdocs` and the `--mkdocs-parameter-*` flags now print deprecation warnings.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 9fc5387: Improved handling of mapping-style Markdown extension configuration.
|
|
14
|
+
- 0fd5fe5: Fixed TechDocs allowing `custom_icons` paths in `mkdocs.yml` that resolve outside the documentation input directory. A `custom_icons` option with such a path is now removed from the configuration with a warning.
|
|
15
|
+
- 8a37336: Fixed TechDocs generation rejecting `mkdocs.yml` files that use the emoji indexes and generators or the `pymdownx.superfences` custom fence formats documented by mkdocs-material, pymdown-extensions and mkdocs-mermaid2.
|
|
16
|
+
- 76ac6ed: Updated dependency `js-yaml` to `^5.0.0`.
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @backstage/integration@2.1.3
|
|
19
|
+
- @backstage/backend-plugin-api@1.11.0
|
|
20
|
+
- @backstage/config@1.3.10
|
|
21
|
+
- @backstage/errors@1.3.2
|
|
22
|
+
- @backstage/plugin-techdocs-common@0.1.2
|
|
23
|
+
- @backstage/catalog-model@1.10.2
|
|
24
|
+
- @backstage/integration-aws-node@0.2.3
|
|
25
|
+
- @backstage/plugin-search-common@1.2.26
|
|
26
|
+
|
|
27
|
+
## 2.0.3-next.2
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- 76ac6ed: Updated dependency `js-yaml` to `^5.0.0`.
|
|
32
|
+
- Updated dependencies
|
|
33
|
+
- @backstage/integration@2.1.3-next.1
|
|
34
|
+
- @backstage/plugin-techdocs-common@0.1.2-next.0
|
|
35
|
+
|
|
36
|
+
## 2.0.3-next.1
|
|
37
|
+
|
|
38
|
+
### Patch Changes
|
|
39
|
+
|
|
40
|
+
- Bumped version to account for a patch release.
|
|
41
|
+
|
|
42
|
+
## 2.0.2-next.1
|
|
4
43
|
|
|
5
44
|
### Patch Changes
|
|
6
45
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
46
|
+
- 9fc5387: Improved handling of mapping-style Markdown extension configuration.
|
|
47
|
+
- 0fd5fe5: Fixed TechDocs allowing `custom_icons` paths in `mkdocs.yml` that resolve outside the documentation input directory. A `custom_icons` option with such a path is now removed from the configuration with a warning.
|
|
48
|
+
- 8a37336: Fixed TechDocs generation rejecting `mkdocs.yml` files that use the emoji indexes and generators or the `pymdownx.superfences` custom fence formats documented by mkdocs-material, pymdown-extensions and mkdocs-mermaid2.
|
|
49
|
+
- Updated dependencies
|
|
50
|
+
- @backstage/backend-plugin-api@1.11.0-next.1
|
|
9
51
|
|
|
10
|
-
## 2.0.1
|
|
52
|
+
## 2.0.1-next.0
|
|
11
53
|
|
|
12
54
|
### Patch Changes
|
|
13
55
|
|
|
14
|
-
-
|
|
56
|
+
- Updated dependencies
|
|
57
|
+
- @backstage/integration@2.1.3-next.0
|
|
58
|
+
- @backstage/config@1.3.10-next.0
|
|
59
|
+
- @backstage/errors@1.3.2-next.0
|
|
60
|
+
- @backstage/backend-plugin-api@1.10.2-next.0
|
|
61
|
+
- @backstage/integration-aws-node@0.2.3-next.0
|
|
62
|
+
- @backstage/catalog-model@1.10.2-next.0
|
|
63
|
+
- @backstage/plugin-search-common@1.2.26-next.0
|
|
15
64
|
|
|
16
65
|
## 2.0.0
|
|
17
66
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensions.cjs.js","sources":["../src/extensions.ts"],"sourcesContent":["/*\n * Copyright 2023 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 { createExtensionPoint } from '@backstage/backend-plugin-api';\nimport { DocsBuildStrategy } from './techdocsTypes';\nimport {\n PreparerBase,\n PublisherBase,\n PublisherType,\n RemoteProtocol,\n
|
|
1
|
+
{"version":3,"file":"extensions.cjs.js","sources":["../src/extensions.ts"],"sourcesContent":["/*\n * Copyright 2023 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 { createExtensionPoint } from '@backstage/backend-plugin-api';\nimport { DocsBuildStrategy } from './techdocsTypes';\nimport {\n GeneratorBase,\n PreparerBase,\n PublisherBase,\n PublisherType,\n RemoteProtocol,\n SupportedGeneratorKey,\n} from './stages';\nimport * as winston from 'winston';\nimport { PublisherSettings } from './stages/publish/types';\n\n/**\n * Extension point type for configuring TechDocs builds.\n *\n * @public\n */\nexport interface TechdocsBuildsExtensionPoint {\n setBuildStrategy(buildStrategy: DocsBuildStrategy): void;\n setBuildLogTransport(transport: winston.transport): void;\n}\n\n/**\n * Extension point for configuring TechDocs builds.\n *\n * @public\n */\nexport const techdocsBuildsExtensionPoint =\n createExtensionPoint<TechdocsBuildsExtensionPoint>({\n id: 'techdocs.builds',\n });\n\n/**\n * Extension point type for configuring TechDocs generators.\n *\n * Use `registerGenerator` to add an engine-specific generator from a backend\n * module (e.g. `plugin-techdocs-backend-module-zensical`). The key corresponds\n * to the `backstage.io/techdocs-engine` entity annotation value.\n *\n * `setTechdocsGenerator` is kept for backwards compatibility — it replaces the\n * default MkDocs generator.\n *\n * @public\n */\nexport interface TechdocsGeneratorExtensionPoint {\n setTechdocsGenerator(generator: GeneratorBase): void;\n registerGenerator(key: SupportedGeneratorKey, generator: GeneratorBase): void;\n}\n\n/**\n * Extension point for configuring a custom TechDocs generator\n *\n * @public\n */\nexport const techdocsGeneratorExtensionPoint =\n createExtensionPoint<TechdocsGeneratorExtensionPoint>({\n id: 'techdocs.generator',\n });\n\n/**\n * Extension point type for configuring a custom TechDocs preparer\n *\n * @public\n */\nexport interface TechdocsPreparerExtensionPoint {\n registerPreparer(protocol: RemoteProtocol, preparer: PreparerBase): void;\n}\n\n/**\n * Extension point for configuring a custom TechDocs preparer\n *\n * @public\n */\nexport const techdocsPreparerExtensionPoint =\n createExtensionPoint<TechdocsPreparerExtensionPoint>({\n id: 'techdocs.preparer',\n });\n\n/**\n * Extension point type for configuring a custom TechDocs publisher\n *\n * @public\n */\nexport interface TechdocsPublisherExtensionPoint {\n registerPublisher(type: PublisherType, publisher: PublisherBase): void;\n registerPublisherSettings<T extends keyof PublisherSettings>(\n publisher: T,\n settings: PublisherSettings[T],\n ): void;\n}\n\n/**\n * Extension point for configuring a custom TechDocs publisher\n *\n * @public\n */\nexport const techdocsPublisherExtensionPoint =\n createExtensionPoint<TechdocsPublisherExtensionPoint>({\n id: 'techdocs.publisher',\n });\n"],"names":["createExtensionPoint"],"mappings":";;;;AA2CO,MAAM,+BACXA,qCAAA,CAAmD;AAAA,EACjD,EAAA,EAAI;AACN,CAAC;AAwBI,MAAM,kCACXA,qCAAA,CAAsD;AAAA,EACpD,EAAA,EAAI;AACN,CAAC;AAgBI,MAAM,iCACXA,qCAAA,CAAqD;AAAA,EACnD,EAAA,EAAI;AACN,CAAC;AAoBI,MAAM,kCACXA,qCAAA,CAAsD;AAAA,EACpD,EAAA,EAAI;AACN,CAAC;;;;;"}
|
package/dist/helpers.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.cjs.js","sources":["../src/helpers.ts"],"sourcesContent":["/*\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 LoggerService,\n UrlReaderService,\n resolveSafeChildPath,\n} from '@backstage/backend-plugin-api';\nimport {\n Entity,\n getEntitySourceLocation,\n parseLocationRef,\n} from '@backstage/catalog-model';\nimport { InputError } from '@backstage/errors';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common';\nimport path from 'node:path';\nimport { PreparerResponse, RemoteProtocol } from './stages/prepare/types';\n\n/**\n * Parsed location annotation\n * @public\n */\nexport type ParsedLocationAnnotation = {\n type: RemoteProtocol;\n target: string;\n};\n\n/**\n * Returns a parsed locations annotation\n * @public\n * @param annotationName - The name of the annotation in the entity metadata\n * @param entity - A TechDocs entity instance\n */\nexport const parseReferenceAnnotation = (\n annotationName: string,\n entity: Entity,\n): ParsedLocationAnnotation => {\n const annotation = entity.metadata.annotations?.[annotationName];\n if (!annotation) {\n throw new InputError(\n `No ${annotationName} annotation provided in entity: ${entity.metadata.name}`,\n );\n }\n\n const { type, target } = parseLocationRef(annotation);\n return {\n type: type as RemoteProtocol,\n target,\n };\n};\n\n/**\n * TechDocs references of type `dir` are relative the source location of the entity.\n * This function transforms relative references to absolute ones, based on the\n * location the entity was ingested from. If the entity was registered by a `url`\n * location, it returns a `url` location with a resolved target that points to the\n * targeted subfolder. If the entity was registered by a `file` location, it returns\n * an absolute `dir` location.\n * @public\n * @param entity - the entity with annotations\n * @param dirAnnotation - the parsed techdocs-ref annotation of type 'dir'\n * @param scmIntegrations - access to the scmIntegration to do url transformations\n * @throws if the entity doesn't specify a `dir` location or is ingested from an unsupported location.\n * @returns the transformed location with an absolute target.\n */\nexport const transformDirLocation = (\n entity: Entity,\n dirAnnotation: ParsedLocationAnnotation,\n scmIntegrations: ScmIntegrationRegistry,\n): { type: 'dir' | 'url'; target: string } => {\n const location = getEntitySourceLocation(entity);\n\n switch (location.type) {\n case 'url': {\n const target = scmIntegrations.resolveUrl({\n url: dirAnnotation.target,\n base: location.target,\n });\n\n return {\n type: 'url',\n target,\n };\n }\n\n case 'file': {\n // only permit targets in the same folder as the target of the `file` location!\n const target = resolveSafeChildPath(\n path.dirname(location.target),\n dirAnnotation.target,\n );\n\n return {\n type: 'dir',\n target,\n };\n }\n\n default:\n throw new InputError(`Unable to resolve location type ${location.type}`);\n }\n};\n\n/**\n * Returns an entity reference based on the TechDocs annotation type\n * @public\n * @param entity - A TechDocs instance\n * @param scmIntegration - An implementation for SCM integration API\n */\nexport const getLocationForEntity = (\n entity: Entity,\n scmIntegration: ScmIntegrationRegistry,\n): ParsedLocationAnnotation => {\n const annotation = parseReferenceAnnotation(TECHDOCS_ANNOTATION, entity);\n\n switch (annotation.type) {\n case 'url':\n return annotation;\n case 'dir':\n return transformDirLocation(entity, annotation, scmIntegration);\n default:\n throw new Error(`Invalid reference annotation ${annotation.type}`);\n }\n};\n\n/**\n * Returns a preparer response {@link PreparerResponse}\n * @public\n * @param reader - Read a tree of files from a repository\n * @param entity - A TechDocs entity instance\n * @param opts - Options for configuring the reader, e.g. logger, etag, etc.\n */\nexport const getDocFilesFromRepository = async (\n reader: UrlReaderService,\n entity: Entity,\n opts?: { etag?: string; logger?: LoggerService },\n): Promise<PreparerResponse> => {\n const { target } = parseReferenceAnnotation(TECHDOCS_ANNOTATION, entity);\n\n opts?.logger?.debug(`Reading files from ${target}`);\n // readTree will throw NotModifiedError if etag has not changed.\n const readTreeResponse = await reader.readTree(target, { etag: opts?.etag });\n const preparedDir = await readTreeResponse.dir();\n\n opts?.logger?.debug(`Tree downloaded and stored at ${preparedDir}`);\n\n return {\n preparedDir,\n etag: readTreeResponse.etag,\n };\n};\n"],"names":["InputError","parseLocationRef","getEntitySourceLocation","resolveSafeChildPath","path","TECHDOCS_ANNOTATION"],"mappings":";;;;;;;;;;;;AA+CO,MAAM,wBAAA,GAA2B,CACtC,cAAA,EACA,MAAA,KAC6B;AAC7B,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,cAAc,CAAA;AAC/D,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,MAAM,IAAIA,iBAAA;AAAA,MACR,CAAA,GAAA,EAAM,cAAc,CAAA,gCAAA,EAAmC,MAAA,CAAO,SAAS,IAAI,CAAA;AAAA,KAC7E;AAAA,EACF;AAEA,EAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAO,GAAIC,8BAAiB,UAAU,CAAA;AACpD,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA;AAAA,GACF;AACF;AAgBO,MAAM,oBAAA,GAAuB,CAClC,MAAA,EACA,aAAA,EACA,eAAA,KAC4C;AAC5C,EAAA,MAAM,QAAA,GAAWC,qCAAwB,MAAM,CAAA;AAE/C,EAAA,QAAQ,SAAS,IAAA;AAAM,IACrB,KAAK,KAAA,EAAO;AACV,MAAA,MAAM,MAAA,GAAS,gBAAgB,UAAA,CAAW;AAAA,QACxC,KAAK,aAAA,CAAc,MAAA;AAAA,QACnB,MAAM,QAAA,CAAS;AAAA,OAChB,CAAA;AAED,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,KAAA;AAAA,QACN;AAAA,OACF;AAAA,IACF;AAAA,IAEA,KAAK,MAAA,EAAQ;AAEX,MAAA,MAAM,MAAA,GAASC,qCAAA;AAAA,QACbC,qBAAA,CAAK,OAAA,CAAQ,QAAA,CAAS,MAAM,CAAA;AAAA,QAC5B,aAAA,CAAc;AAAA,OAChB;AAEA,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,KAAA;AAAA,QACN;AAAA,OACF;AAAA,IACF;AAAA,IAEA;AACE,MAAA,MAAM,IAAIJ,iBAAA,CAAW,CAAA,gCAAA,EAAmC,QAAA,CAAS,IAAI,CAAA,CAAE,CAAA;AAAA;AAE7E;AAQO,MAAM,oBAAA,GAAuB,CAClC,MAAA,EACA,cAAA,KAC6B;AAC7B,EAAA,MAAM,UAAA,GAAa,wBAAA,CAAyBK,wCAAA,EAAqB,MAAM,CAAA;AAEvE,EAAA,QAAQ,WAAW,IAAA;AAAM,IACvB,KAAK,KAAA;AACH,MAAA,OAAO,UAAA;AAAA,IACT,KAAK,KAAA;AACH,MAAA,OAAO,oBAAA,CAAqB,MAAA,EAAQ,UAAA,EAAY,cAAc,CAAA;AAAA,IAChE;AACE,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgC,UAAA,CAAW,IAAI,CAAA,CAAE,CAAA;AAAA;AAEvE;AASO,MAAM,yBAAA,GAA4B,OACvC,MAAA,EACA,MAAA,EACA,IAAA,KAC8B;AAC9B,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,wBAAA,CAAyBA,0CAAqB,MAAM,CAAA;AAEvE,EAAA,IAAA,EAAM,MAAA,EAAQ,KAAA,CAAM,CAAA,mBAAA,EAAsB,MAAM,CAAA,CAAE,CAAA;AAElD,EAAA,MAAM,gBAAA,GAAmB,MAAM,MAAA,CAAO,QAAA,CAAS,QAAQ,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,CAAA;AAC3E,EAAA,MAAM,WAAA,GAAc,MAAM,gBAAA,CAAiB,GAAA,EAAI;AAE/C,EAAA,IAAA,EAAM,MAAA,EAAQ,KAAA,CAAM,CAAA,8BAAA,EAAiC,WAAW,CAAA,CAAE,CAAA;AAElE,EAAA,OAAO;AAAA,IACL,WAAA;AAAA,IACA,MAAM,gBAAA,CAAiB;AAAA,GACzB;AACF
|
|
1
|
+
{"version":3,"file":"helpers.cjs.js","sources":["../src/helpers.ts"],"sourcesContent":["/*\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 LoggerService,\n UrlReaderService,\n resolveSafeChildPath,\n} from '@backstage/backend-plugin-api';\nimport {\n Entity,\n getEntitySourceLocation,\n parseLocationRef,\n} from '@backstage/catalog-model';\nimport { InputError } from '@backstage/errors';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common';\nimport path from 'node:path';\nimport { PreparerResponse, RemoteProtocol } from './stages/prepare/types';\n\n/**\n * Parsed location annotation\n * @public\n */\nexport type ParsedLocationAnnotation = {\n type: RemoteProtocol;\n target: string;\n};\n\n/**\n * Returns a parsed locations annotation\n * @public\n * @param annotationName - The name of the annotation in the entity metadata\n * @param entity - A TechDocs entity instance\n */\nexport const parseReferenceAnnotation = (\n annotationName: string,\n entity: Entity,\n): ParsedLocationAnnotation => {\n const annotation = entity.metadata.annotations?.[annotationName];\n if (!annotation) {\n throw new InputError(\n `No ${annotationName} annotation provided in entity: ${entity.metadata.name}`,\n );\n }\n\n const { type, target } = parseLocationRef(annotation);\n return {\n type: type as RemoteProtocol,\n target,\n };\n};\n\n/**\n * TechDocs references of type `dir` are relative the source location of the entity.\n * This function transforms relative references to absolute ones, based on the\n * location the entity was ingested from. If the entity was registered by a `url`\n * location, it returns a `url` location with a resolved target that points to the\n * targeted subfolder. If the entity was registered by a `file` location, it returns\n * an absolute `dir` location.\n * @public\n * @param entity - the entity with annotations\n * @param dirAnnotation - the parsed techdocs-ref annotation of type 'dir'\n * @param scmIntegrations - access to the scmIntegration to do url transformations\n * @throws if the entity doesn't specify a `dir` location or is ingested from an unsupported location.\n * @returns the transformed location with an absolute target.\n */\nexport const transformDirLocation = (\n entity: Entity,\n dirAnnotation: ParsedLocationAnnotation,\n scmIntegrations: ScmIntegrationRegistry,\n): { type: 'dir' | 'url'; target: string } => {\n const location = getEntitySourceLocation(entity);\n\n switch (location.type) {\n case 'url': {\n const target = scmIntegrations.resolveUrl({\n url: dirAnnotation.target,\n base: location.target,\n });\n\n return {\n type: 'url',\n target,\n };\n }\n\n case 'file': {\n // only permit targets in the same folder as the target of the `file` location!\n const target = resolveSafeChildPath(\n path.dirname(location.target),\n dirAnnotation.target,\n );\n\n return {\n type: 'dir',\n target,\n };\n }\n\n default:\n throw new InputError(`Unable to resolve location type ${location.type}`);\n }\n};\n\n/**\n * Returns an entity reference based on the TechDocs annotation type\n * @public\n * @param entity - A TechDocs instance\n * @param scmIntegration - An implementation for SCM integration API\n */\nexport const getLocationForEntity = (\n entity: Entity,\n scmIntegration: ScmIntegrationRegistry,\n): ParsedLocationAnnotation => {\n const annotation = parseReferenceAnnotation(TECHDOCS_ANNOTATION, entity);\n\n switch (annotation.type) {\n case 'url':\n return annotation;\n case 'dir':\n return transformDirLocation(entity, annotation, scmIntegration);\n default:\n throw new Error(`Invalid reference annotation ${annotation.type}`);\n }\n};\n\n/**\n * Returns a preparer response {@link PreparerResponse}\n * @public\n * @param reader - Read a tree of files from a repository\n * @param entity - A TechDocs entity instance\n * @param opts - Options for configuring the reader, e.g. logger, etag, etc.\n */\nexport const getDocFilesFromRepository = async (\n reader: UrlReaderService,\n entity: Entity,\n opts?: { etag?: string; logger?: LoggerService },\n): Promise<PreparerResponse> => {\n const { target } = parseReferenceAnnotation(TECHDOCS_ANNOTATION, entity);\n\n opts?.logger?.debug(`Reading files from ${target}`);\n // readTree will throw NotModifiedError if etag has not changed.\n const readTreeResponse = await reader.readTree(target, { etag: opts?.etag });\n const preparedDir = await readTreeResponse.dir();\n\n opts?.logger?.debug(`Tree downloaded and stored at ${preparedDir}`);\n\n return {\n preparedDir,\n etag: readTreeResponse.etag,\n };\n};\n"],"names":["InputError","parseLocationRef","getEntitySourceLocation","resolveSafeChildPath","path","TECHDOCS_ANNOTATION"],"mappings":";;;;;;;;;;;;AA+CO,MAAM,wBAAA,GAA2B,CACtC,cAAA,EACA,MAAA,KAC6B;AAC7B,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,cAAc,CAAA;AAC/D,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,MAAM,IAAIA,iBAAA;AAAA,MACR,CAAA,GAAA,EAAM,cAAc,CAAA,gCAAA,EAAmC,MAAA,CAAO,SAAS,IAAI,CAAA;AAAA,KAC7E;AAAA,EACF;AAEA,EAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAO,GAAIC,8BAAiB,UAAU,CAAA;AACpD,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA;AAAA,GACF;AACF;AAgBO,MAAM,oBAAA,GAAuB,CAClC,MAAA,EACA,aAAA,EACA,eAAA,KAC4C;AAC5C,EAAA,MAAM,QAAA,GAAWC,qCAAwB,MAAM,CAAA;AAE/C,EAAA,QAAQ,SAAS,IAAA;AAAM,IACrB,KAAK,KAAA,EAAO;AACV,MAAA,MAAM,MAAA,GAAS,gBAAgB,UAAA,CAAW;AAAA,QACxC,KAAK,aAAA,CAAc,MAAA;AAAA,QACnB,MAAM,QAAA,CAAS;AAAA,OAChB,CAAA;AAED,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,KAAA;AAAA,QACN;AAAA,OACF;AAAA,IACF;AAAA,IAEA,KAAK,MAAA,EAAQ;AAEX,MAAA,MAAM,MAAA,GAASC,qCAAA;AAAA,QACbC,qBAAA,CAAK,OAAA,CAAQ,QAAA,CAAS,MAAM,CAAA;AAAA,QAC5B,aAAA,CAAc;AAAA,OAChB;AAEA,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,KAAA;AAAA,QACN;AAAA,OACF;AAAA,IACF;AAAA,IAEA;AACE,MAAA,MAAM,IAAIJ,iBAAA,CAAW,CAAA,gCAAA,EAAmC,QAAA,CAAS,IAAI,CAAA,CAAE,CAAA;AAAA;AAE7E;AAQO,MAAM,oBAAA,GAAuB,CAClC,MAAA,EACA,cAAA,KAC6B;AAC7B,EAAA,MAAM,UAAA,GAAa,wBAAA,CAAyBK,wCAAA,EAAqB,MAAM,CAAA;AAEvE,EAAA,QAAQ,WAAW,IAAA;AAAM,IACvB,KAAK,KAAA;AACH,MAAA,OAAO,UAAA;AAAA,IACT,KAAK,KAAA;AACH,MAAA,OAAO,oBAAA,CAAqB,MAAA,EAAQ,UAAA,EAAY,cAAc,CAAA;AAAA,IAChE;AACE,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgC,UAAA,CAAW,IAAI,CAAA,CAAE,CAAA;AAAA;AAEvE;AASO,MAAM,yBAAA,GAA4B,OACvC,MAAA,EACA,MAAA,EACA,IAAA,KAC8B;AAC9B,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,wBAAA,CAAyBA,0CAAqB,MAAM,CAAA;AAEvE,EAAA,IAAA,EAAM,MAAA,EAAQ,KAAA,CAAM,CAAA,mBAAA,EAAsB,MAAM,CAAA,CAAE,CAAA;AAElD,EAAA,MAAM,gBAAA,GAAmB,MAAM,MAAA,CAAO,QAAA,CAAS,QAAQ,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,CAAA;AAC3E,EAAA,MAAM,WAAA,GAAc,MAAM,gBAAA,CAAiB,GAAA,EAAI;AAE/C,EAAA,IAAA,EAAM,MAAA,EAAQ,KAAA,CAAM,CAAA,8BAAA,EAAiC,WAAW,CAAA,CAAE,CAAA;AAElE,EAAA,OAAO;AAAA,IACL,WAAA;AAAA,IACA,MAAM,gBAAA,CAAiB;AAAA,GACzB;AACF;;;;;"}
|
package/dist/index.cjs.js
CHANGED
|
@@ -6,6 +6,7 @@ var url = require('./stages/prepare/url.cjs.js');
|
|
|
6
6
|
var preparers = require('./stages/prepare/preparers.cjs.js');
|
|
7
7
|
var publish = require('./stages/publish/publish.cjs.js');
|
|
8
8
|
var helpers = require('./helpers.cjs.js');
|
|
9
|
+
var techdocsTypes = require('./techdocsTypes.cjs.js');
|
|
9
10
|
var extensions = require('./extensions.cjs.js');
|
|
10
11
|
var generators = require('./stages/generate/generators.cjs.js');
|
|
11
12
|
var techdocs = require('./stages/generate/techdocs.cjs.js');
|
|
@@ -22,6 +23,7 @@ exports.getDocFilesFromRepository = helpers.getDocFilesFromRepository;
|
|
|
22
23
|
exports.getLocationForEntity = helpers.getLocationForEntity;
|
|
23
24
|
exports.parseReferenceAnnotation = helpers.parseReferenceAnnotation;
|
|
24
25
|
exports.transformDirLocation = helpers.transformDirLocation;
|
|
26
|
+
exports.TECHDOCS_ENGINE_CATALOG_ANNOTATION_KEY = techdocsTypes.TECHDOCS_ENGINE_CATALOG_ANNOTATION_KEY;
|
|
25
27
|
exports.techdocsBuildsExtensionPoint = extensions.techdocsBuildsExtensionPoint;
|
|
26
28
|
exports.techdocsGeneratorExtensionPoint = extensions.techdocsGeneratorExtensionPoint;
|
|
27
29
|
exports.techdocsPreparerExtensionPoint = extensions.techdocsPreparerExtensionPoint;
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -273,6 +273,7 @@ declare class TechdocsGenerator implements GeneratorBase {
|
|
|
273
273
|
*/
|
|
274
274
|
declare class Generators implements GeneratorBuilder {
|
|
275
275
|
private generatorMap;
|
|
276
|
+
private defaultEngine;
|
|
276
277
|
/**
|
|
277
278
|
* Returns a generators instance containing a generator for TechDocs
|
|
278
279
|
* @param config - A Backstage configuration
|
|
@@ -281,7 +282,7 @@ declare class Generators implements GeneratorBuilder {
|
|
|
281
282
|
static fromConfig(config: Config, options: {
|
|
282
283
|
logger: LoggerService;
|
|
283
284
|
containerRunner?: TechDocsContainerRunner;
|
|
284
|
-
customGenerator?:
|
|
285
|
+
customGenerator?: GeneratorBase;
|
|
285
286
|
}): Promise<GeneratorBuilder>;
|
|
286
287
|
/**
|
|
287
288
|
* Register a generator in the generators collection
|
|
@@ -587,6 +588,12 @@ interface DocsBuildStrategy {
|
|
|
587
588
|
entity: Entity;
|
|
588
589
|
}): Promise<boolean>;
|
|
589
590
|
}
|
|
591
|
+
/**
|
|
592
|
+
* A catalog annotation key indicating which TechDoc Generation Engine to use
|
|
593
|
+
*
|
|
594
|
+
* @public
|
|
595
|
+
*/
|
|
596
|
+
declare const TECHDOCS_ENGINE_CATALOG_ANNOTATION_KEY = "backstage.io/techdocs-engine";
|
|
590
597
|
|
|
591
598
|
/**
|
|
592
599
|
* Extension point type for configuring TechDocs builds.
|
|
@@ -604,12 +611,20 @@ interface TechdocsBuildsExtensionPoint {
|
|
|
604
611
|
*/
|
|
605
612
|
declare const techdocsBuildsExtensionPoint: _backstage_backend_plugin_api.ExtensionPoint<TechdocsBuildsExtensionPoint>;
|
|
606
613
|
/**
|
|
607
|
-
* Extension point type for configuring
|
|
614
|
+
* Extension point type for configuring TechDocs generators.
|
|
615
|
+
*
|
|
616
|
+
* Use `registerGenerator` to add an engine-specific generator from a backend
|
|
617
|
+
* module (e.g. `plugin-techdocs-backend-module-zensical`). The key corresponds
|
|
618
|
+
* to the `backstage.io/techdocs-engine` entity annotation value.
|
|
619
|
+
*
|
|
620
|
+
* `setTechdocsGenerator` is kept for backwards compatibility — it replaces the
|
|
621
|
+
* default MkDocs generator.
|
|
608
622
|
*
|
|
609
623
|
* @public
|
|
610
624
|
*/
|
|
611
625
|
interface TechdocsGeneratorExtensionPoint {
|
|
612
|
-
setTechdocsGenerator(generator:
|
|
626
|
+
setTechdocsGenerator(generator: GeneratorBase): void;
|
|
627
|
+
registerGenerator(key: SupportedGeneratorKey, generator: GeneratorBase): void;
|
|
613
628
|
}
|
|
614
629
|
/**
|
|
615
630
|
* Extension point for configuring a custom TechDocs generator
|
|
@@ -647,5 +662,5 @@ interface TechdocsPublisherExtensionPoint {
|
|
|
647
662
|
*/
|
|
648
663
|
declare const techdocsPublisherExtensionPoint: _backstage_backend_plugin_api.ExtensionPoint<TechdocsPublisherExtensionPoint>;
|
|
649
664
|
|
|
650
|
-
export { DirectoryPreparer, Generators, Preparers, Publisher, TechdocsGenerator, UrlPreparer, getDocFilesFromRepository, getLocationForEntity, getMkDocsYml, getMkdocsYml, parseReferenceAnnotation, techdocsBuildsExtensionPoint, techdocsGeneratorExtensionPoint, techdocsPreparerExtensionPoint, techdocsPublisherExtensionPoint, transformDirLocation };
|
|
665
|
+
export { DirectoryPreparer, Generators, Preparers, Publisher, TECHDOCS_ENGINE_CATALOG_ANNOTATION_KEY, TechdocsGenerator, UrlPreparer, getDocFilesFromRepository, getLocationForEntity, getMkDocsYml, getMkdocsYml, parseReferenceAnnotation, techdocsBuildsExtensionPoint, techdocsGeneratorExtensionPoint, techdocsPreparerExtensionPoint, techdocsPublisherExtensionPoint, transformDirLocation };
|
|
651
666
|
export type { ContainerRunnerPullOptions, DocsBuildStrategy, ETag, GeneratorBase, GeneratorBuilder, GeneratorOptions, GeneratorRunOptions, MigrateRequest, ParsedLocationAnnotation, PreparerBase, PreparerBuilder, PreparerConfig, PreparerOptions, PreparerResponse, PublishRequest, PublishResponse, PublisherBase, PublisherBuilder, PublisherFactory, PublisherSettings, PublisherType, ReadinessResponse, RemoteProtocol, SupportedGeneratorKey, TechDocsContainerRunner, TechDocsDocument, TechDocsMetadata, TechdocsBuildsExtensionPoint, TechdocsGeneratorExtensionPoint, TechdocsPreparerExtensionPoint, TechdocsPublisherExtensionPoint };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DockerContainerRunner.cjs.js","sources":["../../../src/stages/generate/DockerContainerRunner.ts"],"sourcesContent":["/*\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 Docker from 'dockerode';\nimport fs from 'fs-extra';\nimport { ForwardedError } from '@backstage/errors';\nimport { PassThrough } from 'node:stream';\nimport { pipeline as pipelineStream } from 'node:stream';\nimport { promisify } from 'node:util';\nimport { ContainerRunnerPullOptions, TechDocsContainerRunner } from './types';\nimport { Writable } from 'node:stream';\n\nconst pipeline = promisify(pipelineStream);\n\nexport type UserOptions = {\n User?: string;\n};\n\n/**\n * @internal\n */\nexport class DockerContainerRunner implements TechDocsContainerRunner {\n private readonly dockerClient: Docker;\n\n constructor() {\n this.dockerClient = new Docker();\n }\n\n async runContainer(options: {\n imageName: string;\n command?: string | string[];\n args: string[];\n logStream?: Writable;\n mountDirs?: Record<string, string>;\n workingDir?: string;\n envVars?: Record<string, string>;\n pullImage?: boolean;\n pullOptions?: ContainerRunnerPullOptions;\n defaultUser?: boolean;\n }) {\n const {\n imageName,\n command,\n args,\n logStream = new PassThrough(),\n mountDirs = {},\n workingDir,\n envVars = {},\n pullImage = true,\n pullOptions = {},\n defaultUser = false,\n } = options;\n\n // Show a better error message when Docker is unavailable.\n try {\n await this.dockerClient.ping();\n } catch (e) {\n throw new ForwardedError(\n 'This operation requires Docker. Docker does not appear to be available. Docker.ping() failed with',\n e,\n );\n }\n\n if (pullImage) {\n await new Promise<void>((resolve, reject) => {\n this.dockerClient.pull(imageName, pullOptions, (err, stream) => {\n if (err) {\n reject(err);\n } else if (!stream) {\n reject(\n new Error(\n 'Unexpected error: no stream returned from Docker while pulling image',\n ),\n );\n } else {\n pipeline(stream, logStream, { end: false })\n .then(resolve)\n .catch(reject);\n }\n });\n });\n }\n\n const userOptions: UserOptions = {};\n if (!defaultUser && process.getuid && process.getgid) {\n // Files that are created inside the Docker container will be owned by\n // root on the host system on non Mac systems, because of reasons. Mainly the fact that\n // volume sharing is done using NFS on Mac and actual mounts in Linux world.\n // So we set the user in the container as the same user and group id as the host.\n // On Windows we don't have process.getuid nor process.getgid\n userOptions.User = `${process.getuid()}:${process.getgid()}`;\n }\n\n // Initialize volumes to mount based on mountDirs map\n const Volumes: { [T: string]: object } = {};\n for (const containerDir of Object.values(mountDirs)) {\n Volumes[containerDir] = {};\n }\n\n // Create bind volumes\n const Binds: string[] = [];\n for (const [hostDir, containerDir] of Object.entries(mountDirs)) {\n // Need to use realpath here as Docker mounting does not like\n // symlinks for binding volumes\n const realHostDir = await fs.realpath(hostDir);\n Binds.push(`${realHostDir}:${containerDir}`);\n }\n\n // Create docker environment variables array\n const Env = new Array<string>();\n for (const [key, value] of Object.entries(envVars)) {\n Env.push(`${key}=${value}`);\n }\n\n const [{ Error: error, StatusCode: statusCode }] =\n await this.dockerClient.run(imageName, args, logStream, {\n Volumes,\n HostConfig: {\n AutoRemove: true,\n Binds,\n },\n ...(workingDir ? { WorkingDir: workingDir } : {}),\n Entrypoint: command,\n Env,\n ...userOptions,\n } as Docker.ContainerCreateOptions);\n\n if (error) {\n throw new Error(\n `Docker failed to run with the following error message: ${error}`,\n );\n }\n\n if (statusCode !== 0) {\n throw new Error(\n `Docker container returned a non-zero exit code (${statusCode})`,\n );\n }\n }\n}\n"],"names":["promisify","pipelineStream","Docker","PassThrough","ForwardedError","fs"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"DockerContainerRunner.cjs.js","sources":["../../../src/stages/generate/DockerContainerRunner.ts"],"sourcesContent":["/*\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 Docker from 'dockerode';\nimport fs from 'fs-extra';\nimport { ForwardedError } from '@backstage/errors';\nimport { PassThrough } from 'node:stream';\nimport { pipeline as pipelineStream } from 'node:stream';\nimport { promisify } from 'node:util';\nimport { ContainerRunnerPullOptions, TechDocsContainerRunner } from './types';\nimport { Writable } from 'node:stream';\n\nconst pipeline = promisify(pipelineStream);\n\nexport type UserOptions = {\n User?: string;\n};\n\n/**\n * @internal\n */\nexport class DockerContainerRunner implements TechDocsContainerRunner {\n private readonly dockerClient: Docker;\n\n constructor() {\n this.dockerClient = new Docker();\n }\n\n async runContainer(options: {\n imageName: string;\n command?: string | string[];\n args: string[];\n logStream?: Writable;\n mountDirs?: Record<string, string>;\n workingDir?: string;\n envVars?: Record<string, string>;\n pullImage?: boolean;\n pullOptions?: ContainerRunnerPullOptions;\n defaultUser?: boolean;\n }) {\n const {\n imageName,\n command,\n args,\n logStream = new PassThrough(),\n mountDirs = {},\n workingDir,\n envVars = {},\n pullImage = true,\n pullOptions = {},\n defaultUser = false,\n } = options;\n\n // Show a better error message when Docker is unavailable.\n try {\n await this.dockerClient.ping();\n } catch (e) {\n throw new ForwardedError(\n 'This operation requires Docker. Docker does not appear to be available. Docker.ping() failed with',\n e,\n );\n }\n\n if (pullImage) {\n await new Promise<void>((resolve, reject) => {\n this.dockerClient.pull(imageName, pullOptions, (err, stream) => {\n if (err) {\n reject(err);\n } else if (!stream) {\n reject(\n new Error(\n 'Unexpected error: no stream returned from Docker while pulling image',\n ),\n );\n } else {\n pipeline(stream, logStream, { end: false })\n .then(resolve)\n .catch(reject);\n }\n });\n });\n }\n\n const userOptions: UserOptions = {};\n if (!defaultUser && process.getuid && process.getgid) {\n // Files that are created inside the Docker container will be owned by\n // root on the host system on non Mac systems, because of reasons. Mainly the fact that\n // volume sharing is done using NFS on Mac and actual mounts in Linux world.\n // So we set the user in the container as the same user and group id as the host.\n // On Windows we don't have process.getuid nor process.getgid\n userOptions.User = `${process.getuid()}:${process.getgid()}`;\n }\n\n // Initialize volumes to mount based on mountDirs map\n const Volumes: { [T: string]: object } = {};\n for (const containerDir of Object.values(mountDirs)) {\n Volumes[containerDir] = {};\n }\n\n // Create bind volumes\n const Binds: string[] = [];\n for (const [hostDir, containerDir] of Object.entries(mountDirs)) {\n // Need to use realpath here as Docker mounting does not like\n // symlinks for binding volumes\n const realHostDir = await fs.realpath(hostDir);\n Binds.push(`${realHostDir}:${containerDir}`);\n }\n\n // Create docker environment variables array\n const Env = new Array<string>();\n for (const [key, value] of Object.entries(envVars)) {\n Env.push(`${key}=${value}`);\n }\n\n const [{ Error: error, StatusCode: statusCode }] =\n await this.dockerClient.run(imageName, args, logStream, {\n Volumes,\n HostConfig: {\n AutoRemove: true,\n Binds,\n },\n ...(workingDir ? { WorkingDir: workingDir } : {}),\n Entrypoint: command,\n Env,\n ...userOptions,\n } as Docker.ContainerCreateOptions);\n\n if (error) {\n throw new Error(\n `Docker failed to run with the following error message: ${error}`,\n );\n }\n\n if (statusCode !== 0) {\n throw new Error(\n `Docker container returned a non-zero exit code (${statusCode})`,\n );\n }\n }\n}\n"],"names":["promisify","pipelineStream","Docker","PassThrough","ForwardedError","fs"],"mappings":"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"}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var helpers = require('./helpers.cjs.js');
|
|
4
3
|
var techdocs = require('./techdocs.cjs.js');
|
|
4
|
+
var techdocsTypes = require('../../techdocsTypes.cjs.js');
|
|
5
5
|
|
|
6
|
+
function normalizeGeneratorKey(key) {
|
|
7
|
+
return key === "techdocs" ? "mkdocs" : key;
|
|
8
|
+
}
|
|
6
9
|
class Generators {
|
|
7
10
|
generatorMap = /* @__PURE__ */ new Map();
|
|
11
|
+
defaultEngine = "mkdocs";
|
|
8
12
|
/**
|
|
9
13
|
* Returns a generators instance containing a generator for TechDocs
|
|
10
14
|
* @param config - A Backstage configuration
|
|
@@ -12,8 +16,11 @@ class Generators {
|
|
|
12
16
|
*/
|
|
13
17
|
static async fromConfig(config, options) {
|
|
14
18
|
const generators = new Generators();
|
|
15
|
-
const
|
|
16
|
-
generators.
|
|
19
|
+
const defaultEngine = config.getOptionalString("techdocs.generator.defaultEngine") ?? "mkdocs";
|
|
20
|
+
generators.defaultEngine = defaultEngine;
|
|
21
|
+
options.logger.info(`TechDocs generator defaultEngine: ${defaultEngine}`);
|
|
22
|
+
const mkdocsGenerator = options.customGenerator ?? techdocs.TechdocsGenerator.fromConfig(config, options);
|
|
23
|
+
generators.register("mkdocs", mkdocsGenerator);
|
|
17
24
|
return generators;
|
|
18
25
|
}
|
|
19
26
|
/**
|
|
@@ -22,17 +29,26 @@ class Generators {
|
|
|
22
29
|
* @param generator - The generator instance to register
|
|
23
30
|
*/
|
|
24
31
|
register(generatorKey, generator) {
|
|
25
|
-
this.generatorMap.set(generatorKey, generator);
|
|
32
|
+
this.generatorMap.set(normalizeGeneratorKey(generatorKey), generator);
|
|
26
33
|
}
|
|
27
34
|
/**
|
|
28
35
|
* Returns the generator for a given TechDocs entity
|
|
29
36
|
* @param entity - A TechDocs entity instance
|
|
30
37
|
*/
|
|
31
38
|
get(entity) {
|
|
32
|
-
|
|
39
|
+
if (!entity) {
|
|
40
|
+
throw new Error("No entity provided");
|
|
41
|
+
}
|
|
42
|
+
const annotatedEngine = entity.metadata?.annotations?.[techdocsTypes.TECHDOCS_ENGINE_CATALOG_ANNOTATION_KEY];
|
|
43
|
+
const generatorKey = normalizeGeneratorKey(
|
|
44
|
+
annotatedEngine ?? this.defaultEngine
|
|
45
|
+
);
|
|
33
46
|
const generator = this.generatorMap.get(generatorKey);
|
|
34
47
|
if (!generator) {
|
|
35
|
-
|
|
48
|
+
const source = annotatedEngine ? `the ${techdocsTypes.TECHDOCS_ENGINE_CATALOG_ANNOTATION_KEY} annotation` : "techdocs.generator.defaultEngine";
|
|
49
|
+
throw new Error(
|
|
50
|
+
`No TechDocs generator registered for engine "${generatorKey}" (from ${source}). Registered engines: ${[...this.generatorMap.keys()].join(", ")}`
|
|
51
|
+
);
|
|
36
52
|
}
|
|
37
53
|
return generator;
|
|
38
54
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generators.cjs.js","sources":["../../../src/stages/generate/generators.ts"],"sourcesContent":["/*\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 { Entity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport {
|
|
1
|
+
{"version":3,"file":"generators.cjs.js","sources":["../../../src/stages/generate/generators.ts"],"sourcesContent":["/*\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 { Entity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport { TechdocsGenerator } from './techdocs';\nimport {\n GeneratorBase,\n GeneratorBuilder,\n SupportedGeneratorKey,\n} from './types';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { TechDocsContainerRunner } from './types';\nimport { TECHDOCS_ENGINE_CATALOG_ANNOTATION_KEY } from '../../techdocsTypes';\n\n/**\n * 'techdocs' was the generator key before engines were introduced, and is\n * kept as an alias of 'mkdocs' so that existing registrations keep working.\n */\nfunction normalizeGeneratorKey(key: SupportedGeneratorKey): string {\n return key === 'techdocs' ? 'mkdocs' : key;\n}\n\n/**\n * Collection of docs generators\n * @public\n */\nexport class Generators implements GeneratorBuilder {\n private generatorMap = new Map<SupportedGeneratorKey, GeneratorBase>();\n private defaultEngine: SupportedGeneratorKey = 'mkdocs';\n\n /**\n * Returns a generators instance containing a generator for TechDocs\n * @param config - A Backstage configuration\n * @param options - Options to configure the TechDocs generator\n */\n static async fromConfig(\n config: Config,\n options: {\n logger: LoggerService;\n containerRunner?: TechDocsContainerRunner;\n customGenerator?: GeneratorBase;\n },\n ): Promise<GeneratorBuilder> {\n const generators = new Generators();\n const defaultEngine =\n config.getOptionalString('techdocs.generator.defaultEngine') ?? 'mkdocs';\n\n generators.defaultEngine = defaultEngine;\n\n options.logger.info(`TechDocs generator defaultEngine: ${defaultEngine}`);\n\n const mkdocsGenerator =\n options.customGenerator ?? TechdocsGenerator.fromConfig(config, options);\n generators.register('mkdocs', mkdocsGenerator);\n\n return generators;\n }\n\n /**\n * Register a generator in the generators collection\n * @param generatorKey - Unique identifier for the generator\n * @param generator - The generator instance to register\n */\n register(generatorKey: SupportedGeneratorKey, generator: GeneratorBase) {\n this.generatorMap.set(normalizeGeneratorKey(generatorKey), generator);\n }\n\n /**\n * Returns the generator for a given TechDocs entity\n * @param entity - A TechDocs entity instance\n */\n get(entity: Entity): GeneratorBase {\n if (!entity) {\n throw new Error('No entity provided');\n }\n\n const annotatedEngine =\n entity.metadata?.annotations?.[TECHDOCS_ENGINE_CATALOG_ANNOTATION_KEY];\n const generatorKey = normalizeGeneratorKey(\n annotatedEngine ?? this.defaultEngine,\n );\n const generator = this.generatorMap.get(generatorKey);\n\n if (!generator) {\n const source = annotatedEngine\n ? `the ${TECHDOCS_ENGINE_CATALOG_ANNOTATION_KEY} annotation`\n : 'techdocs.generator.defaultEngine';\n throw new Error(\n `No TechDocs generator registered for engine \"${generatorKey}\" (from ${source}). ` +\n `Registered engines: ${[...this.generatorMap.keys()].join(', ')}`,\n );\n }\n\n return generator;\n }\n}\n"],"names":["TechdocsGenerator","TECHDOCS_ENGINE_CATALOG_ANNOTATION_KEY"],"mappings":";;;;;AAgCA,SAAS,sBAAsB,GAAA,EAAoC;AACjE,EAAA,OAAO,GAAA,KAAQ,aAAa,QAAA,GAAW,GAAA;AACzC;AAMO,MAAM,UAAA,CAAuC;AAAA,EAC1C,YAAA,uBAAmB,GAAA,EAA0C;AAAA,EAC7D,aAAA,GAAuC,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO/C,aAAa,UAAA,CACX,MAAA,EACA,OAAA,EAK2B;AAC3B,IAAA,MAAM,UAAA,GAAa,IAAI,UAAA,EAAW;AAClC,IAAA,MAAM,aAAA,GACJ,MAAA,CAAO,iBAAA,CAAkB,kCAAkC,CAAA,IAAK,QAAA;AAElE,IAAA,UAAA,CAAW,aAAA,GAAgB,aAAA;AAE3B,IAAA,OAAA,CAAQ,MAAA,CAAO,IAAA,CAAK,CAAA,kCAAA,EAAqC,aAAa,CAAA,CAAE,CAAA;AAExE,IAAA,MAAM,kBACJ,OAAA,CAAQ,eAAA,IAAmBA,0BAAA,CAAkB,UAAA,CAAW,QAAQ,OAAO,CAAA;AACzE,IAAA,UAAA,CAAW,QAAA,CAAS,UAAU,eAAe,CAAA;AAE7C,IAAA,OAAO,UAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAA,CAAS,cAAqC,SAAA,EAA0B;AACtE,IAAA,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,qBAAA,CAAsB,YAAY,GAAG,SAAS,CAAA;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,MAAA,EAA+B;AACjC,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAI,MAAM,oBAAoB,CAAA;AAAA,IACtC;AAEA,IAAA,MAAM,eAAA,GACJ,MAAA,CAAO,QAAA,EAAU,WAAA,GAAcC,oDAAsC,CAAA;AACvE,IAAA,MAAM,YAAA,GAAe,qBAAA;AAAA,MACnB,mBAAmB,IAAA,CAAK;AAAA,KAC1B;AACA,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,YAAY,CAAA;AAEpD,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,MAAM,MAAA,GAAS,eAAA,GACX,CAAA,IAAA,EAAOA,oDAAsC,CAAA,WAAA,CAAA,GAC7C,kCAAA;AACJ,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,6CAAA,EAAgD,YAAY,CAAA,QAAA,EAAW,MAAM,0BACpD,CAAC,GAAG,IAAA,CAAK,YAAA,CAAa,IAAA,EAAM,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,OACnE;AAAA,IACF;AAEA,IAAA,OAAO,SAAA;AAAA,EACT;AACF;;"}
|
|
@@ -12,17 +12,29 @@ var helpers = require('../publish/helpers.cjs.js');
|
|
|
12
12
|
|
|
13
13
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
14
14
|
|
|
15
|
+
function _interopNamespaceCompat(e) {
|
|
16
|
+
if (e && typeof e === 'object' && 'default' in e) return e;
|
|
17
|
+
var n = Object.create(null);
|
|
18
|
+
if (e) {
|
|
19
|
+
Object.keys(e).forEach(function (k) {
|
|
20
|
+
if (k !== 'default') {
|
|
21
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
22
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
get: function () { return e[k]; }
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
n.default = e;
|
|
30
|
+
return Object.freeze(n);
|
|
31
|
+
}
|
|
32
|
+
|
|
15
33
|
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
16
34
|
var gitUrlParse__default = /*#__PURE__*/_interopDefaultCompat(gitUrlParse);
|
|
17
|
-
var
|
|
35
|
+
var yaml__namespace = /*#__PURE__*/_interopNamespaceCompat(yaml);
|
|
18
36
|
var path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
19
37
|
|
|
20
|
-
function getGeneratorKey(entity) {
|
|
21
|
-
if (!entity) {
|
|
22
|
-
throw new Error("No entity provided");
|
|
23
|
-
}
|
|
24
|
-
return "techdocs";
|
|
25
|
-
}
|
|
26
38
|
const runCommand = async ({
|
|
27
39
|
command,
|
|
28
40
|
args,
|
|
@@ -107,32 +119,36 @@ class UnknownTag {
|
|
|
107
119
|
this.type = type;
|
|
108
120
|
}
|
|
109
121
|
}
|
|
110
|
-
const MKDOCS_SCHEMA = yaml.
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
represent: (
|
|
116
|
-
|
|
117
|
-
construct: (data, type) => new UnknownTag(data, type)
|
|
122
|
+
const MKDOCS_SCHEMA = yaml.YAML11_SCHEMA.withTags(
|
|
123
|
+
yaml.defineScalarTag("", {
|
|
124
|
+
matchByTagPrefix: true,
|
|
125
|
+
resolve: (data, _isExplicit, tagName) => new UnknownTag(data, tagName),
|
|
126
|
+
identify: (data) => data instanceof UnknownTag && typeof data.data === "string",
|
|
127
|
+
represent: (data) => data.data,
|
|
128
|
+
representTagName: (data) => data.type
|
|
118
129
|
}),
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
130
|
+
yaml.defineSequenceTag("", {
|
|
131
|
+
matchByTagPrefix: true,
|
|
132
|
+
create: (tagName) => new UnknownTag([], tagName),
|
|
133
|
+
addItem: (carrier, item) => {
|
|
134
|
+
carrier.data.push(item);
|
|
135
|
+
},
|
|
136
|
+
identify: (data) => data instanceof UnknownTag && Array.isArray(data.data),
|
|
137
|
+
represent: (data) => data.data,
|
|
138
|
+
representTagName: (data) => data.type
|
|
126
139
|
}),
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
140
|
+
yaml.defineMappingTag("tag:", {
|
|
141
|
+
matchByTagPrefix: true,
|
|
142
|
+
create: (tagName) => new UnknownTag({}, tagName),
|
|
143
|
+
addPair: (carrier, key, value) => yaml.mapTag.addPair(carrier.data, key, value),
|
|
144
|
+
has: (carrier, key) => yaml.mapTag.has(carrier.data, key),
|
|
145
|
+
keys: (result) => yaml.mapTag.keys(result.data),
|
|
146
|
+
get: (result, key) => yaml.mapTag.get(result.data, key),
|
|
147
|
+
identify: (data) => data instanceof UnknownTag && typeof data.data === "object" && data.data !== null && !Array.isArray(data.data),
|
|
148
|
+
represent: (data) => new Map(Object.entries(data.data)),
|
|
149
|
+
representTagName: (data) => data.type
|
|
134
150
|
})
|
|
135
|
-
|
|
151
|
+
);
|
|
136
152
|
const generateMkdocsYml = async (inputDir, siteOptions) => {
|
|
137
153
|
try {
|
|
138
154
|
const mkdocsYmlPath = path__default.default.join(inputDir, "mkdocs.yml");
|
|
@@ -144,7 +160,7 @@ const generateMkdocsYml = async (inputDir, siteOptions) => {
|
|
|
144
160
|
};
|
|
145
161
|
await fs__default.default.writeFile(
|
|
146
162
|
mkdocsYmlPath,
|
|
147
|
-
|
|
163
|
+
yaml__namespace.dump(defaultMkdocsContent, { schema: MKDOCS_SCHEMA })
|
|
148
164
|
);
|
|
149
165
|
} catch (error) {
|
|
150
166
|
throw new errors.ForwardedError("Could not generate mkdocs.yml file", error);
|
|
@@ -248,7 +264,7 @@ const ALLOWED_THEME_KEYS = /* @__PURE__ */ new Set([
|
|
|
248
264
|
"features"
|
|
249
265
|
]);
|
|
250
266
|
const validateMkdocsYaml = async (inputDir, mkdocsYmlFileString) => {
|
|
251
|
-
const mkdocsYml =
|
|
267
|
+
const mkdocsYml = yaml__namespace.load(mkdocsYmlFileString, {
|
|
252
268
|
schema: MKDOCS_SCHEMA
|
|
253
269
|
});
|
|
254
270
|
if (mkdocsYml === null || typeof mkdocsYml !== "object") {
|
|
@@ -323,7 +339,7 @@ const patchIndexPreBuild = async ({
|
|
|
323
339
|
].join(" ")} exists.`
|
|
324
340
|
);
|
|
325
341
|
};
|
|
326
|
-
const createOrUpdateMetadata = async (techdocsMetadataPath, logger) => {
|
|
342
|
+
const createOrUpdateMetadata = async (techdocsMetadataPath, logger, engine) => {
|
|
327
343
|
const techdocsMetadataDir = techdocsMetadataPath.split(path__default.default.sep).slice(0, -1).join(path__default.default.sep);
|
|
328
344
|
try {
|
|
329
345
|
await fs__default.default.access(techdocsMetadataPath, fs__default.default.constants.F_OK);
|
|
@@ -339,6 +355,9 @@ const createOrUpdateMetadata = async (techdocsMetadataPath, logger) => {
|
|
|
339
355
|
throw new Error(message);
|
|
340
356
|
}
|
|
341
357
|
json.build_timestamp = Date.now();
|
|
358
|
+
{
|
|
359
|
+
json.engine = engine;
|
|
360
|
+
}
|
|
342
361
|
try {
|
|
343
362
|
json.files = (await helpers.getFileTreeRecursively(techdocsMetadataDir)).map(
|
|
344
363
|
(file) => file.replace(`${techdocsMetadataDir}${path__default.default.sep}`, "")
|
|
@@ -365,7 +384,6 @@ exports.MKDOCS_SCHEMA = MKDOCS_SCHEMA;
|
|
|
365
384
|
exports.UnknownTag = UnknownTag;
|
|
366
385
|
exports.createOrUpdateMetadata = createOrUpdateMetadata;
|
|
367
386
|
exports.generateMkdocsYml = generateMkdocsYml;
|
|
368
|
-
exports.getGeneratorKey = getGeneratorKey;
|
|
369
387
|
exports.getMkdocsYml = getMkdocsYml;
|
|
370
388
|
exports.getRepoUrlFromLocationAnnotation = getRepoUrlFromLocationAnnotation;
|
|
371
389
|
exports.patchIndexPreBuild = patchIndexPreBuild;
|