diff --git a/packages/cli/package.json b/packages/cli/package.json index 6b317c23..65021161 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -3,7 +3,7 @@ "description": "Command line interface for Tuture", "version": "0.1.0", "bin": { - "tuture": "./lib/index.js" + "tuture": "./dist/index.js" }, "type": "module", "main": "dist/index.js", @@ -28,6 +28,7 @@ "fs-extra": "^7.0.0", "get-port": "^5.1.1", "inquirer": "^6.0.0", + "isbinaryfile": "^5.0.0", "micromatch": "^3.1.10", "open": "^6.4.0", "prosemirror-markdown": "1.5.1", @@ -42,9 +43,9 @@ "@oclif/dev-cli": "^1", "@types/debug": "^4.1.7", "@types/inquirer": "^6.5.0", - "@types/prosemirror-markdown": "1.5.2", "@types/micromatch": "^4.0.1", "@types/node": "^10", + "@types/prosemirror-markdown": "1.5.2", "globby": "^10", "rimraf": "^2.6.2", "ts-node": "^8" diff --git a/packages/cli/src/commands/build.ts b/packages/cli/src/commands/build.ts index 1d6ef29a..424b7969 100644 --- a/packages/cli/src/commands/build.ts +++ b/packages/cli/src/commands/build.ts @@ -12,7 +12,6 @@ import { Collection, IMeta, isCommitEqual, - ArticleNodes, tutureSchema, markdownSerializer, } from '@tuture/core'; @@ -297,10 +296,7 @@ function articleTmpl(meta: IMeta, steps: any[]) { .replace(/\n{3,}/g, '\n\n'); } -function generateTutorials( - collection: Collection, - articleNodes: ArticleNodes[], -) { +function generateTutorials(collection: Collection) { const { name, articles, diff --git a/packages/cli/src/commands/destroy.ts b/packages/cli/src/commands/destroy.ts index 3e563e86..41648f48 100644 --- a/packages/cli/src/commands/destroy.ts +++ b/packages/cli/src/commands/destroy.ts @@ -1,6 +1,11 @@ import { Command } from 'commander'; import inquirer from 'inquirer'; import debug from 'debug'; +import { + loadCollection, + deleteDocs, + deleteCollection, +} from '@tuture/local-server'; import logger from '../utils/logger.js'; @@ -35,6 +40,13 @@ async function doDestroy(options: DestroyOptions) { } } + const collection = loadCollection(); + const articleIds = collection.articles.map((article) => article.id); + d('delete article ids: %o', articleIds); + await deleteDocs(articleIds); + + await deleteCollection(collection.id); + logger.log('success', 'Tutorial has been destroyed!'); } diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts index 1f28558d..07c10bba 100644 --- a/packages/cli/src/commands/init.ts +++ b/packages/cli/src/commands/init.ts @@ -66,7 +66,7 @@ async function doInit(options: InitOptions) { d('cwd: %s', process.cwd()); d('options: %o', options); - const item = await getInventoryItemByPath(process.cwd()); + const item = getInventoryItemByPath(process.cwd()); d('inventory item: %o', item); if (item) { logger.log('success', 'Tuture tutorial has already been initialized!'); @@ -120,8 +120,8 @@ async function doInit(options: InitOptions) { collection.version = SCHEMA_VERSION; d('init collection: %O', collection); - await saveToInventory(process.cwd(), collection); - await saveCollection(collection); + saveToInventory(process.cwd(), collection); + saveCollection(collection); logger.log('success', 'Tuture tutorial has been initialized!'); } diff --git a/packages/cli/src/utils/index.ts b/packages/cli/src/utils/index.ts index 35a8aa88..829d9444 100644 --- a/packages/cli/src/utils/index.ts +++ b/packages/cli/src/utils/index.ts @@ -20,42 +20,34 @@ export async function initNodes(ignoredFiles?: string[]): Promise { // filter out commits whose commit message starts with 'tuture:' .filter(({ message }) => !message.startsWith('tuture:')); - const nodeProms: Promise[] = logs.map( - async ({ message, hash }, index) => { - const files = await readDiff(hash); - const delimiterAttrs = { commit: hash }; - const stepAttrs = { - id: randHex(32), - name: message, + const nodeProms: Promise[] = logs.map(async ({ message, hash }) => { + const files = await readDiff(hash); + const delimiterAttrs = { commit: hash }; + const fileNodes = await Promise.all( + files.map(async (diffFile) => { + const hidden = ignoredFiles?.some((pattern) => + mm.isMatch(diffFile.to!, pattern), + ); + return await newEmptyFile(hash, diffFile, Boolean(hidden)); + }), + ); + return [ + { type: 'step_start', attrs: delimiterAttrs, content: [] }, + newStepTitle(hash, [{ type: 'text', text: message }]), + newEmptyExplain({ + level: 'step', + pos: 'pre', commit: hash, - order: index, - }; - const fileNodes = await Promise.all( - files.map(async (diffFile) => { - const hidden = ignoredFiles?.some((pattern) => - mm.isMatch(diffFile.to!, pattern), - ); - return await newEmptyFile(hash, diffFile, Boolean(hidden)); - }), - ); - return [ - { type: 'step_start', attrs: delimiterAttrs, content: [] }, - newStepTitle(hash, [{ type: 'text', text: message }]), - newEmptyExplain({ - level: 'step', - pos: 'pre', - commit: hash, - }), - ...fileNodes.flat(), - newEmptyExplain({ - level: 'step', - pos: 'post', - commit: hash, - }), - { type: 'step_end', attrs: delimiterAttrs, content: [] }, - ]; - }, - ); + }), + ...fileNodes.flat(), + newEmptyExplain({ + level: 'step', + pos: 'post', + commit: hash, + }), + { type: 'step_end', attrs: delimiterAttrs, content: [] }, + ]; + }); const nodes = await Promise.all(nodeProms); return nodes.flat(); diff --git a/packages/cli/src/utils/node.ts b/packages/cli/src/utils/node.ts index a20a43f7..c422780e 100644 --- a/packages/cli/src/utils/node.ts +++ b/packages/cli/src/utils/node.ts @@ -1,4 +1,5 @@ import debug from 'debug'; +import { isBinaryFile } from 'isbinaryfile'; import { IText, INode, @@ -11,7 +12,6 @@ import { getHiddenLines, Collection, Article, - isStepTitle, } from '@tuture/core'; import { readFileAtCommit } from '@tuture/local-server'; @@ -47,6 +47,7 @@ export async function newEmptyFile( diffFile: DiffFile, hidden: boolean, ): Promise { + // TODO: handle delete case (the file no longer exists!) const file = diffFile.to!; const diffBlock: IDiffBlock = { type: 'diff_block', @@ -62,6 +63,27 @@ export async function newEmptyFile( hiddenLines: getHiddenLines(diffFile), }, }; + + if (await isBinaryFile(file)) { + // Binary files are hidden by default. + diffBlock.attrs.hidden = true; + } else { + const code = diffFile.deleted + ? '' + : (await readFileAtCommit(commit, file)) || ''; + const originalCode = diffFile.new + ? '' + : (await readFileAtCommit(`${commit}~1`, file)) || ''; + + // Skip files with too lengthy diff + // TODO: Add it to the config + if (code.length <= 10000 || originalCode.length <= 10000) { + // If not binary, try reading diff. + diffBlock.attrs.code = code; + diffBlock.attrs.originalCode = originalCode; + } + } + d('diffBlock: %o', diffBlock); const delimiterAttrs = { commit, diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index f4236de6..46c5842d 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,5 +1,4 @@ export * from './interfaces.js'; -export * from './compat.js'; export * from './utils.js'; export * from './diff.js'; export * from './version.js'; diff --git a/packages/core/src/schema.ts b/packages/core/src/schema.ts index f61734d5..d83236e6 100644 --- a/packages/core/src/schema.ts +++ b/packages/core/src/schema.ts @@ -72,6 +72,36 @@ export const tutureSchema = new Schema({ }, }, + ordered_list: { + attrs: { + order: { + default: 1, + }, + }, + content: 'list_item+', + group: 'block', + parseDOM: [{ tag: 'ol' }], + toDOM: (node) => + node.attrs.order === 1 + ? ['ol', 0] + : ['ol', { start: node.attrs.order }, 0], + }, + + bullet_list: { + content: 'list_item+', + group: 'block', + parseDOM: [{ tag: 'ul' }], + toDOM: () => ['ul', 0], + }, + + list_item: { + content: 'paragraph block*', + defining: true, + draggable: false, + parseDOM: [{ tag: 'li' }], + toDOM: () => ['li', 0], + }, + explain: { content: 'block+', group: 'block', diff --git a/packages/editor/package.json b/packages/editor/package.json index 9d0e2ecc..e5f6cb92 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -40,8 +40,8 @@ "smooth-scroll-into-view-if-needed": "^1.1.32", "tiptap": "1.32.2", "tiptap-extensions": "1.35.2", - "v-code-diff": "^0.3.8", "vue": "^2.6.11", + "vue-code-diff": "^1.2.0", "vue-demi": "^0.7.4", "vue-router": "^3.2.0", "vuex": "^3.4.0", diff --git a/packages/editor/src/editor/components/DiffView.vue b/packages/editor/src/editor/components/DiffView.vue index 216b4ba5..2bc8a9ca 100644 --- a/packages/editor/src/editor/components/DiffView.vue +++ b/packages/editor/src/editor/components/DiffView.vue @@ -14,8 +14,9 @@ class="whitespace-normal" :old-string="originalCode" :new-string="code" - :file-name="filename" - :output-format="outputFormat" + :context="10" + :fileName="filename" + :outputFormat="outputFormat" /> import { defineComponent } from 'vue-demi'; +import CodeDiff from 'vue-code-diff'; + // import { CodeDiff } from 'v-code-diff'; import MonacoEditor from './MonacoEditor.vue'; export default defineComponent({ props: ['node', 'updateAttrs', 'view', 'editor'], components: { - // CodeDiff, + CodeDiff, MonacoEditor, }, data() { diff --git a/packages/editor/src/main.js b/packages/editor/src/main.js index 64d7fc32..3c4a3d10 100644 --- a/packages/editor/src/main.js +++ b/packages/editor/src/main.js @@ -56,7 +56,6 @@ import { faArrowRight, } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'; -import CodeDiff from 'v-code-diff'; import App from './App.vue'; import router from './router'; @@ -120,8 +119,6 @@ Vue.use(Switch); Vue.use(Popover); Vue.use(Popconfirm); -Vue.use(CodeDiff); - Vue.prototype.$message = message; // 捕获 monaco 的 unhandledrejection diff --git a/packages/local-server/src/utils/collection.ts b/packages/local-server/src/utils/collection.ts index 0cc4ee1b..aaa7c7b7 100644 --- a/packages/local-server/src/utils/collection.ts +++ b/packages/local-server/src/utils/collection.ts @@ -1,11 +1,11 @@ import debug from 'debug'; import fs from 'fs-extra'; import path from 'path'; -import { INode, Collection, SCHEMA_VERSION } from '@tuture/core'; +import { Collection } from '@tuture/core'; import { LowSync, JSONFileSync } from 'lowdb'; import { getCollectionsRoot } from './path.js'; -import { getInventoryItemByPath } from './inventory.js'; +import { getInventoryItemByPath, removeFromInventory } from './inventory.js'; const d = debug('tuture:local-server:collection'); @@ -54,21 +54,6 @@ export function getCollectionDb(collectionId?: string) { */ export function loadCollection(collectionId?: string) { const db = getCollectionDb(collectionId); - - // if (collection.version !== 'v1' && collection.version !== SCHEMA_VERSION) { - // throw new Error( - // 'incompatible collection version, please contact mrc@mail.tuture.co to fix it', - // ); - // } - - // if (collection.version === 'v1') { - // let [collectionV2, stepDocs] = convertV1ToV2(collection); - // collection = collectionV2; - // collection.version = SCHEMA_VERSION; - - // Object.entries(stepDocs).forEach(([id, doc]) => saveStepSync(id, doc)); - // } - return db.data!; } @@ -84,4 +69,5 @@ export function saveCollection(collection: Collection) { export async function deleteCollection(collectionId: string) { await fs.remove(getCollectionPath(collectionId)); + removeFromInventory(collectionId); } diff --git a/packages/local-server/src/utils/doc.ts b/packages/local-server/src/utils/doc.ts index 8229c9a8..6352da92 100644 --- a/packages/local-server/src/utils/doc.ts +++ b/packages/local-server/src/utils/doc.ts @@ -25,8 +25,10 @@ export async function saveDoc(doc: any) { await ldb.destroy(); } -export async function deleteDoc(docId: string) { +export async function deleteDocs(docIds: string[]) { const ldb = getDocPersistence(); - await ldb.clearDocument(docId); + await Promise.all( + docIds.map(async (docId) => await ldb.clearDocument(docId)), + ); await ldb.destroy(); } diff --git a/packages/migrator/package.json b/packages/migrator/package.json new file mode 100644 index 00000000..75fac4fe --- /dev/null +++ b/packages/migrator/package.json @@ -0,0 +1,46 @@ +{ + "name": "@tuture/migrator", + "description": "Migration utility for legacy Tuture tutorials", + "version": "0.0.1", + "bin": { + "tuture-migrate": "./dist/index.js" + }, + "type": "module", + "main": "dist/index.js", + "bugs": "https://github.com/tuture-dev/tuture/issues", + "scripts": { + "build": "rimraf dist && tsc -v && tsc -b", + "test": "echo NO TESTS" + }, + "dependencies": { + "@tuture/core": "^0.0.7", + "@tuture/local-server": "^0.0.7", + "commander": "^8.3.0", + "debug": "^4.3.3", + "fs-extra": "^7.0.0", + "inquirer": "^6.0.0", + "isbinaryfile": "^5.0.0", + "micromatch": "^3.1.10", + "open": "^6.4.0", + "prosemirror-markdown": "1.5.1", + "tslib": "^1" + }, + "devDependencies": { + "@types/debug": "^4.1.7", + "@types/node": "^10", + "rimraf": "^2.6.2", + "ts-node": "^8" + }, + "engines": { + "node": ">=16.0.0" + }, + "files": [ + "/dist", + "/npm-shrinkwrap.json" + ], + "keywords": [ + "tuture", + "cli" + ], + "license": "MIT" +} diff --git a/packages/migrator/src/index.ts b/packages/migrator/src/index.ts new file mode 100644 index 00000000..e3e62a88 --- /dev/null +++ b/packages/migrator/src/index.ts @@ -0,0 +1,16 @@ +#!/usr/bin/env node + +import { Command } from 'commander'; +import { MigrateOptions, migrate } from './migrate.js'; + +const program = new Command('tuture'); + +program + .version('0.0.1') + .argument('[path]', 'path to legacy tutorial') + .option('--dry-run', 'run in dry-run mode') + .description('Migration utility for legacy Tuture tutorials') + .action(async (path: string, options: MigrateOptions) => { + await migrate(path, options); + }) + .parse(process.argv); diff --git a/packages/core/src/compat.ts b/packages/migrator/src/migrate.ts similarity index 53% rename from packages/core/src/compat.ts rename to packages/migrator/src/migrate.ts index ec6ed357..85e2ab46 100644 --- a/packages/core/src/compat.ts +++ b/packages/migrator/src/migrate.ts @@ -1,12 +1,27 @@ +import debug from 'debug'; +import fs from 'fs-extra'; +import path from 'path'; +import pick from 'lodash.pick'; +import { isBinaryFile } from 'isbinaryfile'; import { Element, Node } from 'editure'; +import { Collection, IText, INode, IMark } from '@tuture/core'; import { - Collection as CollectionV2, - IText, - INode, - IMark, - Article, -} from './interfaces'; -import { Collection, File, Explain, StepTitle, getStepTitle } from './legacy'; + Collection as CollectionV1, + Step, + File, + Explain, + StepTitle, +} from '@tuture/core/dist/legacy'; +import { + readDiff, + readFileAtCommit, + saveDoc, + saveCollection, + saveToInventory, + getInventoryItemByPath, +} from '@tuture/local-server'; + +const d = debug('tuture:migrator'); function convertInline(node: Node): IText | INode | null { if (node.type === 'image') { @@ -88,6 +103,16 @@ function convertBlock(node: Element): INode { }, ], }; + case 'image': + return { + type: 'paragraph', + content: [ + { + type: 'image', + attrs: { src: node.url }, + }, + ], + }; case 'note': return { type: 'notice', @@ -168,7 +193,11 @@ function convertFile(file: File): INode[] { throw new Error(`number of children err, file: ${JSON.stringify(file)}`); } const [prex, diff, postex] = file.children; - const commitFile = { commit: diff.commit, file: file.file }; + const commitFile = { + commit: diff.commit, + file: file.file, + display: file.display, + }; return [ { type: 'file_start', @@ -206,76 +235,128 @@ function convertFile(file: File): INode[] { ]; } -export type ArticleNodes = { - articleId: string; - nodes: INode[]; +function convertStep(step: Step): INode[] { + return [ + { type: 'step_start', attrs: { commit: step.commit } }, + ...step.children.flatMap((node, index) => { + if (index === 0) { + const title = node as StepTitle; + return { + type: 'heading', + content: convertInlineNodes(title.children), + attrs: { + id: title.id, + level: 2, + fixed: true, + commit: title.commit, + }, + }; + } else if (index === 1 || index === step.children.length - 1) { + return { + type: 'explain', + attrs: { + fixed: true, + level: 'step', + pos: index === 1 ? 'pre' : 'post', + commit: step.commit, + }, + content: (node as Explain).children.map((block) => + convertBlock(block as Element), + ), + }; + } else { + return convertFile(node as File); + } + }), + { type: 'step_end', attrs: { commit: step.commit } }, + ]; +} + +export type MigrateOptions = { + dryRun: boolean; }; -// export function convertV1ToV2( -// collection: Collection, -// ): [CollectionV2, StepDocs] { -// const stepDocs: StepDocs = {}; -// const collectionV2 = collection as any; -// collectionV2.unassignedSteps = []; -// // collectionV2.articles.forEach((article: Article) => { -// // article.steps = []; -// // }); +export async function migrate(tutorialPath: string, options: MigrateOptions) { + process.chdir(tutorialPath); + d('cwd: %s', process.cwd()); + + const item = getInventoryItemByPath(process.cwd()); + d('inventory item: %o', item); + if (item) { + console.log('Tutorial has already been migrated!'); + return; + } + + const oldCollectionPath = path.join('.tuture', 'collection.json'); + const oldCollection: CollectionV1 = fs.readJSONSync(oldCollectionPath); + console.log(`legacy collection read from ${oldCollectionPath}`); + + const articleProms = oldCollection.articles.map(async (article) => { + const steps = oldCollection.steps.filter( + (step) => step.articleId === article.id, + ); + if (steps.length === 0) { + return; + } + let nodes = steps.flatMap((step) => convertStep(step)); + nodes = await Promise.all( + nodes.map(async (node) => { + if (node.type !== 'diff_block') { + return node; + } + const { commit, file } = node.attrs!; + if (await isBinaryFile(file)) { + return node; + } + + const diffFile = (await readDiff(commit)).filter( + (df) => df.to! === file, + )[0]; + const code = diffFile.deleted + ? '' + : (await readFileAtCommit(commit, file)) || ''; + const originalCode = diffFile.new + ? '' + : (await readFileAtCommit(`${commit}~1`, file)) || ''; -// for (let i = 0; i < collection.steps.length; i++) { -// const stepV1 = collection.steps[i]; -// const stepMeta = { -// id: stepV1.id, -// commit: stepV1.commit, -// }; -// if (stepV1.articleId) { -// for (let article of collectionV2.articles) { -// if (article.id === stepV1.articleId) { -// article.steps.push(stepMeta); -// } -// } -// } else { -// collectionV2.unassignedSteps.push(stepMeta); -// } + // Skip files with too lengthy diff + if (code.length > 10000 || originalCode.length > 10000) { + return node; + } -// const stepAttrs = { -// id: stepV1.id, -// name: getStepTitle(stepV1), -// articleId: stepV1.articleId || '', -// commit: stepV1.commit, -// order: i, -// }; -// stepDocs[stepV1.id] = { -// type: 'doc', -// attrs: stepAttrs, -// content: [ -// { type: 'step_start', attrs: { commit: stepV1.commit } }, -// ...stepV1.children.flatMap((node, index) => { -// if (index === 0) { -// const title = node as StepTitle; -// return newStepTitle(convertInlineNodes(title.children), stepAttrs); -// } else if (index === 1 || index === stepV1.children.length - 1) { -// return { -// type: 'explain', -// attrs: { -// fixed: true, -// level: 'step', -// pos: index === 1 ? 'pre' : 'post', -// commit: stepV1.commit, -// }, -// content: (node as Explain).children.map((block) => -// convertBlock(block as Element), -// ), -// }; -// } else { -// return convertFile(node as File); -// } -// }), -// { type: 'step_end', attrs: { commit: stepV1.commit } }, -// ], -// }; -// } + return { + type: 'diff_block', + attrs: { ...node.attrs, code, originalCode }, + }; + }), + ); + const doc = { + type: 'doc', + content: nodes, + attrs: { id: article.id }, + }; + if (options.dryRun) { + console.log('saving doc:', JSON.stringify(doc, null, 2)); + } else { + await saveDoc(doc); + } + }); + await Promise.all(articleProms); -// delete collectionV2.steps; + const newCollection: Collection = pick(oldCollection, [ + 'name', + 'id', + 'created', + 'articles', + 'version', + ]); + newCollection.version = 'v2'; -// return [collectionV2 as CollectionV2, stepDocs]; -// } + if (options.dryRun) { + console.log('new collection:', JSON.stringify(newCollection, null, 2)); + } else { + saveToInventory(process.cwd(), newCollection); + saveCollection(newCollection); + console.log('saved collection to inventory.'); + } +} diff --git a/packages/migrator/tsconfig.json b/packages/migrator/tsconfig.json new file mode 100644 index 00000000..c692db9f --- /dev/null +++ b/packages/migrator/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "importHelpers": true, + "module": "ES2015", + "outDir": "dist", + "rootDir": "src", + "strict": false, + "skipLibCheck": true, + "typeRoots": ["node_modules/@types", "../../node_modules/@types"] + }, + "include": ["src/**/*"] +} diff --git a/yarn.lock b/yarn.lock index cad41ad2..c26e0fbf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7097,21 +7097,26 @@ diff-sequences@^24.9.0: resolved "https://registry.nlark.com/diff-sequences/download/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" integrity sha1-VxXWJE4qpl9Iu6C8ly2wsLEelbU= -diff2html@^3.4.5: - version "3.4.15" - resolved "https://registry.yarnpkg.com/diff2html/-/diff2html-3.4.15.tgz#9cba93d7a8d05104963a0e36e2e4aaca6505ce05" - integrity sha512-DNzGoknNE1lIPJWkIYCszIe8PxXHrHl939WQX+Rzr8Q5l3ex8VyJjZCGKwzfMN6jiSyli7hNHyoApnz6prfZ3Q== +diff2html@^3.3.1: + version "3.4.16" + resolved "https://registry.yarnpkg.com/diff2html/-/diff2html-3.4.16.tgz#3d27e88594fa0e1ab954cc11e90895f9fa7b002d" + integrity sha512-KfkvEoZTJertjoGPYFLn8n0yRdvzJcHvFJpJwbIxUlHU9x6qqhRZEM+TlgtU09jdLqRZAQyWFoxPiP6HeT2IYA== dependencies: diff "5.0.0" hogan.js "3.0.2" optionalDependencies: highlight.js "11.2.0" -diff@5.0.0, diff@^5.0.0: +diff@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +diff@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + diff@^4.0.1: version "4.0.2" resolved "https://registry.nlark.com/diff/download/diff-4.0.2.tgz?cache=0&sync_timestamp=1624608104914&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdiff%2Fdownload%2Fdiff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" @@ -9407,11 +9412,16 @@ highlight.js@11.2.0: resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.2.0.tgz#a7e3b8c1fdc4f0538b93b2dc2ddd53a40c6ab0f0" integrity sha512-JOySjtOEcyG8s4MLR2MNbLUyaXqUunmSnL2kdV/KuGJOmHZuAR5xC54Ko7goAXBWNhf09Vy3B+U7vR62UZ/0iw== -highlight.js@^10.5.0, highlight.js@^10.7.1, highlight.js@~10.7.0: +highlight.js@^10.7.1, highlight.js@~10.7.0: version "10.7.3" resolved "https://registry.npmmirror.com/highlight.js/download/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" integrity sha1-aXJy45kTVuQMPKxWanTu9oF1ZTE= +highlight.js@^9.18.5: + version "9.18.5" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.5.tgz#d18a359867f378c138d6819edfc2a8acd5f29825" + integrity sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA== + hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.nlark.com/hmac-drbg/download/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -10549,6 +10559,11 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: resolved "https://registry.nlark.com/isarray/download/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= +isbinaryfile@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-5.0.0.tgz#034b7e54989dab8986598cbcea41f66663c65234" + integrity sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.nlark.com/isexe/download/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -14579,20 +14594,13 @@ prosemirror-markdown@1.5.1: markdown-it "^10.0.0" prosemirror-model "^1.0.0" -prosemirror-model@1.14.3, prosemirror-model@^1.0.0, prosemirror-model@^1.1.0, prosemirror-model@^1.13.1, prosemirror-model@^1.14.3, prosemirror-model@^1.8.1: +prosemirror-model@1.14.3, prosemirror-model@^1.0.0, prosemirror-model@^1.1.0, prosemirror-model@^1.13.1, prosemirror-model@^1.14.3, prosemirror-model@^1.2.0, prosemirror-model@^1.8.1: version "1.14.3" resolved "https://registry.nlark.com/prosemirror-model/download/prosemirror-model-1.14.3.tgz#a9c250d3c4023ddf10ecb41a0a7a130e9741d37e" integrity sha1-qcJQ08QCPd8Q7LQaCnoTDpdB034= dependencies: orderedmap "^1.1.0" -prosemirror-model@^1.2.0: - version "1.16.1" - resolved "http://bnpm.byted.org/prosemirror-model/-/prosemirror-model-1.16.1.tgz#fb388270bc9609b66298d6a7e15d0cc1d6c61253" - integrity sha512-r1/w0HDU40TtkXp0DyKBnFPYwd8FSlUSJmGCGFv4DeynfeSlyQF2FD0RQbVEMOe6P3PpUSXM6LZBV7W/YNZ4mA== - dependencies: - orderedmap "^1.1.0" - prosemirror-schema-basic@^1.1.2: version "1.1.2" resolved "http://bnpm.byted.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.1.2.tgz#4bde5c339c845e0d08ec8fe473064e372ca51ae3" @@ -17868,16 +17876,6 @@ uuid@^3.0.0, uuid@^3.0.1, uuid@^3.3.2, uuid@^3.4.0: resolved "https://registry.nlark.com/uuid/download/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4= -v-code-diff@^0.3.8: - version "0.3.8" - resolved "https://registry.yarnpkg.com/v-code-diff/-/v-code-diff-0.3.8.tgz#8d8c584ca54585f6d4f6043cfdcc888510504dd2" - integrity sha512-rE1RvZt40lFXqtoUPeOnE3ygxLzgjCddG+/4afsUw463v6jQcGqy8gsbt/8AkLr+ieAzWhlmRXEbTfvktrWjGw== - dependencies: - diff "^5.0.0" - diff2html "^3.4.5" - highlight.js "^10.5.0" - vue-demi latest - v8-compile-cache@^2.0.3, v8-compile-cache@^2.3.0: version "2.3.0" resolved "https://registry.nlark.com/v8-compile-cache/download/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" @@ -18044,6 +18042,16 @@ vue-cli-plugin-vite@~1.0.0-rc.3: vite-plugin-vue-cli "1.0.0" vite-plugin-vue2 "1.5.1" +vue-code-diff@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/vue-code-diff/-/vue-code-diff-1.2.0.tgz#e38013307bab9296cc3512b2e7c9afed7890ae4a" + integrity sha512-kgSCl1Cr3I0u0z5DyJFbqQ1Hk7s9uBl7bfGwIn1X8f1xGmWdu4eRqfeOLTS0ut06VfGslaprXdaSvgn7YGDh0Q== + dependencies: + diff "^3.5.0" + diff2html "^3.3.1" + highlight.js "^9.18.5" + vue "^2.6.12" + vue-demi@*: version "0.11.4" resolved "https://registry.nlark.com/vue-demi/download/vue-demi-0.11.4.tgz#6101992fe4724cf5634018a16e953f3052e94e2a" @@ -18054,11 +18062,6 @@ vue-demi@^0.7.4: resolved "https://registry.nlark.com/vue-demi/download/vue-demi-0.7.5.tgz#88dee7492fc99a0f911ff03fc02c658fa2a79af8" integrity sha1-iN7nSS/Jmg+RH/A/wCxlj6Knmvg= -vue-demi@latest: - version "0.12.1" - resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.12.1.tgz#f7e18efbecffd11ab069d1472d7a06e319b4174c" - integrity sha512-QL3ny+wX8c6Xm1/EZylbgzdoDolye+VpCXRhI2hug9dJTP3OUJ3lmiKN3CsVV3mOJKwFi0nsstbgob0vG7aoIw== - vue-eslint-parser@^7.0.0: version "7.11.0" resolved "https://registry.npmmirror.com/vue-eslint-parser/download/vue-eslint-parser-7.11.0.tgz?cache=0&sync_timestamp=1634602895439&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fvue-eslint-parser%2Fdownload%2Fvue-eslint-parser-7.11.0.tgz#214b5dea961007fcffb2ee65b8912307628d0daf" @@ -18128,7 +18131,7 @@ vue-template-es2015-compiler@^1.9.0, vue-template-es2015-compiler@^1.9.1: resolved "https://registry.nlark.com/vue-template-es2015-compiler/download/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" integrity sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU= -vue@^2.6.11: +vue@^2.6.11, vue@^2.6.12: version "2.6.14" resolved "https://registry.npmmirror.com/vue/download/vue-2.6.14.tgz?cache=0&sync_timestamp=1633712767060&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fvue%2Fdownload%2Fvue-2.6.14.tgz#e51aa5250250d569a3fbad3a8a5a687d6036e235" integrity sha1-5RqlJQJQ1Wmj+606ilpofWA24jU=