mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-23 22:12:44 +03:00
UBERF-4905 Change collaborator client payload (#4392)
Signed-off-by: Alexander Onnikov <alexander.onnikov@xored.com>
This commit is contained in:
parent
b4d898be5b
commit
c0c17993cf
@ -13,7 +13,8 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Class, Doc, Markup, Ref, concatLink } from '@hcengineering/core'
|
||||
import { Class, Doc, Hierarchy, Markup, Ref, concatLink } from '@hcengineering/core'
|
||||
import { minioDocumentId, mongodbDocumentId } from './utils'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -26,18 +27,32 @@ export interface CollaboratorClient {
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export function getClient (token: string, collaboratorUrl: string): CollaboratorClient {
|
||||
return new CollaboratorClientImpl(token, collaboratorUrl)
|
||||
export function getClient (hierarchy: Hierarchy, token: string, collaboratorUrl: string): CollaboratorClient {
|
||||
return new CollaboratorClientImpl(hierarchy, token, collaboratorUrl)
|
||||
}
|
||||
|
||||
class CollaboratorClientImpl implements CollaboratorClient {
|
||||
constructor (
|
||||
private readonly hierarchy: Hierarchy,
|
||||
private readonly token: string,
|
||||
private readonly collaboratorUrl: string
|
||||
) {}
|
||||
|
||||
initialContentId (classId: Ref<Class<Doc>>, docId: Ref<Doc>, attribute: string): string {
|
||||
const domain = this.hierarchy.getDomain(classId)
|
||||
return mongodbDocumentId(domain, docId, attribute)
|
||||
}
|
||||
|
||||
async get (classId: Ref<Class<Doc>>, docId: Ref<Doc>, attribute: string): Promise<Markup> {
|
||||
const url = concatLink(this.collaboratorUrl, `/api/content/${classId}/${docId}/${attribute}`)
|
||||
const documentId = encodeURIComponent(minioDocumentId(docId, attribute))
|
||||
const initialContentId = encodeURIComponent(this.initialContentId(classId, docId, attribute))
|
||||
attribute = encodeURIComponent(attribute)
|
||||
|
||||
const url = concatLink(
|
||||
this.collaboratorUrl,
|
||||
`/api/content/${documentId}/${attribute}?initialContentId=${initialContentId}`
|
||||
)
|
||||
|
||||
const res = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
@ -50,7 +65,15 @@ class CollaboratorClientImpl implements CollaboratorClient {
|
||||
}
|
||||
|
||||
async update (classId: Ref<Class<Doc>>, docId: Ref<Doc>, attribute: string, value: Markup): Promise<void> {
|
||||
const url = concatLink(this.collaboratorUrl, `/api/content/${classId}/${docId}/${attribute}`)
|
||||
const documentId = encodeURIComponent(minioDocumentId(docId, attribute))
|
||||
const initialContentId = encodeURIComponent(this.initialContentId(classId, docId, attribute))
|
||||
attribute = encodeURIComponent(attribute)
|
||||
|
||||
const url = concatLink(
|
||||
this.collaboratorUrl,
|
||||
`/api/content/${documentId}/${attribute}?initialContentId=${initialContentId}`
|
||||
)
|
||||
|
||||
await fetch(url, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
|
@ -14,3 +14,4 @@
|
||||
//
|
||||
|
||||
export { type CollaboratorClient, getClient } from './client'
|
||||
export * from './utils'
|
||||
|
24
packages/collaborator-client/src/utils.ts
Normal file
24
packages/collaborator-client/src/utils.ts
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
// Copyright © 2024 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 { Doc, Domain, Ref } from '@hcengineering/core'
|
||||
|
||||
export function minioDocumentId (docId: Ref<Doc>, attribute?: string): string {
|
||||
return attribute !== undefined ? `minio://${docId}%${attribute}` : `minio://${docId}`
|
||||
}
|
||||
|
||||
export function mongodbDocumentId (domain: Domain, docId: Ref<Doc>, attribute: string): string {
|
||||
return `mongodb://${domain}/${docId}/${attribute}`
|
||||
}
|
@ -13,20 +13,22 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { type CollaboratorClient, getClient } from '@hcengineering/collaborator-client'
|
||||
import { type CollaboratorClient, getClient as getCollaborator } from '@hcengineering/collaborator-client'
|
||||
import type { Class, Doc, Markup, Ref } from '@hcengineering/core'
|
||||
import { getMetadata } from '@hcengineering/platform'
|
||||
|
||||
import { getClient } from '.'
|
||||
import presentation from './plugin'
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export function getCollaboratorClient (): CollaboratorClient {
|
||||
const hierarchy = getClient().getHierarchy()
|
||||
const token = getMetadata(presentation.metadata.Token) ?? ''
|
||||
const collaboratorURL = getMetadata(presentation.metadata.CollaboratorUrl) ?? ''
|
||||
|
||||
return getClient(token, collaboratorURL)
|
||||
return getCollaborator(hierarchy, token, collaboratorURL)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -153,18 +153,18 @@ export async function start (
|
||||
|
||||
const restCtx = ctx.newChild('REST', {})
|
||||
|
||||
const getContext = (token: Token, documentId: string): Context => {
|
||||
const getContext = (token: Token, initialContentId?: string): Context => {
|
||||
return {
|
||||
connectionId: generateId(),
|
||||
workspaceId: token.workspace,
|
||||
clientFactory: getClientFactory(token, controller),
|
||||
initialContentId: documentId,
|
||||
initialContentId: initialContentId ?? '',
|
||||
targetContentId: ''
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
app.get('/api/content/:classId/:docId/:attribute', async (req, res) => {
|
||||
app.get('/api/content/:documentId/:field', async (req, res) => {
|
||||
console.log('handle request', req.method, req.url)
|
||||
|
||||
const authHeader = req.headers.authorization
|
||||
@ -176,22 +176,21 @@ export async function start (
|
||||
const token = authHeader.split(' ')[1]
|
||||
const decodedToken = decodeToken(token)
|
||||
|
||||
const docId = req.params.docId
|
||||
const attribute = req.params.attribute
|
||||
const documentId = req.params.documentId
|
||||
const field = req.params.field
|
||||
const initialContentId = req.query.initialContentId as string
|
||||
|
||||
if (docId === undefined || docId === '') {
|
||||
res.status(400).send({ err: "'docId' is missing" })
|
||||
if (documentId === undefined || documentId === '') {
|
||||
res.status(400).send({ err: "'documentId' is missing" })
|
||||
return
|
||||
}
|
||||
|
||||
if (attribute === undefined || attribute === '') {
|
||||
res.status(400).send({ err: "'attribute' is missing" })
|
||||
if (field === undefined || field === '') {
|
||||
res.status(400).send({ err: "'field' is missing" })
|
||||
return
|
||||
}
|
||||
|
||||
const documentId = `minio://${docId}%${attribute}`
|
||||
|
||||
const context = getContext(decodedToken, documentId)
|
||||
const context = getContext(decodedToken, initialContentId)
|
||||
|
||||
await restCtx.with(`${req.method} /content`, {}, async (ctx) => {
|
||||
const connection = await ctx.with('connect', {}, async () => {
|
||||
@ -202,7 +201,7 @@ export async function start (
|
||||
const html = await ctx.with('transform', {}, async () => {
|
||||
let content = ''
|
||||
await connection.transact((document) => {
|
||||
content = transformer.fromYdoc(document, attribute)
|
||||
content = transformer.fromYdoc(document, field)
|
||||
})
|
||||
return content
|
||||
})
|
||||
@ -221,7 +220,7 @@ export async function start (
|
||||
})
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
app.put('/api/content/:classId/:docId/:attribute', async (req, res) => {
|
||||
app.put('/api/content/:documentId/:field', async (req, res) => {
|
||||
console.log('handle request', req.method, req.url)
|
||||
|
||||
const authHeader = req.headers.authorization
|
||||
@ -233,27 +232,26 @@ export async function start (
|
||||
const token = authHeader.split(' ')[1]
|
||||
const decodedToken = decodeToken(token)
|
||||
|
||||
const docId = req.params.docId
|
||||
const attribute = req.params.attribute
|
||||
|
||||
if (docId === undefined || docId === '') {
|
||||
res.status(400).send({ err: "'docId' is missing" })
|
||||
return
|
||||
}
|
||||
|
||||
if (attribute === undefined || attribute === '') {
|
||||
res.status(400).send({ err: "'attribute' is missing" })
|
||||
return
|
||||
}
|
||||
|
||||
const documentId = `minio://${docId}%${attribute}`
|
||||
const documentId = req.params.documentId
|
||||
const field = req.params.field
|
||||
const initialContentId = req.query.initialContentId as string
|
||||
const data = req.body.html ?? '<p></p>'
|
||||
|
||||
const context = getContext(decodedToken, documentId)
|
||||
if (documentId === undefined || documentId === '') {
|
||||
res.status(400).send({ err: "'documentId' is missing" })
|
||||
return
|
||||
}
|
||||
|
||||
if (field === undefined || field === '') {
|
||||
res.status(400).send({ err: "'field' is missing" })
|
||||
return
|
||||
}
|
||||
|
||||
const context = getContext(decodedToken, initialContentId)
|
||||
|
||||
await restCtx.with(`${req.method} /content`, {}, async (ctx) => {
|
||||
const update = await ctx.with('transform', {}, () => {
|
||||
const ydoc = transformer.toYdoc(data, attribute)
|
||||
const ydoc = transformer.toYdoc(data, field)
|
||||
return encodeStateAsUpdate(ydoc)
|
||||
})
|
||||
|
||||
@ -264,7 +262,7 @@ export async function start (
|
||||
try {
|
||||
await ctx.with('update', {}, async () => {
|
||||
await connection.transact((document) => {
|
||||
const fragment = document.getXmlFragment(attribute)
|
||||
const fragment = document.getXmlFragment(field)
|
||||
document.transact((tr) => {
|
||||
fragment.delete(0, fragment.length)
|
||||
applyUpdate(document, update)
|
||||
|
Loading…
Reference in New Issue
Block a user