@teambit/envs 0.0.568 → 0.0.572
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/components/env-console/env-console.tsx +30 -0
- package/components/env-console/index.ts +1 -0
- package/components/env-overview/env-overview.tsx +21 -0
- package/components/env-overview/index.ts +1 -0
- package/components/index.ts +1 -0
- package/context/context.ts +54 -0
- package/context/index.ts +1 -0
- package/envs.cmd.tsx +87 -0
- package/exceptions/env-not-configured-for-component.ts +10 -0
- package/exceptions/env-not-found-in-runtime.ts +7 -0
- package/exceptions/env-not-found.ts +12 -0
- package/exceptions/index.ts +3 -0
- package/package-tar/teambit-envs-0.0.572.tgz +0 -0
- package/package.json +22 -37
- package/runtime/env-runtime.ts +25 -0
- package/runtime/envs-execution-result.ts +46 -0
- package/runtime/index.ts +2 -0
- package/runtime/runtime.ts +97 -0
- package/services/concrete-service.ts +8 -0
- package/services/index.ts +3 -0
- package/services/service-handler.ts +6 -0
- package/services/service.ts +52 -0
- package/types/asset.d.ts +29 -0
- package/types/style.d.ts +42 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3
|
+
import { Box, Text } from 'ink';
|
|
4
|
+
import React, { useEffect, useState } from 'react';
|
|
5
|
+
|
|
6
|
+
import { EnvRuntime } from '../../runtime';
|
|
7
|
+
|
|
8
|
+
export type EnvConsoleProps = {
|
|
9
|
+
runtime: EnvRuntime;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function EnvConsole() {
|
|
13
|
+
const [counter, setCounter] = useState(0);
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
const timer = setInterval(() => {
|
|
17
|
+
setCounter((previousCounter) => previousCounter + 1);
|
|
18
|
+
}, 100);
|
|
19
|
+
|
|
20
|
+
return () => {
|
|
21
|
+
clearInterval(timer);
|
|
22
|
+
};
|
|
23
|
+
}, []);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<Box>
|
|
27
|
+
<Text color="green">{counter} tests passed</Text>
|
|
28
|
+
</Box>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { EnvConsole } from './env-console';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Text, Newline } from 'ink';
|
|
3
|
+
import { EnvDefinition } from '../../env-definition';
|
|
4
|
+
|
|
5
|
+
export type EnvOverviewProps = {
|
|
6
|
+
envDef: EnvDefinition;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* renders an env overview in the terminal.
|
|
11
|
+
*/
|
|
12
|
+
export function EnvOverview({ envDef }: EnvOverviewProps) {
|
|
13
|
+
return (
|
|
14
|
+
<Text>
|
|
15
|
+
<Text bold underline>
|
|
16
|
+
Environment: {envDef.id}
|
|
17
|
+
</Text>
|
|
18
|
+
<Newline />
|
|
19
|
+
</Text>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { EnvOverview } from './env-overview';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { EnvConsole } from './env-console';
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { EnvDefinition } from '../env-definition';
|
|
2
|
+
|
|
3
|
+
import { EnvRuntime, Runtime } from '../runtime';
|
|
4
|
+
|
|
5
|
+
export type ServiceMap<T> = {
|
|
6
|
+
[env: string]: T;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export class ExecutionContext {
|
|
10
|
+
constructor(
|
|
11
|
+
/**
|
|
12
|
+
* upper scope of all environment contexts.
|
|
13
|
+
*/
|
|
14
|
+
readonly upper: Runtime,
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* runtime instance of the environment.
|
|
18
|
+
*/
|
|
19
|
+
readonly envRuntime: EnvRuntime,
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* components applied in the execution context.
|
|
23
|
+
*/
|
|
24
|
+
public components = envRuntime.components
|
|
25
|
+
) {}
|
|
26
|
+
|
|
27
|
+
relatedContexts: string[] = [];
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* extension ID of the environment
|
|
31
|
+
*/
|
|
32
|
+
get id() {
|
|
33
|
+
return this.envRuntime.id;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* environment instance.
|
|
38
|
+
*/
|
|
39
|
+
get env(): any {
|
|
40
|
+
return this.envRuntime.env;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get envDefinition(): EnvDefinition {
|
|
44
|
+
return new EnvDefinition(this.id, this.env);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
apply<T>(name: string, args: any[]): T {
|
|
48
|
+
if (!this.env[name]) {
|
|
49
|
+
throw new Error(`method ${name} not implemented`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return this.env[name].apply(this.env, ...args);
|
|
53
|
+
}
|
|
54
|
+
}
|
package/context/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ExecutionContext } from './context';
|
package/envs.cmd.tsx
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Text, Newline } from 'ink';
|
|
3
|
+
import { CLITable } from '@teambit/cli-table';
|
|
4
|
+
import { Command } from '@teambit/cli';
|
|
5
|
+
import { ComponentMain, ComponentFactory, Component } from '@teambit/component';
|
|
6
|
+
import { EnvsMain } from './environments.main.runtime';
|
|
7
|
+
import { EnvOverview } from './components/env-overview';
|
|
8
|
+
|
|
9
|
+
export class EnvsCmd implements Command {
|
|
10
|
+
name = 'envs [name]';
|
|
11
|
+
alias = 'env';
|
|
12
|
+
shortDescription = 'show all component envs';
|
|
13
|
+
description = 'show all components envs';
|
|
14
|
+
options = [];
|
|
15
|
+
group = 'development';
|
|
16
|
+
|
|
17
|
+
constructor(private envs: EnvsMain, private componentAspect: ComponentMain) {}
|
|
18
|
+
|
|
19
|
+
async showEnv(id: string, host: ComponentFactory) {
|
|
20
|
+
const component = await host.get(await host.resolveComponentId(id));
|
|
21
|
+
if (!component) throw new Error(`component for env ${id} was not found`);
|
|
22
|
+
const env = this.envs.getEnv(component);
|
|
23
|
+
const envRuntime = await this.envs.createEnvironment([component]);
|
|
24
|
+
const envExecutionContext = envRuntime.getEnvExecutionContext();
|
|
25
|
+
const services = this.envs.getServices(env);
|
|
26
|
+
const allP = services.services.map(async ([serviceId, service]) => {
|
|
27
|
+
if (service.render)
|
|
28
|
+
return (
|
|
29
|
+
<Text>
|
|
30
|
+
<Text bold underline color="cyan">
|
|
31
|
+
{serviceId}
|
|
32
|
+
</Text>
|
|
33
|
+
<Newline />
|
|
34
|
+
<Newline />
|
|
35
|
+
{await service.render(env, envExecutionContext)}
|
|
36
|
+
</Text>
|
|
37
|
+
);
|
|
38
|
+
return (
|
|
39
|
+
<Text key={serviceId}>
|
|
40
|
+
<Text bold underline>
|
|
41
|
+
{serviceId}
|
|
42
|
+
</Text>
|
|
43
|
+
</Text>
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const all = await Promise.all(allP);
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<Text>
|
|
51
|
+
<EnvOverview envDef={env} />
|
|
52
|
+
{all.map((item) => item)}
|
|
53
|
+
</Text>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async render([name]: [string]): Promise<JSX.Element> {
|
|
58
|
+
const host = await this.componentAspect.getHost();
|
|
59
|
+
// TODO: think what to do re this line with gilad.
|
|
60
|
+
if (!host) throw new Error('error: workspace not found');
|
|
61
|
+
if (name) return this.showEnv(name, host);
|
|
62
|
+
const components = await host.list();
|
|
63
|
+
// TODO: refactor to a react table
|
|
64
|
+
return <Text>{this.getTable(components)}</Text>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private getTable(components: Component[]) {
|
|
68
|
+
const tableData = components.map((component) => {
|
|
69
|
+
const env = this.envs.getDescriptor(component);
|
|
70
|
+
return {
|
|
71
|
+
component: component.id.toString(),
|
|
72
|
+
env: env ? env.id : 'N/A',
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const header = [
|
|
77
|
+
{
|
|
78
|
+
value: 'component',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
value: 'env',
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
const table = CLITable.fromObject(header, tableData);
|
|
85
|
+
return table.render();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BitError } from '@teambit/bit-error';
|
|
2
|
+
|
|
3
|
+
export class EnvNotConfiguredForComponent extends BitError {
|
|
4
|
+
constructor(id: string, componentId?: string) {
|
|
5
|
+
const suffix = componentId ? ` for the component ${componentId}` : '';
|
|
6
|
+
super(`environment with ID: "${id}" is not configured as extension${suffix}.
|
|
7
|
+
you probably need to add this environment as a key to your variant in the workspace.jsonc. for example, "your-variant": { "${id}": {} }
|
|
8
|
+
`);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BitError } from '@teambit/bit-error';
|
|
2
|
+
|
|
3
|
+
export class EnvNotFound extends BitError {
|
|
4
|
+
constructor(private id: string, private componentId?: string) {
|
|
5
|
+
super(getMessage(id, componentId));
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function getMessage(id: string, componentId?: string): string {
|
|
10
|
+
const compIdDetails = componentId ? `configured on component ${componentId}` : '';
|
|
11
|
+
return `environment with ID: ${id} ${compIdDetails} was not found`;
|
|
12
|
+
}
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teambit/envs",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.572",
|
|
4
4
|
"homepage": "https://bit.dev/teambit/envs/envs",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"componentId": {
|
|
7
7
|
"scope": "teambit.envs",
|
|
8
8
|
"name": "envs",
|
|
9
|
-
"version": "0.0.
|
|
9
|
+
"version": "0.0.572"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@teambit/harmony": "0.2.11",
|
|
@@ -16,23 +16,23 @@
|
|
|
16
16
|
"p-map-series": "2.1.0",
|
|
17
17
|
"@babel/runtime": "7.12.18",
|
|
18
18
|
"core-js": "^3.0.0",
|
|
19
|
-
"@teambit/component": "0.0.
|
|
20
|
-
"@teambit/builder": "0.0.
|
|
21
|
-
"@teambit/bundler": "0.0.
|
|
22
|
-
"@teambit/compiler": "0.0.
|
|
23
|
-
"@teambit/dependency-resolver": "0.0.
|
|
24
|
-
"@teambit/elements": "0.0.
|
|
25
|
-
"@teambit/formatter": "0.0.
|
|
26
|
-
"@teambit/linter": "0.0.
|
|
27
|
-
"@teambit/pkg": "0.0.
|
|
28
|
-
"@teambit/schema": "0.0.
|
|
29
|
-
"@teambit/tester": "0.0.
|
|
30
|
-
"@teambit/webpack": "0.0.
|
|
31
|
-
"@teambit/graphql": "0.0.
|
|
32
|
-
"@teambit/cli": "0.0.
|
|
33
|
-
"@teambit/logger": "0.0.
|
|
34
|
-
"@teambit/cli-table": "0.0.
|
|
35
|
-
"@teambit/bit-error": "0.0.
|
|
19
|
+
"@teambit/component": "0.0.572",
|
|
20
|
+
"@teambit/builder": "0.0.572",
|
|
21
|
+
"@teambit/bundler": "0.0.572",
|
|
22
|
+
"@teambit/compiler": "0.0.572",
|
|
23
|
+
"@teambit/dependency-resolver": "0.0.572",
|
|
24
|
+
"@teambit/elements": "0.0.25",
|
|
25
|
+
"@teambit/formatter": "0.0.123",
|
|
26
|
+
"@teambit/linter": "0.0.572",
|
|
27
|
+
"@teambit/pkg": "0.0.572",
|
|
28
|
+
"@teambit/schema": "0.0.572",
|
|
29
|
+
"@teambit/tester": "0.0.572",
|
|
30
|
+
"@teambit/webpack": "0.0.572",
|
|
31
|
+
"@teambit/graphql": "0.0.572",
|
|
32
|
+
"@teambit/cli": "0.0.395",
|
|
33
|
+
"@teambit/logger": "0.0.483",
|
|
34
|
+
"@teambit/cli-table": "0.0.18",
|
|
35
|
+
"@teambit/bit-error": "0.0.381"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/react": "^17.0.8",
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
"@types/jest": "^26.0.0",
|
|
43
43
|
"@types/react-dom": "^17.0.5",
|
|
44
44
|
"@types/node": "12.20.4",
|
|
45
|
-
"@teambit/envs.aspect-docs.envs": "0.0.
|
|
45
|
+
"@teambit/envs.aspect-docs.envs": "0.0.117"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"@teambit/legacy": "1.0.
|
|
48
|
+
"@teambit/legacy": "1.0.181",
|
|
49
49
|
"react-dom": "^16.8.0 || ^17.0.0",
|
|
50
50
|
"react": "^16.8.0 || ^17.0.0"
|
|
51
51
|
},
|
|
@@ -73,27 +73,12 @@
|
|
|
73
73
|
"react": "-"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
76
|
-
"@teambit/legacy": "1.0.
|
|
76
|
+
"@teambit/legacy": "1.0.181",
|
|
77
77
|
"react-dom": "^16.8.0 || ^17.0.0",
|
|
78
78
|
"react": "^16.8.0 || ^17.0.0"
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
},
|
|
82
|
-
"files": [
|
|
83
|
-
"dist",
|
|
84
|
-
"!dist/tsconfig.tsbuildinfo",
|
|
85
|
-
"**/*.md",
|
|
86
|
-
"**/*.mdx",
|
|
87
|
-
"**/*.js",
|
|
88
|
-
"**/*.json",
|
|
89
|
-
"**/*.sass",
|
|
90
|
-
"**/*.scss",
|
|
91
|
-
"**/*.less",
|
|
92
|
-
"**/*.css",
|
|
93
|
-
"**/*.css",
|
|
94
|
-
"**/*.jpeg",
|
|
95
|
-
"**/*.gif"
|
|
96
|
-
],
|
|
97
82
|
"private": false,
|
|
98
83
|
"engines": {
|
|
99
84
|
"node": ">=12.22.0"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Component } from '@teambit/component';
|
|
2
|
+
|
|
3
|
+
import { Environment } from '../environment';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* env runtime is an instance which represent the given env in a
|
|
7
|
+
*/
|
|
8
|
+
export class EnvRuntime {
|
|
9
|
+
constructor(
|
|
10
|
+
/**
|
|
11
|
+
* ID of the wrapping extension.
|
|
12
|
+
*/
|
|
13
|
+
readonly id: string,
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* environment
|
|
17
|
+
*/
|
|
18
|
+
readonly env: Environment,
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* components to be loaded in the environment
|
|
22
|
+
*/
|
|
23
|
+
readonly components: Component[]
|
|
24
|
+
) {}
|
|
25
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { flatten } from 'lodash';
|
|
2
|
+
|
|
3
|
+
import { ServiceExecutionResult } from '../services';
|
|
4
|
+
import { EnvResult } from './runtime';
|
|
5
|
+
|
|
6
|
+
export class EnvsExecutionResult<T extends ServiceExecutionResult> {
|
|
7
|
+
constructor(readonly results: EnvResult<T>[]) {}
|
|
8
|
+
|
|
9
|
+
hasErrors() {
|
|
10
|
+
return Boolean(this.errors.length);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* execution errors.
|
|
15
|
+
*/
|
|
16
|
+
get errors(): Error[] {
|
|
17
|
+
return flatten(this.results.map((envResult) => this.getErrorsOfEnv(envResult)));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getErrorsOfEnv(envResult: EnvResult<T>): Error[] {
|
|
21
|
+
const execError = envResult.error;
|
|
22
|
+
const errors = envResult.data ? envResult.data.errors || [] : [];
|
|
23
|
+
if (execError) errors.push(execError);
|
|
24
|
+
return errors;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* if only one error is found, throw it. otherwise, summarize the errors per env and throw the
|
|
29
|
+
* output
|
|
30
|
+
*/
|
|
31
|
+
throwErrorsIfExist() {
|
|
32
|
+
if (!this.errors || !this.errors.length) return;
|
|
33
|
+
if (this.errors.length === 1 && this.errors[0] instanceof Error) throw this.errors[0];
|
|
34
|
+
const errorsPerEnvs = this.results.map((envResult) => this.getEnvErrorsAsString(envResult));
|
|
35
|
+
const errorOutput = errorsPerEnvs.join('\n\n');
|
|
36
|
+
throw new Error(errorOutput);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
getEnvErrorsAsString(envResult: EnvResult<T>): string {
|
|
40
|
+
const errors = this.getErrorsOfEnv(envResult);
|
|
41
|
+
if (!errors.length) return '';
|
|
42
|
+
const title = `found ${errors.length} error(s) for ${envResult.env.id}`;
|
|
43
|
+
const errorsStr = errors.map((error) => `${error.message}\n${error.stack}`).join('\n');
|
|
44
|
+
return `${title}\n${errorsStr}`;
|
|
45
|
+
}
|
|
46
|
+
}
|
package/runtime/index.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Logger } from '@teambit/logger';
|
|
2
|
+
import { ComponentID } from '@teambit/component';
|
|
3
|
+
import mapSeries from 'p-map-series';
|
|
4
|
+
import { EnvNotFoundInRuntime } from '../exceptions';
|
|
5
|
+
import { ExecutionContext } from '../context';
|
|
6
|
+
import { EnvService, ServiceExecutionResult } from '../services';
|
|
7
|
+
import { EnvRuntime } from './env-runtime';
|
|
8
|
+
import { EnvsExecutionResult } from './envs-execution-result';
|
|
9
|
+
|
|
10
|
+
export interface EnvResult<T extends ServiceExecutionResult> {
|
|
11
|
+
env: EnvRuntime;
|
|
12
|
+
data?: T;
|
|
13
|
+
error?: Error;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class Runtime {
|
|
17
|
+
constructor(
|
|
18
|
+
/**
|
|
19
|
+
* runtime instances of the environments.
|
|
20
|
+
*/
|
|
21
|
+
readonly runtimeEnvs: EnvRuntime[],
|
|
22
|
+
|
|
23
|
+
private logger: Logger
|
|
24
|
+
) {}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* execute a service on a specific env.
|
|
28
|
+
*/
|
|
29
|
+
runEnv<T>(
|
|
30
|
+
envRuntimeId: string,
|
|
31
|
+
service: EnvService<T>,
|
|
32
|
+
options?: { [key: string]: any }
|
|
33
|
+
): Promise<EnvsExecutionResult<T>> {
|
|
34
|
+
const envRuntime = this.runtimeEnvs.find((runtime) => {
|
|
35
|
+
const id = ComponentID.fromString(runtime.id);
|
|
36
|
+
const withoutVersion = id._legacy.toStringWithoutVersion();
|
|
37
|
+
return withoutVersion === envRuntimeId;
|
|
38
|
+
});
|
|
39
|
+
if (!envRuntime) throw new EnvNotFoundInRuntime(envRuntimeId);
|
|
40
|
+
return this.run(service, options, [envRuntime]);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* execute a service once for all environments.
|
|
45
|
+
*/
|
|
46
|
+
async runOnce<T>(service: EnvService<T>, options?: { [key: string]: any }): Promise<any> {
|
|
47
|
+
if (!service.runOnce) throw new Error('a service must implement `runOnce()` in order to be executed');
|
|
48
|
+
const envsExecutionContext = this.getEnvExecutionContext();
|
|
49
|
+
const serviceResult = await service.runOnce(envsExecutionContext, options);
|
|
50
|
+
return serviceResult;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
getEnvExecutionContext(): ExecutionContext[] {
|
|
54
|
+
const envsExecutionContext = this.runtimeEnvs.map((env) => new ExecutionContext(this, env));
|
|
55
|
+
return envsExecutionContext;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* execute a service on each one of the environments.
|
|
60
|
+
*/
|
|
61
|
+
async run<T>(
|
|
62
|
+
/**
|
|
63
|
+
* environment service to execute.
|
|
64
|
+
*/
|
|
65
|
+
service: EnvService<T>,
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* options to proxy to the service upon execution.
|
|
69
|
+
*/
|
|
70
|
+
options?: { [key: string]: any },
|
|
71
|
+
runtimes?: EnvRuntime[]
|
|
72
|
+
): Promise<EnvsExecutionResult<T>> {
|
|
73
|
+
if (!service.run) throw new Error('a service must implement `run()` in order to be executed');
|
|
74
|
+
const errors: Error[] = [];
|
|
75
|
+
const contexts: EnvResult<T>[] = await mapSeries(runtimes || this.runtimeEnvs, async (env) => {
|
|
76
|
+
try {
|
|
77
|
+
// @ts-ignore
|
|
78
|
+
const serviceResult = await service.run(new ExecutionContext(this, env), options);
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
env,
|
|
82
|
+
data: serviceResult,
|
|
83
|
+
};
|
|
84
|
+
} catch (err: any) {
|
|
85
|
+
this.logger.error(err.message, err);
|
|
86
|
+
this.logger.consoleFailure(`service ${service.name} env ${env.id} has failed. ${err.message}`);
|
|
87
|
+
errors.push(err);
|
|
88
|
+
return {
|
|
89
|
+
env,
|
|
90
|
+
error: err,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return new EnvsExecutionResult(contexts);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Component } from '@teambit/component';
|
|
2
|
+
import { Environment } from '../environment';
|
|
3
|
+
|
|
4
|
+
export type EnvContext = {
|
|
5
|
+
components: Component[];
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export interface ServiceExecutionResult {
|
|
9
|
+
errors?: Error[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* services allows to reuse and standardize services for development environments.
|
|
14
|
+
* examples for services can be: `linting`, `compilation`, `build`, and others which offer
|
|
15
|
+
* standard services to environments such as `react`, `angular` and `vue` and different compositions of each for
|
|
16
|
+
* more concrete needs.
|
|
17
|
+
*
|
|
18
|
+
* `TData` - type of data returned by the service handler.
|
|
19
|
+
* `TOpts` is the type of options passed to the environment through execution.
|
|
20
|
+
* `TExecResponse` is the execution result of the service.
|
|
21
|
+
*/
|
|
22
|
+
export interface Service<TExecResponse extends ServiceExecutionResult, TData = {}, TOpts = {}> {
|
|
23
|
+
/**
|
|
24
|
+
* name of the service. (e.g. `compile`, `test`, etc.)
|
|
25
|
+
*/
|
|
26
|
+
name?: string;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* description of the env.
|
|
30
|
+
*/
|
|
31
|
+
description?: string;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* create a string to describe to service in the env cli.
|
|
35
|
+
*/
|
|
36
|
+
render?(env: Environment, context: EnvContext[]): JSX.Element | Promise<JSX.Element>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* get service data from an environment.
|
|
40
|
+
*/
|
|
41
|
+
getDescriptor?(environment: Environment, context?: EnvContext[]): TData | undefined | Promise<TData | undefined>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* executes a service on a subset of components.
|
|
45
|
+
*/
|
|
46
|
+
run?(context: EnvContext, options?: TOpts): Promise<TExecResponse>;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
*
|
|
50
|
+
*/
|
|
51
|
+
runOnce?(context: EnvContext[], options?: TOpts): Promise<any>;
|
|
52
|
+
}
|
package/types/asset.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
declare module '*.png' {
|
|
2
|
+
const value: any;
|
|
3
|
+
export = value;
|
|
4
|
+
}
|
|
5
|
+
declare module '*.svg' {
|
|
6
|
+
import type { FunctionComponent, SVGProps } from 'react';
|
|
7
|
+
|
|
8
|
+
export const ReactComponent: FunctionComponent<SVGProps<SVGSVGElement> & { title?: string }>;
|
|
9
|
+
const src: string;
|
|
10
|
+
export default src;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// @TODO Gilad
|
|
14
|
+
declare module '*.jpg' {
|
|
15
|
+
const value: any;
|
|
16
|
+
export = value;
|
|
17
|
+
}
|
|
18
|
+
declare module '*.jpeg' {
|
|
19
|
+
const value: any;
|
|
20
|
+
export = value;
|
|
21
|
+
}
|
|
22
|
+
declare module '*.gif' {
|
|
23
|
+
const value: any;
|
|
24
|
+
export = value;
|
|
25
|
+
}
|
|
26
|
+
declare module '*.bmp' {
|
|
27
|
+
const value: any;
|
|
28
|
+
export = value;
|
|
29
|
+
}
|
package/types/style.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
declare module '*.module.css' {
|
|
2
|
+
const classes: { readonly [key: string]: string };
|
|
3
|
+
export default classes;
|
|
4
|
+
}
|
|
5
|
+
declare module '*.module.scss' {
|
|
6
|
+
const classes: { readonly [key: string]: string };
|
|
7
|
+
export default classes;
|
|
8
|
+
}
|
|
9
|
+
declare module '*.module.sass' {
|
|
10
|
+
const classes: { readonly [key: string]: string };
|
|
11
|
+
export default classes;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare module '*.module.less' {
|
|
15
|
+
const classes: { readonly [key: string]: string };
|
|
16
|
+
export default classes;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare module '*.less' {
|
|
20
|
+
const classes: { readonly [key: string]: string };
|
|
21
|
+
export default classes;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
declare module '*.css' {
|
|
25
|
+
const classes: { readonly [key: string]: string };
|
|
26
|
+
export default classes;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
declare module '*.sass' {
|
|
30
|
+
const classes: { readonly [key: string]: string };
|
|
31
|
+
export default classes;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
declare module '*.scss' {
|
|
35
|
+
const classes: { readonly [key: string]: string };
|
|
36
|
+
export default classes;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
declare module '*.mdx' {
|
|
40
|
+
const component: any;
|
|
41
|
+
export default component;
|
|
42
|
+
}
|