forge-solana-sdk 2.2.2 โ 2.2.3
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/README.md +21 -0
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/test.d.ts +2 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +335 -0
- package/dist/commands/test.js.map +1 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -81,6 +81,26 @@ forge audit
|
|
|
81
81
|
- ๐ก๏ธ **Access Control**: Signer constraints, PDA bumps
|
|
82
82
|
- ๐ **Configuration**: Wallet paths, cluster settings
|
|
83
83
|
|
|
84
|
+
### Testing Framework
|
|
85
|
+
```bash
|
|
86
|
+
forge test
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Automated Test Generation:**
|
|
90
|
+
- ๐งช **Comprehensive Coverage**: Program initialization, all instructions, edge cases
|
|
91
|
+
- ๐ **Security Testing**: Access control validation, error condition handling
|
|
92
|
+
- ๐ฐ **Token Operations**: SPL token transfer, mint, burn functionality
|
|
93
|
+
- ๐ฏ **PDA Validation**: Proper derived address generation and validation
|
|
94
|
+
- โก **Performance Tests**: Gas usage analysis, large data handling
|
|
95
|
+
|
|
96
|
+
**Generated Test Suite Includes:**
|
|
97
|
+
- โ
Program initialization and IDL validation
|
|
98
|
+
- โ
All instruction handlers with sensible defaults
|
|
99
|
+
- โ
Token program integration tests
|
|
100
|
+
- โ
PDA derivation correctness
|
|
101
|
+
- โ
Error condition testing
|
|
102
|
+
- โ
Access control enforcement
|
|
103
|
+
|
|
84
104
|
### Update FORGE
|
|
85
105
|
```bash
|
|
86
106
|
forge update
|
|
@@ -107,6 +127,7 @@ FORGE transforms natural language intents into production-ready Solana programs.
|
|
|
107
127
|
|
|
108
128
|
### Core Features
|
|
109
129
|
- โ
**Intent-Driven Generation**: `"transfer 100 tokens safely"` โ Modern CPI code
|
|
130
|
+
- โ
**Automated Testing Framework**: Comprehensive test suites with security validation
|
|
110
131
|
- โ
**Multi-Environment Deployment**: Deploy to devnet/mainnet/localnet with safety checks
|
|
111
132
|
- โ
**Security Audit Tools**: Automated security analysis and best practices validation
|
|
112
133
|
- โ
**Complete Anchor Workspace**: Ready-to-build projects with proper structure
|
package/dist/cli.js
CHANGED
|
@@ -8,6 +8,7 @@ const deploy_js_1 = require("./commands/deploy.js");
|
|
|
8
8
|
const status_js_1 = require("./commands/status.js");
|
|
9
9
|
const generate_sdk_js_1 = require("./commands/generate-sdk.js");
|
|
10
10
|
const audit_js_1 = require("./commands/audit.js");
|
|
11
|
+
const test_js_1 = require("./commands/test.js");
|
|
11
12
|
const program = new commander_1.Command();
|
|
12
13
|
program
|
|
13
14
|
.name('forge')
|
|
@@ -34,6 +35,12 @@ program
|
|
|
34
35
|
.action(async () => {
|
|
35
36
|
await (0, audit_js_1.auditCommand)();
|
|
36
37
|
});
|
|
38
|
+
program
|
|
39
|
+
.command('test')
|
|
40
|
+
.description('Generate and run comprehensive test suite')
|
|
41
|
+
.action(async () => {
|
|
42
|
+
await (0, test_js_1.testCommand)();
|
|
43
|
+
});
|
|
37
44
|
program
|
|
38
45
|
.command('generate-sdk [outputDir]')
|
|
39
46
|
.description('Generate TypeScript SDK from Anchor program')
|
|
@@ -58,6 +65,7 @@ program.on('--help', () => {
|
|
|
58
65
|
console.log('\nCommands:');
|
|
59
66
|
console.log(' init Create new Anchor projects');
|
|
60
67
|
console.log(' audit Run security audit on program');
|
|
68
|
+
console.log(' test Generate and run comprehensive tests');
|
|
61
69
|
console.log(' deploy Deploy to Solana network');
|
|
62
70
|
console.log(' generate-sdk Generate TypeScript SDK from program');
|
|
63
71
|
console.log(' status Check environment & versions');
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,yCAAkC;AAClC,gDAAiD;AACjD,oDAAqD;AACrD,oDAAoE;AACpE,gEAAgE;AAChE,kDAAmD;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"AAWA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA4BjD"}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.testCommand = testCommand;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const child_process_1 = require("child_process");
|
|
7
|
+
async function testCommand() {
|
|
8
|
+
console.log('๐งช FORGE Testing Framework\n');
|
|
9
|
+
try {
|
|
10
|
+
// Check if we're in an Anchor project
|
|
11
|
+
if (!(0, fs_1.existsSync)('Anchor.toml')) {
|
|
12
|
+
console.error('โ Not in an Anchor project directory');
|
|
13
|
+
console.error('Run "forge init" first or cd into your project');
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
console.log('๐ Analyzing program structure...');
|
|
17
|
+
const programStructure = await analyzeProgram();
|
|
18
|
+
console.log('๐ Generating test suite...');
|
|
19
|
+
await generateTestSuite(programStructure);
|
|
20
|
+
console.log('๐ฆ Installing test dependencies...');
|
|
21
|
+
await installTestDeps();
|
|
22
|
+
console.log('๐ Running tests...');
|
|
23
|
+
await runTests();
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
console.error('โ Test generation failed');
|
|
27
|
+
console.error(`Error: ${error.message}`);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function analyzeProgram() {
|
|
32
|
+
const structure = {
|
|
33
|
+
instructions: [],
|
|
34
|
+
accounts: [],
|
|
35
|
+
hasTokenProgram: false,
|
|
36
|
+
hasSystemProgram: false,
|
|
37
|
+
hasAssociatedToken: false,
|
|
38
|
+
pdas: [],
|
|
39
|
+
};
|
|
40
|
+
try {
|
|
41
|
+
// Find and analyze Rust program files
|
|
42
|
+
const { glob } = require('glob');
|
|
43
|
+
const rustFiles = await glob('programs/**/*.rs');
|
|
44
|
+
for (const file of rustFiles) {
|
|
45
|
+
const content = (0, fs_1.readFileSync)(file, 'utf8');
|
|
46
|
+
// Extract instruction handlers
|
|
47
|
+
const instructionMatches = content.match(/pub fn (\w+)\(/g);
|
|
48
|
+
if (instructionMatches) {
|
|
49
|
+
structure.instructions.push(...instructionMatches.map(match => match.replace('pub fn ', '').replace('(', '')));
|
|
50
|
+
}
|
|
51
|
+
// Check for program dependencies
|
|
52
|
+
if (content.includes('anchor_spl::token')) {
|
|
53
|
+
structure.hasTokenProgram = true;
|
|
54
|
+
}
|
|
55
|
+
if (content.includes('system_program')) {
|
|
56
|
+
structure.hasSystemProgram = true;
|
|
57
|
+
}
|
|
58
|
+
if (content.includes('associated_token')) {
|
|
59
|
+
structure.hasAssociatedToken = true;
|
|
60
|
+
}
|
|
61
|
+
// Extract PDA definitions
|
|
62
|
+
const pdaMatches = content.match(/seeds\s*=\s*\[([^]]*)\]/g);
|
|
63
|
+
if (pdaMatches) {
|
|
64
|
+
structure.pdas.push(...pdaMatches);
|
|
65
|
+
}
|
|
66
|
+
// Extract account structs
|
|
67
|
+
const accountMatches = content.match(/#\s*\[account\]\s+pub struct (\w+)/g);
|
|
68
|
+
if (accountMatches) {
|
|
69
|
+
structure.accounts.push(...accountMatches.map(match => match.replace('#[account]\n pub struct ', '')));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.warn(`โ ๏ธ Could not fully analyze program: ${error}`);
|
|
75
|
+
}
|
|
76
|
+
return structure;
|
|
77
|
+
}
|
|
78
|
+
async function generateTestSuite(structure) {
|
|
79
|
+
const testsDir = (0, path_1.join)('tests');
|
|
80
|
+
const testFile = (0, path_1.join)(testsDir, 'forge-generated.ts');
|
|
81
|
+
let testContent = `import * as anchor from "@coral-xyz/anchor";
|
|
82
|
+
import { Program } from "@coral-xyz/anchor";
|
|
83
|
+
import { ${getProgramName()} } from "../target/types/${getProgramName()}";
|
|
84
|
+
import { expect } from "chai";
|
|
85
|
+
import { PublicKey, Keypair, SystemProgram } from "@solana/web3.js";
|
|
86
|
+
${structure.hasTokenProgram ? 'import { TOKEN_PROGRAM_ID, createMint, createAccount, mintTo } from "@solana/spl-token";' : ''}
|
|
87
|
+
${structure.hasAssociatedToken ? 'import { getAssociatedTokenAddress, createAssociatedTokenAccount } from "@solana/spl-token";' : ''}
|
|
88
|
+
|
|
89
|
+
describe("${getProgramName()} - FORGE Generated Tests", () => {
|
|
90
|
+
// Configure the client to use the local cluster.
|
|
91
|
+
const provider = anchor.AnchorProvider.env();
|
|
92
|
+
anchor.setProvider(provider);
|
|
93
|
+
|
|
94
|
+
const program = anchor.workspace.${getProgramName()} as Program<${getProgramName()}>;
|
|
95
|
+
|
|
96
|
+
let user: Keypair;
|
|
97
|
+
let user2: Keypair;
|
|
98
|
+
${structure.hasTokenProgram ? 'let mint: PublicKey;\n let userTokenAccount: PublicKey;\n let user2TokenAccount: PublicKey;' : ''}
|
|
99
|
+
|
|
100
|
+
before(async () => {
|
|
101
|
+
user = Keypair.generate();
|
|
102
|
+
user2 = Keypair.generate();
|
|
103
|
+
|
|
104
|
+
// Airdrop SOL to users
|
|
105
|
+
await provider.connection.confirmTransaction(
|
|
106
|
+
await provider.connection.requestAirdrop(user.publicKey, 2 * anchor.web3.LAMPORTS_PER_SOL)
|
|
107
|
+
);
|
|
108
|
+
await provider.connection.confirmTransaction(
|
|
109
|
+
await provider.connection.requestAirdrop(user2.publicKey, 2 * anchor.web3.LAMPORTS_PER_SOL)
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
${structure.hasTokenProgram ? `
|
|
113
|
+
// Create mint and token accounts for testing
|
|
114
|
+
mint = await createMint(
|
|
115
|
+
provider.connection,
|
|
116
|
+
user,
|
|
117
|
+
user.publicKey,
|
|
118
|
+
user.publicKey,
|
|
119
|
+
9
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
userTokenAccount = await createAssociatedTokenAccount(
|
|
123
|
+
provider.connection,
|
|
124
|
+
user,
|
|
125
|
+
mint,
|
|
126
|
+
user.publicKey
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
user2TokenAccount = await createAssociatedTokenAccount(
|
|
130
|
+
provider.connection,
|
|
131
|
+
user,
|
|
132
|
+
mint,
|
|
133
|
+
user2.publicKey
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
// Mint initial tokens
|
|
137
|
+
await mintTo(
|
|
138
|
+
provider.connection,
|
|
139
|
+
user,
|
|
140
|
+
mint,
|
|
141
|
+
userTokenAccount,
|
|
142
|
+
user,
|
|
143
|
+
1000000000 // 1 token
|
|
144
|
+
);` : ''}
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe("Program Initialization", () => {
|
|
148
|
+
it("Should initialize program state", async () => {
|
|
149
|
+
// Basic initialization test
|
|
150
|
+
expect(program.programId).to.be.instanceOf(PublicKey);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it("Should have valid IDL", async () => {
|
|
154
|
+
const idl = program.idl;
|
|
155
|
+
expect(idl).to.exist;
|
|
156
|
+
expect(idl.instructions).to.be.an('array');
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
${structure.instructions.map((instruction) => `
|
|
161
|
+
describe("${instruction} instruction", () => {
|
|
162
|
+
it("Should execute ${instruction} successfully", async () => {
|
|
163
|
+
// TODO: Implement specific test logic for ${instruction}
|
|
164
|
+
// This is a template - customize based on your instruction requirements
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
const tx = await program.methods
|
|
168
|
+
.${instruction}(${getDefaultParams(instruction)})
|
|
169
|
+
.accounts({
|
|
170
|
+
${getDefaultAccounts(instruction, structure)}
|
|
171
|
+
})
|
|
172
|
+
.signers([user])
|
|
173
|
+
.rpc();
|
|
174
|
+
|
|
175
|
+
// Verify transaction success
|
|
176
|
+
const txInfo = await provider.connection.getTransaction(tx);
|
|
177
|
+
expect(txInfo).to.exist;
|
|
178
|
+
expect(txInfo?.meta?.err).to.be.null;
|
|
179
|
+
|
|
180
|
+
} catch (error) {
|
|
181
|
+
// If instruction is not implemented yet, this is expected
|
|
182
|
+
console.log(\`โ ๏ธ ${instruction} not yet implemented - skipping test\`);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it("Should reject ${instruction} with invalid inputs", async () => {
|
|
187
|
+
// TODO: Test error conditions
|
|
188
|
+
// This tests that the program properly validates inputs
|
|
189
|
+
});
|
|
190
|
+
});`).join('\n')}
|
|
191
|
+
|
|
192
|
+
${structure.hasTokenProgram ? `
|
|
193
|
+
describe("Token Operations", () => {
|
|
194
|
+
it("Should handle token transfers correctly", async () => {
|
|
195
|
+
// Test token transfer functionality if applicable
|
|
196
|
+
const initialBalance = await provider.connection.getTokenAccountBalance(userTokenAccount);
|
|
197
|
+
|
|
198
|
+
// Perform token operation
|
|
199
|
+
// TODO: Add specific token transfer test
|
|
200
|
+
|
|
201
|
+
const finalBalance = await provider.connection.getTokenAccountBalance(userTokenAccount);
|
|
202
|
+
expect(finalBalance.value.uiAmount).to.be.at.most(initialBalance.value.uiAmount!);
|
|
203
|
+
});
|
|
204
|
+
});` : ''}
|
|
205
|
+
|
|
206
|
+
describe("Access Control", () => {
|
|
207
|
+
it("Should reject unauthorized operations", async () => {
|
|
208
|
+
// Test that program properly enforces access controls
|
|
209
|
+
try {
|
|
210
|
+
// Attempt operation with wrong signer
|
|
211
|
+
// This should fail
|
|
212
|
+
expect.fail("Expected operation to be rejected");
|
|
213
|
+
} catch (error: any) {
|
|
214
|
+
// Expected to fail
|
|
215
|
+
expect(error.message).to.include("Error");
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
describe("PDA Derivation", () => {
|
|
221
|
+
${structure.pdas.map((pda, index) => `
|
|
222
|
+
it("Should derive PDA ${index + 1} correctly", async () => {
|
|
223
|
+
const [pdaAddress, bump] = PublicKey.findProgramAddressSync(
|
|
224
|
+
${pda},
|
|
225
|
+
program.programId
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
expect(pdaAddress).to.be.instanceOf(PublicKey);
|
|
229
|
+
expect(bump).to.be.a('number');
|
|
230
|
+
expect(bump).to.be.greaterThan(0);
|
|
231
|
+
expect(bump).to.be.lessThan(256);
|
|
232
|
+
});`).join('\n')}
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
describe("Edge Cases", () => {
|
|
236
|
+
it("Should handle zero values appropriately", async () => {
|
|
237
|
+
// Test division by zero, empty arrays, etc.
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it("Should handle maximum values", async () => {
|
|
241
|
+
// Test u64::MAX, maximum token amounts, etc.
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
`;
|
|
246
|
+
// Write test file
|
|
247
|
+
if (!(0, fs_1.existsSync)(testsDir)) {
|
|
248
|
+
(0, child_process_1.execSync)(`mkdir -p ${testsDir}`);
|
|
249
|
+
}
|
|
250
|
+
(0, fs_1.writeFileSync)(testFile, testContent);
|
|
251
|
+
console.log(`โ
Generated comprehensive test suite: ${testFile}`);
|
|
252
|
+
}
|
|
253
|
+
async function installTestDeps() {
|
|
254
|
+
try {
|
|
255
|
+
// Check if package.json exists and add test dependencies if needed
|
|
256
|
+
if ((0, fs_1.existsSync)('package.json')) {
|
|
257
|
+
const packageJson = JSON.parse((0, fs_1.readFileSync)('package.json', 'utf8'));
|
|
258
|
+
const testDeps = {
|
|
259
|
+
"chai": "^4.3.7",
|
|
260
|
+
"@types/chai": "^4.3.5",
|
|
261
|
+
"mocha": "^10.2.0",
|
|
262
|
+
"@types/mocha": "^10.0.1"
|
|
263
|
+
};
|
|
264
|
+
let needsInstall = false;
|
|
265
|
+
for (const [dep, version] of Object.entries(testDeps)) {
|
|
266
|
+
if (!packageJson.devDependencies?.[dep]) {
|
|
267
|
+
if (!packageJson.devDependencies)
|
|
268
|
+
packageJson.devDependencies = {};
|
|
269
|
+
packageJson.devDependencies[dep] = version;
|
|
270
|
+
needsInstall = true;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (needsInstall) {
|
|
274
|
+
(0, fs_1.writeFileSync)('package.json', JSON.stringify(packageJson, null, 2));
|
|
275
|
+
(0, child_process_1.execSync)('npm install', { stdio: 'inherit' });
|
|
276
|
+
console.log('โ
Installed test dependencies');
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
console.warn(`โ ๏ธ Could not install test dependencies: ${error}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
async function runTests() {
|
|
285
|
+
try {
|
|
286
|
+
console.log('Running Anchor tests...');
|
|
287
|
+
(0, child_process_1.execSync)('anchor test', { stdio: 'inherit' });
|
|
288
|
+
console.log('โ
All tests passed!');
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
console.error('โ Some tests failed');
|
|
292
|
+
console.error('Check the output above for details');
|
|
293
|
+
process.exit(1);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
function getProgramName() {
|
|
297
|
+
try {
|
|
298
|
+
const anchorToml = (0, fs_1.readFileSync)('Anchor.toml', 'utf8');
|
|
299
|
+
const match = anchorToml.match(/name\s*=\s*"([^"]+)"/);
|
|
300
|
+
return match ? match[1] : 'my-program';
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
return 'my-program';
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
function getDefaultParams(instruction) {
|
|
307
|
+
// Generate sensible default parameters based on instruction name
|
|
308
|
+
if (instruction.includes('transfer'))
|
|
309
|
+
return 'new anchor.BN(1000)';
|
|
310
|
+
if (instruction.includes('mint'))
|
|
311
|
+
return 'new anchor.BN(1000000)';
|
|
312
|
+
if (instruction.includes('burn'))
|
|
313
|
+
return 'new anchor.BN(1000)';
|
|
314
|
+
if (instruction.includes('initialize'))
|
|
315
|
+
return '';
|
|
316
|
+
return '/* TODO: Add parameters */';
|
|
317
|
+
}
|
|
318
|
+
function getDefaultAccounts(instruction, structure) {
|
|
319
|
+
let accounts = '';
|
|
320
|
+
if (instruction.includes('transfer') && structure.hasTokenProgram) {
|
|
321
|
+
accounts = `
|
|
322
|
+
from: userTokenAccount,
|
|
323
|
+
to: user2TokenAccount,
|
|
324
|
+
authority: user.publicKey,`;
|
|
325
|
+
}
|
|
326
|
+
accounts += `
|
|
327
|
+
user: user.publicKey,
|
|
328
|
+
systemProgram: SystemProgram.programId,`;
|
|
329
|
+
if (structure.hasTokenProgram) {
|
|
330
|
+
accounts += `
|
|
331
|
+
tokenProgram: TOKEN_PROGRAM_ID,`;
|
|
332
|
+
}
|
|
333
|
+
return accounts;
|
|
334
|
+
}
|
|
335
|
+
//# sourceMappingURL=test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "forge-solana-sdk",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.3",
|
|
4
4
|
"description": "FORGE - Intent-driven app assembly on Solana",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -39,6 +39,10 @@
|
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "^20",
|
|
42
|
-
"typescript": "^5"
|
|
42
|
+
"typescript": "^5",
|
|
43
|
+
"chai": "^4.3.7",
|
|
44
|
+
"@types/chai": "^4.3.5",
|
|
45
|
+
"mocha": "^10.2.0",
|
|
46
|
+
"@types/mocha": "^10.0.1"
|
|
43
47
|
}
|
|
44
48
|
}
|