backend -> backend-legacy, backend-next -> backend
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createBackendModule } from '@backstage/backend-plugin-api';
|
||||
import {
|
||||
DEFAULT_NAMESPACE,
|
||||
stringifyEntityRef,
|
||||
} from '@backstage/catalog-model';
|
||||
import { githubAuthenticator } from '@backstage/plugin-auth-backend-module-github-provider';
|
||||
import {
|
||||
authProvidersExtensionPoint,
|
||||
createOAuthProviderFactory,
|
||||
} from '@backstage/plugin-auth-node';
|
||||
|
||||
export default createBackendModule({
|
||||
pluginId: 'auth',
|
||||
moduleId: 'githubProvider',
|
||||
register(reg) {
|
||||
reg.registerInit({
|
||||
deps: { providers: authProvidersExtensionPoint },
|
||||
async init({ providers }) {
|
||||
providers.registerProvider({
|
||||
providerId: 'github',
|
||||
factory: createOAuthProviderFactory({
|
||||
authenticator: githubAuthenticator,
|
||||
async signInResolver({ result: { fullProfile } }, ctx) {
|
||||
const userId = fullProfile.username;
|
||||
if (!userId) {
|
||||
throw new Error(
|
||||
`GitHub user profile does not contain a username`,
|
||||
);
|
||||
}
|
||||
|
||||
const userEntityRef = stringifyEntityRef({
|
||||
kind: 'User',
|
||||
name: userId,
|
||||
namespace: DEFAULT_NAMESPACE,
|
||||
});
|
||||
|
||||
return ctx.issueToken({
|
||||
claims: {
|
||||
sub: userEntityRef,
|
||||
ent: [userEntityRef],
|
||||
},
|
||||
});
|
||||
},
|
||||
}),
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { PluginEnvironment } from './types';
|
||||
|
||||
describe('test', () => {
|
||||
it('unbreaks the test runner', () => {
|
||||
const unbreaker = {} as PluginEnvironment;
|
||||
expect(unbreaker).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+31
-164
@@ -14,171 +14,38 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Hi!
|
||||
*
|
||||
* Note that this is an EXAMPLE Backstage backend. Please check the README.
|
||||
*
|
||||
* Happy hacking!
|
||||
*/
|
||||
import { createBackend } from '@backstage/backend-defaults';
|
||||
|
||||
import Router from 'express-promise-router';
|
||||
import {
|
||||
CacheManager,
|
||||
createServiceBuilder,
|
||||
DatabaseManager,
|
||||
getRootLogger,
|
||||
HostDiscovery,
|
||||
loadBackendConfig,
|
||||
notFoundHandler,
|
||||
ServerTokenManager,
|
||||
UrlReaders,
|
||||
useHotMemoize,
|
||||
} from '@backstage/backend-common';
|
||||
import { TaskScheduler } from '@backstage/backend-tasks';
|
||||
import { Config } from '@backstage/config';
|
||||
import healthcheck from './plugins/healthcheck';
|
||||
import { metricsHandler, metricsInit } from './metrics';
|
||||
import auth from './plugins/auth';
|
||||
import catalog from './plugins/catalog';
|
||||
import events from './plugins/events';
|
||||
import kubernetes from './plugins/kubernetes';
|
||||
import scaffolder from './plugins/scaffolder';
|
||||
import proxy from './plugins/proxy';
|
||||
import search from './plugins/search';
|
||||
import techdocs from './plugins/techdocs';
|
||||
import app from './plugins/app';
|
||||
import permission from './plugins/permission';
|
||||
import signals from './plugins/signals';
|
||||
import devtools from './plugins/devtools';
|
||||
import { PluginEnvironment } from './types';
|
||||
import { ServerPermissionClient } from '@backstage/plugin-permission-node';
|
||||
import { DefaultIdentityClient } from '@backstage/plugin-auth-node';
|
||||
import { DefaultEventBroker } from '@backstage/plugin-events-backend';
|
||||
import { DefaultEventsService } from '@backstage/plugin-events-node';
|
||||
import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
|
||||
import { MeterProvider } from '@opentelemetry/sdk-metrics';
|
||||
import { metrics } from '@opentelemetry/api';
|
||||
import { DefaultSignalsService } from '@backstage/plugin-signals-node';
|
||||
const backend = createBackend();
|
||||
|
||||
// Expose opentelemetry metrics using a Prometheus exporter on
|
||||
// http://localhost:9464/metrics . See prometheus.yml in packages/backend for
|
||||
// more information on how to scrape it.
|
||||
const exporter = new PrometheusExporter();
|
||||
const meterProvider = new MeterProvider();
|
||||
metrics.setGlobalMeterProvider(meterProvider);
|
||||
meterProvider.addMetricReader(exporter);
|
||||
backend.add(import('@backstage/plugin-auth-backend'));
|
||||
backend.add(import('./authModuleGithubProvider'));
|
||||
backend.add(import('@backstage/plugin-auth-backend-module-guest-provider'));
|
||||
|
||||
function makeCreateEnv(config: Config) {
|
||||
const root = getRootLogger();
|
||||
const reader = UrlReaders.default({ logger: root, config });
|
||||
const discovery = HostDiscovery.fromConfig(config);
|
||||
const tokenManager = ServerTokenManager.fromConfig(config, { logger: root });
|
||||
const permissions = ServerPermissionClient.fromConfig(config, {
|
||||
discovery,
|
||||
tokenManager,
|
||||
});
|
||||
const databaseManager = DatabaseManager.fromConfig(config, { logger: root });
|
||||
const cacheManager = CacheManager.fromConfig(config);
|
||||
const taskScheduler = TaskScheduler.fromConfig(config, { databaseManager });
|
||||
const identity = DefaultIdentityClient.create({
|
||||
discovery,
|
||||
});
|
||||
backend.add(import('@backstage/plugin-app-backend/alpha'));
|
||||
backend.add(import('@backstage/plugin-catalog-backend-module-unprocessed'));
|
||||
backend.add(
|
||||
import('@backstage/plugin-catalog-backend-module-scaffolder-entity-model'),
|
||||
);
|
||||
backend.add(import('@backstage/plugin-catalog-backend/alpha'));
|
||||
backend.add(import('@backstage/plugin-devtools-backend'));
|
||||
backend.add(import('@backstage/plugin-kubernetes-backend/alpha'));
|
||||
backend.add(
|
||||
import('@backstage/plugin-permission-backend-module-allow-all-policy'),
|
||||
);
|
||||
backend.add(import('@backstage/plugin-permission-backend/alpha'));
|
||||
backend.add(import('@backstage/plugin-proxy-backend/alpha'));
|
||||
backend.add(import('@backstage/plugin-scaffolder-backend/alpha'));
|
||||
backend.add(import('@backstage/plugin-scaffolder-backend-module-github'));
|
||||
backend.add(import('@backstage/plugin-search-backend-module-catalog/alpha'));
|
||||
backend.add(import('@backstage/plugin-search-backend-module-explore/alpha'));
|
||||
backend.add(import('@backstage/plugin-search-backend-module-techdocs/alpha'));
|
||||
backend.add(
|
||||
import('@backstage/plugin-catalog-backend-module-backstage-openapi'),
|
||||
);
|
||||
backend.add(import('@backstage/plugin-search-backend/alpha'));
|
||||
backend.add(import('@backstage/plugin-techdocs-backend/alpha'));
|
||||
backend.add(import('@backstage/plugin-signals-backend'));
|
||||
backend.add(import('@backstage/plugin-notifications-backend'));
|
||||
|
||||
const eventsService = DefaultEventsService.create({ logger: root });
|
||||
const eventBroker = new DefaultEventBroker(
|
||||
root.child({ type: 'plugin' }),
|
||||
eventsService,
|
||||
);
|
||||
const signalsService = DefaultSignalsService.create({
|
||||
events: eventsService,
|
||||
});
|
||||
|
||||
root.info(`Created UrlReader ${reader}`);
|
||||
|
||||
return (plugin: string): PluginEnvironment => {
|
||||
const logger = root.child({ type: 'plugin', plugin });
|
||||
const database = databaseManager.forPlugin(plugin);
|
||||
const cache = cacheManager.forPlugin(plugin);
|
||||
const scheduler = taskScheduler.forPlugin(plugin);
|
||||
|
||||
return {
|
||||
logger,
|
||||
cache,
|
||||
database,
|
||||
config,
|
||||
reader,
|
||||
eventBroker,
|
||||
events: eventsService,
|
||||
discovery,
|
||||
tokenManager,
|
||||
permissions,
|
||||
scheduler,
|
||||
identity,
|
||||
signals: signalsService,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
async function main() {
|
||||
metricsInit();
|
||||
const logger = getRootLogger();
|
||||
|
||||
logger.info(
|
||||
`You are running an example backend, which is supposed to be mainly used for contributing back to Backstage. ` +
|
||||
`Do NOT deploy this to production. Read more here https://backstage.io/docs/getting-started/`,
|
||||
);
|
||||
|
||||
const config = await loadBackendConfig({
|
||||
argv: process.argv,
|
||||
logger,
|
||||
});
|
||||
|
||||
const createEnv = makeCreateEnv(config);
|
||||
|
||||
const healthcheckEnv = useHotMemoize(module, () => createEnv('healthcheck'));
|
||||
const catalogEnv = useHotMemoize(module, () => createEnv('catalog'));
|
||||
const scaffolderEnv = useHotMemoize(module, () => createEnv('scaffolder'));
|
||||
const authEnv = useHotMemoize(module, () => createEnv('auth'));
|
||||
const proxyEnv = useHotMemoize(module, () => createEnv('proxy'));
|
||||
const searchEnv = useHotMemoize(module, () => createEnv('search'));
|
||||
const techdocsEnv = useHotMemoize(module, () => createEnv('techdocs'));
|
||||
const kubernetesEnv = useHotMemoize(module, () => createEnv('kubernetes'));
|
||||
const appEnv = useHotMemoize(module, () => createEnv('app'));
|
||||
const permissionEnv = useHotMemoize(module, () => createEnv('permission'));
|
||||
const eventsEnv = useHotMemoize(module, () => createEnv('events'));
|
||||
const devToolsEnv = useHotMemoize(module, () => createEnv('devtools'));
|
||||
const signalsEnv = useHotMemoize(module, () => createEnv('signals'));
|
||||
|
||||
const apiRouter = Router();
|
||||
apiRouter.use('/catalog', await catalog(catalogEnv));
|
||||
apiRouter.use('/events', await events(eventsEnv));
|
||||
apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv));
|
||||
apiRouter.use('/auth', await auth(authEnv));
|
||||
apiRouter.use('/search', await search(searchEnv));
|
||||
apiRouter.use('/techdocs', await techdocs(techdocsEnv));
|
||||
apiRouter.use('/kubernetes', await kubernetes(kubernetesEnv));
|
||||
apiRouter.use('/proxy', await proxy(proxyEnv));
|
||||
apiRouter.use('/permission', await permission(permissionEnv));
|
||||
apiRouter.use('/devtools', await devtools(devToolsEnv));
|
||||
apiRouter.use('/signals', await signals(signalsEnv));
|
||||
apiRouter.use(notFoundHandler());
|
||||
|
||||
const service = createServiceBuilder(module)
|
||||
.loadConfig(config)
|
||||
.addRouter('', await healthcheck(healthcheckEnv))
|
||||
.addRouter('', metricsHandler())
|
||||
.addRouter('/api', apiRouter)
|
||||
.addRouter('', await app(appEnv));
|
||||
|
||||
await service.start().catch(err => {
|
||||
logger.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.hot?.accept();
|
||||
main().catch(error => {
|
||||
console.error('Backend failed to start up', error);
|
||||
process.exit(1);
|
||||
});
|
||||
backend.start();
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useHotCleanup } from '@backstage/backend-common';
|
||||
import { RequestHandler, Request } from 'express';
|
||||
import promBundle from 'express-prom-bundle';
|
||||
import prom from 'prom-client';
|
||||
import * as url from 'url';
|
||||
|
||||
/**
|
||||
* Experimental Prometheus metrics used to benchmark the performance of the
|
||||
* software catalog. Use this at your own risk.
|
||||
*/
|
||||
const rootRegEx = new RegExp('^/([^/]*)/.*');
|
||||
const apiRegEx = new RegExp('^/api/([^/]*)/.*');
|
||||
|
||||
function normalizePath(req: Request): string {
|
||||
const path = url.parse(req.originalUrl || req.url).pathname || '/';
|
||||
|
||||
// Capture /api/ and the plugin name
|
||||
if (apiRegEx.test(path)) {
|
||||
return path.replace(apiRegEx, '/api/$1');
|
||||
}
|
||||
|
||||
// Only the first path segment at root level
|
||||
return path.replace(rootRegEx, '/$1');
|
||||
}
|
||||
|
||||
export function metricsInit(): void {
|
||||
prom.collectDefaultMetrics({ prefix: 'backstage_' });
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a /metrics endpoint, register default runtime metrics and instrument the router.
|
||||
*/
|
||||
export function metricsHandler(): RequestHandler {
|
||||
// We can only initialize the metrics once and have to clean them up between hot reloads
|
||||
useHotCleanup(module, () => prom.register.clear());
|
||||
|
||||
return promBundle({
|
||||
includeMethod: true,
|
||||
includePath: true,
|
||||
// Using includePath alone is problematic, as it will include path labels with high
|
||||
// cardinality (e.g. path params). Instead we would have to template them. However, this
|
||||
// is difficult, as every backend plugin might use different routes. Instead we only take
|
||||
// the first directory of the path, to have at least an idea how each plugin performs:
|
||||
normalizePath,
|
||||
promClient: { collectDefaultMetrics: {} },
|
||||
});
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
EntityProvider,
|
||||
EntityProviderConnection,
|
||||
} from '@backstage/plugin-catalog-node';
|
||||
import { EventParams, EventsService } from '@backstage/plugin-events-node';
|
||||
import { Logger } from 'winston';
|
||||
|
||||
export class DemoEventBasedEntityProvider implements EntityProvider {
|
||||
private readonly logger: Logger;
|
||||
private readonly events: EventsService;
|
||||
private readonly topics: string[];
|
||||
|
||||
constructor(opts: {
|
||||
events: EventsService;
|
||||
logger: Logger;
|
||||
topics: string[];
|
||||
}) {
|
||||
this.events = opts.events;
|
||||
this.logger = opts.logger;
|
||||
this.topics = opts.topics;
|
||||
}
|
||||
|
||||
async subscribe() {
|
||||
await this.events.subscribe({
|
||||
id: 'DemoEventBasedEntityProvider',
|
||||
topics: this.topics,
|
||||
onEvent: async (params: EventParams): Promise<void> => {
|
||||
this.logger.info(
|
||||
`onEvent: topic=${params.topic}, metadata=${JSON.stringify(
|
||||
params.metadata,
|
||||
)}, payload=${JSON.stringify(params.eventPayload)}`,
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async connect(_: EntityProviderConnection): Promise<void> {
|
||||
// not doing anything here
|
||||
}
|
||||
|
||||
getProviderName(): string {
|
||||
return DemoEventBasedEntityProvider.name;
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createRouter } from '@backstage/plugin-app-backend';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
return await createRouter({
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
database: env.database,
|
||||
appPackageName: 'example-app',
|
||||
});
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
DEFAULT_NAMESPACE,
|
||||
stringifyEntityRef,
|
||||
} from '@backstage/catalog-model';
|
||||
import {
|
||||
createRouter,
|
||||
providers,
|
||||
defaultAuthProviderFactories,
|
||||
} from '@backstage/plugin-auth-backend';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
return await createRouter({
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
database: env.database,
|
||||
discovery: env.discovery,
|
||||
tokenManager: env.tokenManager,
|
||||
providerFactories: {
|
||||
...defaultAuthProviderFactories,
|
||||
|
||||
// NOTE: DO NOT add this many resolvers in your own instance!
|
||||
// It is important that each real user always gets resolved to
|
||||
// the same sign-in identity. The code below will not do that.
|
||||
// It is here for demo purposes only.
|
||||
github: providers.github.create({
|
||||
signIn: {
|
||||
async resolver({ result: { fullProfile } }, ctx) {
|
||||
const userId = fullProfile.username;
|
||||
if (!userId) {
|
||||
throw new Error(
|
||||
`GitHub user profile does not contain a username`,
|
||||
);
|
||||
}
|
||||
|
||||
const userEntityRef = stringifyEntityRef({
|
||||
kind: 'User',
|
||||
name: userId,
|
||||
namespace: DEFAULT_NAMESPACE,
|
||||
});
|
||||
|
||||
return ctx.issueToken({
|
||||
claims: {
|
||||
sub: userEntityRef,
|
||||
ent: [userEntityRef],
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
}),
|
||||
gitlab: providers.gitlab.create({
|
||||
signIn: {
|
||||
async resolver({ result: { fullProfile } }, ctx) {
|
||||
return ctx.signInWithCatalogUser({
|
||||
entityRef: {
|
||||
name: fullProfile.id,
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
}),
|
||||
microsoft: providers.microsoft.create({
|
||||
signIn: {
|
||||
resolver:
|
||||
providers.microsoft.resolvers.emailMatchingUserEntityAnnotation(),
|
||||
},
|
||||
}),
|
||||
google: providers.google.create({
|
||||
signIn: {
|
||||
resolver:
|
||||
providers.google.resolvers.emailLocalPartMatchingUserEntityName(),
|
||||
},
|
||||
}),
|
||||
okta: providers.okta.create({
|
||||
signIn: {
|
||||
resolver:
|
||||
providers.okta.resolvers.emailMatchingUserEntityAnnotation(),
|
||||
},
|
||||
}),
|
||||
bitbucket: providers.bitbucket.create({
|
||||
signIn: {
|
||||
resolver:
|
||||
providers.bitbucket.resolvers.usernameMatchingUserEntityAnnotation(),
|
||||
},
|
||||
}),
|
||||
onelogin: providers.onelogin.create({
|
||||
signIn: {
|
||||
async resolver({ result: { fullProfile } }, ctx) {
|
||||
return ctx.signInWithCatalogUser({
|
||||
entityRef: {
|
||||
name: fullProfile.id,
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
bitbucketServer: providers.bitbucketServer.create({
|
||||
signIn: {
|
||||
resolver:
|
||||
providers.bitbucketServer.resolvers.emailMatchingUserEntityProfileEmail(),
|
||||
},
|
||||
}),
|
||||
|
||||
// This is an example of how to configure the OAuth2Proxy provider as well
|
||||
// as how to sign a user in without a matching user entity in the catalog.
|
||||
// You can try it out using `<ProxiedSignInPage {...props} provider="myproxy" />`
|
||||
myproxy: providers.oauth2Proxy.create({
|
||||
signIn: {
|
||||
async resolver({ result }, ctx) {
|
||||
const entityRef = stringifyEntityRef({
|
||||
kind: 'user',
|
||||
namespace: DEFAULT_NAMESPACE,
|
||||
name: result.getHeader('x-forwarded-user')!,
|
||||
});
|
||||
return ctx.issueToken({
|
||||
claims: {
|
||||
sub: entityRef,
|
||||
ent: [entityRef],
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CatalogBuilder } from '@backstage/plugin-catalog-backend';
|
||||
import { ScaffolderEntitiesProcessor } from '@backstage/plugin-catalog-backend-module-scaffolder-entity-model';
|
||||
import { UnprocessedEntitiesModule } from '@backstage/plugin-catalog-backend-module-unprocessed';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
import { DemoEventBasedEntityProvider } from './DemoEventBasedEntityProvider';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
const builder = CatalogBuilder.create(env);
|
||||
builder.addProcessor(new ScaffolderEntitiesProcessor());
|
||||
|
||||
const demoProvider = new DemoEventBasedEntityProvider({
|
||||
events: env.events,
|
||||
logger: env.logger,
|
||||
topics: ['example'],
|
||||
});
|
||||
await demoProvider.subscribe();
|
||||
builder.addEntityProvider(demoProvider);
|
||||
|
||||
const { processingEngine, router } = await builder.build();
|
||||
|
||||
const unprocessed = UnprocessedEntitiesModule.create({
|
||||
database: await env.database.getClient(),
|
||||
router,
|
||||
permissions: env.permissions,
|
||||
discovery: env.discovery,
|
||||
});
|
||||
|
||||
unprocessed.registerRoutes();
|
||||
|
||||
await processingEngine.start();
|
||||
return router;
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createRouter } from '@backstage/plugin-devtools-backend';
|
||||
import { Router } from 'express';
|
||||
import type { PluginEnvironment } from '../types';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
return createRouter({
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
permissions: env.permissions,
|
||||
discovery: env.discovery,
|
||||
});
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { HttpPostIngressEventPublisher } from '@backstage/plugin-events-backend';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
const eventsRouter = Router();
|
||||
|
||||
const http = HttpPostIngressEventPublisher.fromConfig({
|
||||
config: env.config,
|
||||
events: env.events,
|
||||
logger: env.logger,
|
||||
});
|
||||
http.bind(eventsRouter);
|
||||
|
||||
return eventsRouter;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createStatusCheckRouter } from '@backstage/backend-common';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
return await createStatusCheckRouter({
|
||||
logger: env.logger,
|
||||
path: '/healthcheck',
|
||||
});
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
import { CatalogClient } from '@backstage/catalog-client';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
const catalogApi = new CatalogClient({ discoveryApi: env.discovery });
|
||||
const { router } = await KubernetesBuilder.createBuilder({
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
catalogApi,
|
||||
permissions: env.permissions,
|
||||
discovery: env.discovery,
|
||||
}).build();
|
||||
return router;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { BackstageIdentityResponse } from '@backstage/plugin-auth-node';
|
||||
import { createRouter } from '@backstage/plugin-permission-backend';
|
||||
import {
|
||||
AuthorizeResult,
|
||||
PolicyDecision,
|
||||
} from '@backstage/plugin-permission-common';
|
||||
import {
|
||||
PermissionPolicy,
|
||||
PolicyQuery,
|
||||
} from '@backstage/plugin-permission-node';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
|
||||
class ExamplePermissionPolicy implements PermissionPolicy {
|
||||
async handle(
|
||||
_request: PolicyQuery,
|
||||
_user?: BackstageIdentityResponse,
|
||||
): Promise<PolicyDecision> {
|
||||
// some logic to determine if the user is allowed to access the resource
|
||||
|
||||
return {
|
||||
result: AuthorizeResult.ALLOW,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
return await createRouter({
|
||||
config: env.config,
|
||||
logger: env.logger,
|
||||
discovery: env.discovery,
|
||||
policy: new ExamplePermissionPolicy(),
|
||||
identity: env.identity,
|
||||
});
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createRouter } from '@backstage/plugin-proxy-backend';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
return await createRouter({
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
discovery: env.discovery,
|
||||
});
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CatalogClient } from '@backstage/catalog-client';
|
||||
import {
|
||||
createBuiltinActions,
|
||||
createRouter,
|
||||
} from '@backstage/plugin-scaffolder-backend';
|
||||
import { Router } from 'express';
|
||||
import type { PluginEnvironment } from '../types';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import { createConfluenceToMarkdownAction } from '@backstage/plugin-scaffolder-backend-module-confluence-to-markdown';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
const catalogClient = new CatalogClient({
|
||||
discoveryApi: env.discovery,
|
||||
});
|
||||
|
||||
const integrations = ScmIntegrations.fromConfig(env.config);
|
||||
|
||||
const builtInActions = createBuiltinActions({
|
||||
integrations,
|
||||
config: env.config,
|
||||
catalogClient,
|
||||
reader: env.reader,
|
||||
});
|
||||
|
||||
const actions = [
|
||||
...builtInActions,
|
||||
createConfluenceToMarkdownAction({
|
||||
integrations,
|
||||
config: env.config,
|
||||
reader: env.reader,
|
||||
}),
|
||||
];
|
||||
|
||||
return await createRouter({
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
database: env.database,
|
||||
catalogClient: catalogClient,
|
||||
reader: env.reader,
|
||||
discovery: env.discovery,
|
||||
scheduler: env.scheduler,
|
||||
permissions: env.permissions,
|
||||
actions,
|
||||
});
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useHotCleanup } from '@backstage/backend-common';
|
||||
import { DefaultCatalogCollatorFactory } from '@backstage/plugin-search-backend-module-catalog';
|
||||
import { ToolDocumentCollatorFactory } from '@backstage/plugin-search-backend-module-explore';
|
||||
import { createRouter } from '@backstage/plugin-search-backend';
|
||||
import { ElasticSearchSearchEngine } from '@backstage/plugin-search-backend-module-elasticsearch';
|
||||
import { PgSearchEngine } from '@backstage/plugin-search-backend-module-pg';
|
||||
import {
|
||||
IndexBuilder,
|
||||
SearchEngine,
|
||||
LunrSearchEngine,
|
||||
} from '@backstage/plugin-search-backend-node';
|
||||
import { DefaultTechDocsCollatorFactory } from '@backstage/plugin-search-backend-module-techdocs';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
|
||||
async function createSearchEngine(
|
||||
env: PluginEnvironment,
|
||||
): Promise<SearchEngine> {
|
||||
if (env.config.has('search.elasticsearch')) {
|
||||
return await ElasticSearchSearchEngine.fromConfig({
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
});
|
||||
}
|
||||
|
||||
if (await PgSearchEngine.supported(env.database)) {
|
||||
return await PgSearchEngine.fromConfig(env.config, {
|
||||
database: env.database,
|
||||
logger: env.logger,
|
||||
});
|
||||
}
|
||||
|
||||
return new LunrSearchEngine({ logger: env.logger });
|
||||
}
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
// Initialize a connection to a search engine.
|
||||
const searchEngine = await createSearchEngine(env);
|
||||
const indexBuilder = new IndexBuilder({
|
||||
logger: env.logger,
|
||||
searchEngine,
|
||||
});
|
||||
|
||||
const schedule = env.scheduler.createScheduledTaskRunner({
|
||||
frequency: { minutes: 10 },
|
||||
timeout: { minutes: 15 },
|
||||
// A 3 second delay gives the backend server a chance to initialize before
|
||||
// any collators are executed, which may attempt requests against the API.
|
||||
initialDelay: { seconds: 3 },
|
||||
});
|
||||
|
||||
// Collators are responsible for gathering documents known to plugins. This
|
||||
// particular collator gathers entities from the software catalog.
|
||||
indexBuilder.addCollator({
|
||||
schedule,
|
||||
factory: DefaultCatalogCollatorFactory.fromConfig(env.config, {
|
||||
discovery: env.discovery,
|
||||
tokenManager: env.tokenManager,
|
||||
}),
|
||||
});
|
||||
|
||||
indexBuilder.addCollator({
|
||||
schedule,
|
||||
factory: DefaultTechDocsCollatorFactory.fromConfig(env.config, {
|
||||
discovery: env.discovery,
|
||||
logger: env.logger,
|
||||
tokenManager: env.tokenManager,
|
||||
}),
|
||||
});
|
||||
|
||||
indexBuilder.addCollator({
|
||||
schedule,
|
||||
factory: ToolDocumentCollatorFactory.fromConfig(env.config, {
|
||||
discovery: env.discovery,
|
||||
logger: env.logger,
|
||||
}),
|
||||
});
|
||||
|
||||
// The scheduler controls when documents are gathered from collators and sent
|
||||
// to the search engine for indexing.
|
||||
const { scheduler } = await indexBuilder.build();
|
||||
scheduler.start();
|
||||
|
||||
useHotCleanup(module, () => scheduler.stop());
|
||||
|
||||
return await createRouter({
|
||||
engine: indexBuilder.getSearchEngine(),
|
||||
types: indexBuilder.getDocumentTypes(),
|
||||
discovery: env.discovery,
|
||||
permissions: env.permissions,
|
||||
config: env.config,
|
||||
logger: env.logger,
|
||||
});
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Router } from 'express';
|
||||
import { createRouter } from '@backstage/plugin-signals-backend';
|
||||
import { PluginEnvironment } from '../types';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
return await createRouter({
|
||||
logger: env.logger,
|
||||
events: env.events,
|
||||
identity: env.identity,
|
||||
discovery: env.discovery,
|
||||
});
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DockerContainerRunner } from '@backstage/backend-common';
|
||||
import {
|
||||
createRouter,
|
||||
Generators,
|
||||
Preparers,
|
||||
Publisher,
|
||||
} from '@backstage/plugin-techdocs-backend';
|
||||
import Docker from 'dockerode';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
// Preparers are responsible for fetching source files for documentation.
|
||||
const preparers = await Preparers.fromConfig(env.config, {
|
||||
logger: env.logger,
|
||||
reader: env.reader,
|
||||
});
|
||||
|
||||
// Docker client (conditionally) used by the generators, based on techdocs.generators config.
|
||||
const dockerClient = new Docker();
|
||||
const containerRunner = new DockerContainerRunner({ dockerClient });
|
||||
|
||||
// Generators are used for generating documentation sites.
|
||||
const generators = await Generators.fromConfig(env.config, {
|
||||
logger: env.logger,
|
||||
containerRunner,
|
||||
});
|
||||
|
||||
// Publisher is used for
|
||||
// 1. Publishing generated files to storage
|
||||
// 2. Fetching files from storage and passing them to TechDocs frontend.
|
||||
const publisher = await Publisher.fromConfig(env.config, {
|
||||
logger: env.logger,
|
||||
discovery: env.discovery,
|
||||
});
|
||||
|
||||
// checks if the publisher is working and logs the result
|
||||
await publisher.getReadiness();
|
||||
|
||||
return await createRouter({
|
||||
preparers,
|
||||
generators,
|
||||
publisher,
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
discovery: env.discovery,
|
||||
cache: env.cache,
|
||||
});
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Logger } from 'winston';
|
||||
import { Config } from '@backstage/config';
|
||||
import {
|
||||
PluginCacheManager,
|
||||
PluginDatabaseManager,
|
||||
PluginEndpointDiscovery,
|
||||
TokenManager,
|
||||
UrlReader,
|
||||
} from '@backstage/backend-common';
|
||||
import { PluginTaskScheduler } from '@backstage/backend-tasks';
|
||||
import { IdentityApi } from '@backstage/plugin-auth-node';
|
||||
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
|
||||
import { EventBroker, EventsService } from '@backstage/plugin-events-node';
|
||||
import { SignalsService } from '@backstage/plugin-signals-node';
|
||||
|
||||
export type PluginEnvironment = {
|
||||
logger: Logger;
|
||||
cache: PluginCacheManager;
|
||||
database: PluginDatabaseManager;
|
||||
config: Config;
|
||||
reader: UrlReader;
|
||||
discovery: PluginEndpointDiscovery;
|
||||
tokenManager: TokenManager;
|
||||
permissions: PermissionEvaluator;
|
||||
scheduler: PluginTaskScheduler;
|
||||
identity: IdentityApi;
|
||||
/**
|
||||
* @deprecated use `events` instead
|
||||
*/
|
||||
eventBroker: EventBroker;
|
||||
events: EventsService;
|
||||
signals: SignalsService;
|
||||
};
|
||||
Reference in New Issue
Block a user