@teambit/component 1.0.107 → 1.0.108
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/aspect-entry.ts +73 -0
- package/aspect-list.ts +132 -0
- package/component-factory.ts +190 -0
- package/component-fs.ts +66 -0
- package/component-interface.ts +26 -0
- package/component-meta.ts +29 -0
- package/component.aspect.ts +9 -0
- package/component.graphql.ts +256 -0
- package/component.main.runtime.ts +170 -0
- package/component.route.ts +38 -0
- package/component.ts +319 -0
- package/config.ts +24 -0
- package/dist/aspect-entry.d.ts +4 -4
- package/dist/aspect-entry.js +1 -2
- package/dist/aspect-entry.js.map +1 -1
- package/dist/aspect-list.js +2 -2
- package/dist/aspect-list.js.map +1 -1
- package/dist/aspect.section.d.ts +3 -3
- package/dist/component-factory.d.ts +3 -3
- package/dist/component-interface.d.ts +1 -1
- package/dist/component-map/component-map.d.ts +2 -2
- package/dist/component.composition.d.ts +2 -2
- package/dist/component.d.ts +3 -3
- package/dist/component.graphql.d.ts +13 -13
- package/dist/component.graphql.js +3 -6
- package/dist/component.graphql.js.map +1 -1
- package/dist/component.js +5 -9
- package/dist/component.js.map +1 -1
- package/dist/component.main.runtime.d.ts +2 -2
- package/dist/component.route.d.ts +2 -2
- package/dist/component.ui.runtime.d.ts +7 -7
- package/dist/component.ui.runtime.js +12 -27
- package/dist/component.ui.runtime.js.map +1 -1
- package/dist/get-component-opts.d.ts +1 -1
- package/dist/hash.d.ts +1 -1
- package/dist/{preview-1703590665075.js → preview-1703647408454.js} +2 -2
- package/dist/snap/author.d.ts +1 -1
- package/dist/snap/snap.d.ts +1 -1
- package/dist/tag/tag.d.ts +1 -1
- package/dist/tag-map.d.ts +1 -1
- package/dist/ui/aspect-page/aspect-page.d.ts +2 -2
- package/dist/ui/aspect-page/aspect-page.js +1 -2
- package/dist/ui/aspect-page/aspect-page.js.map +1 -1
- package/dist/ui/component-error/component-error.d.ts +4 -4
- package/dist/ui/component-model/component-model.d.ts +21 -21
- package/dist/ui/component-model/component-model.js +1 -1
- package/dist/ui/component-model/component-model.js.map +1 -1
- package/dist/ui/component-searcher/component-result.d.ts +4 -4
- package/dist/ui/component-searcher/component-result.js +2 -2
- package/dist/ui/component-searcher/component-result.js.map +1 -1
- package/dist/ui/component-searcher/component-searcher.d.ts +2 -2
- package/dist/ui/component.d.ts +5 -5
- package/dist/ui/component.js +6 -6
- package/dist/ui/component.js.map +1 -1
- package/dist/ui/context/component-context.d.ts +1 -1
- package/dist/ui/context/component-provider.d.ts +5 -5
- package/dist/ui/menu/menu-nav.d.ts +2 -2
- package/dist/ui/menu/menu-nav.js +5 -5
- package/dist/ui/menu/menu-nav.js.map +1 -1
- package/dist/ui/menu/menu.d.ts +9 -9
- package/dist/ui/menu/menu.js +28 -31
- package/dist/ui/menu/menu.js.map +1 -1
- package/dist/ui/menu/nav-plugin.d.ts +7 -7
- package/dist/ui/top-bar-nav/top-bar-nav.d.ts +2 -2
- package/dist/ui/use-component-from-location.js +1 -1
- package/dist/ui/use-component-from-location.js.map +1 -1
- package/dist/ui/use-component-logs.d.ts +7 -7
- package/dist/ui/use-component-logs.js +5 -6
- package/dist/ui/use-component-logs.js.map +1 -1
- package/dist/ui/use-component-query.js +13 -17
- package/dist/ui/use-component-query.js.map +1 -1
- package/dist/ui/use-component.model.d.ts +7 -7
- package/get-component-opts.ts +14 -0
- package/hash.ts +4 -0
- package/head.ts +0 -0
- package/history-graph.ts +1 -0
- package/index.ts +50 -0
- package/on-load.ts +0 -0
- package/package.json +30 -37
- package/state.ts +88 -0
- package/store.ts +3 -0
- package/tag-map.ts +87 -0
- package/tsconfig.json +16 -21
- package/types/asset.d.ts +15 -3
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import stripAnsi from 'strip-ansi';
|
|
2
|
+
import gql from 'graphql-tag';
|
|
3
|
+
import { GraphQLJSONObject } from 'graphql-type-json';
|
|
4
|
+
import { pathNormalizeToLinux } from '@teambit/legacy/dist/utils';
|
|
5
|
+
import { Component } from './component';
|
|
6
|
+
import { ComponentFactory } from './component-factory';
|
|
7
|
+
import { ComponentMain } from './component.main.runtime';
|
|
8
|
+
|
|
9
|
+
export function componentSchema(componentExtension: ComponentMain) {
|
|
10
|
+
return {
|
|
11
|
+
typeDefs: gql`
|
|
12
|
+
scalar JSON
|
|
13
|
+
scalar JSONObject
|
|
14
|
+
|
|
15
|
+
type ComponentID {
|
|
16
|
+
name: String!
|
|
17
|
+
version: String
|
|
18
|
+
scope: String
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type Tag {
|
|
22
|
+
# semver assigned to the tag.
|
|
23
|
+
version: String!
|
|
24
|
+
|
|
25
|
+
# tag hash.
|
|
26
|
+
hash: String!
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type Snap {
|
|
30
|
+
# hash of the snapshot.
|
|
31
|
+
hash: String!
|
|
32
|
+
|
|
33
|
+
# time of the snapshot.
|
|
34
|
+
timestamp: String!
|
|
35
|
+
|
|
36
|
+
# parents of the snap
|
|
37
|
+
parents: [String]!
|
|
38
|
+
|
|
39
|
+
# snapper
|
|
40
|
+
author: Author!
|
|
41
|
+
|
|
42
|
+
# snapshot message
|
|
43
|
+
message: String
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
type LogEntry {
|
|
47
|
+
message: String!
|
|
48
|
+
displayName: String
|
|
49
|
+
username: String
|
|
50
|
+
parents: [String]!
|
|
51
|
+
email: String
|
|
52
|
+
date: String
|
|
53
|
+
hash: String!
|
|
54
|
+
tag: String
|
|
55
|
+
id: String!
|
|
56
|
+
profileImage: String
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
type Author {
|
|
60
|
+
# display name of the snapper.
|
|
61
|
+
displayName: String!
|
|
62
|
+
|
|
63
|
+
# author of the snapper.
|
|
64
|
+
email: String!
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
type Component {
|
|
68
|
+
# id of the component.
|
|
69
|
+
id: ComponentID!
|
|
70
|
+
|
|
71
|
+
# head snap of the component.
|
|
72
|
+
head: Snap
|
|
73
|
+
|
|
74
|
+
# head tag of the component.
|
|
75
|
+
headTag: Tag
|
|
76
|
+
|
|
77
|
+
# list of all relative component paths.
|
|
78
|
+
fs: [String]
|
|
79
|
+
|
|
80
|
+
# relative path to the main file of the component
|
|
81
|
+
mainFile: String
|
|
82
|
+
|
|
83
|
+
# return specific file contents by relative file path.
|
|
84
|
+
getFile(path: String): String
|
|
85
|
+
|
|
86
|
+
# latest version of the component.
|
|
87
|
+
latest: String
|
|
88
|
+
|
|
89
|
+
# display name of the component
|
|
90
|
+
displayName: String!
|
|
91
|
+
|
|
92
|
+
# component buildStatus
|
|
93
|
+
buildStatus: String
|
|
94
|
+
|
|
95
|
+
# list of component releases.
|
|
96
|
+
tags: [Tag]!
|
|
97
|
+
|
|
98
|
+
# Log entry of the component.
|
|
99
|
+
log: LogEntry!
|
|
100
|
+
|
|
101
|
+
"""
|
|
102
|
+
component logs
|
|
103
|
+
"""
|
|
104
|
+
logs(
|
|
105
|
+
"""
|
|
106
|
+
type of logs to show (tag or snap)
|
|
107
|
+
"""
|
|
108
|
+
type: String
|
|
109
|
+
offset: Int
|
|
110
|
+
limit: Int
|
|
111
|
+
"""
|
|
112
|
+
head to start traversing logs from
|
|
113
|
+
"""
|
|
114
|
+
head: String
|
|
115
|
+
sort: String
|
|
116
|
+
"""
|
|
117
|
+
start traversing logs from the fetched component's head
|
|
118
|
+
"""
|
|
119
|
+
takeHeadFromComponent: Boolean
|
|
120
|
+
): [LogEntry]!
|
|
121
|
+
|
|
122
|
+
aspects(include: [String]): [Aspect]
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
type Aspect {
|
|
126
|
+
id: String!
|
|
127
|
+
icon: String
|
|
128
|
+
config: JSONObject
|
|
129
|
+
data: JSONObject
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
type InvalidComponent {
|
|
133
|
+
id: ComponentID!
|
|
134
|
+
errorName: String!
|
|
135
|
+
errorMessage: String!
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
type ComponentHost {
|
|
139
|
+
id: ID!
|
|
140
|
+
name: String!
|
|
141
|
+
|
|
142
|
+
# load a component.
|
|
143
|
+
get(id: String!, withState: Boolean): Component
|
|
144
|
+
|
|
145
|
+
# list components
|
|
146
|
+
list(offset: Int, limit: Int): [Component]!
|
|
147
|
+
|
|
148
|
+
# list invalid components and their errors
|
|
149
|
+
listInvalid: [InvalidComponent]!
|
|
150
|
+
|
|
151
|
+
# get component logs(snaps) by component id
|
|
152
|
+
snaps(id: String!): [LogEntry]! @deprecated(reason: "Use the logs field on Component")
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
type Query {
|
|
156
|
+
getHost(id: String): ComponentHost
|
|
157
|
+
}
|
|
158
|
+
`,
|
|
159
|
+
resolvers: {
|
|
160
|
+
JSONObject: GraphQLJSONObject,
|
|
161
|
+
Component: {
|
|
162
|
+
id: (component: Component) => component.id.toObject(),
|
|
163
|
+
displayName: (component: Component) => component.displayName,
|
|
164
|
+
fs: (component: Component) => {
|
|
165
|
+
return component.state.filesystem.files.map((file) => file.relative);
|
|
166
|
+
},
|
|
167
|
+
log: async (component: Component) => {
|
|
168
|
+
const snap = await component.loadSnap(component.id.version);
|
|
169
|
+
return {
|
|
170
|
+
...snap,
|
|
171
|
+
date: snap.timestamp.getTime(),
|
|
172
|
+
email: snap.author.email,
|
|
173
|
+
username: snap.author.name,
|
|
174
|
+
displayName: snap.author.displayName,
|
|
175
|
+
id: snap.hash,
|
|
176
|
+
};
|
|
177
|
+
},
|
|
178
|
+
getFile: (component: Component, { path }: { path: string }) => {
|
|
179
|
+
const maybeFile = component.state.filesystem.files.find(
|
|
180
|
+
(file) => pathNormalizeToLinux(file.relative) === path
|
|
181
|
+
);
|
|
182
|
+
if (!maybeFile) return undefined;
|
|
183
|
+
return maybeFile.contents.toString('utf-8');
|
|
184
|
+
},
|
|
185
|
+
mainFile: (component: Component) => {
|
|
186
|
+
return component.state._consumer.mainFile;
|
|
187
|
+
},
|
|
188
|
+
headTag: (component: Component) => component.headTag?.toObject(),
|
|
189
|
+
latest: (component: Component) => component.latest,
|
|
190
|
+
tags: (component) => {
|
|
191
|
+
// graphql doesn't support map types
|
|
192
|
+
return component.tags.toArray().map((tag) => tag.toObject());
|
|
193
|
+
},
|
|
194
|
+
aspects: (component: Component, { include }: { include?: string[] }) => {
|
|
195
|
+
return component.state.aspects.filter(include).serialize();
|
|
196
|
+
},
|
|
197
|
+
logs: async (
|
|
198
|
+
component: Component,
|
|
199
|
+
filter?: {
|
|
200
|
+
type?: string;
|
|
201
|
+
offset?: number;
|
|
202
|
+
limit?: number;
|
|
203
|
+
head?: string;
|
|
204
|
+
sort?: string;
|
|
205
|
+
takeHeadFromComponent: boolean;
|
|
206
|
+
}
|
|
207
|
+
) => {
|
|
208
|
+
let head = filter?.head;
|
|
209
|
+
if (!head && filter?.takeHeadFromComponent) {
|
|
210
|
+
head = component.id.version;
|
|
211
|
+
}
|
|
212
|
+
const finalFilter = { ...filter, ...{ head } };
|
|
213
|
+
return (await component.getLogs(finalFilter)).map((log) => ({ ...log, id: log.hash }));
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
ComponentHost: {
|
|
217
|
+
get: async (host: ComponentFactory, { id }: { id: string }) => {
|
|
218
|
+
try {
|
|
219
|
+
const componentId = await host.resolveComponentId(id);
|
|
220
|
+
const component = await host.get(componentId);
|
|
221
|
+
return component;
|
|
222
|
+
} catch (error: any) {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
snaps: async (host: ComponentFactory, { id }: { id: string }) => {
|
|
227
|
+
const componentId = await host.resolveComponentId(id);
|
|
228
|
+
// return (await host.getLogs(componentId)).map(log => ({...log, id: log.hash}))
|
|
229
|
+
return host.getLogs(componentId);
|
|
230
|
+
},
|
|
231
|
+
list: async (host: ComponentFactory, filter?: { offset: number; limit: number }) => {
|
|
232
|
+
return host.list(filter);
|
|
233
|
+
},
|
|
234
|
+
listInvalid: async (host: ComponentFactory) => {
|
|
235
|
+
const invalidComps = await host.listInvalid();
|
|
236
|
+
return invalidComps.map(({ id, err }) => ({
|
|
237
|
+
id,
|
|
238
|
+
errorName: err.name,
|
|
239
|
+
errorMessage: err.message ? stripAnsi(err.message) : err.name,
|
|
240
|
+
}));
|
|
241
|
+
},
|
|
242
|
+
id: async (host: ComponentFactory) => {
|
|
243
|
+
return host.name;
|
|
244
|
+
},
|
|
245
|
+
name: async (host: ComponentFactory) => {
|
|
246
|
+
return host.name;
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
Query: {
|
|
250
|
+
getHost: (componentExt: ComponentMain, { id }: { id: string }) => {
|
|
251
|
+
return componentExtension.getHost(id);
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { CLIAspect, CLIMain, MainRuntime } from '@teambit/cli';
|
|
2
|
+
import { ExpressAspect, ExpressMain, Route } from '@teambit/express';
|
|
3
|
+
import { GraphqlAspect, GraphqlMain } from '@teambit/graphql';
|
|
4
|
+
import { Slot, SlotRegistry } from '@teambit/harmony';
|
|
5
|
+
import { ComponentID } from '@teambit/component-id';
|
|
6
|
+
import { flatten, orderBy } from 'lodash';
|
|
7
|
+
import { ExtensionDataList } from '@teambit/legacy/dist/consumer/config';
|
|
8
|
+
import { ComponentFactory } from './component-factory';
|
|
9
|
+
import { ComponentAspect } from './component.aspect';
|
|
10
|
+
import { componentSchema } from './component.graphql';
|
|
11
|
+
import { ComponentRoute } from './component.route';
|
|
12
|
+
import { AspectList } from './aspect-list';
|
|
13
|
+
import { HostNotFound } from './exceptions';
|
|
14
|
+
import { AspectEntry } from './aspect-entry';
|
|
15
|
+
import {
|
|
16
|
+
ShowCmd,
|
|
17
|
+
ShowFragment,
|
|
18
|
+
NameFragment,
|
|
19
|
+
MainFileFragment,
|
|
20
|
+
IDFragment,
|
|
21
|
+
ScopeFragment,
|
|
22
|
+
FilesFragment,
|
|
23
|
+
ExtensionsFragment,
|
|
24
|
+
} from './show';
|
|
25
|
+
import { RegisteredComponentRoute } from '.';
|
|
26
|
+
|
|
27
|
+
export type ComponentHostSlot = SlotRegistry<ComponentFactory>;
|
|
28
|
+
|
|
29
|
+
export type ShowFragmentSlot = SlotRegistry<ShowFragment[]>;
|
|
30
|
+
|
|
31
|
+
export class ComponentMain {
|
|
32
|
+
constructor(
|
|
33
|
+
/**
|
|
34
|
+
* slot for component hosts to register.
|
|
35
|
+
*/
|
|
36
|
+
private hostSlot: ComponentHostSlot,
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Express Extension
|
|
40
|
+
*/
|
|
41
|
+
private express: ExpressMain,
|
|
42
|
+
|
|
43
|
+
private showFragmentSlot: ShowFragmentSlot
|
|
44
|
+
) {}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* register a new component host.
|
|
48
|
+
*/
|
|
49
|
+
registerHost(host: ComponentFactory) {
|
|
50
|
+
this.hostSlot.register(host);
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* important! avoid using this method.
|
|
56
|
+
* seems like this method was written to work around a very specific case when the ComponentID of the aspects are
|
|
57
|
+
* not available. in case of new components, to get the ComponentID, the workspace-aspect is needed to get the
|
|
58
|
+
* default-scope. when this method is called from the scope, there is no way to get the real component-id.
|
|
59
|
+
* instead, this method asks for the "scope", which when called by the scope-aspect is the current scope-name.
|
|
60
|
+
* it may or may not be the real scope-name of the aspect.
|
|
61
|
+
* to fix this possibly incorrect scope-name, the `workspace.resolveScopeAspectListIds()` checks whether the
|
|
62
|
+
* scope-name is the same as scope.name, and if so, resolve it to the correct scope-name.
|
|
63
|
+
*/
|
|
64
|
+
createAspectListFromLegacy(legacyExtensionDataList: ExtensionDataList) {
|
|
65
|
+
return AspectList.fromLegacyExtensions(legacyExtensionDataList);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
createAspectListFromEntries(entries: AspectEntry[]) {
|
|
69
|
+
return new AspectList(entries);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
registerRoute(routes: RegisteredComponentRoute[]) {
|
|
73
|
+
const routeEntries = routes.map((route: RegisteredComponentRoute) => {
|
|
74
|
+
return new ComponentRoute(route, this);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const flattenRoutes = flatten(routeEntries) as any as Route[];
|
|
78
|
+
|
|
79
|
+
this.express.register(flattenRoutes);
|
|
80
|
+
return this;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* set the prior host.
|
|
85
|
+
*/
|
|
86
|
+
setHostPriority(id: string) {
|
|
87
|
+
const host = this.hostSlot.get(id);
|
|
88
|
+
if (!host) {
|
|
89
|
+
throw new HostNotFound(id);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
this._priorHost = host;
|
|
93
|
+
return this;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* get component host by extension ID.
|
|
98
|
+
*/
|
|
99
|
+
getHost(id?: string): ComponentFactory {
|
|
100
|
+
if (id) {
|
|
101
|
+
const host = this.hostSlot.get(id);
|
|
102
|
+
if (!host) throw new HostNotFound(id);
|
|
103
|
+
return host;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return this.getPriorHost();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
getRoute(id: ComponentID, routeName: string) {
|
|
110
|
+
return `/api/${id.toString()}/~aspect/${routeName}`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* get the prior host.
|
|
115
|
+
*/
|
|
116
|
+
private getPriorHost() {
|
|
117
|
+
if (this._priorHost) return this._priorHost;
|
|
118
|
+
|
|
119
|
+
const hosts = this.hostSlot.values();
|
|
120
|
+
const priorityHost = hosts.find((host) => host.priority);
|
|
121
|
+
return priorityHost || hosts[0];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
getShowFragments() {
|
|
125
|
+
const fragments = orderBy(flatten(this.showFragmentSlot.values()), ['weight', ['asc']]);
|
|
126
|
+
return fragments;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
isHost(name: string) {
|
|
130
|
+
return !!this.hostSlot.get(name);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* register a show fragment to display further information in the `bit show` command.
|
|
135
|
+
*/
|
|
136
|
+
registerShowFragments(showFragments: ShowFragment[]) {
|
|
137
|
+
this.showFragmentSlot.register(showFragments);
|
|
138
|
+
return this;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private _priorHost: ComponentFactory | undefined;
|
|
142
|
+
|
|
143
|
+
static slots = [Slot.withType<ComponentFactory>(), Slot.withType<Route[]>(), Slot.withType<ShowFragment[]>()];
|
|
144
|
+
|
|
145
|
+
static runtime = MainRuntime;
|
|
146
|
+
static dependencies = [GraphqlAspect, ExpressAspect, CLIAspect];
|
|
147
|
+
|
|
148
|
+
static async provider(
|
|
149
|
+
[graphql, express, cli]: [GraphqlMain, ExpressMain, CLIMain],
|
|
150
|
+
config,
|
|
151
|
+
[hostSlot, showFragmentSlot]: [ComponentHostSlot, ShowFragmentSlot]
|
|
152
|
+
) {
|
|
153
|
+
const componentExtension = new ComponentMain(hostSlot, express, showFragmentSlot);
|
|
154
|
+
cli.register(new ShowCmd(componentExtension));
|
|
155
|
+
|
|
156
|
+
componentExtension.registerShowFragments([
|
|
157
|
+
new NameFragment(),
|
|
158
|
+
new MainFileFragment(),
|
|
159
|
+
new IDFragment(),
|
|
160
|
+
new ScopeFragment(),
|
|
161
|
+
new FilesFragment(),
|
|
162
|
+
new ExtensionsFragment(),
|
|
163
|
+
]);
|
|
164
|
+
graphql.register(componentSchema(componentExtension));
|
|
165
|
+
|
|
166
|
+
return componentExtension;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
ComponentAspect.addRuntime(ComponentMain);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { NextFunction, Request, Response, Route } from '@teambit/express';
|
|
2
|
+
|
|
3
|
+
import { ComponentMain } from './component.main.runtime';
|
|
4
|
+
|
|
5
|
+
export type RegisteredComponentRoute = Route & {
|
|
6
|
+
resolveComponent?: boolean;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type ComponentUrlParams = {
|
|
10
|
+
componentId: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export class ComponentRoute implements Route {
|
|
14
|
+
constructor(private registerRoute: RegisteredComponentRoute, private componentExtension: ComponentMain) {}
|
|
15
|
+
dynamicRouteRegex = '/?[^/@]+/[^~]*';
|
|
16
|
+
readonly route = `/:componentId(${this.dynamicRouteRegex})/~aspect${this.registerRoute.route}`;
|
|
17
|
+
|
|
18
|
+
get componentMiddlewares() {
|
|
19
|
+
return [
|
|
20
|
+
async (req: Request<ComponentUrlParams>, res: Response, next: NextFunction) => {
|
|
21
|
+
const resolveComponent = this.registerRoute.resolveComponent ?? true;
|
|
22
|
+
if (resolveComponent) {
|
|
23
|
+
const { componentId } = req.params;
|
|
24
|
+
const host = this.componentExtension.getHost();
|
|
25
|
+
const compId = await host.resolveComponentId(componentId);
|
|
26
|
+
const component = await host.get(compId);
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
req.component = component;
|
|
29
|
+
}
|
|
30
|
+
next();
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
method = this.registerRoute.method;
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
middlewares = this.componentMiddlewares.concat(this.registerRoute.middlewares);
|
|
38
|
+
}
|