mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-23 03:22:19 +03:00
Show model diff (#562)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
9d6e2f2076
commit
78f4916b6d
@ -110,7 +110,6 @@ specifiers:
|
|||||||
'@types/express-fileupload': ^1.1.7
|
'@types/express-fileupload': ^1.1.7
|
||||||
'@types/faker': ~5.5.9
|
'@types/faker': ~5.5.9
|
||||||
'@types/heft-jest': ^1.0.2
|
'@types/heft-jest': ^1.0.2
|
||||||
'@types/jpeg-js': ~0.3.7
|
|
||||||
'@types/koa': ^2.13.4
|
'@types/koa': ^2.13.4
|
||||||
'@types/koa-bodyparser': ^4.3.3
|
'@types/koa-bodyparser': ^4.3.3
|
||||||
'@types/koa-router': ^7.4.4
|
'@types/koa-router': ^7.4.4
|
||||||
@ -136,6 +135,7 @@ specifiers:
|
|||||||
express: ^4.17.1
|
express: ^4.17.1
|
||||||
express-fileupload: ^1.2.1
|
express-fileupload: ^1.2.1
|
||||||
faker: ~5.5.3
|
faker: ~5.5.3
|
||||||
|
fast-equals: ^2.0.3
|
||||||
file-loader: ^6.2.0
|
file-loader: ^6.2.0
|
||||||
filesize: ^8.0.3
|
filesize: ^8.0.3
|
||||||
intl-messageformat: ^9.7.1
|
intl-messageformat: ^9.7.1
|
||||||
@ -279,7 +279,6 @@ dependencies:
|
|||||||
'@types/express-fileupload': 1.1.7
|
'@types/express-fileupload': 1.1.7
|
||||||
'@types/faker': 5.5.9
|
'@types/faker': 5.5.9
|
||||||
'@types/heft-jest': 1.0.2
|
'@types/heft-jest': 1.0.2
|
||||||
'@types/jpeg-js': 0.3.7
|
|
||||||
'@types/koa': 2.13.4
|
'@types/koa': 2.13.4
|
||||||
'@types/koa-bodyparser': 4.3.3
|
'@types/koa-bodyparser': 4.3.3
|
||||||
'@types/koa-router': 7.4.4
|
'@types/koa-router': 7.4.4
|
||||||
@ -305,6 +304,7 @@ dependencies:
|
|||||||
express: 4.17.1
|
express: 4.17.1
|
||||||
express-fileupload: 1.2.1
|
express-fileupload: 1.2.1
|
||||||
faker: 5.5.3
|
faker: 5.5.3
|
||||||
|
fast-equals: 2.0.4
|
||||||
file-loader: 6.2.0_webpack@5.57.1
|
file-loader: 6.2.0_webpack@5.57.1
|
||||||
filesize: 8.0.3
|
filesize: 8.0.3
|
||||||
intl-messageformat: 9.7.1
|
intl-messageformat: 9.7.1
|
||||||
@ -4502,6 +4502,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/fast-equals/2.0.4:
|
||||||
|
resolution: {integrity: sha512-caj/ZmjHljPrZtbzJ3kfH5ia/k4mTJe/qSiXAGzxZWRZgsgDV0cvNaQULqUX8t0/JVlzzEdYOwCN5DmzTxoD4w==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/fast-glob/3.2.7:
|
/fast-glob/3.2.7:
|
||||||
resolution: {integrity: sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==}
|
resolution: {integrity: sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -9134,37 +9138,6 @@ packages:
|
|||||||
webpack: 5.57.1_webpack-cli@4.8.0
|
webpack: 5.57.1_webpack-cli@4.8.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/ts-node/10.2.1_8304ecd715830f7c190b4d1dea90b100:
|
|
||||||
resolution: {integrity: sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==}
|
|
||||||
engines: {node: '>=12.0.0'}
|
|
||||||
hasBin: true
|
|
||||||
peerDependencies:
|
|
||||||
'@swc/core': '>=1.2.50'
|
|
||||||
'@swc/wasm': '>=1.2.50'
|
|
||||||
'@types/node': '*'
|
|
||||||
typescript: '>=2.7'
|
|
||||||
peerDependenciesMeta:
|
|
||||||
'@swc/core':
|
|
||||||
optional: true
|
|
||||||
'@swc/wasm':
|
|
||||||
optional: true
|
|
||||||
dependencies:
|
|
||||||
'@cspotcode/source-map-support': 0.6.1
|
|
||||||
'@tsconfig/node10': 1.0.8
|
|
||||||
'@tsconfig/node12': 1.0.9
|
|
||||||
'@tsconfig/node14': 1.0.1
|
|
||||||
'@tsconfig/node16': 1.0.2
|
|
||||||
'@types/node': 16.10.3
|
|
||||||
acorn: 8.5.0
|
|
||||||
acorn-walk: 8.2.0
|
|
||||||
arg: 4.1.3
|
|
||||||
create-require: 1.1.1
|
|
||||||
diff: 4.0.2
|
|
||||||
make-error: 1.3.6
|
|
||||||
typescript: 4.4.3
|
|
||||||
yn: 3.1.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/ts-node/10.2.1_c2efd757c6d07d33b05f123839e1b1a4:
|
/ts-node/10.2.1_c2efd757c6d07d33b05f123839e1b1a4:
|
||||||
resolution: {integrity: sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==}
|
resolution: {integrity: sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==}
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: '>=12.0.0'}
|
||||||
@ -10052,7 +10025,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@rushstack/heft': 0.41.1
|
'@rushstack/heft': 0.41.1
|
||||||
'@types/heft-jest': 1.0.2
|
'@types/heft-jest': 1.0.2
|
||||||
'@types/node': 16.10.3
|
'@types/node': 16.11.12
|
||||||
'@typescript-eslint/eslint-plugin': 5.4.0_87dbf04088b125598d0271706532eaf3
|
'@typescript-eslint/eslint-plugin': 5.4.0_87dbf04088b125598d0271706532eaf3
|
||||||
'@typescript-eslint/parser': 5.4.0_eslint@7.32.0+typescript@4.4.3
|
'@typescript-eslint/parser': 5.4.0_eslint@7.32.0+typescript@4.4.3
|
||||||
eslint: 7.32.0
|
eslint: 7.32.0
|
||||||
@ -10292,7 +10265,7 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/contact-resources.tgz_476f694f64637160ae71e12ff57815b9:
|
file:projects/contact-resources.tgz_476f694f64637160ae71e12ff57815b9:
|
||||||
resolution: {integrity: sha512-5aEH1fHFn/BbM8mJcS2gPNW9koEkNtX8P3uC+iEID5xQPUuJV5rsfba17/Iq2bYj5DeLkyvNO5wAwoECwVCvRA==, tarball: file:projects/contact-resources.tgz}
|
resolution: {integrity: sha512-4SUPVPcAFE83qvwymkwI7i+z0ioEgAmM+H08vsjXRkEeD0vOlRLD3tEBX+0W49mL93EZG0TUEPP8zPcl7wiiAg==, tarball: file:projects/contact-resources.tgz}
|
||||||
id: file:projects/contact-resources.tgz
|
id: file:projects/contact-resources.tgz
|
||||||
name: '@rush-temp/contact-resources'
|
name: '@rush-temp/contact-resources'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
@ -10353,7 +10326,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@rushstack/heft': 0.41.1
|
'@rushstack/heft': 0.41.1
|
||||||
'@types/heft-jest': 1.0.2
|
'@types/heft-jest': 1.0.2
|
||||||
'@types/node': 16.10.3
|
'@types/node': 16.11.12
|
||||||
'@types/ws': 7.4.7
|
'@types/ws': 7.4.7
|
||||||
'@typescript-eslint/eslint-plugin': 5.4.0_87dbf04088b125598d0271706532eaf3
|
'@typescript-eslint/eslint-plugin': 5.4.0_87dbf04088b125598d0271706532eaf3
|
||||||
'@typescript-eslint/parser': 5.4.0_eslint@7.32.0+typescript@4.4.3
|
'@typescript-eslint/parser': 5.4.0_eslint@7.32.0+typescript@4.4.3
|
||||||
@ -10592,7 +10565,7 @@ packages:
|
|||||||
'@types/express-fileupload': 1.1.7
|
'@types/express-fileupload': 1.1.7
|
||||||
'@types/heft-jest': 1.0.2
|
'@types/heft-jest': 1.0.2
|
||||||
'@types/minio': 7.0.10
|
'@types/minio': 7.0.10
|
||||||
'@types/node': 16.10.3
|
'@types/node': 16.11.12
|
||||||
'@types/uuid': 8.3.1
|
'@types/uuid': 8.3.1
|
||||||
'@typescript-eslint/eslint-plugin': 5.4.0_87dbf04088b125598d0271706532eaf3
|
'@typescript-eslint/eslint-plugin': 5.4.0_87dbf04088b125598d0271706532eaf3
|
||||||
'@typescript-eslint/parser': 5.4.0_eslint@7.32.0+typescript@4.4.3
|
'@typescript-eslint/parser': 5.4.0_eslint@7.32.0+typescript@4.4.3
|
||||||
@ -10615,7 +10588,7 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/generator.tgz:
|
file:projects/generator.tgz:
|
||||||
resolution: {integrity: sha512-n46hjl25xFASqC9A+jFGBgQNshHS/86Q4a07NdpR7jn7rdcpHWn+3mpndvyplwyOVfdhbbP/AGmasHJhWtEsxg==, tarball: file:projects/generator.tgz}
|
resolution: {integrity: sha512-vufLNo3Nd5EZMfZnpDyCgzmtiOxuuOCfdcez1VUXR8EJV+07YGGLKpYcUsJ+hp7vrOMe5/iW0gGun4p42SEL9Q==, tarball: file:projects/generator.tgz}
|
||||||
name: '@rush-temp/generator'
|
name: '@rush-temp/generator'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -10804,7 +10777,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@rushstack/heft': 0.41.1
|
'@rushstack/heft': 0.41.1
|
||||||
'@types/heft-jest': 1.0.2
|
'@types/heft-jest': 1.0.2
|
||||||
'@types/node': 16.10.3
|
'@types/node': 16.11.12
|
||||||
'@typescript-eslint/eslint-plugin': 5.4.0_87dbf04088b125598d0271706532eaf3
|
'@typescript-eslint/eslint-plugin': 5.4.0_87dbf04088b125598d0271706532eaf3
|
||||||
'@typescript-eslint/parser': 5.4.0_eslint@7.32.0+typescript@4.4.3
|
'@typescript-eslint/parser': 5.4.0_eslint@7.32.0+typescript@4.4.3
|
||||||
eslint: 7.32.0
|
eslint: 7.32.0
|
||||||
@ -10813,7 +10786,7 @@ packages:
|
|||||||
eslint-plugin-node: 11.1.0_eslint@7.32.0
|
eslint-plugin-node: 11.1.0_eslint@7.32.0
|
||||||
eslint-plugin-promise: 5.1.1_eslint@7.32.0
|
eslint-plugin-promise: 5.1.1_eslint@7.32.0
|
||||||
prettier: 2.4.1
|
prettier: 2.4.1
|
||||||
ts-node: 10.2.1_8304ecd715830f7c190b4d1dea90b100
|
ts-node: 10.2.1_c2efd757c6d07d33b05f123839e1b1a4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@swc/core'
|
- '@swc/core'
|
||||||
- '@swc/wasm'
|
- '@swc/wasm'
|
||||||
@ -11093,7 +11066,7 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/model-task.tgz_typescript@4.4.3:
|
file:projects/model-task.tgz_typescript@4.4.3:
|
||||||
resolution: {integrity: sha512-WzEdSzLqN2Fj+TXMdy9pLEsBPMjqlz6eT2nQLwwQgRyPcT6S6qAbEgqTiPZmk10vW2/qA5X6DDAf82yC/8zVJA==, tarball: file:projects/model-task.tgz}
|
resolution: {integrity: sha512-8CPB0TE05gwOb4WKefT6zaL/jIgiwfqBM46riENkiR6TJgy1oiACqoS1p7YA+XzZJSy0eAaR3308lGohMNNGzQ==, tarball: file:projects/model-task.tgz}
|
||||||
id: file:projects/model-task.tgz
|
id: file:projects/model-task.tgz
|
||||||
name: '@rush-temp/model-task'
|
name: '@rush-temp/model-task'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
@ -11156,7 +11129,7 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/model-workbench.tgz_typescript@4.4.3:
|
file:projects/model-workbench.tgz_typescript@4.4.3:
|
||||||
resolution: {integrity: sha512-BBgFzmrL/3h+HI8NnMkFXjL84t27f8yOF87D4LdeSHlF/sUC20IVdLzwk/6wn/6ayGlPWbQF/54Y5V2X4NtsJQ==, tarball: file:projects/model-workbench.tgz}
|
resolution: {integrity: sha512-iQ3Un4SlIh2PhEenOxWjXpRfWE3TrSRTtnBI3j2ar5kllG2vB58LLny9urWYpxVI2yRqyrquowtQBj/ZO+vTAA==, tarball: file:projects/model-workbench.tgz}
|
||||||
id: file:projects/model-workbench.tgz
|
id: file:projects/model-workbench.tgz
|
||||||
name: '@rush-temp/model-workbench'
|
name: '@rush-temp/model-workbench'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
@ -11440,7 +11413,7 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/recruit-resources.tgz_476f694f64637160ae71e12ff57815b9:
|
file:projects/recruit-resources.tgz_476f694f64637160ae71e12ff57815b9:
|
||||||
resolution: {integrity: sha512-V7iAy6fX/2McQ0gZjvzHL4qA4ETElxXHEBh6ZnXBuYE8ht0sqLIXSGdgJstxyR++MWTe5ZM7l4GS/re3zYGdnw==, tarball: file:projects/recruit-resources.tgz}
|
resolution: {integrity: sha512-+AEmp4tNJEHvQatbY5fN1niGYpaIyWMPXbo0QRhUDELdEkm0nhevUfw2Cf44Yj0DroXL+S0YgnXcEI7AtV2QOQ==, tarball: file:projects/recruit-resources.tgz}
|
||||||
id: file:projects/recruit-resources.tgz
|
id: file:projects/recruit-resources.tgz
|
||||||
name: '@rush-temp/recruit-resources'
|
name: '@rush-temp/recruit-resources'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
@ -11477,7 +11450,7 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/recruit.tgz:
|
file:projects/recruit.tgz:
|
||||||
resolution: {integrity: sha512-tYzfXei8i5vr9puawxtiFBtY1xE6jzFUpEykNwvoGC7VfkrCQ+HvFqfEIF0sD24tGVxSogQ9u+LkEu+ePl32Jw==, tarball: file:projects/recruit.tgz}
|
resolution: {integrity: sha512-nqrkga8ccMV8sqQ6O4ta9qEdvHkgEChdViELXUXViGldrhz6qi9UAE1aDuVYHgEFRX+eC+OACSME0YpHbibylw==, tarball: file:projects/recruit.tgz}
|
||||||
name: '@rush-temp/recruit'
|
name: '@rush-temp/recruit'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -11700,7 +11673,7 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/setting-resources.tgz_476f694f64637160ae71e12ff57815b9:
|
file:projects/setting-resources.tgz_476f694f64637160ae71e12ff57815b9:
|
||||||
resolution: {integrity: sha512-I85L1AQz7schJl8/PKyTjw+/svzxhQ9xnlHSQQnMffB1cSQ265P1v7Zt+NERnsqLGD/l3c59nqXep8JrSDf/Tw==, tarball: file:projects/setting-resources.tgz}
|
resolution: {integrity: sha512-Ybi5GrbbI/5SMBIe5W9Ub8cwA3wIKPCj98lSJ+Z9YCokpjYn2dGhRJ5LeBKBPu8LDWPfxlrU2Yi17YcHu0xufw==, tarball: file:projects/setting-resources.tgz}
|
||||||
id: file:projects/setting-resources.tgz
|
id: file:projects/setting-resources.tgz
|
||||||
name: '@rush-temp/setting-resources'
|
name: '@rush-temp/setting-resources'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
@ -11822,7 +11795,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@rushstack/heft': 0.41.1
|
'@rushstack/heft': 0.41.1
|
||||||
'@types/heft-jest': 1.0.2
|
'@types/heft-jest': 1.0.2
|
||||||
'@types/node': 16.10.3
|
'@types/node': 16.11.12
|
||||||
'@typescript-eslint/eslint-plugin': 5.4.0_87dbf04088b125598d0271706532eaf3
|
'@typescript-eslint/eslint-plugin': 5.4.0_87dbf04088b125598d0271706532eaf3
|
||||||
'@typescript-eslint/parser': 5.4.0_eslint@7.32.0+typescript@4.4.3
|
'@typescript-eslint/parser': 5.4.0_eslint@7.32.0+typescript@4.4.3
|
||||||
eslint: 7.32.0
|
eslint: 7.32.0
|
||||||
@ -11968,7 +11941,7 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/tool.tgz:
|
file:projects/tool.tgz:
|
||||||
resolution: {integrity: sha512-TNUt6NCYHOiiDDPuhdNtvqtdvWb8N2xFRQAu+Ku3QyKgKH4dMpzV2WNSDnURNSUtN3mCE2OUyiGOLej8B9lbXA==, tarball: file:projects/tool.tgz}
|
resolution: {integrity: sha512-Ymz2K4mDdajWonLpamGYn7fTN7OqKKjW6SWBB0iZzBxb9BtZOpIY3IVaV9Bm3PYDpm7WOgJ82EjwZbO9+nczFQ==, tarball: file:projects/tool.tgz}
|
||||||
name: '@rush-temp/tool'
|
name: '@rush-temp/tool'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -11987,6 +11960,7 @@ packages:
|
|||||||
eslint-plugin-import: 2.25.3_eslint@7.32.0
|
eslint-plugin-import: 2.25.3_eslint@7.32.0
|
||||||
eslint-plugin-node: 11.1.0_eslint@7.32.0
|
eslint-plugin-node: 11.1.0_eslint@7.32.0
|
||||||
eslint-plugin-promise: 5.1.1_eslint@7.32.0
|
eslint-plugin-promise: 5.1.1_eslint@7.32.0
|
||||||
|
fast-equals: 2.0.4
|
||||||
jwt-simple: 0.5.6
|
jwt-simple: 0.5.6
|
||||||
minio: 7.0.19
|
minio: 7.0.19
|
||||||
mongodb: 4.1.3
|
mongodb: 4.1.3
|
||||||
@ -12105,7 +12079,7 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
file:projects/workbench-resources.tgz_476f694f64637160ae71e12ff57815b9:
|
file:projects/workbench-resources.tgz_476f694f64637160ae71e12ff57815b9:
|
||||||
resolution: {integrity: sha512-HKzFdAy5VwIlv4gJv9iN8FjsuvYCp98kvZ0uTAQtK0aavp5lve4rKPGehK+WHUmm7H/IiPD8yXQWEPherq3eZQ==, tarball: file:projects/workbench-resources.tgz}
|
resolution: {integrity: sha512-yWHOAPBVj1y9VbkYHOaANIkCbBfQOkKKvxj2dEFK3It4WUN/jxZSPqrmW1/ZNkENZVaWzRL1VY6uGhJJ5dwgFQ==, tarball: file:projects/workbench-resources.tgz}
|
||||||
id: file:projects/workbench-resources.tgz
|
id: file:projects/workbench-resources.tgz
|
||||||
name: '@rush-temp/workbench-resources'
|
name: '@rush-temp/workbench-resources'
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
"ws": "^8.2.0",
|
"ws": "^8.2.0",
|
||||||
"@anticrm/client": "~0.6.1",
|
"@anticrm/client": "~0.6.1",
|
||||||
"@anticrm/platform": "~0.6.5",
|
"@anticrm/platform": "~0.6.5",
|
||||||
"@anticrm/model": "~0.6.0"
|
"@anticrm/model": "~0.6.0",
|
||||||
|
"fast-equals": "^2.0.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ import { Client } from 'minio'
|
|||||||
import { Db, MongoClient } from 'mongodb'
|
import { Db, MongoClient } from 'mongodb'
|
||||||
import { connect } from './connect'
|
import { connect } from './connect'
|
||||||
import { clearTelegramHistory } from './telegram'
|
import { clearTelegramHistory } from './telegram'
|
||||||
import { dumpWorkspace, initWorkspace, restoreWorkspace, upgradeWorkspace } from './workspace'
|
import { diffWorkspace, dumpWorkspace, initWorkspace, restoreWorkspace, upgradeWorkspace } from './workspace'
|
||||||
|
|
||||||
const mongodbUri = process.env.MONGO_URL
|
const mongodbUri = process.env.MONGO_URL
|
||||||
if (mongodbUri === undefined) {
|
if (mongodbUri === undefined) {
|
||||||
@ -195,6 +195,13 @@ program
|
|||||||
return await restoreWorkspace(mongodbUri, workspace, dirName, minio)
|
return await restoreWorkspace(mongodbUri, workspace, dirName, minio)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('diff-workspace <workspace>')
|
||||||
|
.description('restore workspace transactions and minio resources from previous dump.')
|
||||||
|
.action(async (workspace, cmd) => {
|
||||||
|
return await diffWorkspace(mongodbUri, workspace)
|
||||||
|
})
|
||||||
|
|
||||||
program
|
program
|
||||||
.command('clear-telegram-history')
|
.command('clear-telegram-history')
|
||||||
.description('clear telegram history')
|
.description('clear telegram history')
|
||||||
|
157
dev/tool/src/mdiff.ts
Normal file
157
dev/tool/src/mdiff.ts
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
import core, { Attribute, Data, Doc, DocumentUpdate, Hierarchy, ModelDb, Ref, Tx, Type } from '@anticrm/core'
|
||||||
|
import { deepEqual } from 'fast-equals'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export async function buildModel (existingTxes: Tx[]): Promise<{ hierarchy: Hierarchy, model: ModelDb, dropTx: Tx[] }> {
|
||||||
|
existingTxes = existingTxes.filter((tx) => tx.modifiedBy === core.account.System)
|
||||||
|
const dropTx: Tx[] = []
|
||||||
|
const hierarchy = new Hierarchy()
|
||||||
|
const model = new ModelDb(hierarchy)
|
||||||
|
// Construct existing model
|
||||||
|
existingTxes.forEach(hierarchy.tx.bind(hierarchy))
|
||||||
|
for (const tx of existingTxes) {
|
||||||
|
await applyTx(model, tx, dropTx)
|
||||||
|
}
|
||||||
|
return { hierarchy, model, dropTx }
|
||||||
|
}
|
||||||
|
|
||||||
|
async function applyTx (model: ModelDb, tx: Tx, dropTx: Tx[]): Promise<void> {
|
||||||
|
try {
|
||||||
|
await model.tx(tx)
|
||||||
|
} catch (err: any) {
|
||||||
|
dropTx.push(tx)
|
||||||
|
console.info('Found issue during processing of tx. Transaction', tx, 'is dropped...')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toUndef (value: any): any {
|
||||||
|
return value === null ? undefined : value
|
||||||
|
}
|
||||||
|
|
||||||
|
function diffAttributes (doc: Data<Doc>, newDoc: Data<Doc>): DocumentUpdate<Doc> {
|
||||||
|
const result: DocumentUpdate<any> = {}
|
||||||
|
const allDocuments = new Map(Object.entries(doc))
|
||||||
|
const newDocuments = new Map(Object.entries(newDoc))
|
||||||
|
|
||||||
|
for (const [key, value] of allDocuments) {
|
||||||
|
const newValue = toUndef(newDocuments.get(key))
|
||||||
|
if (!deepEqual(newValue, toUndef(value))) {
|
||||||
|
// update is required, since values are different
|
||||||
|
result[key] = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const [key, value] of newDocuments) {
|
||||||
|
const oldValue = toUndef(allDocuments.get(key))
|
||||||
|
if (oldValue === undefined && value !== undefined) {
|
||||||
|
// Update with new value.
|
||||||
|
result[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a set of transactions to upgrade from one model to another.
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export async function generateModelDiff (existingTxes: Tx[], txes: Tx[]): Promise<{ diffTx: Op[], dropTx: Tx[] }> {
|
||||||
|
const { model, dropTx } = await buildModel(existingTxes)
|
||||||
|
const { model: newModel } = await buildModel(txes)
|
||||||
|
|
||||||
|
const diffTx = generateDocumentDiff(
|
||||||
|
await model.findAll(core.class.Doc, {}),
|
||||||
|
await newModel.findAll(core.class.Doc, {})
|
||||||
|
)
|
||||||
|
return { diffTx, dropTx }
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Op = Record<string, any>
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export function generateDocumentDiff (oldDocs: Doc[], newDocs: Doc[]): Op[] {
|
||||||
|
const diffTx: Op[] = []
|
||||||
|
|
||||||
|
const allDocuments = new Map(oldDocs.map((d) => [getId(d), d]))
|
||||||
|
const newDocuments = new Map(newDocs.map((d) => [getId(d), d]))
|
||||||
|
|
||||||
|
// Find same documents.
|
||||||
|
allDocuments.forEach(handleUpdateRemove(newDocuments, diffTx))
|
||||||
|
newDocuments.forEach(handleAdd(allDocuments, diffTx))
|
||||||
|
return diffTx
|
||||||
|
}
|
||||||
|
|
||||||
|
function getId (d: Doc): Ref<Doc> {
|
||||||
|
// We need to update Attribute IDS
|
||||||
|
if (d._class === core.class.Attribute) {
|
||||||
|
const attr = d as Attribute<Type<any>>
|
||||||
|
return (attr.attributeOf + '.' + attr.name) as Ref<Doc>
|
||||||
|
} else if (d._class === 'view:class:Viewlet' as Ref<Doc>) {
|
||||||
|
const cr = d as any
|
||||||
|
return ((cr.attachTo as string) + '.' + (cr.open as string)) as Ref<Doc>
|
||||||
|
} else if (d._class === 'workbench:class:Application' as Ref<Doc>) {
|
||||||
|
const cr = d as any
|
||||||
|
return ('workbench.app.' + (cr.label as string)) as Ref<Doc>
|
||||||
|
} else if (d._class === 'view:class:ActionTarget' as Ref<Doc>) {
|
||||||
|
const cr = d as any
|
||||||
|
return ((cr.target as string) + '.' + (cr.action as string)) as Ref<Doc>
|
||||||
|
} else if (d._class === 'server-core:class:Trigger' as Ref<Doc>) {
|
||||||
|
const cr = d as any
|
||||||
|
return ((cr.trigger as string)) as Ref<Doc>
|
||||||
|
}
|
||||||
|
return d._id
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleAdd (allDocuments: Map<Ref<Doc>, Doc>, newTxes: Op[]): (value: Doc, key: Ref<Doc>) => void {
|
||||||
|
return (doc, key) => {
|
||||||
|
if (!allDocuments.has(key)) {
|
||||||
|
// Add is required
|
||||||
|
const { _id, _class, modifiedBy, modifiedOn, space, ...data } = doc
|
||||||
|
const tx: Op = {
|
||||||
|
_class: 'create-doc',
|
||||||
|
objectId: _id,
|
||||||
|
objectClass: doc._class,
|
||||||
|
attributes: data
|
||||||
|
}
|
||||||
|
newTxes.push(tx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleUpdateRemove (newDocuments: Map<Ref<Doc>, Doc>, newTxes: Op[]): (value: Doc, key: Ref<Doc>) => void {
|
||||||
|
return (doc, key) => {
|
||||||
|
const newDoc = newDocuments.get(key)
|
||||||
|
if (newDoc !== undefined) {
|
||||||
|
// update is required.
|
||||||
|
const { _id, _class, modifiedBy, modifiedOn, space, ...data } = newDoc
|
||||||
|
const { _id: _0, _class: _1, modifiedBy: _2, modifiedOn: _3, space: _4, ...oldData } = doc
|
||||||
|
const operations = diffAttributes(oldData, data)
|
||||||
|
if (Object.keys(operations).length > 0) {
|
||||||
|
const tx: Op = {
|
||||||
|
_class: 'update-doc',
|
||||||
|
objectId: _id,
|
||||||
|
objectClass: _class,
|
||||||
|
operations
|
||||||
|
}
|
||||||
|
newTxes.push(tx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Delete is required
|
||||||
|
const { _id: oldId, _class: _1, modifiedBy: _2, modifiedOn: _3, space: _4, ...oldData } = doc
|
||||||
|
const tx: Op = {
|
||||||
|
_class: 'remove-doc',
|
||||||
|
objectId: oldId,
|
||||||
|
objectClass: doc._class,
|
||||||
|
data: oldData
|
||||||
|
}
|
||||||
|
newTxes.push(tx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function printDiff (diffTx: Op[]): void {
|
||||||
|
// Collect Classes.
|
||||||
|
console.log('Diff Transactions', JSON.stringify(diffTx, undefined, 2))
|
||||||
|
}
|
@ -24,6 +24,7 @@ import { Document, MongoClient } from 'mongodb'
|
|||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { connect } from './connect'
|
import { connect } from './connect'
|
||||||
import { MigrateClientImpl } from './upgrade'
|
import { MigrateClientImpl } from './upgrade'
|
||||||
|
import { generateModelDiff, printDiff } from './mdiff'
|
||||||
|
|
||||||
const txes = JSON.parse(JSON.stringify(builder.getTxes())) as Tx[]
|
const txes = JSON.parse(JSON.stringify(builder.getTxes())) as Tx[]
|
||||||
|
|
||||||
@ -245,3 +246,40 @@ export async function restoreWorkspace (mongoUrl: string, dbName: string, fileNa
|
|||||||
await client.close()
|
await client.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function diffWorkspace (mongoUrl: string, dbName: string): Promise<void> {
|
||||||
|
const client = new MongoClient(mongoUrl)
|
||||||
|
try {
|
||||||
|
await client.connect()
|
||||||
|
const db = client.db(dbName)
|
||||||
|
|
||||||
|
console.log('diffing transactions...')
|
||||||
|
|
||||||
|
const currentModel = await db.collection(DOMAIN_TX).find<Tx>({
|
||||||
|
objectSpace: core.space.Model,
|
||||||
|
modifiedBy: core.account.System,
|
||||||
|
objectClass: { $ne: contact.class.EmployeeAccount }
|
||||||
|
}).toArray()
|
||||||
|
|
||||||
|
const txes = builder.getTxes().filter(tx => {
|
||||||
|
return tx.objectSpace === core.space.Model &&
|
||||||
|
tx.modifiedBy === core.account.System &&
|
||||||
|
(tx as any).objectClass !== contact.class.EmployeeAccount
|
||||||
|
})
|
||||||
|
|
||||||
|
const { diffTx, dropTx } = await generateModelDiff(currentModel, txes)
|
||||||
|
if (diffTx.length > 0) {
|
||||||
|
console.log('DIFF Transactions:')
|
||||||
|
|
||||||
|
printDiff(diffTx)
|
||||||
|
}
|
||||||
|
if (dropTx.length > 0) {
|
||||||
|
console.log('Broken Transactions:')
|
||||||
|
for (const tx of dropTx) {
|
||||||
|
console.log(JSON.stringify(tx, undefined, 2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
await client.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user