@teambit/preview 1.0.106 → 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.
Files changed (66) hide show
  1. package/artifact-file-middleware.ts +66 -0
  2. package/bundling-strategy.ts +30 -0
  3. package/component-preview.route.ts +52 -0
  4. package/component-preview.ts +3 -0
  5. package/dist/artifact-file-middleware.d.ts +2 -2
  6. package/dist/artifact-file-middleware.js +2 -2
  7. package/dist/artifact-file-middleware.js.map +1 -1
  8. package/dist/bundler/chunks.d.ts +1 -1
  9. package/dist/bundler/html-plugin.js +1 -1
  10. package/dist/bundler/html-plugin.js.map +1 -1
  11. package/dist/bundling-strategy.d.ts +2 -2
  12. package/dist/env-preview-template.task.d.ts +1 -1
  13. package/dist/env-preview-template.task.js +1 -1
  14. package/dist/env-preview-template.task.js.map +1 -1
  15. package/dist/env-template.route.d.ts +1 -1
  16. package/dist/execution-ref.d.ts +1 -1
  17. package/dist/generate-link.d.ts +1 -1
  18. package/dist/gql/fetch-component-aspects.d.ts +1 -1
  19. package/dist/{preview-1703505948637.js → preview-1703647408454.js} +2 -2
  20. package/dist/preview-artifact.d.ts +2 -2
  21. package/dist/preview-env.d.ts +1 -1
  22. package/dist/preview-modules.d.ts +1 -1
  23. package/dist/preview.composition.d.ts +2 -2
  24. package/dist/preview.main.runtime.d.ts +14 -14
  25. package/dist/preview.main.runtime.js +17 -24
  26. package/dist/preview.main.runtime.js.map +1 -1
  27. package/dist/preview.preview.runtime.d.ts +5 -5
  28. package/dist/preview.preview.runtime.js +5 -8
  29. package/dist/preview.preview.runtime.js.map +1 -1
  30. package/dist/preview.service.d.ts +1 -1
  31. package/dist/preview.service.js +1 -1
  32. package/dist/preview.service.js.map +1 -1
  33. package/dist/preview.start-plugin.d.ts +2 -2
  34. package/dist/rendering-context.d.ts +3 -3
  35. package/dist/rendering-context.js +1 -1
  36. package/dist/rendering-context.js.map +1 -1
  37. package/dist/size-event.d.ts +1 -1
  38. package/dist/strategies/component-strategy.d.ts +1 -1
  39. package/dist/strategies/component-strategy.js +12 -15
  40. package/dist/strategies/component-strategy.js.map +1 -1
  41. package/dist/strategies/env-strategy.js +1 -1
  42. package/dist/strategies/env-strategy.js.map +1 -1
  43. package/dist/strategies/generate-component-link.d.ts +1 -1
  44. package/dist/types/preview-module.d.ts +3 -3
  45. package/env-preview-template.task.ts +280 -0
  46. package/env-template.route.ts +72 -0
  47. package/execution-ref.ts +25 -0
  48. package/generate-link.ts +73 -0
  49. package/index.ts +18 -0
  50. package/mk-temp-dir.ts +7 -0
  51. package/package.json +31 -38
  52. package/preview-artifact.ts +24 -0
  53. package/preview-assets.route.ts +36 -0
  54. package/preview-context.ts +5 -0
  55. package/preview-definition.ts +41 -0
  56. package/preview-env.ts +46 -0
  57. package/preview-type.ts +36 -0
  58. package/preview.aspect.ts +12 -0
  59. package/preview.graphql.ts +48 -0
  60. package/preview.route.ts +58 -0
  61. package/preview.task.ts +85 -0
  62. package/preview.ts +13 -0
  63. package/rendering-context.ts +16 -0
  64. package/size-event.ts +14 -0
  65. package/tsconfig.json +16 -21
  66. package/types/asset.d.ts +15 -3
@@ -0,0 +1,280 @@
1
+ import {
2
+ BuildContext,
3
+ BuiltTaskResult,
4
+ BuildTask,
5
+ TaskLocation,
6
+ ComponentResult,
7
+ CAPSULE_ARTIFACTS_DIR,
8
+ } from '@teambit/builder';
9
+ import { MainRuntime } from '@teambit/cli';
10
+ import mapSeries from 'p-map-series';
11
+ import { Component, ComponentMap } from '@teambit/component';
12
+ import { AspectLoaderMain } from '@teambit/aspect-loader';
13
+ import { Bundler, BundlerContext, BundlerHtmlConfig, BundlerResult, Target } from '@teambit/bundler';
14
+ import type { EnvDefinition, Environment, EnvsMain } from '@teambit/envs';
15
+ import { join } from 'path';
16
+ import { compact, flatten, isEmpty } from 'lodash';
17
+ import { Logger } from '@teambit/logger';
18
+ import { DependencyResolverMain } from '@teambit/dependency-resolver';
19
+ import { existsSync, mkdirpSync } from 'fs-extra';
20
+ import type { PreviewMain } from './preview.main.runtime';
21
+ import { generateTemplateEntries } from './bundler/chunks';
22
+ import { generateHtmlConfig } from './bundler/html-plugin';
23
+ import { writePeerLink } from './bundler/create-peers-link';
24
+
25
+ export type ModuleExpose = {
26
+ name: string;
27
+ path: string;
28
+ include?: string[];
29
+ };
30
+
31
+ type TargetsGroup = {
32
+ env: Environment;
33
+ envToGetBundler: Environment;
34
+ targets: Target[];
35
+ };
36
+ type TargetsGroupMap = {
37
+ [envId: string]: TargetsGroup;
38
+ };
39
+
40
+ export const GENERATE_ENV_TEMPLATE_TASK_NAME = 'GenerateEnvTemplate';
41
+
42
+ export class EnvPreviewTemplateTask implements BuildTask {
43
+ aspectId = 'teambit.preview/preview';
44
+ name = GENERATE_ENV_TEMPLATE_TASK_NAME;
45
+ location: TaskLocation = 'end';
46
+ // readonly dependencies = [CompilerAspect.id];
47
+
48
+ constructor(
49
+ private preview: PreviewMain,
50
+ private envs: EnvsMain,
51
+ private aspectLoader: AspectLoaderMain,
52
+ private dependencyResolver: DependencyResolverMain,
53
+ private logger: Logger
54
+ ) {}
55
+
56
+ async execute(context: BuildContext): Promise<BuiltTaskResult> {
57
+ const previewDefs = this.preview.getDefs();
58
+ const htmlConfig = previewDefs.map((previewModule) => generateHtmlConfig(previewModule, { dev: context.dev }));
59
+ const originalSeedersIds = context.capsuleNetwork.originalSeedersCapsules.map((c) => c.component.id.toString());
60
+ const grouped: TargetsGroupMap = {};
61
+ // avoid running them with `Promise.all` because getEnv methods do import/isolate which can't be in parallel.
62
+ await mapSeries(context.components, async (component) => {
63
+ // Do not run over other components in the graph. it make the process much longer with no need
64
+ if (originalSeedersIds && originalSeedersIds.length && !originalSeedersIds.includes(component.id.toString())) {
65
+ return undefined;
66
+ }
67
+ const envDef = this.envs.getEnvFromComponent(component);
68
+ if (!envDef) return undefined;
69
+ const env = envDef.env;
70
+ const bundlingStrategy = this.preview.getBundlingStrategy(envDef.env);
71
+ if (bundlingStrategy.name === 'env') {
72
+ return undefined;
73
+ }
74
+ const target = await this.getEnvTargetFromComponent(context, component, envDef, htmlConfig);
75
+ if (!target) return undefined;
76
+ const shouldUseDefaultBundler = this.shouldUseDefaultBundler(envDef);
77
+ let envToGetBundler = this.envs.getEnvsEnvDefinition().env;
78
+ let groupEnvId = 'default';
79
+ if (!shouldUseDefaultBundler) {
80
+ envToGetBundler = env;
81
+ groupEnvId = envDef.id;
82
+ }
83
+ if (!grouped[groupEnvId]) {
84
+ grouped[groupEnvId] = {
85
+ env,
86
+ envToGetBundler,
87
+ targets: [target],
88
+ };
89
+ } else {
90
+ grouped[groupEnvId].targets.push(target);
91
+ }
92
+ return undefined;
93
+ });
94
+ if (isEmpty(grouped)) {
95
+ return { componentsResults: [] };
96
+ }
97
+
98
+ return this.runBundlerForGroups(context, grouped);
99
+ }
100
+
101
+ private async runBundlerForGroups(context: BuildContext, groups: TargetsGroupMap): Promise<BuiltTaskResult> {
102
+ const bundlerContext: BundlerContext = Object.assign(context, {
103
+ targets: [],
104
+ entry: [],
105
+ development: context.dev,
106
+ metaData: {
107
+ initiator: `${GENERATE_ENV_TEMPLATE_TASK_NAME} task`,
108
+ envId: context.id,
109
+ isEnvTemplate: true,
110
+ },
111
+ });
112
+
113
+ const bundlerResults = await mapSeries(Object.entries(groups), async ([, targetsGroup]) => {
114
+ bundlerContext.targets = targetsGroup.targets;
115
+ const bundler: Bundler = await targetsGroup.envToGetBundler.getTemplateBundler(bundlerContext);
116
+ const bundlerResult = await bundler.run();
117
+ return bundlerResult;
118
+ });
119
+
120
+ const results = await this.computeResults(bundlerContext, flatten(bundlerResults));
121
+ return results;
122
+ }
123
+
124
+ private shouldUseDefaultBundler(envDef: EnvDefinition): boolean {
125
+ if (this.aspectLoader.isCoreEnv(envDef.id) && envDef.id !== 'teambit.react/react-native') return true;
126
+ const env = envDef.env;
127
+ if (env.getTemplateBundler && typeof env.getTemplateBundler === 'function') return false;
128
+ return true;
129
+ }
130
+
131
+ private async getEnvTargetFromComponent(
132
+ context: BuildContext,
133
+ envComponent: Component,
134
+ envDef: EnvDefinition,
135
+ htmlConfig: BundlerHtmlConfig[]
136
+ ): Promise<Target | undefined> {
137
+ const envPreviewConfig = this.preview.getEnvPreviewConfig(envDef.env);
138
+
139
+ const peers = await this.dependencyResolver.getPreviewHostDependenciesFromEnv(envDef.env);
140
+ // const module = await this.getPreviewModule(envComponent);
141
+ // const entries = Object.keys(module).map((key) => module.exposes[key]);
142
+ const capsule = context.capsuleNetwork.graphCapsules.getCapsule(envComponent.id);
143
+ if (!capsule) throw new Error('no capsule found');
144
+ // Passing here the env itself to make sure it's preview runtime will be part of the preview root file
145
+ // that's needed to make sure the providers register there are running correctly
146
+ const previewRoot = await this.preview.writePreviewRuntime(context, [envComponent.id.toString()]);
147
+ const entries = await this.generateEntries({
148
+ envDef,
149
+ splitComponentBundle: envPreviewConfig.splitComponentBundle ?? false,
150
+ workDir: capsule.path,
151
+ peers,
152
+ previewRoot,
153
+ });
154
+
155
+ const outputPath = this.computeOutputPath(context, envComponent);
156
+ if (!existsSync(outputPath)) mkdirpSync(outputPath);
157
+ const resolvedEnvAspects = await this.preview.resolveAspects(MainRuntime.name, [envComponent.id], undefined, {
158
+ requestedOnly: true,
159
+ // required to support envs that are plguins (.bit-env files)
160
+ filterByRuntime: false,
161
+ });
162
+ const resolvedEnv = resolvedEnvAspects[0];
163
+ const hostRootDir = resolvedEnv?.aspectPath;
164
+
165
+ if (!hostRootDir) {
166
+ this.logger.warn(`env preview template task, hostRootDir is not defined, for env ${envComponent.id.toString()}`);
167
+ }
168
+
169
+ return {
170
+ peers,
171
+ html: htmlConfig,
172
+ entries,
173
+ chunking: { splitChunks: true },
174
+ components: [envComponent],
175
+ outputPath,
176
+ /* It's a path to the root of the host component. */
177
+ hostRootDir,
178
+ hostDependencies: peers,
179
+ aliasHostDependencies: true,
180
+ };
181
+ }
182
+
183
+ private async generateEntries({
184
+ previewRoot,
185
+ workDir,
186
+ peers,
187
+ envDef,
188
+ splitComponentBundle,
189
+ }: {
190
+ previewRoot: string;
191
+ workDir: string;
192
+ peers: string[];
193
+ envDef: EnvDefinition;
194
+ splitComponentBundle: boolean;
195
+ }) {
196
+ const previewModules = await this.getPreviewModules(envDef);
197
+ const previewEntries = previewModules.map(({ name, path, ...rest }) => {
198
+ const linkFile = this.preview.writeLink(
199
+ name,
200
+ ComponentMap.create([]),
201
+ { default: path },
202
+ workDir,
203
+ splitComponentBundle
204
+ );
205
+
206
+ return { name, path, ...rest, entry: linkFile };
207
+ });
208
+ const peerLink = await writePeerLink(peers, workDir);
209
+
210
+ const entries = generateTemplateEntries({
211
+ peers: peerLink,
212
+ previewRootPath: previewRoot,
213
+ previewModules: previewEntries,
214
+ });
215
+ return entries;
216
+ }
217
+
218
+ async computeResults(context: BundlerContext, results: BundlerResult[]) {
219
+ const allResults = results.map((result) => {
220
+ const componentsResults: ComponentResult[] = result.components.map((component) => {
221
+ return {
222
+ component,
223
+ errors: result.errors.map((err) => (typeof err === 'string' ? err : err.message)),
224
+ warning: result.warnings,
225
+ startTime: result.startTime,
226
+ endTime: result.endTime,
227
+ };
228
+ });
229
+ return componentsResults;
230
+ });
231
+
232
+ const componentsResults = flatten(allResults);
233
+
234
+ const artifacts = getArtifactDef();
235
+
236
+ return {
237
+ componentsResults,
238
+ artifacts,
239
+ };
240
+ }
241
+
242
+ private async getPreviewModules(envDef: EnvDefinition): Promise<ModuleExpose[]> {
243
+ const previewDefs = this.preview.getDefs();
244
+
245
+ const modules = compact(
246
+ await Promise.all(
247
+ previewDefs.map(async (def) => {
248
+ if (!def.renderTemplatePathByEnv) return undefined;
249
+ return {
250
+ name: def.prefix,
251
+ path: (await def.renderTemplatePathByEnv(envDef.env)) || '',
252
+ include: def.include,
253
+ };
254
+ })
255
+ )
256
+ );
257
+
258
+ return modules;
259
+ }
260
+
261
+ private computeOutputPath(context: BuildContext, component: Component) {
262
+ const capsule = context.capsuleNetwork.graphCapsules.getCapsule(component.id);
263
+ if (!capsule) throw new Error('no capsule found');
264
+ return join(capsule.path, getArtifactDirectory());
265
+ }
266
+ }
267
+
268
+ export function getArtifactDirectory() {
269
+ return join(CAPSULE_ARTIFACTS_DIR, 'env-template');
270
+ }
271
+
272
+ export function getArtifactDef() {
273
+ return [
274
+ {
275
+ name: 'env-template',
276
+ globPatterns: ['**'],
277
+ rootDir: getArtifactDirectory(),
278
+ },
279
+ ];
280
+ }
@@ -0,0 +1,72 @@
1
+ import type { NextFunction, Request, Response } from '@teambit/express';
2
+ import type { ComponentUrlParams, RegisteredComponentRoute } from '@teambit/component';
3
+ import { noPreview, serverError } from '@teambit/ui-foundation.ui.pages.static-error';
4
+ import type { Logger } from '@teambit/logger';
5
+
6
+ import type { PreviewMain } from './preview.main.runtime';
7
+ import type { PreviewArtifact } from './preview-artifact';
8
+ import { getArtifactFileMiddleware, GetCacheControlFunc } from './artifact-file-middleware';
9
+
10
+ type UrlParams = ComponentUrlParams & {
11
+ filePath?: string;
12
+ };
13
+
14
+ // Week for now
15
+ const CACHE_MAX_AGE = 60 * 60 * 24 * 7;
16
+
17
+ const getCacheControl: GetCacheControlFunc = (_filePath: string, _contents: string, mimeType?: string | null) => {
18
+ // Do not cache the html files
19
+ if (mimeType && mimeType === 'text/html') {
20
+ return undefined;
21
+ }
22
+ return `private, max-age=${CACHE_MAX_AGE}`;
23
+ };
24
+
25
+ export class EnvTemplateRoute implements RegisteredComponentRoute {
26
+ constructor(
27
+ /**
28
+ * preview extension.
29
+ */
30
+ private preview: PreviewMain,
31
+ private logger: Logger
32
+ ) {}
33
+
34
+ route = `/env-template/:previewName/:filePath(*)`;
35
+ method = 'get';
36
+
37
+ // Since we might give it a core env id
38
+ // Then in the component route when we do host.get(id) it will fail, as we don't have the core envs in the scope/workspace
39
+ resolveComponent = false;
40
+
41
+ // @ts-ignore
42
+ middlewares = [
43
+ async (req: Request<UrlParams>, res: Response, next: NextFunction) => {
44
+ try {
45
+ // @ts-ignore TODO: @guy please fix.
46
+ // const component = req.component as Component | undefined;
47
+ // if (!component) return res.status(404).send(noPreview());
48
+
49
+ let artifact: PreviewArtifact | undefined;
50
+ // TODO - prevent error `getVinylsAndImportIfMissing is not a function` #4680
51
+ try {
52
+ const { componentId: envId } = req.params;
53
+ artifact = await this.preview.getEnvTemplateByEnvId(envId);
54
+ } catch (e: any) {
55
+ this.logger.error(`getEnvTemplateByEnvId has failed`, e);
56
+ return res.status(404).send(noPreview());
57
+ }
58
+
59
+ // @ts-ignore
60
+ req.artifact = artifact;
61
+ // @ts-ignore
62
+ req.isLegacyPath = false;
63
+
64
+ return next();
65
+ } catch (e: any) {
66
+ this.logger.error('failed getting preview', e);
67
+ return res.status(500).send(serverError());
68
+ }
69
+ },
70
+ getArtifactFileMiddleware(this.logger, getCacheControl),
71
+ ];
72
+ }
@@ -0,0 +1,25 @@
1
+ import { Component, ComponentID } from '@teambit/component';
2
+ import type { ExecutionContext } from '@teambit/envs';
3
+
4
+ // TODO - use workspace.list() instead of this
5
+ export class ExecutionRef {
6
+ constructor(public executionCtx: ExecutionContext) {
7
+ this.currentComponents = executionCtx.components;
8
+ }
9
+
10
+ currentComponents: Component[];
11
+
12
+ add(added: Component) {
13
+ this.currentComponents = this.currentComponents.concat(added);
14
+ }
15
+ remove(removed: ComponentID) {
16
+ this.currentComponents = this.currentComponents.filter((c) => c.id.toString() !== removed.toString());
17
+ }
18
+ update(next: Component) {
19
+ this.currentComponents = this.currentComponents.map((c) => (c.equals(next) ? next : c));
20
+ }
21
+
22
+ get(id: ComponentID) {
23
+ return this.currentComponents.find((x) => x.id.isEqual(id));
24
+ }
25
+ }
@@ -0,0 +1,73 @@
1
+ import { toWindowsCompatiblePath } from '@teambit/toolbox.path.to-windows-compatible-path';
2
+ import camelcase from 'camelcase';
3
+ import type { ComponentMap } from '@teambit/component';
4
+
5
+ export type MainModulesMap = {
6
+ /**
7
+ * Path to default module in case there is no specific module for the current environment.
8
+ */
9
+ default: string;
10
+ [envId: string]: string;
11
+ };
12
+
13
+ // :TODO refactor to building an AST and generate source code based on it.
14
+ export function generateLink(
15
+ prefix: string,
16
+ componentMap: ComponentMap<string[]>,
17
+ mainModulesMap?: MainModulesMap,
18
+ isSplitComponentBundle = false
19
+ ): string {
20
+ const links = componentMap.toArray().map(([component, modulePath], compIdx) => ({
21
+ componentIdentifier: component.id.fullName,
22
+ modules: modulePath.map((path, pathIdx) => ({
23
+ varName: moduleVarName(compIdx, pathIdx),
24
+ resolveFrom: toWindowsCompatiblePath(path),
25
+ })),
26
+ }));
27
+
28
+ let modulesLinks;
29
+ if (mainModulesMap) {
30
+ modulesLinks = Object.entries(mainModulesMap).map(([envId, path]) => {
31
+ const resolveFrom = toWindowsCompatiblePath(path);
32
+ const varName = getEnvVarName(envId);
33
+ return { envId, varName, resolveFrom };
34
+ });
35
+ }
36
+
37
+ return `
38
+ import { linkModules } from '${toWindowsCompatiblePath(require.resolve('./preview.preview.runtime'))}';
39
+
40
+ ${links
41
+ .map((link) => link.modules.map((module) => `import * as ${module.varName} from "${module.resolveFrom}";`).join('\n'))
42
+ .filter((line) => line !== '') // prevent empty lines
43
+ .join('\n')}
44
+
45
+ ${modulesLinks.map((module) => `import * as ${module.varName} from "${module.resolveFrom}";`).join('\n')}
46
+
47
+ linkModules('${prefix}', {
48
+ modulesMap: {
49
+ ${modulesLinks
50
+ // must include all components, including empty
51
+ .map((module) => `"${module.envId}": ${module.varName}`)
52
+ .join(',\n ')}
53
+ },
54
+ isSplitComponentBundle: ${isSplitComponentBundle},
55
+ componentMap: {
56
+ ${links
57
+ // must include all components, including empty
58
+ .map((link) => ` "${link.componentIdentifier}": [${link.modules.map((module) => module.varName).join(', ')}]`)
59
+ .join(',\n')}
60
+ }
61
+ });
62
+ `;
63
+ }
64
+
65
+ function moduleVarName(componentIdx: number, fileIdx: number) {
66
+ return `file_${componentIdx}_${fileIdx}`;
67
+ }
68
+
69
+ function getEnvVarName(envId: string) {
70
+ const envNameFormatted = camelcase(envId.replace('@', '').replace('.', '-').replace(/\//g, '-'));
71
+ const varName = `${envNameFormatted}MainModule`;
72
+ return varName;
73
+ }
package/index.ts ADDED
@@ -0,0 +1,18 @@
1
+ export { PreviewAspect as default, PreviewAspect, PreviewRuntime } from './preview.aspect';
2
+
3
+ export * from './events';
4
+ export type { PreviewEnv, Preview } from './preview-env';
5
+ export type {
6
+ PreviewMain,
7
+ EnvPreviewConfig,
8
+ ComponentPreviewSize,
9
+ PreviewStrategyName,
10
+ PreviewFiles,
11
+ ComponentPreviewMetaData,
12
+ } from './preview.main.runtime';
13
+ export type { PreviewPreview, RenderingContextOptions, RenderingContextProvider } from './preview.preview.runtime';
14
+ export type { PreviewDefinition } from './preview-definition';
15
+ export type { PreviewModule, ModuleFile } from './types/preview-module';
16
+ export type { RenderingContext } from './rendering-context';
17
+ // Exporting directly from the inner file to prevent breaking the bundling process
18
+ export { ENV_PREVIEW_STRATEGY_NAME, COMPONENT_PREVIEW_STRATEGY_NAME } from './strategies/strategies-names';
package/mk-temp-dir.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { mkdtempSync } from 'fs-extra';
2
+ import { tmpdir } from 'os';
3
+ import { sep } from 'path';
4
+
5
+ export function makeTempDir(prefix = '') {
6
+ return mkdtempSync(`${tmpdir()}${sep}${prefix}`);
7
+ }
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@teambit/preview",
3
- "version": "1.0.106",
3
+ "version": "1.0.108",
4
4
  "homepage": "https://bit.cloud/teambit/preview/preview",
5
5
  "main": "dist/index.js",
6
6
  "componentId": {
7
7
  "scope": "teambit.preview",
8
8
  "name": "preview",
9
- "version": "1.0.106"
9
+ "version": "1.0.108"
10
10
  },
11
11
  "dependencies": {
12
12
  "mime": "2.5.2",
@@ -16,58 +16,54 @@
16
16
  "camelcase": "6.2.0",
17
17
  "graphql-tag": "2.12.1",
18
18
  "object-hash": "2.1.1",
19
- "cross-fetch": "3.1.5",
20
- "memoizee": "0.4.15",
21
19
  "lodash.compact": "3.0.1",
22
20
  "graphql-request": "6.1.0",
23
- "core-js": "^3.0.0",
24
- "@babel/runtime": "7.20.0",
25
21
  "@teambit/ui-foundation.ui.pages.static-error": "0.0.92",
26
22
  "@teambit/component-id": "1.2.0",
27
23
  "@teambit/harmony": "0.4.6",
28
24
  "@teambit/bit-error": "0.0.404",
29
- "@teambit/express": "0.0.938",
30
- "@teambit/logger": "0.0.932",
31
- "@teambit/builder": "1.0.106",
32
- "@teambit/bundler": "1.0.106",
33
- "@teambit/component": "1.0.106",
25
+ "@teambit/express": "0.0.939",
26
+ "@teambit/logger": "0.0.933",
27
+ "@teambit/builder": "1.0.108",
28
+ "@teambit/bundler": "1.0.108",
29
+ "@teambit/component": "1.0.108",
34
30
  "@teambit/preview.ui.component-preview": "1.0.3",
35
- "@teambit/aspect-loader": "1.0.106",
36
- "@teambit/cli": "0.0.839",
37
- "@teambit/dependency-resolver": "1.0.106",
38
- "@teambit/envs": "1.0.106",
31
+ "@teambit/aspect-loader": "1.0.108",
32
+ "@teambit/cli": "0.0.840",
33
+ "@teambit/dependency-resolver": "1.0.108",
34
+ "@teambit/envs": "1.0.108",
39
35
  "@teambit/toolbox.path.to-windows-compatible-path": "0.0.494",
40
- "@teambit/graphql": "1.0.106",
41
- "@teambit/pkg": "1.0.106",
42
- "@teambit/pubsub": "1.0.106",
43
- "@teambit/scope": "1.0.106",
44
- "@teambit/ui": "1.0.106",
45
- "@teambit/watcher": "1.0.106",
46
- "@teambit/workspace": "1.0.106",
47
- "@teambit/compiler": "1.0.106",
36
+ "@teambit/graphql": "1.0.108",
37
+ "@teambit/pkg": "1.0.108",
38
+ "@teambit/pubsub": "1.0.108",
39
+ "@teambit/scope": "1.0.108",
40
+ "@teambit/ui": "1.0.108",
41
+ "@teambit/watcher": "1.0.108",
42
+ "@teambit/workspace": "1.0.108",
43
+ "@teambit/compiler": "1.0.108",
48
44
  "@teambit/preview.cli.preview-server-status": "0.0.504",
49
45
  "@teambit/preview.cli.webpack-events-listener": "0.0.172",
50
- "@teambit/isolator": "1.0.106"
46
+ "@teambit/isolator": "1.0.108"
51
47
  },
52
48
  "devDependencies": {
53
49
  "@types/mime": "2.0.3",
54
50
  "@types/fs-extra": "9.0.7",
55
51
  "@types/lodash": "4.14.165",
56
- "@types/react": "^17.0.8",
57
52
  "@types/object-hash": "1.3.4",
58
53
  "@types/memoizee": "0.4.5",
54
+ "cross-fetch": "3.1.5",
55
+ "memoizee": "0.4.15",
59
56
  "@types/lodash.compact": "3.0.6",
60
57
  "@types/mocha": "9.1.0",
61
- "@types/node": "12.20.4",
62
- "@types/react-dom": "^17.0.5",
63
- "@types/jest": "^26.0.0",
64
- "@types/testing-library__jest-dom": "5.9.5",
58
+ "@types/jest": "^29.2.2",
59
+ "@types/testing-library__jest-dom": "^5.9.5",
60
+ "@teambit/harmony.envs.core-aspect-env": "0.0.13",
65
61
  "@teambit/preview.aspect-docs.preview": "0.0.165"
66
62
  },
67
63
  "peerDependencies": {
68
- "@teambit/legacy": "1.0.624",
69
- "react": "^16.8.0 || ^17.0.0",
70
- "react-dom": "^16.8.0 || ^17.0.0"
64
+ "react": "^17.0.0 || ^18.0.0",
65
+ "@types/react": "^18.2.12",
66
+ "@teambit/legacy": "1.0.624"
71
67
  },
72
68
  "license": "Apache-2.0",
73
69
  "optionalDependencies": {},
@@ -81,7 +77,7 @@
81
77
  },
82
78
  "private": false,
83
79
  "engines": {
84
- "node": ">=12.22.0"
80
+ "node": ">=16.0.0"
85
81
  },
86
82
  "repository": {
87
83
  "type": "git",
@@ -90,12 +86,9 @@
90
86
  "keywords": [
91
87
  "bit",
92
88
  "bit-aspect",
89
+ "bit-core-aspect",
93
90
  "components",
94
91
  "collaboration",
95
- "web",
96
- "react",
97
- "react-components",
98
- "angular",
99
- "angular-components"
92
+ "web"
100
93
  ]
101
94
  }
@@ -0,0 +1,24 @@
1
+ import { AbstractVinyl } from '@teambit/legacy/dist/consumer/component/sources';
2
+ import { pathNormalizeToLinux } from '@teambit/legacy/dist/utils';
3
+ import { uniq } from 'lodash';
4
+
5
+ export class PreviewArtifact {
6
+ constructor(private artifacts: AbstractVinyl[]) {}
7
+
8
+ getPaths() {
9
+ // TODO: check why the artifacts stored twice, then remove this uniq here
10
+ return uniq(this.artifacts.map((artifact) => artifact.relative));
11
+ }
12
+
13
+ getFile(path: string) {
14
+ return this.artifacts.find((file) => {
15
+ return pathNormalizeToLinux(file.relative) === path;
16
+ });
17
+ }
18
+
19
+ getFileEndsWith(path: string) {
20
+ return this.artifacts.find((file) => {
21
+ return pathNormalizeToLinux(file.relative).endsWith(path);
22
+ });
23
+ }
24
+ }
@@ -0,0 +1,36 @@
1
+ import type { Request, Response, Route } from '@teambit/express';
2
+ import type { Component } from '@teambit/component';
3
+ import { serverError } from '@teambit/ui-foundation.ui.pages.static-error';
4
+ import type { Logger } from '@teambit/logger';
5
+
6
+ import { PreviewMain } from './preview.main.runtime';
7
+
8
+ export class PreviewAssetsRoute implements Route {
9
+ constructor(
10
+ /**
11
+ * preview extension.
12
+ */
13
+ private preview: PreviewMain,
14
+ private logger: Logger
15
+ ) {}
16
+
17
+ route = '/preview-assets';
18
+ method = 'get';
19
+
20
+ middlewares = [
21
+ async (req: Request, res: Response) => {
22
+ try {
23
+ // @ts-ignore TODO: @guy please fix.
24
+ const component = req.component as Component | undefined;
25
+ // if (!component) return res.status(404).send(noPreview());
26
+ if (!component) return res.status(404).jsonp({ error: 'not found' });
27
+ const result = await this.preview.getPreviewFiles(component);
28
+ if (!result) return res.status(404).jsonp({ error: 'not found' });
29
+ return res.json(result);
30
+ } catch (e: any) {
31
+ this.logger.error('failed getting preview assets', e);
32
+ return res.status(500).send(serverError());
33
+ }
34
+ },
35
+ ];
36
+ }
@@ -0,0 +1,5 @@
1
+ import { BuildContext } from '@teambit/builder';
2
+
3
+ export interface PreviewContext extends BuildContext {
4
+ entries: string[];
5
+ }