npm cli app

This commit is contained in:
ngoc 2026-01-26 04:15:56 +07:00
parent b62a25c5eb
commit aed85dff72
No known key found for this signature in database
GPG Key ID: 51FE6110113A5C32
12 changed files with 564 additions and 235 deletions

52
.npmignore Normal file
View File

@ -0,0 +1,52 @@
# Source files (only compiled JS will be included)
*.ts
!*.d.ts
# Tests
tests/
**/*.test.ts
**/*.test.js
# Build config
tsconfig.json
tsconfig.build.json
bun.lockb
# Development
.env
.env.*
!.env.example
# Logs
*.log
anvil.log
.anvil.pid
# IDE
.vscode/
.idea/
*.swp
*.swo
# OS
.DS_Store
Thumbs.db
# Git
.git/
.gitignore
# CI/CD
.github/
# Documentation (keep README.md)
docs/
# Deployments
deployments/
# Node modules (will be installed by user)
node_modules/
# Parent directory references
../

173
INSTALL.md Normal file
View File

@ -0,0 +1,173 @@
# Installing NLA CLI Globally
## Prerequisites
- Node.js >= 18.0.0
- npm or yarn or pnpm
- A blockchain node (local Anvil or remote RPC URL)
- At least one LLM provider API key (OpenAI, Anthropic, or OpenRouter)
## Installation
### Global Installation (Recommended)
Install the NLA CLI globally to use it from anywhere:
```bash
npm install -g nla
```
Or with yarn:
```bash
yarn global add nla
```
Or with pnpm:
```bash
pnpm add -g nla
```
### Verify Installation
```bash
nla --help
```
## Configuration
Create a `.env` file in your project directory:
```bash
# Copy the example environment file
cp node_modules/nla/.env.example .env
# Edit with your configuration
nano .env
```
Required environment variables:
```bash
# At least one LLM provider API key
OPENAI_API_KEY=sk-...
# OR
ANTHROPIC_API_KEY=sk-ant-...
# OR
OPENROUTER_API_KEY=sk-or-...
# Oracle configuration
ORACLE_PRIVATE_KEY=0x...
RPC_URL=http://localhost:8545
# Optional: For enhanced search
PERPLEXITY_API_KEY=pplx-...
```
## Quick Start
### 1. Start Development Environment
```bash
nla dev
```
This will:
- Start Anvil (local blockchain)
- Deploy all contracts
- Start the oracle
### 2. Create an Escrow
```bash
nla escrow:create \
--demand "The sky is blue" \
--amount 10 \
--token 0xa513E6E4b8f2a923D98304ec87F64353C4D5C853 \
--oracle 0x70997970C51812dc3A010C7d01b50e0d17dc79C8
```
### 3. Fulfill an Escrow
```bash
nla escrow:fulfill \
--escrow-uid 0x... \
--fulfillment "The sky appears blue today" \
--oracle 0x70997970C51812dc3A010C7d01b50e0d17dc79C8
```
### 4. Collect Payment
```bash
nla escrow:collect \
--escrow-uid 0x... \
--fulfillment-uid 0x...
```
## Uninstallation
```bash
npm uninstall -g nla
```
## Development
If you want to contribute or modify the CLI:
```bash
# Clone the repository
git clone https://github.com/arkhai-io/natural-language-agreements.git
cd natural-language-agreements
# Install dependencies
npm install
# Build
npm run build
# Link locally
npm link
```
## Troubleshooting
### Command not found after installation
Make sure your npm global bin directory is in your PATH:
```bash
# Check npm global bin path
npm bin -g
# Add to PATH (add to ~/.bashrc or ~/.zshrc)
export PATH="$(npm bin -g):$PATH"
```
### Permission errors on Linux/Mac
If you get permission errors, either:
1. Use a Node version manager (recommended):
```bash
# Install nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# Install and use Node
nvm install 18
nvm use 18
# Now install without sudo
npm install -g nla
```
2. Or configure npm to use a different directory:
```bash
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
```
## Support
For issues and questions:
- GitHub: https://github.com/arkhai-io/natural-language-agreements/issues
- Documentation: https://github.com/arkhai-io/natural-language-agreements

207
cli/commands/dev.ts Normal file
View File

@ -0,0 +1,207 @@
import { spawn, spawnSync } from "child_process";
import { existsSync, readFileSync, writeFileSync, createWriteStream, unlinkSync } from "fs";
import { join } from "path";
// Colors for console output
const colors = {
green: '\x1b[32m',
blue: '\x1b[34m',
red: '\x1b[31m',
yellow: '\x1b[33m',
reset: '\x1b[0m'
};
// Load .env file if it exists
function loadEnvFile() {
const envPath = '.env';
if (existsSync(envPath)) {
console.log(`${colors.blue}📄 Loading .env file...${colors.reset}`);
const envContent = readFileSync(envPath, 'utf-8');
const lines = envContent.split('\n');
for (const line of lines) {
// Skip comments and empty lines
if (line.trim().startsWith('#') || !line.trim()) continue;
// Parse key=value
const match = line.match(/^([^=]+)=(.*)$/);
if (match) {
const key = match[1].trim();
const value = match[2].trim();
// Only set if not already in environment
if (!process.env[key]) {
process.env[key] = value;
}
}
}
console.log(`${colors.green}✅ Environment variables loaded${colors.reset}`);
}
}
// Helper to check if a command exists
function commandExists(command: string): boolean {
try {
const result = spawnSync(process.platform === 'win32' ? 'where' : 'which', [command], {
stdio: 'pipe'
});
return result.status === 0;
} catch {
return false;
}
}
// Helper to check if a port is in use
function isPortInUse(port: number): boolean {
try {
const result = spawnSync('lsof', ['-Pi', `:${port}`, '-sTCP:LISTEN', '-t'], {
stdio: 'pipe'
});
return result.status === 0;
} catch {
return false;
}
}
// Dev command - Start complete development environment
export async function runDevCommand(cliDir: string) {
console.log(`${colors.blue}════════════════════════════════════════════════════════${colors.reset}`);
console.log(`${colors.blue} Natural Language Agreement Oracle - Quick Setup${colors.reset}`);
console.log(`${colors.blue}════════════════════════════════════════════════════════${colors.reset}\n`);
// Load .env file first
loadEnvFile();
console.log('');
// Check prerequisites
console.log(`${colors.blue}📋 Checking prerequisites...${colors.reset}\n`);
// Check Bun
if (!commandExists('bun')) {
console.error(`${colors.red}❌ Bun is not installed${colors.reset}`);
console.log('Please install it: https://bun.sh');
process.exit(1);
}
console.log(`${colors.green}✅ Bun installed${colors.reset}`);
// Check Foundry
if (!commandExists('forge')) {
console.error(`${colors.red}❌ Foundry (forge) is not installed${colors.reset}`);
console.log('Please install it: https://book.getfoundry.sh/getting-started/installation');
process.exit(1);
}
console.log(`${colors.green}✅ Foundry installed${colors.reset}`);
// Check Anvil
if (!commandExists('anvil')) {
console.error(`${colors.red}❌ Anvil is not installed${colors.reset}`);
console.log('Please install Foundry: https://book.getfoundry.sh/getting-started/installation');
process.exit(1);
}
console.log(`${colors.green}✅ Anvil installed${colors.reset}`);
// Check LLM API keys
const hasOpenAI = !!process.env.OPENAI_API_KEY;
const hasAnthropic = !!process.env.ANTHROPIC_API_KEY;
const hasOpenRouter = !!process.env.OPENROUTER_API_KEY;
const hasPerplexity = !!process.env.PERPLEXITY_API_KEY;
if (!hasOpenAI && !hasAnthropic && !hasOpenRouter && !hasPerplexity) {
console.error(`${colors.red}❌ No LLM provider API key set${colors.reset}`);
console.log('Please add at least one API key to your environment:');
console.log(' export OPENAI_API_KEY=sk-...');
console.log(' export ANTHROPIC_API_KEY=sk-ant-...');
console.log(' export OPENROUTER_API_KEY=sk-or-...');
process.exit(1);
}
if (hasOpenAI) console.log(`${colors.green}✅ OpenAI API key configured${colors.reset}`);
if (hasAnthropic) console.log(`${colors.green}✅ Anthropic API key configured${colors.reset}`);
if (hasOpenRouter) console.log(`${colors.green}✅ OpenRouter API key configured${colors.reset}`);
if (hasPerplexity) console.log(`${colors.green}✅ Perplexity API key configured${colors.reset}`);
console.log('');
// Check if Anvil is already running
if (isPortInUse(8545)) {
console.log(`${colors.yellow}⚠️ Anvil is already running on port 8545${colors.reset}`);
console.log(`${colors.blue}Using existing Anvil instance${colors.reset}\n`);
} else {
// Start Anvil
console.log(`${colors.blue}🔨 Starting Anvil...${colors.reset}`);
const anvilProcess = spawn('anvil', [], {
stdio: ['ignore', 'pipe', 'pipe'],
detached: true
});
// Save PID
writeFileSync('.anvil.pid', anvilProcess.pid!.toString());
// Redirect output to log file
const logStream = createWriteStream('anvil.log', { flags: 'a' });
anvilProcess.stdout?.pipe(logStream);
anvilProcess.stderr?.pipe(logStream);
anvilProcess.unref();
console.log(`${colors.green}✅ Anvil started (PID: ${anvilProcess.pid})${colors.reset}`);
console.log(' Logs: tail -f anvil.log');
// Wait for Anvil to be ready
await new Promise(resolve => setTimeout(resolve, 3000));
}
// Deploy contracts
console.log(`\n${colors.blue}📝 Deploying contracts...${colors.reset}\n`);
const deployScript = join(cliDir, 'server', 'deploy.js');
const deployResult = spawnSync('bun', ['run', deployScript, '--network', 'localhost', '--rpc-url', 'http://localhost:8545'], {
stdio: 'inherit',
cwd: process.cwd()
});
if (deployResult.status !== 0) {
console.error(`${colors.red}❌ Deployment failed${colors.reset}`);
process.exit(1);
}
// Start oracle
console.log(`\n${colors.blue}🚀 Starting oracle...${colors.reset}\n`);
const oracleScript = join(cliDir, 'server', 'oracle.js');
const deploymentFile = join(cliDir, 'deployments', 'localhost.json');
const oracleProcess = spawn('bun', ['run', oracleScript, '--deployment', deploymentFile], {
stdio: 'inherit',
cwd: process.cwd()
});
// Handle cleanup on exit
const cleanup = () => {
console.log(`\n${colors.yellow}🛑 Shutting down...${colors.reset}`);
// Kill oracle
oracleProcess.kill();
// Kill Anvil
try {
const pidFile = '.anvil.pid';
if (existsSync(pidFile)) {
const pid = readFileSync(pidFile, 'utf-8').trim();
try {
process.kill(parseInt(pid));
console.log(`${colors.green}✅ Anvil stopped${colors.reset}`);
} catch (e) {
// Process might already be dead
}
unlinkSync(pidFile);
}
} catch (e) {
// Ignore errors
}
process.exit(0);
};
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);
// Keep process alive
await new Promise(() => {});
}

43
cli/commands/stop.ts Normal file
View File

@ -0,0 +1,43 @@
import { spawnSync } from "child_process";
import { existsSync, readFileSync, unlinkSync } from "fs";
// Colors for console output
const colors = {
green: '\x1b[32m',
yellow: '\x1b[33m',
red: '\x1b[31m',
reset: '\x1b[0m'
};
// Stop command - Stop all services
export async function runStopCommand() {
console.log(`${colors.yellow}🛑 Stopping services...${colors.reset}\n`);
// Stop Anvil
try {
const pidFile = '.anvil.pid';
if (existsSync(pidFile)) {
const pid = readFileSync(pidFile, 'utf-8').trim();
try {
process.kill(parseInt(pid));
console.log(`${colors.green}✅ Anvil stopped${colors.reset}`);
} catch (e) {
console.log(`${colors.yellow}⚠️ Anvil process not found (may have already stopped)${colors.reset}`);
}
unlinkSync(pidFile);
} else {
console.log(`${colors.yellow}⚠️ No Anvil PID file found${colors.reset}`);
}
} catch (e) {
console.error(`${colors.red}❌ Error stopping Anvil:${colors.reset}`, e);
}
// Try to kill any remaining processes on port 8545
try {
spawnSync('pkill', ['-f', 'anvil']);
} catch (e) {
// Ignore
}
console.log(`\n${colors.green}✅ Services stopped${colors.reset}`);
}

View File

@ -1,11 +1,20 @@
#!/usr/bin/env bun
#!/usr/bin/env node
import { parseArgs } from "util";
import { spawnSync } from "child_process";
import { existsSync, readFileSync } from "fs";
import { fileURLToPath } from "url";
import { dirname, join } from "path";
import { createPublicClient, http, parseAbiParameters, decodeAbiParameters } from "viem";
import { foundry } from "viem/chains";
import { contracts } from "alkahest-ts";
import { runDevCommand } from "./commands/dev.js";
import { runStopCommand } from "./commands/stop.js";
// Get the directory name for ESM modules (compatible with both Node and Bun)
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Helper function to display usage
function displayHelp() {
console.log(`
@ -83,7 +92,7 @@ Examples:
// Parse command line arguments
function parseCliArgs() {
const args = Bun.argv.slice(2);
const args = process.argv.slice(2);
if (args.length === 0) {
displayHelp();
@ -120,27 +129,9 @@ function parseCliArgs() {
return { command, ...values };
}
// Shell command handler
async function runShellCommand(scriptName: string, args: string[] = []) {
const { spawnSync } = await import("child_process");
const scriptDir = import.meta.dir;
const scriptPath = `${scriptDir}/scripts/${scriptName}`;
// Run the shell script
const result = spawnSync(scriptPath, args, {
stdio: "inherit",
cwd: process.cwd(),
shell: true,
});
process.exit(result.status || 0);
}
// Server command handler (for deploy.ts, oracle.ts)
async function runServerCommand(scriptName: string, args: string[] = []) {
const { spawnSync } = await import("child_process");
const scriptDir = import.meta.dir;
const scriptPath = `${scriptDir}/server/${scriptName}`;
const scriptPath = join(__dirname, "server", scriptName);
// Run the TypeScript file directly
const result = spawnSync("bun", ["run", scriptPath, ...args], {
@ -157,25 +148,25 @@ async function main() {
const args = parseCliArgs();
const command = args.command;
// Handle shell script commands (dev and stop need shell for process management)
// Handle dev and stop commands
if (command === "dev") {
await runShellCommand("dev.sh");
await runDevCommand(__dirname);
return;
}
if (command === "stop") {
await runShellCommand("stop.sh");
await runStopCommand();
return;
}
// Handle TypeScript commands that can run directly
if (command === "deploy") {
await runServerCommand("deploy.ts", Bun.argv.slice(3));
await runServerCommand("deploy.js", process.argv.slice(3));
return;
}
if (command === "start-oracle") {
await runServerCommand("oracle.ts", Bun.argv.slice(3));
await runServerCommand("oracle.js", process.argv.slice(3));
return;
}
@ -184,13 +175,13 @@ async function main() {
switch (command) {
case "escrow:create":
scriptPath = "./client/create-escrow.ts";
scriptPath = "./client/create-escrow.js";
break;
case "escrow:fulfill":
scriptPath = "./client/fulfill-escrow.ts";
scriptPath = "./client/fulfill-escrow.js";
break;
case "escrow:collect":
scriptPath = "./client/collect-escrow.ts";
scriptPath = "./client/collect-escrow.js";
break;
case "escrow:status":
await runStatusCommand(args);
@ -203,11 +194,10 @@ async function main() {
// Run the command as a subprocess with the args (excluding the command name)
const { spawnSync } = await import("child_process");
const scriptDir = import.meta.dir;
const fullScriptPath = `${scriptDir}/${scriptPath}`;
const fullScriptPath = join(__dirname, scriptPath);
// Build args array without the command name
const commandArgs = Bun.argv.slice(3); // Skip bun, script, and command
const commandArgs = process.argv.slice(3); // Skip node, script, and command
const result = spawnSync("bun", ["run", fullScriptPath, ...commandArgs], {
stdio: "inherit",

View File

@ -1,138 +0,0 @@
#!/bin/bash
# Complete setup and deployment for local development
# This script will:
# 1. Check prerequisites
# 2. Start Anvil
# 3. Deploy contracts
# 4. Start the oracle
set -e
# Colors for output
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${BLUE}════════════════════════════════════════════════════════${NC}"
echo -e "${BLUE} Natural Language Agreement Oracle - Quick Setup${NC}"
echo -e "${BLUE}════════════════════════════════════════════════════════${NC}\n"
# Check prerequisites
echo -e "${BLUE}📋 Checking prerequisites...${NC}\n"
# Load .env file if it exists
if [ -f ".env" ]; then
echo -e "${BLUE}📄 Loading .env file...${NC}"
export $(cat .env | grep -v '^#' | xargs)
echo -e "${GREEN}✅ Environment variables loaded${NC}"
fi
# Check Bun
if ! command -v bun &> /dev/null; then
echo -e "${RED}❌ Bun is not installed${NC}"
echo "Please install it: https://bun.sh"
exit 1
fi
echo -e "${GREEN}✅ Bun installed${NC}"
# Check Foundry
if ! command -v forge &> /dev/null; then
echo -e "${RED}❌ Foundry (forge) is not installed${NC}"
echo "Please install it: https://book.getfoundry.sh/getting-started/installation"
exit 1
fi
echo -e "${GREEN}✅ Foundry installed${NC}"
# Check Anvil
if ! command -v anvil &> /dev/null; then
echo -e "${RED}❌ Anvil is not installed${NC}"
echo "Please install Foundry: https://book.getfoundry.sh/getting-started/installation"
exit 1
fi
echo -e "${GREEN}✅ Anvil installed${NC}"
# Check alkahest
if [ ! -d "../alkahest" ]; then
echo -e "${RED}❌ alkahest repository not found${NC}"
echo "Please clone it in the parent directory:"
echo " cd .. && git clone https://github.com/arkhai-io/alkahest.git"
exit 1
fi
echo -e "${GREEN}✅ alkahest repository found${NC}"
# Check LLM API keys
if [ -z "$OPENAI_API_KEY" ] && [ -z "$ANTHROPIC_API_KEY" ] && [ -z "$OPENROUTER_API_KEY" ]; then
echo -e "${RED}❌ No LLM provider API key set${NC}"
echo "Please add at least one API key to your .env file:"
echo " OPENAI_API_KEY=sk-..."
echo " ANTHROPIC_API_KEY=sk-ant-..."
echo " OPENROUTER_API_KEY=sk-or-..."
exit 1
fi
if [ -n "$OPENAI_API_KEY" ]; then
echo -e "${GREEN}✅ OpenAI API key configured${NC}"
fi
if [ -n "$ANTHROPIC_API_KEY" ]; then
echo -e "${GREEN}✅ Anthropic API key configured${NC}"
fi
if [ -n "$OPENROUTER_API_KEY" ]; then
echo -e "${GREEN}✅ OpenRouter API key configured${NC}"
fi
if [ -n "$PERPLEXITY_API_KEY" ]; then
echo -e "${GREEN}✅ Perplexity API key configured${NC}"
fi
echo ""
# Install dependencies
echo -e "${BLUE}📦 Installing dependencies...${NC}\n"
bun install
# Check if Anvil is already running
if lsof -Pi :8545 -sTCP:LISTEN -t >/dev/null ; then
echo -e "${YELLOW}⚠️ Anvil is already running on port 8545${NC}"
read -p "Do you want to kill it and start fresh? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
pkill -f anvil || true
sleep 2
else
echo -e "${BLUE}Using existing Anvil instance${NC}\n"
fi
fi
# Start Anvil in background if not running
if ! lsof -Pi :8545 -sTCP:LISTEN -t >/dev/null ; then
echo -e "${BLUE}🔨 Starting Anvil...${NC}"
anvil > anvil.log 2>&1 &
ANVIL_PID=$!
echo $ANVIL_PID > .anvil.pid
echo -e "${GREEN}✅ Anvil started (PID: $ANVIL_PID)${NC}"
echo " Logs: tail -f anvil.log"
sleep 3
fi
# Deploy contracts
echo -e "\n${BLUE}📝 Deploying contracts...${NC}\n"
bun run cli/server/deploy.ts --network localhost --rpc-url http://localhost:8545
# Start oracle
echo -e "\n${BLUE}🚀 Starting oracle...${NC}\n"
bun run cli/server/oracle.ts --deployment ./cli/deployments/localhost.json
# Cleanup function
cleanup() {
echo -e "\n${YELLOW}🛑 Shutting down...${NC}"
if [ -f .anvil.pid ]; then
ANVIL_PID=$(cat .anvil.pid)
kill $ANVIL_PID 2>/dev/null || true
rm .anvil.pid
echo -e "${GREEN}✅ Anvil stopped${NC}"
fi
exit 0
}
trap cleanup SIGINT SIGTERM

View File

@ -1,30 +0,0 @@
#!/bin/bash
# Stop all running oracle and Anvil processes
# Colors for output
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${BLUE}🛑 Stopping Natural Language Agreement services...${NC}\n"
# Stop Anvil
if [ -f .anvil.pid ]; then
ANVIL_PID=$(cat .anvil.pid)
if kill -0 $ANVIL_PID 2>/dev/null; then
kill $ANVIL_PID
echo -e "${GREEN}✅ Stopped Anvil (PID: $ANVIL_PID)${NC}"
fi
rm .anvil.pid
else
# Try to kill any running anvil
pkill -f anvil && echo -e "${GREEN}✅ Stopped Anvil${NC}" || echo -e "${YELLOW}⚠️ No Anvil process found${NC}"
fi
# Stop oracle
pkill -f "bun run oracle" && echo -e "${GREEN}✅ Stopped oracle${NC}" || echo -e "${YELLOW}⚠️ No oracle process found${NC}"
echo -e "\n${GREEN}✨ Cleanup complete${NC}"

View File

@ -1,4 +1,4 @@
#!/usr/bin/env bun
#!/usr/bin/env node
/**
* Deployment script for Alkahest Natural Language Agreement Oracle
*
@ -54,7 +54,7 @@ Examples:
// Parse command line arguments
function parseCliArgs() {
const { values } = parseArgs({
args: Bun.argv.slice(2),
args: process.argv.slice(2),
options: {
"network": { type: "string" },
"rpc-url": { type: "string" },

View File

@ -1,4 +1,4 @@
#!/usr/bin/env bun
#!/usr/bin/env node
import { parseArgs } from "util";
import { parseAbiParameters, createWalletClient, http, publicActions } from "viem";
import { privateKeyToAccount } from "viem/accounts";
@ -57,7 +57,7 @@ Examples:
// Parse command line arguments
function parseCliArgs() {
const { values } = parseArgs({
args: Bun.argv.slice(2),
args: process.argv.slice(2),
options: {
"rpc-url": { type: "string" },
"private-key": { type: "string" },

View File

@ -1,15 +1,45 @@
{
"name": "natural-language-agreement-extension",
"module": "index.ts",
"name": "nla",
"version": "1.0.0",
"description": "Natural Language Agreement Oracle - CLI for creating and managing blockchain agreements using natural language",
"type": "module",
"private": true,
"devDependencies": {
"@types/bun": "latest"
"private": false,
"author": "Arkhai",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/arkhai-io/natural-language-agreements.git"
},
"keywords": [
"blockchain",
"ethereum",
"smart-contracts",
"natural-language",
"oracle",
"ai",
"llm",
"escrow"
],
"bin": {
"nla": "cli/index.ts"
"nla": "./dist/cli/index.js"
},
"files": [
"dist/**/*",
"README.md",
".env.example"
],
"engines": {
"node": ">=18.0.0"
},
"preferGlobal": true,
"devDependencies": {
"@types/bun": "latest",
"@types/node": "^20.0.0",
"typescript": "^5.9.3"
},
"scripts": {
"build": "tsc --project tsconfig.build.json",
"prepublishOnly": "npm run build",
"dev": "bun run index.ts",
"start": "bun run index.ts",
"test": "bun test ./tests --exclude alkahest-ts/** ",

16
tsconfig.build.json Normal file
View File

@ -0,0 +1,16 @@
{
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./",
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"esModuleInterop": true,
"skipLibCheck": true,
"strict": true,
"resolveJsonModule": true
},
"include": ["cli/**/*"],
"exclude": ["node_modules", "tests", "dist"]
}

View File

@ -1,30 +1,16 @@
{
"compilerOptions": {
// Environment setup & latest features
"lib": ["ESNext"],
"target": "ESNext",
"module": "Preserve",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,
"outDir": "dist",
"rootDir": ".",
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
// Bundler mode
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
// Best practices
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
// Some stricter flags (disabled by default)
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false,
}
"skipLibCheck": true
},
"include": [
"cli/**/*"
]
}