@venizia/ignis 0.2.2 → 0.3.0

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.
@@ -0,0 +1,4 @@
1
+ import { houseConfigs } from '@venizia/dev-configs/linters';
2
+
3
+ // oxlint (oxlint.config.mts) runs every other rule; ESLint runs the naming convention and the house rules.
4
+ export default houseConfigs;
@@ -0,0 +1,4 @@
1
+ import { defineConfig } from 'oxfmt';
2
+ import { oxfmtConfigs } from '@venizia/dev-configs/formatters';
3
+
4
+ export default defineConfig(oxfmtConfigs);
@@ -0,0 +1,4 @@
1
+ import { defineConfig } from 'oxlint';
2
+ import { oxlintConfigs } from '@venizia/dev-configs/linters';
3
+
4
+ export default defineConfig(oxlintConfigs);
@@ -0,0 +1,5 @@
1
+ # {{app}}
2
+
3
+ The {{app}} backend of {{project}}, built on IGNIS.
4
+
5
+ `bun run dev` serves `http://localhost:{{devPort}}/api/hello`.
@@ -0,0 +1 @@
1
+ PORT={{devPort}}
@@ -0,0 +1,33 @@
1
+ import { ApiReferenceComponent, BaseApplication, type IApplicationInfo } from '@venizia/ignis';
2
+ import AutoArtifacts from '@venizia/ignis-boot/auto';
3
+ import packageJson from '../package.json';
4
+
5
+ export class Application extends BaseApplication {
6
+ getAppInfo(): IApplicationInfo {
7
+ return {
8
+ name: packageJson.name,
9
+ version: packageJson.version,
10
+ description: 'The {{app}} backend of {{project}}',
11
+ };
12
+ }
13
+
14
+ staticConfigure() {}
15
+
16
+ preConfigure() {
17
+ this.component(ApiReferenceComponent);
18
+ }
19
+
20
+ postConfigure() {}
21
+
22
+ setupMiddlewares() {}
23
+ }
24
+
25
+ export const application = new Application({
26
+ scope: 'Application',
27
+ config: {
28
+ host: '0.0.0.0',
29
+ port: Number(process.env.PORT ?? '{{devPort}}'),
30
+ path: { base: '/api', isStrict: false },
31
+ artifacts: AutoArtifacts,
32
+ },
33
+ });
@@ -0,0 +1,34 @@
1
+ import { z } from '@hono/zod-openapi';
2
+ import {
3
+ BaseRestController,
4
+ controller,
5
+ get,
6
+ jsonContent,
7
+ type TRouteContext,
8
+ } from '@venizia/ignis';
9
+ import { HTTP } from '@venizia/ignis-helpers';
10
+
11
+ @controller({ path: '/hello' })
12
+ export class HelloController extends BaseRestController {
13
+ constructor() {
14
+ super({ scope: HelloController.name });
15
+ }
16
+
17
+ // binding() is abstract - leave it empty when every route uses @get/@post decorators.
18
+ override binding() {}
19
+
20
+ @get({
21
+ configs: {
22
+ path: '/',
23
+ responses: {
24
+ [HTTP.ResultCodes.RS_2.Ok]: jsonContent({
25
+ description: 'Says hello',
26
+ schema: z.object({ message: z.string() }),
27
+ }),
28
+ },
29
+ },
30
+ })
31
+ sayHello(context: TRouteContext) {
32
+ return context.json({ message: 'Hello from IGNIS!' }, HTTP.ResultCodes.RS_2.Ok);
33
+ }
34
+ }
@@ -0,0 +1,11 @@
1
+ import { application } from './application';
2
+
3
+ const main = async () => {
4
+ application.init();
5
+ await application.start();
6
+ };
7
+
8
+ main().catch((error: unknown) => {
9
+ console.error('[main] Application start failed | Error:', error);
10
+ process.exit(1);
11
+ });
@@ -0,0 +1,81 @@
1
+ // Smoke test: runs src/index.ts exactly as the quickstart page tells the reader to, on a free port,
2
+ // and calls its two endpoints over HTTP.
3
+ import { afterAll, beforeAll, describe, expect, test } from 'bun:test';
4
+ import { getError } from '@venizia/ignis-helpers';
5
+ import path from 'node:path';
6
+
7
+ const HOST = '127.0.0.1';
8
+ const START_TIMEOUT_MS = 10_000;
9
+ const POLL_INTERVAL_MS = 100;
10
+
11
+ const findFreePort = async () => {
12
+ const probe = Bun.serve({ hostname: HOST, port: 0, fetch: () => new Response() });
13
+ const port = probe.port;
14
+ await probe.stop(true);
15
+ return port;
16
+ };
17
+
18
+ const waitForServer = async (opts: { url: string; process: Bun.Subprocess }) => {
19
+ const deadline = Date.now() + START_TIMEOUT_MS;
20
+
21
+ while (Date.now() < deadline) {
22
+ if (opts.process.exitCode !== null) {
23
+ throw getError({
24
+ message: `[smoke] src/index.ts exited early | Code: ${opts.process.exitCode}`,
25
+ });
26
+ }
27
+
28
+ const isUp = await fetch(opts.url).then(
29
+ response => response.ok,
30
+ () => false,
31
+ );
32
+
33
+ if (isUp) {
34
+ return;
35
+ }
36
+
37
+ await Bun.sleep(POLL_INTERVAL_MS);
38
+ }
39
+
40
+ throw getError({
41
+ message: `[smoke] server did not answer within ${START_TIMEOUT_MS} ms | Url: ${opts.url}`,
42
+ });
43
+ };
44
+
45
+ describe('{{app}}', () => {
46
+ let server: Bun.Subprocess;
47
+ let baseUrl = '';
48
+
49
+ beforeAll(async () => {
50
+ const port = await findFreePort();
51
+ baseUrl = `http://${HOST}:${port}/api`;
52
+
53
+ server = Bun.spawn(['bun', 'run', 'src/index.ts'], {
54
+ cwd: path.resolve(__dirname, '..'),
55
+ env: { ...process.env, PORT: String(port) },
56
+ stdout: 'ignore',
57
+ stderr: 'inherit',
58
+ });
59
+
60
+ await waitForServer({ url: `${baseUrl}/hello`, process: server });
61
+ });
62
+
63
+ afterAll(async () => {
64
+ server?.kill();
65
+ await server?.exited;
66
+ });
67
+
68
+ test('GET /hello says hello', async () => {
69
+ const response = await fetch(`${baseUrl}/hello`);
70
+
71
+ expect(response.status).toBe(200);
72
+ expect(await response.json()).toEqual({ message: 'Hello from IGNIS!' });
73
+ });
74
+
75
+ test('GET /doc/explorer serves the API reference', async () => {
76
+ const response = await fetch(`${baseUrl}/doc/explorer`);
77
+
78
+ expect(response.status).toBe(200);
79
+ expect(response.headers.get('content-type')).toContain('text/html');
80
+ });
81
+ });
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "http://json.schemastore.org/tsconfig",
3
+ "extends": "@venizia/dev-configs/tsconfig.common.json",
4
+ "compilerOptions": {
5
+ "outDir": "dist",
6
+ "rootDir": "src",
7
+ "paths": {
8
+ "@/*": [
9
+ "./src/*"
10
+ ]
11
+ },
12
+ "experimentalDecorators": true,
13
+ "emitDecoratorMetadata": true,
14
+ "useDefineForClassFields": false
15
+ },
16
+ "include": [
17
+ "src"
18
+ ],
19
+ "exclude": [
20
+ "node_modules",
21
+ "dist"
22
+ ]
23
+ }
@@ -0,0 +1,50 @@
1
+ {
2
+ "presetVersion": 1,
3
+ "side": "backend",
4
+ "summary": "An IGNIS API on Bun: one controller, AutoArtifacts, the API reference at /api/doc/explorer.",
5
+ "devPort": 3000,
6
+ "dependencies": {
7
+ "@hono/zod-openapi": "^1.6.3",
8
+ "@scalar/hono-api-reference": "^0.11.16",
9
+ "@venizia/ignis": "0.3.0",
10
+ "@venizia/ignis-boot": "0.3.0",
11
+ "@venizia/ignis-helpers": "0.3.0",
12
+ "hono": "^4.13.7",
13
+ "winston": "^3.19.0",
14
+ "winston-daily-rotate-file": "^5.0.0",
15
+ "winston-transport": "^4.9.0"
16
+ },
17
+ "devDependencies": {
18
+ "@types/bun": "^1.4.1",
19
+ "@venizia/dev-configs": "0.3.1",
20
+ "eslint": "^10.10.0",
21
+ "oxfmt": "0.73.0",
22
+ "oxlint": "1.88.0",
23
+ "oxlint-tsgolint": "7.0.2004",
24
+ "tsc-alias": "^1.9.4",
25
+ "typescript": "^6.0.3"
26
+ },
27
+ "peers": {},
28
+ "scripts": {
29
+ "dev": "NODE_ENV=development bun run src/index.ts",
30
+ "start": "NODE_ENV=production bun run dist/index.js",
31
+ "build": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
32
+ "typecheck": "tsc --noEmit -p tsconfig.json",
33
+ "lint": "oxlint -c .configs/oxlint.config.mts --deny-warnings && eslint -c .configs/eslint.config.mjs . && oxfmt -c .configs/oxfmt.config.mts --check \"**/*.{ts,tsx,mts,js,mjs}\"",
34
+ "lint:fix": "oxlint -c .configs/oxlint.config.mts --fix && eslint -c .configs/eslint.config.mjs . --fix && oxfmt -c .configs/oxfmt.config.mts \"**/*.{ts,tsx,mts,js,mjs}\"",
35
+ "test": "bun test"
36
+ },
37
+ "checks": [
38
+ "typecheck",
39
+ "lint",
40
+ "test"
41
+ ],
42
+ "files": "./files",
43
+ "atlas": [
44
+ {
45
+ "name": "ignis",
46
+ "repo": "VENIZIA-AI/ignis",
47
+ "ref": "develop"
48
+ }
49
+ ]
50
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@venizia/ignis",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "High-performance TypeScript server infrastructure combining LoopBack 4 enterprise architecture (decorator-based DI, repository pattern, component system) with Hono speed (~140k req/s). Features auto-generated OpenAPI docs, Drizzle ORM type-safe SQL, JWT/Basic authentication, Casbin authorization, convention-based bootstrapping, and pluggable components for health checks, Swagger UI, mail, Socket.IO, and static assets. Built for Bun and Node.js.",
5
5
  "keywords": [
6
6
  "access-control",
@@ -190,16 +190,19 @@
190
190
  "access": "public"
191
191
  },
192
192
  "sideEffects": false,
193
+ "vulcan": {
194
+ "preset": "./dist/vulcan-preset/preset.json"
195
+ },
193
196
  "scripts": {
194
197
  "force-update": "sh ./scripts/force-update.sh",
195
198
  "prepublishOnly": "make rebuild"
196
199
  },
197
200
  "dependencies": {
198
- "@venizia/ignis-connectors": "0.2.2",
199
- "@venizia/ignis-filter": "0.2.2",
200
- "@venizia/ignis-helpers": "0.2.2",
201
- "@venizia/ignis-inversion": "0.2.2",
202
- "@venizia/ignis-kernel": "0.2.2",
201
+ "@venizia/ignis-connectors": "0.3.0",
202
+ "@venizia/ignis-filter": "0.3.0",
203
+ "@venizia/ignis-helpers": "0.3.0",
204
+ "@venizia/ignis-inversion": "0.3.0",
205
+ "@venizia/ignis-kernel": "0.3.0",
203
206
  "reflect-metadata": "^0.2.2"
204
207
  },
205
208
  "peerDependencies": {
@@ -304,7 +307,7 @@
304
307
  "@types/nodemailer": "^8.0.1",
305
308
  "@types/pg": "^8.23.1",
306
309
  "@venizia/dev-configs": "0.3.1",
307
- "@venizia/ignis-boot": "0.2.1",
310
+ "@venizia/ignis-boot": "0.3.0",
308
311
  "casbin": "^5.51.1",
309
312
  "eslint": "^10.10.0",
310
313
  "meilisearch": "^0.60.0",