mirror of https://github.com/fantasticit/think.git
feat: export document to docx
This commit is contained in:
parent
3c11bfc121
commit
123d93fd07
|
@ -62,6 +62,7 @@
|
||||||
"docx": "^7.3.0",
|
"docx": "^7.3.0",
|
||||||
"dompurify": "^2.3.5",
|
"dompurify": "^2.3.5",
|
||||||
"downloadjs": "^1.4.7",
|
"downloadjs": "^1.4.7",
|
||||||
|
"html-to-docx": "^1.4.0",
|
||||||
"interactjs": "^1.10.11",
|
"interactjs": "^1.10.11",
|
||||||
"katex": "^0.15.2",
|
"katex": "^0.15.2",
|
||||||
"kity": "^2.0.4",
|
"kity": "^2.0.4",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Badge, Button, Dropdown, Modal, Space, Typography } from '@douyinfe/semi-ui';
|
import { Badge, Button, Dropdown, Modal, Space, Typography } from '@douyinfe/semi-ui';
|
||||||
import { IDocument } from '@think/domains';
|
import { IDocument } from '@think/domains';
|
||||||
import { IconJSON, IconMarkdown, IconPDF, IconWord } from 'components/icons';
|
import { IconJSON, IconMarkdown, IconPDF, IconWord } from 'components/icons';
|
||||||
|
import { useDocumentDetail } from 'data/document';
|
||||||
import download from 'downloadjs';
|
import download from 'downloadjs';
|
||||||
import { safeJSONParse, safeJSONStringify } from 'helpers/json';
|
import { safeJSONParse, safeJSONStringify } from 'helpers/json';
|
||||||
import { IsOnMobile } from 'hooks/use-on-mobile';
|
import { IsOnMobile } from 'hooks/use-on-mobile';
|
||||||
|
@ -8,7 +9,6 @@ import { useToggle } from 'hooks/use-toggle';
|
||||||
import React, { useCallback, useEffect, useMemo } from 'react';
|
import React, { useCallback, useEffect, useMemo } from 'react';
|
||||||
import { createEditor } from 'tiptap/core';
|
import { createEditor } from 'tiptap/core';
|
||||||
import { AllExtensions } from 'tiptap/core/all-kit';
|
import { AllExtensions } from 'tiptap/core/all-kit';
|
||||||
import { prosemirrorToDocx } from 'tiptap/docx';
|
|
||||||
import { prosemirrorToMarkdown } from 'tiptap/markdown/prosemirror-to-markdown';
|
import { prosemirrorToMarkdown } from 'tiptap/markdown/prosemirror-to-markdown';
|
||||||
|
|
||||||
import styles from './index.module.scss';
|
import styles from './index.module.scss';
|
||||||
|
@ -24,6 +24,7 @@ interface IProps {
|
||||||
export const DocumentExporter: React.FC<IProps> = ({ document, render }) => {
|
export const DocumentExporter: React.FC<IProps> = ({ document, render }) => {
|
||||||
const { isMobile } = IsOnMobile.useHook();
|
const { isMobile } = IsOnMobile.useHook();
|
||||||
const [visible, toggleVisible] = useToggle(false);
|
const [visible, toggleVisible] = useToggle(false);
|
||||||
|
const { exportDocx } = useDocumentDetail(document.id);
|
||||||
|
|
||||||
const editor = useMemo(() => {
|
const editor = useMemo(() => {
|
||||||
return createEditor({
|
return createEditor({
|
||||||
|
@ -47,10 +48,13 @@ export const DocumentExporter: React.FC<IProps> = ({ document, render }) => {
|
||||||
}, [document, editor]);
|
}, [document, editor]);
|
||||||
|
|
||||||
const exportWord = useCallback(() => {
|
const exportWord = useCallback(() => {
|
||||||
prosemirrorToDocx(editor.view, editor.state).then((buffer) => {
|
const editorContent = editor.view.dom.closest('.ProseMirror');
|
||||||
download(buffer, `${document.title}.docx`);
|
if (editorContent) {
|
||||||
});
|
exportDocx(editorContent.outerHTML).then((res) => {
|
||||||
}, [document, editor]);
|
download(Buffer.from(res as Buffer), `${document.title}.docx`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [editor, exportDocx, document]);
|
||||||
|
|
||||||
const exportPDF = useCallback(() => {
|
const exportPDF = useCallback(() => {
|
||||||
printEditorContent(editor.view);
|
printEditorContent(editor.view);
|
||||||
|
|
|
@ -199,7 +199,19 @@ export const useDocumentDetail = (documentId, options: UseQueryOptions<IDocument
|
||||||
[refetch, documentId]
|
[refetch, documentId]
|
||||||
);
|
);
|
||||||
|
|
||||||
return { data, loading: isLoading, error, update, toggleStatus };
|
/**
|
||||||
|
* 导出文档
|
||||||
|
*/
|
||||||
|
const exportDocx = useCallback(async (content) => {
|
||||||
|
const res = await HttpClient.request({
|
||||||
|
method: DocumentApiDefinition.exportDocx.method,
|
||||||
|
url: DocumentApiDefinition.exportDocx.client(),
|
||||||
|
data: { content },
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { data, loading: isLoading, error, update, toggleStatus, exportDocx };
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -47,13 +47,13 @@ export const Title = Node.create<TitleOptions>({
|
||||||
parseHTML() {
|
parseHTML() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
tag: 'div[class=node-title]',
|
tag: 'h1[class=node-title]',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
renderHTML({ HTMLAttributes }) {
|
renderHTML({ HTMLAttributes }) {
|
||||||
return ['div', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
return ['h1', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
|
||||||
},
|
},
|
||||||
|
|
||||||
addNodeView() {
|
addNodeView() {
|
||||||
|
|
|
@ -1,149 +0,0 @@
|
||||||
import axios from 'axios';
|
|
||||||
import { HeadingLevel } from 'docx';
|
|
||||||
import { EditorState } from 'prosemirror-state';
|
|
||||||
import { EditorView } from 'prosemirror-view';
|
|
||||||
import { Attachment } from 'tiptap/core/extensions/attachment';
|
|
||||||
import { BulletList } from 'tiptap/core/extensions/bullet-list';
|
|
||||||
import { Callout } from 'tiptap/core/extensions/callout';
|
|
||||||
import { CodeBlock } from 'tiptap/core/extensions/code-block';
|
|
||||||
import { DocumentChildren } from 'tiptap/core/extensions/document-children';
|
|
||||||
import { DocumentReference } from 'tiptap/core/extensions/document-reference';
|
|
||||||
import { Flow } from 'tiptap/core/extensions/flow';
|
|
||||||
import { HardBreak } from 'tiptap/core/extensions/hard-break';
|
|
||||||
import { HorizontalRule } from 'tiptap/core/extensions/horizontal-rule';
|
|
||||||
import { Iframe } from 'tiptap/core/extensions/iframe';
|
|
||||||
import { Katex } from 'tiptap/core/extensions/katex';
|
|
||||||
import { ListItem } from 'tiptap/core/extensions/listItem';
|
|
||||||
import { Mind } from 'tiptap/core/extensions/mind';
|
|
||||||
import { OrderedList } from 'tiptap/core/extensions/ordered-list';
|
|
||||||
import { Status } from 'tiptap/core/extensions/status';
|
|
||||||
import { TableOfContents } from 'tiptap/core/extensions/table-of-contents';
|
|
||||||
import { TaskItem } from 'tiptap/core/extensions/task-item';
|
|
||||||
import { TaskList } from 'tiptap/core/extensions/task-list';
|
|
||||||
import { Title } from 'tiptap/core/extensions/title';
|
|
||||||
|
|
||||||
import { defaultMarks, defaultNodes, DocxSerializer, writeDocx } from './prosemirror-docx';
|
|
||||||
|
|
||||||
function getLatexFromNode(node): string {
|
|
||||||
return node.attrs.text;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nodeSerializer = {
|
|
||||||
...defaultNodes,
|
|
||||||
[Title.name](state, node) {
|
|
||||||
state.renderInline(node);
|
|
||||||
state.closeBlock(node, { heading: HeadingLevel.TITLE });
|
|
||||||
},
|
|
||||||
[DocumentChildren.name](state, node) {
|
|
||||||
state.renderInline(node);
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
[DocumentReference.name](state, node) {
|
|
||||||
state.renderInline(node);
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
[TableOfContents.name](state, node) {
|
|
||||||
state.renderInline(node);
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
[BulletList.name](state, node) {
|
|
||||||
state.renderList(node, 'bullets');
|
|
||||||
},
|
|
||||||
[OrderedList.name](state, node) {
|
|
||||||
state.renderList(node, 'numbered');
|
|
||||||
},
|
|
||||||
[ListItem.name](state, node) {
|
|
||||||
state.renderListItem(node);
|
|
||||||
},
|
|
||||||
[HorizontalRule.name](state, node) {
|
|
||||||
state.closeBlock(node, { thematicBreak: true });
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
[TaskList.name](state, node) {
|
|
||||||
state.renderInline(node);
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
[TaskItem.name](state, node) {
|
|
||||||
state.renderInline(node);
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
[CodeBlock.name](state, node) {
|
|
||||||
state.renderContent(node);
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
[Status.name](state, node) {
|
|
||||||
state.text(node.attrs.text ?? '');
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
[Flow.name](state, node) {
|
|
||||||
state.renderContent(node);
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
[Mind.name](state, node) {
|
|
||||||
state.renderContent(node);
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
[HardBreak.name](state, node) {
|
|
||||||
state.addRunOptions({ break: 1 });
|
|
||||||
},
|
|
||||||
[Katex.name](state, node) {
|
|
||||||
state.math(getLatexFromNode(node), { inline: false });
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
[Iframe.name](state, node) {
|
|
||||||
state.renderContent(node);
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
[Attachment.name](state, node) {
|
|
||||||
state.renderContent(node);
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
[Callout.name](state, node) {
|
|
||||||
state.renderContent(node);
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const docxSerializer = new DocxSerializer(nodeSerializer, defaultMarks);
|
|
||||||
|
|
||||||
async function getImageBuffer(src: string) {
|
|
||||||
const image = await axios
|
|
||||||
.get(src, {
|
|
||||||
responseType: 'arraybuffer',
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
return { data: '' };
|
|
||||||
});
|
|
||||||
return Buffer.from(image.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const prosemirrorToDocx = async (view: EditorView, state: EditorState): Promise<Blob> => {
|
|
||||||
const dom = view.dom.closest('.ProseMirror');
|
|
||||||
const imageBufferCache = new Map();
|
|
||||||
const images = Array.from(await dom.querySelectorAll('img')) as HTMLImageElement[];
|
|
||||||
|
|
||||||
await Promise.all(
|
|
||||||
images.map(async (img) => {
|
|
||||||
try {
|
|
||||||
const buffer = await getImageBuffer(img.src);
|
|
||||||
imageBufferCache.set(img.src, buffer);
|
|
||||||
} catch (e) {
|
|
||||||
imageBufferCache.set(img.src, Buffer.from('图片加载失败'));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const wordDocument = docxSerializer.serialize(state.doc, {
|
|
||||||
getImageBuffer(src) {
|
|
||||||
return imageBufferCache.get(src);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-async-promise-executor
|
|
||||||
return new Promise(async (resolve) => {
|
|
||||||
await writeDocx(wordDocument, (buffer) => {
|
|
||||||
imageBufferCache.clear();
|
|
||||||
resolve(new Blob([buffer]));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,4 +0,0 @@
|
||||||
export { defaultDocxSerializer, defaultMarks, defaultNodes } from './schema';
|
|
||||||
export type { MarkSerializer, NodeSerializer } from './serializer';
|
|
||||||
export { DocxSerializer, DocxSerializerState } from './serializer';
|
|
||||||
export { createDocFromState, writeDocx } from './utils';
|
|
|
@ -1,48 +0,0 @@
|
||||||
import { AlignmentType, convertInchesToTwip, ILevelsOptions, LevelFormat } from 'docx';
|
|
||||||
|
|
||||||
import { INumbering } from './types';
|
|
||||||
|
|
||||||
function basicIndentStyle(indent: number): Pick<ILevelsOptions, 'style' | 'alignment'> {
|
|
||||||
return {
|
|
||||||
alignment: AlignmentType.START,
|
|
||||||
style: {
|
|
||||||
paragraph: {
|
|
||||||
indent: { left: convertInchesToTwip(indent), hanging: convertInchesToTwip(0.18) },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const numbered = Array(3)
|
|
||||||
.fill([LevelFormat.DECIMAL, LevelFormat.LOWER_LETTER, LevelFormat.LOWER_ROMAN])
|
|
||||||
.flat()
|
|
||||||
.map((format, level) => ({
|
|
||||||
level,
|
|
||||||
format,
|
|
||||||
text: `%${level + 1}.`,
|
|
||||||
...basicIndentStyle((level + 1) / 2),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const bullets = Array(3)
|
|
||||||
.fill(['●', '○', '■'])
|
|
||||||
.flat()
|
|
||||||
.map((text, level) => ({
|
|
||||||
level,
|
|
||||||
format: LevelFormat.BULLET,
|
|
||||||
text,
|
|
||||||
...basicIndentStyle((level + 1) / 2),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const styles = {
|
|
||||||
numbered,
|
|
||||||
bullets,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type NumberingStyles = keyof typeof styles;
|
|
||||||
|
|
||||||
export function createNumbering(reference: string, style: NumberingStyles): INumbering {
|
|
||||||
return {
|
|
||||||
reference,
|
|
||||||
levels: styles[style],
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,123 +0,0 @@
|
||||||
import { HeadingLevel, ShadingType } from 'docx';
|
|
||||||
|
|
||||||
import { DocxSerializer, MarkSerializer, NodeSerializer } from './serializer';
|
|
||||||
import { getLatexFromNode } from './utils';
|
|
||||||
|
|
||||||
export const defaultNodes: NodeSerializer = {
|
|
||||||
text(state, node) {
|
|
||||||
state.text(node.text ?? '');
|
|
||||||
},
|
|
||||||
paragraph(state, node) {
|
|
||||||
state.renderInline(node);
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
heading(state, node) {
|
|
||||||
state.renderInline(node);
|
|
||||||
const heading = [
|
|
||||||
HeadingLevel.HEADING_1,
|
|
||||||
HeadingLevel.HEADING_2,
|
|
||||||
HeadingLevel.HEADING_3,
|
|
||||||
HeadingLevel.HEADING_4,
|
|
||||||
HeadingLevel.HEADING_5,
|
|
||||||
HeadingLevel.HEADING_6,
|
|
||||||
][node.attrs.level - 1];
|
|
||||||
state.closeBlock(node, { heading });
|
|
||||||
},
|
|
||||||
blockquote(state, node) {
|
|
||||||
state.renderContent(node, { style: 'IntenseQuote' });
|
|
||||||
},
|
|
||||||
code_block(state, node) {
|
|
||||||
// TODO: something for code
|
|
||||||
state.renderContent(node);
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
horizontal_rule(state, node) {
|
|
||||||
// Kinda hacky, but this works to insert two paragraphs, the first with a break
|
|
||||||
state.closeBlock(node, { thematicBreak: true });
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
hard_break(state) {
|
|
||||||
state.addRunOptions({ break: 1 });
|
|
||||||
},
|
|
||||||
ordered_list(state, node) {
|
|
||||||
state.renderList(node, 'numbered');
|
|
||||||
},
|
|
||||||
bullet_list(state, node) {
|
|
||||||
state.renderList(node, 'bullets');
|
|
||||||
},
|
|
||||||
list_item(state, node) {
|
|
||||||
state.renderListItem(node);
|
|
||||||
},
|
|
||||||
// Presentational
|
|
||||||
image(state, node) {
|
|
||||||
const { src } = node.attrs;
|
|
||||||
state.image(src);
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
// Technical
|
|
||||||
math(state, node) {
|
|
||||||
state.math(getLatexFromNode(node), { inline: true });
|
|
||||||
},
|
|
||||||
equation(state, node) {
|
|
||||||
const { id, numbered } = node.attrs;
|
|
||||||
state.math(getLatexFromNode(node), { inline: false, numbered, id });
|
|
||||||
state.closeBlock(node);
|
|
||||||
},
|
|
||||||
table(state, node) {
|
|
||||||
state.table(node);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const defaultMarks: MarkSerializer = {
|
|
||||||
em() {
|
|
||||||
return { italics: true };
|
|
||||||
},
|
|
||||||
strong() {
|
|
||||||
return { bold: true };
|
|
||||||
},
|
|
||||||
link() {
|
|
||||||
// Note, this is handled specifically in the serializer
|
|
||||||
// Word treats links more like a Node rather than a mark
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
code() {
|
|
||||||
return {
|
|
||||||
font: {
|
|
||||||
name: 'Monospace',
|
|
||||||
},
|
|
||||||
color: '000000',
|
|
||||||
shading: {
|
|
||||||
type: ShadingType.SOLID,
|
|
||||||
color: 'D2D3D2',
|
|
||||||
fill: 'D2D3D2',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
abbr() {
|
|
||||||
// TODO: abbreviation
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
subscript() {
|
|
||||||
return { subScript: true };
|
|
||||||
},
|
|
||||||
superscript() {
|
|
||||||
return { superScript: true };
|
|
||||||
},
|
|
||||||
strikethrough() {
|
|
||||||
// doubleStrike!
|
|
||||||
return { strike: true };
|
|
||||||
},
|
|
||||||
underline() {
|
|
||||||
return {
|
|
||||||
underline: {},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
smallcaps() {
|
|
||||||
return { smallCaps: true };
|
|
||||||
},
|
|
||||||
allcaps() {
|
|
||||||
return { allCaps: true };
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const defaultDocxSerializer = new DocxSerializer(defaultNodes, defaultMarks);
|
|
|
@ -1,376 +0,0 @@
|
||||||
import sizeOf from 'buffer-image-size';
|
|
||||||
import {
|
|
||||||
AlignmentType,
|
|
||||||
Bookmark,
|
|
||||||
ExternalHyperlink,
|
|
||||||
FootnoteReferenceRun,
|
|
||||||
ImageRun,
|
|
||||||
InternalHyperlink,
|
|
||||||
IParagraphOptions,
|
|
||||||
IRunOptions,
|
|
||||||
ITableCellOptions,
|
|
||||||
Math,
|
|
||||||
MathRun,
|
|
||||||
Paragraph,
|
|
||||||
ParagraphChild,
|
|
||||||
SequentialIdentifier,
|
|
||||||
SimpleField,
|
|
||||||
Table,
|
|
||||||
TableCell,
|
|
||||||
TableRow,
|
|
||||||
TabStopPosition,
|
|
||||||
TabStopType,
|
|
||||||
TextRun,
|
|
||||||
WidthType,
|
|
||||||
} from 'docx';
|
|
||||||
import { Mark, Node as ProsemirrorNode, Schema } from 'prosemirror-model';
|
|
||||||
|
|
||||||
import { createNumbering, NumberingStyles } from './numbering';
|
|
||||||
import { IFootnotes, INumbering, Mutable } from './types';
|
|
||||||
import { createDocFromState, createShortId } from './utils';
|
|
||||||
|
|
||||||
// This is duplicated from @curvenote/schema
|
|
||||||
export type AlignOptions = 'left' | 'center' | 'right';
|
|
||||||
|
|
||||||
export type NodeSerializer<S extends Schema = any> = Record<
|
|
||||||
string,
|
|
||||||
(state: DocxSerializerState<S>, node: ProsemirrorNode<S>, parent: ProsemirrorNode<S>, index: number) => void
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type MarkSerializer<S extends Schema = any> = Record<
|
|
||||||
string,
|
|
||||||
(state: DocxSerializerState<S>, node: ProsemirrorNode<S>, mark: Mark<S>) => IRunOptions
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type Options = {
|
|
||||||
getImageBuffer: (src: string) => Buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type IMathOpts = {
|
|
||||||
inline?: boolean;
|
|
||||||
id?: string | null;
|
|
||||||
numbered?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
const MAX_IMAGE_WIDTH = 600;
|
|
||||||
|
|
||||||
function createReferenceBookmark(id: string, kind: 'Equation' | 'Figure' | 'Table', before?: string, after?: string) {
|
|
||||||
const textBefore = before ? [new TextRun(before)] : [];
|
|
||||||
const textAfter = after ? [new TextRun(after)] : [];
|
|
||||||
return new Bookmark({
|
|
||||||
id,
|
|
||||||
children: [...textBefore, new SequentialIdentifier(kind), ...textAfter],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DocxSerializerState<S extends Schema = any> {
|
|
||||||
nodes: NodeSerializer<S>;
|
|
||||||
|
|
||||||
options: Options;
|
|
||||||
|
|
||||||
marks: MarkSerializer<S>;
|
|
||||||
|
|
||||||
children: (Paragraph | Table)[];
|
|
||||||
|
|
||||||
numbering: INumbering[];
|
|
||||||
|
|
||||||
footnotes: IFootnotes = {};
|
|
||||||
|
|
||||||
nextRunOpts?: IRunOptions;
|
|
||||||
|
|
||||||
current: ParagraphChild[] = [];
|
|
||||||
|
|
||||||
currentLink?: { link: string; children: IRunOptions[] };
|
|
||||||
|
|
||||||
// Optionally add options
|
|
||||||
nextParentParagraphOpts?: IParagraphOptions;
|
|
||||||
|
|
||||||
currentNumbering?: { reference: string; level: number };
|
|
||||||
|
|
||||||
constructor(nodes: NodeSerializer<S>, marks: MarkSerializer<S>, options: Options) {
|
|
||||||
this.nodes = nodes;
|
|
||||||
this.marks = marks;
|
|
||||||
// @ts-ignore
|
|
||||||
this.options = options ?? {};
|
|
||||||
this.children = [];
|
|
||||||
this.numbering = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
renderContent(parent: ProsemirrorNode<S>, opts?: IParagraphOptions) {
|
|
||||||
parent.forEach((node, _, i) => {
|
|
||||||
if (opts) this.addParagraphOptions(opts);
|
|
||||||
this.render(node, parent, i);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render(node: ProsemirrorNode<S>, parent: ProsemirrorNode<S>, index: number) {
|
|
||||||
if (typeof parent === 'number') throw new Error('!');
|
|
||||||
if (!this.nodes[node.type.name]) throw new Error(`Token type \`${node.type.name}\` not supported by Word renderer`);
|
|
||||||
this.nodes[node.type.name](this, node, parent, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderMarks(node: ProsemirrorNode<S>, marks: Mark[]): IRunOptions {
|
|
||||||
return marks
|
|
||||||
.map((mark) => {
|
|
||||||
return this.marks[mark.type.name]?.(this, node, mark);
|
|
||||||
})
|
|
||||||
.reduce((a, b) => ({ ...a, ...b }), {});
|
|
||||||
}
|
|
||||||
|
|
||||||
renderInline(parent: ProsemirrorNode<S>) {
|
|
||||||
// Pop the stack over to this object when we encounter a link, and closeLink restores it
|
|
||||||
let currentLink: { link: string; stack: ParagraphChild[] } | undefined;
|
|
||||||
const closeLink = () => {
|
|
||||||
if (!currentLink) return;
|
|
||||||
const hyperlink = new ExternalHyperlink({
|
|
||||||
link: currentLink.link,
|
|
||||||
// child: this.current[0],
|
|
||||||
children: this.current,
|
|
||||||
});
|
|
||||||
this.current = [...currentLink.stack, hyperlink];
|
|
||||||
currentLink = undefined;
|
|
||||||
};
|
|
||||||
const openLink = (href: string) => {
|
|
||||||
const sameLink = href === currentLink?.link;
|
|
||||||
this.addRunOptions({ style: 'Hyperlink' });
|
|
||||||
// TODO: https://github.com/dolanmiu/docx/issues/1119
|
|
||||||
// Remove the if statement here and oneLink!
|
|
||||||
const oneLink = true;
|
|
||||||
if (!oneLink) {
|
|
||||||
closeLink();
|
|
||||||
} else {
|
|
||||||
if (currentLink && sameLink) return;
|
|
||||||
if (currentLink && !sameLink) {
|
|
||||||
// Close previous, and open a new one
|
|
||||||
closeLink();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentLink = {
|
|
||||||
link: href,
|
|
||||||
stack: this.current,
|
|
||||||
};
|
|
||||||
this.current = [];
|
|
||||||
};
|
|
||||||
const progress = (node: ProsemirrorNode<S>, offset: number, index: number) => {
|
|
||||||
const links = node.marks.filter((m) => m.type.name === 'link');
|
|
||||||
const hasLink = links.length > 0;
|
|
||||||
if (hasLink) {
|
|
||||||
openLink(links[0].attrs.href);
|
|
||||||
} else if (!hasLink && currentLink) {
|
|
||||||
closeLink();
|
|
||||||
}
|
|
||||||
if (node.isText) {
|
|
||||||
this.text(node.text, this.renderMarks(node, node.marks));
|
|
||||||
} else {
|
|
||||||
this.render(node, parent, index);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
parent.forEach(progress);
|
|
||||||
// Must call close at the end of everything, just in case
|
|
||||||
closeLink();
|
|
||||||
}
|
|
||||||
|
|
||||||
renderList(node: ProsemirrorNode<S>, style: NumberingStyles) {
|
|
||||||
if (!this.currentNumbering) {
|
|
||||||
const nextId = createShortId();
|
|
||||||
this.numbering.push(createNumbering(nextId, style));
|
|
||||||
this.currentNumbering = { reference: nextId, level: 0 };
|
|
||||||
} else {
|
|
||||||
const { reference, level } = this.currentNumbering;
|
|
||||||
this.currentNumbering = { reference, level: level + 1 };
|
|
||||||
}
|
|
||||||
this.renderContent(node);
|
|
||||||
if (this.currentNumbering.level === 0) {
|
|
||||||
delete this.currentNumbering;
|
|
||||||
} else {
|
|
||||||
const { reference, level } = this.currentNumbering;
|
|
||||||
this.currentNumbering = { reference, level: level - 1 };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a pass through to the paragraphs, etc. underneath they will close the block
|
|
||||||
renderListItem(node: ProsemirrorNode<S>) {
|
|
||||||
if (!this.currentNumbering) throw new Error('Trying to create a list item without a list?');
|
|
||||||
this.addParagraphOptions({ numbering: this.currentNumbering });
|
|
||||||
this.renderContent(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
addParagraphOptions(opts: IParagraphOptions) {
|
|
||||||
this.nextParentParagraphOpts = { ...this.nextParentParagraphOpts, ...opts };
|
|
||||||
}
|
|
||||||
|
|
||||||
addRunOptions(opts: IRunOptions) {
|
|
||||||
this.nextRunOpts = { ...this.nextRunOpts, ...opts };
|
|
||||||
}
|
|
||||||
|
|
||||||
text(text: string | null | undefined, opts?: IRunOptions) {
|
|
||||||
if (!text) return;
|
|
||||||
this.current.push(new TextRun({ text, ...this.nextRunOpts, ...opts }));
|
|
||||||
delete this.nextRunOpts;
|
|
||||||
}
|
|
||||||
|
|
||||||
math(latex: string, opts: IMathOpts = { inline: true }) {
|
|
||||||
if (opts.inline || !opts.numbered) {
|
|
||||||
this.current.push(new Math({ children: [new MathRun(latex)] }));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const id = opts.id ?? createShortId();
|
|
||||||
this.current = [
|
|
||||||
new TextRun('\t'),
|
|
||||||
new Math({
|
|
||||||
children: [new MathRun(latex)],
|
|
||||||
}),
|
|
||||||
new TextRun('\t('),
|
|
||||||
createReferenceBookmark(id, 'Equation'),
|
|
||||||
new TextRun(')'),
|
|
||||||
];
|
|
||||||
this.addParagraphOptions({
|
|
||||||
tabStops: [
|
|
||||||
{
|
|
||||||
type: TabStopType.CENTER,
|
|
||||||
position: TabStopPosition.MAX / 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: TabStopType.RIGHT,
|
|
||||||
position: TabStopPosition.MAX,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// not sure what this actually is, seems to be close for 8.5x11
|
|
||||||
maxImageWidth = MAX_IMAGE_WIDTH;
|
|
||||||
|
|
||||||
image(src: string, widthPercent = 70, align: AlignOptions = 'center') {
|
|
||||||
const buffer = this.options.getImageBuffer(src);
|
|
||||||
|
|
||||||
if (!buffer) return;
|
|
||||||
|
|
||||||
const dimensions = sizeOf(buffer);
|
|
||||||
const aspect = dimensions.height / dimensions.width;
|
|
||||||
const width = this.maxImageWidth * (widthPercent / 100);
|
|
||||||
this.current.push(
|
|
||||||
new ImageRun({
|
|
||||||
data: buffer,
|
|
||||||
transformation: {
|
|
||||||
width,
|
|
||||||
height: width * aspect,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
let alignment: AlignmentType;
|
|
||||||
switch (align) {
|
|
||||||
case 'right':
|
|
||||||
alignment = AlignmentType.RIGHT;
|
|
||||||
break;
|
|
||||||
case 'left':
|
|
||||||
alignment = AlignmentType.LEFT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
alignment = AlignmentType.CENTER;
|
|
||||||
}
|
|
||||||
this.addParagraphOptions({
|
|
||||||
alignment,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
table(node: ProsemirrorNode<S>) {
|
|
||||||
const actualChildren = this.children;
|
|
||||||
const rows: TableRow[] = [];
|
|
||||||
node.content.forEach(({ content: rowContent }) => {
|
|
||||||
const cells: TableCell[] = [];
|
|
||||||
// Check if all cells are headers in this row
|
|
||||||
let tableHeader = true;
|
|
||||||
rowContent.forEach((cell) => {
|
|
||||||
if (cell.type.name !== 'table_header') {
|
|
||||||
tableHeader = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// This scales images inside of tables
|
|
||||||
this.maxImageWidth = MAX_IMAGE_WIDTH / rowContent.childCount;
|
|
||||||
rowContent.forEach((cell) => {
|
|
||||||
this.children = [];
|
|
||||||
this.renderContent(cell);
|
|
||||||
const tableCellOpts: Mutable<ITableCellOptions> = {
|
|
||||||
children: this.children,
|
|
||||||
};
|
|
||||||
const colspan = cell.attrs.colspan ?? 1;
|
|
||||||
const rowspan = cell.attrs.rowspan ?? 1;
|
|
||||||
if (colspan > 1) tableCellOpts.columnSpan = colspan;
|
|
||||||
if (rowspan > 1) tableCellOpts.rowSpan = rowspan;
|
|
||||||
cells.push(new TableCell(tableCellOpts));
|
|
||||||
});
|
|
||||||
rows.push(new TableRow({ children: cells, tableHeader }));
|
|
||||||
});
|
|
||||||
this.maxImageWidth = MAX_IMAGE_WIDTH;
|
|
||||||
|
|
||||||
const table = new Table({
|
|
||||||
rows,
|
|
||||||
// columnWidths: Array.from({ length: rows[0].cells.length }, () => 3505),
|
|
||||||
});
|
|
||||||
actualChildren.push(table);
|
|
||||||
// If there are multiple tables, this seperates them
|
|
||||||
actualChildren.push(new Paragraph(''));
|
|
||||||
this.children = actualChildren;
|
|
||||||
}
|
|
||||||
|
|
||||||
captionLabel(id: string, kind: 'Figure' | 'Table', { suffix } = { suffix: ': ' }) {
|
|
||||||
this.current.push(...[createReferenceBookmark(id, kind, `${kind} `), new TextRun(suffix)]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$footnoteCounter = 0;
|
|
||||||
|
|
||||||
footnote(node: ProsemirrorNode<S>) {
|
|
||||||
const { current, nextRunOpts } = this;
|
|
||||||
// Delete everything and work with the footnote inline on the current
|
|
||||||
this.current = [];
|
|
||||||
delete this.nextRunOpts;
|
|
||||||
|
|
||||||
this.$footnoteCounter += 1;
|
|
||||||
this.renderInline(node);
|
|
||||||
this.footnotes[this.$footnoteCounter] = {
|
|
||||||
children: [new Paragraph({ children: this.current })],
|
|
||||||
};
|
|
||||||
this.current = current;
|
|
||||||
this.nextRunOpts = nextRunOpts;
|
|
||||||
this.current.push(new FootnoteReferenceRun(this.$footnoteCounter));
|
|
||||||
}
|
|
||||||
|
|
||||||
closeBlock(node: ProsemirrorNode<S>, props?: IParagraphOptions) {
|
|
||||||
const paragraph = new Paragraph({
|
|
||||||
children: this.current,
|
|
||||||
...this.nextParentParagraphOpts,
|
|
||||||
...props,
|
|
||||||
});
|
|
||||||
this.current = [];
|
|
||||||
delete this.nextParentParagraphOpts;
|
|
||||||
this.children.push(paragraph);
|
|
||||||
}
|
|
||||||
|
|
||||||
createReference(id: string, before?: string, after?: string) {
|
|
||||||
const children: ParagraphChild[] = [];
|
|
||||||
if (before) children.push(new TextRun(before));
|
|
||||||
children.push(new SimpleField(`REF ${id} \\h`));
|
|
||||||
if (after) children.push(new TextRun(after));
|
|
||||||
const ref = new InternalHyperlink({ anchor: id, children });
|
|
||||||
this.current.push(ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DocxSerializer<S extends Schema = any> {
|
|
||||||
nodes: NodeSerializer<S>;
|
|
||||||
|
|
||||||
marks: MarkSerializer<S>;
|
|
||||||
|
|
||||||
constructor(nodes: NodeSerializer<S>, marks: MarkSerializer<S>) {
|
|
||||||
this.nodes = nodes;
|
|
||||||
this.marks = marks;
|
|
||||||
}
|
|
||||||
|
|
||||||
serialize(content: ProsemirrorNode<S>, options: Options) {
|
|
||||||
const state = new DocxSerializerState<S>(this.nodes, this.marks, options);
|
|
||||||
state.renderContent(content);
|
|
||||||
const doc = createDocFromState(state);
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
import { INumberingOptions } from 'docx';
|
|
||||||
import { IPropertiesOptions } from 'docx/build/file/core-properties';
|
|
||||||
|
|
||||||
export type Mutable<T> = {
|
|
||||||
-readonly [k in keyof T]: T[k];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type IFootnotes = Mutable<Required<IPropertiesOptions>['footnotes']>;
|
|
||||||
export type INumbering = INumberingOptions['config'][0];
|
|
|
@ -1,47 +0,0 @@
|
||||||
import { Document, INumberingOptions, ISectionOptions, Packer, SectionType } from 'docx';
|
|
||||||
import { Node as ProsemirrorNode } from 'prosemirror-model';
|
|
||||||
|
|
||||||
import { IFootnotes } from './types';
|
|
||||||
|
|
||||||
export function createShortId() {
|
|
||||||
return Math.random().toString(36).substr(2, 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createDocFromState(state: {
|
|
||||||
numbering: INumberingOptions['config'];
|
|
||||||
children: ISectionOptions['children'];
|
|
||||||
footnotes?: IFootnotes;
|
|
||||||
}) {
|
|
||||||
const doc = new Document({
|
|
||||||
footnotes: state.footnotes,
|
|
||||||
numbering: {
|
|
||||||
config: state.numbering,
|
|
||||||
},
|
|
||||||
sections: [
|
|
||||||
{
|
|
||||||
properties: {
|
|
||||||
type: SectionType.CONTINUOUS,
|
|
||||||
},
|
|
||||||
children: state.children,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function writeDocx(
|
|
||||||
doc: Document,
|
|
||||||
write: ((buffer: Buffer) => void) | ((buffer: Buffer) => Promise<void>)
|
|
||||||
) {
|
|
||||||
const buffer = await Packer.toBuffer(doc);
|
|
||||||
return write(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getLatexFromNode(node: ProsemirrorNode): string {
|
|
||||||
let math = '';
|
|
||||||
node.forEach((child) => {
|
|
||||||
if (child.isText) math += child.text;
|
|
||||||
// TODO: improve this as we may have other things in the future
|
|
||||||
});
|
|
||||||
return math;
|
|
||||||
}
|
|
|
@ -32,6 +32,14 @@ export declare const DocumentApiDefinition: {
|
||||||
server: "detail/:id";
|
server: "detail/:id";
|
||||||
client: (id: IDocument['id']) => string;
|
client: (id: IDocument['id']) => string;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 导出文档
|
||||||
|
*/
|
||||||
|
exportDocx: {
|
||||||
|
method: "post";
|
||||||
|
server: "/export/docx";
|
||||||
|
client: () => string;
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* 更新文档
|
* 更新文档
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -34,6 +34,14 @@ exports.DocumentApiDefinition = {
|
||||||
server: 'detail/:id',
|
server: 'detail/:id',
|
||||||
client: function (id) { return "/document/detail/".concat(id); }
|
client: function (id) { return "/document/detail/".concat(id); }
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 导出文档
|
||||||
|
*/
|
||||||
|
exportDocx: {
|
||||||
|
method: 'post',
|
||||||
|
server: '/export/docx',
|
||||||
|
client: function () { return '/document/export/docx'; }
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 更新文档
|
* 更新文档
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -37,6 +37,15 @@ export const DocumentApiDefinition = {
|
||||||
client: (id: IDocument['id']) => `/document/detail/${id}`,
|
client: (id: IDocument['id']) => `/document/detail/${id}`,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出文档
|
||||||
|
*/
|
||||||
|
exportDocx: {
|
||||||
|
method: 'post' as const,
|
||||||
|
server: '/export/docx' as const,
|
||||||
|
client: () => '/document/export/docx',
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新文档
|
* 更新文档
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
"express-rate-limit": "^6.2.0",
|
"express-rate-limit": "^6.2.0",
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.0",
|
||||||
"helmet": "^5.0.2",
|
"helmet": "^5.0.2",
|
||||||
|
"html-to-docx": "^1.4.0",
|
||||||
"ioredis": "^5.0.1",
|
"ioredis": "^5.0.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mysql2": "^2.3.3",
|
"mysql2": "^2.3.3",
|
||||||
|
|
|
@ -109,6 +109,20 @@ export class DocumentController {
|
||||||
return await this.documentService.getDocumentVersion(req.user, documentId);
|
return await this.documentService.getDocumentVersion(req.user, documentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出文档
|
||||||
|
* @param req
|
||||||
|
* @param documentId
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
@UseInterceptors(ClassSerializerInterceptor)
|
||||||
|
@Post(DocumentApiDefinition.exportDocx.server)
|
||||||
|
@HttpCode(HttpStatus.OK)
|
||||||
|
@UseGuards(JwtGuard)
|
||||||
|
async exportDocx(@Body('content') content) {
|
||||||
|
return await this.documentService.exportDocx(content);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文档成员
|
* 获取文档成员
|
||||||
* @param req
|
* @param req
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { WikiService } from '@services/wiki.service';
|
||||||
import { EMPTY_DOCUMNENT } from '@think/constants';
|
import { EMPTY_DOCUMNENT } from '@think/constants';
|
||||||
import { AuthEnum, buildMessageURL, DocumentStatus, IUser } from '@think/domains';
|
import { AuthEnum, buildMessageURL, DocumentStatus, IUser } from '@think/domains';
|
||||||
import { instanceToPlain } from 'class-transformer';
|
import { instanceToPlain } from 'class-transformer';
|
||||||
|
import * as HTMLtoDOCX from 'html-to-docx';
|
||||||
import * as lodash from 'lodash';
|
import * as lodash from 'lodash';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
|
|
||||||
|
@ -761,4 +762,20 @@ export class DocumentService {
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出文档
|
||||||
|
* html-to-docx
|
||||||
|
* @param user
|
||||||
|
* @param content
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public async exportDocx(content) {
|
||||||
|
const fileBuffer = await HTMLtoDOCX(content, null, {
|
||||||
|
table: { row: { cantSplit: true } },
|
||||||
|
footer: true,
|
||||||
|
pageNumber: true,
|
||||||
|
});
|
||||||
|
return fileBuffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
229
pnpm-lock.yaml
229
pnpm-lock.yaml
|
@ -108,6 +108,7 @@ importers:
|
||||||
eslint-plugin-react-hooks: ^4.5.0
|
eslint-plugin-react-hooks: ^4.5.0
|
||||||
eslint-plugin-simple-import-sort: ^7.0.0
|
eslint-plugin-simple-import-sort: ^7.0.0
|
||||||
fs-extra: ^10.0.0
|
fs-extra: ^10.0.0
|
||||||
|
html-to-docx: ^1.4.0
|
||||||
interactjs: ^1.10.11
|
interactjs: ^1.10.11
|
||||||
katex: ^0.15.2
|
katex: ^0.15.2
|
||||||
kity: ^2.0.4
|
kity: ^2.0.4
|
||||||
|
@ -205,6 +206,7 @@ importers:
|
||||||
docx: 7.3.0
|
docx: 7.3.0
|
||||||
dompurify: 2.3.5
|
dompurify: 2.3.5
|
||||||
downloadjs: 1.4.7
|
downloadjs: 1.4.7
|
||||||
|
html-to-docx: 1.4.0
|
||||||
interactjs: 1.10.11
|
interactjs: 1.10.11
|
||||||
katex: 0.15.2
|
katex: 0.15.2
|
||||||
kity: 2.0.4
|
kity: 2.0.4
|
||||||
|
@ -326,6 +328,7 @@ importers:
|
||||||
express-rate-limit: ^6.2.0
|
express-rate-limit: ^6.2.0
|
||||||
fs-extra: ^10.0.0
|
fs-extra: ^10.0.0
|
||||||
helmet: ^5.0.2
|
helmet: ^5.0.2
|
||||||
|
html-to-docx: ^1.4.0
|
||||||
ioredis: ^5.0.1
|
ioredis: ^5.0.1
|
||||||
jest: ^27.2.5
|
jest: ^27.2.5
|
||||||
lodash: ^4.17.21
|
lodash: ^4.17.21
|
||||||
|
@ -383,6 +386,7 @@ importers:
|
||||||
express-rate-limit: 6.2.0_express@4.17.2
|
express-rate-limit: 6.2.0_express@4.17.2
|
||||||
fs-extra: 10.0.0
|
fs-extra: 10.0.0
|
||||||
helmet: 5.0.2
|
helmet: 5.0.2
|
||||||
|
html-to-docx: 1.4.0
|
||||||
ioredis: 5.0.1
|
ioredis: 5.0.1
|
||||||
lodash: 4.17.21
|
lodash: 4.17.21
|
||||||
mysql2: 2.3.3
|
mysql2: 2.3.3
|
||||||
|
@ -2615,6 +2619,57 @@ packages:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- encoding
|
- encoding
|
||||||
|
|
||||||
|
/@oozcitak/dom/1.15.5:
|
||||||
|
resolution: {integrity: sha512-L6v3Mwb0TaYBYgeYlIeBaHnc+2ZEaDSbFiRm5KmqZQSoBlbPlf+l6aIH/sD5GUf2MYwULw00LT7+dOnEuAEC0A==}
|
||||||
|
engines: {node: '>=8.0'}
|
||||||
|
dependencies:
|
||||||
|
'@oozcitak/infra': 1.0.5
|
||||||
|
'@oozcitak/url': 1.0.0
|
||||||
|
'@oozcitak/util': 8.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@oozcitak/infra/1.0.3:
|
||||||
|
resolution: {integrity: sha512-9O2wxXGnRzy76O1XUxESxDGsXT5kzETJPvYbreO4mv6bqe1+YSuux2cZTagjJ/T4UfEwFJz5ixanOqB0QgYAag==}
|
||||||
|
engines: {node: '>=6.0'}
|
||||||
|
dependencies:
|
||||||
|
'@oozcitak/util': 1.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@oozcitak/infra/1.0.5:
|
||||||
|
resolution: {integrity: sha512-o+zZH7M6l5e3FaAWy3ojaPIVN5eusaYPrKm6MZQt0DKNdgXa2wDYExjpP0t/zx+GoQgQKzLu7cfD8rHCLt8JrQ==}
|
||||||
|
engines: {node: '>=6.0'}
|
||||||
|
dependencies:
|
||||||
|
'@oozcitak/util': 8.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@oozcitak/url/1.0.0:
|
||||||
|
resolution: {integrity: sha512-LGrMeSxeLzsdaitxq3ZmBRVOrlRRQIgNNci6L0VRnOKlJFuRIkNm4B+BObXPCJA6JT5bEJtrrwjn30jueHJYZQ==}
|
||||||
|
engines: {node: '>=8.0'}
|
||||||
|
dependencies:
|
||||||
|
'@oozcitak/infra': 1.0.3
|
||||||
|
'@oozcitak/util': 1.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@oozcitak/util/1.0.1:
|
||||||
|
resolution: {integrity: sha512-dFwFqcKrQnJ2SapOmRD1nQWEZUtbtIy9Y6TyJquzsalWNJsKIPxmTI0KG6Ypyl8j7v89L2wixH9fQDNrF78hKg==}
|
||||||
|
engines: {node: '>=6.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@oozcitak/util/1.0.2:
|
||||||
|
resolution: {integrity: sha512-4n8B1cWlJleSOSba5gxsMcN4tO8KkkcvXhNWW+ADqvq9Xj+Lrl9uCa90GRpjekqQJyt84aUX015DG81LFpZYXA==}
|
||||||
|
engines: {node: '>=6.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@oozcitak/util/8.0.0:
|
||||||
|
resolution: {integrity: sha512-+9Hq6yuoq/3TRV/n/xcpydGBq2qN2/DEDMqNTG7rm95K6ZE2/YY/sPyx62+1n8QsE9O26e5M1URlXsk+AnN9Jw==}
|
||||||
|
engines: {node: '>=6.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@oozcitak/util/8.3.3:
|
||||||
|
resolution: {integrity: sha512-Ufpab7G5PfnEhQyy5kDg9C8ltWJjsVT1P/IYqacjstaqydG4Q21HAT2HUZQYBrC/a1ZLKCz87pfydlDvv8y97w==}
|
||||||
|
engines: {node: '>=6.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@popperjs/core/2.11.2:
|
/@popperjs/core/2.11.2:
|
||||||
resolution: {integrity: sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA==}
|
resolution: {integrity: sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -4355,6 +4410,10 @@ packages:
|
||||||
resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==}
|
resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/browser-split/0.0.1:
|
||||||
|
resolution: {integrity: sha512-JhvgRb2ihQhsljNda3BI8/UcRHVzrVwo3Q+P8vDtSiyobXuFpuZ9mq+MbRGMnC22CjW3RrfXdg6j6ITX8M+7Ow==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/browserslist/4.19.1:
|
/browserslist/4.19.1:
|
||||||
resolution: {integrity: sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==}
|
resolution: {integrity: sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==}
|
||||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||||
|
@ -4483,6 +4542,10 @@ packages:
|
||||||
resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
|
resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
/camelize/1.0.0:
|
||||||
|
resolution: {integrity: sha512-W2lPwkBkMZwFlPCXhIlYgxu+7gC/NUlCtdK652DAJ1JdgV0sTrvuPFshNPrFa1TY2JOkLhgdeEBplB4ezEa+xg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/caniuse-lite/1.0.30001304:
|
/caniuse-lite/1.0.30001304:
|
||||||
resolution: {integrity: sha512-bdsfZd6K6ap87AGqSHJP/s1V+U6Z5lyrcbBu3ovbCCf8cSYpwTtGrCBObMpJqwxfTbLW6YTIdbb1jEeTelcpYQ==}
|
resolution: {integrity: sha512-bdsfZd6K6ap87AGqSHJP/s1V+U6Z5lyrcbBu3ovbCCf8cSYpwTtGrCBObMpJqwxfTbLW6YTIdbb1jEeTelcpYQ==}
|
||||||
|
|
||||||
|
@ -5306,6 +5369,25 @@ packages:
|
||||||
xml-js: 1.6.11
|
xml-js: 1.6.11
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/dom-serializer/0.2.2:
|
||||||
|
resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==}
|
||||||
|
dependencies:
|
||||||
|
domelementtype: 2.3.0
|
||||||
|
entities: 2.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/dom-walk/0.1.2:
|
||||||
|
resolution: {integrity: sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/domelementtype/1.3.1:
|
||||||
|
resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/domelementtype/2.3.0:
|
||||||
|
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/domexception/2.0.1:
|
/domexception/2.0.1:
|
||||||
resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==}
|
resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -5313,10 +5395,23 @@ packages:
|
||||||
webidl-conversions: 5.0.0
|
webidl-conversions: 5.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/domhandler/2.4.2:
|
||||||
|
resolution: {integrity: sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==}
|
||||||
|
dependencies:
|
||||||
|
domelementtype: 1.3.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/dompurify/2.3.5:
|
/dompurify/2.3.5:
|
||||||
resolution: {integrity: sha512-kD+f8qEaa42+mjdOpKeztu9Mfx5bv9gVLO6K9jRx4uGvh6Wv06Srn4jr1wPNY2OOUGGSKHNFN+A8MA3v0E0QAQ==}
|
resolution: {integrity: sha512-kD+f8qEaa42+mjdOpKeztu9Mfx5bv9gVLO6K9jRx4uGvh6Wv06Srn4jr1wPNY2OOUGGSKHNFN+A8MA3v0E0QAQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/domutils/1.7.0:
|
||||||
|
resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==}
|
||||||
|
dependencies:
|
||||||
|
dom-serializer: 0.2.2
|
||||||
|
domelementtype: 1.3.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/dot-prop/6.0.1:
|
/dot-prop/6.0.1:
|
||||||
resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==}
|
resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
@ -5424,6 +5519,14 @@ packages:
|
||||||
graceful-fs: 4.2.9
|
graceful-fs: 4.2.9
|
||||||
tapable: 2.2.1
|
tapable: 2.2.1
|
||||||
|
|
||||||
|
/ent/2.2.0:
|
||||||
|
resolution: {integrity: sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/entities/1.1.2:
|
||||||
|
resolution: {integrity: sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/entities/2.1.0:
|
/entities/2.1.0:
|
||||||
resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==}
|
resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==}
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -5439,6 +5542,14 @@ packages:
|
||||||
is-arrayish: 0.2.1
|
is-arrayish: 0.2.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/error/4.4.0:
|
||||||
|
resolution: {integrity: sha512-SNDKualLUtT4StGFP7xNfuFybL2f6iJujFtrWuvJqGbVQGaN+adE23veqzPz1hjUjTunLi2EnJ+0SJxtbJreKw==}
|
||||||
|
dependencies:
|
||||||
|
camelize: 1.0.0
|
||||||
|
string-template: 0.2.1
|
||||||
|
xtend: 4.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/es-abstract/1.19.1:
|
/es-abstract/1.19.1:
|
||||||
resolution: {integrity: sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==}
|
resolution: {integrity: sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
@ -5526,7 +5637,7 @@ packages:
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
/escape-html/1.0.3:
|
/escape-html/1.0.3:
|
||||||
resolution: {integrity: sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=}
|
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
|
||||||
|
|
||||||
/escape-string-regexp/1.0.5:
|
/escape-string-regexp/1.0.5:
|
||||||
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
|
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
|
||||||
|
@ -5845,6 +5956,12 @@ packages:
|
||||||
resolution: {integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=}
|
resolution: {integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
|
|
||||||
|
/ev-store/7.0.0:
|
||||||
|
resolution: {integrity: sha512-otazchNRnGzp2YarBJ+GXKVGvhxVATB1zmaStxJBYet0Dyq7A9VhH8IUEB/gRcL6Ch52lfpgPTRJ2m49epyMsQ==}
|
||||||
|
dependencies:
|
||||||
|
individual: 3.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/events/3.3.0:
|
/events/3.3.0:
|
||||||
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
|
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
|
||||||
engines: {node: '>=0.8.x'}
|
engines: {node: '>=0.8.x'}
|
||||||
|
@ -6416,6 +6533,13 @@ packages:
|
||||||
which: 1.3.1
|
which: 1.3.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/global/4.4.0:
|
||||||
|
resolution: {integrity: sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==}
|
||||||
|
dependencies:
|
||||||
|
min-document: 2.19.0
|
||||||
|
process: 0.11.10
|
||||||
|
dev: false
|
||||||
|
|
||||||
/globals/11.12.0:
|
/globals/11.12.0:
|
||||||
resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
|
resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
@ -6563,6 +6687,38 @@ packages:
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/html-to-docx/1.4.0:
|
||||||
|
resolution: {integrity: sha512-VEbwMb5lwQZiJcnRZLofhziNtQ9UbVE7MQGICZKp896gC6P0ikfU6XRc8g4Z5qmYRBqLBXnY7b6iFYJ72yqNrw==}
|
||||||
|
dependencies:
|
||||||
|
color-name: 1.1.4
|
||||||
|
escape-html: 1.0.3
|
||||||
|
html-to-vdom: 0.7.0
|
||||||
|
image-size: 1.0.2
|
||||||
|
jszip: 3.10.0
|
||||||
|
lodash: 4.17.21
|
||||||
|
nanoid: 3.3.1
|
||||||
|
virtual-dom: 2.1.1
|
||||||
|
xmlbuilder2: 2.1.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/html-to-vdom/0.7.0:
|
||||||
|
resolution: {integrity: sha512-k+d2qNkbx0JO00KezQsNcn6k2I/xSBP4yXYFLvXbcasTTDh+RDLUJS3puxqyNnpdyXWRHFGoKU7cRmby8/APcQ==}
|
||||||
|
dependencies:
|
||||||
|
ent: 2.2.0
|
||||||
|
htmlparser2: 3.10.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/htmlparser2/3.10.1:
|
||||||
|
resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==}
|
||||||
|
dependencies:
|
||||||
|
domelementtype: 1.3.1
|
||||||
|
domhandler: 2.4.2
|
||||||
|
domutils: 1.7.0
|
||||||
|
entities: 1.1.2
|
||||||
|
inherits: 2.0.4
|
||||||
|
readable-stream: 3.6.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/http-errors/1.8.1:
|
/http-errors/1.8.1:
|
||||||
resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==}
|
resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
|
@ -6665,6 +6821,14 @@ packages:
|
||||||
resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==}
|
resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==}
|
||||||
engines: {node: '>= 4'}
|
engines: {node: '>= 4'}
|
||||||
|
|
||||||
|
/image-size/1.0.2:
|
||||||
|
resolution: {integrity: sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==}
|
||||||
|
engines: {node: '>=14.0.0'}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
queue: 6.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/immediate/3.0.6:
|
/immediate/3.0.6:
|
||||||
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
|
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -6701,6 +6865,10 @@ packages:
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/individual/3.0.0:
|
||||||
|
resolution: {integrity: sha512-rUY5vtT748NMRbEMrTNiFfy29BgGZwGXUi2NFUVMWQrogSLzlJvQV9eeMWi+g1aVaQ53tpyLAQtd5x/JH0Nh1g==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/inflight/1.0.6:
|
/inflight/1.0.6:
|
||||||
resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=}
|
resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -6918,6 +7086,10 @@ packages:
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/is-object/1.0.2:
|
||||||
|
resolution: {integrity: sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/is-path-cwd/2.2.0:
|
/is-path-cwd/2.2.0:
|
||||||
resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==}
|
resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
@ -8319,6 +8491,12 @@ packages:
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/min-document/2.19.0:
|
||||||
|
resolution: {integrity: sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==}
|
||||||
|
dependencies:
|
||||||
|
dom-walk: 0.1.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/min-indent/1.0.1:
|
/min-indent/1.0.1:
|
||||||
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
|
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
@ -8500,6 +8678,10 @@ packages:
|
||||||
- webpack
|
- webpack
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/next-tick/0.2.2:
|
||||||
|
resolution: {integrity: sha512-f7h4svPtl+QidoBv4taKXUjJ70G2asaZ8G28nS0OkqaalX8dwwrtWtyxEDPK62AC00ur/+/E0pUwBwY5EPn15Q==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/next/12.1.0_sfoxds7t5ydpegc3knd667wn6m:
|
/next/12.1.0_sfoxds7t5ydpegc3knd667wn6m:
|
||||||
resolution: {integrity: sha512-s885kWvnIlxsUFHq9UGyIyLiuD0G3BUC/xrH0CEnH5lHEWkwQcHOORgbDF0hbrW9vr/7am4ETfX4A7M6DjrE7Q==}
|
resolution: {integrity: sha512-s885kWvnIlxsUFHq9UGyIyLiuD0G3BUC/xrH0CEnH5lHEWkwQcHOORgbDF0hbrW9vr/7am4ETfX4A7M6DjrE7Q==}
|
||||||
engines: {node: '>=12.22.0'}
|
engines: {node: '>=12.22.0'}
|
||||||
|
@ -9264,6 +9446,11 @@ packages:
|
||||||
resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==}
|
resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/process/0.11.10:
|
||||||
|
resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
|
||||||
|
engines: {node: '>= 0.6.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/prompts/2.4.2:
|
/prompts/2.4.2:
|
||||||
resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
|
resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
@ -9466,6 +9653,12 @@ packages:
|
||||||
/queue-microtask/1.2.3:
|
/queue-microtask/1.2.3:
|
||||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||||
|
|
||||||
|
/queue/6.0.2:
|
||||||
|
resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==}
|
||||||
|
dependencies:
|
||||||
|
inherits: 2.0.4
|
||||||
|
dev: false
|
||||||
|
|
||||||
/quick-format-unescaped/4.0.4:
|
/quick-format-unescaped/4.0.4:
|
||||||
resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
|
resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -10471,6 +10664,10 @@ packages:
|
||||||
strip-ansi: 6.0.1
|
strip-ansi: 6.0.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/string-template/0.2.1:
|
||||||
|
resolution: {integrity: sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/string-width/4.2.3:
|
/string-width/4.2.3:
|
||||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -11558,6 +11755,19 @@ packages:
|
||||||
resolution: {integrity: sha512-CjMt64yC9D+XUx2t3F0TPbh/Yt5+/ke8/s3IizXa6NtksdJUFDoCcNxi/KRZ9eiZPR/D77pHnnQzAtCoLDaGIw==}
|
resolution: {integrity: sha512-CjMt64yC9D+XUx2t3F0TPbh/Yt5+/ke8/s3IizXa6NtksdJUFDoCcNxi/KRZ9eiZPR/D77pHnnQzAtCoLDaGIw==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/virtual-dom/2.1.1:
|
||||||
|
resolution: {integrity: sha512-wb6Qc9Lbqug0kRqo/iuApfBpJJAq14Sk1faAnSmtqXiwahg7PVTvWMs9L02Z8nNIMqbwsxzBAA90bbtRLbw0zg==}
|
||||||
|
dependencies:
|
||||||
|
browser-split: 0.0.1
|
||||||
|
error: 4.4.0
|
||||||
|
ev-store: 7.0.0
|
||||||
|
global: 4.4.0
|
||||||
|
is-object: 1.0.2
|
||||||
|
next-tick: 0.2.2
|
||||||
|
x-is-array: 0.1.0
|
||||||
|
x-is-string: 0.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/vm2/3.9.5:
|
/vm2/3.9.5:
|
||||||
resolution: {integrity: sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng==}
|
resolution: {integrity: sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng==}
|
||||||
engines: {node: '>=6.0'}
|
engines: {node: '>=6.0'}
|
||||||
|
@ -11995,6 +12205,14 @@ packages:
|
||||||
optional: true
|
optional: true
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/x-is-array/0.1.0:
|
||||||
|
resolution: {integrity: sha512-goHPif61oNrr0jJgsXRfc8oqtYzvfiMJpTqwE7Z4y9uH+T3UozkGqQ4d2nX9mB9khvA8U2o/UbPOFjgC7hLWIA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/x-is-string/0.1.0:
|
||||||
|
resolution: {integrity: sha512-GojqklwG8gpzOVEVki5KudKNoq7MbbjYZCbyWzEz7tyPA7eleiE0+ePwOWQQRb5fm86rD3S8Tc0tSFf3AOv50w==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/xml-js/1.6.11:
|
/xml-js/1.6.11:
|
||||||
resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==}
|
resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
@ -12023,6 +12241,15 @@ packages:
|
||||||
engines: {node: '>=4.0'}
|
engines: {node: '>=4.0'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/xmlbuilder2/2.1.2:
|
||||||
|
resolution: {integrity: sha512-PI710tmtVlQ5VmwzbRTuhmVhKnj9pM8Si+iOZCV2g2SNo3gCrpzR2Ka9wNzZtqfD+mnP+xkrqoNy0sjKZqP4Dg==}
|
||||||
|
engines: {node: '>=8.0'}
|
||||||
|
dependencies:
|
||||||
|
'@oozcitak/dom': 1.15.5
|
||||||
|
'@oozcitak/infra': 1.0.5
|
||||||
|
'@oozcitak/util': 8.3.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
/xmlchars/2.2.0:
|
/xmlchars/2.2.0:
|
||||||
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
|
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
Loading…
Reference in New Issue