diff --git a/.github/workflows/lab.yml b/.github/workflows/lab.yml new file mode 100644 index 0000000..21a5a0a --- /dev/null +++ b/.github/workflows/lab.yml @@ -0,0 +1,39 @@ +name: Sigyn Lab CI + +on: + push: + branches: [main] + + pull_request: + paths: + - "package-lock.json" + - "src/lab/**" + - ".github/workflows/lab.yml" + - "!src/lab/**/*.md" + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [22.x] + fail-fast: false + steps: + - name: Harden Runner + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 + with: + egress-policy: audit + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: ${{ matrix.node-version }} + - name: Install dependencies + run: npm ci + - name: Build packages + run: npm run build + - name: Unit tests + run: npm run test --workspace=src/lab diff --git a/package-lock.json b/package-lock.json index b52a1b6..29d5b39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "src/slack", "src/teams", "src/pattern", - "src/demo-api" + "src/lab" ], "devDependencies": { "@openally/config.eslint": "^1.3.0", @@ -1004,14 +1004,14 @@ "resolved": "src/config", "link": true }, - "node_modules/@sigyn/demo-api": { - "resolved": "src/demo-api", - "link": true - }, "node_modules/@sigyn/discord": { "resolved": "src/discord", "link": true }, + "node_modules/@sigyn/lab": { + "resolved": "src/lab", + "link": true + }, "node_modules/@sigyn/logql": { "resolved": "src/logql", "link": true @@ -6275,9 +6275,9 @@ "license": "Apache-2.0" }, "node_modules/ts-pattern": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.6.0.tgz", - "integrity": "sha512-SL8u60X5+LoEy9tmQHWCdPc2hhb2pKI6I1tU5Jue3v8+iRqZdcT3mWPwKKJy1fMfky6uha82c8ByHAE8PMhKHw==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.6.1.tgz", + "integrity": "sha512-k126YkAs7sZFGTIr6rEdEbxOkqj4cEKAfhwpJMQcwt2M1SuwSD4PM2ClfeUuIlLwEMtVotiZhOsqXNNWqAMWKA==", "license": "MIT" }, "node_modules/tsd": { @@ -7198,7 +7198,49 @@ } }, "src/demo-api": { - "name": "@sigyn/demo-api", + "extraneous": true + }, + "src/discord": { + "name": "@sigyn/discord", + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "@myunisoft/httpie": "^5.0.1" + }, + "engines": { + "node": ">=20" + } + }, + "src/discord/node_modules/@myunisoft/httpie": { + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "@openally/result": "^1.2.1", + "content-type": "^1.0.5", + "lru-cache": "^11.0.0", + "statuses": "^2.0.1", + "undici": "^6.9.0" + }, + "engines": { + "node": ">=20" + } + }, + "src/discord/node_modules/lru-cache": { + "version": "11.0.2", + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "src/discord/node_modules/undici": { + "version": "6.21.1", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "src/lab": { + "name": "@sigyn/lab", "version": "1.0.0", "license": "MIT", "dependencies": { @@ -7212,7 +7254,7 @@ "node": ">=20" } }, - "src/demo-api/node_modules/@fastify/ajv-compiler": { + "src/lab/node_modules/@fastify/ajv-compiler": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-3.6.0.tgz", "integrity": "sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==", @@ -7223,7 +7265,7 @@ "fast-uri": "^2.0.0" } }, - "src/demo-api/node_modules/@fastify/ajv-compiler/node_modules/ajv-formats": { + "src/lab/node_modules/@fastify/ajv-compiler/node_modules/ajv-formats": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", @@ -7240,13 +7282,13 @@ } } }, - "src/demo-api/node_modules/@fastify/error": { + "src/lab/node_modules/@fastify/error": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/@fastify/error/-/error-3.4.1.tgz", "integrity": "sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==", "license": "MIT" }, - "src/demo-api/node_modules/@fastify/fast-json-stringify-compiler": { + "src/lab/node_modules/@fastify/fast-json-stringify-compiler": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz", "integrity": "sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==", @@ -7255,7 +7297,7 @@ "fast-json-stringify": "^5.7.0" } }, - "src/demo-api/node_modules/@fastify/merge-json-schemas": { + "src/lab/node_modules/@fastify/merge-json-schemas": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@fastify/merge-json-schemas/-/merge-json-schemas-0.1.1.tgz", "integrity": "sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==", @@ -7264,7 +7306,7 @@ "fast-deep-equal": "^3.1.3" } }, - "src/demo-api/node_modules/avvio": { + "src/lab/node_modules/avvio": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/avvio/-/avvio-8.4.0.tgz", "integrity": "sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==", @@ -7274,7 +7316,7 @@ "fastq": "^1.17.1" } }, - "src/demo-api/node_modules/cookie": { + "src/lab/node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", @@ -7283,7 +7325,7 @@ "node": ">= 0.6" } }, - "src/demo-api/node_modules/fast-json-stringify": { + "src/lab/node_modules/fast-json-stringify": { "version": "5.16.1", "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-5.16.1.tgz", "integrity": "sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==", @@ -7298,13 +7340,13 @@ "rfdc": "^1.2.0" } }, - "src/demo-api/node_modules/fast-uri": { + "src/lab/node_modules/fast-uri": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.4.0.tgz", "integrity": "sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==", "license": "MIT" }, - "src/demo-api/node_modules/fastify": { + "src/lab/node_modules/fastify": { "version": "4.29.0", "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.29.0.tgz", "integrity": "sha512-MaaUHUGcCgC8fXQDsDtioaCcag1fmPJ9j64vAKunqZF4aSub040ZGi/ag8NGE2714yREPOKZuHCfpPzuUD3UQQ==", @@ -7338,7 +7380,7 @@ "toad-cache": "^3.3.0" } }, - "src/demo-api/node_modules/find-my-way": { + "src/lab/node_modules/find-my-way": { "version": "8.2.2", "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-8.2.2.tgz", "integrity": "sha512-Dobi7gcTEq8yszimcfp/R7+owiT4WncAJ7VTTgFH1jYJ5GaG1FbhjwDG820hptN0QDFvzVY3RfCzdInvGPGzjA==", @@ -7352,7 +7394,7 @@ "node": ">=14" } }, - "src/demo-api/node_modules/json-schema-ref-resolver": { + "src/lab/node_modules/json-schema-ref-resolver": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-1.0.1.tgz", "integrity": "sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==", @@ -7361,7 +7403,7 @@ "fast-deep-equal": "^3.1.3" } }, - "src/demo-api/node_modules/light-my-request": { + "src/lab/node_modules/light-my-request": { "version": "5.14.0", "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.14.0.tgz", "integrity": "sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA==", @@ -7372,13 +7414,13 @@ "set-cookie-parser": "^2.4.1" } }, - "src/demo-api/node_modules/process-warning": { + "src/lab/node_modules/process-warning": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==", "license": "MIT" }, - "src/demo-api/node_modules/ret": { + "src/lab/node_modules/ret": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/ret/-/ret-0.4.3.tgz", "integrity": "sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==", @@ -7387,7 +7429,7 @@ "node": ">=10" } }, - "src/demo-api/node_modules/safe-regex2": { + "src/lab/node_modules/safe-regex2": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-3.1.0.tgz", "integrity": "sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==", @@ -7396,54 +7438,12 @@ "ret": "~0.4.0" } }, - "src/demo-api/node_modules/secure-json-parse": { + "src/lab/node_modules/secure-json-parse": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", "license": "BSD-3-Clause" }, - "src/discord": { - "name": "@sigyn/discord", - "version": "2.0.0", - "license": "MIT", - "dependencies": { - "@myunisoft/httpie": "^5.0.1" - }, - "engines": { - "node": ">=20" - } - }, - "src/discord/node_modules/@myunisoft/httpie": { - "version": "5.0.1", - "license": "MIT", - "dependencies": { - "@openally/result": "^1.2.1", - "content-type": "^1.0.5", - "lru-cache": "^11.0.0", - "statuses": "^2.0.1", - "undici": "^6.9.0" - }, - "engines": { - "node": ">=20" - } - }, - "src/discord/node_modules/lru-cache": { - "version": "11.0.2", - "license": "ISC", - "engines": { - "node": "20 || >=22" - } - }, - "src/discord/node_modules/undici": { - "version": "6.21.1", - "license": "MIT", - "engines": { - "node": ">=18.17" - } - }, - "src/lab": { - "extraneous": true - }, "src/logql": { "name": "@sigyn/logql", "version": "2.2.0", diff --git a/package.json b/package.json index a65162e..6560c2a 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "src/slack", "src/teams", "src/pattern", - "src/demo-api" + "src/lab" ], "devDependencies": { "@openally/config.eslint": "^1.3.0", diff --git a/src/demo-api/README.md b/src/demo-api/README.md deleted file mode 100644 index 1be7523..0000000 --- a/src/demo-api/README.md +++ /dev/null @@ -1,5 +0,0 @@ -TBC. - -1. build: `npm run build` -2. start: `npm run start` -3. check the result on `http://localhost:3000/` diff --git a/src/demo-api/src/index.ts b/src/demo-api/src/index.ts deleted file mode 100644 index f1b9e8a..0000000 --- a/src/demo-api/src/index.ts +++ /dev/null @@ -1,39 +0,0 @@ -// Import Node.js Dependencies -import path from "node:path"; - -// Import Third-party Dependencies -import { DockerComposeEnvironment } from "testcontainers"; -import { GrafanaApi } from "@myunisoft/loki"; - -// Import Internal Dependencies -import { LogGenerator } from "./seeder/logs.js"; - -const environment = await new DockerComposeEnvironment( - // "../" because we are in ./dist/ folder after TSC compilation - path.join(__dirname, "../docker"), - "docker-compose.yaml" -).up(); -const loki = environment.getContainer("loki"); -const lokiUrl = `http://${loki.getHost()}:${loki.getMappedPort(3100)}`; - -const api = new GrafanaApi({ - remoteApiURL: lokiUrl, - apiToken: "" -}); - -const logGenerator = new LogGenerator({ - count: 500, - labels: { app: "demo" } -}); -const logs = [...logGenerator.generate()]; - -await api.Loki.push(logs); - -console.log("Logs ready on http://localhost:3000/explore"); - -// keep process alive -process.stdin.resume(); - -process.once("exit", () => { - environment.stop(); -}); diff --git a/src/lab/README.md b/src/lab/README.md new file mode 100644 index 0000000..58b0280 --- /dev/null +++ b/src/lab/README.md @@ -0,0 +1,120 @@ +
+ A test and demonstration tool for generating and exploring logs in both formatted and JSON styles, integrated with Grafana Loki via Docker. +
+ ++ + + + + + + + + + + + + + + +
+ +## 🚧 Requirements + +- [Node.js](https://nodejs.org/en/) version 20 or higher + +## 🚀 Getting Started + +This package is available in the Node Package Repository and can be easily installed with [npm](https://doc.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com) + +```bash +$ npm i @sigyn/lab +# or +$ yarn add @sigyn/lab +``` + +## 📚 Usage + +```ts +import { run } from "@sigyn/lab"; + +await run({ + count: 200, + labels: { + app: "demo-app" + } +}); +// Grafana Loki ready on http://localhost:3000 with 200 random logs. +``` + +## 🌐 API + +### `run(options?: LogGeneratorOptions): Promise