mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-13 03:40:48 +00:00
tool update
Signed-off-by: Andrey Platov <andrey@hardcoreeng.com>
This commit is contained in:
parent
f3f4013fab
commit
f1f254b104
@ -91,7 +91,6 @@ specifiers:
|
||||
css-loader: ^5.2.1
|
||||
deep-equal: ^2.0.5
|
||||
dotenv-webpack: ^7.0.2
|
||||
esbuild: ^0.12.24
|
||||
eslint: ^7.32.0
|
||||
eslint-config-standard-with-typescript: ^20.0.0
|
||||
eslint-plugin-import: '2'
|
||||
@ -213,7 +212,6 @@ dependencies:
|
||||
css-loader: 5.2.7_webpack@5.48.0
|
||||
deep-equal: 2.0.5
|
||||
dotenv-webpack: 7.0.3_webpack@5.48.0
|
||||
esbuild: 0.12.24
|
||||
eslint: 7.32.0
|
||||
eslint-config-standard-with-typescript: 20.0.0_2e482f375e273d762fe67cbd5e194b49
|
||||
eslint-plugin-import: 2.23.4_eslint@7.32.0
|
||||
@ -3463,12 +3461,6 @@ packages:
|
||||
resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==}
|
||||
dev: false
|
||||
|
||||
/esbuild/0.12.24:
|
||||
resolution: {integrity: sha512-C0ibY+HsXzYB6L/pLWEiWjMpghKsIc58Q5yumARwBQsHl9DXPakW+5NI/Y9w4YXiz0PEP6XTGTT/OV4Nnsmb4A==}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
|
||||
/esbuild/0.12.26:
|
||||
resolution: {integrity: sha512-YmTkhPKjvTJ+G5e96NyhGf69bP+hzO0DscqaVJTi5GM34uaD4Ecj7omu5lJO+NrxCUBRhy2chONLK1h/2LwoXA==}
|
||||
hasBin: true
|
||||
@ -9431,7 +9423,7 @@ packages:
|
||||
'@types/heft-jest': 1.0.2
|
||||
'@types/node': 16.7.5
|
||||
'@typescript-eslint/eslint-plugin': 4.28.5_a8e83fcad666e1ba86be4b2e27a20aea
|
||||
esbuild: 0.12.24
|
||||
esbuild: 0.12.26
|
||||
eslint: 7.32.0
|
||||
eslint-plugin-import: 2.23.4_eslint@7.32.0
|
||||
eslint-plugin-node: 11.1.0_eslint@7.32.0
|
||||
@ -10124,12 +10116,14 @@ packages:
|
||||
dev: false
|
||||
|
||||
file:projects/tool.tgz_6c259fadfeb3a4b20890aefe87070b8b:
|
||||
resolution: {integrity: sha512-Z0BaX1B1yinHaiai353t9rj20BUpViVPFU9rX9LC0dA8wvHQ/5WY8jgEmhwrHYhq/+iauybdXG8tBCJLBQTeBQ==, tarball: file:projects/tool.tgz}
|
||||
resolution: {integrity: sha512-mb2zTxDp5DHlfEi7/b+0vGiTzSkQsIpDf3A5ZgT/zjugH4VCX2j8M7N7n+ZA1+KFdhw69egzQ3Hru0gCATaWEg==, tarball: file:projects/tool.tgz}
|
||||
id: file:projects/tool.tgz
|
||||
name: '@rush-temp/tool'
|
||||
version: 0.0.0
|
||||
dependencies:
|
||||
'@types/heft-jest': 1.0.2
|
||||
'@types/minio': 7.0.10
|
||||
'@types/node': 16.7.5
|
||||
'@typescript-eslint/eslint-plugin': 4.28.5_a8e83fcad666e1ba86be4b2e27a20aea
|
||||
commander: 8.1.0
|
||||
esbuild: 0.12.26
|
||||
@ -10137,12 +10131,13 @@ packages:
|
||||
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
|
||||
minio: 7.0.19
|
||||
mongodb: 4.1.1
|
||||
ts-node: 10.2.1_typescript@4.3.5
|
||||
ts-node: 10.2.1_eb14afb1492fcd444e277f1fdb668e87
|
||||
transitivePeerDependencies:
|
||||
- '@swc/core'
|
||||
- '@swc/wasm'
|
||||
- '@types/node'
|
||||
- '@typescript-eslint/parser'
|
||||
- supports-color
|
||||
- typescript
|
||||
|
@ -21,11 +21,19 @@
|
||||
"eslint-plugin-node":"11",
|
||||
"eslint":"^7.32.0",
|
||||
"ts-node":"^10.2.1",
|
||||
"esbuild":"^0.12.26"
|
||||
"esbuild":"^0.12.26",
|
||||
"@types/minio":"^7.0.10",
|
||||
"@types/node":"^16.7.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"mongodb":"^4.1.1",
|
||||
"commander":"^8.1.0",
|
||||
"@anticrm/account":"~0.6.0"
|
||||
"@anticrm/account":"~0.6.0",
|
||||
"jwt-simple":"^0.5.6",
|
||||
"@anticrm/contrib":"~0.6.0",
|
||||
"@anticrm/core":"~0.6.11",
|
||||
"@anticrm/contact":"~0.6.0",
|
||||
"@anticrm/workspace":"~0.6.0",
|
||||
"minio":"^7.0.19"
|
||||
}
|
||||
}
|
||||
|
@ -20,5 +20,7 @@ export MINIO_SECRET_KEY=$(kubectl get secret --namespace default minio -o jsonpa
|
||||
|
||||
kubectl run anticrm-tool --rm --tty -i --restart='Never' \
|
||||
--env="MONGO_URL=mongodb://root:$MONGODB_ROOT_PASSWORD@mng-mongodb:27017/" \
|
||||
--env="TRANSACTOR_URL=ws://transactor/" \
|
||||
--env="MINIO_ENDPOINT=minio" \
|
||||
--env="MINIO_ACCESS_KEY=$MINIO_ACCESS_KEY" \
|
||||
--env="MINIO_SECRET_KEY=$MINIO_SECRET_KEY" --image anticrm/tool --command -- bash
|
||||
|
@ -17,8 +17,51 @@
|
||||
import { program } from 'commander'
|
||||
import { MongoClient, Db } from 'mongodb'
|
||||
import { getAccount, createAccount, assignWorkspace, createWorkspace } from '@anticrm/account'
|
||||
import { createContributingClient } from '@anticrm/contrib'
|
||||
import core, { TxOperations } from '@anticrm/core'
|
||||
import { encode } from 'jwt-simple'
|
||||
import { Client } from 'minio'
|
||||
import { initWorkspace } from './workspace'
|
||||
|
||||
const mongodbUri = process.env.MONGO_URL ?? 'mongodb://localhost:27017'
|
||||
import contact from '@anticrm/contact'
|
||||
|
||||
const mongodbUri = process.env.MONGO_URL
|
||||
if (mongodbUri === undefined) {
|
||||
console.error('please provide mongodb url.')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const transactorUrl = process.env.TRANSACTOR_URL
|
||||
if (transactorUrl === undefined) {
|
||||
console.error('please provide transactor url.')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const minioEndpoint = process.env.MINIO_ENDPOINT
|
||||
if (minioEndpoint === undefined) {
|
||||
console.error('please provide minio endpoint')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const minioAccessKey = process.env.MINIO_ACCESS_KEY
|
||||
if (minioAccessKey === undefined) {
|
||||
console.error('please provide minio access key')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const minioSecretKey = process.env.MINIO_SECRET_KEY
|
||||
if (minioSecretKey === undefined) {
|
||||
console.error('please provide minio secret key')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const minio = new Client({
|
||||
endPoint: minioEndpoint,
|
||||
port: 9000,
|
||||
useSSL: false,
|
||||
accessKey: minioAccessKey,
|
||||
secretKey: minioSecretKey
|
||||
})
|
||||
|
||||
async function withDatabase (uri: string, f: (db: Db) => Promise<any>): Promise<void> {
|
||||
console.log(`connecting to database '${uri}'...`)
|
||||
@ -35,21 +78,40 @@ program
|
||||
.command('create-user <email>')
|
||||
.description('create user and corresponding account in master database')
|
||||
.requiredOption('-p, --password <password>', 'user password')
|
||||
.requiredOption('-f, --fullname <fullname>', 'full user name')
|
||||
.action(async (email, cmd) => {
|
||||
.requiredOption('-f, --first <firstname>', 'first name')
|
||||
.requiredOption('-l, --last <lastname>', 'first name')
|
||||
.action(async (email: string, cmd) => {
|
||||
return await withDatabase(mongodbUri, async (db) => {
|
||||
await createAccount(db, email, cmd.password)
|
||||
// await createContact(withTenant(client, cmd.workspace), email, cmd.fullname)
|
||||
console.log(`creating account ${cmd.firstname as string} ${cmd.lastname as string} (${email})...`)
|
||||
await createAccount(db, email, cmd.password, cmd.firstname, cmd.lastname)
|
||||
})
|
||||
})
|
||||
|
||||
program
|
||||
.command('assign-workspace <email> <workspace>')
|
||||
.description('assign workspace')
|
||||
.action(async (email, workspace, cmd) => {
|
||||
.action(async (email: string, workspace: string, cmd) => {
|
||||
return await withDatabase(mongodbUri, async (db) => {
|
||||
console.log(`assigning user ${email as string} to ${workspace as string}...`)
|
||||
console.log(`retrieveing account from ${email}...`)
|
||||
const account = await getAccount(db, email)
|
||||
if (account === null) {
|
||||
throw new Error('account not found')
|
||||
}
|
||||
console.log(`assigning user ${email} to ${workspace}...`)
|
||||
await assignWorkspace(db, email, workspace)
|
||||
const token = encode({ email: 'anticrm@hc.engineering', workspace }, 'secret')
|
||||
const url = new URL(`/${token}`, transactorUrl)
|
||||
const contrib = await createContributingClient(url.href)
|
||||
const txop = new TxOperations(contrib, core.account.System)
|
||||
await txop.createDoc(contact.class.Employee, contact.space.Employee, {
|
||||
firstName: account.first,
|
||||
lastName: account.last,
|
||||
city: 'Mountain View',
|
||||
channels: []
|
||||
})
|
||||
await txop.createDoc(core.class.Account, core.space.Model, {
|
||||
email
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -70,8 +132,7 @@ program
|
||||
.action(async (workspace, cmd) => {
|
||||
return await withDatabase(mongodbUri, async (db) => {
|
||||
await createWorkspace(db, workspace, cmd.organization)
|
||||
|
||||
// await initDatabase(withTenant(client, workspace))
|
||||
await initWorkspace(mongodbUri, workspace, transactorUrl, minio)
|
||||
})
|
||||
})
|
||||
|
||||
|
1490
dev/tool/src/model.tx.json
Normal file
1490
dev/tool/src/model.tx.json
Normal file
File diff suppressed because it is too large
Load Diff
59
dev/tool/src/workspace.ts
Normal file
59
dev/tool/src/workspace.ts
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// 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 { MongoClient, Document } from 'mongodb'
|
||||
import core, { DOMAIN_TX, Tx } from '@anticrm/core'
|
||||
import { createContributingClient } from '@anticrm/contrib'
|
||||
import { encode } from 'jwt-simple'
|
||||
import { Client } from 'minio'
|
||||
|
||||
import * as txJson from './model.tx.json'
|
||||
|
||||
const txes = (txJson as any).default as Tx[]
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export async function initWorkspace (mongoUrl: string, dbName: string, clientUrl: string, minio: Client): Promise<void> {
|
||||
const client = new MongoClient(mongoUrl)
|
||||
try {
|
||||
await client.connect()
|
||||
const db = client.db(dbName)
|
||||
|
||||
console.log('dropping database...')
|
||||
await db.dropDatabase()
|
||||
|
||||
console.log('creating model...')
|
||||
const model = txes.filter(tx => tx.objectSpace === core.space.Model)
|
||||
const result = await db.collection(DOMAIN_TX).insertMany(model as Document[])
|
||||
console.log(`${result.insertedCount} model transactions inserted.`)
|
||||
|
||||
console.log('creating data...')
|
||||
const data = txes.filter(tx => tx.objectSpace !== core.space.Model)
|
||||
const token = encode({ email: 'anticrm@hc.engineering', workspace: dbName }, 'secret')
|
||||
const url = new URL(`/${token}`, clientUrl)
|
||||
const contrib = await createContributingClient(url.href)
|
||||
for (const tx of data) {
|
||||
await contrib.tx(tx)
|
||||
}
|
||||
contrib.close()
|
||||
|
||||
console.log('create minio bucket')
|
||||
if (!await minio.bucketExists(dbName)) { await minio.makeBucket(dbName, 'k8s') }
|
||||
} finally {
|
||||
await client.close()
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib"
|
||||
"outDir": "./lib",
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
//
|
||||
|
||||
import { mergeIds } from '@anticrm/platform'
|
||||
import type { Ref, Space, Class, Type } from '@anticrm/core'
|
||||
import type { Ref, Class, Type } from '@anticrm/core'
|
||||
import contact, { contactId } from '@anticrm/contact'
|
||||
import type { ChannelProvider, Channel } from '@anticrm/contact'
|
||||
import type { AnyComponent } from '@anticrm/ui'
|
||||
@ -35,8 +35,5 @@ export const ids = mergeIds(contactId, contact, {
|
||||
},
|
||||
class: {
|
||||
TypeChannels: '' as Ref<Class<Type<Channel[]>>>
|
||||
},
|
||||
space: {
|
||||
Employee: '' as Ref<Space>
|
||||
}
|
||||
})
|
||||
|
@ -16,33 +16,10 @@
|
||||
|
||||
import { Builder } from '@anticrm/model'
|
||||
|
||||
import core from '@anticrm/core'
|
||||
import contact from '@anticrm/model-contact'
|
||||
import recruit from '@anticrm/model-recruit'
|
||||
|
||||
export function createDemo (builder: Builder): void {
|
||||
builder.createDoc(contact.class.Employee, contact.space.Employee, {
|
||||
firstName: 'Rosamund',
|
||||
lastName: 'Chen',
|
||||
city: 'Mountain View',
|
||||
channels: []
|
||||
})
|
||||
|
||||
builder.createDoc(core.class.Account, core.space.Model, {
|
||||
email: 'rosamund@hc.engineering'
|
||||
})
|
||||
|
||||
builder.createDoc(contact.class.Employee, contact.space.Employee, {
|
||||
firstName: 'Elon',
|
||||
lastName: 'Musk',
|
||||
city: 'Bel Air',
|
||||
channels: []
|
||||
})
|
||||
|
||||
builder.createDoc(core.class.Account, core.space.Model, {
|
||||
email: 'elon@hc.engineering'
|
||||
})
|
||||
|
||||
builder.createDoc(recruit.class.Candidate, recruit.space.CandidatesPublic, {
|
||||
firstName: 'Andrey',
|
||||
lastName: 'P.',
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
import { plugin } from '@anticrm/platform'
|
||||
import type { Plugin, Asset } from '@anticrm/platform'
|
||||
import type { Doc, Ref, Class, UXObject } from '@anticrm/core'
|
||||
import type { Doc, Ref, Class, UXObject, Space } from '@anticrm/core'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -90,5 +90,8 @@ export default plugin(contactId, {
|
||||
WhatsApp: '' as Asset,
|
||||
Youtube: '' as Asset,
|
||||
GitHub: '' as Asset
|
||||
},
|
||||
space: {
|
||||
Employee: '' as Ref<Space>
|
||||
}
|
||||
})
|
||||
|
@ -51,6 +51,8 @@ const accountPlugin = plugin(accountId, {
|
||||
export interface Account {
|
||||
_id: ObjectId
|
||||
email: string
|
||||
first: string
|
||||
last: string
|
||||
hash: Binary
|
||||
salt: Binary
|
||||
workspaces: ObjectId[]
|
||||
@ -161,7 +163,7 @@ export async function login (db: Db, email: string, password: string, workspace:
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export async function createAccount (db: Db, email: string, password: string): Promise<AccountInfo> {
|
||||
export async function createAccount (db: Db, email: string, password: string, first: string, last: string): Promise<AccountInfo> {
|
||||
const salt = randomBytes(32)
|
||||
const hash = hashWithSalt(password, salt)
|
||||
|
||||
@ -174,11 +176,15 @@ export async function createAccount (db: Db, email: string, password: string): P
|
||||
email,
|
||||
hash,
|
||||
salt,
|
||||
first,
|
||||
last,
|
||||
workspaces: []
|
||||
})
|
||||
|
||||
return {
|
||||
_id: insert.insertedId,
|
||||
first,
|
||||
last,
|
||||
email,
|
||||
workspaces: []
|
||||
}
|
||||
|
@ -14,17 +14,21 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { Tx, WithTx } from '@anticrm/core'
|
||||
import { Tx, Storage, Class, Doc, DocumentQuery, FindOptions, Ref, FindResult } from '@anticrm/core'
|
||||
import { serialize } from '@anticrm/platform'
|
||||
import WebSocket from 'ws'
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export class ContributingClient implements WithTx {
|
||||
export class ContributingClient implements Storage {
|
||||
constructor (private readonly websocket: WebSocket) {
|
||||
}
|
||||
|
||||
findAll <T extends Doc>(_class: Ref<Class<T>>, query: DocumentQuery<T>, options?: FindOptions<T> | undefined): Promise<FindResult<T>> {
|
||||
throw new Error('findAll not implemeneted for contributing client')
|
||||
}
|
||||
|
||||
async tx (tx: Tx): Promise<void> {
|
||||
this.websocket.send(serialize({
|
||||
method: 'tx',
|
||||
|
Loading…
Reference in New Issue
Block a user