@backstage/plugin-techdocs-node 1.12.12-next.1 → 1.12.12

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 (43) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/extensions.cjs.js +22 -0
  3. package/dist/extensions.cjs.js.map +1 -0
  4. package/dist/helpers.cjs.js +80 -0
  5. package/dist/helpers.cjs.js.map +1 -0
  6. package/dist/index.cjs.js +29 -2602
  7. package/dist/index.cjs.js.map +1 -1
  8. package/dist/index.d.ts +11 -1
  9. package/dist/stages/generate/DockerContainerRunner.cjs.js +99 -0
  10. package/dist/stages/generate/DockerContainerRunner.cjs.js.map +1 -0
  11. package/dist/stages/generate/generators.cjs.js +42 -0
  12. package/dist/stages/generate/generators.cjs.js.map +1 -0
  13. package/dist/stages/generate/helpers.cjs.js +265 -0
  14. package/dist/stages/generate/helpers.cjs.js.map +1 -0
  15. package/dist/stages/generate/index.cjs.js +15 -0
  16. package/dist/stages/generate/index.cjs.js.map +1 -0
  17. package/dist/stages/generate/mkdocsPatchers.cjs.js +96 -0
  18. package/dist/stages/generate/mkdocsPatchers.cjs.js.map +1 -0
  19. package/dist/stages/generate/techdocs.cjs.js +169 -0
  20. package/dist/stages/generate/techdocs.cjs.js.map +1 -0
  21. package/dist/stages/prepare/dir.cjs.js +63 -0
  22. package/dist/stages/prepare/dir.cjs.js.map +1 -0
  23. package/dist/stages/prepare/preparers.cjs.js +54 -0
  24. package/dist/stages/prepare/preparers.cjs.js.map +1 -0
  25. package/dist/stages/prepare/url.cjs.js +46 -0
  26. package/dist/stages/prepare/url.cjs.js.map +1 -0
  27. package/dist/stages/publish/awsS3.cjs.js +436 -0
  28. package/dist/stages/publish/awsS3.cjs.js.map +1 -0
  29. package/dist/stages/publish/azureBlobStorage.cjs.js +337 -0
  30. package/dist/stages/publish/azureBlobStorage.cjs.js.map +1 -0
  31. package/dist/stages/publish/googleStorage.cjs.js +288 -0
  32. package/dist/stages/publish/googleStorage.cjs.js.map +1 -0
  33. package/dist/stages/publish/helpers.cjs.js +138 -0
  34. package/dist/stages/publish/helpers.cjs.js.map +1 -0
  35. package/dist/stages/publish/local.cjs.js +248 -0
  36. package/dist/stages/publish/local.cjs.js.map +1 -0
  37. package/dist/stages/publish/migrations/GoogleMigration.cjs.js +52 -0
  38. package/dist/stages/publish/migrations/GoogleMigration.cjs.js.map +1 -0
  39. package/dist/stages/publish/openStackSwift.cjs.js +286 -0
  40. package/dist/stages/publish/openStackSwift.cjs.js.map +1 -0
  41. package/dist/stages/publish/publish.cjs.js +100 -0
  42. package/dist/stages/publish/publish.cjs.js.map +1 -0
  43. package/package.json +13 -13
@@ -0,0 +1,286 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs-extra');
4
+ var JSON5 = require('json5');
5
+ var createLimiter = require('p-limit');
6
+ var path = require('path');
7
+ var openstackSwiftSdk = require('@trendyol-js/openstack-swift-sdk');
8
+ var types = require('@trendyol-js/openstack-swift-sdk/lib/types');
9
+ var stream = require('stream');
10
+ var helpers = require('./helpers.cjs.js');
11
+ var errors = require('@backstage/errors');
12
+
13
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
14
+
15
+ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
16
+ var JSON5__default = /*#__PURE__*/_interopDefaultCompat(JSON5);
17
+ var createLimiter__default = /*#__PURE__*/_interopDefaultCompat(createLimiter);
18
+ var path__default = /*#__PURE__*/_interopDefaultCompat(path);
19
+
20
+ const streamToBuffer = (stream) => {
21
+ return new Promise((resolve, reject) => {
22
+ try {
23
+ const chunks = [];
24
+ stream.on("data", (chunk) => chunks.push(chunk));
25
+ stream.on("error", reject);
26
+ stream.on("end", () => resolve(Buffer.concat(chunks)));
27
+ } catch (e) {
28
+ throw new errors.ForwardedError("Unable to parse the response data", e);
29
+ }
30
+ });
31
+ };
32
+ const bufferToStream = (buffer) => {
33
+ const stream$1 = new stream.Readable();
34
+ stream$1.push(buffer);
35
+ stream$1.push(null);
36
+ return stream$1;
37
+ };
38
+ class OpenStackSwiftPublish {
39
+ storageClient;
40
+ containerName;
41
+ logger;
42
+ constructor(options) {
43
+ this.storageClient = options.storageClient;
44
+ this.containerName = options.containerName;
45
+ this.logger = options.logger;
46
+ }
47
+ static fromConfig(config, logger) {
48
+ let containerName = "";
49
+ try {
50
+ containerName = config.getString(
51
+ "techdocs.publisher.openStackSwift.containerName"
52
+ );
53
+ } catch (error) {
54
+ throw new Error(
55
+ "Since techdocs.publisher.type is set to 'openStackSwift' in your app config, techdocs.publisher.openStackSwift.containerName is required."
56
+ );
57
+ }
58
+ const openStackSwiftConfig = config.getConfig(
59
+ "techdocs.publisher.openStackSwift"
60
+ );
61
+ const storageClient = new openstackSwiftSdk.SwiftClient({
62
+ authEndpoint: openStackSwiftConfig.getString("authUrl"),
63
+ swiftEndpoint: openStackSwiftConfig.getString("swiftUrl"),
64
+ credentialId: openStackSwiftConfig.getString("credentials.id"),
65
+ secret: openStackSwiftConfig.getString("credentials.secret")
66
+ });
67
+ return new OpenStackSwiftPublish({ storageClient, containerName, logger });
68
+ }
69
+ /*
70
+ * Check if the defined container exists. Being able to connect means the configuration is good
71
+ * and the storage client will work.
72
+ */
73
+ async getReadiness() {
74
+ try {
75
+ const container = await this.storageClient.getContainerMetadata(
76
+ this.containerName
77
+ );
78
+ if (!(container instanceof types.NotFound)) {
79
+ this.logger.info(
80
+ `Successfully connected to the OpenStack Swift container ${this.containerName}.`
81
+ );
82
+ return {
83
+ isAvailable: true
84
+ };
85
+ }
86
+ this.logger.error(
87
+ `Could not retrieve metadata about the OpenStack Swift container ${this.containerName}. Make sure the container exists. Also make sure that authentication is setup either by explicitly defining credentials and region in techdocs.publisher.openStackSwift in app config or by using environment variables. Refer to https://backstage.io/docs/features/techdocs/using-cloud-storage`
88
+ );
89
+ return {
90
+ isAvailable: false
91
+ };
92
+ } catch (err) {
93
+ errors.assertError(err);
94
+ this.logger.error(`from OpenStack client library: ${err.message}`);
95
+ return {
96
+ isAvailable: false
97
+ };
98
+ }
99
+ }
100
+ /**
101
+ * Upload all the files from the generated `directory` to the OpenStack Swift container.
102
+ * Directory structure used in the bucket is - entityNamespace/entityKind/entityName/index.html
103
+ */
104
+ async publish({
105
+ entity,
106
+ directory
107
+ }) {
108
+ try {
109
+ const objects = [];
110
+ const allFilesToUpload = await helpers.getFileTreeRecursively(directory);
111
+ const limiter = createLimiter__default.default(10);
112
+ const uploadPromises = [];
113
+ for (const filePath of allFilesToUpload) {
114
+ const relativeFilePath = path__default.default.relative(directory, filePath);
115
+ const relativeFilePathPosix = relativeFilePath.split(path__default.default.sep).join(path__default.default.posix.sep);
116
+ const entityRootDir = `${entity.metadata.namespace}/${entity.kind}/${entity.metadata.name}`;
117
+ const destination = `${entityRootDir}/${relativeFilePathPosix}`;
118
+ objects.push(destination);
119
+ const uploadFile = limiter(async () => {
120
+ const fileBuffer = await fs__default.default.readFile(filePath);
121
+ const stream = bufferToStream(fileBuffer);
122
+ return this.storageClient.upload(
123
+ this.containerName,
124
+ destination,
125
+ stream
126
+ );
127
+ });
128
+ uploadPromises.push(uploadFile);
129
+ }
130
+ await Promise.all(uploadPromises);
131
+ this.logger.info(
132
+ `Successfully uploaded all the generated files for Entity ${entity.metadata.name}. Total number of files: ${allFilesToUpload.length}`
133
+ );
134
+ return { objects };
135
+ } catch (e) {
136
+ const errorMessage = `Unable to upload file(s) to OpenStack Swift. ${e}`;
137
+ this.logger.error(errorMessage);
138
+ throw new Error(errorMessage);
139
+ }
140
+ }
141
+ async fetchTechDocsMetadata(entityName) {
142
+ return await new Promise(async (resolve, reject) => {
143
+ const entityRootDir = `${entityName.namespace}/${entityName.kind}/${entityName.name}`;
144
+ const downloadResponse = await this.storageClient.download(
145
+ this.containerName,
146
+ `${entityRootDir}/techdocs_metadata.json`
147
+ );
148
+ if (!(downloadResponse instanceof types.NotFound)) {
149
+ const stream = downloadResponse.data;
150
+ try {
151
+ const techdocsMetadataJson = await streamToBuffer(stream);
152
+ if (!techdocsMetadataJson) {
153
+ throw new Error(
154
+ `Unable to parse the techdocs metadata file ${entityRootDir}/techdocs_metadata.json.`
155
+ );
156
+ }
157
+ const techdocsMetadata = JSON5__default.default.parse(
158
+ techdocsMetadataJson.toString("utf-8")
159
+ );
160
+ resolve(techdocsMetadata);
161
+ } catch (err) {
162
+ errors.assertError(err);
163
+ this.logger.error(err.message);
164
+ reject(new Error(err.message));
165
+ }
166
+ } else {
167
+ reject({
168
+ message: `TechDocs metadata fetch failed, The file /rootDir/${entityRootDir}/techdocs_metadata.json does not exist !`
169
+ });
170
+ }
171
+ });
172
+ }
173
+ /**
174
+ * Express route middleware to serve static files on a route in techdocs-backend.
175
+ */
176
+ docsRouter() {
177
+ return async (req, res) => {
178
+ const filePath = decodeURI(req.path.replace(/^\//, ""));
179
+ const fileExtension = path__default.default.extname(filePath);
180
+ const responseHeaders = helpers.getHeadersForFileExtension(fileExtension);
181
+ const downloadResponse = await this.storageClient.download(
182
+ this.containerName,
183
+ filePath
184
+ );
185
+ if (!(downloadResponse instanceof types.NotFound)) {
186
+ const stream = downloadResponse.data;
187
+ try {
188
+ for (const [headerKey, headerValue] of Object.entries(
189
+ responseHeaders
190
+ )) {
191
+ res.setHeader(headerKey, headerValue);
192
+ }
193
+ res.send(await streamToBuffer(stream));
194
+ } catch (err) {
195
+ errors.assertError(err);
196
+ this.logger.warn(
197
+ `TechDocs OpenStack swift router failed to serve content from container ${this.containerName} at path ${filePath}: ${err.message}`
198
+ );
199
+ res.status(404).send("File Not Found");
200
+ }
201
+ } else {
202
+ this.logger.warn(
203
+ `TechDocs OpenStack swift router failed to serve content from container ${this.containerName} at path ${filePath}: Not found`
204
+ );
205
+ res.status(404).send("File Not Found");
206
+ }
207
+ };
208
+ }
209
+ /**
210
+ * A helper function which checks if index.html of an Entity's docs site is available. This
211
+ * can be used to verify if there are any pre-generated docs available to serve.
212
+ */
213
+ async hasDocsBeenGenerated(entity) {
214
+ const entityRootDir = `${entity.metadata.namespace}/${entity.kind}/${entity.metadata.name}`;
215
+ try {
216
+ const fileResponse = await this.storageClient.getMetadata(
217
+ this.containerName,
218
+ `${entityRootDir}/index.html`
219
+ );
220
+ if (!(fileResponse instanceof types.NotFound)) {
221
+ return true;
222
+ }
223
+ return false;
224
+ } catch (err) {
225
+ errors.assertError(err);
226
+ this.logger.warn(err.message);
227
+ return false;
228
+ }
229
+ }
230
+ async migrateDocsCase({
231
+ removeOriginal = false,
232
+ concurrency = 25
233
+ }) {
234
+ const allObjects = await this.getAllObjectsFromContainer();
235
+ const limiter = createLimiter__default.default(concurrency);
236
+ await Promise.all(
237
+ allObjects.map(
238
+ (f) => limiter(async (file) => {
239
+ let newPath;
240
+ try {
241
+ newPath = helpers.lowerCaseEntityTripletInStoragePath(file);
242
+ } catch (e) {
243
+ errors.assertError(e);
244
+ this.logger.warn(e.message);
245
+ return;
246
+ }
247
+ if (file === newPath) {
248
+ return;
249
+ }
250
+ try {
251
+ this.logger.debug(`Migrating ${file} to ${newPath}`);
252
+ await this.storageClient.copy(
253
+ this.containerName,
254
+ file,
255
+ this.containerName,
256
+ newPath
257
+ );
258
+ if (removeOriginal) {
259
+ await this.storageClient.delete(this.containerName, file);
260
+ }
261
+ } catch (e) {
262
+ errors.assertError(e);
263
+ this.logger.warn(`Unable to migrate ${file}: ${e.message}`);
264
+ }
265
+ }, f)
266
+ )
267
+ );
268
+ }
269
+ /**
270
+ * Returns a list of all object keys from the configured container.
271
+ */
272
+ async getAllObjectsFromContainer({ prefix } = { prefix: "" }) {
273
+ let objects = [];
274
+ const OSS_MAX_LIMIT = Math.pow(2, 31) - 1;
275
+ const allObjects = await this.storageClient.list(
276
+ this.containerName,
277
+ prefix,
278
+ OSS_MAX_LIMIT
279
+ );
280
+ objects = allObjects.map((object) => object.name);
281
+ return objects;
282
+ }
283
+ }
284
+
285
+ exports.OpenStackSwiftPublish = OpenStackSwiftPublish;
286
+ //# sourceMappingURL=openStackSwift.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openStackSwift.cjs.js","sources":["../../../src/stages/publish/openStackSwift.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 */\nimport { Entity, CompoundEntityRef } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport express from 'express';\nimport fs from 'fs-extra';\nimport JSON5 from 'json5';\nimport createLimiter from 'p-limit';\nimport path from 'path';\nimport { SwiftClient } from '@trendyol-js/openstack-swift-sdk';\nimport { NotFound } from '@trendyol-js/openstack-swift-sdk/lib/types';\nimport { Stream, Readable } from 'stream';\n\nimport {\n getFileTreeRecursively,\n getHeadersForFileExtension,\n lowerCaseEntityTripletInStoragePath,\n} from './helpers';\nimport {\n PublisherBase,\n PublishRequest,\n PublishResponse,\n ReadinessResponse,\n TechDocsMetadata,\n} from './types';\nimport { assertError, ForwardedError } from '@backstage/errors';\nimport { LoggerService } from '@backstage/backend-plugin-api';\n\nconst streamToBuffer = (stream: Stream | Readable): Promise<Buffer> => {\n return new Promise((resolve, reject) => {\n try {\n const chunks: any[] = [];\n stream.on('data', chunk => chunks.push(chunk));\n stream.on('error', reject);\n stream.on('end', () => resolve(Buffer.concat(chunks)));\n } catch (e) {\n throw new ForwardedError('Unable to parse the response data', e);\n }\n });\n};\n\nconst bufferToStream = (buffer: Buffer): Readable => {\n const stream = new Readable();\n stream.push(buffer);\n stream.push(null);\n return stream;\n};\n\nexport class OpenStackSwiftPublish implements PublisherBase {\n private readonly storageClient: SwiftClient;\n private readonly containerName: string;\n private readonly logger: LoggerService;\n\n constructor(options: {\n storageClient: SwiftClient;\n containerName: string;\n logger: LoggerService;\n }) {\n this.storageClient = options.storageClient;\n this.containerName = options.containerName;\n this.logger = options.logger;\n }\n\n static fromConfig(config: Config, logger: LoggerService): PublisherBase {\n let containerName = '';\n try {\n containerName = config.getString(\n 'techdocs.publisher.openStackSwift.containerName',\n );\n } catch (error) {\n throw new Error(\n \"Since techdocs.publisher.type is set to 'openStackSwift' in your app config, \" +\n 'techdocs.publisher.openStackSwift.containerName is required.',\n );\n }\n\n const openStackSwiftConfig = config.getConfig(\n 'techdocs.publisher.openStackSwift',\n );\n\n const storageClient = new SwiftClient({\n authEndpoint: openStackSwiftConfig.getString('authUrl'),\n swiftEndpoint: openStackSwiftConfig.getString('swiftUrl'),\n credentialId: openStackSwiftConfig.getString('credentials.id'),\n secret: openStackSwiftConfig.getString('credentials.secret'),\n });\n\n return new OpenStackSwiftPublish({ storageClient, containerName, logger });\n }\n\n /*\n * Check if the defined container exists. Being able to connect means the configuration is good\n * and the storage client will work.\n */\n async getReadiness(): Promise<ReadinessResponse> {\n try {\n const container = await this.storageClient.getContainerMetadata(\n this.containerName,\n );\n\n if (!(container instanceof NotFound)) {\n this.logger.info(\n `Successfully connected to the OpenStack Swift container ${this.containerName}.`,\n );\n return {\n isAvailable: true,\n };\n }\n this.logger.error(\n `Could not retrieve metadata about the OpenStack Swift container ${this.containerName}. ` +\n 'Make sure the container exists. Also make sure that authentication is setup either by ' +\n 'explicitly defining credentials and region in techdocs.publisher.openStackSwift in app config or ' +\n 'by using environment variables. Refer to https://backstage.io/docs/features/techdocs/using-cloud-storage',\n );\n return {\n isAvailable: false,\n };\n } catch (err) {\n assertError(err);\n this.logger.error(`from OpenStack client library: ${err.message}`);\n return {\n isAvailable: false,\n };\n }\n }\n\n /**\n * Upload all the files from the generated `directory` to the OpenStack Swift container.\n * Directory structure used in the bucket is - entityNamespace/entityKind/entityName/index.html\n */\n async publish({\n entity,\n directory,\n }: PublishRequest): Promise<PublishResponse> {\n try {\n const objects: string[] = [];\n\n // Note: OpenStack Swift manages creation of parent directories if they do not exist.\n // So collecting path of only the files is good enough.\n const allFilesToUpload = await getFileTreeRecursively(directory);\n const limiter = createLimiter(10);\n const uploadPromises: Array<Promise<unknown>> = [];\n for (const filePath of allFilesToUpload) {\n // Remove the absolute path prefix of the source directory\n // Path of all files to upload, relative to the root of the source directory\n // e.g. ['index.html', 'sub-page/index.html', 'assets/images/favicon.png']\n const relativeFilePath = path.relative(directory, filePath);\n // Convert destination file path to a POSIX path for uploading.\n // Swift expects / as path separator and relativeFilePath will contain \\\\ on Windows.\n // https://docs.openstack.org/python-openstackclient/pike/cli/man/openstack.html\n const relativeFilePathPosix = relativeFilePath\n .split(path.sep)\n .join(path.posix.sep);\n\n // The / delimiter is intentional since it represents the cloud storage and not the local file system.\n const entityRootDir = `${entity.metadata.namespace}/${entity.kind}/${entity.metadata.name}`;\n const destination = `${entityRootDir}/${relativeFilePathPosix}`; // Swift container file relative path\n objects.push(destination);\n\n // Rate limit the concurrent execution of file uploads to batches of 10 (per publish)\n const uploadFile = limiter(async () => {\n const fileBuffer = await fs.readFile(filePath);\n const stream = bufferToStream(fileBuffer);\n return this.storageClient.upload(\n this.containerName,\n destination,\n stream,\n );\n });\n uploadPromises.push(uploadFile);\n }\n await Promise.all(uploadPromises);\n this.logger.info(\n `Successfully uploaded all the generated files for Entity ${entity.metadata.name}. Total number of files: ${allFilesToUpload.length}`,\n );\n return { objects };\n } catch (e) {\n const errorMessage = `Unable to upload file(s) to OpenStack Swift. ${e}`;\n this.logger.error(errorMessage);\n throw new Error(errorMessage);\n }\n }\n\n async fetchTechDocsMetadata(\n entityName: CompoundEntityRef,\n ): Promise<TechDocsMetadata> {\n return await new Promise<TechDocsMetadata>(async (resolve, reject) => {\n const entityRootDir = `${entityName.namespace}/${entityName.kind}/${entityName.name}`;\n\n const downloadResponse = await this.storageClient.download(\n this.containerName,\n `${entityRootDir}/techdocs_metadata.json`,\n );\n\n if (!(downloadResponse instanceof NotFound)) {\n const stream = downloadResponse.data;\n try {\n const techdocsMetadataJson = await streamToBuffer(stream);\n if (!techdocsMetadataJson) {\n throw new Error(\n `Unable to parse the techdocs metadata file ${entityRootDir}/techdocs_metadata.json.`,\n );\n }\n\n const techdocsMetadata = JSON5.parse(\n techdocsMetadataJson.toString('utf-8'),\n );\n\n resolve(techdocsMetadata);\n } catch (err) {\n assertError(err);\n this.logger.error(err.message);\n reject(new Error(err.message));\n }\n } else {\n reject({\n message: `TechDocs metadata fetch failed, The file /rootDir/${entityRootDir}/techdocs_metadata.json does not exist !`,\n });\n }\n });\n }\n\n /**\n * Express route middleware to serve static files on a route in techdocs-backend.\n */\n docsRouter(): express.Handler {\n return async (req, res) => {\n // Decode and trim the leading forward slash\n // filePath example - /default/Component/documented-component/index.html\n const filePath = decodeURI(req.path.replace(/^\\//, ''));\n\n // Files with different extensions (CSS, HTML) need to be served with different headers\n const fileExtension = path.extname(filePath);\n const responseHeaders = getHeadersForFileExtension(fileExtension);\n\n const downloadResponse = await this.storageClient.download(\n this.containerName,\n filePath,\n );\n\n if (!(downloadResponse instanceof NotFound)) {\n const stream = downloadResponse.data;\n\n try {\n // Inject response headers\n for (const [headerKey, headerValue] of Object.entries(\n responseHeaders,\n )) {\n res.setHeader(headerKey, headerValue);\n }\n\n res.send(await streamToBuffer(stream));\n } catch (err) {\n assertError(err);\n this.logger.warn(\n `TechDocs OpenStack swift router failed to serve content from container ${this.containerName} at path ${filePath}: ${err.message}`,\n );\n res.status(404).send('File Not Found');\n }\n } else {\n this.logger.warn(\n `TechDocs OpenStack swift router failed to serve content from container ${this.containerName} at path ${filePath}: Not found`,\n );\n res.status(404).send('File Not Found');\n }\n };\n }\n\n /**\n * A helper function which checks if index.html of an Entity's docs site is available. This\n * can be used to verify if there are any pre-generated docs available to serve.\n */\n async hasDocsBeenGenerated(entity: Entity): Promise<boolean> {\n const entityRootDir = `${entity.metadata.namespace}/${entity.kind}/${entity.metadata.name}`;\n try {\n const fileResponse = await this.storageClient.getMetadata(\n this.containerName,\n `${entityRootDir}/index.html`,\n );\n\n if (!(fileResponse instanceof NotFound)) {\n return true;\n }\n return false;\n } catch (err) {\n assertError(err);\n this.logger.warn(err.message);\n return false;\n }\n }\n\n async migrateDocsCase({\n removeOriginal = false,\n concurrency = 25,\n }): Promise<void> {\n // Iterate through every file in the root of the publisher.\n const allObjects = await this.getAllObjectsFromContainer();\n const limiter = createLimiter(concurrency);\n await Promise.all(\n allObjects.map(f =>\n limiter(async file => {\n let newPath;\n try {\n newPath = lowerCaseEntityTripletInStoragePath(file);\n } catch (e) {\n assertError(e);\n this.logger.warn(e.message);\n return;\n }\n\n // If all parts are already lowercase, ignore.\n if (file === newPath) {\n return;\n }\n\n try {\n this.logger.debug(`Migrating ${file} to ${newPath}`);\n await this.storageClient.copy(\n this.containerName,\n file,\n this.containerName,\n newPath,\n );\n if (removeOriginal) {\n await this.storageClient.delete(this.containerName, file);\n }\n } catch (e) {\n assertError(e);\n this.logger.warn(`Unable to migrate ${file}: ${e.message}`);\n }\n }, f),\n ),\n );\n }\n\n /**\n * Returns a list of all object keys from the configured container.\n */\n protected async getAllObjectsFromContainer(\n { prefix } = { prefix: '' },\n ): Promise<string[]> {\n let objects: string[] = [];\n const OSS_MAX_LIMIT = Math.pow(2, 31) - 1;\n\n const allObjects = await this.storageClient.list(\n this.containerName,\n prefix,\n OSS_MAX_LIMIT,\n );\n objects = allObjects.map((object: any) => object.name);\n\n return objects;\n }\n}\n"],"names":["ForwardedError","stream","Readable","SwiftClient","NotFound","assertError","getFileTreeRecursively","createLimiter","path","fs","JSON5","getHeadersForFileExtension","lowerCaseEntityTripletInStoragePath"],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ 'use strict';
2
+
3
+ var awsS3 = require('./awsS3.cjs.js');
4
+ var azureBlobStorage = require('./azureBlobStorage.cjs.js');
5
+ var googleStorage = require('./googleStorage.cjs.js');
6
+ var local = require('./local.cjs.js');
7
+ var openStackSwift = require('./openStackSwift.cjs.js');
8
+
9
+ class Publisher {
10
+ publishers = /* @__PURE__ */ new Map();
11
+ register(type, publisher) {
12
+ this.publishers.set(type, publisher);
13
+ }
14
+ get(config) {
15
+ const publisherType = config.getOptionalString(
16
+ "techdocs.publisher.type"
17
+ ) ?? "local";
18
+ if (!publisherType) {
19
+ throw new Error("TechDocs publisher type not specified for the entity");
20
+ }
21
+ const publisher = this.publishers.get(publisherType);
22
+ if (!publisher) {
23
+ throw new Error(
24
+ `TechDocs publisher '${publisherType}' is not registered`
25
+ );
26
+ }
27
+ return publisher;
28
+ }
29
+ /**
30
+ * Returns a instance of TechDocs publisher
31
+ * @param config - A Backstage configuration
32
+ * @param options - Options for configuring the publisher factory
33
+ */
34
+ static async fromConfig(config, options) {
35
+ const { logger, discovery, customPublisher } = options;
36
+ const publishers = new Publisher();
37
+ if (customPublisher) {
38
+ publishers.register("techdocs", customPublisher);
39
+ return customPublisher;
40
+ }
41
+ const publisherType = config.getOptionalString(
42
+ "techdocs.publisher.type"
43
+ ) ?? "local";
44
+ switch (publisherType) {
45
+ case "googleGcs":
46
+ logger.info("Creating Google Storage Bucket publisher for TechDocs");
47
+ publishers.register(
48
+ publisherType,
49
+ googleStorage.GoogleGCSPublish.fromConfig(
50
+ config,
51
+ logger,
52
+ options.publisherSettings?.googleGcs
53
+ )
54
+ );
55
+ break;
56
+ case "awsS3":
57
+ logger.info("Creating AWS S3 Bucket publisher for TechDocs");
58
+ publishers.register(
59
+ publisherType,
60
+ await awsS3.AwsS3Publish.fromConfig(config, logger)
61
+ );
62
+ break;
63
+ case "azureBlobStorage":
64
+ logger.info(
65
+ "Creating Azure Blob Storage Container publisher for TechDocs"
66
+ );
67
+ publishers.register(
68
+ publisherType,
69
+ azureBlobStorage.AzureBlobStoragePublish.fromConfig(config, logger)
70
+ );
71
+ break;
72
+ case "openStackSwift":
73
+ logger.info(
74
+ "Creating OpenStack Swift Container publisher for TechDocs"
75
+ );
76
+ publishers.register(
77
+ publisherType,
78
+ openStackSwift.OpenStackSwiftPublish.fromConfig(config, logger)
79
+ );
80
+ break;
81
+ case "local":
82
+ logger.info("Creating Local publisher for TechDocs");
83
+ publishers.register(
84
+ publisherType,
85
+ local.LocalPublish.fromConfig(config, logger, discovery)
86
+ );
87
+ break;
88
+ default:
89
+ logger.info("Creating Local publisher for TechDocs");
90
+ publishers.register(
91
+ publisherType,
92
+ local.LocalPublish.fromConfig(config, logger, discovery)
93
+ );
94
+ }
95
+ return publishers.get(config);
96
+ }
97
+ }
98
+
99
+ exports.Publisher = Publisher;
100
+ //# sourceMappingURL=publish.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.cjs.js","sources":["../../../src/stages/publish/publish.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 { Config } from '@backstage/config';\nimport { AwsS3Publish } from './awsS3';\nimport { AzureBlobStoragePublish } from './azureBlobStorage';\nimport { GoogleGCSPublish } from './googleStorage';\nimport { LocalPublish } from './local';\nimport { OpenStackSwiftPublish } from './openStackSwift';\nimport {\n PublisherFactory,\n PublisherBase,\n PublisherType,\n PublisherBuilder,\n} from './types';\n\n/**\n * Factory class to create a TechDocs publisher based on defined publisher type in app config.\n * Uses `techdocs.publisher.type`.\n * @public\n */\nexport class Publisher implements PublisherBuilder {\n private publishers: Map<PublisherType | 'techdocs', PublisherBase> =\n new Map();\n\n register(type: PublisherType | 'techdocs', publisher: PublisherBase): void {\n this.publishers.set(type, publisher);\n }\n\n get(config: Config): PublisherBase {\n const publisherType = (config.getOptionalString(\n 'techdocs.publisher.type',\n ) ?? 'local') as PublisherType;\n\n if (!publisherType) {\n throw new Error('TechDocs publisher type not specified for the entity');\n }\n\n const publisher = this.publishers.get(publisherType);\n if (!publisher) {\n throw new Error(\n `TechDocs publisher '${publisherType}' is not registered`,\n );\n }\n\n return publisher;\n }\n\n /**\n * Returns a instance of TechDocs publisher\n * @param config - A Backstage configuration\n * @param options - Options for configuring the publisher factory\n */\n static async fromConfig(\n config: Config,\n options: PublisherFactory,\n ): Promise<PublisherBase> {\n const { logger, discovery, customPublisher } = options;\n\n const publishers = new Publisher();\n\n if (customPublisher) {\n publishers.register('techdocs', customPublisher);\n return customPublisher;\n }\n\n const publisherType = (config.getOptionalString(\n 'techdocs.publisher.type',\n ) ?? 'local') as PublisherType;\n\n switch (publisherType) {\n case 'googleGcs':\n logger.info('Creating Google Storage Bucket publisher for TechDocs');\n publishers.register(\n publisherType,\n GoogleGCSPublish.fromConfig(\n config,\n logger,\n options.publisherSettings?.googleGcs,\n ),\n );\n break;\n case 'awsS3':\n logger.info('Creating AWS S3 Bucket publisher for TechDocs');\n publishers.register(\n publisherType,\n await AwsS3Publish.fromConfig(config, logger),\n );\n break;\n case 'azureBlobStorage':\n logger.info(\n 'Creating Azure Blob Storage Container publisher for TechDocs',\n );\n publishers.register(\n publisherType,\n AzureBlobStoragePublish.fromConfig(config, logger),\n );\n break;\n case 'openStackSwift':\n logger.info(\n 'Creating OpenStack Swift Container publisher for TechDocs',\n );\n publishers.register(\n publisherType,\n OpenStackSwiftPublish.fromConfig(config, logger),\n );\n break;\n case 'local':\n logger.info('Creating Local publisher for TechDocs');\n publishers.register(\n publisherType,\n LocalPublish.fromConfig(config, logger, discovery),\n );\n break;\n default:\n logger.info('Creating Local publisher for TechDocs');\n publishers.register(\n publisherType,\n LocalPublish.fromConfig(config, logger, discovery),\n );\n }\n\n return publishers.get(config);\n }\n}\n"],"names":["GoogleGCSPublish","AwsS3Publish","AzureBlobStoragePublish","OpenStackSwiftPublish","LocalPublish"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-techdocs-node",
3
- "version": "1.12.12-next.1",
3
+ "version": "1.12.12",
4
4
  "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli",
5
5
  "backstage": {
6
6
  "role": "node-library",
@@ -53,22 +53,22 @@
53
53
  "@aws-sdk/types": "^3.347.0",
54
54
  "@azure/identity": "^4.0.0",
55
55
  "@azure/storage-blob": "^12.5.0",
56
- "@backstage/backend-plugin-api": "1.0.1-next.0",
57
- "@backstage/catalog-model": "1.7.0",
58
- "@backstage/config": "1.2.0",
59
- "@backstage/errors": "1.2.4",
60
- "@backstage/integration": "1.15.1-next.0",
61
- "@backstage/integration-aws-node": "0.1.12",
62
- "@backstage/plugin-search-common": "1.2.14",
63
- "@backstage/plugin-techdocs-common": "0.1.0",
56
+ "@backstage/backend-plugin-api": "^1.0.1",
57
+ "@backstage/catalog-model": "^1.7.0",
58
+ "@backstage/config": "^1.2.0",
59
+ "@backstage/errors": "^1.2.4",
60
+ "@backstage/integration": "^1.15.1",
61
+ "@backstage/integration-aws-node": "^0.1.12",
62
+ "@backstage/plugin-search-common": "^1.2.14",
63
+ "@backstage/plugin-techdocs-common": "^0.1.0",
64
64
  "@google-cloud/storage": "^7.0.0",
65
- "@smithy/node-http-handler": "^2.1.7",
65
+ "@smithy/node-http-handler": "^3.0.0",
66
66
  "@trendyol-js/openstack-swift-sdk": "^0.0.7",
67
67
  "@types/express": "^4.17.6",
68
68
  "dockerode": "^4.0.0",
69
69
  "express": "^4.17.1",
70
70
  "fs-extra": "^11.2.0",
71
- "git-url-parse": "^14.0.0",
71
+ "git-url-parse": "^15.0.0",
72
72
  "hpagent": "^1.2.0",
73
73
  "js-yaml": "^4.0.0",
74
74
  "json5": "^2.1.3",
@@ -78,8 +78,8 @@
78
78
  "winston": "^3.2.1"
79
79
  },
80
80
  "devDependencies": {
81
- "@backstage/backend-test-utils": "1.0.1-next.1",
82
- "@backstage/cli": "0.28.0-next.1",
81
+ "@backstage/backend-test-utils": "^1.0.1",
82
+ "@backstage/cli": "^0.28.0",
83
83
  "@types/fs-extra": "^11.0.0",
84
84
  "@types/js-yaml": "^4.0.0",
85
85
  "@types/mime-types": "^2.1.0",