@teambit/isolator 0.0.566 → 0.0.570
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/capsule/capsule.ts +138 -0
- package/capsule/container-exec.ts +31 -0
- package/capsule/container.ts +128 -0
- package/capsule/index.ts +3 -0
- package/package-tar/teambit-isolator-0.0.570.tgz +0 -0
- package/package.json +12 -27
- package/types/asset.d.ts +29 -0
- package/types/style.d.ts +42 -0
@@ -0,0 +1,138 @@
|
|
1
|
+
import { NodeFS } from '@teambit/any-fs';
|
2
|
+
import { Capsule as CapsuleTemplate, Console, Exec, State } from '@teambit/capsule';
|
3
|
+
import { Component } from '@teambit/component';
|
4
|
+
import filenamify from 'filenamify';
|
5
|
+
import { realpathSync } from 'fs';
|
6
|
+
import glob from 'glob';
|
7
|
+
import path from 'path';
|
8
|
+
import v4 from 'uuid';
|
9
|
+
|
10
|
+
import FsContainer, { BitExecOption } from './container';
|
11
|
+
import ContainerExec from './container-exec';
|
12
|
+
|
13
|
+
export default class Capsule extends CapsuleTemplate<Exec, NodeFS> {
|
14
|
+
private _wrkDir: string;
|
15
|
+
constructor(
|
16
|
+
/**
|
17
|
+
* container implementation the capsule is being executed within.
|
18
|
+
*/
|
19
|
+
protected container: FsContainer,
|
20
|
+
/**
|
21
|
+
* the capsule's file system.
|
22
|
+
*/
|
23
|
+
readonly fs: NodeFS,
|
24
|
+
/**
|
25
|
+
* console for controlling process streams as stdout, stdin and stderr.
|
26
|
+
*/
|
27
|
+
readonly console: Console = new Console(),
|
28
|
+
/**
|
29
|
+
* capsule's state.
|
30
|
+
*/
|
31
|
+
readonly state: State,
|
32
|
+
readonly component: Component
|
33
|
+
) {
|
34
|
+
super(container, fs, console, state);
|
35
|
+
this._wrkDir = container.wrkDir;
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* @deprecated please use `this.path`
|
40
|
+
*/
|
41
|
+
get wrkDir(): string {
|
42
|
+
return this.path;
|
43
|
+
}
|
44
|
+
|
45
|
+
get path(): string {
|
46
|
+
return realpathSync(this._wrkDir);
|
47
|
+
}
|
48
|
+
|
49
|
+
start(): Promise<any> {
|
50
|
+
return this.container.start();
|
51
|
+
}
|
52
|
+
|
53
|
+
async execNode(executable: string, args: any, exec: ContainerExec) {
|
54
|
+
return this.typedExec(
|
55
|
+
{
|
56
|
+
command: ['node', executable, ...(args.args || [])],
|
57
|
+
cwd: '',
|
58
|
+
},
|
59
|
+
exec
|
60
|
+
);
|
61
|
+
}
|
62
|
+
|
63
|
+
async typedExec(opts: BitExecOption, exec = new ContainerExec()) {
|
64
|
+
return this.container.exec(opts, exec);
|
65
|
+
}
|
66
|
+
|
67
|
+
outputFile(file: string, data: any, options?: any): Promise<any> {
|
68
|
+
return this.container.outputFile(file, data, options);
|
69
|
+
}
|
70
|
+
|
71
|
+
removePath(dir: string): Promise<any> {
|
72
|
+
return this.container.removePath(dir);
|
73
|
+
}
|
74
|
+
|
75
|
+
symlink(src: string, dest: string): Promise<any> {
|
76
|
+
return this.container.symlink(src, dest);
|
77
|
+
}
|
78
|
+
|
79
|
+
// TODO: refactor this crap and simplify capsule API
|
80
|
+
async execute(cmd: string, options?: Record<string, any> | null | undefined) {
|
81
|
+
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
|
82
|
+
const execResults = await this.exec({ command: cmd.split(' '), options });
|
83
|
+
let stdout = '';
|
84
|
+
let stderr = '';
|
85
|
+
return new Promise((resolve, reject) => {
|
86
|
+
execResults.stdout.on('data', (data: string) => {
|
87
|
+
stdout += data;
|
88
|
+
});
|
89
|
+
execResults.stdout.on('error', (error: string) => {
|
90
|
+
return reject(error);
|
91
|
+
});
|
92
|
+
// @ts-ignore
|
93
|
+
execResults.on('close', () => {
|
94
|
+
return resolve({ stdout, stderr });
|
95
|
+
});
|
96
|
+
execResults.stderr.on('error', (error: string) => {
|
97
|
+
return reject(error);
|
98
|
+
});
|
99
|
+
execResults.stderr.on('data', (data: string) => {
|
100
|
+
stderr += data;
|
101
|
+
});
|
102
|
+
});
|
103
|
+
}
|
104
|
+
|
105
|
+
/**
|
106
|
+
* @todo: fix.
|
107
|
+
* it skips the capsule fs because for some reason `capsule.fs.promises.readdir` doesn't work
|
108
|
+
* the same as `capsule.fs.readdir` and it doesn't have the capsule dir as pwd.
|
109
|
+
*
|
110
|
+
* returns the paths inside the capsule
|
111
|
+
*/
|
112
|
+
getAllFilesPaths(dir = '.', options: { ignore?: string[] } = {}) {
|
113
|
+
const files = glob.sync('**', { cwd: path.join(this.path, dir), nodir: true, ...options });
|
114
|
+
return files.map((file) => path.join(dir, file));
|
115
|
+
}
|
116
|
+
|
117
|
+
static getCapsuleDirName(component: Component, config: { alwaysNew?: boolean; name?: string } = {}) {
|
118
|
+
return config.name || filenamify(component.id.toString(), { replacement: '_' });
|
119
|
+
}
|
120
|
+
|
121
|
+
static getCapsuleRootDir(component: Component, baseDir: string, config: { alwaysNew?: boolean; name?: string } = {}) {
|
122
|
+
return path.join(baseDir, Capsule.getCapsuleDirName(component, config));
|
123
|
+
}
|
124
|
+
|
125
|
+
static async createFromComponent(
|
126
|
+
component: Component,
|
127
|
+
baseDir: string,
|
128
|
+
config: { alwaysNew?: boolean; name?: string } = {}
|
129
|
+
): Promise<Capsule> {
|
130
|
+
// TODO: make this a static method and combine with ComponentCapsule
|
131
|
+
const capsuleDirName = Capsule.getCapsuleDirName(component, config);
|
132
|
+
const wrkDir = path.join(baseDir, config.alwaysNew ? `${capsuleDirName}_${v4()}` : capsuleDirName);
|
133
|
+
const container = new FsContainer(wrkDir);
|
134
|
+
const capsule = new Capsule(container, container.fs, new Console(), new State(), component);
|
135
|
+
await capsule.start();
|
136
|
+
return capsule;
|
137
|
+
}
|
138
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import { DuplexBufferStream, Exec, ExecStatus } from '@teambit/capsule';
|
2
|
+
import { EventEmitter } from 'events';
|
3
|
+
|
4
|
+
export default class ContainerExec extends EventEmitter implements Exec {
|
5
|
+
constructor(private _code: number = 0) {
|
6
|
+
super();
|
7
|
+
}
|
8
|
+
|
9
|
+
stdout: DuplexBufferStream = new DuplexBufferStream();
|
10
|
+
stderr: DuplexBufferStream = new DuplexBufferStream();
|
11
|
+
stdin: DuplexBufferStream = new DuplexBufferStream();
|
12
|
+
|
13
|
+
setStatus(status: number): void {
|
14
|
+
this._code = status;
|
15
|
+
this.emit('close');
|
16
|
+
}
|
17
|
+
|
18
|
+
get code(): number {
|
19
|
+
return this._code;
|
20
|
+
}
|
21
|
+
|
22
|
+
inspect(): Promise<ExecStatus> {
|
23
|
+
return Promise.resolve({
|
24
|
+
running: true,
|
25
|
+
pid: 1,
|
26
|
+
});
|
27
|
+
}
|
28
|
+
abort(): Promise<void> {
|
29
|
+
throw new Error('Method not implemented.');
|
30
|
+
}
|
31
|
+
}
|
@@ -0,0 +1,128 @@
|
|
1
|
+
import { AnyFS, NodeFS } from '@teambit/any-fs';
|
2
|
+
import { Container, ContainerFactoryOptions, ContainerStatus, Exec, ExecOptions } from '@teambit/capsule';
|
3
|
+
import execa from 'execa';
|
4
|
+
import fs from 'fs-extra';
|
5
|
+
import * as path from 'path';
|
6
|
+
import { Stream } from 'stream';
|
7
|
+
|
8
|
+
import ContainerExec from './container-exec';
|
9
|
+
|
10
|
+
const debug = require('debug')('fs-container');
|
11
|
+
|
12
|
+
export interface BitExecOption extends ExecOptions {
|
13
|
+
cwd: string;
|
14
|
+
stdio?: 'pipe' | 'ipc' | 'ignore' | 'inherit' | Stream | number | undefined;
|
15
|
+
}
|
16
|
+
export interface BitContainerConfig extends ContainerFactoryOptions {
|
17
|
+
other?: string;
|
18
|
+
}
|
19
|
+
|
20
|
+
export default class FsContainer implements Container<Exec, AnyFS> {
|
21
|
+
id = 'FS Container';
|
22
|
+
|
23
|
+
fs: NodeFS = new NodeFS(this.wrkDir);
|
24
|
+
|
25
|
+
constructor(readonly wrkDir: string) {}
|
26
|
+
|
27
|
+
// TODO: do we need this?
|
28
|
+
public getPath() {
|
29
|
+
return this.wrkDir;
|
30
|
+
}
|
31
|
+
|
32
|
+
private composePath(pathToCompose) {
|
33
|
+
return path.join(this.getPath(), pathToCompose);
|
34
|
+
}
|
35
|
+
|
36
|
+
outputFile(file, data, options) {
|
37
|
+
const filePath = this.composePath(file);
|
38
|
+
debug(`writing file on ${filePath}`);
|
39
|
+
return fs.outputFile(filePath, data, options);
|
40
|
+
}
|
41
|
+
|
42
|
+
removePath(dir: string): Promise<any> {
|
43
|
+
const pathToRemove = this.composePath(dir);
|
44
|
+
return fs.remove(pathToRemove);
|
45
|
+
}
|
46
|
+
|
47
|
+
async symlink(src: string, dest: string): Promise<any> {
|
48
|
+
const srcPath = this.composePath(src);
|
49
|
+
const destPath = this.composePath(dest);
|
50
|
+
await fs.ensureDir(path.dirname(destPath));
|
51
|
+
return fs.ensureSymlink(srcPath, destPath);
|
52
|
+
}
|
53
|
+
|
54
|
+
async exec(execOptions: BitExecOption, exec = new ContainerExec()): Promise<ContainerExec> {
|
55
|
+
const cwd = execOptions.cwd ? this.composePath(execOptions.cwd) : this.getPath();
|
56
|
+
debug(`executing the following command: ${execOptions.command.join(' ')}, on cwd: ${cwd}`);
|
57
|
+
const subprocessP = execa.command(execOptions.command.join(' '), {
|
58
|
+
shell: true,
|
59
|
+
cwd,
|
60
|
+
stdio: ['ipc'],
|
61
|
+
});
|
62
|
+
|
63
|
+
// @TODO: FIX! This probably causes errors ad the promise is not handled properly!
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
65
|
+
subprocessP.on('message', function (msg: any) {
|
66
|
+
exec.emit('message', msg);
|
67
|
+
});
|
68
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
69
|
+
subprocessP.stderr?.pipe(exec.stderr);
|
70
|
+
subprocessP.stdout?.pipe(exec.stdout);
|
71
|
+
['close', 'exit'].forEach(function (eventName: string) {
|
72
|
+
// @TODO: FIX! This probably causes errors ad the promise is not handled properly!
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
74
|
+
subprocessP.on(eventName, function (statusCode) {
|
75
|
+
exec.setStatus(statusCode);
|
76
|
+
});
|
77
|
+
});
|
78
|
+
|
79
|
+
return exec;
|
80
|
+
}
|
81
|
+
|
82
|
+
async execP(execOptions: BitExecOption): Promise<string> {
|
83
|
+
let hasError = false;
|
84
|
+
const exec = await this.exec(execOptions);
|
85
|
+
return new Promise((resolve, reject) => {
|
86
|
+
exec.stdout.on('error', () => {
|
87
|
+
hasError = true;
|
88
|
+
});
|
89
|
+
exec.on('close', () => {
|
90
|
+
if (hasError) reject(exec.stderr.getContents!(exec.stderr.size).toString());
|
91
|
+
resolve(exec.stdout.getContents!(exec.stdout.size).toString());
|
92
|
+
});
|
93
|
+
});
|
94
|
+
}
|
95
|
+
|
96
|
+
async terminal() {
|
97
|
+
const cwd = this.getPath();
|
98
|
+
return execa.command(process.env.SHELL || '/bin/zsh', { cwd, stdio: 'inherit' });
|
99
|
+
}
|
100
|
+
|
101
|
+
start(): Promise<void> {
|
102
|
+
return fs.ensureDir(this.wrkDir);
|
103
|
+
}
|
104
|
+
// @ts-ignore
|
105
|
+
async inspect(): Promise<ContainerStatus> {
|
106
|
+
// todo: probably not needed for this container
|
107
|
+
}
|
108
|
+
async pause(): Promise<void> {
|
109
|
+
// do nothing
|
110
|
+
}
|
111
|
+
async resume(): Promise<void> {
|
112
|
+
// do nothing
|
113
|
+
}
|
114
|
+
// eslint-disable-next-line
|
115
|
+
stop(ttl?: number | undefined): Promise<void> {
|
116
|
+
return fs.remove(this.wrkDir);
|
117
|
+
}
|
118
|
+
async destroy(): Promise<void> {
|
119
|
+
await this.stop();
|
120
|
+
}
|
121
|
+
log(): Promise<Exec> {
|
122
|
+
throw new Error('Method not implemented.');
|
123
|
+
}
|
124
|
+
on(event: string, fn: (data: any) => void): void {
|
125
|
+
return fn(event);
|
126
|
+
// throw new Error('Method not implemented.');
|
127
|
+
}
|
128
|
+
}
|
package/capsule/index.ts
ADDED
Binary file
|
package/package.json
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "@teambit/isolator",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.570",
|
4
4
|
"homepage": "https://bit.dev/teambit/component/isolator",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"componentId": {
|
7
7
|
"scope": "teambit.component",
|
8
8
|
"name": "isolator",
|
9
|
-
"version": "0.0.
|
9
|
+
"version": "0.0.570"
|
10
10
|
},
|
11
11
|
"dependencies": {
|
12
12
|
"@teambit/harmony": "0.2.11",
|
@@ -23,14 +23,14 @@
|
|
23
23
|
"execa": "2.1.0",
|
24
24
|
"@babel/runtime": "7.12.18",
|
25
25
|
"core-js": "^3.0.0",
|
26
|
-
"@teambit/component": "0.0.
|
27
|
-
"@teambit/legacy-bit-id": "0.0.
|
28
|
-
"@teambit/cli": "0.0.
|
29
|
-
"@teambit/component-package-version": "0.0.
|
30
|
-
"@teambit/dependency-resolver": "0.0.
|
31
|
-
"@teambit/global-config": "0.0.
|
32
|
-
"@teambit/graph": "0.0.
|
33
|
-
"@teambit/logger": "0.0.
|
26
|
+
"@teambit/component": "0.0.570",
|
27
|
+
"@teambit/legacy-bit-id": "0.0.384",
|
28
|
+
"@teambit/cli": "0.0.395",
|
29
|
+
"@teambit/component-package-version": "0.0.381",
|
30
|
+
"@teambit/dependency-resolver": "0.0.570",
|
31
|
+
"@teambit/global-config": "0.0.396",
|
32
|
+
"@teambit/graph": "0.0.570",
|
33
|
+
"@teambit/logger": "0.0.482"
|
34
34
|
},
|
35
35
|
"devDependencies": {
|
36
36
|
"@types/fs-extra": "9.0.7",
|
@@ -45,7 +45,7 @@
|
|
45
45
|
"@types/node": "12.20.4"
|
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"
|
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
|
+
}
|