mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-08-13 22:37:29 +00:00
Add contract and Playwright PR checks
This commit is contained in:
parent
447974dbba
commit
254233c3ab
11 changed files with 277 additions and 45 deletions
36
.github/workflows/ci.yml
vendored
36
.github/workflows/ci.yml
vendored
|
|
@ -1,7 +1,3 @@
|
||||||
# Managed by sh1pt Actions Fleet
|
|
||||||
# pack: node-pnpm-ci@1.0.0
|
|
||||||
# install: sh1pt-actions-store
|
|
||||||
# hash: sha256:aa7aeaf3bddaf7bf324ceb02f46ab421bb229d5f5917fdb6f7a1a948a4a9fcce
|
|
||||||
name: CI
|
name: CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
|
@ -19,21 +15,31 @@ concurrency:
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 25
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v4
|
- name: Setup Node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
version: 9
|
node-version: 24
|
||||||
|
cache: npm
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- name: Install dependencies
|
||||||
with:
|
run: npm ci
|
||||||
node-version: '22'
|
|
||||||
cache: pnpm
|
|
||||||
|
|
||||||
- run: pnpm install --frozen-lockfile
|
- name: Build and unit tests
|
||||||
|
run: npm run check
|
||||||
|
|
||||||
- run: pnpm typecheck
|
- name: Validate schema fixtures
|
||||||
|
run: npm run schemas:validate
|
||||||
|
|
||||||
- run: pnpm test
|
- name: API contract tests
|
||||||
|
run: npm run test:contract
|
||||||
|
|
||||||
|
- name: Install Playwright browsers
|
||||||
|
run: npx playwright install --with-deps chromium
|
||||||
|
|
||||||
|
- name: Playwright E2E
|
||||||
|
run: npm run test:e2e
|
||||||
|
|
|
||||||
16
.github/workflows/test.yml
vendored
16
.github/workflows/test.yml
vendored
|
|
@ -1,7 +1,3 @@
|
||||||
# Managed by sh1pt Actions Fleet
|
|
||||||
# pack: node-pnpm-test@1.0.0
|
|
||||||
# install: sh1pt-actions-store
|
|
||||||
# hash: sha256:14a3f6fdbc21be92e815a16317251c967e4fbd95a5daf98819e0c23e7d56bf4f
|
|
||||||
name: test
|
name: test
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
|
@ -19,17 +15,13 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v4
|
|
||||||
with:
|
|
||||||
version: 9.12.0
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 22
|
node-version: 24
|
||||||
cache: pnpm
|
cache: npm
|
||||||
|
|
||||||
- run: pnpm install --frozen-lockfile
|
- run: npm ci
|
||||||
|
|
||||||
- run: pnpm test
|
- run: npm test
|
||||||
env:
|
env:
|
||||||
CI: true
|
CI: true
|
||||||
|
|
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -5,5 +5,7 @@ dist
|
||||||
!.env.example
|
!.env.example
|
||||||
.DS_Store
|
.DS_Store
|
||||||
coverage
|
coverage
|
||||||
|
playwright-report
|
||||||
|
test-results
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
.commandboard
|
.commandboard
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc -p tsconfig.json",
|
"build": "tsc -p tsconfig.json",
|
||||||
"dev": "tsx src/index.ts"
|
"dev": "tsx src/index.ts",
|
||||||
|
"test": "vitest run src",
|
||||||
|
"test:contract": "vitest run src/contract.test.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@logicsrc/plugin-core": "file:../../packages/plugin-core",
|
"@logicsrc/plugin-core": "file:../../packages/plugin-core",
|
||||||
|
|
@ -16,6 +18,7 @@
|
||||||
"@logicsrc/validators": "file:../../packages/validators"
|
"@logicsrc/validators": "file:../../packages/validators"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"tsx": "^4.21.0"
|
"tsx": "^4.21.0",
|
||||||
|
"vitest": "^4.0.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
88
apps/commandboard-api/src/contract.test.ts
Normal file
88
apps/commandboard-api/src/contract.test.ts
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
import type { Server } from "node:http";
|
||||||
|
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
||||||
|
import { createCommandBoardServer } from "./index.js";
|
||||||
|
|
||||||
|
let server: Server;
|
||||||
|
let baseUrl: string;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
server = createCommandBoardServer();
|
||||||
|
await new Promise<void>((resolve) => server.listen(0, resolve));
|
||||||
|
const address = server.address();
|
||||||
|
if (!address || typeof address === "string") {
|
||||||
|
throw new Error("Expected API server to bind to a local port");
|
||||||
|
}
|
||||||
|
baseUrl = `http://127.0.0.1:${address.port}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await new Promise<void>((resolve, reject) => {
|
||||||
|
server.close((error) => (error ? reject(error) : resolve()));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("CommandBoard API contracts", () => {
|
||||||
|
it("exposes health contract", async () => {
|
||||||
|
const response = await fetch(`${baseUrl}/health`);
|
||||||
|
const body = await response.json() as { ok: boolean; service: string };
|
||||||
|
|
||||||
|
expect(response.status).toBe(200);
|
||||||
|
expect(body).toEqual({ ok: true, service: "commandboard-api" });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("exposes default plugin contract including sh1pt", async () => {
|
||||||
|
const response = await fetch(`${baseUrl}/api/plugins`);
|
||||||
|
const body = await response.json() as {
|
||||||
|
plugins: Array<{ id: string; enabled: boolean; capabilities: string[] }>;
|
||||||
|
capabilities: Record<string, string[]>;
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(response.status).toBe(200);
|
||||||
|
expect(body.plugins.map((plugin) => plugin.id)).toEqual(["coinpay", "ugig", "sh1pt"]);
|
||||||
|
expect(body.plugins.find((plugin) => plugin.id === "sh1pt")).toMatchObject({
|
||||||
|
enabled: true,
|
||||||
|
capabilities: expect.arrayContaining(["projects.sync", "actions.publish", "deployments.status"])
|
||||||
|
});
|
||||||
|
expect(body.capabilities["actions.publish"]).toEqual(["sh1pt"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("exposes sh1pt project and action contracts", async () => {
|
||||||
|
const projectsResponse = await fetch(`${baseUrl}/api/plugins/sh1pt/projects`);
|
||||||
|
const projectsBody = await projectsResponse.json() as { projects: Array<{ id: string; board: string; status: string; actions: number }> };
|
||||||
|
const actionsResponse = await fetch(`${baseUrl}/api/plugins/sh1pt/actions`);
|
||||||
|
const actionsBody = await actionsResponse.json() as { actions: Array<{ id: string; title: string; publishable: boolean }> };
|
||||||
|
|
||||||
|
expect(projectsResponse.status).toBe(200);
|
||||||
|
expect(projectsBody.projects[0]).toMatchObject({ id: "sh1pt_project_1", board: "/projects/sh1pt", status: "active" });
|
||||||
|
expect(actionsResponse.status).toBe(200);
|
||||||
|
expect(actionsBody.actions[0]).toMatchObject({ id: "action_release_checklist", publishable: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("accepts sh1pt action publish requests", async () => {
|
||||||
|
const response = await fetch(`${baseUrl}/api/plugins/sh1pt/actions/publish`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "content-type": "application/json" },
|
||||||
|
body: JSON.stringify({ action_id: "action_release_checklist" })
|
||||||
|
});
|
||||||
|
const body = await response.json() as { accepted: boolean; action_id: string; board: string };
|
||||||
|
|
||||||
|
expect(response.status).toBe(202);
|
||||||
|
expect(body).toEqual({
|
||||||
|
accepted: true,
|
||||||
|
action_id: "action_release_checklist",
|
||||||
|
board: "/projects/sh1pt"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects invalid LogicSRC task payloads", async () => {
|
||||||
|
const response = await fetch(`${baseUrl}/api/tasks`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "content-type": "application/json" },
|
||||||
|
body: JSON.stringify({ type: "logicsrc.task", title: "Incomplete" })
|
||||||
|
});
|
||||||
|
const body = await response.json() as { errors: unknown[] };
|
||||||
|
|
||||||
|
expect(response.status).toBe(422);
|
||||||
|
expect(Array.isArray(body.errors)).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { createServer, type IncomingMessage, type ServerResponse } from "node:http";
|
import { createServer, type IncomingMessage, type ServerResponse } from "node:http";
|
||||||
|
import { pathToFileURL } from "node:url";
|
||||||
import { createPluginRegistry } from "@logicsrc/plugin-core";
|
import { createPluginRegistry } from "@logicsrc/plugin-core";
|
||||||
import { coinPayPlugin } from "@logicsrc/plugin-coinpay";
|
import { coinPayPlugin } from "@logicsrc/plugin-coinpay";
|
||||||
import { sh1ptPlugin } from "@logicsrc/plugin-sh1pt";
|
import { sh1ptPlugin } from "@logicsrc/plugin-sh1pt";
|
||||||
|
|
@ -40,13 +41,15 @@ const sh1ptActions = [
|
||||||
{ id: "action_deploy_preview", title: "Deploy preview", publishable: true }
|
{ id: "action_deploy_preview", title: "Deploy preview", publishable: true }
|
||||||
];
|
];
|
||||||
|
|
||||||
const server = createServer(async (request, response) => {
|
export function createCommandBoardServer() {
|
||||||
|
return createServer(async (request, response) => {
|
||||||
try {
|
try {
|
||||||
await route(request, response);
|
await route(request, response);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
json(response, 500, { error: error instanceof Error ? error.message : String(error) });
|
json(response, 500, { error: error instanceof Error ? error.message : String(error) });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function route(request: IncomingMessage, response: ServerResponse) {
|
async function route(request: IncomingMessage, response: ServerResponse) {
|
||||||
const url = new URL(request.url ?? "/", "http://localhost");
|
const url = new URL(request.url ?? "/", "http://localhost");
|
||||||
|
|
@ -141,7 +144,14 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
||||||
return typeof value === "object" && value !== null && !Array.isArray(value);
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const port = Number(process.env.PORT ?? 4010);
|
export function startCommandBoardServer(port = Number(process.env.PORT ?? 4010)) {
|
||||||
server.listen(port, () => {
|
const server = createCommandBoardServer();
|
||||||
|
server.listen(port, () => {
|
||||||
console.log(`CommandBoard.run API listening on http://localhost:${port}`);
|
console.log(`CommandBoard.run API listening on http://localhost:${port}`);
|
||||||
});
|
});
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
||||||
|
startCommandBoardServer();
|
||||||
|
}
|
||||||
|
|
|
||||||
29
apps/commandboard-web/e2e/commandboard.spec.ts
Normal file
29
apps/commandboard-web/e2e/commandboard.spec.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { expect, test } from "@playwright/test";
|
||||||
|
|
||||||
|
test.describe("CommandBoard.run PWA", () => {
|
||||||
|
test("renders the command board workspace", async ({ page }) => {
|
||||||
|
await page.goto("/");
|
||||||
|
|
||||||
|
await expect(page.getByText("CommandBoard.run").first()).toBeVisible();
|
||||||
|
await expect(page.getByRole("heading", { name: "The command network for humans and AI agents." })).toBeVisible();
|
||||||
|
await expect(page.getByText("/gigs", { exact: true })).toBeVisible();
|
||||||
|
await expect(page.getByText("QA checkout flow")).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("shows default plugin status including sh1pt", async ({ page }) => {
|
||||||
|
await page.goto("/");
|
||||||
|
|
||||||
|
await expect(page.getByText("CoinPay").last()).toBeVisible();
|
||||||
|
await expect(page.getByText("uGig").last()).toBeVisible();
|
||||||
|
await expect(page.getByText("sh1pt").last()).toBeVisible();
|
||||||
|
await expect(page.getByText("projects, actions, and releases")).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("surfaces sh1pt project activity", async ({ page }) => {
|
||||||
|
await page.goto("/");
|
||||||
|
|
||||||
|
await expect(page.getByText("/projects/sh1pt", { exact: true })).toBeVisible();
|
||||||
|
await expect(page.getByText("Release action published")).toBeVisible();
|
||||||
|
await expect(page.getByText("/projects/sh1pt · deployment ready")).toBeVisible();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -5,12 +5,15 @@
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "node scripts/check-assets.js",
|
"build": "node scripts/check-assets.js",
|
||||||
"dev": "vite --host 0.0.0.0"
|
"dev": "vite --host 0.0.0.0",
|
||||||
|
"test:e2e": "playwright test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitejs/plugin-react": "^5.1.1",
|
"@vitejs/plugin-react": "^5.1.1",
|
||||||
"vite": "^7.2.6",
|
"vite": "^7.2.6",
|
||||||
"typescript": "^5.9.3"
|
"typescript": "^5.9.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {}
|
"devDependencies": {
|
||||||
|
"@playwright/test": "^1.57.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
31
apps/commandboard-web/playwright.config.ts
Normal file
31
apps/commandboard-web/playwright.config.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { defineConfig, devices } from "@playwright/test";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
testDir: "./e2e",
|
||||||
|
timeout: 30_000,
|
||||||
|
expect: {
|
||||||
|
timeout: 5_000
|
||||||
|
},
|
||||||
|
fullyParallel: true,
|
||||||
|
reporter: process.env.CI ? [["github"], ["list"]] : "list",
|
||||||
|
use: {
|
||||||
|
baseURL: "http://127.0.0.1:5173",
|
||||||
|
trace: "on-first-retry"
|
||||||
|
},
|
||||||
|
projects: [
|
||||||
|
{
|
||||||
|
name: "chromium",
|
||||||
|
use: { ...devices["Desktop Chrome"] }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "mobile-chrome",
|
||||||
|
use: { ...devices["Pixel 7"] }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
webServer: {
|
||||||
|
command: "npm run dev -- --port 5173",
|
||||||
|
url: "http://127.0.0.1:5173",
|
||||||
|
reuseExistingServer: !process.env.CI,
|
||||||
|
timeout: 30_000
|
||||||
|
}
|
||||||
|
});
|
||||||
70
package-lock.json
generated
70
package-lock.json
generated
|
|
@ -30,7 +30,8 @@
|
||||||
"@logicsrc/validators": "file:../../packages/validators"
|
"@logicsrc/validators": "file:../../packages/validators"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"tsx": "^4.21.0"
|
"tsx": "^4.21.0",
|
||||||
|
"vitest": "^4.0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"apps/commandboard-web": {
|
"apps/commandboard-web": {
|
||||||
|
|
@ -41,7 +42,9 @@
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"vite": "^7.2.6"
|
"vite": "^7.2.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {}
|
"devDependencies": {
|
||||||
|
"@playwright/test": "^1.57.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"apps/commandboard-web/node_modules/vite": {
|
"apps/commandboard-web/node_modules/vite": {
|
||||||
"version": "7.3.5",
|
"version": "7.3.5",
|
||||||
|
|
@ -939,6 +942,22 @@
|
||||||
"url": "https://github.com/sponsors/Boshen"
|
"url": "https://github.com/sponsors/Boshen"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@playwright/test": {
|
||||||
|
"version": "1.60.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.60.0.tgz",
|
||||||
|
"integrity": "sha512-O71yZIbAh/PxDMNGns37GHBIfrVkEVyn+AXyIa5dOTfb4/xNvRWV+Vv/NMbNCtODB/pO7vLlF2OTmMVLhmr7Ag==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"playwright": "1.60.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"playwright": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rolldown/binding-android-arm64": {
|
"node_modules/@rolldown/binding-android-arm64": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz",
|
||||||
|
|
@ -2486,6 +2505,53 @@
|
||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/playwright": {
|
||||||
|
"version": "1.60.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.60.0.tgz",
|
||||||
|
"integrity": "sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"playwright-core": "1.60.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"playwright": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"fsevents": "2.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/playwright-core": {
|
||||||
|
"version": "1.60.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.60.0.tgz",
|
||||||
|
"integrity": "sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bin": {
|
||||||
|
"playwright-core": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/playwright/node_modules/fsevents": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||||
|
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.5.15",
|
"version": "8.5.15",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,9 @@
|
||||||
"build": "npm --workspace @logicsrc/schemas run build && npm --workspace @logicsrc/validators run build && npm --workspace @logicsrc/plugin-core run build && npm --workspace @logicsrc/plugin-coinpay run build && npm --workspace @logicsrc/plugin-ugig run build && npm --workspace @logicsrc/plugin-sh1pt run build && npm --workspace @logicsrc/tui run build && npm --workspace @logicsrc/cli run build && npm --workspace @logicsrc/commandboard-api run build && npm --workspace @logicsrc/commandboard-web run build",
|
"build": "npm --workspace @logicsrc/schemas run build && npm --workspace @logicsrc/validators run build && npm --workspace @logicsrc/plugin-core run build && npm --workspace @logicsrc/plugin-coinpay run build && npm --workspace @logicsrc/plugin-ugig run build && npm --workspace @logicsrc/plugin-sh1pt run build && npm --workspace @logicsrc/tui run build && npm --workspace @logicsrc/cli run build && npm --workspace @logicsrc/commandboard-api run build && npm --workspace @logicsrc/commandboard-web run build",
|
||||||
"test": "npm run test --workspaces --if-present",
|
"test": "npm run test --workspaces --if-present",
|
||||||
"check": "npm run build && npm run test",
|
"check": "npm run build && npm run test",
|
||||||
"schemas:validate": "npm --workspace @logicsrc/validators run validate:fixtures"
|
"schemas:validate": "npm --workspace @logicsrc/validators run validate:fixtures",
|
||||||
|
"test:contract": "npm --workspace @logicsrc/commandboard-api run test:contract",
|
||||||
|
"test:e2e": "npm --workspace @logicsrc/commandboard-web run test:e2e"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^24.10.1",
|
"@types/node": "^24.10.1",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue