@backstage/frontend-app-api 0.0.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 +22 -0
- package/README.md +9 -0
- package/config.d.ts +35 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.esm.js +367 -0
- package/dist/index.esm.js.map +1 -0
- package/package.json +48 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# @backstage/frontend-app-api
|
|
2
|
+
|
|
3
|
+
## 0.0.1-next.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/core-plugin-api@1.6.0-next.2
|
|
9
|
+
- @backstage/plugin-graphiql@0.2.54-next.2
|
|
10
|
+
- @backstage/config@1.1.0-next.1
|
|
11
|
+
- @backstage/frontend-plugin-api@0.0.1-next.0
|
|
12
|
+
- @backstage/types@1.1.0
|
|
13
|
+
|
|
14
|
+
## 0.0.1-next.0
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies
|
|
19
|
+
- @backstage/config@1.1.0-next.0
|
|
20
|
+
- @backstage/plugin-graphiql@0.2.54-next.1
|
|
21
|
+
- @backstage/frontend-plugin-api@0.0.0
|
|
22
|
+
- @backstage/types@1.1.0
|
package/README.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# @backstage/frontend-app-api
|
|
2
|
+
|
|
3
|
+
**This package is EXPERIMENTAL, we recommend against using it for production deployments**
|
|
4
|
+
|
|
5
|
+
This package provides the core API used by Backstage frontend apps. It implements the design outlined in [RFC: Frontend System Evolution](https://github.com/backstage/backstage/issues/18372).
|
|
6
|
+
|
|
7
|
+
## Documentation
|
|
8
|
+
|
|
9
|
+
- [Backstage Documentation](https://backstage.io/docs)
|
package/config.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 The Backstage Authors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export interface Config {
|
|
18
|
+
app?: {
|
|
19
|
+
/**
|
|
20
|
+
* @deepVisibility frontend
|
|
21
|
+
*/
|
|
22
|
+
extensions?:
|
|
23
|
+
| string
|
|
24
|
+
| {
|
|
25
|
+
[extensionId: string]:
|
|
26
|
+
| boolean
|
|
27
|
+
| string
|
|
28
|
+
| {
|
|
29
|
+
at?: string;
|
|
30
|
+
extension?: string;
|
|
31
|
+
config?: unknown;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import React, { createContext } from 'react';
|
|
2
|
+
import { ConfigReader } from '@backstage/config';
|
|
3
|
+
import { createExtension, coreExtensionData } from '@backstage/frontend-plugin-api';
|
|
4
|
+
import { BrowserRouter, useRoutes } from 'react-router-dom';
|
|
5
|
+
import mapValues from 'lodash/mapValues';
|
|
6
|
+
|
|
7
|
+
const CoreRouter = createExtension({
|
|
8
|
+
id: "core.router",
|
|
9
|
+
at: "root",
|
|
10
|
+
inputs: {
|
|
11
|
+
routes: {
|
|
12
|
+
extensionData: {
|
|
13
|
+
path: coreExtensionData.routePath,
|
|
14
|
+
ref: coreExtensionData.routeRef,
|
|
15
|
+
component: coreExtensionData.reactComponent
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
output: {
|
|
20
|
+
component: coreExtensionData.reactComponent
|
|
21
|
+
},
|
|
22
|
+
factory({ bind, inputs }) {
|
|
23
|
+
const Routes = () => {
|
|
24
|
+
const element = useRoutes(
|
|
25
|
+
inputs.routes.map((route) => ({
|
|
26
|
+
path: route.path,
|
|
27
|
+
element: /* @__PURE__ */ React.createElement(route.component, null)
|
|
28
|
+
}))
|
|
29
|
+
);
|
|
30
|
+
return element;
|
|
31
|
+
};
|
|
32
|
+
bind({
|
|
33
|
+
component: () => /* @__PURE__ */ React.createElement(BrowserRouter, null, /* @__PURE__ */ React.createElement(Routes, null))
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
function createExtensionInstance(options) {
|
|
39
|
+
var _a;
|
|
40
|
+
const { extension, config, source, attachments } = options;
|
|
41
|
+
const extensionData = /* @__PURE__ */ new Map();
|
|
42
|
+
let parsedConfig;
|
|
43
|
+
try {
|
|
44
|
+
parsedConfig = (_a = extension.configSchema) == null ? void 0 : _a.parse(config != null ? config : {});
|
|
45
|
+
} catch (e) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
`Invalid configuration for extension instance '${extension.id}', ${e}`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
extension.factory({
|
|
52
|
+
source,
|
|
53
|
+
config: parsedConfig,
|
|
54
|
+
bind: (namedOutputs) => {
|
|
55
|
+
for (const [name, output] of Object.entries(namedOutputs)) {
|
|
56
|
+
const ref = extension.output[name];
|
|
57
|
+
if (!ref) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`Extension instance '${extension.id}' tried to bind unknown output '${name}'`
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
extensionData.set(ref.id, output);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
inputs: mapValues(
|
|
66
|
+
extension.inputs,
|
|
67
|
+
({ extensionData: pointData }, inputName) => {
|
|
68
|
+
var _a2;
|
|
69
|
+
return ((_a2 = attachments.get(inputName)) != null ? _a2 : []).map(
|
|
70
|
+
(attachment) => mapValues(pointData, (ref) => attachment.data.get(ref.id))
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
});
|
|
75
|
+
} catch (e) {
|
|
76
|
+
throw new Error(
|
|
77
|
+
`Failed to instantiate extension instance '${extension.id}', ${e}`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
id: options.extension.id,
|
|
82
|
+
data: extensionData,
|
|
83
|
+
attachments,
|
|
84
|
+
$$type: "extension-instance"
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const knownExtensionParameters = ["at", "disabled", "config"];
|
|
89
|
+
function readAppExtensionParameters(rootConfig) {
|
|
90
|
+
const arr = rootConfig.getOptional("app.extensions");
|
|
91
|
+
if (!Array.isArray(arr)) {
|
|
92
|
+
if (arr === void 0) {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
rootConfig.getConfigArray("app.extensions");
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
return arr.map(
|
|
99
|
+
(arrayEntry, arrayIndex) => expandShorthandExtensionParameters(arrayEntry, arrayIndex)
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
function expandShorthandExtensionParameters(arrayEntry, arrayIndex) {
|
|
103
|
+
function errorMsg(msg, key, prop) {
|
|
104
|
+
return `Invalid extension configuration at app.extensions[${arrayIndex}]${key ? `[${key}]` : ""}${prop ? `.${prop}` : ""}, ${msg}`;
|
|
105
|
+
}
|
|
106
|
+
function assertValidId(id2) {
|
|
107
|
+
if (!id2 || id2 !== id2.trim()) {
|
|
108
|
+
throw new Error(
|
|
109
|
+
errorMsg("extension ID must not be empty or contain whitespace")
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
if (id2.includes("/")) {
|
|
113
|
+
let message = `extension ID must not contain slashes; got '${id2}'`;
|
|
114
|
+
const good = id2.split("/")[0];
|
|
115
|
+
if (good) {
|
|
116
|
+
message += `, did you mean '${good}'?`;
|
|
117
|
+
}
|
|
118
|
+
throw new Error(errorMsg(message));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (typeof arrayEntry === "string") {
|
|
122
|
+
assertValidId(arrayEntry);
|
|
123
|
+
return {
|
|
124
|
+
id: arrayEntry,
|
|
125
|
+
disabled: false
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
if (typeof arrayEntry !== "object" || arrayEntry === null || Array.isArray(arrayEntry)) {
|
|
129
|
+
throw new Error(errorMsg("must be a string or an object"));
|
|
130
|
+
}
|
|
131
|
+
const keys = Object.keys(arrayEntry);
|
|
132
|
+
if (keys.length !== 1) {
|
|
133
|
+
const joinedKeys = keys.length ? `'${keys.join("', '")}'` : "none";
|
|
134
|
+
throw new Error(errorMsg(`must have exactly one key, got ${joinedKeys}`));
|
|
135
|
+
}
|
|
136
|
+
const id = String(keys[0]);
|
|
137
|
+
const value = arrayEntry[id];
|
|
138
|
+
assertValidId(id);
|
|
139
|
+
if (value === null) {
|
|
140
|
+
return {
|
|
141
|
+
id,
|
|
142
|
+
disabled: false
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
if (typeof value === "boolean") {
|
|
146
|
+
return {
|
|
147
|
+
id,
|
|
148
|
+
disabled: !value
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
152
|
+
throw new Error(errorMsg("value must be a boolean or object", id));
|
|
153
|
+
}
|
|
154
|
+
const at = value.at;
|
|
155
|
+
const disabled = value.disabled;
|
|
156
|
+
const config = value.config;
|
|
157
|
+
if (at !== void 0 && typeof at !== "string") {
|
|
158
|
+
throw new Error(errorMsg("must be a string", id, "at"));
|
|
159
|
+
} else if (disabled !== void 0 && typeof disabled !== "boolean") {
|
|
160
|
+
throw new Error(errorMsg("must be a boolean", id, "disabled"));
|
|
161
|
+
} else if (config !== void 0 && (typeof config !== "object" || config === null || Array.isArray(config))) {
|
|
162
|
+
throw new Error(errorMsg("must be an object", id, "config"));
|
|
163
|
+
}
|
|
164
|
+
const unknownKeys = Object.keys(value).filter(
|
|
165
|
+
(k) => !knownExtensionParameters.includes(k)
|
|
166
|
+
);
|
|
167
|
+
if (unknownKeys.length > 0) {
|
|
168
|
+
throw new Error(
|
|
169
|
+
errorMsg(
|
|
170
|
+
`unknown parameter; expected one of '${knownExtensionParameters.join(
|
|
171
|
+
"', '"
|
|
172
|
+
)}'`,
|
|
173
|
+
id,
|
|
174
|
+
unknownKeys.join(", ")
|
|
175
|
+
)
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
id,
|
|
180
|
+
at,
|
|
181
|
+
disabled,
|
|
182
|
+
config
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function mergeExtensionParameters(options) {
|
|
186
|
+
const { sources, builtinExtensions, parameters } = options;
|
|
187
|
+
const overrides = [
|
|
188
|
+
...sources.flatMap(
|
|
189
|
+
(plugin) => plugin.extensions.map((extension) => ({
|
|
190
|
+
extension,
|
|
191
|
+
params: {
|
|
192
|
+
source: plugin,
|
|
193
|
+
at: extension.at,
|
|
194
|
+
disabled: extension.disabled,
|
|
195
|
+
config: void 0
|
|
196
|
+
}
|
|
197
|
+
}))
|
|
198
|
+
),
|
|
199
|
+
...builtinExtensions.map((extension) => ({
|
|
200
|
+
extension,
|
|
201
|
+
params: {
|
|
202
|
+
source: void 0,
|
|
203
|
+
at: extension.at,
|
|
204
|
+
disabled: extension.disabled,
|
|
205
|
+
config: void 0
|
|
206
|
+
}
|
|
207
|
+
}))
|
|
208
|
+
];
|
|
209
|
+
for (const overrideParam of parameters) {
|
|
210
|
+
const existingIndex = overrides.findIndex(
|
|
211
|
+
(e) => e.extension.id === overrideParam.id
|
|
212
|
+
);
|
|
213
|
+
if (existingIndex !== -1) {
|
|
214
|
+
const existing = overrides[existingIndex];
|
|
215
|
+
if (overrideParam.at) {
|
|
216
|
+
existing.params.at = overrideParam.at;
|
|
217
|
+
}
|
|
218
|
+
if (overrideParam.config) {
|
|
219
|
+
existing.params.config = overrideParam.config;
|
|
220
|
+
}
|
|
221
|
+
if (Boolean(existing.params.disabled) !== Boolean(overrideParam.disabled)) {
|
|
222
|
+
existing.params.disabled = Boolean(overrideParam.disabled);
|
|
223
|
+
if (!existing.params.disabled) {
|
|
224
|
+
overrides.splice(existingIndex, 1);
|
|
225
|
+
overrides.push(existing);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
} else {
|
|
229
|
+
throw new Error(`Extension ${overrideParam.id} does not exist`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return overrides.filter((override) => !override.params.disabled).map((param) => ({
|
|
233
|
+
extension: param.extension,
|
|
234
|
+
at: param.params.at,
|
|
235
|
+
source: param.params.source,
|
|
236
|
+
config: param.params.config
|
|
237
|
+
}));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const RoutingContext = createContext({
|
|
241
|
+
resolve: () => () => ""
|
|
242
|
+
});
|
|
243
|
+
class RouteResolver {
|
|
244
|
+
constructor(routePaths) {
|
|
245
|
+
this.routePaths = routePaths;
|
|
246
|
+
}
|
|
247
|
+
resolve(anyRouteRef) {
|
|
248
|
+
const basePath = this.routePaths.get(anyRouteRef);
|
|
249
|
+
if (!basePath) {
|
|
250
|
+
return void 0;
|
|
251
|
+
}
|
|
252
|
+
return () => basePath;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
function RoutingProvider(props) {
|
|
256
|
+
return /* @__PURE__ */ React.createElement(RoutingContext.Provider, { value: new RouteResolver(props.routePaths) }, props.children);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function getAvailablePlugins() {
|
|
260
|
+
var _a;
|
|
261
|
+
const discovered = window["__@backstage/discovered__"];
|
|
262
|
+
return (_a = discovered == null ? void 0 : discovered.modules.map((m) => m.default).filter(isBackstagePlugin)) != null ? _a : [];
|
|
263
|
+
}
|
|
264
|
+
function isBackstagePlugin(obj) {
|
|
265
|
+
if (obj !== null && typeof obj === "object" && "$$type" in obj) {
|
|
266
|
+
return obj.$$type === "backstage-plugin";
|
|
267
|
+
}
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function createApp(options) {
|
|
272
|
+
var _a, _b;
|
|
273
|
+
const appConfig = ConfigReader.fromConfigs(process.env.APP_CONFIG);
|
|
274
|
+
const builtinExtensions = [CoreRouter];
|
|
275
|
+
const discoveredPlugins = getAvailablePlugins();
|
|
276
|
+
const extensionParams = mergeExtensionParameters({
|
|
277
|
+
sources: [...options.plugins, ...discoveredPlugins],
|
|
278
|
+
builtinExtensions,
|
|
279
|
+
parameters: readAppExtensionParameters(appConfig)
|
|
280
|
+
});
|
|
281
|
+
const attachmentMap = /* @__PURE__ */ new Map();
|
|
282
|
+
for (const instanceParams of extensionParams) {
|
|
283
|
+
const [extensionId, pointId = "default"] = instanceParams.at.split("/");
|
|
284
|
+
let pointMap = attachmentMap.get(extensionId);
|
|
285
|
+
if (!pointMap) {
|
|
286
|
+
pointMap = /* @__PURE__ */ new Map();
|
|
287
|
+
attachmentMap.set(extensionId, pointMap);
|
|
288
|
+
}
|
|
289
|
+
let instances2 = pointMap.get(pointId);
|
|
290
|
+
if (!instances2) {
|
|
291
|
+
instances2 = [];
|
|
292
|
+
pointMap.set(pointId, instances2);
|
|
293
|
+
}
|
|
294
|
+
instances2.push(instanceParams);
|
|
295
|
+
}
|
|
296
|
+
const instances = /* @__PURE__ */ new Map();
|
|
297
|
+
function createInstance(instanceParams) {
|
|
298
|
+
var _a2, _b2;
|
|
299
|
+
const existingInstance = instances.get(instanceParams.extension.id);
|
|
300
|
+
if (existingInstance) {
|
|
301
|
+
return existingInstance;
|
|
302
|
+
}
|
|
303
|
+
const attachments = new Map(
|
|
304
|
+
Array.from(
|
|
305
|
+
(_b2 = (_a2 = attachmentMap.get(instanceParams.extension.id)) == null ? void 0 : _a2.entries()) != null ? _b2 : []
|
|
306
|
+
).map(([inputName, attachmentConfigs]) => [
|
|
307
|
+
inputName,
|
|
308
|
+
attachmentConfigs.map(createInstance)
|
|
309
|
+
])
|
|
310
|
+
);
|
|
311
|
+
const newInstance = createExtensionInstance({
|
|
312
|
+
extension: instanceParams.extension,
|
|
313
|
+
source: instanceParams.source,
|
|
314
|
+
config: instanceParams.config,
|
|
315
|
+
attachments
|
|
316
|
+
});
|
|
317
|
+
instances.set(instanceParams.extension.id, newInstance);
|
|
318
|
+
return newInstance;
|
|
319
|
+
}
|
|
320
|
+
const rootConfigs = (_b = (_a = attachmentMap.get("root")) == null ? void 0 : _a.get("default")) != null ? _b : [];
|
|
321
|
+
const rootInstances = rootConfigs.map(
|
|
322
|
+
(instanceParams) => createInstance(instanceParams)
|
|
323
|
+
);
|
|
324
|
+
const routePaths = extractRouteInfoFromInstanceTree(rootInstances);
|
|
325
|
+
return {
|
|
326
|
+
createRoot() {
|
|
327
|
+
const rootComponents = rootInstances.map(
|
|
328
|
+
(e) => e.data.get(
|
|
329
|
+
coreExtensionData.reactComponent.id
|
|
330
|
+
)
|
|
331
|
+
);
|
|
332
|
+
return /* @__PURE__ */ React.createElement(RoutingProvider, { routePaths }, rootComponents.map((Component, i) => /* @__PURE__ */ React.createElement(Component, { key: i })));
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
function extractRouteInfoFromInstanceTree(roots) {
|
|
337
|
+
const results = /* @__PURE__ */ new Map();
|
|
338
|
+
function visit(current, basePath) {
|
|
339
|
+
var _a;
|
|
340
|
+
const routePath = (_a = current.data.get(coreExtensionData.routePath.id)) != null ? _a : "";
|
|
341
|
+
const routeRef = current.data.get(
|
|
342
|
+
coreExtensionData.routeRef.id
|
|
343
|
+
);
|
|
344
|
+
const fullPath = basePath + routePath;
|
|
345
|
+
if (routeRef) {
|
|
346
|
+
const routeRefId = routeRef.id;
|
|
347
|
+
if (routeRefId !== current.id) {
|
|
348
|
+
throw new Error(
|
|
349
|
+
`Route ref '${routeRefId}' must have the same ID as extension '${current.id}'`
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
results.set(routeRef, fullPath);
|
|
353
|
+
}
|
|
354
|
+
for (const children of current.attachments.values()) {
|
|
355
|
+
for (const child of children) {
|
|
356
|
+
visit(child, fullPath);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
for (const root of roots) {
|
|
361
|
+
visit(root, "");
|
|
362
|
+
}
|
|
363
|
+
return results;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export { createApp };
|
|
367
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/extensions/CoreRouter.tsx","../src/createExtensionInstance.ts","../src/wiring/parameters.ts","../src/routing/RoutingContext.tsx","../src/wiring/discovery.ts","../src/createApp.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport {\n createExtension,\n coreExtensionData,\n} from '@backstage/frontend-plugin-api';\nimport { BrowserRouter, useRoutes } from 'react-router-dom';\n\nexport const CoreRouter = createExtension({\n id: 'core.router',\n at: 'root',\n inputs: {\n routes: {\n extensionData: {\n path: coreExtensionData.routePath,\n ref: coreExtensionData.routeRef,\n component: coreExtensionData.reactComponent,\n },\n },\n },\n output: {\n component: coreExtensionData.reactComponent,\n },\n factory({ bind, inputs }) {\n const Routes = () => {\n const element = useRoutes(\n inputs.routes.map(route => ({\n path: route.path,\n element: <route.component />,\n })),\n );\n\n return element;\n };\n bind({\n component: () => (\n <BrowserRouter>\n <Routes />\n </BrowserRouter>\n ),\n });\n },\n});\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackstagePlugin, Extension } from '@backstage/frontend-plugin-api';\nimport mapValues from 'lodash/mapValues';\n\n/** @internal */\nexport interface ExtensionInstance {\n readonly id: string;\n /**\n * Maps extension data ref IDs to extensions produced.\n */\n readonly data: Map<string, unknown>;\n /**\n * Maps input names to the actual instances given to them.\n */\n readonly attachments: Map<string, ExtensionInstance[]>;\n readonly $$type: 'extension-instance';\n}\n\n/** @internal */\nexport function createExtensionInstance(options: {\n extension: Extension<unknown>;\n config: unknown;\n source?: BackstagePlugin;\n attachments: Map<string, ExtensionInstance[]>;\n}): ExtensionInstance {\n const { extension, config, source, attachments } = options;\n const extensionData = new Map<string, unknown>();\n\n let parsedConfig: unknown;\n try {\n parsedConfig = extension.configSchema?.parse(config ?? {});\n } catch (e) {\n throw new Error(\n `Invalid configuration for extension instance '${extension.id}', ${e}`,\n );\n }\n\n try {\n extension.factory({\n source,\n config: parsedConfig,\n bind: namedOutputs => {\n for (const [name, output] of Object.entries(namedOutputs)) {\n const ref = extension.output[name];\n if (!ref) {\n throw new Error(\n `Extension instance '${extension.id}' tried to bind unknown output '${name}'`,\n );\n }\n extensionData.set(ref.id, output);\n }\n },\n inputs: mapValues(\n extension.inputs,\n ({ extensionData: pointData }, inputName) => {\n // TODO: validation\n return (attachments.get(inputName) ?? []).map(attachment =>\n mapValues(pointData, ref => attachment.data.get(ref.id)),\n );\n },\n ),\n });\n } catch (e) {\n throw new Error(\n `Failed to instantiate extension instance '${extension.id}', ${e}`,\n );\n }\n\n return {\n id: options.extension.id,\n data: extensionData,\n attachments,\n $$type: 'extension-instance',\n };\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config } from '@backstage/config';\nimport { BackstagePlugin, Extension } from '@backstage/frontend-plugin-api';\nimport { JsonValue } from '@backstage/types';\n\nexport interface ExtensionParameters {\n id: string;\n at?: string;\n disabled?: boolean;\n config?: unknown;\n}\n\nconst knownExtensionParameters = ['at', 'disabled', 'config'];\n\n// Since we'll never merge arrays in config the config reader context\n// isn't too much of a help. Fall back to manual config reading logic\n// as the Config interface makes it quite hard for us otherwise.\n/** @internal */\nexport function readAppExtensionParameters(\n rootConfig: Config,\n): ExtensionParameters[] {\n const arr = rootConfig.getOptional('app.extensions');\n if (!Array.isArray(arr)) {\n if (arr === undefined) {\n return [];\n }\n // This will throw, and show which part of config had the wrong type\n rootConfig.getConfigArray('app.extensions');\n return [];\n }\n\n return arr.map((arrayEntry, arrayIndex) =>\n expandShorthandExtensionParameters(arrayEntry, arrayIndex),\n );\n}\n\n/** @internal */\nexport function expandShorthandExtensionParameters(\n arrayEntry: JsonValue,\n arrayIndex: number,\n): ExtensionParameters {\n function errorMsg(msg: string, key?: string, prop?: string) {\n return `Invalid extension configuration at app.extensions[${arrayIndex}]${\n key ? `[${key}]` : ''\n }${prop ? `.${prop}` : ''}, ${msg}`;\n }\n\n // NOTE(freben): This check is intentionally not complete and doesn't check\n // whether letters and digits are used, etc. It's not up to the config reading\n // logic to decide what constitutes a valid extension ID; that should be\n // decided by the logic that loads and instantiates the extensions. This check\n // is just here to catch real mistakes or truly conceptually wrong input.\n function assertValidId(id: string) {\n if (!id || id !== id.trim()) {\n throw new Error(\n errorMsg('extension ID must not be empty or contain whitespace'),\n );\n }\n\n if (id.includes('/')) {\n let message = `extension ID must not contain slashes; got '${id}'`;\n const good = id.split('/')[0];\n if (good) {\n message += `, did you mean '${good}'?`;\n }\n throw new Error(errorMsg(message));\n }\n }\n\n // Example YAML:\n // - entity.card.about\n if (typeof arrayEntry === 'string') {\n assertValidId(arrayEntry);\n return {\n id: arrayEntry,\n disabled: false,\n };\n }\n\n // All remaining cases are single-key objects\n if (\n typeof arrayEntry !== 'object' ||\n arrayEntry === null ||\n Array.isArray(arrayEntry)\n ) {\n throw new Error(errorMsg('must be a string or an object'));\n }\n const keys = Object.keys(arrayEntry);\n if (keys.length !== 1) {\n const joinedKeys = keys.length ? `'${keys.join(\"', '\")}'` : 'none';\n throw new Error(errorMsg(`must have exactly one key, got ${joinedKeys}`));\n }\n\n const id = String(keys[0]);\n const value = arrayEntry[id];\n assertValidId(id);\n\n // This example covers a potentially common mistake in the syntax\n // Example YAML:\n // - entity.card.about:\n if (value === null) {\n return {\n id,\n disabled: false,\n };\n }\n\n // Example YAML:\n // - catalog.page.cicd: false\n if (typeof value === 'boolean') {\n return {\n id,\n disabled: !value,\n };\n }\n\n // The remaining case is the generic object. Example YAML:\n // - tech-radar.page:\n // at: core.router/routes\n // disabled: false\n // config:\n // path: /tech-radar\n // width: 1500\n // height: 800\n if (typeof value !== 'object' || Array.isArray(value)) {\n // We don't mention null here - we don't want people to explicitly enter\n // - entity.card.about: null\n throw new Error(errorMsg('value must be a boolean or object', id));\n }\n\n const at = value.at;\n const disabled = value.disabled;\n const config = value.config;\n\n if (at !== undefined && typeof at !== 'string') {\n throw new Error(errorMsg('must be a string', id, 'at'));\n } else if (disabled !== undefined && typeof disabled !== 'boolean') {\n throw new Error(errorMsg('must be a boolean', id, 'disabled'));\n } else if (\n config !== undefined &&\n (typeof config !== 'object' || config === null || Array.isArray(config))\n ) {\n throw new Error(errorMsg('must be an object', id, 'config'));\n }\n\n const unknownKeys = Object.keys(value).filter(\n k => !knownExtensionParameters.includes(k),\n );\n if (unknownKeys.length > 0) {\n throw new Error(\n errorMsg(\n `unknown parameter; expected one of '${knownExtensionParameters.join(\n \"', '\",\n )}'`,\n id,\n unknownKeys.join(', '),\n ),\n );\n }\n\n return {\n id,\n at,\n disabled,\n config,\n };\n}\n\nexport interface ExtensionInstanceParameters {\n extension: Extension<unknown>;\n source?: BackstagePlugin;\n at: string;\n config?: unknown;\n}\n\n/** @internal */\nexport function mergeExtensionParameters(options: {\n sources: BackstagePlugin[];\n builtinExtensions: Extension<unknown>[];\n parameters: Array<ExtensionParameters>;\n}): ExtensionInstanceParameters[] {\n const { sources, builtinExtensions, parameters } = options;\n\n const overrides = [\n ...sources.flatMap(plugin =>\n plugin.extensions.map(extension => ({\n extension,\n params: {\n source: plugin,\n at: extension.at,\n disabled: extension.disabled,\n config: undefined as unknown,\n },\n })),\n ),\n ...builtinExtensions.map(extension => ({\n extension,\n params: {\n source: undefined,\n at: extension.at,\n disabled: extension.disabled,\n config: undefined as unknown,\n },\n })),\n ];\n\n for (const overrideParam of parameters) {\n const existingIndex = overrides.findIndex(\n e => e.extension.id === overrideParam.id,\n );\n if (existingIndex !== -1) {\n const existing = overrides[existingIndex];\n if (overrideParam.at) {\n existing.params.at = overrideParam.at;\n }\n if (overrideParam.config) {\n // TODO: merge config?\n existing.params.config = overrideParam.config;\n }\n if (\n Boolean(existing.params.disabled) !== Boolean(overrideParam.disabled)\n ) {\n existing.params.disabled = Boolean(overrideParam.disabled);\n if (!existing.params.disabled) {\n // bump\n overrides.splice(existingIndex, 1);\n overrides.push(existing);\n }\n }\n } else {\n throw new Error(`Extension ${overrideParam.id} does not exist`);\n }\n }\n\n return overrides\n .filter(override => !override.params.disabled)\n .map(param => ({\n extension: param.extension,\n at: param.params.at,\n source: param.params.source,\n config: param.params.config,\n }));\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { RouteRef } from '@backstage/core-plugin-api';\nimport React, { createContext, ReactNode } from 'react';\n\nexport interface RoutingContextType {\n resolve(\n routeRef: RouteRef,\n options: { pathname: string },\n ): (() => string) | undefined;\n}\n\nexport const RoutingContext = createContext<RoutingContextType>({\n resolve: () => () => '',\n});\n\nexport class RouteResolver {\n constructor(private readonly routePaths: Map<RouteRef, string>) {}\n\n resolve(anyRouteRef: RouteRef<{}>): (() => string) | undefined {\n const basePath = this.routePaths.get(anyRouteRef);\n if (!basePath) {\n return undefined;\n }\n return () => basePath;\n }\n}\n\nexport function RoutingProvider(props: {\n routePaths: Map<RouteRef, string>;\n children?: ReactNode;\n}) {\n return (\n <RoutingContext.Provider value={new RouteResolver(props.routePaths)}>\n {props.children}\n </RoutingContext.Provider>\n );\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackstagePlugin } from '@backstage/frontend-plugin-api';\n\ninterface DiscoveryGlobal {\n modules: Array<{ name: string; default: unknown }>;\n}\n\n/**\n * @public\n */\nexport function getAvailablePlugins(): BackstagePlugin[] {\n const discovered = (\n window as { '__@backstage/discovered__'?: DiscoveryGlobal }\n )['__@backstage/discovered__'];\n\n return (\n discovered?.modules.map(m => m.default).filter(isBackstagePlugin) ?? []\n );\n}\n\nfunction isBackstagePlugin(obj: unknown): obj is BackstagePlugin {\n if (obj !== null && typeof obj === 'object' && '$$type' in obj) {\n return obj.$$type === 'backstage-plugin';\n }\n return false;\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport { ConfigReader } from '@backstage/config';\nimport {\n BackstagePlugin,\n coreExtensionData,\n} from '@backstage/frontend-plugin-api';\nimport { CoreRouter } from './extensions/CoreRouter';\nimport {\n createExtensionInstance,\n ExtensionInstance,\n} from './createExtensionInstance';\nimport {\n ExtensionInstanceParameters,\n mergeExtensionParameters,\n readAppExtensionParameters,\n} from './wiring/parameters';\nimport { RoutingProvider } from './routing/RoutingContext';\nimport { RouteRef } from '@backstage/core-plugin-api';\nimport { getAvailablePlugins } from './wiring/discovery';\n\n/** @public */\nexport function createApp(options: { plugins: BackstagePlugin[] }): {\n createRoot(): JSX.Element;\n} {\n const appConfig = ConfigReader.fromConfigs(process.env.APP_CONFIG as any);\n\n const builtinExtensions = [CoreRouter];\n const discoveredPlugins = getAvailablePlugins();\n\n // pull in default extension instance from discovered packages\n // apply config to adjust default extension instances and add more\n const extensionParams = mergeExtensionParameters({\n sources: [...options.plugins, ...discoveredPlugins],\n builtinExtensions,\n parameters: readAppExtensionParameters(appConfig),\n });\n\n // TODO: validate the config of all extension instances\n // We do it at this point to ensure that merging (if any) of config has already happened\n\n // Create attachment map so that we can look attachments up during instance creation\n const attachmentMap = new Map<\n string,\n Map<string, ExtensionInstanceParameters[]>\n >();\n for (const instanceParams of extensionParams) {\n const [extensionId, pointId = 'default'] = instanceParams.at.split('/');\n\n let pointMap = attachmentMap.get(extensionId);\n if (!pointMap) {\n pointMap = new Map();\n attachmentMap.set(extensionId, pointMap);\n }\n\n let instances = pointMap.get(pointId);\n if (!instances) {\n instances = [];\n pointMap.set(pointId, instances);\n }\n\n instances.push(instanceParams);\n }\n\n const instances = new Map<string, ExtensionInstance>();\n\n function createInstance(\n instanceParams: ExtensionInstanceParameters,\n ): ExtensionInstance {\n const existingInstance = instances.get(instanceParams.extension.id);\n if (existingInstance) {\n return existingInstance;\n }\n\n const attachments = new Map(\n Array.from(\n attachmentMap.get(instanceParams.extension.id)?.entries() ?? [],\n ).map(([inputName, attachmentConfigs]) => [\n inputName,\n attachmentConfigs.map(createInstance),\n ]),\n );\n\n const newInstance = createExtensionInstance({\n extension: instanceParams.extension,\n source: instanceParams.source,\n config: instanceParams.config,\n attachments,\n });\n\n instances.set(instanceParams.extension.id, newInstance);\n\n return newInstance;\n }\n\n const rootConfigs = attachmentMap.get('root')?.get('default') ?? [];\n const rootInstances = rootConfigs.map(instanceParams =>\n createInstance(instanceParams),\n );\n\n const routePaths = extractRouteInfoFromInstanceTree(rootInstances);\n\n return {\n createRoot() {\n const rootComponents = rootInstances.map(\n e =>\n e.data.get(\n coreExtensionData.reactComponent.id,\n ) as typeof coreExtensionData.reactComponent.T,\n );\n return (\n <RoutingProvider routePaths={routePaths}>\n {rootComponents.map((Component, i) => (\n <Component key={i} />\n ))}\n </RoutingProvider>\n );\n },\n };\n}\n\n/** @internal */\nexport function extractRouteInfoFromInstanceTree(\n roots: ExtensionInstance[],\n): Map<RouteRef, string> {\n const results = new Map<RouteRef, string>();\n\n function visit(current: ExtensionInstance, basePath: string) {\n const routePath = current.data.get(coreExtensionData.routePath.id) ?? '';\n const routeRef = current.data.get(\n coreExtensionData.routeRef.id,\n ) as RouteRef;\n\n // TODO: join paths in a more robust way\n const fullPath = basePath + routePath;\n if (routeRef) {\n const routeRefId = (routeRef as any).id; // TODO: properly\n if (routeRefId !== current.id) {\n throw new Error(\n `Route ref '${routeRefId}' must have the same ID as extension '${current.id}'`,\n );\n }\n results.set(routeRef, fullPath);\n }\n\n for (const children of current.attachments.values()) {\n for (const child of children) {\n visit(child, fullPath);\n }\n }\n }\n\n for (const root of roots) {\n visit(root, '');\n }\n return results;\n}\n"],"names":["_a","id","instances","_b"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@backstage/frontend-app-api",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"main": "dist/index.esm.js",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public",
|
|
9
|
+
"main": "dist/index.esm.js",
|
|
10
|
+
"types": "dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"backstage": {
|
|
13
|
+
"role": "web-library"
|
|
14
|
+
},
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"scripts": {
|
|
17
|
+
"start": "backstage-cli package start",
|
|
18
|
+
"build": "backstage-cli package build",
|
|
19
|
+
"lint": "backstage-cli package lint",
|
|
20
|
+
"test": "backstage-cli package test",
|
|
21
|
+
"clean": "backstage-cli package clean",
|
|
22
|
+
"prepack": "backstage-cli package prepack",
|
|
23
|
+
"postpack": "backstage-cli package postpack"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@backstage/cli": "^0.22.13-next.2",
|
|
27
|
+
"@testing-library/jest-dom": "^5.10.1",
|
|
28
|
+
"@types/react": "^16.13.1 || ^17.0.0"
|
|
29
|
+
},
|
|
30
|
+
"configSchema": "config.d.ts",
|
|
31
|
+
"files": [
|
|
32
|
+
"config.d.ts",
|
|
33
|
+
"dist"
|
|
34
|
+
],
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@backstage/config": "^1.1.0-next.1",
|
|
37
|
+
"@backstage/core-plugin-api": "^1.6.0-next.2",
|
|
38
|
+
"@backstage/frontend-plugin-api": "^0.0.0",
|
|
39
|
+
"@backstage/plugin-graphiql": "^0.2.54-next.2",
|
|
40
|
+
"@backstage/types": "^1.1.0",
|
|
41
|
+
"lodash": "^4.17.21"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"react": "^16.13.1 || ^17.0.0",
|
|
45
|
+
"react-router-dom": "6.0.0-beta.0 || ^6.3.0"
|
|
46
|
+
},
|
|
47
|
+
"module": "./dist/index.esm.js"
|
|
48
|
+
}
|