mysqlsyncr 1.1.12 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +59 -0
  2. package/__tests__/acceptCurrent.test.js +117 -0
  3. package/__tests__/columnAttributes.test.js +101 -0
  4. package/__tests__/options.test.js +259 -0
  5. package/__tests__/parser.test.js +167 -166
  6. package/__tests__/parser2.test.js +155 -152
  7. package/__tests__/paths.test.js +21 -0
  8. package/__tests__/prompt.test.js +106 -0
  9. package/__tests__/sync.test.js +348 -0
  10. package/__tests__/templateDrift.test.js +72 -0
  11. package/__tests__/versions.test.js +138 -0
  12. package/dist/index.cjs +4059 -1733
  13. package/dist/index.js +4101 -1777
  14. package/package.json +66 -59
  15. package/rollup.config.js +2 -1
  16. package/src/DBStructureChecker.js +47 -0
  17. package/src/acceptCurrent.js +225 -0
  18. package/src/apply.js +254 -136
  19. package/src/cli.js +61 -34
  20. package/src/compare.js +106 -92
  21. package/src/differences.js +258 -212
  22. package/src/dump.js +63 -54
  23. package/src/getters.js +151 -139
  24. package/src/index.js +223 -169
  25. package/src/loggers.js +156 -139
  26. package/src/normalizers.js +28 -6
  27. package/src/options.js +133 -0
  28. package/src/parsers.js +82 -36
  29. package/src/paths.js +41 -0
  30. package/src/prompt.js +109 -0
  31. package/src/rebuild.js +106 -0
  32. package/src/rows.js +46 -0
  33. package/src/socketServer.js +106 -24
  34. package/src/templateDrift.js +93 -0
  35. package/src/versions.js +112 -0
  36. package/ui/README.md +55 -40
  37. package/ui/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuYjalmUiAw-k1h7X_-h.woff +0 -0
  38. package/ui/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuZtalmUiAw-B7du-70m.woff +0 -0
  39. package/ui/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuaabVmUiAw-CoAZ_DKt.woff +0 -0
  40. package/ui/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWub2bVmUiAw-D0406B4n.woff +0 -0
  41. package/ui/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbFmUiAw-CnAg2DeQ.woff +0 -0
  42. package/ui/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVmUiAw-BG9VWE5v.woff +0 -0
  43. package/ui/dist/spa/assets/MainLayout-DLH1Kfg-.js +1 -0
  44. package/ui/dist/spa/assets/axios-2hQ_j_Tz.js +1 -0
  45. package/ui/dist/spa/assets/flUhRq6tzZclQEJ-Vdg-IuiaDsNa-OUIwM9U8.woff +0 -0
  46. package/ui/dist/spa/assets/index-Cqrg985P.js +23 -0
  47. package/ui/dist/spa/assets/index-pOWtXlXQ.css +1 -0
  48. package/ui/dist/spa/index.html +2 -2
  49. package/ui/package.json +43 -42
  50. package/ui/src/components/DefinitionDiff.vue +169 -0
  51. package/ui/src/pages/MainComponent.vue +704 -78
  52. package/ui/dist/spa/assets/KFOkCnqEu92Fr1MmgVxIIzQ-Y2mpUUkw.woff +0 -0
  53. package/ui/dist/spa/assets/KFOlCnqEu92Fr1MmEU9fBBc--ViM7Ag4Q.woff +0 -0
  54. package/ui/dist/spa/assets/KFOlCnqEu92Fr1MmSU5fBBc--CrFzpgl6.woff +0 -0
  55. package/ui/dist/spa/assets/KFOlCnqEu92Fr1MmWUlfBBc--CW3_XjG_.woff +0 -0
  56. package/ui/dist/spa/assets/KFOlCnqEu92Fr1MmYUtfBBc--Dr8fnyGc.woff +0 -0
  57. package/ui/dist/spa/assets/KFOmCnqEu92Fr1Mu4mxM-DAYh6T4l.woff +0 -0
  58. package/ui/dist/spa/assets/MainLayout-CvQD3xKr.js +0 -1
  59. package/ui/dist/spa/assets/axios-C0XcclIb.js +0 -1
  60. package/ui/dist/spa/assets/flUhRq6tzZclQEJ-Vdg-IuiaDsNa-Dr0goTwe.woff +0 -0
  61. package/ui/dist/spa/assets/index-CwWo8xmP.js +0 -40
  62. package/ui/dist/spa/assets/index-kXpA8n8r.css +0 -5
package/ui/package.json CHANGED
@@ -1,42 +1,43 @@
1
- {
2
- "name": "mysqlsyncr",
3
- "version": "0.0.1",
4
- "description": "A simple ui for the sync features in mysqlsyncr",
5
- "productName": "MySQLsyncr",
6
- "author": "Craigzyc <craig.zych@neelands.com>",
7
- "type": "module",
8
- "private": true,
9
- "scripts": {
10
- "lint": "eslint -c ./eslint.config.js \"./src*/**/*.{js,cjs,mjs,vue}\"",
11
- "format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
12
- "test": "echo \"No test specified\" && exit 0",
13
- "dev": "quasar dev",
14
- "build": "quasar build",
15
- "postinstall": "quasar prepare"
16
- },
17
- "dependencies": {
18
- "axios": "^1.2.1",
19
- "pinia": "^2.0.11",
20
- "@quasar/extras": "^1.16.4",
21
- "quasar": "^2.16.0",
22
- "vue": "^3.4.18",
23
- "vue-router": "^4.0.0"
24
- },
25
- "devDependencies": {
26
- "@eslint/js": "^9.14.0",
27
- "eslint": "^9.14.0",
28
- "eslint-plugin-vue": "^9.30.0",
29
- "globals": "^15.12.0",
30
- "vite-plugin-checker": "^0.8.0",
31
- "@vue/eslint-config-prettier": "^10.1.0",
32
- "prettier": "^3.3.3",
33
- "@quasar/app-vite": "^2.0.0",
34
- "autoprefixer": "^10.4.2",
35
- "postcss": "^8.4.14"
36
- },
37
- "engines": {
38
- "node": "^28 || ^26 || ^24 || ^22 || ^20 || ^18",
39
- "npm": ">= 6.13.4",
40
- "yarn": ">= 1.21.1"
41
- }
42
- }
1
+ {
2
+ "name": "mysqlsyncr",
3
+ "version": "0.0.1",
4
+ "description": "A simple ui for the sync features in mysqlsyncr",
5
+ "productName": "MySQLsyncr",
6
+ "author": "Craigzyc <craig.zych@neelands.com>",
7
+ "type": "module",
8
+ "private": true,
9
+ "scripts": {
10
+ "lint": "eslint -c ./eslint.config.js \"./src*/**/*.{js,cjs,mjs,vue}\"",
11
+ "format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
12
+ "test": "echo \"No test specified\" && exit 0",
13
+ "dev": "quasar dev",
14
+ "build": "quasar build",
15
+ "postinstall": "quasar prepare"
16
+ },
17
+ "dependencies": {
18
+ "@quasar/extras": "^1.16.4",
19
+ "axios": "^1.20.0",
20
+ "diff": "^5.2.2",
21
+ "pinia": "^2.0.11",
22
+ "quasar": "^2.35.1",
23
+ "vue": "^3.5.44",
24
+ "vue-router": "^4.0.0"
25
+ },
26
+ "devDependencies": {
27
+ "@eslint/js": "^9.14.0",
28
+ "@quasar/app-vite": "^2.0.0",
29
+ "@vue/eslint-config-prettier": "^10.1.0",
30
+ "autoprefixer": "^10.4.2",
31
+ "eslint": "^9.14.0",
32
+ "eslint-plugin-vue": "^9.30.0",
33
+ "globals": "^15.12.0",
34
+ "postcss": "^8.4.14",
35
+ "prettier": "^3.3.3",
36
+ "vite-plugin-checker": "^0.8.0"
37
+ },
38
+ "engines": {
39
+ "node": "^28 || ^26 || ^24 || ^22 || ^20 || ^18",
40
+ "npm": ">= 6.13.4",
41
+ "yarn": ">= 1.21.1"
42
+ }
43
+ }
@@ -0,0 +1,169 @@
1
+ <template>
2
+ <div class="definition-diff">
3
+ <div class="row items-center q-gutter-md q-mb-sm">
4
+ <span class="legend legend-removed">− {{ expectedLabel }}</span>
5
+ <span class="legend legend-added">+ {{ currentLabel }}</span>
6
+ <q-space />
7
+ <q-toggle v-model="changesOnly" dense label="Changes only" />
8
+ <q-toggle v-model="ignoreWhitespace" dense label="Ignore whitespace" />
9
+ </div>
10
+ <div v-if="!hasChanges" class="text-grey q-pa-sm">
11
+ No differences{{ ignoreWhitespace ? ' apart from whitespace' : '' }}.
12
+ </div>
13
+ <div v-else class="diff-code">
14
+ <div v-for="(row, i) in visibleRows" :key="i" :class="['diff-line', `diff-${row.kind}`]">
15
+ <span class="diff-no">{{ row.templateNo ?? '' }}</span>
16
+ <span class="diff-no">{{ row.databaseNo ?? '' }}</span>
17
+ <span class="diff-mark">{{ marks[row.kind] }}</span>
18
+ <span class="diff-text">{{ row.text }}</span>
19
+ </div>
20
+ </div>
21
+ </div>
22
+ </template>
23
+
24
+ <script>
25
+ import { diffLines } from 'diff'
26
+
27
+ // Unchanged lines kept around each change when showing changes only
28
+ const CONTEXT_LINES = 3
29
+
30
+ const withTrailingNewline = (text) => {
31
+ const normalized = (text ?? '').replace(/\r\n/g, '\n')
32
+ return normalized.endsWith('\n') ? normalized : `${normalized}\n`
33
+ }
34
+
35
+ // Same rule the comparison uses: runs of whitespace count as one space
36
+ const collapseWhitespace = (line) => line.replace(/\s+/g, ' ').trim()
37
+
38
+ /**
39
+ * Line-by-line comparison of two versions of a definition: by default the
40
+ * template's and the database's, or any two given labels.
41
+ */
42
+ export default {
43
+ name: 'DefinitionDiff',
44
+ props: {
45
+ expected: { type: String, default: '' },
46
+ current: { type: String, default: '' },
47
+ expectedLabel: { type: String, default: 'Template (expected)' },
48
+ currentLabel: { type: String, default: 'Database (current)' },
49
+ },
50
+ data() {
51
+ return {
52
+ changesOnly: true,
53
+ ignoreWhitespace: true,
54
+ marks: { same: ' ', removed: '−', added: '+', skip: '' },
55
+ }
56
+ },
57
+ computed: {
58
+ // [{ kind: 'same' | 'removed' | 'added', text, templateNo, databaseNo }]
59
+ rows() {
60
+ const options = this.ignoreWhitespace
61
+ ? { comparator: (left, right) => collapseWhitespace(left) === collapseWhitespace(right) }
62
+ : {}
63
+ const parts = diffLines(withTrailingNewline(this.expected), withTrailingNewline(this.current), options)
64
+ const rows = []
65
+ let templateNo = 1
66
+ let databaseNo = 1
67
+ for (const part of parts) {
68
+ for (const text of part.value.replace(/\n$/, '').split('\n')) {
69
+ if (part.removed) rows.push({ kind: 'removed', text, templateNo: templateNo++ })
70
+ else if (part.added) rows.push({ kind: 'added', text, databaseNo: databaseNo++ })
71
+ else rows.push({ kind: 'same', text, templateNo: templateNo++, databaseNo: databaseNo++ })
72
+ }
73
+ }
74
+ return rows
75
+ },
76
+ hasChanges() {
77
+ return this.rows.some((row) => row.kind !== 'same')
78
+ },
79
+ visibleRows() {
80
+ if (!this.changesOnly) return this.rows
81
+ const keep = this.rows.map(() => false)
82
+ this.rows.forEach((row, i) => {
83
+ if (row.kind === 'same') return
84
+ for (let j = Math.max(0, i - CONTEXT_LINES); j <= Math.min(this.rows.length - 1, i + CONTEXT_LINES); j++) {
85
+ keep[j] = true
86
+ }
87
+ })
88
+ const visible = []
89
+ let skipped = 0
90
+ const addSkip = () => {
91
+ if (skipped > 0) visible.push({ kind: 'skip', text: `… ${skipped} unchanged line${skipped === 1 ? '' : 's'}` })
92
+ skipped = 0
93
+ }
94
+ this.rows.forEach((row, i) => {
95
+ if (keep[i]) {
96
+ addSkip()
97
+ visible.push(row)
98
+ } else {
99
+ skipped++
100
+ }
101
+ })
102
+ addSkip()
103
+ return visible
104
+ },
105
+ },
106
+ }
107
+ </script>
108
+
109
+ <style scoped>
110
+ .diff-code {
111
+ font-family: monospace;
112
+ font-size: 12px;
113
+ border: 1px solid #ddd;
114
+ border-radius: 4px;
115
+ overflow-x: auto;
116
+ max-height: 60vh;
117
+ overflow-y: auto;
118
+ }
119
+ .diff-line {
120
+ display: flex;
121
+ white-space: pre;
122
+ min-width: max-content;
123
+ }
124
+ .diff-no {
125
+ width: 3.5em;
126
+ flex: none;
127
+ text-align: right;
128
+ padding-right: 0.5em;
129
+ color: #999;
130
+ user-select: none;
131
+ }
132
+ .diff-mark {
133
+ width: 1.5em;
134
+ flex: none;
135
+ text-align: center;
136
+ user-select: none;
137
+ }
138
+ .diff-removed {
139
+ background: #ffebe9;
140
+ }
141
+ .diff-removed .diff-mark {
142
+ color: #c62828;
143
+ }
144
+ .diff-added {
145
+ background: #e6ffec;
146
+ }
147
+ .diff-added .diff-mark {
148
+ color: #2e7d32;
149
+ }
150
+ .diff-skip {
151
+ background: #f1f3f5;
152
+ color: #777;
153
+ font-style: italic;
154
+ }
155
+ .legend {
156
+ font-family: monospace;
157
+ font-size: 12px;
158
+ padding: 2px 6px;
159
+ border-radius: 3px;
160
+ }
161
+ .legend-removed {
162
+ background: #ffebe9;
163
+ color: #c62828;
164
+ }
165
+ .legend-added {
166
+ background: #e6ffec;
167
+ color: #2e7d32;
168
+ }
169
+ </style>