diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 3aca4eab2a..c61c11bfc9 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -1,13 +1,15 @@ lockfileVersion: 5.3 specifiers: - '@microsoft/api-extractor': ~7.18.4 + '@microsoft/api-extractor': ^7.18.4 '@rush-temp/core': file:./projects/core.tgz '@rush-temp/platform': file:./projects/platform.tgz '@rush-temp/platform-rig': file:./projects/platform-rig.tgz + '@rush-temp/server': file:./projects/server.tgz '@rushstack/heft': ^0.35.0 '@rushstack/heft-jest-plugin': ~0.1.15 '@types/heft-jest': ^1.0.2 + '@types/node': ^16.4.10 '@typescript-eslint/eslint-plugin': '4' '@typescript-eslint/parser': ^4.0.0 eslint: ^7.32.0 @@ -16,17 +18,21 @@ specifiers: eslint-plugin-node: '11' eslint-plugin-promise: '4' intl-messageformat: ^9.7.1 + jwt-simple: ^0.5.6 simplytyped: ^3.3.0 typescript: ^4.3.5 + ws: ^8.0.0 dependencies: '@microsoft/api-extractor': 7.18.4 - '@rush-temp/core': file:projects/core.tgz_typescript@4.3.5 - '@rush-temp/platform': file:projects/platform.tgz - '@rush-temp/platform-rig': file:projects/platform-rig.tgz + '@rush-temp/core': file:projects/core.tgz_6c259fadfeb3a4b20890aefe87070b8b + '@rush-temp/platform': file:projects/platform.tgz_6c259fadfeb3a4b20890aefe87070b8b + '@rush-temp/platform-rig': file:projects/platform-rig.tgz_6ab28797e7a22071465f7d680ae81ae5 + '@rush-temp/server': file:projects/server.tgz_6c259fadfeb3a4b20890aefe87070b8b '@rushstack/heft': 0.35.0 '@rushstack/heft-jest-plugin': 0.1.15_@rushstack+heft@0.35.0 '@types/heft-jest': 1.0.2 + '@types/node': 16.4.10 '@typescript-eslint/eslint-plugin': 4.28.5_a8e83fcad666e1ba86be4b2e27a20aea '@typescript-eslint/parser': 4.28.5_eslint@7.32.0+typescript@4.3.5 eslint: 7.32.0 @@ -35,8 +41,10 @@ dependencies: eslint-plugin-node: 11.1.0_eslint@7.32.0 eslint-plugin-promise: 4.3.1 intl-messageformat: 9.8.1 + jwt-simple: 0.5.6 simplytyped: 3.3.0_typescript@4.3.5 typescript: 4.3.5 + ws: 8.0.0 packages: @@ -741,26 +749,6 @@ packages: jsonpath-plus: 4.0.0 dev: false - /@rushstack/heft-jest-plugin/0.1.15: - resolution: {integrity: sha512-uWJ+wQPHW9LY+74jICdtRe/wvwbQPbq61p1BgNwY0alSoNeovv/J6K6QR6y9Ci8PYzwNiegtqkdoyFg9g4TtMQ==} - peerDependencies: - '@rushstack/heft': ^0.35.0 - dependencies: - '@jest/core': 25.4.0 - '@jest/reporters': 25.4.0 - '@jest/transform': 25.4.0 - '@rushstack/heft-config-file': 0.6.1 - '@rushstack/node-core-library': 3.39.1 - jest-config: 25.4.0 - jest-snapshot: 25.4.0 - lodash: 4.17.21 - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - utf-8-validate - dev: false - /@rushstack/heft-jest-plugin/0.1.15_@rushstack+heft@0.35.0: resolution: {integrity: sha512-uWJ+wQPHW9LY+74jICdtRe/wvwbQPbq61p1BgNwY0alSoNeovv/J6K6QR6y9Ci8PYzwNiegtqkdoyFg9g4TtMQ==} peerDependencies: @@ -952,6 +940,12 @@ packages: resolution: {integrity: sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==} dev: false + /@types/ws/7.4.7: + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + dependencies: + '@types/node': 16.4.10 + dev: false + /@types/yargs-parser/20.2.1: resolution: {integrity: sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==} dev: false @@ -3490,6 +3484,11 @@ packages: verror: 1.10.0 dev: false + /jwt-simple/0.5.6: + resolution: {integrity: sha512-40aUybvhH9t2h71ncA1/1SbtTNCVZHgsTsTgqPUxGWDmUDrXyDf2wMNQKEbdBjbf4AI+fQhbECNTV6lWxQKUzg==} + engines: {node: '>= 0.4.0'} + dev: false + /kind-of/3.2.2: resolution: {integrity: sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=} engines: {node: '>=0.10.0'} @@ -5114,6 +5113,19 @@ packages: optional: true dev: false + /ws/8.0.0: + resolution: {integrity: sha512-6AcSIXpBlS0QvCVKk+3cWnWElLsA6SzC0lkQ43ciEglgXJXiCWK3/CGFEJ+Ybgp006CMibamAsqOlxE9s4AvYA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + /xml-name-validator/3.0.0: resolution: {integrity: sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==} dev: false @@ -5166,57 +5178,88 @@ packages: commander: 2.20.3 dev: false - file:projects/core.tgz_typescript@4.3.5: - resolution: {integrity: sha512-gM4kVbLtQPRGrnJPjshrLTW81xCp1qmb1hNcRto1f9BOsHp1plS4AuePeg5GSuxOAx3/iYN/b67RBGc8zpKLVw==, tarball: file:projects/core.tgz} + file:projects/core.tgz_6c259fadfeb3a4b20890aefe87070b8b: + resolution: {integrity: sha512-4iqZRqHALr0XQc7M7ThP9gwgI61o+2YBB+M44mGj0igVPmqYWmnvTBHo8sxdBGDEtLdvbVKwCDR9fWXEDi/48w==, tarball: file:projects/core.tgz} id: file:projects/core.tgz name: '@rush-temp/core' version: 0.0.0 dependencies: '@types/heft-jest': 1.0.2 + '@typescript-eslint/eslint-plugin': 4.28.5_a8e83fcad666e1ba86be4b2e27a20aea + eslint: 7.32.0 + eslint-plugin-import: 2.23.4_eslint@7.32.0 + eslint-plugin-node: 11.1.0_eslint@7.32.0 + eslint-plugin-promise: 4.3.1 simplytyped: 3.3.0_typescript@4.3.5 transitivePeerDependencies: + - '@typescript-eslint/parser' + - supports-color - typescript dev: false - file:projects/platform-rig.tgz: - resolution: {integrity: sha512-kjMXo63GJVeYUiMoTOYnbDP7Hsm8JuAtKuFpZo2Hthm88EMxnxZTBHNJ3KkaPUW5HPWAyP/eWzSHG+4eEJixZA==, tarball: file:projects/platform-rig.tgz} + file:projects/platform-rig.tgz_6ab28797e7a22071465f7d680ae81ae5: + resolution: {integrity: sha512-VwGZVPcf2apIoa4sxQkIvW90B4otxf7ayw1jlTiZKQsQfwnLRKXvInMbIIAP0zCPRWIZdXXBYpUDm3dOJ/2bYQ==, tarball: file:projects/platform-rig.tgz} + id: file:projects/platform-rig.tgz name: '@rush-temp/platform-rig' version: 0.0.0 dependencies: '@microsoft/api-extractor': 7.18.4 '@rushstack/heft': 0.35.0 '@rushstack/heft-jest-plugin': 0.1.15_@rushstack+heft@0.35.0 - '@typescript-eslint/eslint-plugin': 4.28.5_a8e83fcad666e1ba86be4b2e27a20aea '@typescript-eslint/parser': 4.28.5_eslint@7.32.0+typescript@4.3.5 - eslint: 7.32.0 eslint-config-standard-with-typescript: 20.0.0_2e482f375e273d762fe67cbd5e194b49 - eslint-plugin-import: 2.23.4_eslint@7.32.0 - eslint-plugin-node: 11.1.0_eslint@7.32.0 - eslint-plugin-promise: 4.3.1 typescript: 4.3.5 transitivePeerDependencies: + - '@typescript-eslint/eslint-plugin' - bufferutil - canvas + - eslint + - eslint-plugin-import + - eslint-plugin-node + - eslint-plugin-promise - supports-color - utf-8-validate dev: false - file:projects/platform.tgz: - resolution: {integrity: sha512-5cFV2VVh65WRhdCjPXkit2cPAnJx3O7QwOXMfhxkhsqYDRMWKvqOfqHKCZLHly3izAt2hpZKHWKZSqpllMrNDQ==, tarball: file:projects/platform.tgz} + file:projects/platform.tgz_6c259fadfeb3a4b20890aefe87070b8b: + resolution: {integrity: sha512-ns2pvtr7PGSfs03rSNYXhC1HH7/2912s9f95jf8L1eakYalR0/d1f9sfNGgDrEqF7+q/tpQCmUoaExF5HndL6g==, tarball: file:projects/platform.tgz} + id: file:projects/platform.tgz name: '@rush-temp/platform' version: 0.0.0 dependencies: - '@rushstack/heft-jest-plugin': 0.1.15 '@types/heft-jest': 1.0.2 '@typescript-eslint/eslint-plugin': 4.28.5_a8e83fcad666e1ba86be4b2e27a20aea - '@typescript-eslint/parser': 4.28.5_eslint@7.32.0+typescript@4.3.5 eslint: 7.32.0 - eslint-config-standard-with-typescript: 20.0.0_2e482f375e273d762fe67cbd5e194b49 eslint-plugin-import: 2.23.4_eslint@7.32.0 eslint-plugin-node: 11.1.0_eslint@7.32.0 eslint-plugin-promise: 4.3.1 intl-messageformat: 9.8.1 - typescript: 4.3.5 transitivePeerDependencies: + - '@typescript-eslint/parser' - supports-color + - typescript + dev: false + + file:projects/server.tgz_6c259fadfeb3a4b20890aefe87070b8b: + resolution: {integrity: sha512-RNLOYCrfV7DpGNDy74lWtChPLzJkaP/Tb10vh3usOUf8kjByj8MXjhnKRgb8ZMn2MkkquQ+Pdz5Hi/tfcSsvxw==, tarball: file:projects/server.tgz} + id: file:projects/server.tgz + name: '@rush-temp/server' + version: 0.0.0 + dependencies: + '@types/heft-jest': 1.0.2 + '@types/node': 16.4.10 + '@types/ws': 7.4.7 + '@typescript-eslint/eslint-plugin': 4.28.5_a8e83fcad666e1ba86be4b2e27a20aea + eslint: 7.32.0 + eslint-plugin-import: 2.23.4_eslint@7.32.0 + eslint-plugin-node: 11.1.0_eslint@7.32.0 + eslint-plugin-promise: 4.3.1 + jwt-simple: 0.5.6 + ws: 8.0.0 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - bufferutil + - supports-color + - typescript + - utf-8-validate dev: false diff --git a/packages/core/package.json b/packages/core/package.json index bd68f0c494..7bcf04d9b7 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@anticrm/core", - "version": "0.5.0", + "version": "0.6.0", "main": "lib/index.js", "author": "Anticrm Platform Contributors", "license": "EPL-2.0", @@ -13,11 +13,16 @@ "format": "prettier --write 'src/**/*.{ts*,js*,yml}' && ts-standard --fix src" }, "devDependencies": { - "@anticrm/platform-rig":"~0.5.0", - "@types/heft-jest":"^1.0.2" + "@anticrm/platform-rig":"~0.6.0", + "@types/heft-jest":"^1.0.2", + "@typescript-eslint/eslint-plugin":"4", + "eslint-plugin-import":"2", + "eslint-plugin-promise":"4", + "eslint-plugin-node":"11", + "eslint":"^7.32.0" }, "dependencies": { - "@anticrm/platform": "~0.5.0", + "@anticrm/platform": "~0.6.0", "simplytyped": "^3.3.0" } } diff --git a/packages/platform-rig/package.json b/packages/platform-rig/package.json index ef32e9e93e..a0406285aa 100644 --- a/packages/platform-rig/package.json +++ b/packages/platform-rig/package.json @@ -1,6 +1,6 @@ { "name": "@anticrm/platform-rig", - "version": "0.5.0", + "version": "0.6.0", "scripts": { "build": "" }, @@ -13,12 +13,7 @@ "@typescript-eslint/parser":"^4.0.0" }, "dependencies": { - "@microsoft/api-extractor": "~7.18.4", - "@typescript-eslint/eslint-plugin":"4", - "eslint-plugin-promise":"4", - "eslint-plugin-import":"2", - "eslint-plugin-node":"11", - "typescript":"^4.3.5", - "eslint":"^7.32.0" + "@microsoft/api-extractor": "^7.18.4", + "typescript":"^4.3.5" } } diff --git a/packages/platform/package.json b/packages/platform/package.json index ef8336f46c..0ca6143ef9 100644 --- a/packages/platform/package.json +++ b/packages/platform/package.json @@ -1,6 +1,6 @@ { "name": "@anticrm/platform", - "version": "0.5.0", + "version": "0.6.0", "main": "lib/index.js", "author": "Anticrm Platform Contributors", "license": "EPL-2.0", @@ -13,11 +13,13 @@ "format": "prettier --write 'src/**/*.{ts*,js*,yml}' && ts-standard --fix src" }, "devDependencies": { - "@anticrm/platform-rig":"~0.5.0", - "@types/heft-jest":"^1.0.2" - }, - "peerDependencies": { - "@typescript-eslint/parser":"^4.0.0" + "@anticrm/platform-rig":"~0.6.0", + "@types/heft-jest":"^1.0.2", + "@typescript-eslint/eslint-plugin":"4", + "eslint-plugin-import":"2", + "eslint-plugin-promise":"4", + "eslint-plugin-node":"11", + "eslint":"^7.32.0" }, "dependencies": { "intl-messageformat": "^9.7.1" diff --git a/rush.json b/rush.json index c4a9cb9a30..0a412a810b 100644 --- a/rush.json +++ b/rush.json @@ -460,6 +460,11 @@ "packageName": "@anticrm/core", "projectFolder": "packages/core", "shouldPublish": true + }, + { + "packageName": "@anticrm/server", + "projectFolder": "server/server", + "shouldPublish": true } // // { diff --git a/server/server/.eslintrc.js b/server/server/.eslintrc.js new file mode 100644 index 0000000000..89f8151bd4 --- /dev/null +++ b/server/server/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + extends: ['./node_modules/@anticrm/platform-rig/profiles/default/config/eslint.config.json'], + parserOptions: { + project: './tsconfig.json' + } +} \ No newline at end of file diff --git a/server/server/config/rig.json b/server/server/config/rig.json new file mode 100644 index 0000000000..af1257a896 --- /dev/null +++ b/server/server/config/rig.json @@ -0,0 +1,18 @@ +// The "rig.json" file directs tools to look for their config files in an external package. +// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + + /** + * (Required) The name of the rig package to inherit from. + * It should be an NPM package name with the "-rig" suffix. + */ + "rigPackageName": "@anticrm/platform-rig" + + /** + * (Optional) Selects a config profile from the rig package. The name must consist of + * lowercase alphanumeric words separated by hyphens, for example "sample-profile". + * If omitted, then the "default" profile will be used." + */ + // "rigProfile": "your-profile-name" +} diff --git a/server/server/package.json b/server/server/package.json new file mode 100644 index 0000000000..5b9902e280 --- /dev/null +++ b/server/server/package.json @@ -0,0 +1,31 @@ +{ + "name": "@anticrm/server", + "version": "0.6.0", + "main": "lib/index.js", + "author": "Anticrm Platform Contributors", + "license": "EPL-2.0", + "scripts": { + "build": "heft build", + "build:docs": "api-extractor run --local", + "test": "jest", + "lint": "ts-standard src", + "lint:fix": "eslint --fix ./src", + "format": "prettier --write 'src/**/*.{ts*,js*,yml}' && ts-standard --fix src" + }, + "devDependencies": { + "@anticrm/platform-rig":"~0.6.0", + "@types/heft-jest":"^1.0.2", + "@types/node": "^16.4.10", + "@typescript-eslint/eslint-plugin":"4", + "eslint-plugin-import":"2", + "eslint-plugin-promise":"4", + "eslint-plugin-node":"11", + "eslint":"^7.32.0", + "@types/ws":"^7.4.7" + }, + "dependencies": { + "jwt-simple": "^0.5.6", + "ws": "^8.0.0", + "@anticrm/platform": "~0.6.0" + } +} diff --git a/server/server/src/__tests__/server.test.ts b/server/server/src/__tests__/server.test.ts new file mode 100644 index 0000000000..0dd1cfcd00 --- /dev/null +++ b/server/server/src/__tests__/server.test.ts @@ -0,0 +1,39 @@ +// +// Copyright © 2020, 2021 Anticrm Platform Contributors. +// Copyright © 2021 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import { start, _Token } from '../server' +import { encode } from 'jwt-simple' +import WebSocket from 'ws' + +describe('server', () => { + start(async () => ({}), 3333) + + function connect (): WebSocket { + const payload: _Token = { + workspace: 'latest' + } + const token = encode(payload, 'secret') + return new WebSocket('ws://localhost:3333/' + token) + } + + it('should connect to server', (done) => { + const conn = connect() + conn.on('open', () => { + conn.close() + done() + }) + }) +}) diff --git a/server/server/src/index.ts b/server/server/src/index.ts new file mode 100644 index 0000000000..a700de9f8e --- /dev/null +++ b/server/server/src/index.ts @@ -0,0 +1,28 @@ +// +// Copyright © 2020, 2021 Anticrm Platform Contributors. +// Copyright © 2021 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// import { start } from './server' + +// const mongodbUri = process.env.MONGODB_URI || 'mongodb://localhost:27017' + +// console.log('mongodb uri: ...' + mongodbUri.substring(25)) + +// start(18080, mongodbUri) + +/** + * @public + */ +export const x = 42 diff --git a/server/server/src/server.ts b/server/server/src/server.ts new file mode 100644 index 0000000000..86b555c31a --- /dev/null +++ b/server/server/src/server.ts @@ -0,0 +1,73 @@ +// +// Copyright © 2020, 2021 Anticrm Platform Contributors. +// Copyright © 2021 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import { readRequest, serialize } from '@anticrm/platform' +import { createServer, IncomingMessage } from 'http' +import WebSocket, { Server } from 'ws' +import { decode } from 'jwt-simple' + +/** + * @internal + */ +export interface _Token { + workspace: string +} + +async function handleRequest (service: S, ws: WebSocket, msg: string): Promise { + const request = readRequest(msg) + const f = (service as any)[request.method] + const result = await f.apply(null, request.params) + ws.send(serialize({ + id: request.id, + result + })) +} + +/** + * @public + * @param serviceFactory + * @param port + * @param host + */ +export function start (serviceFactory: () => Promise, port: number, host?: string): void { + // console.log('starting server on port ' + port + '...') + // console.log('host: ' + host) + + const connections: S[] = [] + + const wss = new Server({ noServer: true }) + // eslint-disable-next-line @typescript-eslint/no-misused-promises + wss.on('connection', async (ws: WebSocket, request: any, token: _Token) => { + const service = await serviceFactory() + connections.push(service) + // eslint-disable-next-line @typescript-eslint/no-misused-promises + ws.on('message', async (msg: string) => await handleRequest(service, ws, msg)) + }) + + const server = createServer() + server.on('upgrade', (request: IncomingMessage, socket, head: Buffer) => { + const token = request.url?.substring(1) // remove leading '/' + if (token === undefined) { + socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n') + socket.destroy() + } else { + const payload = decode(token, 'secret', false) + wss.handleUpgrade(request, socket, head, ws => wss.emit('connection', ws, request, payload)) + } + }) + + server.listen(port, host) +} diff --git a/server/server/tsconfig.json b/server/server/tsconfig.json new file mode 100644 index 0000000000..fffbf4c341 --- /dev/null +++ b/server/server/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "./node_modules/@anticrm/platform-rig/profiles/default/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "esModuleInterop": true + } +} \ No newline at end of file