From maintainx-pack
Sets up TypeScript/Node.js local dev environment for MaintainX API integrations with tsx hot reload, Vitest unit tests, axios mocks, and project scaffolding.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin maintainx-packThis skill is limited to using the following tools:
Set up an efficient local development workflow for building and testing MaintainX integrations with hot reload, mock servers, and automated testing.
Sets up MaintainX REST API authentication: generates keys, configures env vars, installs TypeScript Axios client for work orders/assets/locations. For CMMS integrations.
Sets up local dev workflow for Miro API v2 integrations with TypeScript hot reload via tsx, Vitest testing using fixtures, and ngrok webhook tunneling.
Sets up Node.js/TypeScript dev environment for Mistral AI with tsx hot reload, Vitest unit/integration tests including mocking, and dotenv env config.
Share bugs, ideas, or general feedback.
Set up an efficient local development workflow for building and testing MaintainX integrations with hot reload, mock servers, and automated testing.
maintainx-install-auth setupMAINTAINX_API_KEY environment variable setmkdir maintainx-integration && cd maintainx-integration
npm init -y
npm install axios dotenv
npm install -D typescript tsx vitest @types/node
npx tsc --init --target ES2022 --module NodeNext --moduleResolution nodenext --outDir dist
Create tsconfig.json paths:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "nodenext",
"outDir": "dist",
"strict": true,
"esModuleInterop": true
},
"include": ["src/**/*"]
}
maintainx-integration/
├── src/
│ ├── client.ts # MaintainX API client (from install-auth)
│ ├── work-orders.ts # Work order service layer
│ └── sync.ts # Data sync logic
├── tests/
│ ├── client.test.ts # Unit tests with mocks
│ └── integration.test.ts # Live API tests
├── .env # MAINTAINX_API_KEY=...
├── .env.example # MAINTAINX_API_KEY=your-key-here
├── package.json
└── tsconfig.json
{
"scripts": {
"dev": "tsx watch src/index.ts",
"test": "vitest run",
"test:watch": "vitest",
"test:integration": "INTEGRATION=true vitest run tests/integration.test.ts",
"build": "tsc",
"repl": "tsx src/repl.ts"
}
}
// tests/client.test.ts
import { describe, it, expect, vi, beforeEach } from 'vitest';
import axios from 'axios';
vi.mock('axios');
describe('MaintainXClient', () => {
beforeEach(() => {
vi.resetAllMocks();
process.env.MAINTAINX_API_KEY = 'test-key-123';
});
it('creates a work order', async () => {
const mockResponse = {
data: { id: 1, title: 'Test WO', status: 'OPEN' },
};
vi.mocked(axios.create).mockReturnValue({
post: vi.fn().mockResolvedValue(mockResponse),
interceptors: { response: { use: vi.fn() } },
} as any);
const { MaintainXClient } = await import('../src/client');
const client = new MaintainXClient();
const result = await client.createWorkOrder({ title: 'Test WO' });
expect(result.data.title).toBe('Test WO');
expect(result.data.status).toBe('OPEN');
});
it('paginates work orders', async () => {
const page1 = { data: { workOrders: [{ id: 1 }], cursor: 'abc' } };
const page2 = { data: { workOrders: [{ id: 2 }], cursor: null } };
const getMock = vi.fn()
.mockResolvedValueOnce(page1)
.mockResolvedValueOnce(page2);
vi.mocked(axios.create).mockReturnValue({
get: getMock,
interceptors: { response: { use: vi.fn() } },
} as any);
const { MaintainXClient } = await import('../src/client');
const client = new MaintainXClient();
const all = [];
let cursor: string | undefined;
do {
const { data } = await client.getWorkOrders({ cursor });
all.push(...data.workOrders);
cursor = data.cursor;
} while (cursor);
expect(all).toHaveLength(2);
});
});
// src/repl.ts
import * as repl from 'node:repl';
import 'dotenv/config';
import { MaintainXClient } from './client';
const client = new MaintainXClient();
console.log('MaintainX REPL ready. `client` is available.');
console.log('Try: await client.getWorkOrders({ limit: 3 })');
const r = repl.start({ prompt: 'maintainx> ' });
r.context.client = client;
# Start REPL
npm run repl
# maintainx> const { data } = await client.getWorkOrders({ limit: 3 })
# maintainx> data.workOrders.map(wo => wo.title)
tsx watch for hot reload.env.example template for team onboardingpackage.json| Issue | Solution |
|---|---|
MAINTAINX_API_KEY undefined | Copy .env.example to .env and fill in your key |
| 429 Rate Limited during dev | Add delays between calls, use mocks for unit tests |
| TypeScript import errors | Ensure moduleResolution: "nodenext" in tsconfig |
tsx not found | Install with npm i -D tsx |
For SDK patterns and best practices, see maintainx-sdk-patterns.
Docker-based dev environment:
# Dockerfile.dev
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["npm", "run", "dev"]
# docker-compose.dev.yml
services:
app:
build: { dockerfile: Dockerfile.dev }
env_file: .env
volumes: ["./src:/app/src"]
Run integration tests against live API:
INTEGRATION=true npm run test:integration