@axis-backstage/plugin-statuspage-backend 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # @axis-backstage/plugin-statuspage-backend
2
+
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - b445aaa: Initial Release of the Statuspage Plugin
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [b445aaa]
12
+ - @axis-backstage/plugin-statuspage-common@0.2.0
package/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # Statuspage backend
2
+
3
+ Welcome to the Statuspage backend plugin!
4
+
5
+ The plugin retrieves component status information the statuspage.io api.
6
+
7
+ ## Setup
8
+
9
+ The following sections will help you get the Readme Backend plugin setup and running.
10
+
11
+ ### Installation
12
+
13
+ Install the plugin by following the example below:
14
+
15
+ ```bash
16
+ # From your Backstage root directory
17
+ yarn --cwd packages/backend add @axis-backstage/plugin-statuspage-backend
18
+ ```
19
+
20
+ ### Integrating
21
+
22
+ Here's how to get the backend plugin up and running:
23
+
24
+ 1. Create a new file named `packages/backend/src/plugins/statuspage.ts`, and add the following to it:
25
+
26
+ ```ts
27
+ import { PluginEnvironment } from '../types';
28
+ import { createRouter } from '@internal/plugin-statuspage-backend';
29
+ import { Router } from 'express';
30
+
31
+ export default async function createPlugin(
32
+ env: PluginEnvironment,
33
+ ): Promise<Router> {
34
+ return await createRouter({
35
+ logger: env.logger,
36
+ config: env.config,
37
+ });
38
+ }
39
+ ```
40
+
41
+ 2. Wire this into the overall backend router by adding the following to `packages/backend/src/index.ts`:
42
+
43
+ ```ts
44
+ import statuspage from './plugins/statuspage';
45
+ ...
46
+
47
+ async function main() {
48
+ // Add this line under the other lines that follow the useHotMemoize pattern
49
+ const statuspageEnv = useHotMemoize(module, () => createEnv('statuspage'));
50
+
51
+ ....
52
+
53
+ // Add this under the lines that add their routers to apiRouter
54
+ apiRouter.use('/statuspage', authMiddleware, await statuspage(statuspageEnv));
55
+ }
56
+ ```
package/config.d.ts ADDED
@@ -0,0 +1,30 @@
1
+ export interface Config {
2
+ /**
3
+ * Configuration for the StatusPage plugin.
4
+ * @visibility backend
5
+ */
6
+ statuspage: {
7
+ /**
8
+ * The name of the instance
9
+ * @visibility backend
10
+ */
11
+ name: string;
12
+
13
+ /**
14
+ * The page id of the your statuspage
15
+ * @visibility backend
16
+ */
17
+ pageid: string;
18
+
19
+ /**
20
+ * Client access token
21
+ * @visibility secret
22
+ */
23
+ token: string;
24
+
25
+ /**
26
+ * Link to the statuspage
27
+ */
28
+ link?: string;
29
+ }[];
30
+ }
@@ -0,0 +1,123 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var backendCommon = require('@backstage/backend-common');
6
+ var express = require('express');
7
+ var Router = require('express-promise-router');
8
+ var fetch = require('cross-fetch');
9
+ var backendPluginApi = require('@backstage/backend-plugin-api');
10
+
11
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
+
13
+ var express__default = /*#__PURE__*/_interopDefaultLegacy(express);
14
+ var Router__default = /*#__PURE__*/_interopDefaultLegacy(Router);
15
+ var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch);
16
+
17
+ const BASE_URL = "https://api.statuspage.io/v1/pages/";
18
+ const getInstance = (config, name) => {
19
+ const instance = config.find((i) => i.name === name);
20
+ if (!instance) {
21
+ throw new Error(
22
+ `Config for instance '${name}' not found in statuspage.instances`
23
+ );
24
+ }
25
+ return instance;
26
+ };
27
+ const fetchData = async (url, token) => {
28
+ const response = await fetch__default["default"](url, {
29
+ headers: {
30
+ Authorization: `OAuth ${token}`,
31
+ Accept: "application/json"
32
+ }
33
+ });
34
+ if (!response.ok) {
35
+ throw new Error(`Failed to fetch status page data from ${url}`);
36
+ }
37
+ return response.json();
38
+ };
39
+ const fetchComponents = async (name, config) => {
40
+ const instance = getInstance(config, name);
41
+ const url = `${BASE_URL}${instance.pageid}/components`;
42
+ return fetchData(url, instance.token);
43
+ };
44
+ const fetchComponentGroups = async (name, config) => {
45
+ const instance = getInstance(config, name);
46
+ const url = `${BASE_URL}${instance.pageid}/component-groups`;
47
+ return fetchData(url, instance.token);
48
+ };
49
+ const getLink = (name, config) => {
50
+ const instance = getInstance(config, name);
51
+ return instance.link;
52
+ };
53
+
54
+ function getStatuspageConfig(config) {
55
+ const statuspageConfig = config.getOptional("statuspage");
56
+ if (!statuspageConfig) {
57
+ return [];
58
+ }
59
+ return statuspageConfig;
60
+ }
61
+
62
+ const COMPONENT_GROUPS_KEY = "component-groups";
63
+ const COMPONENTS_KEY = "components";
64
+ async function createRouter(options) {
65
+ const { logger, config } = options;
66
+ logger.info("Setting up router for statuspage-backend");
67
+ const pluginCache = backendCommon.CacheManager.fromConfig(config).forPlugin("statuspage");
68
+ const statuspageConfig = getStatuspageConfig(config);
69
+ const cache = pluginCache.getClient({ defaultTtl: 1e3 * 60 * 2 });
70
+ const router = Router__default["default"]();
71
+ router.use(express__default["default"].json());
72
+ router.get("/fetch-components/:name", async (request, response) => {
73
+ const name = request.params.name;
74
+ let components = await cache.get(`${COMPONENTS_KEY}-${name}`);
75
+ if (!components) {
76
+ components = await fetchComponents(name, statuspageConfig);
77
+ await cache.set(`${COMPONENTS_KEY}-${name}`, components);
78
+ }
79
+ response.json(components);
80
+ });
81
+ router.get("/fetch-component-groups/:name", async (request, response) => {
82
+ const name = request.params.name;
83
+ let componentGroups = await cache.get(
84
+ `${COMPONENT_GROUPS_KEY}-${name}`
85
+ );
86
+ if (!componentGroups) {
87
+ componentGroups = await fetchComponentGroups(name, statuspageConfig);
88
+ await cache.set(`${COMPONENT_GROUPS_KEY}-${name}`, componentGroups);
89
+ }
90
+ response.json(componentGroups);
91
+ });
92
+ router.get("/fetch-link/:name", (request, response) => {
93
+ const name = request.params.name;
94
+ response.json({ url: getLink(name, statuspageConfig) || "" });
95
+ });
96
+ router.use(backendCommon.errorHandler());
97
+ return router;
98
+ }
99
+
100
+ const statuspagePlugin = backendPluginApi.createBackendPlugin({
101
+ pluginId: "statuspage",
102
+ register(env) {
103
+ env.registerInit({
104
+ deps: {
105
+ config: backendPluginApi.coreServices.rootConfig,
106
+ logger: backendPluginApi.coreServices.logger,
107
+ httpRouter: backendPluginApi.coreServices.httpRouter
108
+ },
109
+ async init({ config, logger, httpRouter }) {
110
+ httpRouter.use(
111
+ await createRouter({
112
+ config,
113
+ logger: backendCommon.loggerToWinstonLogger(logger)
114
+ })
115
+ );
116
+ }
117
+ });
118
+ }
119
+ });
120
+
121
+ exports.createRouter = createRouter;
122
+ exports["default"] = statuspagePlugin;
123
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/service/api.ts","../src/config.ts","../src/service/router.ts","../src/plugin.ts"],"sourcesContent":["import fetch from 'cross-fetch';\nimport type {\n Component,\n ComponentGroup,\n} from '@axis-backstage/plugin-statuspage-common';\nimport { StatuspageConfig } from '../types';\n\nconst BASE_URL = 'https://api.statuspage.io/v1/pages/';\n\nconst getInstance = (config: StatuspageConfig, name: string) => {\n const instance = config.find(i => i.name === name);\n\n if (!instance) {\n throw new Error(\n `Config for instance '${name}' not found in statuspage.instances`,\n );\n }\n\n return instance;\n};\n\nconst fetchData = async <T>(url: string, token: string): Promise<T> => {\n const response = await fetch(url, {\n headers: {\n Authorization: `OAuth ${token}`,\n Accept: 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch status page data from ${url}`);\n }\n\n return response.json() as T;\n};\n\nexport const fetchComponents = async (\n name: string,\n config: StatuspageConfig,\n): Promise<Component[]> => {\n const instance = getInstance(config, name);\n const url = `${BASE_URL}${instance.pageid}/components`;\n return fetchData<Component[]>(url, instance.token);\n};\n\nexport const fetchComponentGroups = async (\n name: string,\n config: StatuspageConfig,\n): Promise<ComponentGroup[]> => {\n const instance = getInstance(config, name);\n const url = `${BASE_URL}${instance.pageid}/component-groups`;\n return fetchData(url, instance.token);\n};\n\nexport const getLink = (\n name: string,\n config: StatuspageConfig,\n): string | undefined => {\n const instance = getInstance(config, name);\n return instance.link;\n};\n","import { Config } from '@backstage/config';\nimport type { StatuspageConfig } from './types';\n\nexport function getStatuspageConfig(config: Config): StatuspageConfig {\n const statuspageConfig = config.getOptional('statuspage');\n if (!statuspageConfig) {\n return [];\n }\n return statuspageConfig as unknown as StatuspageConfig;\n}\n","import { CacheManager, errorHandler } from '@backstage/backend-common';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { Logger } from 'winston';\nimport { fetchComponentGroups, fetchComponents, getLink } from './api';\nimport { Config } from '@backstage/config';\nimport { getStatuspageConfig } from '../config';\n\n/**\n * Router options.\n *\n * @public\n */\nexport interface RouterOptions {\n /** The logger instance */\n logger: Logger;\n /** Backstage config object */\n config: Config;\n}\n\nconst COMPONENT_GROUPS_KEY = 'component-groups';\nconst COMPONENTS_KEY = 'components';\n\n/**\n * Create the router.\n *\n * @public\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const { logger, config } = options;\n logger.info('Setting up router for statuspage-backend');\n const pluginCache = CacheManager.fromConfig(config).forPlugin('statuspage');\n const statuspageConfig = getStatuspageConfig(config);\n const cache = pluginCache.getClient({ defaultTtl: 1000 * 60 * 2 });\n\n const router = Router();\n router.use(express.json());\n\n router.get('/fetch-components/:name', async (request, response) => {\n const name = request.params.name;\n let components = (await cache.get(`${COMPONENTS_KEY}-${name}`)) as any;\n if (!components) {\n components = await fetchComponents(name, statuspageConfig);\n await cache.set(`${COMPONENTS_KEY}-${name}`, components);\n }\n response.json(components);\n });\n\n router.get('/fetch-component-groups/:name', async (request, response) => {\n const name = request.params.name;\n let componentGroups = (await cache.get(\n `${COMPONENT_GROUPS_KEY}-${name}`,\n )) as any;\n if (!componentGroups) {\n componentGroups = await fetchComponentGroups(name, statuspageConfig);\n await cache.set(`${COMPONENT_GROUPS_KEY}-${name}`, componentGroups);\n }\n response.json(componentGroups);\n });\n\n router.get('/fetch-link/:name', (request, response) => {\n const name = request.params.name;\n response.json({ url: getLink(name, statuspageConfig) || '' });\n });\n\n router.use(errorHandler());\n return router;\n}\n","import { loggerToWinstonLogger } from '@backstage/backend-common';\nimport {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './service/router';\n\n/**\n * Entrypoint for our plugin.\n *\n * @public\n */\nexport const statuspagePlugin = createBackendPlugin({\n pluginId: 'statuspage',\n register(env) {\n env.registerInit({\n deps: {\n config: coreServices.rootConfig,\n logger: coreServices.logger,\n httpRouter: coreServices.httpRouter,\n },\n async init({ config, logger, httpRouter }) {\n httpRouter.use(\n await createRouter({\n config,\n logger: loggerToWinstonLogger(logger),\n }),\n );\n },\n });\n },\n});\n"],"names":["fetch","CacheManager","Router","express","errorHandler","createBackendPlugin","coreServices","loggerToWinstonLogger"],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import express from 'express';
2
+ import { Logger } from 'winston';
3
+ import { Config } from '@backstage/config';
4
+ import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
5
+
6
+ /**
7
+ * Router options.
8
+ *
9
+ * @public
10
+ */
11
+ interface RouterOptions {
12
+ /** The logger instance */
13
+ logger: Logger;
14
+ /** Backstage config object */
15
+ config: Config;
16
+ }
17
+ /**
18
+ * Create the router.
19
+ *
20
+ * @public
21
+ */
22
+ declare function createRouter(options: RouterOptions): Promise<express.Router>;
23
+
24
+ /**
25
+ * Entrypoint for our plugin.
26
+ *
27
+ * @public
28
+ */
29
+ declare const statuspagePlugin: () => _backstage_backend_plugin_api.BackendFeature;
30
+
31
+ export { RouterOptions, createRouter, statuspagePlugin as default };
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@axis-backstage/plugin-statuspage-backend",
3
+ "version": "0.2.0",
4
+ "main": "dist/index.cjs.js",
5
+ "types": "dist/index.d.ts",
6
+ "license": "Apache-2.0",
7
+ "publishConfig": {
8
+ "access": "public",
9
+ "main": "dist/index.cjs.js",
10
+ "types": "dist/index.d.ts"
11
+ },
12
+ "backstage": {
13
+ "role": "backend-plugin"
14
+ },
15
+ "scripts": {
16
+ "start": "backstage-cli package start",
17
+ "build": "backstage-cli package build",
18
+ "lint": "backstage-cli package lint",
19
+ "test": "backstage-cli package test",
20
+ "clean": "backstage-cli package clean",
21
+ "prepack": "backstage-cli package prepack",
22
+ "postpack": "backstage-cli package postpack"
23
+ },
24
+ "dependencies": {
25
+ "@axis-backstage/plugin-statuspage-common": "^0.2.0",
26
+ "@backstage/backend-common": "^0.20.1",
27
+ "@backstage/backend-plugin-api": "^0.6.9",
28
+ "@backstage/config": "^1.1.1",
29
+ "@types/express": "*",
30
+ "cross-fetch": "^4.0.0",
31
+ "express": "^4.17.1",
32
+ "express-promise-router": "^4.1.0",
33
+ "winston": "^3.2.1"
34
+ },
35
+ "devDependencies": {
36
+ "@backstage/cli": "^0.25.1"
37
+ },
38
+ "files": [
39
+ "dist",
40
+ "config.d.ts"
41
+ ],
42
+ "configSchema": "config.d.ts"
43
+ }