├── tools ├── schematics │ └── .gitkeep └── tsconfig.tools.json ├── packages ├── plugin │ ├── theia │ │ ├── src │ │ │ └── index.ts │ │ ├── package.json │ │ ├── .eslintrc.json │ │ ├── README.md │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ └── jest.config.js │ ├── ws │ │ ├── src │ │ │ └── index.ts │ │ ├── .eslintrc.json │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ ├── jest.config.js │ │ ├── README.md │ │ └── package.json │ ├── webview │ │ ├── src │ │ │ └── index.ts │ │ ├── .eslintrc.json │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ ├── jest.config.js │ │ ├── package.json │ │ └── README.md │ ├── webworker │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ │ └── connector.ts │ │ ├── .eslintrc.json │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ ├── jest.config.js │ │ ├── package.json │ │ └── README.md │ ├── child-process │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ │ └── connector.ts │ │ ├── .eslintrc.json │ │ ├── README.md │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ ├── jest.config.js │ │ └── package.json │ ├── iframe │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ │ └── theme.ts │ │ ├── .eslintrc.json │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ ├── jest.config.js │ │ ├── package.json │ │ └── README.md │ ├── vscode │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ │ └── extension.ts │ │ ├── .eslintrc.json │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ ├── jest.config.js │ │ ├── package.json │ │ └── README.md │ ├── electron │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ │ ├── electronPluginClient.ts │ │ │ │ └── electronBasePlugin.ts │ │ ├── .eslintrc.json │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── jest.config.js │ │ └── package.json │ └── core │ │ ├── .eslintrc.json │ │ ├── doc │ │ └── videos │ │ │ ├── remix_local_plugin.gif │ │ │ └── remix_load_local_plugin.mp4 │ │ ├── src │ │ ├── index.ts │ │ └── lib │ │ │ ├── node.ts │ │ │ ├── api.ts │ │ │ └── origin.ts │ │ ├── assets │ │ └── origins.json │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ ├── jest.config.js │ │ ├── package.json │ │ └── tests │ │ ├── node.spec.ts │ │ ├── origin.spec.ts │ │ ├── remix-api.spec.ts │ │ └── api.spec.ts ├── engine │ ├── node │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ │ └── child-process.ts │ │ ├── .eslintrc.json │ │ ├── README.md │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ ├── jest.config.js │ │ └── package.json │ ├── theia │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ │ ├── engine-theia.ts │ │ │ │ └── engine-theia.spec.ts │ │ ├── package.json │ │ ├── .eslintrc.json │ │ ├── README.md │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ └── jest.config.js │ ├── electron │ │ ├── src │ │ │ ├── index.ts │ │ │ └── global.d.ts │ │ ├── README.md │ │ ├── .eslintrc.json │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── jest.config.js │ │ └── package.json │ ├── web │ │ ├── .eslintrc.json │ │ ├── src │ │ │ ├── index.ts │ │ │ └── lib │ │ │ │ ├── view.ts │ │ │ │ ├── host.ts │ │ │ │ ├── window.ts │ │ │ │ ├── web-worker.ts │ │ │ │ └── theme.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── README.md │ │ └── tests │ │ │ └── view.spec.ts │ ├── core │ │ ├── .eslintrc.json │ │ ├── src │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── doc │ │ │ ├── api │ │ │ │ └── engine.md │ │ │ ├── tutorial │ │ │ │ ├── 4-external-plugins.md │ │ │ │ └── 1-getting-started.md │ │ │ └── connector │ │ │ │ ├── plugin-connector.md │ │ │ │ └── client-connector.md │ │ └── tests │ │ │ └── manager.spec.ts │ └── vscode │ │ ├── .eslintrc.json │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ ├── src │ │ ├── index.ts │ │ ├── util │ │ │ ├── editor.ts │ │ │ └── path.ts │ │ └── lib │ │ │ ├── appmanager.ts │ │ │ ├── extension.ts │ │ │ ├── contentimport.ts │ │ │ └── command.ts │ │ ├── jest.config.js │ │ └── package.json ├── api │ ├── src │ │ ├── lib │ │ │ ├── window │ │ │ │ ├── index.ts │ │ │ │ ├── profile.ts │ │ │ │ └── api.ts │ │ │ ├── dgit │ │ │ │ ├── index.ts │ │ │ │ ├── profile.ts │ │ │ │ └── api.ts │ │ │ ├── git │ │ │ │ ├── index.ts │ │ │ │ ├── profile.ts │ │ │ │ └── api.ts │ │ │ ├── settings │ │ │ │ ├── index.ts │ │ │ │ ├── api.ts │ │ │ │ └── profile.ts │ │ │ ├── compiler │ │ │ │ ├── type │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── profile.ts │ │ │ │ └── api.ts │ │ │ ├── plugin-manager │ │ │ │ ├── index.ts │ │ │ │ ├── profile.ts │ │ │ │ └── api.ts │ │ │ ├── vscextapi │ │ │ │ ├── index.ts │ │ │ │ ├── profile.ts │ │ │ │ └── api.ts │ │ │ ├── udapp │ │ │ │ ├── index.ts │ │ │ │ ├── profile.ts │ │ │ │ ├── api.ts │ │ │ │ └── type.ts │ │ │ ├── editor │ │ │ │ ├── index.ts │ │ │ │ ├── profile.ts │ │ │ │ ├── type.ts │ │ │ │ └── api.ts │ │ │ ├── network │ │ │ │ ├── index.ts │ │ │ │ ├── profile.ts │ │ │ │ ├── api.ts │ │ │ │ └── type.ts │ │ │ ├── terminal │ │ │ │ ├── index.ts │ │ │ │ ├── type.ts │ │ │ │ ├── profile.ts │ │ │ │ └── api.ts │ │ │ ├── theme │ │ │ │ ├── index.ts │ │ │ │ ├── profile.ts │ │ │ │ ├── api.ts │ │ │ │ └── types.ts │ │ │ ├── content-import │ │ │ │ ├── index.ts │ │ │ │ ├── type.ts │ │ │ │ ├── profile.ts │ │ │ │ └── api.ts │ │ │ ├── unit-testing │ │ │ │ ├── index.ts │ │ │ │ ├── profile.ts │ │ │ │ ├── type.ts │ │ │ │ └── api.ts │ │ │ ├── file-system │ │ │ │ ├── file-manager │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── type.ts │ │ │ │ │ ├── profile.ts │ │ │ │ │ └── api.ts │ │ │ │ └── file-panel │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── type.ts │ │ │ │ │ ├── profile.ts │ │ │ │ │ └── api.ts │ │ │ └── standard-profile.ts │ │ └── index.ts │ ├── .eslintrc.json │ ├── tsconfig.json │ ├── tsconfig.lib.json │ ├── tsconfig.spec.json │ ├── jest.config.js │ ├── doc │ │ ├── settings.md │ │ ├── compiler.md │ │ ├── terminal.md │ │ ├── editor.md │ │ ├── solidity.md │ │ ├── content-import.md │ │ ├── unit-testing.md │ │ └── udapp.md │ ├── package.json │ └── README.md └── utils │ ├── .eslintrc.json │ ├── README.md │ ├── src │ ├── lib │ │ ├── types │ │ │ ├── options.ts │ │ │ ├── service.ts │ │ │ ├── queue.ts │ │ │ ├── status.ts │ │ │ ├── message.ts │ │ │ ├── plugin.ts │ │ │ ├── profile.ts │ │ │ └── api.ts │ │ └── tools │ │ │ ├── event-name.ts │ │ │ └── method-path.ts │ └── index.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ ├── tsconfig.spec.json │ ├── jest.config.js │ ├── tests │ ├── event-name.spec.ts │ └── method-path.spec.ts │ └── package.json ├── examples └── example │ ├── engine │ ├── web │ │ ├── src │ │ │ ├── assets │ │ │ │ ├── .gitkeep │ │ │ │ └── web.worker.js │ │ │ ├── test-setup.ts │ │ │ ├── environments │ │ │ │ ├── environment.prod.ts │ │ │ │ └── environment.ts │ │ │ ├── favicon.ico │ │ │ ├── app │ │ │ │ ├── terminal │ │ │ │ │ ├── terminal.component.html │ │ │ │ │ ├── terminal.component.scss │ │ │ │ │ └── terminal.component.ts │ │ │ │ ├── plugins │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── terminal.ts │ │ │ │ │ ├── window.ts │ │ │ │ │ ├── library.ts │ │ │ │ │ ├── manager.ts │ │ │ │ │ └── theme.ts │ │ │ │ ├── engine.ts │ │ │ │ ├── app.component.scss │ │ │ │ ├── app.component.html │ │ │ │ ├── app.module.ts │ │ │ │ └── app.component.ts │ │ │ ├── styles.scss │ │ │ ├── main.ts │ │ │ └── index.html │ │ ├── .eslintrc.json │ │ ├── tsconfig.editor.json │ │ ├── tsconfig.app.json │ │ ├── tsconfig.spec.json │ │ ├── tsconfig.json │ │ ├── jest.config.js │ │ └── .browserslistrc │ └── web-e2e │ │ ├── src │ │ ├── fixtures │ │ │ └── example.json │ │ ├── support │ │ │ ├── app.po.ts │ │ │ ├── index.ts │ │ │ └── commands.ts │ │ ├── integration │ │ │ └── app.spec.ts │ │ └── plugins │ │ │ └── index.js │ │ ├── tsconfig.json │ │ ├── tsconfig.e2e.json │ │ ├── .eslintrc.json │ │ └── cypress.json │ └── plugin │ ├── webview │ ├── src │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── test-setup.ts │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── favicon.ico │ │ ├── styles.scss │ │ ├── app │ │ │ ├── app.component.html │ │ │ ├── app.module.ts │ │ │ ├── app.component.ts │ │ │ └── client.ts │ │ ├── index.html │ │ └── main.ts │ ├── .eslintrc.json │ ├── tsconfig.editor.json │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ ├── tsconfig.json │ ├── jest.config.js │ └── .browserslistrc │ └── webview-e2e │ ├── src │ ├── support │ │ ├── app.po.ts │ │ ├── index.ts │ │ └── commands.ts │ ├── fixtures │ │ └── example.json │ ├── integration │ │ └── app.spec.ts │ └── plugins │ │ └── index.js │ ├── tsconfig.json │ ├── tsconfig.e2e.json │ ├── .eslintrc.json │ └── cypress.json ├── .prettierrc ├── .prettierignore ├── .vscode ├── extensions.json └── launch.json ├── .github └── workflows │ └── rebase-pull-requests.yml ├── .editorconfig ├── jest.preset.js ├── .circleci └── config.yml ├── projects └── client │ └── assets │ └── origins.json ├── tsconfig.spec.json ├── lerna.json ├── .gitignore ├── jest.config.js ├── .eslintrc.json └── tsconfig.base.json /tools/schematics/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/plugin/theia/src/index.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /examples/example/plugin/webview/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/plugin/ws/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/ws'; 2 | -------------------------------------------------------------------------------- /packages/plugin/webview/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/connector' 2 | -------------------------------------------------------------------------------- /packages/engine/node/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/child-process'; 2 | -------------------------------------------------------------------------------- /packages/engine/theia/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/engine-theia'; 2 | -------------------------------------------------------------------------------- /packages/plugin/webworker/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/connector'; 2 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/test-setup.ts: -------------------------------------------------------------------------------- 1 | import 'jest-preset-angular'; 2 | -------------------------------------------------------------------------------- /examples/example/plugin/webview/src/test-setup.ts: -------------------------------------------------------------------------------- 1 | import 'jest-preset-angular'; 2 | -------------------------------------------------------------------------------- /packages/engine/electron/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/electronPlugin'; 2 | -------------------------------------------------------------------------------- /packages/plugin/child-process/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/connector'; 2 | -------------------------------------------------------------------------------- /packages/api/src/lib/window/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './profile' -------------------------------------------------------------------------------- /packages/api/src/lib/dgit/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './profile' 3 | -------------------------------------------------------------------------------- /packages/api/src/lib/git/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './profile' 3 | -------------------------------------------------------------------------------- /packages/api/src/lib/settings/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './profile' -------------------------------------------------------------------------------- /packages/api/src/lib/compiler/type/index.ts: -------------------------------------------------------------------------------- 1 | export * from './input' 2 | export * from './output' -------------------------------------------------------------------------------- /packages/api/src/lib/plugin-manager/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './profile' -------------------------------------------------------------------------------- /packages/api/src/lib/vscextapi/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './profile' 3 | -------------------------------------------------------------------------------- /packages/plugin/iframe/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/connector' 2 | export * from './lib/theme' -------------------------------------------------------------------------------- /packages/plugin/vscode/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/webview'; 2 | export * from './lib/extension'; -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Add files here to ignore them from prettier formatting 2 | 3 | /dist 4 | /coverage 5 | -------------------------------------------------------------------------------- /examples/example/plugin/webview-e2e/src/support/app.po.ts: -------------------------------------------------------------------------------- 1 | export const getGreeting = () => cy.get('h1'); 2 | -------------------------------------------------------------------------------- /packages/api/src/lib/udapp/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './type' 3 | export * from './profile' -------------------------------------------------------------------------------- /packages/api/src/lib/compiler/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './type' 3 | export * from './profile' -------------------------------------------------------------------------------- /packages/api/src/lib/editor/index.ts: -------------------------------------------------------------------------------- 1 | export * from './type' 2 | export * from './api' 3 | export * from './profile' -------------------------------------------------------------------------------- /packages/api/src/lib/network/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './type' 3 | export * from './profile' -------------------------------------------------------------------------------- /packages/api/src/lib/terminal/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './type' 3 | export * from './profile' -------------------------------------------------------------------------------- /packages/api/src/lib/theme/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './profile' 3 | export * from './types' -------------------------------------------------------------------------------- /packages/engine/theia/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/engine-theia", 3 | "version": "0.3.37" 4 | } 5 | -------------------------------------------------------------------------------- /packages/plugin/theia/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/engine-plugin", 3 | "version": "0.3.37" 4 | } 5 | -------------------------------------------------------------------------------- /packages/api/src/lib/content-import/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './type' 3 | export * from './profile' -------------------------------------------------------------------------------- /packages/api/src/lib/unit-testing/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './type' 3 | export * from './profile' -------------------------------------------------------------------------------- /packages/engine/electron/README.md: -------------------------------------------------------------------------------- 1 | # engine-electron 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | -------------------------------------------------------------------------------- /packages/plugin/webview/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { "extends": "../../../.eslintrc", "rules": {}, "ignorePatterns": ["!**/*"] } 2 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | }; 4 | -------------------------------------------------------------------------------- /packages/api/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../.eslintrc", 3 | "rules": {}, 4 | "ignorePatterns": ["!**/*"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/engine/theia/src/lib/engine-theia.ts: -------------------------------------------------------------------------------- 1 | export function engineTheia(): string { 2 | return 'engine-theia'; 3 | } 4 | -------------------------------------------------------------------------------- /packages/plugin/electron/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/electronPluginClient'; 2 | export * from './lib/electronBasePlugin'; -------------------------------------------------------------------------------- /examples/example/plugin/webview/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | }; 4 | -------------------------------------------------------------------------------- /packages/api/src/lib/file-system/file-manager/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './type' 3 | export * from './profile' -------------------------------------------------------------------------------- /packages/api/src/lib/file-system/file-panel/index.ts: -------------------------------------------------------------------------------- 1 | export * from './api' 2 | export * from './profile' 3 | export * from './type' -------------------------------------------------------------------------------- /packages/utils/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../.eslintrc", 3 | "rules": {}, 4 | "ignorePatterns": ["!**/*"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/utils/README.md: -------------------------------------------------------------------------------- 1 | # plugin-utils 2 | 3 | A simple utils library used by `@remixproject/engine` & `@remixproject/plugin`. 4 | -------------------------------------------------------------------------------- /packages/engine/web/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../.eslintrc", 3 | "rules": {}, 4 | "ignorePatterns": ["!**/*"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/plugin/ws/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../.eslintrc", 3 | "rules": {}, 4 | "ignorePatterns": ["!**/*"] 5 | } 6 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/remix-plugin/HEAD/examples/example/engine/web/src/favicon.ico -------------------------------------------------------------------------------- /packages/engine/core/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../.eslintrc", 3 | "rules": {}, 4 | "ignorePatterns": ["!**/*"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/engine/electron/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../.eslintrc", 3 | "rules": {}, 4 | "ignorePatterns": ["!**/*"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/engine/node/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../.eslintrc", 3 | "rules": {}, 4 | "ignorePatterns": ["!**/*"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/engine/vscode/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../.eslintrc", 3 | "rules": {}, 4 | "ignorePatterns": ["!**/*"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/plugin/core/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../.eslintrc", 3 | "rules": {}, 4 | "ignorePatterns": ["!**/*"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/plugin/electron/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../.eslintrc", 3 | "rules": {}, 4 | "ignorePatterns": ["!**/*"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/plugin/iframe/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../.eslintrc", 3 | "rules": {}, 4 | "ignorePatterns": ["!**/*"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/plugin/vscode/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../.eslintrc", 3 | "rules": {}, 4 | "ignorePatterns": ["!**/*"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/api/src/lib/file-system/file-manager/type.ts: -------------------------------------------------------------------------------- 1 | export interface Folder { 2 | [path: string]: { 3 | isDirectory: boolean 4 | } 5 | } -------------------------------------------------------------------------------- /packages/engine/theia/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../.eslintrc.json", 3 | "ignorePatterns": ["!**/*"], 4 | "rules": {} 5 | } 6 | -------------------------------------------------------------------------------- /packages/plugin/child-process/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../.eslintrc", 3 | "rules": {}, 4 | "ignorePatterns": ["!**/*"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/plugin/theia/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../.eslintrc.json", 3 | "ignorePatterns": ["!**/*"], 4 | "rules": {} 5 | } 6 | -------------------------------------------------------------------------------- /examples/example/engine/web-e2e/src/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io" 4 | } 5 | -------------------------------------------------------------------------------- /examples/example/plugin/webview/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/remix-plugin/HEAD/examples/example/plugin/webview/src/favicon.ico -------------------------------------------------------------------------------- /packages/api/src/lib/terminal/type.ts: -------------------------------------------------------------------------------- 1 | export type TerminalMessage = { 2 | value: any, 3 | type: 'html' | 'log' | 'info' | 'warn' | 'error' 4 | } -------------------------------------------------------------------------------- /packages/plugin/webworker/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../.eslintrc.json", 3 | "ignorePatterns": ["!**/*"], 4 | "rules": {} 5 | } 6 | -------------------------------------------------------------------------------- /examples/example/engine/web/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../../.eslintrc.json", 3 | "ignorePatterns": ["!**/*"], 4 | "rules": {} 5 | } 6 | -------------------------------------------------------------------------------- /examples/example/plugin/webview-e2e/src/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io" 4 | } 5 | -------------------------------------------------------------------------------- /examples/example/plugin/webview/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../../.eslintrc.json", 3 | "ignorePatterns": ["!**/*"], 4 | "rules": {} 5 | } 6 | -------------------------------------------------------------------------------- /packages/plugin/core/doc/videos/remix_local_plugin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/remix-plugin/HEAD/packages/plugin/core/doc/videos/remix_local_plugin.gif -------------------------------------------------------------------------------- /packages/plugin/core/doc/videos/remix_load_local_plugin.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethereum/remix-plugin/HEAD/packages/plugin/core/doc/videos/remix_load_local_plugin.mp4 -------------------------------------------------------------------------------- /examples/example/engine/web/src/app/terminal/terminal.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /examples/example/engine/web-e2e/src/support/app.po.ts: -------------------------------------------------------------------------------- 1 | function getId(id: string) { 2 | return cy.get(`[testId="${id}"]`); 3 | } 4 | 5 | export const pluginList = () => getId('plugin-list'); -------------------------------------------------------------------------------- /examples/example/engine/web/src/app/plugins/index.ts: -------------------------------------------------------------------------------- 1 | export * from './manager' 2 | export * from './theme' 3 | export * from './window' 4 | export * from './library' 5 | export * from './terminal'; -------------------------------------------------------------------------------- /examples/example/engine/web/tsconfig.editor.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["**/*.ts"], 4 | "compilerOptions": { 5 | "types": ["jest", "node"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/example/plugin/webview/tsconfig.editor.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["**/*.ts"], 4 | "compilerOptions": { 5 | "types": ["jest", "node"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/plugin/core/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/api'; 2 | export * from './lib/client'; 3 | export * from './lib/connector'; 4 | export * from './lib/node'; 5 | export * from './lib/origin'; 6 | -------------------------------------------------------------------------------- /packages/api/src/lib/content-import/type.ts: -------------------------------------------------------------------------------- 1 | export interface ContentImport { 2 | content: any 3 | cleanUrl: string 4 | type: 'github' | 'http' | 'https' | 'swarm' | 'ipfs' 5 | url: string 6 | } 7 | -------------------------------------------------------------------------------- /packages/engine/core/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/abstract' 2 | export * from './lib/connector' 3 | export * from './lib/engine' 4 | export * from './lib/library' 5 | export * from './lib/manager' 6 | -------------------------------------------------------------------------------- /packages/utils/src/lib/types/options.ts: -------------------------------------------------------------------------------- 1 | export interface PluginOptions { 2 | /** The time to wait for a call to be executed before going to next call in the queue */ 3 | queueTimeout?: number 4 | } -------------------------------------------------------------------------------- /examples/example/plugin/webview/src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | body { 4 | background-color: var(--background); 5 | color: var(--foreground); 6 | } -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "nrwl.angular-console", 4 | "ms-vscode.vscode-typescript-tslint-plugin", 5 | "esbenp.prettier-vscode", 6 | "firsttris.vscode-jest-runner" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /packages/api/src/lib/settings/api.ts: -------------------------------------------------------------------------------- 1 | import { StatusEvents } from '@remixproject/plugin-utils' 2 | 3 | export interface ISettings { 4 | events: {} & StatusEvents 5 | methods: { 6 | getGithubAccessToken(): string 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/engine/node/README.md: -------------------------------------------------------------------------------- 1 | # engine-node 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Running unit tests 6 | 7 | Run `ng test engine-node` to execute the unit tests via [Jest](https://jestjs.io). 8 | -------------------------------------------------------------------------------- /packages/engine/theia/README.md: -------------------------------------------------------------------------------- 1 | # engine-theia 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Running unit tests 6 | 7 | Run `nx test engine-theia` to execute the unit tests via [Jest](https://jestjs.io). 8 | -------------------------------------------------------------------------------- /packages/plugin/theia/README.md: -------------------------------------------------------------------------------- 1 | # plugin-theia 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Running unit tests 6 | 7 | Run `nx test plugin-theia` to execute the unit tests via [Jest](https://jestjs.io). 8 | -------------------------------------------------------------------------------- /packages/plugin/electron/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /examples/example/engine/web/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../../dist/out-tsc", 5 | "types": [] 6 | }, 7 | "files": ["src/main.ts", "src/polyfills.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/engine/theia/src/lib/engine-theia.spec.ts: -------------------------------------------------------------------------------- 1 | import { engineTheia } from './engine-theia'; 2 | 3 | describe('engineTheia', () => { 4 | it('should work', () => { 5 | expect(engineTheia()).toEqual('engine-theia'); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /examples/example/engine/web-e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.e2e.json" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /examples/example/plugin/webview-e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.e2e.json" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /examples/example/plugin/webview/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../../dist/out-tsc", 5 | "types": [] 6 | }, 7 | "files": ["src/main.ts", "src/polyfills.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/engine/web/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/iframe' 2 | export * from './lib/ws' 3 | export * from './lib/theme' 4 | export * from './lib/window' 5 | export * from './lib/web-worker' 6 | export * from './lib/host' 7 | export * from './lib/view' -------------------------------------------------------------------------------- /packages/engine/electron/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /packages/plugin/child-process/README.md: -------------------------------------------------------------------------------- 1 | # plugin-child-process 2 | 3 | This library was generated with [Nx](https://nx.dev). 4 | 5 | ## Running unit tests 6 | 7 | Run `ng test plugin-child-process` to execute the unit tests via [Jest](https://jestjs.io). 8 | -------------------------------------------------------------------------------- /packages/plugin/core/assets/origins.json: -------------------------------------------------------------------------------- 1 | [ 2 | "http://remix-alpha.ethereum.org", 3 | "http://remix.ethereum.org", 4 | "https://remix-alpha.ethereum.org", 5 | "https://remix.ethereum.org", 6 | "package://a7df6d3c223593f3550b35e90d7b0b1f.mod" 7 | ] 8 | -------------------------------------------------------------------------------- /packages/api/src/lib/terminal/profile.ts: -------------------------------------------------------------------------------- 1 | import { ITerminal } from './api' 2 | import { LibraryProfile } from '@remixproject/plugin-utils' 3 | 4 | export const terminalProfile: LibraryProfile = { 5 | name: 'terminal', 6 | methods: ['log'], 7 | } 8 | -------------------------------------------------------------------------------- /packages/api/src/lib/window/profile.ts: -------------------------------------------------------------------------------- 1 | import { IWindow } from './api' 2 | import { LibraryProfile } from '@remixproject/plugin-utils' 3 | 4 | export const windowProfile: LibraryProfile = { 5 | name: 'window', 6 | methods: ['prompt', 'confirm', 'alert'], 7 | } -------------------------------------------------------------------------------- /.github/workflows/rebase-pull-requests.yml: -------------------------------------------------------------------------------- 1 | name: Rebase Pull Requests 2 | on: 3 | push: 4 | branches: [master] 5 | workflow_dispatch: 6 | 7 | jobs: 8 | rebase: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: yann300/rebase-pull-requests@master -------------------------------------------------------------------------------- /packages/api/src/lib/settings/profile.ts: -------------------------------------------------------------------------------- 1 | import { ISettings } from './api' 2 | import { LibraryProfile } from '@remixproject/plugin-utils' 3 | 4 | export const settingsProfile: LibraryProfile = { 5 | name: 'settings', 6 | methods: ['getGithubAccessToken'], 7 | } 8 | -------------------------------------------------------------------------------- /packages/api/src/lib/theme/profile.ts: -------------------------------------------------------------------------------- 1 | import { ITheme } from './api' 2 | import { LibraryProfile } from '@remixproject/plugin-utils' 3 | 4 | export const themeProfile: LibraryProfile = { 5 | name: 'theme', 6 | methods: ['currentTheme'], 7 | events: ['themeChanged'] 8 | } -------------------------------------------------------------------------------- /packages/api/src/lib/vscextapi/profile.ts: -------------------------------------------------------------------------------- 1 | import { IVScodeExtAPI } from './api' 2 | import { LibraryProfile } from '@remixproject/plugin-utils' 3 | 4 | export const vscodeExtProfile: LibraryProfile = { 5 | name: 'vscodeExtAPI', 6 | methods: ['executeCommand'] 7 | } 8 | -------------------------------------------------------------------------------- /packages/api/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/plugin/ws/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/utils/src/lib/types/service.ts: -------------------------------------------------------------------------------- 1 | export type IPluginService = any> = { 2 | methods: string[] 3 | readonly path: string 4 | } & T 5 | 6 | export type GetPluginService> = S extends IPluginService ? S : IPluginService -------------------------------------------------------------------------------- /examples/example/plugin/webview/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |
2 | Nx logo 7 |

Welcome to {{ title }}!

8 |
9 |
10 | 11 |
12 | -------------------------------------------------------------------------------- /packages/api/src/lib/unit-testing/profile.ts: -------------------------------------------------------------------------------- 1 | import { IUnitTesting } from './api' 2 | import { LibraryProfile } from '@remixproject/plugin-utils' 3 | 4 | export const unitTestProfile: LibraryProfile = { 5 | name: 'unitTest', 6 | methods: ['testFromPath', 'testFromSource'], 7 | } 8 | -------------------------------------------------------------------------------- /packages/api/src/lib/vscextapi/api.ts: -------------------------------------------------------------------------------- 1 | import { StatusEvents } from '@remixproject/plugin-utils' 2 | 3 | export interface IVScodeExtAPI { 4 | events: { 5 | } & StatusEvents 6 | methods: { 7 | executeCommand(extension: string, command: string, payload?: any[]): any 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/engine/theia/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/engine/vscode/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/engine/web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/plugin/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/plugin/iframe/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/plugin/theia/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/plugin/webview/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/api/src/lib/terminal/api.ts: -------------------------------------------------------------------------------- 1 | import { StatusEvents } from '@remixproject/plugin-utils' 2 | import { TerminalMessage } from './type'; 3 | export interface ITerminal { 4 | events: { 5 | } & StatusEvents 6 | methods: { 7 | log(message: TerminalMessage): void 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/plugin/webworker/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tools/tsconfig.tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "../dist/out-tsc/tools", 5 | "rootDir": ".", 6 | "module": "commonjs", 7 | "target": "es5", 8 | "types": ["node"] 9 | }, 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/api/src/lib/content-import/profile.ts: -------------------------------------------------------------------------------- 1 | import { IContentImport } from './api' 2 | import { LibraryProfile } from '@remixproject/plugin-utils' 3 | 4 | export const contentImportProfile: LibraryProfile = { 5 | name: 'contentImport', 6 | methods: ['resolve','resolveAndSave'], 7 | } 8 | -------------------------------------------------------------------------------- /packages/api/src/lib/unit-testing/type.ts: -------------------------------------------------------------------------------- 1 | export interface UnitTestResult { 2 | totalFailing: number 3 | totalPassing: number 4 | totalTime: number 5 | errors: UnitTestError[] 6 | } 7 | 8 | export interface UnitTestError { 9 | context: string 10 | value: string 11 | message: string 12 | } -------------------------------------------------------------------------------- /packages/plugin/child-process/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/app/terminal/terminal.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | height: 100%; 4 | border-top: solid 1px black; 5 | box-sizing: border-box; 6 | } 7 | 8 | textarea { 9 | height: 100%; 10 | width: 100%; 11 | border: none; 12 | box-sizing: border-box; 13 | } -------------------------------------------------------------------------------- /packages/utils/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/app/engine.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Engine as PluginEngine } from '@remixproject/engine'; 3 | 4 | @Injectable({ providedIn: 'root' }) 5 | export class Engine extends PluginEngine { 6 | constructor() { 7 | super(); 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/styles.scss: -------------------------------------------------------------------------------- 1 | @import '~@angular/material/theming'; 2 | @import '@angular/material/prebuilt-themes/deeppurple-amber.css'; 3 | @include mat-core(); 4 | 5 | html, body { 6 | margin: 0; 7 | height: 100%; 8 | } 9 | 10 | body { 11 | font-family: 'Montserrat', sans-serif; 12 | } -------------------------------------------------------------------------------- /packages/api/src/lib/theme/api.ts: -------------------------------------------------------------------------------- 1 | import { StatusEvents } from '@remixproject/plugin-utils' 2 | import { Theme } from './types' 3 | 4 | export interface ITheme { 5 | events: { 6 | themeChanged: (theme: Theme) => void 7 | } & StatusEvents 8 | methods: { 9 | currentTheme(): Theme 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /examples/example/engine/web-e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "sourceMap": false, 5 | "outDir": "../../../../dist/out-tsc", 6 | "allowJs": true, 7 | "types": ["cypress", "node"] 8 | }, 9 | "include": ["src/**/*.ts", "src/**/*.js"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/api/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../dist/out-tsc", 6 | "declaration": true, 7 | "types": ["node"] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/engine/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/engine/node/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/engine/theia/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../../dist/out-tsc", 6 | "declaration": true, 7 | "types": ["node"] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/plugin/theia/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../../dist/out-tsc", 6 | "declaration": true, 7 | "types": ["node"] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/plugin/vscode/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.lib.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/utils/src/lib/types/queue.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | PluginRequest, 3 | } from './message' 4 | 5 | export interface PluginQueueInterface { 6 | setCurrentRequest(request: PluginRequest): void 7 | callMethod(method: string, args: any[]): void 8 | letContinue(): void 9 | cancel(): void 10 | } -------------------------------------------------------------------------------- /packages/utils/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../dist/out-tsc", 6 | "declaration": true, 7 | "types": ["node"] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /examples/example/plugin/webview-e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "sourceMap": false, 5 | "outDir": "../../../../dist/out-tsc", 6 | "allowJs": true, 7 | "types": ["cypress", "node"] 8 | }, 9 | "include": ["src/**/*.ts", "src/**/*.js"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/engine/core/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../../dist/out-tsc", 6 | "declaration": true, 7 | "types": [] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/engine/web/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../../dist/out-tsc", 6 | "declaration": true, 7 | "types": [] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/plugin/webview/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../../dist/out-tsc", 6 | "declaration": true, 7 | "types": ["node"] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /examples/example/engine/web/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "files": ["src/test-setup.ts"], 9 | "include": ["**/*.spec.ts", "**/*.d.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/engine/node/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../../dist/out-tsc", 6 | "declaration": true, 7 | "types": ["node"] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/plugin/core/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../../dist/out-tsc", 6 | "declaration": true, 7 | "types": ["node"] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/plugin/ws/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../../dist/out-tsc", 6 | "declaration": true, 7 | "types": ["node"] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /examples/example/engine/web-e2e/src/integration/app.spec.ts: -------------------------------------------------------------------------------- 1 | import { pluginList } from '../support/app.po'; 2 | 3 | describe('example-engine-web', () => { 4 | beforeEach(() => cy.visit('/')); 5 | 6 | it('should display 9 plugins', () => { 7 | pluginList().children('button').should('have.length', 9); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /examples/example/plugin/webview/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "files": ["src/test-setup.ts"], 9 | "include": ["**/*.spec.ts", "**/*.d.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/engine/electron/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../../dist/out-tsc", 6 | "declaration": true, 7 | "types": ["node"] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/engine/vscode/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../../dist/out-tsc", 6 | "declaration": true, 7 | "types": ["node"] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/plugin/electron/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../../dist/out-tsc", 6 | "declaration": true, 7 | "types": ["node"] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/plugin/iframe/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../../dist/out-tsc", 6 | "declaration": true, 7 | "types": ["node"] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/plugin/vscode/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../../dist/out-tsc", 6 | "declaration": true, 7 | "types": ["node"] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/plugin/child-process/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../../dist/out-tsc", 6 | "declaration": true, 7 | "types": ["node"] 8 | }, 9 | "exclude": ["**/*.spec.ts"], 10 | "include": ["**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/api/src/lib/editor/profile.ts: -------------------------------------------------------------------------------- 1 | import { IEditor } from './api' 2 | import { LibraryProfile } from '@remixproject/plugin-utils' 3 | 4 | export const editorProfile: LibraryProfile = { 5 | name: 'editor', 6 | methods: ['discardHighlight', 'highlight', 'addAnnotation', 'clearAnnotations', 'discardHighlightAt', 'gotoLine'], 7 | } 8 | -------------------------------------------------------------------------------- /packages/api/src/lib/git/profile.ts: -------------------------------------------------------------------------------- 1 | import { IGitSystem } from './api' 2 | import { LibraryProfile } from '@remixproject/plugin-utils' 3 | 4 | export const gitProfile: LibraryProfile = { 5 | name: 'remixd.git', 6 | methods: ['clone', 'checkout', 'init', 'add', 'commit', 'fetch', 'pull', 'push', 'reset', 'status', 'remote', 'log'] 7 | } 8 | -------------------------------------------------------------------------------- /packages/utils/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.spec.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs" 6 | }, 7 | "include": [ 8 | "**/*.spec.ts", 9 | "**/*.spec.tsx", 10 | "**/*.spec.js", 11 | "**/*.spec.jsx", 12 | "**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/api/src/lib/file-system/file-panel/type.ts: -------------------------------------------------------------------------------- 1 | export interface customAction { 2 | id: string, 3 | name: string, 4 | type: customActionType[], 5 | path: string[], 6 | extension: string[], 7 | pattern: string[], 8 | sticky?: boolean, 9 | label?: string 10 | } 11 | 12 | export type customActionType = 'file' | 'folder' -------------------------------------------------------------------------------- /packages/plugin/webworker/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "outDir": "../../../dist/out-tsc", 6 | "declaration": true, 7 | "lib": ["webworker"], 8 | "types": ["node"] 9 | }, 10 | "exclude": ["**/*.spec.ts"], 11 | "include": ["**/*.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/utils/src/lib/tools/event-name.ts: -------------------------------------------------------------------------------- 1 | /** Create the name of the event for a call */ 2 | export function callEvent(name: string, key: string, id: number) { 3 | return `[${name}] ${key}-${id}` 4 | } 5 | 6 | /** Create the name of the event for a listen */ 7 | export function listenEvent(name: string, key: string) { 8 | return `[${name}] ${key}` 9 | } -------------------------------------------------------------------------------- /packages/api/src/lib/network/profile.ts: -------------------------------------------------------------------------------- 1 | import { INetwork } from './api' 2 | import { LibraryProfile } from '@remixproject/plugin-utils' 3 | 4 | export const networkProfile: LibraryProfile = { 5 | name: 'network', 6 | methods: ['addNetwork', 'detectNetwork', 'getEndpoint', 'getNetworkProvider', 'removeNetwork'], 7 | events: ['providerChanged'] 8 | } -------------------------------------------------------------------------------- /packages/api/src/lib/udapp/profile.ts: -------------------------------------------------------------------------------- 1 | import { IUdapp } from './api' 2 | import { LibraryProfile } from '@remixproject/plugin-utils' 3 | 4 | export const udappProfile: LibraryProfile = { 5 | name: 'udapp', 6 | methods: ['createVMAccount', 'getAccounts', 'sendTransaction', 'getSettings', 'setEnvironmentMode'], 7 | events: ['newTransaction'] 8 | } 9 | -------------------------------------------------------------------------------- /packages/engine/core/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.spec.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs" 6 | }, 7 | "include": [ 8 | "**/*.spec.ts", 9 | "**/*.spec.tsx", 10 | "**/*.spec.js", 11 | "**/*.spec.jsx", 12 | "**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/engine/node/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.spec.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs" 6 | }, 7 | "include": [ 8 | "**/*.spec.ts", 9 | "**/*.spec.tsx", 10 | "**/*.spec.js", 11 | "**/*.spec.jsx", 12 | "**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/plugin/core/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.spec.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs" 6 | }, 7 | "include": [ 8 | "**/*.spec.ts", 9 | "**/*.spec.tsx", 10 | "**/*.spec.js", 11 | "**/*.spec.jsx", 12 | "**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/plugin/ws/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.spec.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs" 6 | }, 7 | "include": [ 8 | "**/*.spec.ts", 9 | "**/*.spec.tsx", 10 | "**/*.spec.js", 11 | "**/*.spec.jsx", 12 | "**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/api/src/lib/content-import/api.ts: -------------------------------------------------------------------------------- 1 | import { ContentImport } from './type' 2 | import { StatusEvents } from '@remixproject/plugin-utils' 3 | 4 | export interface IContentImport { 5 | events: {} & StatusEvents 6 | methods: { 7 | resolve(path: string): ContentImport 8 | resolveAndSave (url:string, targetPath: string): string 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/api/src/lib/unit-testing/api.ts: -------------------------------------------------------------------------------- 1 | import { UnitTestResult } from './type' 2 | import { StatusEvents } from '@remixproject/plugin-utils' 3 | 4 | export interface IUnitTesting { 5 | events: {} & StatusEvents 6 | methods: { 7 | testFromPath(path: string): UnitTestResult 8 | testFromSource(sourceCode: string): UnitTestResult 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/engine/vscode/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.spec.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs" 6 | }, 7 | "include": [ 8 | "**/*.spec.ts", 9 | "**/*.spec.tsx", 10 | "**/*.spec.js", 11 | "**/*.spec.jsx", 12 | "**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/plugin/iframe/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.spec.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs" 6 | }, 7 | "include": [ 8 | "**/*.spec.ts", 9 | "**/*.spec.tsx", 10 | "**/*.spec.js", 11 | "**/*.spec.jsx", 12 | "**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/plugin/vscode/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.spec.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs" 6 | }, 7 | "include": [ 8 | "**/*.spec.ts", 9 | "**/*.spec.tsx", 10 | "**/*.spec.js", 11 | "**/*.spec.jsx", 12 | "**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /examples/example/engine/web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.app.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | }, 12 | { 13 | "path": "./tsconfig.editor.json" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/api/src/lib/compiler/profile.ts: -------------------------------------------------------------------------------- 1 | import { ICompiler } from './api' 2 | import { LibraryProfile } from '@remixproject/plugin-utils' 3 | 4 | export const compilerProfile: LibraryProfile = { 5 | name: 'solidity', 6 | methods: ['compile', 'getCompilationResult', 'compileWithParameters', 'setCompilerConfig'], 7 | events: ['compilationFinished'] 8 | } 9 | -------------------------------------------------------------------------------- /packages/engine/electron/src/global.d.ts: -------------------------------------------------------------------------------- 1 | export interface IElectronAPI { 2 | activatePlugin: (name: string) => Promise 3 | plugins: { 4 | name: string 5 | on: (cb: any) => void 6 | send: (message: Partial) => void 7 | }[] 8 | } 9 | 10 | declare global { 11 | interface Window { 12 | electronAPI: IElectronAPI 13 | } 14 | } -------------------------------------------------------------------------------- /examples/example/plugin/webview/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../../tsconfig.base.json", 3 | "files": [], 4 | "include": [], 5 | "references": [ 6 | { 7 | "path": "./tsconfig.app.json" 8 | }, 9 | { 10 | "path": "./tsconfig.spec.json" 11 | }, 12 | { 13 | "path": "./tsconfig.editor.json" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /jest.preset.js: -------------------------------------------------------------------------------- 1 | const nxPreset = require('@nrwl/jest/preset'); 2 | module.exports = { 3 | ...nxPreset, 4 | testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], 5 | transform: { 6 | '^.+\\.(ts|js|html)$': 'ts-jest', 7 | }, 8 | resolver: '@nrwl/jest/plugins/resolver', 9 | moduleFileExtensions: ['ts', 'js', 'html'], 10 | coverageReporters: ['html'], 11 | }; 12 | -------------------------------------------------------------------------------- /packages/api/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.spec.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "**/*.spec.ts", 10 | "**/*.spec.tsx", 11 | "**/*.spec.js", 12 | "**/*.spec.jsx", 13 | "**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/engine/theia/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "**/*.spec.ts", 10 | "**/*.spec.tsx", 11 | "**/*.spec.js", 12 | "**/*.spec.jsx", 13 | "**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/plugin/theia/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "**/*.spec.ts", 10 | "**/*.spec.tsx", 11 | "**/*.spec.js", 12 | "**/*.spec.jsx", 13 | "**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/plugin/webview/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "**/*.spec.ts", 10 | "**/*.spec.tsx", 11 | "**/*.spec.js", 12 | "**/*.spec.jsx", 13 | "**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/plugin/webworker/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "**/*.spec.ts", 10 | "**/*.spec.tsx", 11 | "**/*.spec.js", 12 | "**/*.spec.jsx", 13 | "**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /examples/example/engine/web-e2e/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["plugin:cypress/recommended", "../../../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["src/plugins/index.js"], 7 | "rules": { 8 | "@typescript-eslint/no-var-requires": "off", 9 | "no-undef": "off" 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/engine/web/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.spec.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "**/*.spec.ts", 10 | "**/*.spec.tsx", 11 | "**/*.spec.js", 12 | "**/*.spec.jsx", 13 | "**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | jobs: 3 | remix-plugin: 4 | docker: 5 | - image: cimg/node:14.17.6-browsers 6 | working_directory: ~/repo 7 | steps: 8 | - checkout 9 | - run: npm install 10 | - run: npm run build 11 | - run: npm run test 12 | 13 | workflows: 14 | version: 2 15 | build_all: 16 | jobs: 17 | - remix-plugin 18 | -------------------------------------------------------------------------------- /examples/example/plugin/webview-e2e/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["plugin:cypress/recommended", "../../../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"], 4 | "overrides": [ 5 | { 6 | "files": ["src/plugins/index.js"], 7 | "rules": { 8 | "@typescript-eslint/no-var-requires": "off", 9 | "no-undef": "off" 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /examples/example/plugin/webview/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | import { AppComponent } from './app.component'; 5 | 6 | @NgModule({ 7 | declarations: [AppComponent], 8 | imports: [BrowserModule], 9 | providers: [], 10 | bootstrap: [AppComponent], 11 | }) 12 | export class AppModule {} 13 | -------------------------------------------------------------------------------- /packages/plugin/child-process/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.spec.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc", 5 | "module": "commonjs", 6 | "types": ["jest", "node"] 7 | }, 8 | "include": [ 9 | "**/*.spec.ts", 10 | "**/*.spec.tsx", 11 | "**/*.spec.js", 12 | "**/*.spec.jsx", 13 | "**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/engine/web/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../../jest.preset.js', 3 | transform: { 4 | '^.+\\.[tj]sx?$': 'ts-jest', 5 | }, 6 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], 7 | coverageDirectory: '../../../coverage/packages/engine/web', 8 | globals: { 'ts-jest': { tsConfig: '/tsconfig.spec.json' } }, 9 | displayName: 'engine-web', 10 | }; 11 | -------------------------------------------------------------------------------- /packages/api/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../jest.preset.js', 3 | testEnvironment: 'node', 4 | transform: { 5 | '^.+\\.[tj]sx?$': 'ts-jest', 6 | }, 7 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], 8 | coverageDirectory: '../../coverage/packages/api', 9 | globals: { 'ts-jest': { tsConfig: '/tsconfig.spec.json' } }, 10 | displayName: 'api', 11 | }; 12 | -------------------------------------------------------------------------------- /packages/plugin/electron/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../../jest.preset.js', 3 | transform: { 4 | '^.+\\.[tj]sx?$': 'ts-jest', 5 | }, 6 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], 7 | coverageDirectory: '../../../coverage/packages/plugin/iframe', 8 | globals: { 'ts-jest': { tsConfig: '/tsconfig.spec.json' } }, 9 | displayName: 'plugin-iframe', 10 | }; 11 | -------------------------------------------------------------------------------- /packages/plugin/iframe/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../../jest.preset.js', 3 | transform: { 4 | '^.+\\.[tj]sx?$': 'ts-jest', 5 | }, 6 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], 7 | coverageDirectory: '../../../coverage/packages/plugin/iframe', 8 | globals: { 'ts-jest': { tsConfig: '/tsconfig.spec.json' } }, 9 | displayName: 'plugin-iframe', 10 | }; 11 | -------------------------------------------------------------------------------- /packages/utils/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../jest.preset.js', 3 | testEnvironment: 'node', 4 | transform: { 5 | '^.+\\.[tj]sx?$': 'ts-jest', 6 | }, 7 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], 8 | coverageDirectory: '../../coverage/packages/utils', 9 | globals: { 'ts-jest': { tsConfig: '/tsconfig.spec.json' } }, 10 | displayName: 'utils', 11 | }; 12 | -------------------------------------------------------------------------------- /packages/engine/vscode/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/command'; 2 | export * from './lib/dynamic-list'; 3 | export * from './lib/extension'; 4 | export * from './lib/theme'; 5 | export * from './lib/webview'; 6 | export * from './lib/window'; 7 | export * from './lib/filemanager'; 8 | export * from './lib/editor'; 9 | export * from './lib/terminal'; 10 | export * from './lib/contentimport'; 11 | export * from './lib/appmanager'; -------------------------------------------------------------------------------- /projects/client/assets/origins.json: -------------------------------------------------------------------------------- 1 | [ 2 | "http://remix-alpha.ethereum.org", 3 | "http://remix-beta.ethereum.org", 4 | "http://remix.ethereum.org", 5 | "https://remix-alpha.ethereum.org", 6 | "https://remix-beta.ethereum.org", 7 | "https://remix.ethereum.org", 8 | "package://a7df6d3c223593f3550b35e90d7b0b1f.mod", 9 | "package://6fd22d6fe5549ad4c4d8fd3ca0b7816b.mod", 10 | "https://ipfsgw.komputing.org" 11 | ] 12 | -------------------------------------------------------------------------------- /examples/example/plugin/webview/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ExamplePluginWebview 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/plugin/ws/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../../jest.preset.js', 3 | testEnvironment: 'node', 4 | transform: { 5 | '^.+\\.[tj]sx?$': 'ts-jest', 6 | }, 7 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], 8 | coverageDirectory: '../../../coverage/packages/plugin/ws', 9 | globals: { 'ts-jest': { tsConfig: '/tsconfig.spec.json' } }, 10 | displayName: 'plugin-ws', 11 | }; 12 | -------------------------------------------------------------------------------- /examples/example/plugin/webview/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject } from '@angular/core'; 2 | import { Client, CLIENT } from './client'; 3 | 4 | @Component({ 5 | selector: 'engine-root', 6 | templateUrl: './app.component.html', 7 | styleUrls: ['./app.component.scss'], 8 | }) 9 | export class AppComponent { 10 | title = 'Remix Plugin Example'; 11 | constructor(@Inject(CLIENT) private client: Client) {} 12 | } 13 | -------------------------------------------------------------------------------- /packages/engine/core/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../../jest.preset.js', 3 | testEnvironment: 'node', 4 | transform: { 5 | '^.+\\.[tj]sx?$': 'ts-jest', 6 | }, 7 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], 8 | coverageDirectory: '../../../coverage/packages/engine/core', 9 | globals: { 'ts-jest': { tsConfig: '/tsconfig.spec.json' } }, 10 | displayName: 'engine-core', 11 | }; 12 | -------------------------------------------------------------------------------- /packages/engine/node/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../../jest.preset.js', 3 | testEnvironment: 'node', 4 | transform: { 5 | '^.+\\.[tj]sx?$': 'ts-jest', 6 | }, 7 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], 8 | coverageDirectory: '../../../coverage/packages/engine/node', 9 | globals: { 'ts-jest': { tsConfig: '/tsconfig.spec.json' } }, 10 | displayName: 'engine-node', 11 | }; 12 | -------------------------------------------------------------------------------- /packages/engine/theia/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | displayName: 'engine-theia', 3 | preset: '../../../jest.preset.js', 4 | globals: { 5 | 'ts-jest': { 6 | tsConfig: '/tsconfig.spec.json', 7 | }, 8 | }, 9 | transform: { 10 | '^.+\\.[tj]sx?$': 'ts-jest', 11 | }, 12 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], 13 | coverageDirectory: '../../../coverage/packages/engine/theia', 14 | }; 15 | -------------------------------------------------------------------------------- /packages/plugin/core/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../../jest.preset.js', 3 | testEnvironment: 'node', 4 | transform: { 5 | '^.+\\.[tj]sx?$': 'ts-jest', 6 | }, 7 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], 8 | coverageDirectory: '../../../coverage/packages/plugin/core', 9 | globals: { 'ts-jest': { tsConfig: '/tsconfig.spec.json' } }, 10 | displayName: 'plugin-core', 11 | }; 12 | -------------------------------------------------------------------------------- /packages/plugin/theia/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | displayName: 'plugin-theia', 3 | preset: '../../../jest.preset.js', 4 | globals: { 5 | 'ts-jest': { 6 | tsConfig: '/tsconfig.spec.json', 7 | }, 8 | }, 9 | transform: { 10 | '^.+\\.[tj]sx?$': 'ts-jest', 11 | }, 12 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], 13 | coverageDirectory: '../../../coverage/packages/plugin/theia', 14 | }; 15 | -------------------------------------------------------------------------------- /packages/engine/electron/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../../jest.preset.js', 3 | testEnvironment: 'node', 4 | transform: { 5 | '^.+\\.[tj]sx?$': 'ts-jest', 6 | }, 7 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], 8 | coverageDirectory: '../../../coverage/packages/engine/node', 9 | globals: { 'ts-jest': { tsConfig: '/tsconfig.spec.json' } }, 10 | displayName: 'engine-node', 11 | }; 12 | -------------------------------------------------------------------------------- /packages/engine/vscode/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../../jest.preset.js', 3 | testEnvironment: 'node', 4 | transform: { 5 | '^.+\\.[tj]sx?$': 'ts-jest', 6 | }, 7 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], 8 | coverageDirectory: '../../../coverage/packages/engine/vscode', 9 | globals: { 'ts-jest': { tsConfig: '/tsconfig.spec.json' } }, 10 | displayName: 'engine-vscode', 11 | }; 12 | -------------------------------------------------------------------------------- /packages/plugin/vscode/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../../jest.preset.js', 3 | testEnvironment: 'node', 4 | transform: { 5 | '^.+\\.[tj]sx?$': 'ts-jest', 6 | }, 7 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], 8 | coverageDirectory: '../../../coverage/packages/plugin/vscode', 9 | globals: { 'ts-jest': { tsConfig: '/tsconfig.spec.json' } }, 10 | displayName: 'plugin-vscode', 11 | }; 12 | -------------------------------------------------------------------------------- /packages/api/src/lib/editor/type.ts: -------------------------------------------------------------------------------- 1 | export interface HighlightPosition { 2 | start: { 3 | line: number 4 | column: number 5 | } 6 | end: { 7 | line: number 8 | column: number 9 | } 10 | } 11 | 12 | export interface HighLightOptions { 13 | focus: boolean 14 | } 15 | 16 | export interface Annotation { 17 | row: number; 18 | column: number; 19 | text: string; 20 | type: "error" | "warning" | "info"; 21 | } 22 | -------------------------------------------------------------------------------- /packages/plugin/webworker/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | displayName: 'plugin-webworker', 3 | preset: '../../../jest.preset.js', 4 | globals: { 5 | 'ts-jest': { 6 | tsConfig: '/tsconfig.spec.json', 7 | }, 8 | }, 9 | transform: { 10 | '^.+\\.[tj]sx?$': 'ts-jest', 11 | }, 12 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], 13 | coverageDirectory: '../../../coverage/packages/plugin/webworker', 14 | }; 15 | -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "types": ["jest", "node"], 5 | "paths": { 6 | "@remixproject/plugin-utils": ["packages/utils/src/index.ts"], 7 | "@remixproject/plugin-api": ["packages/api/src/index.ts"], 8 | "@remixproject/engine": ["packages/engine/core/src/index.ts"], 9 | "@remixproject/plugin": ["packages/plugin/core/src/index.ts"] 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic() 12 | .bootstrapModule(AppModule) 13 | .catch((err) => console.error(err)); 14 | -------------------------------------------------------------------------------- /packages/api/src/lib/plugin-manager/profile.ts: -------------------------------------------------------------------------------- 1 | import { IPluginManager } from './api' 2 | import { LibraryProfile } from '@remixproject/plugin-utils' 3 | 4 | export const pluginManagerProfile: LibraryProfile & { name: 'manager' } = { 5 | name: 'manager', 6 | methods: ['getProfile', 'updateProfile', 'activatePlugin', 'deactivatePlugin', 'isActive', 'canCall'], 7 | events: ['pluginActivated', 'pluginDeactivated', 'profileAdded', 'profileUpdated'] 8 | } 9 | -------------------------------------------------------------------------------- /packages/plugin/child-process/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../../jest.preset.js', 3 | testEnvironment: 'node', 4 | transform: { 5 | '^.+\\.[tj]sx?$': 'ts-jest', 6 | }, 7 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], 8 | coverageDirectory: '../../../coverage/packages/plugin/child-process', 9 | globals: { 'ts-jest': { tsConfig: '/tsconfig.spec.json' } }, 10 | displayName: 'plugin-child-process', 11 | }; 12 | -------------------------------------------------------------------------------- /examples/example/plugin/webview/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic() 12 | .bootstrapModule(AppModule) 13 | .catch((err) => console.error(err)); 14 | -------------------------------------------------------------------------------- /packages/utils/src/lib/tools/method-path.ts: -------------------------------------------------------------------------------- 1 | 2 | /** Create a method path based on the method name and the path */ 3 | export function getMethodPath(method: string, path?: string) { 4 | if (!path) { 5 | return method 6 | } 7 | const part = path.split('.') 8 | part.shift() 9 | part.push(method) 10 | return part.join('.') 11 | } 12 | 13 | /** Get the root name of a path */ 14 | export function getRootPath(path: string) { 15 | return path.split('.').shift() 16 | } -------------------------------------------------------------------------------- /packages/utils/src/lib/types/status.ts: -------------------------------------------------------------------------------- 1 | export interface Status { 2 | /** Display an icon or number */ 3 | key: number | 'edited' | 'succeed' | 'loading' | 'failed' | 'none' 4 | /** Bootstrap css color */ 5 | type?: 'success' | 'info' | 'warning' | 'error' 6 | /** Describe the status on mouseover */ 7 | title?: string 8 | } 9 | 10 | /* tslint:disable:interface-over-type-literal */ 11 | export type StatusEvents = { 12 | statusChanged: (status: Status) => void 13 | } -------------------------------------------------------------------------------- /packages/plugin/webview/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '../../../jest.preset.js', 3 | globals: { 4 | 'ts-jest': { 5 | tsConfig: '/tsconfig.spec.json', 6 | }, 7 | }, 8 | testEnvironment: 'node', 9 | transform: { 10 | '^.+\\.[tj]sx?$': 'ts-jest', 11 | }, 12 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], 13 | coverageDirectory: '../../../coverage/packages/plugin/webview', 14 | displayName: 'plugin-webview', 15 | }; 16 | -------------------------------------------------------------------------------- /packages/utils/tests/event-name.spec.ts: -------------------------------------------------------------------------------- 1 | import { callEvent, listenEvent } from '../src' 2 | 3 | describe('Event names', () => { 4 | test('call event', () => { 5 | expect(callEvent('solidity', 'compile', 2)).toEqual('[solidity] compile-2') 6 | expect(callEvent('fs', 'setFile', '1' as any)).toEqual('[fs] setFile-1') 7 | }) 8 | test('listen event', () => { 9 | expect(listenEvent('solidity', 'onCompilationFinished')).toEqual('[solidity] onCompilationFinished') 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | height: 100%; 3 | display: flex; 4 | } 5 | aside { 6 | height: 100%; 7 | width: 300px; 8 | display: flex; 9 | flex-direction: column; 10 | justify-content: space-between; 11 | border-right: solid 1px black; 12 | } 13 | 14 | main { 15 | height: 100%; 16 | flex: 1; 17 | display: flex; 18 | flex-direction: column; 19 | 20 | section { 21 | flex: 1; 22 | } 23 | footer { 24 | height: 300px; 25 | } 26 | } -------------------------------------------------------------------------------- /packages/api/src/lib/dgit/profile.ts: -------------------------------------------------------------------------------- 1 | import { IDgitSystem } from './api' 2 | import { LibraryProfile } from '@remixproject/plugin-utils' 3 | 4 | export const dGitProfile: LibraryProfile = { 5 | name: 'dGitProvider', 6 | methods: ['clone', 'addremote', 'delremote', 'remotes', 'init', 'status', 'log', 'commit', 'add', 'rm', 'lsfiles', 'readblob', 'resolveref', 'branch', 'branches','checkout','currentbranch', 'zip', 'push', 'pull', 'setIpfsConfig','getItem','setItem', 'localStorageUsed'] 7 | } 8 | -------------------------------------------------------------------------------- /packages/plugin/vscode/src/lib/extension.ts: -------------------------------------------------------------------------------- 1 | import { ClientConnector } from "@remixproject/plugin" 2 | import { Message } from '@remixproject/plugin-utils' 3 | 4 | class ExtensionConnector implements ClientConnector { 5 | on(cb: (message: Partial) => void): void { 6 | throw new Error("Method not implemented.") 7 | } 8 | onMessage(message: Partial) { 9 | throw new Error('not implemented') 10 | } 11 | send() { 12 | throw new Error('not implemented') 13 | } 14 | } -------------------------------------------------------------------------------- /packages/utils/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/tools/event-name'; 2 | export * from './lib/tools/method-path'; 3 | export * from './lib/tools/service'; 4 | export * from './lib/tools/queue'; 5 | export * from './lib/types/api'; 6 | export * from './lib/types/message'; 7 | export * from './lib/types/plugin'; 8 | export * from './lib/types/profile'; 9 | export * from './lib/types/service'; 10 | export * from './lib/types/status'; 11 | export * from './lib/types/queue'; 12 | export * from './lib/types/options'; -------------------------------------------------------------------------------- /packages/api/src/lib/window/api.ts: -------------------------------------------------------------------------------- 1 | import { StatusEvents } from '@remixproject/plugin-utils' 2 | 3 | export interface IWindow { 4 | events: {} & StatusEvents 5 | methods: { 6 | /** Display an input window */ 7 | prompt(message?: string): string 8 | /** Ask confirmation for an action */ 9 | confirm(message: string): boolean 10 | /** Display a message with actions button. Returned the button clicked if any */ 11 | alert(message: string, actions?: string[]): string | void 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/example/engine/web-e2e/cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "fileServerFolder": ".", 3 | "fixturesFolder": "./src/fixtures", 4 | "integrationFolder": "./src/integration", 5 | "modifyObstructiveCode": false, 6 | "pluginsFile": "./src/plugins/index", 7 | "supportFile": "./src/support/index.ts", 8 | "video": true, 9 | "videosFolder": "../../../../dist/cypress/examples/example/engine/web-e2e/videos", 10 | "screenshotsFolder": "../../../../dist/cypress/examples/example/engine/web-e2e/screenshots", 11 | "chromeWebSecurity": false 12 | } 13 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Test", 9 | "type": "node", 10 | "request": "launch", 11 | "runtimeExecutable": "npm", 12 | "runtimeArgs": ["test"], 13 | "cwd": "${workspaceFolder}", 14 | "console": "internalConsole" 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /examples/example/plugin/webview-e2e/src/integration/app.spec.ts: -------------------------------------------------------------------------------- 1 | import { getGreeting } from '../support/app.po'; 2 | 3 | describe('example-plugin-webview', () => { 4 | beforeEach(() => cy.visit('/')); 5 | 6 | it('should display welcome message', () => { 7 | // Custom command example, see `../support/commands.ts` file 8 | cy.login('my-email@something.com', 'myPassword'); 9 | 10 | // Function helper example, see `../support/app.po.ts` file 11 | getGreeting().contains('Welcome to example-plugin-webview!'); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /examples/example/plugin/webview-e2e/cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "fileServerFolder": ".", 3 | "fixturesFolder": "./src/fixtures", 4 | "integrationFolder": "./src/integration", 5 | "modifyObstructiveCode": false, 6 | "pluginsFile": "./src/plugins/index", 7 | "supportFile": "./src/support/index.ts", 8 | "video": true, 9 | "videosFolder": "../../../../dist/cypress/examples/example/plugin/webview-e2e/videos", 10 | "screenshotsFolder": "../../../../dist/cypress/examples/example/plugin/webview-e2e/screenshots", 11 | "chromeWebSecurity": false 12 | } 13 | -------------------------------------------------------------------------------- /packages/plugin/webworker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/plugin-webworker", 3 | "version": "0.3.37", 4 | "homepage": "https://github.com/ethereum/remix-plugin/tree/master/packages/plugin/webworker#readme", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/ethereum/remix-plugin.git" 8 | }, 9 | "author": { 10 | "name": "GrandSchtroumpf", 11 | "email": "francois.guezengar@hotmail.fr" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/ethereum/remix-plugin/issues" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/api/src/lib/udapp/api.ts: -------------------------------------------------------------------------------- 1 | import { RemixTx, RemixTxReceipt, RemixTxEvent, VMAccount, UdappSettings } from './type' 2 | import { StatusEvents } from '@remixproject/plugin-utils' 3 | export interface IUdapp { 4 | events: { 5 | newTransaction: (transaction: RemixTxEvent) => void 6 | } & StatusEvents 7 | methods: { 8 | sendTransaction(tx: RemixTx): RemixTxReceipt 9 | getAccounts(): string[] 10 | createVMAccount(vmAccount: VMAccount): string 11 | getSettings(): UdappSettings 12 | setEnvironmentMode(env: 'vm' | 'injected' | 'web3'): void 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/**/*" 4 | ], 5 | "version": "0.3.5", 6 | "publishConfig": { 7 | "access": "public", 8 | "directory": "dist/packages" 9 | }, 10 | "command": { 11 | "version": { 12 | "message": "chore(version): bump version to %s", 13 | "yes": true, 14 | "noPush": true, 15 | "noGitTagVersion": true 16 | }, 17 | "publish": { 18 | "contents": "dist/packages", 19 | "message": "chore(release): publish version %s", 20 | "noPush": true, 21 | "noGitTagVersion": true 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/api/doc/settings.md: -------------------------------------------------------------------------------- 1 | # Settings 2 | 3 | - Name in Remix: `settings` 4 | - kind: `settings` 5 | 6 | |Type |Name |Description | 7 | |---------|-----------------------|------------| 8 | |_method_ |`getGithubAccessToken` |Returns the current Github Access Token provided in settings 9 | 10 | ## Examples 11 | 12 | ### Methods 13 | `getGithubAccessToken`: Returns the current Github Access Token provided in settings 14 | ```typescript 15 | const token = await client.call('settings', 'getGithubAccessToken') 16 | // OR 17 | const token = await client.settings.getGithubAccessToken() 18 | ``` -------------------------------------------------------------------------------- /packages/api/doc/compiler.md: -------------------------------------------------------------------------------- 1 | # Compile 2 | 3 | A plugin `compiler` compiles data into an Ethereum Virtual Machine readable bytecode and metadata. 4 | 5 | |Type |Name |Description | 6 | |---------|-----------------------|------------| 7 | |_method_ |`getCompilationResult` |Highlight a piece of code in the editor. 8 | |_method_ |`compile` |Remove the highlight triggered by this plugin. 9 | |_method_ |`setCompilerConfig` |Remove the highlight triggered by this plugin 10 | |_method_ |`compileWithParameters` |Add annotation ( info, warning, error ) at a line, column position with a text -------------------------------------------------------------------------------- /packages/api/doc/terminal.md: -------------------------------------------------------------------------------- 1 | # File System 2 | 3 | - Name in Remix: `terminal` 4 | 5 | |Type |Name |Description | 6 | |---------|-----------------------|------------| 7 | |_method_ |`log` |Log text to the terminal 8 | 9 | ## Examples 10 | 11 | ### Methods 12 | `log`: Get the name of the current file selected. 13 | ```typescript 14 | await client.terminal.log({ type: 'info', value: 'I am a string' }) 15 | // OR 16 | await client.call('terminal',{ type: 'info', value: 'I am a string' }) 17 | ``` 18 | 19 | 20 | > Type Definitions can be found [here](../src/lib/terminal/api.ts) 21 | -------------------------------------------------------------------------------- /packages/api/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/compiler' 2 | export * from './lib/content-import' 3 | export * from './lib/editor' 4 | export * from './lib/file-system/file-manager' 5 | export * from './lib/file-system/file-panel' 6 | export * from './lib/dgit' 7 | export * from './lib/git' 8 | export * from './lib/network' 9 | export * from './lib/plugin-manager' 10 | export * from './lib/settings' 11 | export * from './lib/theme' 12 | export * from './lib/udapp' 13 | export * from './lib/unit-testing' 14 | export * from './lib/window' 15 | 16 | export * from './lib/remix-profile' 17 | export * from './lib/standard-profile' 18 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/app/plugins/terminal.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Plugin } from '@remixproject/engine'; 3 | import { Engine } from '../engine'; 4 | import { Theme } from './theme'; 5 | 6 | @Injectable({ providedIn: 'root' }) 7 | export class Terminal extends Plugin { 8 | constructor(private engine: Engine) { 9 | super({ name: 'terminal' }) 10 | this.engine.register(this); 11 | } 12 | 13 | onActivation() { 14 | this.on('worker', 'log', (text) => console.log('Log', text)); 15 | } 16 | 17 | run(text: string) { 18 | this.call('worker', 'execute', text); 19 | } 20 | } -------------------------------------------------------------------------------- /packages/api/src/lib/network/api.ts: -------------------------------------------------------------------------------- 1 | import { StatusEvents } from '@remixproject/plugin-utils'; 2 | import { NetworkProvider, Network, CustomNetwork } from './type'; 3 | 4 | /** @deprecated: current version in Remix IDE. To improve to match standard JSON RPC methods */ 5 | export interface INetwork { 6 | events: { 7 | providerChanged: (provider: NetworkProvider) => void 8 | } & StatusEvents 9 | methods: { 10 | getNetworkProvider(): NetworkProvider 11 | detectNetwork(): Network | Partial 12 | getEndpoint(): string 13 | addNetwork(network: CustomNetwork): void 14 | removeNetwork(name: string): void 15 | } 16 | } -------------------------------------------------------------------------------- /packages/api/src/lib/network/type.ts: -------------------------------------------------------------------------------- 1 | /** @deprecated: current version in Remix IDE. To improve to match standard JSON RPC methods */ 2 | export interface CustomNetwork { 3 | id?: string 4 | name: string 5 | url: string 6 | } 7 | 8 | /** @deprecated: current version in Remix IDE. To improve to match standard JSON RPC methods */ 9 | export type NetworkProvider = 'vm' | 'injected' | 'web3' 10 | 11 | export type Network = 12 | | { id: '1', name: 'Main' } 13 | | { id: '2', name: 'Morden (deprecated)' } 14 | | { id: '3', name: 'Ropsten' } 15 | | { id: '4', name: 'Rinkeby' } 16 | | { id: '5', name: 'Goerli' } 17 | | { id: '42', name: 'Kovan' } -------------------------------------------------------------------------------- /packages/plugin/webview/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/plugin-webview", 3 | "version": "0.3.37", 4 | "homepage": "https://github.com/ethereum/remix-plugin/tree/master/packages/plugin/webview#readme", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/ethereum/remix-plugin.git" 8 | }, 9 | "author": { 10 | "name": "GrandSchtroumpf", 11 | "email": "francois.guezengar@hotmail.fr" 12 | }, 13 | "dependencies": { 14 | 15 | }, 16 | "bugs": { 17 | "url": "https://github.com/ethereum/remix-plugin/issues" 18 | }, 19 | "gitHead": "ca5c69be64ec4eaf7fe5d1d362726e75cb3b5726" 20 | } 21 | -------------------------------------------------------------------------------- /packages/engine/electron/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/engine-electron", 3 | "version": "0.3.37", 4 | "homepage": "https://github.com/ethereum/remix-plugin/tree/master/packages/engine/node#readme", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/ethereum/remix-plugin.git" 8 | }, 9 | "author": { 10 | "name": "bunsenstraat", 11 | "email": "filip.mertens@ethereum.org" 12 | }, 13 | "contributors": [ 14 | ], 15 | "bugs": { 16 | "url": "https://github.com/ethereum/remix-plugin/issues" 17 | }, 18 | "license": "MIT", 19 | "gitHead": "ca5c69be64ec4eaf7fe5d1d362726e75cb3b5726" 20 | } 21 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/app/plugins/window.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { WindowPlugin } from '@remixproject/engine-web'; 3 | import { Engine } from '../engine'; 4 | import { Theme } from './theme'; 5 | 6 | @Injectable({ providedIn: 'root' }) 7 | export class Window extends WindowPlugin { 8 | constructor(private engine: Engine,private theme: Theme) { 9 | super() 10 | this.engine.register(this); 11 | } 12 | 13 | async onActivation() { 14 | this.on('theme', 'themeChanged', (tx) => this.alert('themeChanged')); 15 | this.on('library', 'newTransaction', (tx) => this.alert('newTransaction')); 16 | } 17 | } -------------------------------------------------------------------------------- /examples/example/engine/web/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ExampleEngineWeb 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/engine/vscode/src/util/editor.ts: -------------------------------------------------------------------------------- 1 | import { TextEditor, window } from 'vscode'; 2 | 3 | export function getOpenedTextEditor() { 4 | if (!window.activeTextEditor) { 5 | return getTextEditorWithDocumentType('file'); 6 | } else { 7 | return window.activeTextEditor; 8 | } 9 | } 10 | 11 | export function getTextEditorWithDocumentType(type: string) { 12 | const editors: any[] = window.visibleTextEditors as any; 13 | const fileEditor: TextEditor = editors.find( 14 | (editor) => 15 | editor.document && 16 | editor.document.uri && 17 | editor.document.uri.scheme && 18 | editor.document.uri.scheme == type 19 | ); 20 | return fileEditor; 21 | } 22 | -------------------------------------------------------------------------------- /examples/example/engine/web-e2e/src/support/index.ts: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands'; 18 | -------------------------------------------------------------------------------- /packages/api/src/lib/editor/api.ts: -------------------------------------------------------------------------------- 1 | import { HighlightPosition, Annotation } from './type' 2 | import { StatusEvents } from '@remixproject/plugin-utils' 3 | import { HighLightOptions } from '@remixproject/plugin-api' 4 | 5 | export interface IEditor { 6 | events: StatusEvents 7 | methods: { 8 | highlight( 9 | position: HighlightPosition, 10 | filePath: string, 11 | hexColor: string, 12 | opt?: HighLightOptions 13 | ): void 14 | discardHighlight(): void 15 | discardHighlightAt(line: number, filePath: string): void 16 | addAnnotation(annotation: Annotation): void 17 | clearAnnotations(): void 18 | gotoLine(line:number, col:number): void 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /examples/example/plugin/webview-e2e/src/support/index.ts: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands'; 18 | -------------------------------------------------------------------------------- /packages/api/src/lib/file-system/file-panel/profile.ts: -------------------------------------------------------------------------------- 1 | import { IFilePanel as IFilePanel } from './api' 2 | import { LocationProfile, Profile } from '@remixproject/plugin-utils' 3 | 4 | export const filePanelProfile: Profile & LocationProfile = { 5 | name: "filePanel", 6 | displayName: "File explorers", 7 | description: "Provides communication between remix file explorers and remix-plugin", 8 | location: "sidePanel", 9 | documentation: "", 10 | version: "0.0.1", 11 | methods: ['getCurrentWorkspace', 'getWorkspaces', 'createWorkspace', 'registerContextMenuItem', 'renameWorkspace', 'deleteWorkspace'], 12 | events: ['setWorkspace', 'workspaceRenamed', 'workspaceDeleted', 'workspaceCreated'], 13 | }; -------------------------------------------------------------------------------- /packages/api/src/lib/plugin-manager/api.ts: -------------------------------------------------------------------------------- 1 | import { StatusEvents, Profile } from '@remixproject/plugin-utils' 2 | 3 | export interface IPluginManager { 4 | events: { 5 | profileUpdated(profile: Profile): void 6 | profileAdded(profile: Profile): void 7 | pluginDeactivated(profile: Profile): void 8 | pluginActivated(profile: Profile): void 9 | } & StatusEvents 10 | methods: { 11 | getProfile(name: string): Promise 12 | updateProfile(profile: Partial): any 13 | activatePlugin(name: string): any 14 | deactivatePlugin(name: string): any 15 | isActive(name: string): boolean 16 | canCall(from: string, to: string, method: string, message?: string): any 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /.cache 7 | /out-tsc 8 | 9 | # dependencies 10 | /node_modules 11 | 12 | # IDEs and editors 13 | /.idea 14 | .project 15 | .classpath 16 | .c9/ 17 | *.launch 18 | .settings/ 19 | *.sublime-workspace 20 | 21 | # IDE - VSCode 22 | .vscode/* 23 | !.vscode/settings.json 24 | !.vscode/tasks.json 25 | !.vscode/launch.json 26 | !.vscode/extensions.json 27 | 28 | # misc 29 | /.sass-cache 30 | /connect.lock 31 | /coverage 32 | /libpeerconnection.log 33 | npm-debug.log 34 | yarn-error.log 35 | testem.log 36 | /typings 37 | 38 | # System Files 39 | .DS_Store 40 | Thumbs.db 41 | remixplugin.code-workspace 42 | -------------------------------------------------------------------------------- /examples/example/plugin/webview/src/app/client.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | import { PluginClient } from '@remixproject/plugin'; 3 | import { createClient } from '@remixproject/plugin-webview'; 4 | 5 | export class Client extends PluginClient { 6 | methods = ['execute']; 7 | constructor() { 8 | super({ customTheme: true }) 9 | } 10 | 11 | execute(value: string) { 12 | this.emit('localEvent', value) 13 | } 14 | 15 | onActivation() { 16 | this.on('theme', 'themeChanged', theme => console.log('theme', theme)); 17 | } 18 | } 19 | 20 | export const CLIENT = new InjectionToken('Remix Clinet', { 21 | providedIn: 'root', 22 | factory: () => createClient(new Client()) 23 | }); -------------------------------------------------------------------------------- /packages/api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/plugin-api", 3 | "version": "0.3.37", 4 | "homepage": "https://github.com/ethereum/remix-plugin/tree/master/packages/api#readme", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/ethereum/remix-plugin.git" 8 | }, 9 | "author": { 10 | "name": "GrandSchtroumpf", 11 | "email": "francois.guezengar@hotmail.fr" 12 | }, 13 | "contributors": [ 14 | { 15 | "name": "Yann Levreau", 16 | "email": "yann@ethdev.com" 17 | } 18 | ], 19 | "bugs": { 20 | "url": "https://github.com/ethereum/remix-plugin/issues" 21 | }, 22 | "license": "MIT", 23 | "gitHead": "ca5c69be64ec4eaf7fe5d1d362726e75cb3b5726" 24 | } 25 | -------------------------------------------------------------------------------- /packages/engine/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/engine", 3 | "version": "0.3.37", 4 | "homepage": "https://github.com/ethereum/remix-plugin/tree/master/packages/engine/core#readme", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/ethereum/remix-plugin.git" 8 | }, 9 | "author": { 10 | "name": "GrandSchtroumpf", 11 | "email": "francois.guezengar@hotmail.fr" 12 | }, 13 | "contributors": [ 14 | { 15 | "name": "Yann Levreau", 16 | "email": "yann@ethdev.com" 17 | } 18 | ], 19 | "bugs": { 20 | "url": "https://github.com/ethereum/remix-plugin/issues" 21 | }, 22 | "license": "MIT", 23 | "gitHead": "ca5c69be64ec4eaf7fe5d1d362726e75cb3b5726" 24 | } 25 | -------------------------------------------------------------------------------- /packages/engine/web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/engine-web", 3 | "version": "0.3.37", 4 | "homepage": "https://github.com/ethereum/remix-plugin/tree/master/packages/engine/web#readme", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/ethereum/remix-plugin.git" 8 | }, 9 | "author": { 10 | "name": "GrandSchtroumpf", 11 | "email": "francois.guezengar@hotmail.fr" 12 | }, 13 | "contributors": [ 14 | { 15 | "name": "Yann Levreau", 16 | "email": "yann@ethdev.com" 17 | } 18 | ], 19 | "bugs": { 20 | "url": "https://github.com/ethereum/remix-plugin/issues" 21 | }, 22 | "license": "MIT", 23 | "gitHead": "ca5c69be64ec4eaf7fe5d1d362726e75cb3b5726" 24 | } 25 | -------------------------------------------------------------------------------- /packages/engine/node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/engine-node", 3 | "version": "0.3.37", 4 | "homepage": "https://github.com/ethereum/remix-plugin/tree/master/packages/engine/node#readme", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/ethereum/remix-plugin.git" 8 | }, 9 | "author": { 10 | "name": "GrandSchtroumpf", 11 | "email": "francois.guezengar@hotmail.fr" 12 | }, 13 | "contributors": [ 14 | { 15 | "name": "Yann Levreau", 16 | "email": "yann@ethdev.com" 17 | } 18 | ], 19 | "bugs": { 20 | "url": "https://github.com/ethereum/remix-plugin/issues" 21 | }, 22 | "license": "MIT", 23 | "gitHead": "ca5c69be64ec4eaf7fe5d1d362726e75cb3b5726" 24 | } 25 | -------------------------------------------------------------------------------- /packages/engine/vscode/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/engine-vscode", 3 | "version": "0.3.37", 4 | "homepage": "https://github.com/ethereum/remix-plugin/tree/master/packages/engine/vscode#readme", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/ethereum/remix-plugin.git" 8 | }, 9 | "author": { 10 | "name": "GrandSchtroumpf", 11 | "email": "francois.guezengar@hotmail.fr" 12 | }, 13 | "contributors": [ 14 | { 15 | "name": "Yann Levreau", 16 | "email": "yann@ethdev.com" 17 | } 18 | ], 19 | "bugs": { 20 | "url": "https://github.com/ethereum/remix-plugin/issues" 21 | }, 22 | "license": "MIT", 23 | "gitHead": "ca5c69be64ec4eaf7fe5d1d362726e75cb3b5726" 24 | } 25 | -------------------------------------------------------------------------------- /packages/plugin/iframe/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/plugin-iframe", 3 | "version": "0.3.37", 4 | "homepage": "https://github.com/ethereum/remix-plugin/tree/master/packages/plugin/iframe#readme", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/ethereum/remix-plugin.git" 8 | }, 9 | "author": { 10 | "name": "GrandSchtroumpf", 11 | "email": "francois.guezengar@hotmail.fr" 12 | }, 13 | "contributors": [ 14 | { 15 | "name": "Yann Levreau", 16 | "email": "yann@ethdev.com" 17 | } 18 | ], 19 | "bugs": { 20 | "url": "https://github.com/ethereum/remix-plugin/issues" 21 | }, 22 | "license": "MIT", 23 | "gitHead": "ca5c69be64ec4eaf7fe5d1d362726e75cb3b5726" 24 | } 25 | -------------------------------------------------------------------------------- /packages/plugin/vscode/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/plugin-vscode", 3 | "version": "0.3.37", 4 | "homepage": "https://github.com/ethereum/remix-plugin/tree/master/packages/plugin/vscode#readme", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/ethereum/remix-plugin.git" 8 | }, 9 | "author": { 10 | "name": "GrandSchtroumpf", 11 | "email": "francois.guezengar@hotmail.fr" 12 | }, 13 | "contributors": [ 14 | { 15 | "name": "Yann Levreau", 16 | "email": "yann@ethdev.com" 17 | } 18 | ], 19 | "bugs": { 20 | "url": "https://github.com/ethereum/remix-plugin/issues" 21 | }, 22 | "license": "MIT", 23 | "gitHead": "ca5c69be64ec4eaf7fe5d1d362726e75cb3b5726" 24 | } 25 | -------------------------------------------------------------------------------- /packages/api/doc/editor.md: -------------------------------------------------------------------------------- 1 | # Editor 2 | 3 | - Name in Remix: `editor` 4 | - kind: `editor` 5 | 6 | |Type |Name |Description | 7 | |---------|-----------------------|------------| 8 | |_method_ |`highlight` |Highlight a piece of code in the editor. 9 | |_method_ |`discardHighlight` |Remove the highlight triggered by this plugin. 10 | |_method_ |`discardHighlightAt` |Remove the highlight triggered by this plugin 11 | |_method_ |`addAnnotation` |Add annotation ( info, warning, error ) at a line, column position with a text 12 | |_method_ |`clearAnnotations` | 13 | 14 | 15 | > Method Definitions can be found [here](../src/lib/editor/api.ts) 16 | 17 | > Type Definitions can be found [here](../src/lib/editor/type.ts) -------------------------------------------------------------------------------- /packages/plugin/electron/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/plugin-electron", 3 | "version": "0.3.37", 4 | "homepage": "https://github.com/ethereum/remix-plugin/tree/master/packages/plugin/iframe#readme", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/ethereum/remix-plugin.git" 8 | }, 9 | "author": { 10 | "name": "GrandSchtroumpf", 11 | "email": "francois.guezengar@hotmail.fr" 12 | }, 13 | "contributors": [ 14 | { 15 | "name": "Yann Levreau", 16 | "email": "yann@ethdev.com" 17 | } 18 | ], 19 | "bugs": { 20 | "url": "https://github.com/ethereum/remix-plugin/issues" 21 | }, 22 | "license": "MIT", 23 | "gitHead": "ca5c69be64ec4eaf7fe5d1d362726e75cb3b5726" 24 | } 25 | -------------------------------------------------------------------------------- /packages/plugin/ws/README.md: -------------------------------------------------------------------------------- 1 | # Plugin ws 2 | This library is a connector that connects a node server to using the `ws` library to the engine. 3 | 4 | If you do not expose any API you can create an instance like this : 5 | ```typescript 6 | const wss = new WebSocket.Server({ port: 8080 }); 7 | wss.on('connection', (ws) => { 8 | const client = createClient(ws) 9 | }) 10 | ``` 11 | 12 | If you need to expose an API to other plugin you need to extends the class: 13 | ```typescript 14 | class MyPlugin extends PluginClient { 15 | methods = ['hello'] 16 | hello() { 17 | console.log('Hello World') 18 | } 19 | } 20 | const wss = new WebSocket.Server({ port: 8080 }); 21 | wss.on('connection', (ws) => { 22 | const client = createClient(ws, new MyPlugin()) 23 | }) 24 | ``` -------------------------------------------------------------------------------- /packages/plugin/child-process/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/plugin-child-process", 3 | "version": "0.3.37", 4 | "homepage": "https://github.com/ethereum/remix-plugin/tree/master/packages/plugin/child_process#readme", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/ethereum/remix-plugin.git" 8 | }, 9 | "author": { 10 | "name": "GrandSchtroumpf", 11 | "email": "francois.guezengar@hotmail.fr" 12 | }, 13 | "contributors": [ 14 | { 15 | "name": "Yann Levreau", 16 | "email": "yann@ethdev.com" 17 | } 18 | ], 19 | "bugs": { 20 | "url": "https://github.com/ethereum/remix-plugin/issues" 21 | }, 22 | "license": "MIT", 23 | "gitHead": "ca5c69be64ec4eaf7fe5d1d362726e75cb3b5726" 24 | } 25 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false, 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /examples/example/plugin/webview/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false, 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/assets/web.worker.js: -------------------------------------------------------------------------------- 1 | // cannot import plugin-webworker because I would need to be inside typescript compiler 2 | // Angular fails at importing WebworkerPlugin for some reason 3 | 4 | addEventListener('message', ({ data }) => { 5 | if (data.key === 'execute') { 6 | const [script] = data.payload; 7 | try { 8 | (new Function(script))() 9 | } catch (e) { 10 | this.emit('error', { 11 | data: [e.message] 12 | }) 13 | } 14 | } 15 | if (data.key === 'handshake') { 16 | data.action = 'response' 17 | data.payload = ['execute'] 18 | postMessage(data) 19 | } 20 | }); 21 | 22 | 23 | console.log = function () { 24 | postMessage({ action: 'emit', key: 'log', payload: [{data: Array.from(arguments)}]}); 25 | } 26 | -------------------------------------------------------------------------------- /packages/api/doc/solidity.md: -------------------------------------------------------------------------------- 1 | # Solidity Compiler 2 | 3 | - Name in Remix: `solidity` 4 | - kind: `compiler` 5 | 6 | 7 | |Type |Name |Description | 8 | |---------|-----------------------|------------| 9 | |_event_ |`compilationFinished` |Triggered when a compilation finishes. 10 | |_method_ |`getCompilationResult` |Get the current result of the compilation. 11 | |_method_ |`compile` |Run solidity compiler with a file. 12 | |_method_ |`compileWithParameters`|Run solidity compiler with a map of source files and settings 13 | |_method_ |`setCompilerConfig`|Set settings for the compiler, see types for more info 14 | 15 | 16 | > Method Definitions can be found [here](../src/lib/compiler/api.ts) 17 | 18 | > Type Definitions can be found [here](../src/lib/compiler/type) -------------------------------------------------------------------------------- /packages/utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/plugin-utils", 3 | "version": "0.3.37", 4 | "dependencies": { 5 | "tslib": "2.0.1" 6 | }, 7 | "homepage": "https://github.com/ethereum/remix-plugin/tree/master/packages/utils#readme", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/ethereum/remix-plugin.git" 11 | }, 12 | "author": { 13 | "name": "GrandSchtroumpf", 14 | "email": "francois.guezengar@hotmail.fr" 15 | }, 16 | "contributors": [ 17 | { 18 | "name": "Yann Levreau", 19 | "email": "yann@ethdev.com" 20 | } 21 | ], 22 | "bugs": { 23 | "url": "https://github.com/ethereum/remix-plugin/issues" 24 | }, 25 | "license": "MIT", 26 | "gitHead": "ca5c69be64ec4eaf7fe5d1d362726e75cb3b5726" 27 | } 28 | -------------------------------------------------------------------------------- /packages/utils/tests/method-path.spec.ts: -------------------------------------------------------------------------------- 1 | import { getMethodPath, getRootPath } from '../src' 2 | 3 | describe('Get Method Path', () => { 4 | test('call event', () => { 5 | expect(getMethodPath('call')).toEqual('call') 6 | expect(getMethodPath('call', '')).toEqual('call') 7 | expect(getMethodPath('call', 'remixd')).toEqual('call') 8 | expect(getMethodPath('call', 'remixd.cmd')).toEqual('cmd.call') 9 | expect(getMethodPath('call', 'remixd.cmd.git')).toEqual('cmd.git.call') 10 | }) 11 | 12 | }) 13 | 14 | describe('Get Root Path', () => { 15 | test('Get root', () => { 16 | expect(getRootPath('remixd')).toEqual('remixd') 17 | expect(getRootPath('remixd.cmd')).toEqual('remixd') 18 | expect(getRootPath('remixd.cmd.git')).toEqual('remixd') 19 | }) 20 | 21 | }) 22 | -------------------------------------------------------------------------------- /packages/plugin/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/plugin", 3 | "version": "0.3.37", 4 | "dependencies": { 5 | "events": "3.2.0" 6 | }, 7 | "homepage": "https://github.com/ethereum/remix-plugin/tree/master/packages/plugin/core#readme", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/ethereum/remix-plugin.git" 11 | }, 12 | "author": { 13 | "name": "GrandSchtroumpf", 14 | "email": "francois.guezengar@hotmail.fr" 15 | }, 16 | "contributors": [ 17 | { 18 | "name": "Yann Levreau", 19 | "email": "yann@ethdev.com" 20 | } 21 | ], 22 | "bugs": { 23 | "url": "https://github.com/ethereum/remix-plugin/issues" 24 | }, 25 | "license": "MIT", 26 | "gitHead": "ca5c69be64ec4eaf7fe5d1d362726e75cb3b5726" 27 | } 28 | -------------------------------------------------------------------------------- /packages/plugin/ws/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remixproject/plugin-ws", 3 | "version": "0.3.37", 4 | "peerDependencies": { 5 | "ws": "^7.3.1" 6 | }, 7 | "homepage": "https://github.com/ethereum/remix-plugin/tree/master/packages/plugin/ws#readme", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/ethereum/remix-plugin.git" 11 | }, 12 | "author": { 13 | "name": "GrandSchtroumpf", 14 | "email": "francois.guezengar@hotmail.fr" 15 | }, 16 | "contributors": [ 17 | { 18 | "name": "Yann Levreau", 19 | "email": "yann@ethdev.com" 20 | } 21 | ], 22 | "bugs": { 23 | "url": "https://github.com/ethereum/remix-plugin/issues" 24 | }, 25 | "license": "MIT", 26 | "gitHead": "ca5c69be64ec4eaf7fe5d1d362726e75cb3b5726" 27 | } 28 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/app/terminal/terminal.component.ts: -------------------------------------------------------------------------------- 1 | import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; 2 | import { FormControl } from '@angular/forms'; 3 | import { Manager, Terminal } from '../plugins'; 4 | 5 | @Component({ 6 | selector: 'engine-terminal', 7 | templateUrl: './terminal.component.html', 8 | styleUrls: ['./terminal.component.scss'], 9 | changeDetection: ChangeDetectionStrategy.OnPush 10 | }) 11 | export class TerminalComponent { 12 | form = new FormControl(); 13 | constructor( 14 | private manager: Manager, 15 | private terminal: Terminal 16 | ) { } 17 | 18 | async submit() { 19 | await this.manager.activatePlugin('terminal'); 20 | this.terminal.run(this.form.value); 21 | this.form.reset(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | projects: [ 3 | '/packages/engine/core', 4 | '/packages/engine/node', 5 | '/packages/engine/web', 6 | '/packages/engine/vscode', 7 | '/packages/utils', 8 | '/packages/api', 9 | '/packages/plugin/core', 10 | '/packages/plugin/iframe', 11 | '/packages/plugin/vscode', 12 | '/packages/plugin/child-process', 13 | '/packages/plugin/ws', 14 | '/packages/plugin/webview', 15 | '/examples/example/engine/web', 16 | '/examples/example/plugin/webview', 17 | '/packages/plugin/webworker', 18 | '/packages/plugin/theia', 19 | '/packages/engine/theia', 20 | ], 21 | }; 22 | -------------------------------------------------------------------------------- /packages/api/src/lib/compiler/api.ts: -------------------------------------------------------------------------------- 1 | import { CompilationResult, CompilationFileSources, lastCompilationResult, CondensedCompilationInput, SourcesInput } from './type' 2 | import { StatusEvents, Api } from '@remixproject/plugin-utils' 3 | 4 | export interface ICompiler extends Api { 5 | events: { 6 | compilationFinished: ( 7 | fileName: string, 8 | source: CompilationFileSources, 9 | languageVersion: string, 10 | data: CompilationResult 11 | ) => void 12 | } & StatusEvents 13 | methods: { 14 | getCompilationResult(): lastCompilationResult 15 | compile(fileName: string): void 16 | setCompilerConfig(settings: CondensedCompilationInput): void 17 | compileWithParameters(targets: SourcesInput, settings: CondensedCompilationInput): lastCompilationResult 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/engine/web/src/lib/view.ts: -------------------------------------------------------------------------------- 1 | import type { Profile, LocationProfile } from '@remixproject/plugin-utils' 2 | import { Plugin } from '@remixproject/engine' 3 | 4 | 5 | export function isView

(profile: Profile): profile is (ViewProfile & P) { 6 | return !!profile['location'] 7 | } 8 | 9 | export type ViewProfile = Profile & LocationProfile 10 | 11 | export abstract class ViewPlugin extends Plugin { 12 | abstract render(): any 13 | 14 | constructor(public profile: ViewProfile) { 15 | super(profile) 16 | } 17 | 18 | async activate() { 19 | await this.call(this.profile.location, 'addView', this.profile, this.render()) 20 | super.activate() 21 | } 22 | 23 | deactivate() { 24 | this.call(this.profile.location, 'removeView', this.profile) 25 | super.deactivate() 26 | } 27 | } -------------------------------------------------------------------------------- /packages/engine/vscode/src/lib/appmanager.ts: -------------------------------------------------------------------------------- 1 | import { PluginManager } from "@remixproject/engine" 2 | import axios from 'axios' 3 | export class VscodeAppManager extends PluginManager { 4 | pluginsDirectory:string 5 | target:string 6 | constructor () { 7 | super() 8 | this.pluginsDirectory = 'https://raw.githubusercontent.com/ethereum/remix-plugins-directory/master/build/metadata.json' 9 | this.target = "vscode" 10 | } 11 | 12 | async registeredPluginData () { 13 | let plugins 14 | try { 15 | plugins = await axios.get(this.pluginsDirectory) 16 | return plugins.data.filter((p:any)=>(p.targets && p.targets.includes(this.target))) 17 | } catch (e) { 18 | throw new Error("Could not fetch plugin profiles.") 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /packages/utils/src/lib/types/message.ts: -------------------------------------------------------------------------------- 1 | export interface PluginRequest { 2 | /** The name of the plugin making the request */ 3 | from: string, 4 | /** @deprecated Will be remove in the next version */ 5 | isFromNative?: boolean, 6 | /** 7 | * The path to access the request inside the plugin 8 | * @example 'remixd.cmd.git' 9 | */ 10 | path?: string 11 | } 12 | 13 | type MessageActions = 'on' | 'off' | 'once' | 'call' | 'response' | 'emit' | 'cancel' 14 | 15 | /** @deprecated Use `MessageAcitons` instead */ 16 | type OldMessageActions = 'notification' | 'request' | 'response' | 'listen' 17 | 18 | export interface Message { 19 | id: number 20 | action: MessageActions | OldMessageActions 21 | name: string 22 | key: string 23 | payload: any 24 | requestInfo: PluginRequest 25 | error?: Error | string 26 | } 27 | -------------------------------------------------------------------------------- /packages/api/src/lib/file-system/file-panel/api.ts: -------------------------------------------------------------------------------- 1 | import { StatusEvents } from '@remixproject/plugin-utils' 2 | import { customAction } from './type'; 3 | export interface IFilePanel { 4 | events: { 5 | setWorkspace: (workspace:any) => void 6 | workspaceRenamed: (workspace:any) => void 7 | workspaceDeleted: (workspace:any) => void 8 | workspaceCreated: (workspace:any) => void 9 | customAction: (cmd: customAction) => void 10 | } & StatusEvents 11 | methods: { 12 | getCurrentWorkspace(): { name: string, isLocalhost: boolean, absolutePath: string } 13 | getWorkspaces(): string[] 14 | deleteWorkspace(name:string): void 15 | createWorkspace(name:string, isEmpty:boolean): void 16 | renameWorkspace(oldName:string, newName:string): void 17 | registerContextMenuItem(cmd: customAction): void 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |

17 | 18 |
19 |
20 |
21 | 22 |
23 |
-------------------------------------------------------------------------------- /examples/example/engine/web/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | displayName: 'example-engine-web', 3 | preset: '../../../../jest.preset.js', 4 | setupFilesAfterEnv: ['/src/test-setup.ts'], 5 | globals: { 6 | 'ts-jest': { 7 | tsConfig: '/tsconfig.spec.json', 8 | stringifyContentPathRegex: '\\.(html|svg)$', 9 | astTransformers: { 10 | before: [ 11 | 'jest-preset-angular/build/InlineFilesTransformer', 12 | 'jest-preset-angular/build/StripStylesTransformer', 13 | ], 14 | }, 15 | }, 16 | }, 17 | coverageDirectory: '../../../../coverage/examples/example/engine/web', 18 | snapshotSerializers: [ 19 | 'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js', 20 | 'jest-preset-angular/build/AngularSnapshotSerializer.js', 21 | 'jest-preset-angular/build/HTMLCommentSerializer.js', 22 | ], 23 | }; 24 | -------------------------------------------------------------------------------- /examples/example/plugin/webview/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | displayName: 'example-plugin-webview', 3 | preset: '../../../../jest.preset.js', 4 | setupFilesAfterEnv: ['/src/test-setup.ts'], 5 | globals: { 6 | 'ts-jest': { 7 | tsConfig: '/tsconfig.spec.json', 8 | stringifyContentPathRegex: '\\.(html|svg)$', 9 | astTransformers: { 10 | before: [ 11 | 'jest-preset-angular/build/InlineFilesTransformer', 12 | 'jest-preset-angular/build/StripStylesTransformer', 13 | ], 14 | }, 15 | }, 16 | }, 17 | coverageDirectory: '../../../../coverage/examples/example/plugin/webview', 18 | snapshotSerializers: [ 19 | 'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js', 20 | 'jest-preset-angular/build/AngularSnapshotSerializer.js', 21 | 'jest-preset-angular/build/HTMLCommentSerializer.js', 22 | ], 23 | }; 24 | -------------------------------------------------------------------------------- /packages/api/src/lib/theme/types.ts: -------------------------------------------------------------------------------- 1 | export interface Theme { 2 | url?: string 3 | /** @deprecated Use brightness instead */ 4 | quality?: 'dark' | 'light' 5 | brightness: 'dark' | 'light' 6 | colors: { 7 | surface: string 8 | background: string 9 | foreground: string 10 | primary: string 11 | primaryContrast: string 12 | secondary?: string 13 | secondaryContrast?: string 14 | success?: string 15 | successContrast?: string 16 | warn: string 17 | warnContrast: string 18 | error: string 19 | errorContrast: string 20 | disabled: string 21 | } 22 | breakpoints: { 23 | xs: number 24 | sm: number 25 | md: number 26 | lg: number 27 | xl: number 28 | } 29 | fontFamily: string 30 | /** A unit to multiply for margin & padding */ 31 | space: number 32 | } 33 | 34 | export interface ThemeUrls { 35 | light: string; 36 | dark: string; 37 | } 38 | -------------------------------------------------------------------------------- /examples/example/engine/web/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | not IE 9-10 # Angular support for IE 9-10 has been deprecated and will be removed as of Angular v11. To opt-in, remove the 'not' prefix on this line. 18 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 19 | -------------------------------------------------------------------------------- /packages/engine/web/src/lib/host.ts: -------------------------------------------------------------------------------- 1 | import type { Profile } from '@remixproject/plugin-utils' 2 | import { Plugin } from '@remixproject/engine' 3 | 4 | // @todo(#250): move this into engine-web 5 | export abstract class HostPlugin extends Plugin { 6 | 7 | constructor(profile: Profile) { 8 | // Remove duplicated if needed 9 | const methods = Array.from(new Set([ 10 | ...(profile.methods || []), 11 | 'currentFocus', 'focus', 'addView', 'removeView' 12 | ])) 13 | super({...profile, methods }) 14 | } 15 | 16 | /** Give the name of the current focus plugin */ 17 | abstract currentFocus(): string 18 | 19 | /** Display the view inside the host */ 20 | abstract focus(name: string): void 21 | 22 | /** Add the view of a plugin into the DOM */ 23 | abstract addView(profile: Profile, view: Element): void 24 | 25 | /** Remove the plugin from the view from the DOM */ 26 | abstract removeView(profile: Profile): void 27 | } -------------------------------------------------------------------------------- /examples/example/plugin/webview/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | not IE 9-10 # Angular support for IE 9-10 has been deprecated and will be removed as of Angular v11. To opt-in, remove the 'not' prefix on this line. 18 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 19 | -------------------------------------------------------------------------------- /examples/example/engine/web-e2e/src/plugins/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example plugins/index.js can be used to load plugins 3 | // 4 | // You can change the location of this file or turn off loading 5 | // the plugins file with the 'pluginsFile' configuration option. 6 | // 7 | // You can read more here: 8 | // https://on.cypress.io/plugins-guide 9 | // *********************************************************** 10 | 11 | // This function is called when a project is opened or re-opened (e.g. due to 12 | // the project's config changing) 13 | 14 | const { preprocessTypescript } = require('@nrwl/cypress/plugins/preprocessor'); 15 | 16 | module.exports = (on, config) => { 17 | // `on` is used to hook into various events Cypress emits 18 | // `config` is the resolved Cypress config 19 | 20 | // Preprocess Typescript file using Nx helper 21 | on('file:preprocessor', preprocessTypescript(config)); 22 | }; 23 | -------------------------------------------------------------------------------- /examples/example/plugin/webview-e2e/src/plugins/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example plugins/index.js can be used to load plugins 3 | // 4 | // You can change the location of this file or turn off loading 5 | // the plugins file with the 'pluginsFile' configuration option. 6 | // 7 | // You can read more here: 8 | // https://on.cypress.io/plugins-guide 9 | // *********************************************************** 10 | 11 | // This function is called when a project is opened or re-opened (e.g. due to 12 | // the project's config changing) 13 | 14 | const { preprocessTypescript } = require('@nrwl/cypress/plugins/preprocessor'); 15 | 16 | module.exports = (on, config) => { 17 | // `on` is used to hook into various events Cypress emits 18 | // `config` is the resolved Cypress config 19 | 20 | // Preprocess Typescript file using Nx helper 21 | on('file:preprocessor', preprocessTypescript(config)); 22 | }; 23 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | import { ReactiveFormsModule } from '@angular/forms'; 4 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 5 | 6 | import { AppComponent } from './app.component'; 7 | import { HostDirective } from './host.directive'; 8 | import { TerminalComponent } from './terminal/terminal.component'; 9 | 10 | // Material 11 | import { MatListModule } from '@angular/material/list'; 12 | import { MatIconModule } from '@angular/material/icon'; 13 | 14 | @NgModule({ 15 | declarations: [ 16 | AppComponent, 17 | HostDirective, 18 | TerminalComponent 19 | ], 20 | imports: [ 21 | BrowserModule, 22 | ReactiveFormsModule, 23 | BrowserAnimationsModule, 24 | MatListModule, 25 | MatIconModule 26 | ], 27 | providers: [], 28 | bootstrap: [AppComponent], 29 | }) 30 | export class AppModule {} 31 | -------------------------------------------------------------------------------- /packages/plugin/iframe/src/lib/theme.ts: -------------------------------------------------------------------------------- 1 | import { PluginClient, PluginOptions } from '@remixproject/plugin' 2 | import { Theme } from "@remixproject/plugin-api" 3 | 4 | /** Start listening on theme changed */ 5 | export async function listenOnThemeChanged(client: PluginClient, options?: Partial>) { 6 | if (options && options.customTheme) return 7 | const cssLink = document.createElement('link') 8 | cssLink.setAttribute('rel', 'stylesheet') 9 | document.head.prepend(cssLink) 10 | client.onload(async () => { 11 | client.on('theme', 'themeChanged', (_theme: Theme) => setTheme(cssLink, _theme)) 12 | const theme = await client.call('theme', 'currentTheme') 13 | setTheme(cssLink, theme) 14 | }) 15 | return cssLink 16 | } 17 | 18 | 19 | function setTheme(cssLink: HTMLLinkElement, theme: Theme) { 20 | cssLink.setAttribute('href', theme.url.replace(/^http:/,"").replace(/^https:/,"")) 21 | document.documentElement.style.setProperty('--theme', theme.quality) 22 | } 23 | -------------------------------------------------------------------------------- /packages/plugin/core/src/lib/node.ts: -------------------------------------------------------------------------------- 1 | import { PluginClient } from "./client" 2 | import { getRootPath } from '@remixproject/plugin-utils' 3 | 4 | /** 5 | * Access a service of an external plugin 6 | */ 7 | export class PluginNode { 8 | 9 | /** 10 | * @param path Path to external plugin 11 | * @param client The main client used in this plugin 12 | */ 13 | constructor(private path: string, private client: PluginClient) {} 14 | 15 | get(name: string) { 16 | return new PluginNode(`${this.path}.${name}`, this.client) 17 | } 18 | 19 | /** Call a method of the node */ 20 | call(method: string, ...payload: any[]) { 21 | return this.client.call(this.path as any, method, payload) 22 | } 23 | 24 | /** 25 | * Listen to an event from the plugin 26 | * @note Event are trigger at the root level yet, not on a specific node 27 | */ 28 | on(method: string, cb: Function) { 29 | // Events are triggered at the root level for now 30 | this.client.on(getRootPath(this.path) as any, method, cb) 31 | } 32 | } -------------------------------------------------------------------------------- /packages/engine/vscode/src/util/path.ts: -------------------------------------------------------------------------------- 1 | import { join, relative } from 'path' 2 | import { workspace, } from 'vscode' 3 | 4 | export function absolutePath(path: string) { 5 | path = path.replace(/^\/browser\//,"").replace(/^browser\//,"") 6 | const root = workspace.workspaceFolders[0].uri.fsPath 7 | // vscode API will never get permission to WriteFile outside of its workspace directory 8 | if(!root) { 9 | return path 10 | } 11 | if(path.startsWith(root)) { 12 | path = relative(root, path) 13 | } 14 | const result = join(root, path) 15 | if (!result.startsWith(root)) { 16 | throw new Error(`Resolved path is should be inside the open workspace : "${root}". Got "${result}`) 17 | } 18 | return result 19 | } 20 | 21 | export function relativePath(path) { 22 | const root = workspace.workspaceFolders[0].uri.fsPath 23 | // vscode API will never get permission to WriteFile outside of its workspace directory 24 | if (!root) { 25 | return path 26 | } 27 | return relative(root, path) 28 | } 29 | 30 | -------------------------------------------------------------------------------- /packages/plugin/core/tests/node.spec.ts: -------------------------------------------------------------------------------- 1 | import { PluginClient } from '@remixproject/plugin' 2 | import { PluginNode } from '../src' 3 | 4 | class MockClient extends PluginClient { 5 | call = jest.fn() 6 | on = jest.fn() 7 | } 8 | 9 | describe('Plugin node', () => { 10 | let client: MockClient 11 | let node: PluginNode 12 | beforeEach(() => { 13 | client = new MockClient() 14 | node = new PluginNode('external', client) 15 | }) 16 | 17 | test('Get', () => { 18 | const deepNode = node.get('service') 19 | expect(deepNode['path']).toBe('external.service') 20 | expect(deepNode instanceof PluginNode).toBeTruthy() 21 | }) 22 | 23 | test('Call', () => { 24 | node.get('service').call('method', 'payload') 25 | expect(client.call).toHaveBeenCalledWith('external.service', 'method', ['payload']) 26 | }) 27 | 28 | test('On', () => { 29 | node.get('service').on('method', () => {}) 30 | expect(client.on.mock.calls[0][0]).toBe('external') 31 | expect(client.on.mock.calls[0][1]).toBe('method') 32 | }) 33 | 34 | }) -------------------------------------------------------------------------------- /packages/plugin/webview/README.md: -------------------------------------------------------------------------------- 1 | # Plugin Webview 2 | 3 | This library provides connectors to connect a plugin to an engine that can load webview or iframes. 4 | ``` 5 | npm install @remixproject/plugin-webview 6 | ``` 7 | 8 | If you do not expose any API you can create an instance like this : 9 | ```typescript 10 | import { createClient } from '@remixproject/plugin-webview' 11 | 12 | const client = createClient() 13 | client.onload(async () => { 14 | const data = client.call('filemanager', 'readFile', 'ballot.sol') 15 | }) 16 | ``` 17 | 18 | If you need to expose an API to other plugin you need to extends the class: 19 | ```typescript 20 | import { createClient } from '@remixproject/plugin-webview' 21 | import { PluginClient } from '@remixproject/plugin' 22 | 23 | class MyPlugin extends PluginClient { 24 | methods = ['hello'] 25 | hello() { 26 | console.log('Hello World') 27 | } 28 | } 29 | const client = createClient() 30 | client.onload(async () => { 31 | const data = client.call('filemanager', 'readFile', 'ballot.sol') 32 | }) 33 | ``` -------------------------------------------------------------------------------- /packages/plugin/webworker/README.md: -------------------------------------------------------------------------------- 1 | # Plugin Webworker 2 | 3 | This library provides connectors to connect a plugin to an engine that can load webworkers. 4 | ``` 5 | npm install @remixproject/plugin-webworker 6 | ``` 7 | 8 | If you do not expose any API you can create an instance like this : 9 | ```typescript 10 | import { createClient } from '@remixproject/plugin-webworker' 11 | 12 | const client = createClient() 13 | client.onload(async () => { 14 | const data = client.call('filemanager', 'readFile', 'ballot.sol') 15 | }) 16 | ``` 17 | 18 | If you need to expose an API to other plugin you need to extends the class: 19 | ```typescript 20 | import { createClient } from '@remixproject/plugin-webworker' 21 | import { PluginClient } from '@rexmixproject/plugin' 22 | 23 | class MyPlugin extends PluginClient { 24 | methods = ['hello'] 25 | hello() { 26 | console.log('Hello World') 27 | } 28 | } 29 | const client = createClient() 30 | client.onload(async () => { 31 | const data = client.call('filemanager', 'readFile', 'ballot.sol') 32 | }) 33 | ``` -------------------------------------------------------------------------------- /packages/api/src/lib/file-system/file-manager/profile.ts: -------------------------------------------------------------------------------- 1 | import { IFileSystem } from './api' 2 | import { LocationProfile, Profile } from '@remixproject/plugin-utils' 3 | 4 | export const filSystemProfile: Profile & LocationProfile = { 5 | name: "fileManager", 6 | displayName: "Native Filemanager for Remix vscode plugin", 7 | description: "Provides communication between vscode filemanager and remix-plugin", 8 | location: "sidePanel", 9 | documentation: "https://remix-ide.readthedocs.io/en/latest/solidity_editor.html", 10 | version: "0.0.1", 11 | methods: [ 12 | "getFolder", 13 | "getCurrentFile", 14 | "getFile", 15 | "setFile", 16 | "switchFile", 17 | // NextFileSystemAPI 18 | "open", 19 | "writeFile", 20 | "readFile", 21 | "rename", 22 | "copyFile", 23 | "mkdir", 24 | "readdir", 25 | "closeAllFiles", 26 | "closeFile", 27 | "remove", 28 | ], 29 | events: ['currentFileChanged', 'fileAdded', 'fileClosed', 'fileRemoved', 'fileRenamed', 'fileSaved', 'noFileSelected', 'folderAdded'] 30 | }; -------------------------------------------------------------------------------- /packages/engine/core/doc/api/engine.md: -------------------------------------------------------------------------------- 1 | # Engine 2 | 3 | The `Engine` deals with the registration of the plugins, to make sure they are available for activation. 4 | 5 | It manages the interaction between plugins (calls & events). 6 | 7 | ## Constructor 8 | The `Engine` depends on the plugin manager for the permission system. 9 | 10 | ```typescript 11 | const manager = new PluginManager() 12 | const engine = new Engine() 13 | engine.register(manager) 14 | ``` 15 | 16 | 17 | ### register 18 | ```typescript 19 | register(plugins: Plugin | Plugin[]): string | string[] 20 | ``` 21 | 22 | Register one or several plugins into the engine and return their names. 23 | 24 | A plugin **must be register before being activated**. 25 | 26 | ### isRegistered 27 | ```typescript 28 | isRegistered(name: string): boolean 29 | ``` 30 | 31 | Checks if a plugin with this name has already been registered by the engine. 32 | 33 | ## Hooks 34 | 35 | ### onRegistration 36 | ```typescript 37 | onRegistration(plugin: Plugin) {} 38 | ``` 39 | 40 | This method triggered when a plugin is registered. -------------------------------------------------------------------------------- /packages/engine/node/src/lib/child-process.ts: -------------------------------------------------------------------------------- 1 | import type { Message, Profile, ExternalProfile } from '@remixproject/plugin-utils' 2 | import { PluginConnector } from '@remixproject/engine' 3 | import { fork, ChildProcess } from 'child_process' 4 | 5 | export class ChildProcessPlugin extends PluginConnector { 6 | private readonly listener = ['message', (msg: Message) => this.getMessage(msg)] as const 7 | process: ChildProcess 8 | 9 | constructor(profile: Profile & ExternalProfile) { 10 | super(profile) 11 | } 12 | 13 | protected send(message: Partial): void { 14 | if (!this.process?.connected) { 15 | throw new Error(`Child process from plugin "${this.name}" is not yet connected`) 16 | } 17 | this.process.send(message) 18 | } 19 | 20 | protected connect(url: string): void { 21 | this.process = fork(url) 22 | this.process.on(...this.listener) 23 | } 24 | 25 | protected disconnect(): void { 26 | this.process.off(...this.listener) 27 | this.process.disconnect() 28 | this.process.kill() 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /packages/engine/web/src/lib/window.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from '@remixproject/engine' 2 | import { IWindow, windowProfile } from '@remixproject/plugin-api' 3 | import { MethodApi, PluginOptions } from '@remixproject/plugin-utils'; 4 | 5 | export class WindowPlugin extends Plugin implements MethodApi { 6 | 7 | constructor(options: PluginOptions = {}) { 8 | super(windowProfile) 9 | // Leave 1min to let the user interact with the window 10 | super.setOptions({ queueTimeout: 60_000, ...options }) 11 | } 12 | 13 | /** Display an input window */ 14 | prompt(message?: string): Promise { 15 | return new Promise((res, rej) => res(window.prompt(message))); 16 | } 17 | 18 | /** Ask confirmation for an action */ 19 | confirm(message: string): Promise { 20 | return new Promise((res) => res(window.confirm(message))); 21 | } 22 | 23 | /** Display a message with actions button. Returned the button clicked if any */ 24 | alert(message: string, actions?: string[]): Promise { 25 | return new Promise((res, rej) => res(window.alert(message))); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /packages/engine/vscode/src/lib/extension.ts: -------------------------------------------------------------------------------- 1 | // Check here : https://code.visualstudio.com/api/references/vscode-api#extensions 2 | import { PluginConnector } from "@remixproject/engine" 3 | import { Profile, ExternalProfile, Message } from '@remixproject/plugin-utils' 4 | import { extensions, Extension } from 'vscode' 5 | 6 | export class ExtensionPlugin extends PluginConnector { 7 | private extension: Extension 8 | private connector: any 9 | 10 | constructor(profile: Profile & ExternalProfile) { 11 | super(profile) 12 | } 13 | 14 | protected send(message: Partial): void { 15 | if (this.extension) { 16 | this.connector.onMessage(message) 17 | } 18 | } 19 | 20 | protected async connect(url: string): Promise { 21 | try { 22 | this.extension = extensions.getExtension(url) 23 | this.connector = await this.extension.activate() 24 | } catch (err) { 25 | throw new Error(`ExtensionPlugin "${this.profile.name}" could not connect to the engine.`) 26 | } 27 | } 28 | 29 | protected disconnect(): void { 30 | if (this.extension) {} 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/api/src/lib/git/api.ts: -------------------------------------------------------------------------------- 1 | import { StatusEvents } from '@remixproject/plugin-utils' 2 | 3 | export interface IGitSystem { 4 | events: { 5 | } & StatusEvents 6 | methods: { 7 | //Priority 8 | clone(url: string): string 9 | checkout(cmd: string): string // Switch branches or restore working tree files 10 | init(): string 11 | add(cmd: string): string 12 | commit(cmd: string): string 13 | fetch(cmd: string): string 14 | pull(cmd: string): string 15 | push(cmd: string): string 16 | reset(cmd: string): string 17 | status(cmd: string): string 18 | remote(cmd: string): string 19 | log(): string 20 | 21 | //Less priority 22 | /* 23 | gitMv(cmd: string): void //Move or rename a file, a directory, or a symlink 24 | gitRm(cmd: string) 25 | gitConfig(cmd: string): void //Get and set repository or global options 26 | gitBranch(cmd: string): void 27 | gitMerge(cmd: string): void 28 | gitRebase(cmd: string): void 29 | gitSwitch(cmd: string): void 30 | gitTag(cmd: string): void 31 | gitBlame(cmd: string): void 32 | */ 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/engine/vscode/src/lib/contentimport.ts: -------------------------------------------------------------------------------- 1 | import { contentImportProfile, IContentImport } from '@remixproject/plugin-api'; 2 | import { ContentImport } from '@remixproject/plugin-api'; 3 | import { MethodApi } from '@remixproject/plugin-utils'; 4 | import { CommandPlugin } from './command'; 5 | import { RemixURLResolver } from '@remix-project/remix-url-resolver'; 6 | 7 | export class ContentImportPlugin extends CommandPlugin 8 | implements MethodApi { 9 | urlResolver: RemixURLResolver; 10 | constructor() { 11 | super(contentImportProfile); 12 | this.urlResolver = new RemixURLResolver(); 13 | } 14 | 15 | async resolve(path: string): Promise { 16 | let resolved: any; 17 | try { 18 | resolved = await this.urlResolver.resolve(path); 19 | const { content, cleanUrl, type } = resolved; 20 | return { content, cleanUrl, type, url: path }; 21 | } catch (e) { 22 | throw Error(e.message); 23 | } 24 | } 25 | // TODO: implement this method 26 | async resolveAndSave(url: string, targetPath: string): Promise { 27 | return ''; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/app/plugins/library.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { LibraryPlugin } from '@remixproject/engine'; 3 | import { LibraryProfile } from '@remixproject/plugin-utils'; 4 | import { EventEmitter } from 'events'; 5 | import { Engine } from '../engine'; 6 | 7 | interface Transaction { 8 | id: string; 9 | } 10 | 11 | class TransactionLibrary { 12 | private transactions: Transaction[] = []; 13 | events = new EventEmitter(); 14 | 15 | sendTransaction(tx: Transaction) { 16 | this.transactions.push(tx); 17 | this.events.emit('newTransaction', tx) 18 | } 19 | 20 | } 21 | 22 | const profile: LibraryProfile = { 23 | name: 'library', 24 | methods: ['sendTransaction'], 25 | events: ['newTransaction'] 26 | } 27 | 28 | @Injectable({ providedIn: 'root' }) 29 | export class Library extends LibraryPlugin { 30 | library: TransactionLibrary; 31 | constructor(engine: Engine) { 32 | const library = new TransactionLibrary(); 33 | super(library, profile); 34 | engine.register(this); 35 | } 36 | 37 | onActivation() { 38 | this.library.sendTransaction({ id: "0" }); 39 | } 40 | } -------------------------------------------------------------------------------- /packages/plugin/webworker/src/lib/connector.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { ClientConnector, connectClient, applyApi, Client, PluginClient } from '@remixproject/plugin' 3 | import type { Message, Api, ApiMap } from '@remixproject/plugin-utils' 4 | import { IRemixApi } from '@remixproject/plugin-api' 5 | 6 | 7 | export class WebworkerConnector implements ClientConnector { 8 | 9 | /** Send a message to the engine */ 10 | send(message: Partial) { 11 | postMessage(message) 12 | } 13 | 14 | /** Get message from the engine */ 15 | on(cb: (message: Partial) => void) { 16 | addEventListener('message', ({ data }) => cb(data)) 17 | } 18 | } 19 | 20 | /** 21 | * Connect a Websocket plugin client to a web engine 22 | * @param client An optional websocket plugin client to connect to the engine. 23 | */ 24 | export const createClient = < 25 | P extends Api, 26 | App extends ApiMap = Readonly 27 | >(client: PluginClient = new PluginClient()): Client => { 28 | const c = client as any 29 | connectClient(new WebworkerConnector(), c) 30 | applyApi(c) 31 | return c 32 | } 33 | -------------------------------------------------------------------------------- /packages/api/src/lib/dgit/api.ts: -------------------------------------------------------------------------------- 1 | import { StatusEvents } from "@remixproject/plugin-utils"; 2 | export interface IDgitSystem { 3 | events: StatusEvents 4 | methods: { 5 | init(): void; 6 | add(cmd: any): string; 7 | commit(cmd: any): string; 8 | status(cmd: any): any[]; 9 | rm(cmd: any): string; 10 | log(cmd: any): any[]; 11 | lsfiles(cmd: any): any[]; 12 | readblob(cmd: any): { oid: string, blob: Uint8Array } 13 | resolveref(cmd: any): string 14 | branch(cmd: any): void 15 | checkout(cmd: any): void 16 | branches(): string[] 17 | currentbranch(): string 18 | push(cmd: any): string 19 | pull(cmd: any): void 20 | setIpfsConfig(config:any): boolean 21 | zip():void 22 | setItem(name:string, content:string):void 23 | getItem(name: string): string 24 | import(cmd: any): void 25 | export(cmd: any): void 26 | remotes(): any[] 27 | addremote(cmd: any): void 28 | delremote(cmd: any): void 29 | clone(cmd: any): void 30 | localStorageUsed(): any 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /packages/plugin/iframe/README.md: -------------------------------------------------------------------------------- 1 | # Plugin frame 2 | 3 | **Except if you want your plugin to ONLY work on the web, prefer [@remixproject/plugin-webview](../webview)** 4 | 5 | This library provides connectors to connect a plugin to an engine running in a web environment. 6 | ``` 7 | npm install @remixproject/plugin-iframe 8 | ``` 9 | 10 | If you do not expose any API you can create an instance like this : 11 | ```typescript 12 | import { createClient } from '@remixproject/plugin-iframe' 13 | 14 | const client = createClient() 15 | client.onload(async () => { 16 | const data = client.call('filemanager', 'readFile', 'ballot.sol') 17 | }) 18 | ``` 19 | 20 | If you need to expose an API to other plugin you need to extends the class: 21 | ```typescript 22 | import { createClient } from '@remixproject/plugin-iframe' 23 | import { PluginClient } from '@rexmixproject/plugin' 24 | 25 | class MyPlugin extends PluginClient { 26 | methods = ['hello'] 27 | hello() { 28 | console.log('Hello World') 29 | } 30 | } 31 | const client = createClient() 32 | client.onload(async () => { 33 | const data = client.call('filemanager', 'readFile', 'ballot.sol') 34 | }) 35 | ``` 36 | -------------------------------------------------------------------------------- /packages/api/src/lib/standard-profile.ts: -------------------------------------------------------------------------------- 1 | import { ProfileMap, Profile, ApiMap } from '@remixproject/plugin-utils' 2 | import { compilerProfile, ICompiler } from './compiler' 3 | import { filSystemProfile, IFileSystem } from './file-system/file-manager' 4 | import { editorProfile, IEditor } from './editor' 5 | import { networkProfile, INetwork } from './network' 6 | import { udappProfile, IUdapp } from './udapp' 7 | import { IPluginManager, pluginManagerProfile } from './plugin-manager' 8 | 9 | export interface IStandardApi { 10 | manager: IPluginManager, 11 | solidity: ICompiler 12 | fileManager: IFileSystem 13 | editor: IEditor 14 | network: INetwork 15 | udapp: IUdapp 16 | } 17 | 18 | export type StandardApi = Readonly 19 | 20 | /** Profiles of all the standard's Native Plugins */ 21 | export const standardProfiles: ProfileMap = Object.freeze({ 22 | manager: pluginManagerProfile, 23 | solidity: { ...compilerProfile, name: 'solidity' } as Profile, 24 | fileManager: { ...filSystemProfile, name: 'fileManager' } as Profile, 25 | editor: editorProfile, 26 | network: networkProfile, 27 | udapp: udappProfile, 28 | }) 29 | -------------------------------------------------------------------------------- /packages/api/README.md: -------------------------------------------------------------------------------- 1 | # plugin-api 2 | 3 | This library host all the API of the common plugins. 4 | 5 | Here is the list of native plugins exposed by Remix IDE 6 | 7 | _Click on the name of the api to get the full documentation._ 8 | 9 | 10 | |API |Name |Description | 11 | |---------------|-------------------------------------|------------| 12 | |File System |[fileManager](./doc/file-system.md) |Manages the File System 13 | |Compiler |[solidity](./doc/solidity.md) |The solidity Compiler 14 | |Editor |[editor](./doc/editor.md) |Enables highlighting in the code Editor 15 | |Network |[network](./doc/network.md) |Defines the network (mainnet, ropsten, ...) and provider (web3, vm, injected) used 16 | |Udapp |[udapp](./doc/udapp.md) |Transaction listener 17 | |Unit Testing |[solidityUnitTesting](./doc/unit-testing.md) |Unit testing library in solidity 18 | |Settings |[settings](./doc/settings.md) |Global settings of the IDE 19 | |Content Import |[contentImport](./doc/content-import.md) |Import files from github, swarm, ipfs, http or https. 20 | |Terminal |[terminal](./doc/terminal.md) |Log to the terminal 21 | 22 | -------------------------------------------------------------------------------- /packages/plugin/vscode/README.md: -------------------------------------------------------------------------------- 1 | # Plugin vscode 2 | This library provides connectors to run plugin in a vscode environment. Use this connector if you have a web based plugin that needs to run inside vscode. 3 | 4 | **Except if you want your plugin to ONLY work on vscode, prefer [@remixproject/plugin-webview](../webview/readme.md)** 5 | 6 | ``` 7 | npm install @remixproject/plugin-vscode 8 | ``` 9 | 10 | ## Webview 11 | Similar to `@remixproject/plugin-iframe`, the webview connector will connect to an engine running inside vscode. 12 | 13 | If you do not expose any API you can create an instance like this : 14 | ```html 15 | 21 | ``` 22 | 23 | If you need to expose an API to other plugin you need to extends the class: 24 | ```html 25 | 37 | ``` -------------------------------------------------------------------------------- /packages/engine/core/doc/tutorial/4-external-plugins.md: -------------------------------------------------------------------------------- 1 | ## External Plugins 2 | 3 | The superpower of the Engine is the ability to interact safely with external plugins. 4 | 5 | Currently the Engine supports 2 communication channels: 6 | - Iframe 7 | - Websocket 8 | 9 | The interface of these plugins is exacly the same as the other plugins. 10 | 11 | ### Iframe 12 | 13 | For the `IframePlugin` we need to specify the `location` where the plugin will be displayed, and the `url` which will be used as the source of the iframe. 14 | 15 | > The Engine can fetch the content of plugin hosted on IPFS or any other server accessible through HTTPS 16 | 17 | ```typescript 18 | const ethdoc = new IframePlugin({ 19 | name: 'ethdoc', 20 | location: 'sidePanel', 21 | url: 'ipfs://QmQmK435v4io3cp6N9aWQHYmgLxpUejjC1RmZCbqL7MJaM' 22 | }) 23 | ``` 24 | 25 | ### Websocket 26 | 27 | For the `WebsocketPlugin` you just need to specify the `url` as there is no UI to display. 28 | 29 | > This plugin is very useful for connecting to a local server like remixD, and an external API 30 | 31 | ```typescript 32 | const remixd = new WebsocketPlugin({ 33 | name: 'remixd', 34 | url: 'wss://localhost:8000' 35 | }) 36 | ``` 37 | 38 | In the future, we'll implement more communication connection like REST, GraphQL, JSON RPC, gRPC, ... -------------------------------------------------------------------------------- /examples/example/engine/web-e2e/src/support/commands.ts: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | 11 | // eslint-disable-next-line @typescript-eslint/no-namespace 12 | declare namespace Cypress { 13 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 14 | interface Chainable { 15 | login(email: string, password: string): void; 16 | } 17 | } 18 | // 19 | // -- This is a parent command -- 20 | Cypress.Commands.add('login', (email, password) => { 21 | console.log('Custom command example: Login', email, password); 22 | }); 23 | // 24 | // -- This is a child command -- 25 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) 26 | // 27 | // 28 | // -- This is a dual command -- 29 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) 30 | // 31 | // 32 | // -- This will overwrite an existing command -- 33 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) 34 | -------------------------------------------------------------------------------- /examples/example/plugin/webview-e2e/src/support/commands.ts: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | 11 | // eslint-disable-next-line @typescript-eslint/no-namespace 12 | declare namespace Cypress { 13 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 14 | interface Chainable { 15 | login(email: string, password: string): void; 16 | } 17 | } 18 | // 19 | // -- This is a parent command -- 20 | Cypress.Commands.add('login', (email, password) => { 21 | console.log('Custom command example: Login', email, password); 22 | }); 23 | // 24 | // -- This is a child command -- 25 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) 26 | // 27 | // 28 | // -- This is a dual command -- 29 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) 30 | // 31 | // 32 | // -- This will overwrite an existing command -- 33 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) 34 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 2018, 6 | "sourceType": "module", 7 | "project": "./tsconfig.*?.json" 8 | }, 9 | "ignorePatterns": ["**/*"], 10 | "plugins": ["@typescript-eslint", "@nrwl/nx"], 11 | "extends": [ 12 | "eslint:recommended", 13 | "plugin:@typescript-eslint/eslint-recommended", 14 | "plugin:@typescript-eslint/recommended", 15 | "prettier", 16 | "prettier/@typescript-eslint" 17 | ], 18 | "rules": { 19 | "@typescript-eslint/explicit-member-accessibility": "off", 20 | "@typescript-eslint/explicit-function-return-type": "off", 21 | "@typescript-eslint/no-parameter-properties": "off", 22 | "@nrwl/nx/enforce-module-boundaries": [ 23 | "error", 24 | { 25 | "enforceBuildableLibDependency": true, 26 | "allow": [], 27 | "depConstraints": [ 28 | { 29 | "sourceTag": "*", 30 | "onlyDependOnLibsWithTags": ["*"] 31 | } 32 | ] 33 | } 34 | ], 35 | "@typescript-eslint/explicit-module-boundary-types": "off" 36 | }, 37 | "overrides": [ 38 | { 39 | "files": ["*.tsx"], 40 | "rules": { 41 | "@typescript-eslint/no-unused-vars": "off" 42 | } 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /packages/plugin/electron/src/lib/electronPluginClient.ts: -------------------------------------------------------------------------------- 1 | import { ClientConnector, connectClient, applyApi, Client, PluginClient } from '@remixproject/plugin' 2 | import type { Message, Api, ApiMap, Profile } from '@remixproject/plugin-utils' 3 | import { IRemixApi } from '@remixproject/plugin-api' 4 | import { ipcMain } from 'electron' 5 | 6 | export class ElectronPluginClientConnector implements ClientConnector { 7 | 8 | constructor(public profile: Profile, public browserWindow: Electron.BrowserWindow) { 9 | } 10 | 11 | /** Send a message to the engine */ 12 | send(message: Partial) { 13 | this.browserWindow.webContents.send(this.profile.name + ':send', message) 14 | } 15 | 16 | /** Listen to message from the engine */ 17 | on(cb: (message: Partial) => void) { 18 | ipcMain.on(this.profile.name + ':on:' + this.browserWindow.webContents.id, (event, message) => { 19 | cb(message) 20 | }) 21 | } 22 | } 23 | 24 | export const createElectronClient = < 25 | P extends Api, 26 | App extends ApiMap = Readonly 27 | >(client: PluginClient = new PluginClient(), profile: Profile 28 | , window: Electron.BrowserWindow 29 | ): Client => { 30 | const c = client as any 31 | connectClient(new ElectronPluginClientConnector(profile, window), c) 32 | applyApi(c) 33 | return c 34 | } -------------------------------------------------------------------------------- /packages/plugin/core/src/lib/api.ts: -------------------------------------------------------------------------------- 1 | import type { Profile, Api, MethodApi, CustomApi, ProfileMap, ApiMapFromProfileMap, PluginApi, ApiMap } from '@remixproject/plugin-utils' 2 | import { PluginClient } from './client' 3 | 4 | /** 5 | * Create an Api 6 | * @param profile The profile of the api 7 | */ 8 | export function createApi(client: PluginClient, profile: Profile): CustomApi { 9 | if (typeof profile.name !== 'string') { 10 | throw new Error('Profile should have a name') 11 | } 12 | const on = >(event: event, cb: T['events'][event]) => { 13 | client.on.call(client, profile.name, event, cb) 14 | } 15 | 16 | const methods = (profile.methods || []).reduce((acc, method) => ({ 17 | ...acc, 18 | [method]: client.call.bind(client, profile.name, method) 19 | }), {} as MethodApi) 20 | return { on, ...methods } 21 | } 22 | 23 | 24 | /** 25 | * Transform a list of profile into a map of API 26 | * @deprecated Use `applyApi` from connector instead 27 | */ 28 | export function getApiMap, App extends ApiMap>( 29 | client: PluginClient, 30 | profiles: T 31 | ): PluginApi> { 32 | return Object.keys(profiles).reduce((acc, name) => { 33 | const profile = profiles[name] as Profile 34 | return { ...acc, [name]: createApi(client, profile ) } 35 | }, {} as PluginApi>) 36 | } 37 | -------------------------------------------------------------------------------- /packages/api/src/lib/udapp/type.ts: -------------------------------------------------------------------------------- 1 | export type RemixTxEvent = { 2 | contractAddress: string 3 | data: string 4 | envMode: 'vm' 5 | executionCost: string 6 | from: string 7 | gas: string 8 | hash: string 9 | input: string 10 | logs: any[] 11 | returnValue: Uint8Array 12 | status: '0x01' | '0x00' 13 | transactionCost: string 14 | transactionHash: string 15 | value: string 16 | } | { 17 | blockHash: string 18 | blockNumber: number 19 | envMod: 'injected' | 'web3' 20 | from: string 21 | gas: number 22 | gasPrice: { c: number[], e: number, s: number } 23 | hash: string 24 | input: string 25 | none: number 26 | r: string 27 | s: string 28 | v: string 29 | status: '0x01' | '0x00' 30 | to: string 31 | transactionCost: string 32 | transactionIndex: number 33 | value: { c: number[], e: number, s: number } 34 | } 35 | 36 | export interface RemixTx { 37 | data: string 38 | from: string 39 | to?: string 40 | timestamp?: string 41 | gasLimit: string 42 | value: string 43 | useCall: boolean 44 | } 45 | 46 | export interface RemixTxReceipt { 47 | transactionHash: string 48 | status: 0 | 1 49 | gasUsed: string 50 | error: string 51 | return: string 52 | createdAddress?: string 53 | } 54 | 55 | export interface VMAccount { 56 | privateKey: string 57 | balance: string 58 | } 59 | 60 | export interface UdappSettings { 61 | selectedAccount:string 62 | selectedEnvMode: 'vm' | 'injected' | 'web3' 63 | networkEnvironment: string 64 | } 65 | -------------------------------------------------------------------------------- /packages/engine/web/src/lib/web-worker.ts: -------------------------------------------------------------------------------- 1 | import type { Message, Profile, ExternalProfile, PluginOptions } from '@remixproject/plugin-utils' 2 | import { PluginConnector } from '@remixproject/engine' 3 | 4 | type WebworkerOptions = WorkerOptions & PluginOptions 5 | 6 | export class WebWorkerPlugin extends PluginConnector { 7 | private worker: Worker 8 | protected options: WebworkerOptions 9 | 10 | constructor(public profile: Profile & ExternalProfile, options?: WebworkerOptions) { 11 | super(profile) 12 | this.setOptions(options) 13 | } 14 | 15 | setOptions(options: Partial) { 16 | super.setOptions({ type: 'module', name: this.name, ...options }) 17 | } 18 | 19 | connect(url: string) { 20 | if ('Worker' in window) { 21 | this.worker = new Worker(url, this.options) 22 | this.worker.onmessage = e => this.getEvent(e) 23 | return this.handshake() 24 | } 25 | } 26 | 27 | disconnect() { 28 | this.worker.terminate() 29 | } 30 | 31 | /** Get message from the iframe */ 32 | private async getEvent(event: MessageEvent) { 33 | const message: Message = event.data 34 | this.getMessage(message) 35 | } 36 | 37 | /** 38 | * Post a message to the webview of this plugin 39 | * @param message The message to post 40 | */ 41 | protected send(message: Partial) { 42 | if (!this.worker) { 43 | throw new Error('No worker attached to the plugin') 44 | } 45 | this.worker.postMessage(message) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/app/plugins/manager.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { PluginManager } from '@remixproject/engine'; 3 | import { Profile } from '@remixproject/plugin-utils'; 4 | import { BehaviorSubject } from 'rxjs'; 5 | import { Engine } from '../engine'; 6 | 7 | 8 | const localPlugins = ['manager', 'main', 'theme', 'window']; 9 | 10 | @Injectable({ providedIn: 'root' }) 11 | export class Manager extends PluginManager { 12 | private activeProfiles = new BehaviorSubject([]); 13 | private idleProfiles = new BehaviorSubject([]); 14 | public activeProfiles$ = this.activeProfiles.asObservable(); 15 | public idleProfiles$ = this.idleProfiles.asObservable(); 16 | 17 | constructor(engine: Engine) { 18 | super() 19 | engine.register(this) 20 | } 21 | 22 | private async updateProfiles() { 23 | const actives = []; 24 | const idles = []; 25 | for (const profile of Object.values(this.profiles)) { 26 | await this.isActive(profile.name) 27 | ? actives.push(profile) 28 | : idles.push(profile) 29 | } 30 | this.activeProfiles.next(actives); 31 | this.idleProfiles.next(idles); 32 | } 33 | 34 | onProfileAdded() { 35 | this.updateProfiles(); 36 | } 37 | 38 | onPluginActivated(profile: Profile) { 39 | this.updateProfiles(); 40 | } 41 | 42 | onPluginDeactivated() { 43 | this.updateProfiles(); 44 | } 45 | 46 | async canDeactivatePlugin(from: Profile, to: Profile) { 47 | return localPlugins.includes(from.name); 48 | } 49 | } -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "sourceMap": true, 6 | "declaration": false, 7 | "moduleResolution": "node", 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "importHelpers": true, 11 | "target": "es2015", 12 | "module": "esnext", 13 | "typeRoots": ["node_modules/@types"], 14 | "lib": ["es2017", "dom"], 15 | "skipLibCheck": true, 16 | "skipDefaultLibCheck": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "@remixproject/plugin-utils": ["packages/utils/src/index.ts"], 20 | "@remixproject/plugin-api": ["packages/api/src/index.ts"], 21 | "@remixproject/engine": ["packages/engine/core/src/index.ts"], 22 | "@remixproject/engine-web": ["packages/engine/web/src/index.ts"], 23 | "@remixproject/plugin": ["packages/plugin/core/src/index.ts"], 24 | "@remixproject/plugin/ws": ["packages/plugin/ws/src/index.ts"], 25 | "@remixproject/plugin-webview": ["packages/plugin/webview/src/index.ts"], 26 | "@remixproject/plugin-webworker": [ 27 | "packages/plugin/webworker/src/index.ts" 28 | ], 29 | "@remixproject/plugin-theia": ["packages/plugin/theia/src/index.ts"], 30 | "@remixproject/engine-theia": ["packages/engine/theia/src/index.ts"], 31 | "@remixproject/engine-electron": ["packages/engine/electron/src/index.ts"], 32 | "@remixproject/plugin-electron": ["packages/plugin/electron/src/index.ts"] 33 | } 34 | }, 35 | "exclude": ["node_modules", "tmp"] 36 | } 37 | -------------------------------------------------------------------------------- /packages/plugin/core/tests/origin.spec.ts: -------------------------------------------------------------------------------- 1 | import { checkOrigin } from "../src" 2 | 3 | declare const global // Needed to mock fetch 4 | 5 | describe('Origin', () => { 6 | test('Check origin', async () => { 7 | const port = 8080 8 | const origins = 'package://' 9 | const goodOrigin = 'http://remix.ethereum.org' 10 | const wrongOrigin = 'http://remix.ethereum.com' 11 | const goodLocalOrigin = `http://127.0.0.1:${port}` 12 | const wrongLocalOrigin = `http://localhost:${port + 1}` 13 | const wrongExternalOrigin = `${origins}wrong` 14 | const goodExternalOrigin = origins 15 | const allowOrigins = [goodLocalOrigin, goodExternalOrigin] 16 | 17 | // Mock fetch api 18 | const mockFetchPromise = Promise.resolve({ 19 | json: () => Promise.resolve([ 20 | "http://remix-alpha.ethereum.org", 21 | "http://remix.ethereum.org", 22 | "https://remix-alpha.ethereum.org", 23 | "https://remix.ethereum.org" 24 | ]) 25 | }) 26 | global.fetch = jest.fn().mockImplementation(() => mockFetchPromise) 27 | 28 | expect(await checkOrigin(goodOrigin)).toBeTruthy() 29 | expect(await checkOrigin(wrongOrigin)).toBeTruthy() // Check origin only with devmode & allowOrigins 30 | expect(await checkOrigin(goodLocalOrigin, { allowOrigins })).toBeTruthy() 31 | expect(await checkOrigin(wrongLocalOrigin, { allowOrigins })).toBeFalsy() 32 | expect(await checkOrigin(goodExternalOrigin, { allowOrigins })).toBeTruthy() 33 | expect(await checkOrigin(wrongExternalOrigin, { allowOrigins })).toBeFalsy() 34 | }) 35 | }) -------------------------------------------------------------------------------- /packages/engine/vscode/src/lib/command.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from '@remixproject/engine' 2 | import { Profile, PluginOptions } from '@remixproject/plugin-utils' 3 | import { Disposable, commands } from 'vscode' 4 | 5 | export const transformCmd = (name: string, method: string) => 6 | `remix.${name}.${method}` 7 | 8 | export interface CommandOptions extends PluginOptions { 9 | transformCmd: (name: string, method: string) => string 10 | } 11 | 12 | // WIP 13 | /** 14 | * Connect methods of the plugins with a command depending on the transformCmd function pass as option 15 | */ 16 | export class CommandPlugin extends Plugin { 17 | subscriptions: Disposable[] = [] 18 | options: CommandOptions 19 | 20 | constructor(profile: Profile) { 21 | super(profile) 22 | this.setOptions({ 23 | transformCmd, 24 | }) 25 | } 26 | 27 | setOptions(options: Partial) { 28 | return super.setOptions(options) 29 | } 30 | 31 | activate() { 32 | this.subscriptions = this.profile.methods 33 | .map((method) => { 34 | try { 35 | const cmd = this.options.transformCmd(this.profile.name, method) 36 | return commands.registerCommand(cmd, (...args) => 37 | this.callPluginMethod(method, args) 38 | ) 39 | } catch (err) { 40 | console.log(err) 41 | } 42 | }) 43 | .filter((command) => { 44 | return command 45 | }) 46 | super.activate() 47 | } 48 | 49 | deactivate() { 50 | super.deactivate() 51 | this.subscriptions.forEach((sub) => sub.dispose()) 52 | } 53 | } -------------------------------------------------------------------------------- /examples/example/engine/web/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { ChangeDetectionStrategy, Component } from '@angular/core'; 2 | import { IframePlugin, WebWorkerPlugin } from '@remixproject/engine-web'; 3 | import { Theme, Manager, Window, Library } from './plugins'; 4 | import { Engine } from './engine'; 5 | 6 | const profiles = [ 7 | { name: 'iframe', url: 'http://localhost:4201', location: 'main' }, 8 | { name: 'scriptRunner', url: 'https://scriptRunner.dyn.plugin.remixproject.org/ipfs/QmbzZFuLHSeLcJ4RUZzNvP3LQ3Yr5Rv4uougPquAVQ2kv1', location: 'main' } 9 | ]; 10 | 11 | @Component({ 12 | selector: 'engine-root', 13 | templateUrl: './app.component.html', 14 | styleUrls: ['./app.component.scss'], 15 | changeDetection: ChangeDetectionStrategy.OnPush 16 | }) 17 | export class AppComponent { 18 | actives$ = this.manager.activeProfiles$; 19 | idles$ = this.manager.idleProfiles$; 20 | 21 | constructor( 22 | private engine: Engine, 23 | private manager: Manager, 24 | private window: Window, 25 | private theme: Theme, 26 | private library: Library 27 | ) {} 28 | 29 | ngAfterViewInit() { 30 | try { 31 | const iframes = profiles.map(profile => new IframePlugin(profile)); 32 | const worker = new WebWorkerPlugin({ name: 'worker', url: '/assets/web.worker.js', methods: ['execute'] }) 33 | this.engine.register([...iframes, worker]); 34 | } catch (err) { 35 | console.error(err) 36 | } 37 | } 38 | 39 | deactivate(name: string) { 40 | this.manager.deactivatePlugin(name); 41 | } 42 | 43 | activate(name: string) { 44 | this.manager.activatePlugin(name); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/utils/src/lib/types/plugin.ts: -------------------------------------------------------------------------------- 1 | import type { IPluginService } from './service' 2 | import { EventCallback, MethodParams, MethodKey, EventKey, Api, ApiMap, EventParams } from './api' 3 | 4 | export interface PluginBase { 5 | methods: string[], 6 | activateService: Record Promise> 7 | /** Listen on an event from another plugin */ 8 | on, Key extends EventKey>( 9 | name: Name, 10 | key: Key, 11 | cb: EventCallback, 12 | ): void 13 | 14 | /** Listen one time on an event from another plugin, then remove event listener */ 15 | once, Key extends EventKey>( 16 | name: Name, 17 | key: Key, 18 | cb: EventCallback, 19 | ): void 20 | 21 | /** Stop listening on an event from another plugin */ 22 | off, Key extends EventKey>( 23 | name: Name, 24 | key: Key, 25 | ): void 26 | 27 | /** Call a method of another plugin */ 28 | call, Key extends MethodKey>( 29 | name: Name, 30 | key: Key, 31 | ...payload: MethodParams 32 | ): Promise 33 | 34 | /** Clear calls in queue of a plugin called by plugin */ 35 | cancel, Key extends MethodKey>( 36 | name: Name, 37 | key: Key, 38 | ): void 39 | 40 | /** Emit an event */ 41 | emit>(key: Key, ...payload: EventParams): void 42 | } 43 | -------------------------------------------------------------------------------- /packages/engine/web/README.md: -------------------------------------------------------------------------------- 1 | # Engine Web 2 | The web engine provides a connector for Iframe & Websocket. 3 | `npm install @remixproject/engine-web` 4 | 5 | ## Iframe 6 | The iframe connector is used to load & connect a plugin inside an iframe. 7 | Iframe based plugin are webview using an `index.html` as entry point & need to use `@remixproject/plugin-iframe`. 8 | 9 | ```typescript 10 | const myPlugin = new IframePlugin({ 11 | name: 'my-plugin', 12 | url: 'https://my-plugin-path.com', 13 | methods: ['getData'] 14 | }) 15 | engine.register(myPlugin); 16 | // This will create the iframe with src="https://my-plugin-path.com" 17 | await manager.activatePlugin('my-plugin'); 18 | const data = manager.call('my-plugin', 'getData'); 19 | ``` 20 | 21 | > Communication between the plugin & the engine uses the `window.postMessage()` API. 22 | 23 | ## Websocket 24 | The websocket connector wraps the native [Websocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) object from the Web API. 25 | Websocket based plugin are usually server with a Websocket connection open. Any library can be used, remixproject provide a wrapper around the `ws` library : `@remixproject/plugin-ws`. 26 | 27 | ```typescript 28 | const myPlugin = new WebsocketOptions({ 29 | name: 'my-plugin', 30 | url: 'https://my-server.com', 31 | methods: ['getData'] 32 | }, { 33 | reconnectDelay: 5000 // Time in ms to wait to reconnect after a disconnection 34 | }); 35 | engine.register(myPlugin); 36 | // This will open a connection with the server. The server must be running first. 37 | await manager.activatePlugin('my-plugin'); 38 | const data = manager.call('my-plugin', 'getData'); 39 | ``` 40 | 41 | -------------------------------------------------------------------------------- /packages/engine/core/doc/tutorial/1-getting-started.md: -------------------------------------------------------------------------------- 1 | ## Create the Engine 2 | 3 | 1. Create the Plugin Manager 4 | 5 | The plugin manager can activate/deactivate plugins, and manages permissions between plugins. 6 | ```typescript 7 | import { PluginManager } from '@remixproject/engine'; 8 | 9 | const manager = new PluginManager() 10 | ``` 11 | 12 | 2. Create the Engine 13 | 14 | The engine manages the communication between plugins. It requires a `PluginManager`. 15 | ```typescript 16 | import { PluginManager, Engine } from '@remixproject/engine'; 17 | 18 | const manager = new PluginManager() 19 | const engine = new Engine() 20 | ``` 21 | 22 | 3. Register a plugin 23 | 24 | We need to register a plugin before activating it. This is done by the `Engine`. 25 | 26 | > ⚠️ **IMPORTANT** You need to register the "manager" before beeing able to activate a plugin 27 | ```typescript 28 | import { PluginManager, Engine, Plugin } from '@remixproject/engine'; 29 | 30 | const manager = new PluginManager() 31 | const engine = new Engine() 32 | const plugin = new Plugin({ name: 'plugin-name' }) 33 | 34 | // Register plugin 35 | engine.register([manager, plugin]) 36 | ``` 37 | 38 | 4. Activate a plugin 39 | 40 | *Once your plugin is registered* you can activate it. This is done by the `PluginManager` 41 | ```typescript 42 | const manager = new PluginManager() 43 | const engine = new Engine() 44 | const plugin = new Plugin({ name: 'plugin-name' }) 45 | 46 | // Register plugins 47 | engine.register([manager, plugin]) 48 | 49 | // Activate plugins 50 | manager.activatePlugin('plugin-name') 51 | ``` 52 | 53 | 54 | 🧪 [Tested code available here](../../examples/engine/tests/1-getting-started.ts) -------------------------------------------------------------------------------- /packages/api/doc/content-import.md: -------------------------------------------------------------------------------- 1 | # Content Import 2 | 3 | - Name in Remix: `contentImport` 4 | - kind: `contentImport` 5 | 6 | |Type |Name |Description | 7 | |---------|-----------------------|------------| 8 | |_method_ |`resolve` |Resolve a file from github, ipfs, swarm, http or https 9 | |_method_ |`resolveAndSave` |Resolve a file from github, ipfs, swarm, http or https and save it in the file explorer 10 | ## Examples 11 | 12 | ### Methods 13 | `resolve`: Resolve a file from github, ipfs, swarm, http or https 14 | ```typescript 15 | const link = "https://github.com/GrandSchtroumpf/solidity-school/blob/master/std-0/1_HelloWorld/HelloWorld.sol" 16 | 17 | const { content } = await client.call('contentImport', 'resolve', link) 18 | // OR 19 | const { content } = await client.contentImport.resolve(link) 20 | ``` 21 | 22 | `resolveAndSave`: Resolve and save a file from github, ipfs, swarm, http or https 23 | ```typescript 24 | const link = "https://github.com/GrandSchtroumpf/solidity-school/blob/master/std-0/1_HelloWorld/HelloWorld.sol" 25 | const targetPath = 'HelloWorld.sol' # optional 26 | 27 | const { content } = await client.call('contentImport', 'resolveAndSave', link, targetPath) 28 | // OR 29 | const { content } = await client.contentImport.resolveAndSave(link, targetPath) 30 | ``` 31 | 32 | ## Types 33 | `ContentImport`: An object that describes the returned file 34 | ```typescript 35 | export interface ContentImport { 36 | content: string 37 | cleanUrl: string 38 | type: 'github' | 'http' | 'https' | 'swarm' | 'ipfs' 39 | url: string 40 | } 41 | ``` 42 | 43 | > Type Definitions can be found [here](../src/lib/content-import/type.ts) -------------------------------------------------------------------------------- /packages/plugin/core/tests/remix-api.spec.ts: -------------------------------------------------------------------------------- 1 | import { remixProfiles } from '@remixproject/plugin-api' 2 | import { createConnectorClient } from '../src' 3 | 4 | describe('Remix Api', () => { 5 | const client = createConnectorClient({ 6 | send() {}, 7 | on() {} 8 | }) 9 | 10 | test('Solidity', () => { 11 | expect(client.solidity).toBeDefined() 12 | expect(client.solidity.getCompilationResult).toBeDefined() 13 | expect(client.solidity.on).toBeDefined() 14 | }) 15 | test('File Manager', () => { 16 | expect(client.fileManager).toBeDefined() 17 | expect(client.fileManager.getCurrentFile).toBeDefined() 18 | expect(client.fileManager.getFile).toBeDefined() 19 | expect(client.fileManager.getFolder).toBeDefined() 20 | expect(client.fileManager.setFile).toBeDefined() 21 | expect(client.fileManager.switchFile).toBeDefined() 22 | expect(client.fileManager.on).toBeDefined() 23 | }) 24 | test('Editor', () => { 25 | expect(client.editor.discardHighlight).toBeDefined() 26 | expect(client.editor.highlight).toBeDefined() 27 | expect(client.editor.on).toBeDefined() 28 | }) 29 | test('Network', () => { 30 | expect(client.network.addNetwork).toBeDefined() 31 | expect(client.network.detectNetwork).toBeDefined() 32 | expect(client.network.getEndpoint).toBeDefined() 33 | expect(client.network.getNetworkProvider).toBeDefined() 34 | expect(client.network.removeNetwork).toBeDefined() 35 | expect(client.network.on).toBeDefined() 36 | }) 37 | test('Udapp', () => { 38 | expect(client.udapp.createVMAccount).toBeDefined() 39 | expect(client.udapp.getAccounts).toBeDefined() 40 | expect(client.udapp.sendTransaction).toBeDefined() 41 | expect(client.udapp.on).toBeDefined() 42 | }) 43 | 44 | }) 45 | -------------------------------------------------------------------------------- /packages/engine/core/tests/manager.spec.ts: -------------------------------------------------------------------------------- 1 | import { Engine, Plugin, PluginManager } from '../src' 2 | 3 | class To extends Plugin { 4 | constructor() { 5 | super({ name: 'to', methods: ['mockMethod'] }) 6 | } 7 | askUserPermission = jest.fn(super.askUserPermission) 8 | mockMethod = jest.fn(() => this.askUserPermission('mockMethod')) 9 | } 10 | 11 | class MockManager extends PluginManager { 12 | canCall = jest.fn(async (from) => from === 'from') 13 | } 14 | 15 | 16 | describe('Abstract Plugin', () => { 17 | let from: Plugin 18 | let anotherFrom: Plugin 19 | let to: To 20 | let manager: MockManager 21 | beforeEach(async () => { 22 | from = new Plugin({ name: 'from' }) 23 | anotherFrom = new Plugin({ name: 'anotherFrom' }) 24 | to = new To() 25 | manager = new MockManager() 26 | const engine = new Engine() 27 | engine.register([manager, from, to, anotherFrom]) 28 | await manager.activatePlugin(['from', 'to', 'anotherFrom']) 29 | }) 30 | 31 | test('Can Call is exposed', async () => { 32 | await from.call('to', 'mockMethod') 33 | expect(to.mockMethod).toHaveBeenCalledTimes(1) 34 | expect(to.askUserPermission).toHaveBeenCalledWith('mockMethod') 35 | expect(manager.canCall).toHaveBeenCalledWith('from', 'to', 'mockMethod', undefined) 36 | }) 37 | 38 | test('', async () => { 39 | const [ shouldBeTrue, shouldBeFalse ] = await Promise.all([ 40 | from.call('to', 'mockMethod'), 41 | anotherFrom.call('to', 'mockMethod') 42 | ]) 43 | expect(to.mockMethod).toHaveBeenCalledTimes(2) 44 | expect(shouldBeTrue).toBeTruthy() 45 | expect(shouldBeFalse).toBeFalsy() 46 | expect(manager.canCall.mock.calls[0][0]).toBe('from') 47 | expect(manager.canCall.mock.calls[1][0]).toBe('anotherFrom') 48 | }) 49 | }) -------------------------------------------------------------------------------- /packages/utils/src/lib/types/profile.ts: -------------------------------------------------------------------------------- 1 | import { MethodKey, Api, ApiMap, EventKey } from './api' 2 | 3 | /** Describe a plugin */ 4 | export interface Profile { 5 | name: string 6 | displayName?: string 7 | methods?: MethodKey[] 8 | events?: EventKey[] 9 | permission?: boolean 10 | hash?: string 11 | description?: string 12 | documentation?: string 13 | version?: string 14 | kind?: string, 15 | canActivate?: string[] 16 | icon?: string 17 | maintainedBy?: string, 18 | author?: string 19 | repo?: string 20 | authorContact?: string 21 | } 22 | 23 | export interface LocationProfile { 24 | location: string 25 | } 26 | 27 | export interface ExternalProfile { 28 | url: string 29 | } 30 | 31 | // export interface ExternalProfile extends ViewProfile { 32 | // url: string 33 | // } 34 | 35 | export interface HostProfile extends Profile { 36 | methods: ('addView' | 'removeView' | 'focus' | string)[] 37 | } 38 | 39 | export interface LibraryProfile extends Profile { 40 | events?: EventKey[] 41 | notifications?: { 42 | [name: string]: string[] 43 | } 44 | } 45 | 46 | 47 | /** A map of profile */ 48 | export type ProfileMap = Partial<{ 49 | [name in keyof T]: Profile 50 | }> 51 | 52 | // PROFILE TO API 53 | 54 | /** Extract the API of a profile */ 55 | export type ApiFromProfile = T extends Profile ? I : never 56 | /** Create an ApiMap from a Profile Map */ 57 | export type ApiMapFromProfileMap> = { 58 | [name in keyof T]: ApiFromProfile 59 | } 60 | 61 | /** Transform an ApiMap into a profile map */ 62 | export type ProfileMapFromApiMap = Readonly<{ 63 | [name in keyof T]: Profile 64 | }> 65 | -------------------------------------------------------------------------------- /packages/plugin/core/src/lib/origin.ts: -------------------------------------------------------------------------------- 1 | import { PluginOptions } from "./client" 2 | 3 | // Old link: 'https://raw.githubusercontent.com/ethereum/remix-plugin/master/projects/client/assets/origins.json' 4 | export const remixOrgins = 'https://gist.githubusercontent.com/EthereumRemix/091ccc57986452bbb33f57abfb13d173/raw/3367e019335746b73288e3710af2922d4c8ef5a3/origins.json' 5 | 6 | /** Fetch the default origins for remix */ 7 | export async function getOriginsFromUrl(url: string) { 8 | const res = await fetch(url) 9 | return res.json() 10 | } 11 | 12 | 13 | export function getDevmodeOrigins({ devMode }: Partial>) { 14 | const localhost = devMode.port ? [ 15 | `http://127.0.0.1:${devMode.port}`, 16 | `http://localhost:${devMode.port}`, 17 | `https://127.0.0.1:${devMode.port}`, 18 | `https://localhost:${devMode.port}`, 19 | ] : [] 20 | const devOrigins = devMode.origins 21 | ? (typeof devMode.origins === 'string') ? [devMode.origins] : devMode.origins 22 | : [] 23 | return [ ...localhost, ...devOrigins ] 24 | } 25 | 26 | 27 | /** 28 | * Check if the sender has the right origin 29 | * @param origin The origin of the incoming message 30 | * @param options client plugin options 31 | */ 32 | export async function checkOrigin(origin: string, options: Partial> = {}) { 33 | let origins = [] 34 | if (options.allowOrigins) { 35 | if (Array.isArray(options.allowOrigins)) { 36 | origins = origins.concat(options.allowOrigins) 37 | } else { 38 | const allOrigins = await getOriginsFromUrl(options.allowOrigins) 39 | origins = origins.concat(allOrigins) 40 | } 41 | } else if (options.devMode) { 42 | const devModes = getDevmodeOrigins(options) 43 | origins = origins.concat(devModes) 44 | } else { 45 | return true 46 | } 47 | return origins.includes(origin) 48 | } 49 | -------------------------------------------------------------------------------- /packages/api/doc/unit-testing.md: -------------------------------------------------------------------------------- 1 | # Content Import 2 | 3 | - Name in Remix: `solidityUnitTesting` 4 | - kind: `unitTesting` 5 | 6 | |Type |Name |Description | 7 | |---------|-----------------------|------------| 8 | |_method_ |`testFromPath` |Run a solidity test that is inside the file system 9 | |_method_ |`testFromSource` |Run a solidity test file from the source 10 | 11 | ## Examples 12 | 13 | ### Methods 14 | `testFromPath`: Run a solidity test that is inside the file system 15 | ```typescript 16 | const path = "browser/ballot_test.sol" 17 | 18 | const result = await client.call('solidityUnitTesting', 'testFromPath', path) 19 | // OR 20 | const result = await client.solidityUnitTesting.testFromPath(path) 21 | ``` 22 | 23 | `testFromSource`: Run a solidity test file from the source 24 | ```typescript 25 | const testFile = ` 26 | pragma solidity >=0.5.0 <0.6.0; 27 | import "remix_tests.sol"; 28 | import "./HelloWorld.sol"; // HelloWorl.sol must be in "browser" 29 | 30 | contract HelloWorldTest { 31 | HelloWorld helloWorld; 32 | function beforeEach() public { 33 | helloWorld = new HelloWorld(); 34 | } 35 | 36 | function checkPrint () public { 37 | string memory result = helloWorld.print(); 38 | Assert.equal(result, string('Hello World!'), "Method 'print' should return 'Hello World!'"); 39 | } 40 | } 41 | ` 42 | 43 | const result = await client.call('solidityUnitTesting', 'testFromSource', testFile) 44 | // OR 45 | const result = await client.solidityUnitTesting.testFromSource(testFile) 46 | ``` 47 | 48 | ## Types 49 | `ContentImport`: An object that describes the returned file 50 | ```typescript 51 | export interface UnitTestResult { 52 | totalFailing: number 53 | totalPassing: number 54 | totalTime: number 55 | errors: UnitTestError[] 56 | } 57 | ``` 58 | 59 | > Type Definitions can be found [here](../src/lib/unit-testing/type.ts) -------------------------------------------------------------------------------- /packages/api/src/lib/file-system/file-manager/api.ts: -------------------------------------------------------------------------------- 1 | import { Folder } from './type' 2 | import { StatusEvents } from '@remixproject/plugin-utils' 3 | 4 | export interface IFileSystem { 5 | events: { 6 | currentFileChanged: (file: string) => void 7 | fileSaved: (file: string) => void 8 | fileAdded: (file: string) => void 9 | folderAdded: (file: string) => void 10 | fileRemoved: (file: string) => void 11 | fileClosed: (file: string) => void 12 | noFileSelected: ()=> void 13 | fileRenamed: (oldName: string, newName:string, isFolder: boolean) => void 14 | } & StatusEvents 15 | methods: { 16 | /** Open the content of the file in the context (eg: Editor) */ 17 | open(path: string): void 18 | /** Set the content of a specific file */ 19 | writeFile(path: string, data: string): void 20 | /** Return the content of a specific file */ 21 | readFile(path: string): string 22 | /** Change the path of a file */ 23 | rename(oldPath: string, newPath: string): void 24 | /** Upsert a file with the content of the source file */ 25 | copyFile(src: string, dest: string): void 26 | /** Create a directory */ 27 | mkdir(path: string): void 28 | /** Get the list of files in the directory */ 29 | readdir(path: string): string[] 30 | /** Removes a file or directory recursively */ 31 | remove(path: string): void 32 | /** Get the name of the file currently focused if any */ 33 | getCurrentFile(): string 34 | /** close all files */ 35 | closeAllFiles(): void 36 | /** close a file */ 37 | closeFile(): void 38 | // Old API 39 | /** @deprecated Use readdir */ 40 | getFolder(path: string): Folder 41 | /** @deprecated Use readFile */ 42 | getFile(path: string): string 43 | /** @deprecated Use writeFile */ 44 | setFile(path: string, content: string): void 45 | /** @deprecated Use open */ 46 | switchFile(path: string): void 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/utils/src/lib/types/api.ts: -------------------------------------------------------------------------------- 1 | import { StatusEvents } from './status' 2 | 3 | export interface Api { 4 | events: { 5 | [key: string]: (...args: any[]) => void 6 | } & StatusEvents 7 | methods: { 8 | [key: string]: (...args: any[]) => void 9 | } 10 | } 11 | 12 | // Used by plugin.on and plugin.emit 13 | export type EventKey = Extract 14 | export type EventParams> = T extends Api 15 | ? Parameters 16 | : any[] 17 | export type EventCallback> = T extends Api 18 | ? T['events'][K] 19 | : (...payload: any[]) => void 20 | 21 | // Used by plugin.call 22 | export type MethodKey = Extract 23 | export type MethodParams> = T extends Api 24 | ? Parameters 25 | : any[] 26 | 27 | ///////// 28 | // API // 29 | ///////// 30 | 31 | // Get the events of the Api 32 | export interface EventApi { 33 | on: >(name: event, cb: T['events'][event]) => void 34 | } 35 | // Get the methods of the Api 36 | export type MethodApi = { 37 | [m in Extract]: ( 38 | ...args: Parameters 39 | ) => Promise> 40 | } 41 | // Create the Api interface 42 | export type CustomApi = EventApi & MethodApi 43 | 44 | /** A map of Api used to describe all the plugin's api in the project */ 45 | export type ApiMap = Readonly> 46 | 47 | /** A map of plugin based on the ApiMap. It enforces the PluginEngine */ 48 | export type PluginApi = { 49 | [name in keyof T]: CustomApi 50 | } 51 | 52 | // The interface that a Plugin should implement 53 | export type API = { 54 | [M in keyof T['methods']]: T['methods'][M] | Promise 55 | } 56 | -------------------------------------------------------------------------------- /examples/example/engine/web/src/app/plugins/theme.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { ThemePlugin } from '@remixproject/engine-web'; 3 | import { Engine } from '../engine'; 4 | 5 | const light = { 6 | brightness: 'light', 7 | fontFamily: 'Arial,"Helvetica Neue",Helvetica,sans-serif', 8 | colors: { 9 | surface: 'white', 10 | background: '#fafafa', // light grey 11 | foreground: 'black', 12 | primary: '#3f51b5', // indigo 13 | primaryContrast: 'white', 14 | secondary: '#e91e63', // pink 15 | secondaryContrast: 'rgba(white, 0.7)', 16 | success: '#4caf50', // green 17 | successContrast: 'rgba(black, 0.87)', 18 | warn: '#ff9800', // orange 19 | warnContrast: 'white', 20 | error: '#f44336', // red 21 | errorContrast: 'white', 22 | disabled: 'rgba(0,0,0,.26)', 23 | }, 24 | } as const; 25 | 26 | const dark = { 27 | brightness: 'dark', 28 | fontFamily: 'Arial,"Helvetica Neue",Helvetica,sans-serif', 29 | colors: { 30 | surface: 'white', 31 | background: '#1E1E1E', 32 | foreground: 'fafafa', 33 | primary: '#3f51b5', // indigo 34 | primaryContrast: 'white', 35 | secondary: '#e91e63', // pink 36 | secondaryContrast: 'rgba(white, 0.7)', 37 | success: '#4caf50', // green 38 | successContrast: 'rgba(black, 0.87)', 39 | warn: '#ff9800', // orange 40 | warnContrast: 'white', 41 | error: '#f44336', // red 42 | errorContrast: 'white', 43 | disabled: 'rgba(0,0,0,.26)', 44 | }, 45 | } as const; 46 | 47 | @Injectable({ providedIn: 'root' }) 48 | export class Theme extends ThemePlugin { 49 | private themes = { dark, light }; 50 | constructor(private engine: Engine) { 51 | super() 52 | this.engine.register(this); 53 | } 54 | 55 | selectTheme(brightness: 'dark' | 'light') { 56 | const theme = this.themes[brightness]; 57 | this.setTheme(theme); 58 | } 59 | 60 | onActivation() { 61 | this.selectTheme('dark'); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /packages/engine/web/tests/view.spec.ts: -------------------------------------------------------------------------------- 1 | import { Engine, PluginManager } from '../../core/src' 2 | import { HostPlugin, ViewPlugin } from '../src' 3 | import { pluginManagerProfile } from '@remixproject/plugin-api' 4 | 5 | export class MockEngine extends Engine { 6 | onRegistration = jest.fn() 7 | } 8 | 9 | class MockManager extends PluginManager { 10 | constructor() { 11 | super(pluginManagerProfile) 12 | } 13 | } 14 | 15 | class MockHost extends HostPlugin { 16 | currentFocus = jest.fn() 17 | isFocus = jest.fn() // (name: string) => 18 | focus = jest.fn() // (name: string) => 19 | addView = jest.fn() // (profile: Profile) => 20 | removeView = jest.fn() // (name: string) => 21 | constructor() { 22 | super({ name: 'sidePanel', methods: [] }) 23 | } 24 | } 25 | 26 | class MockView extends ViewPlugin { 27 | render = jest.fn(() => ({ id: 'element' } as Element)) 28 | onActivation = jest.fn() 29 | onDeactivation = jest.fn() 30 | constructor() { 31 | super({ name: 'view', methods: [], location: 'sidePanel' }) 32 | } 33 | } 34 | 35 | describe('View Plugin', () => { 36 | let manager: MockManager 37 | let host: MockHost 38 | let view: MockView 39 | beforeEach(() => { 40 | view = new MockView() 41 | host = new MockHost() 42 | manager = new MockManager() 43 | const engine = new MockEngine() 44 | engine.register([manager, view, host]) 45 | }) 46 | 47 | test('Activate View call host addView', async () => { 48 | await manager.activatePlugin(['sidePanel', 'view']) 49 | expect(host.addView).toHaveBeenCalledWith(view.profile, { id: 'element' }) 50 | expect(view.onActivation).toHaveBeenCalledTimes(1) 51 | }) 52 | 53 | test('Deactive View call host removeView', async () => { 54 | await manager.activatePlugin(['sidePanel', 'view']) 55 | await manager.deactivatePlugin('view') 56 | expect(host.removeView).toHaveBeenCalledWith(view.profile) 57 | expect(view.onDeactivation).toHaveBeenCalledTimes(1) 58 | }) 59 | }) -------------------------------------------------------------------------------- /packages/engine/web/src/lib/theme.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from '@remixproject/engine' 2 | import { MethodApi } from '@remixproject/plugin-utils' 3 | import { ITheme, Theme, themeProfile } from '@remixproject/plugin-api' 4 | 5 | type DeepPartial = { 6 | [P in keyof T]?: DeepPartial; 7 | }; 8 | 9 | /** 10 | * Utils function to create a theme with default value 11 | * Default values are taken from material design with colors 12 | * - primary: indigo 13 | * - secondary: pink 14 | * - warn: orange 15 | * - error: red 16 | */ 17 | export function createTheme(params: DeepPartial = {}): Theme { 18 | return { 19 | brightness: 'light', 20 | fontFamily: 'Arial,"Helvetica Neue",Helvetica,sans-serif', 21 | space: 8, 22 | ...params, 23 | breakpoints: { 24 | xs: 0, 25 | sm: 600, 26 | md: 1024, 27 | lg: 1440, 28 | xl: 1920, 29 | ...params.breakpoints 30 | }, 31 | colors: { 32 | surface: 'white', 33 | background: '#fafafa', // light grey 34 | foreground: 'black', 35 | primary: '#3f51b5', // indigo 36 | primaryContrast: 'white', 37 | secondary: '#e91e63', // pink 38 | secondaryContrast: 'rgba(white, 0.7)', 39 | success: '#4caf50', // green 40 | successContrast: 'rgba(black, 0.87)', 41 | warn: '#ff9800', // orange 42 | warnContrast: 'white', 43 | error: '#f44336', // red 44 | errorContrast: 'white', 45 | disabled: 'rgba(0,0,0,.26)', 46 | ...params.colors 47 | }, 48 | } 49 | } 50 | 51 | export class ThemePlugin extends Plugin implements MethodApi { 52 | protected getTheme = createTheme 53 | protected theme: Theme 54 | constructor() { 55 | super(themeProfile) 56 | this.theme = this.getTheme() 57 | } 58 | 59 | /** Internal API to set the current theme */ 60 | setTheme(theme: DeepPartial) { 61 | this.theme = this.getTheme(theme) 62 | this.emit('themeChanged', this.theme) 63 | } 64 | 65 | /** External API to get the current theme */ 66 | async currentTheme(): Promise { 67 | return this.theme 68 | } 69 | 70 | } -------------------------------------------------------------------------------- /packages/plugin/child-process/src/lib/connector.ts: -------------------------------------------------------------------------------- 1 | import { ClientConnector, connectClient, applyApi, Client, PluginClient } from '@remixproject/plugin' 2 | import type { Message, Api, ApiMap } from '@remixproject/plugin-utils' 3 | import { IRemixApi } from '@remixproject/plugin-api' 4 | 5 | 6 | export interface WS { 7 | send(data: string): void 8 | on(type: 'message', cb: (event: string) => any): this 9 | } 10 | 11 | /** 12 | * This Websocket connector works with the library `ws` 13 | */ 14 | export class WebsocketConnector implements ClientConnector { 15 | 16 | constructor(private websocket: WS) {} 17 | 18 | /** Send a message to the engine */ 19 | send(message: Partial) { 20 | this.websocket.send(JSON.stringify(message)) 21 | } 22 | 23 | /** Get messae from the engine */ 24 | on(cb: (message: Partial) => void) { 25 | this.websocket.on('message', (event) => { 26 | try { 27 | cb(JSON.parse(event)) 28 | } catch (e) { 29 | console.error(e) 30 | } 31 | }) 32 | } 33 | } 34 | 35 | /** 36 | * Connect a Websocket plugin client to a web engine 37 | * @param client An optional websocket plugin client to connect to the engine. 38 | * 39 | * --------- 40 | * @example 41 | * ```typescript 42 | * const wss = new WebSocket.Server({ port: 8080 }); 43 | * wss.on('connection', (ws) => { 44 | * const client = createClient(ws) 45 | * }) 46 | * ``` 47 | * --------- 48 | * @example 49 | * ```typescript 50 | * class MyPlugin extends PluginClient { 51 | * methods = ['hello'] 52 | * hello() { 53 | * console.log('Hello World') 54 | * } 55 | * } 56 | * const wss = new WebSocket.Server({ port: 8080 }); 57 | * wss.on('connection', (ws) => { 58 | * const client = createClient(ws, new MyPlugin()) 59 | * }) 60 | * ``` 61 | */ 62 | export const createClient = < 63 | P extends Api, 64 | App extends ApiMap = Readonly 65 | >(websocket: WS, client: PluginClient = new PluginClient()): Client => { 66 | const c = client as any 67 | connectClient(new WebsocketConnector(websocket), c) 68 | applyApi(c) 69 | return c 70 | } 71 | -------------------------------------------------------------------------------- /packages/plugin/electron/src/lib/electronBasePlugin.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from "@remixproject/engine"; 2 | import { PluginClient } from "@remixproject/plugin"; 3 | import { Profile } from "@remixproject/plugin-utils"; 4 | import { BrowserWindow } from "electron"; 5 | import { createElectronClient } from "./electronPluginClient"; 6 | 7 | export interface ElectronBasePluginInterface { 8 | createClient(windowId: number): Promise; 9 | closeClient(windowId: number): Promise; 10 | } 11 | 12 | export abstract class ElectronBasePlugin extends Plugin implements ElectronBasePluginInterface { 13 | clients: ElectronBasePluginClient[] = []; 14 | clientClass: any 15 | clientProfile: Profile 16 | constructor(profile: Profile, clientProfile: Profile, clientClass: any) { 17 | super(profile); 18 | this.methods = ['createClient', 'closeClient']; 19 | this.clientClass = clientClass; 20 | this.clientProfile = clientProfile; 21 | } 22 | 23 | async createClient(webContentsId: number): Promise { 24 | if (this.clients.find(client => client.webContentsId === webContentsId)) return true 25 | const client = new this.clientClass(webContentsId, this.clientProfile); 26 | this.clients.push(client); 27 | return new Promise((resolve, reject) => { 28 | client.onload(() => { 29 | resolve(true) 30 | }) 31 | }) 32 | } 33 | async closeClient(windowId: number): Promise { 34 | this.clients = this.clients.filter(client => client.webContentsId !== windowId) 35 | return true; 36 | } 37 | } 38 | 39 | export class ElectronBasePluginClient extends PluginClient { 40 | window: Electron.BrowserWindow; 41 | webContentsId: number; 42 | constructor(webcontentsid: number, profile: Profile, methods: string[] = []) { 43 | super(); 44 | this.methods = profile.methods; 45 | this.webContentsId = webcontentsid; 46 | BrowserWindow.getAllWindows().forEach((window) => { 47 | if (window.webContents.id === webcontentsid) { 48 | this.window = window; 49 | } 50 | }); 51 | createElectronClient(this, profile, this.window); 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /packages/engine/core/doc/connector/plugin-connector.md: -------------------------------------------------------------------------------- 1 | # Develop & Publish a Plugin Connector 2 | 3 | ## Install 4 | ```bash 5 | npm install @remixproject/engine@next 6 | ``` 7 | 8 | ## Create your connector 9 | Create a file `index.ts` 10 | 11 | ```typescript 12 | import { PluginConnector, Profile, ExternalProfile, Message } from '@remixproject/engine' 13 | import io from 'socket.io-client'; 14 | 15 | export class SocketIOPlugin extends PluginConnector { 16 | socket: SocketIOClient.Socket 17 | 18 | constructor(profile: Profile & ExternalProfile) { 19 | super(profile) 20 | } 21 | 22 | protected connect(url: string): void { 23 | this.socket = io(url) 24 | this.socket.on('connect', () => { 25 | this.socket.on('message', (msg: Message) => this.getMessage(msg)) 26 | }) 27 | } 28 | 29 | protected disconnect(): void { 30 | this.socket.close() 31 | } 32 | 33 | protected send(message: Partial): void { 34 | this.socket.send(message) 35 | } 36 | 37 | } 38 | ``` 39 | 40 | ## Build 41 | 42 | ``` 43 | npx tsc index --declaration 44 | ``` 45 | 46 | ## Package.json 47 | ```json 48 | { 49 | "name": "plugin-connector-socket.io", 50 | "main": "index.js", 51 | "types": "index.d.ts", 52 | "peerDependencies": { 53 | "@remixproject/engine": "next", 54 | "socket.io-client": "^2.3.0" 55 | } 56 | } 57 | ``` 58 | 59 | 60 | ## Publish 61 | ``` 62 | npm publish 63 | ``` 64 | 65 | ---- 66 | 67 | # Use a Plugin Connector 68 | Here is how to use your plugin connector in an engine : 69 | 70 | ## Install 71 | ``` 72 | npm install @remixproject/engine@next plugin-connector-socket.io socket.io-client 73 | ``` 74 | 75 | ## Create a client 76 | ```typescript 77 | import { PluginManager, Engine, Plugin } from '@remixproject/engine' 78 | import { SocketIOPlugin } from 'plugin-connector-socket.io' 79 | 80 | const manager = new PluginManager() 81 | const engine = new Engine() 82 | const plugin = new SocketIOPlugin({ name: 'socket', url: 'http://localhost:3000' }) 83 | 84 | // Register plugins 85 | engine.register([manager, plugin]) 86 | 87 | // Activate plugins 88 | manager.activatePlugin('socket') 89 | ``` -------------------------------------------------------------------------------- /packages/plugin/core/tests/api.spec.ts: -------------------------------------------------------------------------------- 1 | import { PluginClient, createApi, getApiMap } from '../src' 2 | import { Api, ExternalProfile, CustomApi, callEvent, listenEvent, StatusEvents, Profile, LocationProfile } from '@remixproject/plugin-utils' 3 | 4 | interface TestApi extends Api { 5 | events: { 6 | event: (isTrue: boolean) => void 7 | } & StatusEvents 8 | methods: { 9 | method: (isTrue: boolean) => boolean 10 | } 11 | } 12 | 13 | const profile: Profile & ExternalProfile & LocationProfile = { 14 | name: 'test', 15 | methods: ['method'], 16 | location: 'sidePanel', 17 | url: 'url' 18 | } 19 | 20 | describe('Client Api', () => { 21 | let client: PluginClient 22 | let api: CustomApi 23 | beforeEach(() => { 24 | client = new PluginClient() 25 | client['isLoaded'] = true 26 | api = createApi(client, profile) 27 | }) 28 | 29 | test('Should create an Api', () => { 30 | expect(api).toBeDefined() 31 | expect(api.on).toBeDefined() 32 | expect(api.method).toBeDefined() 33 | }) 34 | 35 | test('"Method" should send a message', done => { 36 | client.events.on('send', message => { 37 | expect(message).toEqual({ 38 | action: 'request', 39 | name: 'test', 40 | key: 'method', 41 | payload: [true], 42 | id: 1, 43 | }) 44 | done() 45 | }) 46 | api.method(true) 47 | }) 48 | 49 | test('"Method" should return a promise', done => { 50 | client.events.on('send', ({ name, key, id, payload }) => { 51 | client.events.emit(callEvent(name, key, id), payload[0]) 52 | }) 53 | api.method(true).then(isTrue => { 54 | expect(isTrue).toBeTruthy() 55 | done() 56 | }) 57 | }) 58 | 59 | test('"Event" should emit an event', done => { 60 | api.on('event', isTrue => { 61 | expect(isTrue).toBeTruthy() 62 | done() 63 | }) 64 | client.events.emit(listenEvent('test', 'event'), true) 65 | }) 66 | 67 | test('getApiMap returns a map of API', () => { 68 | const { test } = getApiMap(client, { test: profile }) 69 | expect(test.on).toBeDefined() 70 | expect(test.method).toBeDefined() 71 | }) 72 | 73 | }) 74 | -------------------------------------------------------------------------------- /packages/api/doc/udapp.md: -------------------------------------------------------------------------------- 1 | # Udapp 2 | 3 | - Name in Remix: `udapp` 4 | - kind: `udapp` 5 | 6 | The udapp exposes an interface for interacting with the account and transaction. 7 | 8 | |Type |Name |Description 9 | |---------|---------------------|-- 10 | |_event_ |`newTransaction` |Triggered when a new transaction has been sent. 11 | |_method_ |`sendTransaction` |Send a transaction **only for testing networks**. 12 | |_method_ |`getAccounts` |Get an array with the accounts exposed. 13 | |_method_ |`createVMAccount` |Add an account if using the VM provider. 14 | 15 | ## Examples 16 | 17 | ### Events 18 | `newTransaction`: Triggered when a new transaction has been sent. 19 | ```typescript 20 | client.udapp.on('newTransaction', (tx: RemixTx) => { 21 | // Do something 22 | }) 23 | // OR 24 | client.on('udapp', 'newTransaction', (tx: RemixTx) => { 25 | // Do something 26 | }) 27 | ``` 28 | 29 | ### Methods 30 | `sendTransaction`: Send a transaction **only for testing networks**. 31 | ```typescript 32 | const transaction: RemixTx = { 33 | gasLimit: '0x2710', 34 | from: '0xca35b7d915458ef540ade6068dfe2f44e8fa733c', 35 | to: '0xca35b7d915458ef540ade6068dfe2f44e8fa733c' 36 | data: '0x...', 37 | value: '0x00', 38 | useCall: false 39 | } 40 | const receipt = await client.udapp.sendTransaction(transaction) 41 | // OR 42 | const receipt = await client.call('udapp', 'sendTransaction', transaction) 43 | ``` 44 | 45 | `getAccounts`: Get an array with the accounts exposed. 46 | ```typescript 47 | const accounts = await client.udapp.getAccounts() 48 | // OR 49 | const accounts = await client.call('udapp', 'getAccounts') 50 | ``` 51 | 52 | `createVMAccount`: Add an account if using the VM provider. 53 | ```typescript 54 | const privateKey = "71975fbf7fe448e004ac7ae54cad0a383c3906055a75468714156a07385e96ce" 55 | const balance = "0x56BC75E2D63100000" 56 | const address = await client.udapp.createVMAccount({ privateKey, balance }) 57 | // OR 58 | const address = await client.call('udapp', 'createVMAccount', { privateKey, balance }) 59 | ``` 60 | 61 | ## Types 62 | `RemixTx`: A modified version of the transaction for Remix. 63 | `RemixTxReceipt`: A modified version of the transaction receipt for Remix. 64 | 65 | 66 | > Type Definitions can be found [here](../src/lib/udapp/type.ts) -------------------------------------------------------------------------------- /packages/engine/core/doc/connector/client-connector.md: -------------------------------------------------------------------------------- 1 | # Develop & Publish a Client Connector 2 | 3 | ## Install 4 | ```bash 5 | npm install @remixproject/plugin@next 6 | ``` 7 | 8 | ## Create your connector 9 | Create a file `index.ts` 10 | 11 | ```typescript 12 | import { ClientConnector, createConnectorClient, PluginClient, Message } from '@remixproject/plugin' 13 | 14 | export class SocketIOConnector implements ClientConnector { 15 | 16 | constructor(private socket) {} 17 | send(message: Partial) { 18 | this.socket.emit('message', message) 19 | } 20 | on(cb: (message: Partial) => void) { 21 | this.socket.on('message', (msg) => cb(msg)) 22 | } 23 | } 24 | 25 | // A simple wrapper function for the plugin developer 26 | export function createSocketIOClient(socket, client?: PluginClient) { 27 | const connector = new SocketIOConnector(socket) 28 | return createConnectorClient(connector, client) 29 | } 30 | ``` 31 | 32 | ## Build 33 | 34 | ``` 35 | npx tsc index --declaration 36 | ``` 37 | 38 | ## Package.json 39 | ```json 40 | { 41 | "name": "client-connector-socket.io", 42 | "main": "index.js", 43 | "types": "index.d.ts", 44 | "dependencies": { 45 | "@remixproject/plugin": "next" 46 | }, 47 | "peerDependencies": { 48 | "socket.io": "^2.3.0" 49 | } 50 | } 51 | ``` 52 | 53 | Some notes here : 54 | - We use `dependancies` for `@remixproject/plugin` as this is the base code for your connector. 55 | - We use `peerDependencies` for the library we wrap (here `socket.io`), as we want to let the user choose his version of it. 56 | 57 | ## Publish 58 | ``` 59 | npm publish 60 | ``` 61 | 62 | ---- 63 | 64 | # Use a Client Connector 65 | Here is how to use your client connector in a plugin : 66 | 67 | ## Install 68 | ``` 69 | npm install client-connector-socket.io socket.io 70 | ``` 71 | 72 | ## Create a client 73 | This example is an implementation of the [Server documentation from socket.io](https://socket.io/docs/server-api/). 74 | ```typescript 75 | const { createSocketIOClient } = require('client-connector-socket.io') 76 | const http = require('http').createServer(); 77 | const io = require('socket.io')(http); 78 | 79 | io.on('connection', async (socket) => { 80 | const client = createSocketIOClient(socket) 81 | await client.onload() 82 | const code = await client.call('fileManager', 'read', 'Ballot.sol') 83 | }); 84 | 85 | http.listen(3000); 86 | ``` --------------------------------------------------------------------------------