@hocuspocus/extension-webhook 2.0.0-beta.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -143,7 +143,7 @@ class Webhook {
143
143
  requestHeaders: data.requestHeaders,
144
144
  requestParameters: Object.fromEntries(data.requestParameters.entries()),
145
145
  });
146
- return typeof response.data === 'string'
146
+ return typeof response.data === 'string' && response.data.length > 0
147
147
  ? JSON.parse(response.data)
148
148
  : response.data;
149
149
  }
@@ -1 +1 @@
1
- {"version":3,"file":"hocuspocus-webhook.cjs","sources":["../src/index.ts"],"sourcesContent":["import { createHmac } from 'crypto'\nimport {\n Extension,\n onChangePayload,\n onConnectPayload,\n onLoadDocumentPayload,\n onDisconnectPayload,\n} from '@hocuspocus/server'\nimport { Doc } from 'yjs'\nimport { TiptapTransformer, Transformer } from '@hocuspocus/transformer'\nimport axios from 'axios'\nimport { Forbidden } from '@hocuspocus/common'\n\nexport enum Events {\n onChange = 'change',\n onConnect = 'connect',\n onCreate = 'create',\n onDisconnect = 'disconnect',\n}\n\nexport interface Configuration {\n debounce: number | false | null,\n debounceMaxWait: number,\n secret: string,\n transformer: Transformer | {\n toYdoc: (document: any) => Doc,\n fromYdoc: (document: Doc) => any,\n },\n url: string,\n events: Array<Events>,\n}\n\nexport class Webhook implements Extension {\n\n configuration: Configuration = {\n debounce: 2000,\n debounceMaxWait: 10000,\n secret: '',\n transformer: TiptapTransformer,\n url: '',\n events: [\n Events.onChange,\n ],\n }\n\n debounced: Map<string, { timeout: NodeJS.Timeout, start: number }> = new Map()\n\n /**\n * Constructor\n */\n constructor(configuration?: Partial<Configuration>) {\n this.configuration = {\n ...this.configuration,\n ...configuration,\n }\n\n if (!this.configuration.url) {\n throw new Error('url is required!')\n }\n }\n\n /**\n * Create a signature for the response body\n */\n createSignature(body: string): string {\n const hmac = createHmac('sha256', this.configuration.secret)\n\n return `sha256=${hmac.update(body).digest('hex')}`\n }\n\n /**\n * debounce the given function, using the given identifier\n */\n debounce(id: string, func: Function) {\n const old = this.debounced.get(id)\n const start = old?.start || Date.now()\n\n const run = () => {\n this.debounced.delete(id)\n func()\n }\n\n if (old?.timeout) clearTimeout(old.timeout)\n if (Date.now() - start >= this.configuration.debounceMaxWait) return run()\n\n this.debounced.set(id, {\n start,\n timeout: setTimeout(run, <number> this.configuration.debounce),\n })\n }\n\n /**\n * Send a request to the given url containing the given data\n */\n async sendRequest(event: Events, payload: any) {\n const json = JSON.stringify({ event, payload })\n\n return axios.post(\n this.configuration.url,\n json,\n { headers: { 'X-Hocuspocus-Signature-256': this.createSignature(json), 'Content-Type': 'application/json' } },\n )\n }\n\n /**\n * onChange hook\n */\n async onChange(data: onChangePayload) {\n if (!this.configuration.events.includes(Events.onChange)) {\n return\n }\n\n const save = () => {\n try {\n this.sendRequest(Events.onChange, {\n document: this.configuration.transformer.fromYdoc(data.document),\n documentName: data.documentName,\n context: data.context,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n })\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n }\n }\n\n if (!this.configuration.debounce) {\n return save()\n }\n\n this.debounce(data.documentName, save)\n }\n\n /**\n * onLoadDocument hook\n */\n async onLoadDocument(data: onLoadDocumentPayload) {\n if (!this.configuration.events.includes(Events.onCreate)) {\n return\n }\n\n try {\n const response = await this.sendRequest(Events.onCreate, {\n documentName: data.documentName,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n })\n\n if (response.status !== 200 || !response.data) return\n\n const document = typeof response.data === 'string'\n ? JSON.parse(response.data)\n : response.data\n\n // eslint-disable-next-line guard-for-in,no-restricted-syntax\n for (const fieldName in document) {\n if (data.document.isEmpty(fieldName)) {\n data.document.merge(\n this.configuration.transformer.toYdoc(document[fieldName], fieldName),\n )\n }\n }\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n }\n }\n\n /**\n * onConnect hook\n */\n async onConnect(data: onConnectPayload) {\n if (!this.configuration.events.includes(Events.onConnect)) {\n return\n }\n\n try {\n const response = await this.sendRequest(Events.onConnect, {\n documentName: data.documentName,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n })\n\n return typeof response.data === 'string'\n ? JSON.parse(response.data)\n : response.data\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n throw Forbidden\n }\n }\n\n async onDisconnect(data: onDisconnectPayload) {\n if (!this.configuration.events.includes(Events.onDisconnect)) {\n return\n }\n\n try {\n await this.sendRequest(Events.onDisconnect, {\n documentName: data.documentName,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n context: data.context,\n })\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n }\n }\n\n}\n"],"names":["Events","TiptapTransformer","createHmac","axios","Forbidden"],"mappings":"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"}
1
+ {"version":3,"file":"hocuspocus-webhook.cjs","sources":["../src/index.ts"],"sourcesContent":["import { createHmac } from 'crypto'\nimport {\n Extension,\n onChangePayload,\n onConnectPayload,\n onLoadDocumentPayload,\n onDisconnectPayload,\n} from '@hocuspocus/server'\nimport { Doc } from 'yjs'\nimport { TiptapTransformer, Transformer } from '@hocuspocus/transformer'\nimport axios from 'axios'\nimport { Forbidden } from '@hocuspocus/common'\n\nexport enum Events {\n onChange = 'change',\n onConnect = 'connect',\n onCreate = 'create',\n onDisconnect = 'disconnect',\n}\n\nexport interface Configuration {\n debounce: number | false | null,\n debounceMaxWait: number,\n secret: string,\n transformer: Transformer | {\n toYdoc: (document: any) => Doc,\n fromYdoc: (document: Doc) => any,\n },\n url: string,\n events: Array<Events>,\n}\n\nexport class Webhook implements Extension {\n\n configuration: Configuration = {\n debounce: 2000,\n debounceMaxWait: 10000,\n secret: '',\n transformer: TiptapTransformer,\n url: '',\n events: [\n Events.onChange,\n ],\n }\n\n debounced: Map<string, { timeout: NodeJS.Timeout, start: number }> = new Map()\n\n /**\n * Constructor\n */\n constructor(configuration?: Partial<Configuration>) {\n this.configuration = {\n ...this.configuration,\n ...configuration,\n }\n\n if (!this.configuration.url) {\n throw new Error('url is required!')\n }\n }\n\n /**\n * Create a signature for the response body\n */\n createSignature(body: string): string {\n const hmac = createHmac('sha256', this.configuration.secret)\n\n return `sha256=${hmac.update(body).digest('hex')}`\n }\n\n /**\n * debounce the given function, using the given identifier\n */\n debounce(id: string, func: Function) {\n const old = this.debounced.get(id)\n const start = old?.start || Date.now()\n\n const run = () => {\n this.debounced.delete(id)\n func()\n }\n\n if (old?.timeout) clearTimeout(old.timeout)\n if (Date.now() - start >= this.configuration.debounceMaxWait) return run()\n\n this.debounced.set(id, {\n start,\n timeout: setTimeout(run, <number> this.configuration.debounce),\n })\n }\n\n /**\n * Send a request to the given url containing the given data\n */\n async sendRequest(event: Events, payload: any) {\n const json = JSON.stringify({ event, payload })\n\n return axios.post(\n this.configuration.url,\n json,\n { headers: { 'X-Hocuspocus-Signature-256': this.createSignature(json), 'Content-Type': 'application/json' } },\n )\n }\n\n /**\n * onChange hook\n */\n async onChange(data: onChangePayload) {\n if (!this.configuration.events.includes(Events.onChange)) {\n return\n }\n\n const save = () => {\n try {\n this.sendRequest(Events.onChange, {\n document: this.configuration.transformer.fromYdoc(data.document),\n documentName: data.documentName,\n context: data.context,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n })\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n }\n }\n\n if (!this.configuration.debounce) {\n return save()\n }\n\n this.debounce(data.documentName, save)\n }\n\n /**\n * onLoadDocument hook\n */\n async onLoadDocument(data: onLoadDocumentPayload) {\n if (!this.configuration.events.includes(Events.onCreate)) {\n return\n }\n\n try {\n const response = await this.sendRequest(Events.onCreate, {\n documentName: data.documentName,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n })\n\n if (response.status !== 200 || !response.data) return\n\n const document = typeof response.data === 'string'\n ? JSON.parse(response.data)\n : response.data\n\n // eslint-disable-next-line guard-for-in,no-restricted-syntax\n for (const fieldName in document) {\n if (data.document.isEmpty(fieldName)) {\n data.document.merge(\n this.configuration.transformer.toYdoc(document[fieldName], fieldName),\n )\n }\n }\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n }\n }\n\n /**\n * onConnect hook\n */\n async onConnect(data: onConnectPayload) {\n if (!this.configuration.events.includes(Events.onConnect)) {\n return\n }\n\n try {\n const response = await this.sendRequest(Events.onConnect, {\n documentName: data.documentName,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n })\n\n return typeof response.data === 'string' && response.data.length > 0\n ? JSON.parse(response.data)\n : response.data\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n throw Forbidden\n }\n }\n\n async onDisconnect(data: onDisconnectPayload) {\n if (!this.configuration.events.includes(Events.onDisconnect)) {\n return\n }\n\n try {\n await this.sendRequest(Events.onDisconnect, {\n documentName: data.documentName,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n context: data.context,\n })\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n }\n }\n\n}\n"],"names":["Events","TiptapTransformer","createHmac","axios","Forbidden"],"mappings":"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"}
@@ -135,7 +135,7 @@ class Webhook {
135
135
  requestHeaders: data.requestHeaders,
136
136
  requestParameters: Object.fromEntries(data.requestParameters.entries()),
137
137
  });
138
- return typeof response.data === 'string'
138
+ return typeof response.data === 'string' && response.data.length > 0
139
139
  ? JSON.parse(response.data)
140
140
  : response.data;
141
141
  }
@@ -1 +1 @@
1
- {"version":3,"file":"hocuspocus-webhook.esm.js","sources":["../src/index.ts"],"sourcesContent":["import { createHmac } from 'crypto'\nimport {\n Extension,\n onChangePayload,\n onConnectPayload,\n onLoadDocumentPayload,\n onDisconnectPayload,\n} from '@hocuspocus/server'\nimport { Doc } from 'yjs'\nimport { TiptapTransformer, Transformer } from '@hocuspocus/transformer'\nimport axios from 'axios'\nimport { Forbidden } from '@hocuspocus/common'\n\nexport enum Events {\n onChange = 'change',\n onConnect = 'connect',\n onCreate = 'create',\n onDisconnect = 'disconnect',\n}\n\nexport interface Configuration {\n debounce: number | false | null,\n debounceMaxWait: number,\n secret: string,\n transformer: Transformer | {\n toYdoc: (document: any) => Doc,\n fromYdoc: (document: Doc) => any,\n },\n url: string,\n events: Array<Events>,\n}\n\nexport class Webhook implements Extension {\n\n configuration: Configuration = {\n debounce: 2000,\n debounceMaxWait: 10000,\n secret: '',\n transformer: TiptapTransformer,\n url: '',\n events: [\n Events.onChange,\n ],\n }\n\n debounced: Map<string, { timeout: NodeJS.Timeout, start: number }> = new Map()\n\n /**\n * Constructor\n */\n constructor(configuration?: Partial<Configuration>) {\n this.configuration = {\n ...this.configuration,\n ...configuration,\n }\n\n if (!this.configuration.url) {\n throw new Error('url is required!')\n }\n }\n\n /**\n * Create a signature for the response body\n */\n createSignature(body: string): string {\n const hmac = createHmac('sha256', this.configuration.secret)\n\n return `sha256=${hmac.update(body).digest('hex')}`\n }\n\n /**\n * debounce the given function, using the given identifier\n */\n debounce(id: string, func: Function) {\n const old = this.debounced.get(id)\n const start = old?.start || Date.now()\n\n const run = () => {\n this.debounced.delete(id)\n func()\n }\n\n if (old?.timeout) clearTimeout(old.timeout)\n if (Date.now() - start >= this.configuration.debounceMaxWait) return run()\n\n this.debounced.set(id, {\n start,\n timeout: setTimeout(run, <number> this.configuration.debounce),\n })\n }\n\n /**\n * Send a request to the given url containing the given data\n */\n async sendRequest(event: Events, payload: any) {\n const json = JSON.stringify({ event, payload })\n\n return axios.post(\n this.configuration.url,\n json,\n { headers: { 'X-Hocuspocus-Signature-256': this.createSignature(json), 'Content-Type': 'application/json' } },\n )\n }\n\n /**\n * onChange hook\n */\n async onChange(data: onChangePayload) {\n if (!this.configuration.events.includes(Events.onChange)) {\n return\n }\n\n const save = () => {\n try {\n this.sendRequest(Events.onChange, {\n document: this.configuration.transformer.fromYdoc(data.document),\n documentName: data.documentName,\n context: data.context,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n })\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n }\n }\n\n if (!this.configuration.debounce) {\n return save()\n }\n\n this.debounce(data.documentName, save)\n }\n\n /**\n * onLoadDocument hook\n */\n async onLoadDocument(data: onLoadDocumentPayload) {\n if (!this.configuration.events.includes(Events.onCreate)) {\n return\n }\n\n try {\n const response = await this.sendRequest(Events.onCreate, {\n documentName: data.documentName,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n })\n\n if (response.status !== 200 || !response.data) return\n\n const document = typeof response.data === 'string'\n ? JSON.parse(response.data)\n : response.data\n\n // eslint-disable-next-line guard-for-in,no-restricted-syntax\n for (const fieldName in document) {\n if (data.document.isEmpty(fieldName)) {\n data.document.merge(\n this.configuration.transformer.toYdoc(document[fieldName], fieldName),\n )\n }\n }\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n }\n }\n\n /**\n * onConnect hook\n */\n async onConnect(data: onConnectPayload) {\n if (!this.configuration.events.includes(Events.onConnect)) {\n return\n }\n\n try {\n const response = await this.sendRequest(Events.onConnect, {\n documentName: data.documentName,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n })\n\n return typeof response.data === 'string'\n ? JSON.parse(response.data)\n : response.data\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n throw Forbidden\n }\n }\n\n async onDisconnect(data: onDisconnectPayload) {\n if (!this.configuration.events.includes(Events.onDisconnect)) {\n return\n }\n\n try {\n await this.sendRequest(Events.onDisconnect, {\n documentName: data.documentName,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n context: data.context,\n })\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n }\n }\n\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hocuspocus-webhook.esm.js","sources":["../src/index.ts"],"sourcesContent":["import { createHmac } from 'crypto'\nimport {\n Extension,\n onChangePayload,\n onConnectPayload,\n onLoadDocumentPayload,\n onDisconnectPayload,\n} from '@hocuspocus/server'\nimport { Doc } from 'yjs'\nimport { TiptapTransformer, Transformer } from '@hocuspocus/transformer'\nimport axios from 'axios'\nimport { Forbidden } from '@hocuspocus/common'\n\nexport enum Events {\n onChange = 'change',\n onConnect = 'connect',\n onCreate = 'create',\n onDisconnect = 'disconnect',\n}\n\nexport interface Configuration {\n debounce: number | false | null,\n debounceMaxWait: number,\n secret: string,\n transformer: Transformer | {\n toYdoc: (document: any) => Doc,\n fromYdoc: (document: Doc) => any,\n },\n url: string,\n events: Array<Events>,\n}\n\nexport class Webhook implements Extension {\n\n configuration: Configuration = {\n debounce: 2000,\n debounceMaxWait: 10000,\n secret: '',\n transformer: TiptapTransformer,\n url: '',\n events: [\n Events.onChange,\n ],\n }\n\n debounced: Map<string, { timeout: NodeJS.Timeout, start: number }> = new Map()\n\n /**\n * Constructor\n */\n constructor(configuration?: Partial<Configuration>) {\n this.configuration = {\n ...this.configuration,\n ...configuration,\n }\n\n if (!this.configuration.url) {\n throw new Error('url is required!')\n }\n }\n\n /**\n * Create a signature for the response body\n */\n createSignature(body: string): string {\n const hmac = createHmac('sha256', this.configuration.secret)\n\n return `sha256=${hmac.update(body).digest('hex')}`\n }\n\n /**\n * debounce the given function, using the given identifier\n */\n debounce(id: string, func: Function) {\n const old = this.debounced.get(id)\n const start = old?.start || Date.now()\n\n const run = () => {\n this.debounced.delete(id)\n func()\n }\n\n if (old?.timeout) clearTimeout(old.timeout)\n if (Date.now() - start >= this.configuration.debounceMaxWait) return run()\n\n this.debounced.set(id, {\n start,\n timeout: setTimeout(run, <number> this.configuration.debounce),\n })\n }\n\n /**\n * Send a request to the given url containing the given data\n */\n async sendRequest(event: Events, payload: any) {\n const json = JSON.stringify({ event, payload })\n\n return axios.post(\n this.configuration.url,\n json,\n { headers: { 'X-Hocuspocus-Signature-256': this.createSignature(json), 'Content-Type': 'application/json' } },\n )\n }\n\n /**\n * onChange hook\n */\n async onChange(data: onChangePayload) {\n if (!this.configuration.events.includes(Events.onChange)) {\n return\n }\n\n const save = () => {\n try {\n this.sendRequest(Events.onChange, {\n document: this.configuration.transformer.fromYdoc(data.document),\n documentName: data.documentName,\n context: data.context,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n })\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n }\n }\n\n if (!this.configuration.debounce) {\n return save()\n }\n\n this.debounce(data.documentName, save)\n }\n\n /**\n * onLoadDocument hook\n */\n async onLoadDocument(data: onLoadDocumentPayload) {\n if (!this.configuration.events.includes(Events.onCreate)) {\n return\n }\n\n try {\n const response = await this.sendRequest(Events.onCreate, {\n documentName: data.documentName,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n })\n\n if (response.status !== 200 || !response.data) return\n\n const document = typeof response.data === 'string'\n ? JSON.parse(response.data)\n : response.data\n\n // eslint-disable-next-line guard-for-in,no-restricted-syntax\n for (const fieldName in document) {\n if (data.document.isEmpty(fieldName)) {\n data.document.merge(\n this.configuration.transformer.toYdoc(document[fieldName], fieldName),\n )\n }\n }\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n }\n }\n\n /**\n * onConnect hook\n */\n async onConnect(data: onConnectPayload) {\n if (!this.configuration.events.includes(Events.onConnect)) {\n return\n }\n\n try {\n const response = await this.sendRequest(Events.onConnect, {\n documentName: data.documentName,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n })\n\n return typeof response.data === 'string' && response.data.length > 0\n ? JSON.parse(response.data)\n : response.data\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n throw Forbidden\n }\n }\n\n async onDisconnect(data: onDisconnectPayload) {\n if (!this.configuration.events.includes(Events.onDisconnect)) {\n return\n }\n\n try {\n await this.sendRequest(Events.onDisconnect, {\n documentName: data.documentName,\n requestHeaders: data.requestHeaders,\n requestParameters: Object.fromEntries(data.requestParameters.entries()),\n context: data.context,\n })\n } catch (e) {\n console.error(`Caught error in extension-webhook: ${e}`)\n }\n }\n\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { IncomingMessage, ServerResponse } from 'http';
3
4
  import { Socket } from 'net';
4
5
  import WebSocket, { WebSocketServer } from 'ws';
@@ -1,7 +1,7 @@
1
1
  import RedisClient, { ClusterNode, ClusterOptions, RedisOptions } from 'ioredis';
2
2
  import Redlock from 'redlock';
3
3
  import { Document, Extension, afterLoadDocumentPayload, afterStoreDocumentPayload, onDisconnectPayload, onStoreDocumentPayload, onAwarenessUpdatePayload, onChangePayload, Debugger, onConfigurePayload, onListenPayload, beforeBroadcastStatelessPayload } from '@hocuspocus/server';
4
- export declare type RedisInstance = RedisClient.Cluster | RedisClient.Redis;
4
+ export type RedisInstance = RedisClient.Cluster | RedisClient.Redis;
5
5
  export interface Configuration {
6
6
  /**
7
7
  * Redis port
@@ -1,6 +1,6 @@
1
1
  import { HocuspocusProvider, HocuspocusProviderConfiguration } from './HocuspocusProvider';
2
2
  import { HocuspocusProviderWebsocketConfiguration } from './HocuspocusProviderWebsocket';
3
- export declare type HocuspocusCloudProviderConfiguration = Required<Pick<HocuspocusProviderConfiguration, 'name'>> & Partial<HocuspocusProviderConfiguration> & Partial<Pick<HocuspocusProviderWebsocketConfiguration, 'url'>> & AdditionalHocuspocusCloudProviderConfiguration;
3
+ export type HocuspocusCloudProviderConfiguration = Required<Pick<HocuspocusProviderConfiguration, 'name'>> & Partial<HocuspocusProviderConfiguration> & Partial<Pick<HocuspocusProviderWebsocketConfiguration, 'url'>> & AdditionalHocuspocusCloudProviderConfiguration;
4
4
  export interface AdditionalHocuspocusCloudProviderConfiguration {
5
5
  /**
6
6
  * A Hocuspocus Cloud key, get one here: https://hocuspocus.cloud/
@@ -6,7 +6,7 @@ import EventEmitter from './EventEmitter';
6
6
  import { ConstructableOutgoingMessage, onAuthenticationFailedParameters, onCloseParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onStatelessParameters, onStatusParameters, onSyncedParameters, WebSocketStatus } from './types';
7
7
  import { CompleteHocuspocusProviderWebsocketConfiguration, HocuspocusProviderWebsocket } from './HocuspocusProviderWebsocket';
8
8
  import { onAwarenessChangeParameters, onAwarenessUpdateParameters } from '.';
9
- export declare type HocuspocusProviderConfiguration = Required<Pick<CompleteHocuspocusProviderConfiguration, 'name'>> & Partial<CompleteHocuspocusProviderConfiguration> & (Required<Pick<CompleteHocuspocusProviderWebsocketConfiguration, 'url'>> | Required<Pick<CompleteHocuspocusProviderConfiguration, 'websocketProvider'>>);
9
+ export type HocuspocusProviderConfiguration = Required<Pick<CompleteHocuspocusProviderConfiguration, 'name'>> & Partial<CompleteHocuspocusProviderConfiguration> & (Required<Pick<CompleteHocuspocusProviderWebsocketConfiguration, 'url'>> | Required<Pick<CompleteHocuspocusProviderConfiguration, 'websocketProvider'>>);
10
10
  export interface CompleteHocuspocusProviderConfiguration {
11
11
  /**
12
12
  * The identifier/name of your document
@@ -4,7 +4,7 @@ import { Event } from 'ws';
4
4
  import EventEmitter from './EventEmitter';
5
5
  import { onCloseParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onStatusParameters, WebSocketStatus } from './types';
6
6
  import { HocuspocusProvider, onAwarenessChangeParameters, onAwarenessUpdateParameters } from '.';
7
- export declare type HocuspocusProviderWebsocketConfiguration = Required<Pick<CompleteHocuspocusProviderWebsocketConfiguration, 'url'>> & Partial<CompleteHocuspocusProviderWebsocketConfiguration>;
7
+ export type HocuspocusProviderWebsocketConfiguration = Required<Pick<CompleteHocuspocusProviderWebsocketConfiguration, 'url'>> & Partial<CompleteHocuspocusProviderWebsocketConfiguration>;
8
8
  export interface CompleteHocuspocusProviderWebsocketConfiguration {
9
9
  /**
10
10
  * URL of your @hocuspocus/server instance
@@ -0,0 +1,11 @@
1
+ import { HocuspocusProvider, HocuspocusProviderConfiguration } from './HocuspocusProvider';
2
+ export type TiptapCollabProviderConfiguration = Required<Pick<HocuspocusProviderConfiguration, 'name'>> & Partial<HocuspocusProviderConfiguration> & AdditionalTiptapCollabProviderConfiguration;
3
+ export interface AdditionalTiptapCollabProviderConfiguration {
4
+ /**
5
+ * A Hocuspocus Cloud App ID, get one here: https://collab.tiptap.dev
6
+ */
7
+ appId: string;
8
+ }
9
+ export declare class TiptapCollabProvider extends HocuspocusProvider {
10
+ constructor(configuration: TiptapCollabProviderConfiguration);
11
+ }
@@ -1,4 +1,4 @@
1
1
  export * from './HocuspocusProvider';
2
- export * from './HocuspocusCloudProvider';
2
+ export * from './TiptapCollabProvider';
3
3
  export * from './HocuspocusProviderWebsocket';
4
4
  export * from './types';
@@ -43,42 +43,42 @@ export interface OutgoingMessageArguments {
43
43
  export interface Constructable<T> {
44
44
  new (...args: any): T;
45
45
  }
46
- export declare type ConstructableOutgoingMessage = Constructable<AuthenticationMessage> | Constructable<AwarenessMessage> | Constructable<QueryAwarenessMessage> | Constructable<SyncStepOneMessage> | Constructable<SyncStepTwoMessage> | Constructable<UpdateMessage>;
47
- export declare type onAuthenticationFailedParameters = {
46
+ export type ConstructableOutgoingMessage = Constructable<AuthenticationMessage> | Constructable<AwarenessMessage> | Constructable<QueryAwarenessMessage> | Constructable<SyncStepOneMessage> | Constructable<SyncStepTwoMessage> | Constructable<UpdateMessage>;
47
+ export type onAuthenticationFailedParameters = {
48
48
  reason: string;
49
49
  };
50
- export declare type onOpenParameters = {
50
+ export type onOpenParameters = {
51
51
  event: Event;
52
52
  };
53
- export declare type onMessageParameters = {
53
+ export type onMessageParameters = {
54
54
  event: MessageEvent;
55
55
  message: IncomingMessage;
56
56
  };
57
- export declare type onOutgoingMessageParameters = {
57
+ export type onOutgoingMessageParameters = {
58
58
  message: OutgoingMessage;
59
59
  };
60
- export declare type onStatusParameters = {
60
+ export type onStatusParameters = {
61
61
  status: WebSocketStatus;
62
62
  };
63
- export declare type onSyncedParameters = {
63
+ export type onSyncedParameters = {
64
64
  state: boolean;
65
65
  };
66
- export declare type onDisconnectParameters = {
66
+ export type onDisconnectParameters = {
67
67
  event: CloseEvent;
68
68
  };
69
- export declare type onCloseParameters = {
69
+ export type onCloseParameters = {
70
70
  event: CloseEvent;
71
71
  };
72
- export declare type onAwarenessUpdateParameters = {
72
+ export type onAwarenessUpdateParameters = {
73
73
  states: StatesArray;
74
74
  };
75
- export declare type onAwarenessChangeParameters = {
75
+ export type onAwarenessChangeParameters = {
76
76
  states: StatesArray;
77
77
  };
78
- export declare type onStatelessParameters = {
78
+ export type onStatelessParameters = {
79
79
  payload: string;
80
80
  };
81
- export declare type StatesArray = {
81
+ export type StatesArray = {
82
82
  clientId: number;
83
83
  [key: string | number]: any;
84
84
  }[];
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { IncomingMessage as HTTPIncomingMessage } from 'http';
3
4
  import AsyncLock from 'async-lock';
4
5
  import WebSocket from 'ws';
@@ -23,7 +24,7 @@ export declare class Connection {
23
24
  * Constructor.
24
25
  */
25
26
  constructor(connection: WebSocket, request: HTTPIncomingMessage, document: Document, timeout: number, socketId: string, context: any, readOnly: boolean | undefined, logger: Debugger);
26
- boundClose: (event?: CloseEvent | undefined) => void;
27
+ boundClose: (event?: CloseEvent) => void;
27
28
  boundHandleMessage: (data: Uint8Array) => void;
28
29
  boundHandlePong: () => void;
29
30
  handlePong(): void;
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { IncomingMessage, Server as HTTPServer } from 'http';
3
4
  import WebSocket, { AddressInfo, WebSocketServer } from 'ws';
4
5
  import { Configuration, HookName, HookPayload, onListenPayload } from './types';
@@ -1,4 +1,6 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
2
4
  import { IncomingHttpHeaders, IncomingMessage, ServerResponse } from 'http';
3
5
  import { URLSearchParams } from 'url';
4
6
  import { Awareness } from 'y-protocols/awareness';
@@ -47,8 +49,8 @@ export interface Extension {
47
49
  onDisconnect?(data: onDisconnectPayload): Promise<any>;
48
50
  onDestroy?(data: onDestroyPayload): Promise<any>;
49
51
  }
50
- export declare type HookName = 'onConfigure' | 'onListen' | 'onUpgrade' | 'onConnect' | 'connected' | 'onAuthenticate' | 'onLoadDocument' | 'afterLoadDocument' | 'beforeHandleMessage' | 'beforeBroadcastStateless' | 'onStateless' | 'onChange' | 'onStoreDocument' | 'afterStoreDocument' | 'onAwarenessUpdate' | 'onRequest' | 'onDisconnect' | 'onDestroy';
51
- export declare type HookPayload = onConfigurePayload | onListenPayload | onUpgradePayload | onConnectPayload | connectedPayload | onAuthenticatePayload | onLoadDocumentPayload | onStatelessPayload | beforeHandleMessagePayload | beforeBroadcastStatelessPayload | onChangePayload | onStoreDocumentPayload | afterStoreDocumentPayload | onAwarenessUpdatePayload | onRequestPayload | onDisconnectPayload | onDestroyPayload;
52
+ export type HookName = 'onConfigure' | 'onListen' | 'onUpgrade' | 'onConnect' | 'connected' | 'onAuthenticate' | 'onLoadDocument' | 'afterLoadDocument' | 'beforeHandleMessage' | 'beforeBroadcastStateless' | 'onStateless' | 'onChange' | 'onStoreDocument' | 'afterStoreDocument' | 'onAwarenessUpdate' | 'onRequest' | 'onDisconnect' | 'onDestroy';
53
+ export type HookPayload = onConfigurePayload | onListenPayload | onUpgradePayload | onConnectPayload | connectedPayload | onAuthenticatePayload | onLoadDocumentPayload | onStatelessPayload | beforeHandleMessagePayload | beforeBroadcastStatelessPayload | onChangePayload | onStoreDocumentPayload | afterStoreDocumentPayload | onAwarenessUpdatePayload | onRequestPayload | onDisconnectPayload | onDestroyPayload;
52
54
  export interface Configuration extends Extension {
53
55
  /**
54
56
  * A name for the instance, used for logging.
@@ -208,7 +210,7 @@ export interface onAwarenessUpdatePayload {
208
210
  awareness: Awareness;
209
211
  states: StatesArray;
210
212
  }
211
- export declare type StatesArray = {
213
+ export type StatesArray = {
212
214
  clientId: number;
213
215
  [key: string | number]: any;
214
216
  }[];
@@ -1,2 +1,2 @@
1
1
  import { Hocuspocus, Configuration } from '@hocuspocus/server';
2
- export declare const newHocuspocus: (options?: Partial<Configuration> | undefined) => Promise<Hocuspocus>;
2
+ export declare const newHocuspocus: (options?: Partial<Configuration>) => Promise<Hocuspocus>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hocuspocus/extension-webhook",
3
- "version": "2.0.0-beta.0",
3
+ "version": "2.0.0",
4
4
  "description": "hocuspocus webhook extension",
5
5
  "homepage": "https://hocuspocus.dev",
6
6
  "keywords": [
@@ -29,9 +29,9 @@
29
29
  "dist"
30
30
  ],
31
31
  "dependencies": {
32
- "@hocuspocus/common": "^2.0.0-beta.0",
33
- "@hocuspocus/server": "^2.0.0-beta.0",
34
- "@hocuspocus/transformer": "^2.0.0-beta.0",
32
+ "@hocuspocus/common": "^2.0.0",
33
+ "@hocuspocus/server": "^2.0.0",
34
+ "@hocuspocus/transformer": "^2.0.0",
35
35
  "axios": "^1.2.2"
36
36
  },
37
37
  "peerDependencies": {
package/src/index.ts CHANGED
@@ -180,7 +180,7 @@ export class Webhook implements Extension {
180
180
  requestParameters: Object.fromEntries(data.requestParameters.entries()),
181
181
  })
182
182
 
183
- return typeof response.data === 'string'
183
+ return typeof response.data === 'string' && response.data.length > 0
184
184
  ? JSON.parse(response.data)
185
185
  : response.data
186
186
  } catch (e) {