rp2040js 1.3.3 → 1.4.0
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/LICENSE +21 -21
- package/README.md +128 -128
- package/dist/cjs/gdb/gdb-server.js +31 -31
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/peripherals/clocks.d.ts +11 -0
- package/dist/cjs/peripherals/clocks.js +108 -0
- package/dist/cjs/peripherals/pll.d.ts +25 -0
- package/dist/cjs/peripherals/pll.js +94 -0
- package/dist/cjs/peripherals/pwm.js +8 -5
- package/dist/cjs/peripherals/uart.d.ts +2 -0
- package/dist/cjs/peripherals/uart.js +7 -0
- package/dist/cjs/rp2040.d.ts +24 -0
- package/dist/cjs/rp2040.js +52 -3
- package/dist/cjs/utils/timer32.js +6 -0
- package/dist/esm/gdb/gdb-server.js +31 -31
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/peripherals/clocks.d.ts +11 -0
- package/dist/esm/peripherals/clocks.js +108 -0
- package/dist/esm/peripherals/pll.d.ts +25 -0
- package/dist/esm/peripherals/pll.js +90 -0
- package/dist/esm/peripherals/pwm.js +8 -5
- package/dist/esm/peripherals/uart.d.ts +2 -0
- package/dist/esm/peripherals/uart.js +7 -0
- package/dist/esm/rp2040.d.ts +24 -0
- package/dist/esm/rp2040.js +52 -3
- package/dist/esm/utils/timer32.js +6 -0
- package/package.json +88 -88
|
@@ -103,12 +103,15 @@ class PWMChannel {
|
|
|
103
103
|
if (value & CSR_EN && !(this.csr & CSR_EN)) {
|
|
104
104
|
this.updateDoubleBuffered();
|
|
105
105
|
}
|
|
106
|
+
// PH_ADV and PH_RET are self-clearing, so they never appear in the stored csr value
|
|
106
107
|
this.csr = value & ~(CSR_PH_ADV | CSR_PH_RET);
|
|
107
|
-
if (
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
if (value & CSR_EN) {
|
|
109
|
+
if (value & CSR_PH_ADV) {
|
|
110
|
+
this.timer.advance(1);
|
|
111
|
+
}
|
|
112
|
+
if (value & CSR_PH_RET) {
|
|
113
|
+
this.timer.advance(-1);
|
|
114
|
+
}
|
|
112
115
|
}
|
|
113
116
|
this.divMode = (this.csr >> CSR_DIVMODE_SHIFT) & CSR_DIVMODE_MASK;
|
|
114
117
|
this.setBDirection(this.divMode === PWMDivMode.FreeRunning);
|
|
@@ -28,6 +28,8 @@ export declare class RPUART extends BasePeripheral implements Peripheral {
|
|
|
28
28
|
get wordLength(): 5 | 6 | 7 | 8 | undefined;
|
|
29
29
|
get baudDivider(): number;
|
|
30
30
|
get baudRate(): number;
|
|
31
|
+
/** Re-reports the baud rate, unless the firmware has not set the divider yet. */
|
|
32
|
+
clkPeriChanged(): void;
|
|
31
33
|
get flags(): number;
|
|
32
34
|
checkInterrupts(): void;
|
|
33
35
|
feedByte(value: number): void;
|
|
@@ -77,6 +77,13 @@ export class RPUART extends BasePeripheral {
|
|
|
77
77
|
get baudRate() {
|
|
78
78
|
return Math.round(this.rp2040.clkPeri / (this.baudDivider * 16));
|
|
79
79
|
}
|
|
80
|
+
/** Re-reports the baud rate, unless the firmware has not set the divider yet. */
|
|
81
|
+
clkPeriChanged() {
|
|
82
|
+
var _a;
|
|
83
|
+
if (this.baudDivider) {
|
|
84
|
+
(_a = this.onBaudRateChange) === null || _a === void 0 ? void 0 : _a.call(this, this.baudRate);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
80
87
|
get flags() {
|
|
81
88
|
return (this.rxFIFO.full ? RXFF : 0) | (this.rxFIFO.empty ? RXFE : 0) | TXFE;
|
|
82
89
|
}
|
package/dist/esm/rp2040.d.ts
CHANGED
|
@@ -2,10 +2,12 @@ import { IClock } from './clock/clock.js';
|
|
|
2
2
|
import { CortexM0Core } from './cortex-m0-core.js';
|
|
3
3
|
import { GPIOPin } from './gpio-pin.js';
|
|
4
4
|
import { RPADC } from './peripherals/adc.js';
|
|
5
|
+
import { RPClocks } from './peripherals/clocks.js';
|
|
5
6
|
import { RPDMA } from './peripherals/dma.js';
|
|
6
7
|
import { RPI2C } from './peripherals/i2c.js';
|
|
7
8
|
import { Peripheral } from './peripherals/peripheral.js';
|
|
8
9
|
import { RPPIO } from './peripherals/pio.js';
|
|
10
|
+
import { RPPLL } from './peripherals/pll.js';
|
|
9
11
|
import { RPPPB } from './peripherals/ppb.js';
|
|
10
12
|
import { RPPWM } from './peripherals/pwm.js';
|
|
11
13
|
import { RPSPI } from './peripherals/spi.js';
|
|
@@ -19,6 +21,11 @@ export declare const RAM_START_ADDRESS = 536870912;
|
|
|
19
21
|
export declare const APB_START_ADDRESS = 1073741824;
|
|
20
22
|
export declare const DPRAM_START_ADDRESS = 1343225856;
|
|
21
23
|
export declare const SIO_START_ADDRESS = 3489660928;
|
|
24
|
+
/**
|
|
25
|
+
* Notified after clk_sys changes. Listeners that cache a frequency derived from clk_sys
|
|
26
|
+
* (PIO clock dividers, for instance) use this to re-derive it.
|
|
27
|
+
*/
|
|
28
|
+
export type ClockListener = (clkSys: number, oldClkSys: number) => void;
|
|
22
29
|
export declare class RP2040 {
|
|
23
30
|
readonly clock: IClock;
|
|
24
31
|
readonly bootrom: Uint32Array<ArrayBuffer>;
|
|
@@ -32,6 +39,13 @@ export declare class RP2040 {
|
|
|
32
39
|
readonly core: CortexM0Core;
|
|
33
40
|
clkSys: number;
|
|
34
41
|
clkPeri: number;
|
|
42
|
+
/** Crystal oscillator frequency. 12 MHz on the Raspberry Pi Pico and most other boards. */
|
|
43
|
+
xoscFreq: number;
|
|
44
|
+
/** Ring oscillator frequency. Varies with voltage/temperature on real silicon. */
|
|
45
|
+
roscFreq: number;
|
|
46
|
+
readonly pllSys: RPPLL;
|
|
47
|
+
readonly pllUsb: RPPLL;
|
|
48
|
+
readonly clocks: RPClocks;
|
|
35
49
|
readonly ppb: RPPPB;
|
|
36
50
|
readonly sio: RPSIO;
|
|
37
51
|
readonly uart: RPUART[];
|
|
@@ -45,6 +59,7 @@ export declare class RP2040 {
|
|
|
45
59
|
readonly usbCtrl: RPUSBController;
|
|
46
60
|
readonly spi: RPSPI[];
|
|
47
61
|
logger: Logger;
|
|
62
|
+
private readonly clockListeners;
|
|
48
63
|
readonly peripherals: {
|
|
49
64
|
[index: number]: Peripheral;
|
|
50
65
|
};
|
|
@@ -53,6 +68,15 @@ export declare class RP2040 {
|
|
|
53
68
|
loadBootrom(bootromData: Uint32Array): void;
|
|
54
69
|
reset(): void;
|
|
55
70
|
readUint32(address: number): number;
|
|
71
|
+
/**
|
|
72
|
+
* Recomputes `clkSys` and `clkPeri` from the PLL and CLOCKS registers and updates the
|
|
73
|
+
* peripherals derived from them. Until firmware configures the clock tree, each keeps its default.
|
|
74
|
+
*/
|
|
75
|
+
updateClocks(): void;
|
|
76
|
+
private updateClkSys;
|
|
77
|
+
private updateClkPeri;
|
|
78
|
+
/** Registers a listener to be notified whenever clk_sys changes. Returns an unsubscribe function. */
|
|
79
|
+
addClockListener(listener: ClockListener): () => boolean;
|
|
56
80
|
findPeripheral(address: number): Peripheral;
|
|
57
81
|
/** We assume the address is 16-bit aligned */
|
|
58
82
|
readUint16(address: number): number;
|
package/dist/esm/rp2040.js
CHANGED
|
@@ -11,6 +11,7 @@ import { RPIO } from './peripherals/io.js';
|
|
|
11
11
|
import { RPPADS } from './peripherals/pads.js';
|
|
12
12
|
import { UnimplementedPeripheral } from './peripherals/peripheral.js';
|
|
13
13
|
import { RPPIO } from './peripherals/pio.js';
|
|
14
|
+
import { RPPLL } from './peripherals/pll.js';
|
|
14
15
|
import { RPPPB } from './peripherals/ppb.js';
|
|
15
16
|
import { RPPSM } from './peripherals/psm.js';
|
|
16
17
|
import { RPPWM } from './peripherals/pwm.js';
|
|
@@ -53,6 +54,13 @@ export class RP2040 {
|
|
|
53
54
|
/* Clocks */
|
|
54
55
|
this.clkSys = 125 * MHz;
|
|
55
56
|
this.clkPeri = 125 * MHz;
|
|
57
|
+
/** Crystal oscillator frequency. 12 MHz on the Raspberry Pi Pico and most other boards. */
|
|
58
|
+
this.xoscFreq = 12 * MHz;
|
|
59
|
+
/** Ring oscillator frequency. Varies with voltage/temperature on real silicon. */
|
|
60
|
+
this.roscFreq = 6.5 * MHz;
|
|
61
|
+
this.pllSys = new RPPLL(this, 'PLL_SYS_BASE');
|
|
62
|
+
this.pllUsb = new RPPLL(this, 'PLL_USB_BASE');
|
|
63
|
+
this.clocks = new RPClocks(this, 'CLOCKS_BASE');
|
|
56
64
|
this.ppb = new RPPPB(this, 'PPB');
|
|
57
65
|
this.sio = new RPSIO(this);
|
|
58
66
|
this.uart = [
|
|
@@ -125,11 +133,12 @@ export class RP2040 {
|
|
|
125
133
|
}),
|
|
126
134
|
];
|
|
127
135
|
this.logger = new ConsoleLogger(LogLevel.Debug, true);
|
|
136
|
+
this.clockListeners = new Set();
|
|
128
137
|
this.peripherals = {
|
|
129
138
|
0x18000: new RPSSI(this, 'SSI'),
|
|
130
139
|
0x40000: new RP2040SysInfo(this, 'SYSINFO_BASE'),
|
|
131
140
|
0x40004: new RP2040SysCfg(this, 'SYSCFG'),
|
|
132
|
-
0x40008:
|
|
141
|
+
0x40008: this.clocks,
|
|
133
142
|
0x4000c: new RPReset(this, 'RESETS_BASE'),
|
|
134
143
|
0x40010: new RPPSM(this, 'PSM_BASE'),
|
|
135
144
|
0x40014: new RPIO(this, 'IO_BANK0_BASE'),
|
|
@@ -137,8 +146,8 @@ export class RP2040 {
|
|
|
137
146
|
0x4001c: new RPPADS(this, 'PADS_BANK0_BASE', 'bank0'),
|
|
138
147
|
0x40020: new RPPADS(this, 'PADS_QSPI_BASE', 'qspi'),
|
|
139
148
|
0x40024: new RPXOSC(this, 'XOSC_BASE'),
|
|
140
|
-
0x40028:
|
|
141
|
-
0x4002c:
|
|
149
|
+
0x40028: this.pllSys,
|
|
150
|
+
0x4002c: this.pllUsb,
|
|
142
151
|
0x40030: new RPBUSCTRL(this, 'BUSCTRL_BASE'),
|
|
143
152
|
0x40034: this.uart[0],
|
|
144
153
|
0x40038: this.uart[1],
|
|
@@ -214,6 +223,46 @@ export class RP2040 {
|
|
|
214
223
|
this.logger.warn(LOG_NAME, `Read from invalid memory address: ${address.toString(16)}`);
|
|
215
224
|
return 0xffffffff;
|
|
216
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Recomputes `clkSys` and `clkPeri` from the PLL and CLOCKS registers and updates the
|
|
228
|
+
* peripherals derived from them. Until firmware configures the clock tree, each keeps its default.
|
|
229
|
+
*/
|
|
230
|
+
updateClocks() {
|
|
231
|
+
this.updateClkSys();
|
|
232
|
+
this.updateClkPeri();
|
|
233
|
+
}
|
|
234
|
+
updateClkSys() {
|
|
235
|
+
const clkSys = this.clocks.sysFreq;
|
|
236
|
+
// 0 means clk_sys is fed from an unmodelled or unconfigured source: keep the last value
|
|
237
|
+
if (!clkSys || clkSys === this.clkSys) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const oldClkSys = this.clkSys;
|
|
241
|
+
this.clkSys = clkSys;
|
|
242
|
+
this.ppb.systickTimer.frequency = clkSys;
|
|
243
|
+
for (const channel of this.pwm.channels) {
|
|
244
|
+
channel.timer.frequency = this.pwm.clockFreq;
|
|
245
|
+
}
|
|
246
|
+
for (const listener of this.clockListeners) {
|
|
247
|
+
listener(clkSys, oldClkSys);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
updateClkPeri() {
|
|
251
|
+
const clkPeri = this.clocks.periFreq;
|
|
252
|
+
// 0 means the clock generator is stopped, or the source is one we do not model
|
|
253
|
+
if (!clkPeri || clkPeri === this.clkPeri) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
this.clkPeri = clkPeri;
|
|
257
|
+
for (const uart of this.uart) {
|
|
258
|
+
uart.clkPeriChanged();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/** Registers a listener to be notified whenever clk_sys changes. Returns an unsubscribe function. */
|
|
262
|
+
addClockListener(listener) {
|
|
263
|
+
this.clockListeners.add(listener);
|
|
264
|
+
return () => this.clockListeners.delete(listener);
|
|
265
|
+
}
|
|
217
266
|
findPeripheral(address) {
|
|
218
267
|
return this.peripherals[(address >>> 14) << 2];
|
|
219
268
|
}
|
|
@@ -34,6 +34,12 @@ export class Timer32 {
|
|
|
34
34
|
*/
|
|
35
35
|
advance(delta) {
|
|
36
36
|
this.baseValue += delta;
|
|
37
|
+
if (this.topValue !== 0xffffffff) {
|
|
38
|
+
// Keep the base value in range, so that retarding past 0 wraps around to the top
|
|
39
|
+
const topModulo = this.timerMode === TimerMode.ZigZag ? this.topValue * 2 : this.topValue + 1;
|
|
40
|
+
this.baseValue = ((this.baseValue % topModulo) + topModulo) % topModulo;
|
|
41
|
+
}
|
|
42
|
+
this.updated();
|
|
37
43
|
}
|
|
38
44
|
get rawCounter() {
|
|
39
45
|
const { baseFreq, prescalerValue, baseNanos, baseValue, enabled, timerMode } = this;
|
package/package.json
CHANGED
|
@@ -1,88 +1,88 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "rp2040js",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Raspberry Pi Pico (RP2040) Emulator",
|
|
5
|
-
"repository": {
|
|
6
|
-
"type": "git",
|
|
7
|
-
"url": "git+https://github.com/wokwi/rp2040js.git"
|
|
8
|
-
},
|
|
9
|
-
"keywords": [
|
|
10
|
-
"rp2040",
|
|
11
|
-
"raspberry pi pico",
|
|
12
|
-
"emulator"
|
|
13
|
-
],
|
|
14
|
-
"files": [
|
|
15
|
-
"dist"
|
|
16
|
-
],
|
|
17
|
-
"author": "Uri Shaked <uri@wokwi.com>",
|
|
18
|
-
"license": "MIT",
|
|
19
|
-
"type": "module",
|
|
20
|
-
"main": "./dist/cjs/index.js",
|
|
21
|
-
"module": "./dist/esm/index.js",
|
|
22
|
-
"typings": "./dist/cjs/index.d.ts",
|
|
23
|
-
"engines": {
|
|
24
|
-
"node": ">=18.0.0"
|
|
25
|
-
},
|
|
26
|
-
"exports": {
|
|
27
|
-
".": {
|
|
28
|
-
"import": {
|
|
29
|
-
"types": "./dist/esm/index.d.ts",
|
|
30
|
-
"default": "./dist/esm/index.js"
|
|
31
|
-
},
|
|
32
|
-
"require": {
|
|
33
|
-
"types": "./dist/cjs/index.d.ts",
|
|
34
|
-
"default": "./dist/cjs/index.js"
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
"./gdb-tcp-server": {
|
|
38
|
-
"import": {
|
|
39
|
-
"types": "./dist/esm/gdb/gdb-tcp-server.d.ts",
|
|
40
|
-
"default": "./dist/esm/gdb/gdb-tcp-server.js"
|
|
41
|
-
},
|
|
42
|
-
"require": {
|
|
43
|
-
"types": "./dist/cjs/gdb/gdb-tcp-server.d.ts",
|
|
44
|
-
"default": "./dist/cjs/gdb/gdb-tcp-server.js"
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
"scripts": {
|
|
49
|
-
"build": "rimraf dist && tsc && tsc -p tsconfig.cjs.json && node build-scripts/dist-package-json",
|
|
50
|
-
"prepublish": "npm run build",
|
|
51
|
-
"prepare": "husky install",
|
|
52
|
-
"format:check": "prettier --check **/*.{ts,js} !**/dist/** !**/node_modules/**",
|
|
53
|
-
"lint": "eslint . --ext .ts",
|
|
54
|
-
"start": "tsx demo/emulator-run.ts",
|
|
55
|
-
"start:micropython": "tsx demo/micropython-run.ts",
|
|
56
|
-
"start:circuitpython": "tsx demo/micropython-run.ts --circuitpython",
|
|
57
|
-
"start:gdbdiff": "tsx debug/gdbdiff.ts",
|
|
58
|
-
"test": "vitest run",
|
|
59
|
-
"test:watch": "vitest",
|
|
60
|
-
"test:micropython-spi": "tsx test/micropython-spi-test.ts"
|
|
61
|
-
},
|
|
62
|
-
"devDependencies": {
|
|
63
|
-
"@types/minimist": "^1.2.2",
|
|
64
|
-
"@types/node": "^20",
|
|
65
|
-
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
|
66
|
-
"@typescript-eslint/parser": "^6.7.3",
|
|
67
|
-
"eslint": "^8.50.0",
|
|
68
|
-
"husky": "^8.0.3",
|
|
69
|
-
"lint-staged": "^15.4.3",
|
|
70
|
-
"minimist": "^1.2.7",
|
|
71
|
-
"prettier": "^3.0.3",
|
|
72
|
-
"prettier-plugin-organize-imports": "^4.3.0",
|
|
73
|
-
"rimraf": "^5.0.5",
|
|
74
|
-
"tsx": "^4.19.3",
|
|
75
|
-
"typescript": "^5.7.3",
|
|
76
|
-
"uf2": "^1.0.0",
|
|
77
|
-
"vitest": "^4.1.9"
|
|
78
|
-
},
|
|
79
|
-
"lint-staged": {
|
|
80
|
-
"**/*.ts": [
|
|
81
|
-
"eslint --fix",
|
|
82
|
-
"prettier --write"
|
|
83
|
-
],
|
|
84
|
-
"**/*.js": [
|
|
85
|
-
"prettier --write"
|
|
86
|
-
]
|
|
87
|
-
}
|
|
88
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "rp2040js",
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"description": "Raspberry Pi Pico (RP2040) Emulator",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/wokwi/rp2040js.git"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"rp2040",
|
|
11
|
+
"raspberry pi pico",
|
|
12
|
+
"emulator"
|
|
13
|
+
],
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"author": "Uri Shaked <uri@wokwi.com>",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"type": "module",
|
|
20
|
+
"main": "./dist/cjs/index.js",
|
|
21
|
+
"module": "./dist/esm/index.js",
|
|
22
|
+
"typings": "./dist/cjs/index.d.ts",
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=18.0.0"
|
|
25
|
+
},
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"import": {
|
|
29
|
+
"types": "./dist/esm/index.d.ts",
|
|
30
|
+
"default": "./dist/esm/index.js"
|
|
31
|
+
},
|
|
32
|
+
"require": {
|
|
33
|
+
"types": "./dist/cjs/index.d.ts",
|
|
34
|
+
"default": "./dist/cjs/index.js"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"./gdb-tcp-server": {
|
|
38
|
+
"import": {
|
|
39
|
+
"types": "./dist/esm/gdb/gdb-tcp-server.d.ts",
|
|
40
|
+
"default": "./dist/esm/gdb/gdb-tcp-server.js"
|
|
41
|
+
},
|
|
42
|
+
"require": {
|
|
43
|
+
"types": "./dist/cjs/gdb/gdb-tcp-server.d.ts",
|
|
44
|
+
"default": "./dist/cjs/gdb/gdb-tcp-server.js"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "rimraf dist && tsc && tsc -p tsconfig.cjs.json && node build-scripts/dist-package-json",
|
|
50
|
+
"prepublish": "npm run build",
|
|
51
|
+
"prepare": "husky install",
|
|
52
|
+
"format:check": "prettier --check **/*.{ts,js} !**/dist/** !**/node_modules/**",
|
|
53
|
+
"lint": "eslint . --ext .ts",
|
|
54
|
+
"start": "tsx demo/emulator-run.ts",
|
|
55
|
+
"start:micropython": "tsx demo/micropython-run.ts",
|
|
56
|
+
"start:circuitpython": "tsx demo/micropython-run.ts --circuitpython",
|
|
57
|
+
"start:gdbdiff": "tsx debug/gdbdiff.ts",
|
|
58
|
+
"test": "vitest run",
|
|
59
|
+
"test:watch": "vitest",
|
|
60
|
+
"test:micropython-spi": "tsx test/micropython-spi-test.ts"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@types/minimist": "^1.2.2",
|
|
64
|
+
"@types/node": "^20",
|
|
65
|
+
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
|
66
|
+
"@typescript-eslint/parser": "^6.7.3",
|
|
67
|
+
"eslint": "^8.50.0",
|
|
68
|
+
"husky": "^8.0.3",
|
|
69
|
+
"lint-staged": "^15.4.3",
|
|
70
|
+
"minimist": "^1.2.7",
|
|
71
|
+
"prettier": "^3.0.3",
|
|
72
|
+
"prettier-plugin-organize-imports": "^4.3.0",
|
|
73
|
+
"rimraf": "^5.0.5",
|
|
74
|
+
"tsx": "^4.19.3",
|
|
75
|
+
"typescript": "^5.7.3",
|
|
76
|
+
"uf2": "^1.0.0",
|
|
77
|
+
"vitest": "^4.1.9"
|
|
78
|
+
},
|
|
79
|
+
"lint-staged": {
|
|
80
|
+
"**/*.ts": [
|
|
81
|
+
"eslint --fix",
|
|
82
|
+
"prettier --write"
|
|
83
|
+
],
|
|
84
|
+
"**/*.js": [
|
|
85
|
+
"prettier --write"
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
}
|