@emasoft/svg-matrix 1.0.16 → 1.0.17
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.
- package/package.json +6 -2
- package/scripts/postinstall.js +1 -1
- package/scripts/version-sync.js +230 -0
- package/src/index.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@emasoft/svg-matrix",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.17",
|
|
4
4
|
"description": "Arbitrary-precision matrix, vector and affine transformation library for JavaScript using decimal.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -9,7 +9,11 @@
|
|
|
9
9
|
"test:browser": "node test/browser-verify.mjs",
|
|
10
10
|
"test:playwright": "node test/playwright-diagnose.js",
|
|
11
11
|
"ci-test": "npm ci && npm test",
|
|
12
|
-
"
|
|
12
|
+
"version:sync": "node scripts/version-sync.js",
|
|
13
|
+
"version:check": "node scripts/version-sync.js --check",
|
|
14
|
+
"preversion": "npm run version:sync",
|
|
15
|
+
"version": "node scripts/version-sync.js && git add src/index.js package-lock.json",
|
|
16
|
+
"prepublishOnly": "npm run version:check && npm test",
|
|
13
17
|
"postinstall": "node scripts/postinstall.js || true"
|
|
14
18
|
},
|
|
15
19
|
"repository": {
|
package/scripts/postinstall.js
CHANGED
|
@@ -137,7 +137,7 @@ ${c.cyan}${B.v}${c.reset}${R(` ${c.green}${B.dot} Transforms3D${c.reset} 3D af
|
|
|
137
137
|
${c.cyan}${B.v}${c.reset}${R('')}${c.cyan}${B.v}${c.reset}
|
|
138
138
|
${c.cyan}${B.v}${hr}${B.v}${c.reset}
|
|
139
139
|
${c.cyan}${B.v}${c.reset}${R('')}${c.cyan}${B.v}${c.reset}
|
|
140
|
-
${c.cyan}${B.v}${c.reset}${R(` ${c.yellow}New in v1.0.
|
|
140
|
+
${c.cyan}${B.v}${c.reset}${R(` ${c.yellow}New in v1.0.17:${c.reset}`)}${c.cyan}${B.v}${c.reset}
|
|
141
141
|
${c.cyan}${B.v}${c.reset}${R(` ${c.green}${B.dot}${c.reset} Enhanced CLI help: svg-matrix <command> --help`)}${c.cyan}${B.v}${c.reset}
|
|
142
142
|
${c.cyan}${B.v}${c.reset}${R(` ${c.green}${B.dot}${c.reset} High-precision Bezier circle/ellipse approximation`)}${c.cyan}${B.v}${c.reset}
|
|
143
143
|
${c.cyan}${B.v}${c.reset}${R(` ${c.green}${B.dot}${c.reset} E2E verification always enabled for precision`)}${c.cyan}${B.v}${c.reset}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Version synchronization script for @emasoft/svg-matrix
|
|
4
|
+
* Ensures all version references in the codebase match package.json.
|
|
5
|
+
*
|
|
6
|
+
* This script:
|
|
7
|
+
* 1. Reads the canonical version from package.json
|
|
8
|
+
* 2. Updates src/index.js (VERSION constant and @version jsdoc)
|
|
9
|
+
* 3. Can optionally update package-lock.json
|
|
10
|
+
* 4. Validates that all versions are in sync
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* node scripts/version-sync.js # Sync versions
|
|
14
|
+
* node scripts/version-sync.js --check # Check only (exit 1 if mismatch)
|
|
15
|
+
* node scripts/version-sync.js --help # Show help
|
|
16
|
+
*
|
|
17
|
+
* @module scripts/version-sync
|
|
18
|
+
* @license MIT
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
22
|
+
import { fileURLToPath } from 'url';
|
|
23
|
+
import { dirname, join } from 'path';
|
|
24
|
+
|
|
25
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
26
|
+
const ROOT = join(__dirname, '..');
|
|
27
|
+
|
|
28
|
+
// ANSI colors for output
|
|
29
|
+
const colors = process.env.NO_COLOR !== undefined ? {
|
|
30
|
+
reset: '', red: '', green: '', yellow: '', cyan: '', dim: '', bright: '',
|
|
31
|
+
} : {
|
|
32
|
+
reset: '\x1b[0m', red: '\x1b[31m', green: '\x1b[32m',
|
|
33
|
+
yellow: '\x1b[33m', cyan: '\x1b[36m', dim: '\x1b[2m', bright: '\x1b[1m',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Read the canonical version from package.json
|
|
38
|
+
* @returns {string} Version string
|
|
39
|
+
*/
|
|
40
|
+
function getPackageVersion() {
|
|
41
|
+
const pkg = JSON.parse(readFileSync(join(ROOT, 'package.json'), 'utf8'));
|
|
42
|
+
return pkg.version;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Get version from src/index.js VERSION constant
|
|
47
|
+
* @returns {string|null} Version string or null if not found
|
|
48
|
+
*/
|
|
49
|
+
function getIndexVersion() {
|
|
50
|
+
const content = readFileSync(join(ROOT, 'src', 'index.js'), 'utf8');
|
|
51
|
+
const match = content.match(/export const VERSION = ['"]([^'"]+)['"]/);
|
|
52
|
+
return match ? match[1] : null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get @version from src/index.js jsdoc
|
|
57
|
+
* @returns {string|null} Version string or null if not found
|
|
58
|
+
*/
|
|
59
|
+
function getIndexJsDocVersion() {
|
|
60
|
+
const content = readFileSync(join(ROOT, 'src', 'index.js'), 'utf8');
|
|
61
|
+
const match = content.match(/@version\s+(\S+)/);
|
|
62
|
+
return match ? match[1] : null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Get version from package-lock.json root
|
|
67
|
+
* @returns {string|null} Version string or null if not found
|
|
68
|
+
*/
|
|
69
|
+
function getLockfileVersion() {
|
|
70
|
+
try {
|
|
71
|
+
const lock = JSON.parse(readFileSync(join(ROOT, 'package-lock.json'), 'utf8'));
|
|
72
|
+
return lock.version;
|
|
73
|
+
} catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Update src/index.js VERSION constant
|
|
80
|
+
* @param {string} version - New version
|
|
81
|
+
* @returns {boolean} True if updated
|
|
82
|
+
*/
|
|
83
|
+
function updateIndexVersion(version) {
|
|
84
|
+
const filePath = join(ROOT, 'src', 'index.js');
|
|
85
|
+
let content = readFileSync(filePath, 'utf8');
|
|
86
|
+
const original = content;
|
|
87
|
+
|
|
88
|
+
// Update VERSION constant
|
|
89
|
+
content = content.replace(
|
|
90
|
+
/export const VERSION = ['"][^'"]+['"]/,
|
|
91
|
+
`export const VERSION = '${version}'`
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
// Update @version in jsdoc
|
|
95
|
+
content = content.replace(
|
|
96
|
+
/@version\s+\S+/,
|
|
97
|
+
`@version ${version}`
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
if (content !== original) {
|
|
101
|
+
writeFileSync(filePath, content, 'utf8');
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Update package-lock.json version
|
|
109
|
+
* @param {string} version - New version
|
|
110
|
+
* @returns {boolean} True if updated
|
|
111
|
+
*/
|
|
112
|
+
function updateLockfileVersion(version) {
|
|
113
|
+
const filePath = join(ROOT, 'package-lock.json');
|
|
114
|
+
try {
|
|
115
|
+
const lock = JSON.parse(readFileSync(filePath, 'utf8'));
|
|
116
|
+
const original = JSON.stringify(lock);
|
|
117
|
+
|
|
118
|
+
lock.version = version;
|
|
119
|
+
if (lock.packages && lock.packages['']) {
|
|
120
|
+
lock.packages[''].version = version;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const updated = JSON.stringify(lock, null, 2) + '\n';
|
|
124
|
+
if (updated !== original) {
|
|
125
|
+
writeFileSync(filePath, updated, 'utf8');
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
} catch {
|
|
129
|
+
// Lockfile might not exist
|
|
130
|
+
}
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Check if all versions are in sync
|
|
136
|
+
* @returns {{inSync: boolean, versions: Object}}
|
|
137
|
+
*/
|
|
138
|
+
function checkVersions() {
|
|
139
|
+
const pkgVersion = getPackageVersion();
|
|
140
|
+
const indexVersion = getIndexVersion();
|
|
141
|
+
const jsDocVersion = getIndexJsDocVersion();
|
|
142
|
+
const lockVersion = getLockfileVersion();
|
|
143
|
+
|
|
144
|
+
const versions = {
|
|
145
|
+
'package.json': pkgVersion,
|
|
146
|
+
'src/index.js (VERSION)': indexVersion,
|
|
147
|
+
'src/index.js (@version)': jsDocVersion,
|
|
148
|
+
'package-lock.json': lockVersion,
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const inSync = indexVersion === pkgVersion &&
|
|
152
|
+
jsDocVersion === pkgVersion &&
|
|
153
|
+
(lockVersion === null || lockVersion === pkgVersion);
|
|
154
|
+
|
|
155
|
+
return { inSync, versions, canonical: pkgVersion };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Main function
|
|
160
|
+
*/
|
|
161
|
+
function main() {
|
|
162
|
+
const args = process.argv.slice(2);
|
|
163
|
+
|
|
164
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
165
|
+
console.log(`
|
|
166
|
+
${colors.bright}version-sync.js${colors.reset} - Synchronize version numbers across the codebase
|
|
167
|
+
|
|
168
|
+
${colors.cyan}Usage:${colors.reset}
|
|
169
|
+
node scripts/version-sync.js Sync all versions to package.json
|
|
170
|
+
node scripts/version-sync.js --check Check only (exit 1 if mismatch)
|
|
171
|
+
node scripts/version-sync.js --help Show this help
|
|
172
|
+
|
|
173
|
+
${colors.cyan}Files updated:${colors.reset}
|
|
174
|
+
- src/index.js (VERSION constant)
|
|
175
|
+
- src/index.js (@version jsdoc)
|
|
176
|
+
- package-lock.json (if present)
|
|
177
|
+
`);
|
|
178
|
+
process.exit(0);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const checkOnly = args.includes('--check');
|
|
182
|
+
const { inSync, versions, canonical } = checkVersions();
|
|
183
|
+
|
|
184
|
+
console.log(`${colors.bright}Version Check${colors.reset}`);
|
|
185
|
+
console.log(`${colors.dim}${'─'.repeat(50)}${colors.reset}`);
|
|
186
|
+
|
|
187
|
+
for (const [file, version] of Object.entries(versions)) {
|
|
188
|
+
const status = version === canonical
|
|
189
|
+
? `${colors.green}OK${colors.reset}`
|
|
190
|
+
: version === null
|
|
191
|
+
? `${colors.yellow}N/A${colors.reset}`
|
|
192
|
+
: `${colors.red}MISMATCH${colors.reset}`;
|
|
193
|
+
console.log(` ${file.padEnd(30)} ${(version || 'N/A').padEnd(12)} ${status}`);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
console.log(`${colors.dim}${'─'.repeat(50)}${colors.reset}`);
|
|
197
|
+
console.log(` Canonical version: ${colors.cyan}${canonical}${colors.reset}`);
|
|
198
|
+
|
|
199
|
+
if (inSync) {
|
|
200
|
+
console.log(`\n${colors.green}All versions are in sync.${colors.reset}`);
|
|
201
|
+
process.exit(0);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (checkOnly) {
|
|
205
|
+
console.log(`\n${colors.red}Version mismatch detected!${colors.reset}`);
|
|
206
|
+
console.log(`Run ${colors.cyan}node scripts/version-sync.js${colors.reset} to fix.`);
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Sync versions
|
|
211
|
+
console.log(`\n${colors.yellow}Syncing versions...${colors.reset}`);
|
|
212
|
+
|
|
213
|
+
let updated = 0;
|
|
214
|
+
if (updateIndexVersion(canonical)) {
|
|
215
|
+
console.log(` ${colors.green}Updated${colors.reset} src/index.js`);
|
|
216
|
+
updated++;
|
|
217
|
+
}
|
|
218
|
+
if (updateLockfileVersion(canonical)) {
|
|
219
|
+
console.log(` ${colors.green}Updated${colors.reset} package-lock.json`);
|
|
220
|
+
updated++;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (updated > 0) {
|
|
224
|
+
console.log(`\n${colors.green}Synced ${updated} file(s) to version ${canonical}${colors.reset}`);
|
|
225
|
+
} else {
|
|
226
|
+
console.log(`\n${colors.green}All files already in sync.${colors.reset}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
main();
|
package/src/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* SVG path conversion, and 2D/3D affine transformations using Decimal.js.
|
|
6
6
|
*
|
|
7
7
|
* @module @emasoft/svg-matrix
|
|
8
|
-
* @version 1.0.
|
|
8
|
+
* @version 1.0.17
|
|
9
9
|
* @license MIT
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
@@ -58,7 +58,7 @@ Decimal.set({ precision: 80 });
|
|
|
58
58
|
* Library version
|
|
59
59
|
* @constant {string}
|
|
60
60
|
*/
|
|
61
|
-
export const VERSION = '1.0.
|
|
61
|
+
export const VERSION = '1.0.17';
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
64
|
* Default precision for path output (decimal places)
|