ttc-origin-server 0.1.0 → 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.
package/README.md CHANGED
@@ -1,50 +1,37 @@
1
1
  # TTC Origin Server
2
2
 
3
- A lightweight, decorator‑based RPC server for the Tentarcles Origins platform. Quickly expose TypeScript classes as RPC endpoints with Zod validation and automatic API discovery.
4
-
5
- ## Features
6
-
7
- - **Decorator‑based endpoints** – Use `@ttc.describe()` to expose methods
8
- - **Zod validation** – Type‑safe input/output schemas
9
- - **Automatic API discovery** – `/rpc/functions` endpoint lists all available methods
10
- - **Authentication hooks** – Customizable auth middleware
11
- - **Express‑compatible** – Use your own Express app or let the library create one
12
- - **Bun/Node.js** – Runs on Bun (recommended) or Node.js
3
+ A lightweight server wrapper for `ttc-rpc` that exposes your decorated classes as RPC endpoints with automatic API discovery.
13
4
 
14
5
  ## Installation
15
6
 
16
7
  ```bash
17
- # Using Bun
18
8
  bun add ttc-origin-server
19
-
20
- # Using npm
9
+ # or
21
10
  npm install ttc-origin-server
22
-
23
- # Using yarn
24
- yarn add ttc-origin-server
25
11
  ```
26
12
 
27
13
  ## Quick Start
28
14
 
29
- 1. **Create a module**
15
+ 1. **Create a module using `ttc-rpc` decorators**
30
16
 
31
17
  ```typescript
32
- // src/modules/hello.ts
33
- import { ttc } from 'ttc-rpc';
34
- import { z } from 'zod';
35
-
36
- export class HelloService {
37
- @ttc.describe({
38
- name: 'greet',
39
- description: 'Returns a personalized greeting',
40
- input: z.object({
41
- name: z.string().optional().default('World')
42
- }),
43
- output: z.string()
44
- })
45
- greet(input: { name?: string }): string {
46
- return `Hello, ${input.name}!`;
47
- }
18
+ // src/test.ts
19
+ import { ttc } from "ttc-rpc";
20
+ import z from "zod";
21
+
22
+ export class HelloWorldModule {
23
+ @ttc.describe({
24
+ doc: 'some info',
25
+ inputSchema: z.object({
26
+ name: z.string()
27
+ }),
28
+ outputSchema: z.string(),
29
+ validate: true,
30
+ auth: true
31
+ })
32
+ hello(name: string): string {
33
+ return `Hello, ${name}!`;
34
+ }
48
35
  }
49
36
  ```
50
37
 
@@ -53,103 +40,59 @@ export class HelloService {
53
40
  ```typescript
54
41
  // src/index.ts
55
42
  import { runServer } from 'ttc-origin-server';
56
- import { HelloService } from './modules/hello';
43
+ import { HelloWorldModule } from './test';
57
44
 
58
45
  runServer({
59
- name: 'my-service',
60
- description: 'A demo TTC Origins service',
61
- modules: [HelloService],
62
- port: 3000,
63
- authCb: async (req) => {
64
- // Your authentication logic
65
- return true; // Allow all requests
66
- }
46
+ name: 'my-service',
47
+ modules: [HelloWorldModule],
48
+ port: 3000,
49
+ authCb: async (req) => {
50
+ // Your authentication logic
51
+ return true;
52
+ }
67
53
  });
68
54
  ```
69
55
 
70
- 3. **Run it**
56
+ 3. **Run**
71
57
 
72
58
  ```bash
73
59
  bun run src/index.ts
74
- # or with hot reload
75
- bun run dev
76
60
  ```
77
61
 
78
- ## API Reference
62
+ ## API
79
63
 
80
64
  ### `runServer(config)`
81
65
 
82
- Starts the TTC Origin server.
66
+ Starts a TTC Origin server.
83
67
 
84
- **Configuration:**
68
+ **Config options:**
85
69
 
86
- | Option | Type | Description |
87
- |--------|------|-------------|
88
- | `name` | `string` | Service name (spaces replaced with underscores) |
89
- | `description` | `string` | Optional service description |
90
- | `modules` | `any[]` | Array of classes with `@ttc.describe` decorators |
91
- | `port` | `number` | Port to listen on |
92
- | `authCb` | `(req) => Promise<boolean>` | Authentication callback |
93
- | `app` | `express.Express` | Optional existing Express app |
94
- | `requireAuth` | `boolean` | Whether authentication is required |
95
- | `modifyable` | `boolean` | If `true`, exposes the working directory |
70
+ - `name` (string) Service name
71
+ - `modules` (any[]) – Array of classes decorated with `@ttc.describe`
72
+ - `port` (number) Port to listen on
73
+ - `authCb` (req => Promise<boolean>) Authentication callback
74
+ - `app` (express.Express) Optional existing Express app
75
+ - `requireAuth` (boolean) Whether authentication is required
76
+ - `modifyable` (boolean) If `true`, exposes working directory
77
+ - `description` (string) Optional description
96
78
 
97
79
  ### Endpoints
98
80
 
99
- - `GET /rpc/info` – Returns service metadata
100
- - `GET /rpc/functions` – Lists all available RPC methods with schemas
101
- - `POST /rpc/:module/:method` – Invokes an RPC method (handled by `ttc-rpc`)
81
+ - `GET /rpc/info` – Service metadata
82
+ - `GET /rpc/functions` – Lists all RPC methods (auto‑discovered)
83
+ - `POST /rpc/:module/:method` – Invoke an RPC method (handled by `ttc-rpc`)
102
84
 
103
- ## Example Module
85
+ ## Decorator Usage
104
86
 
105
- ```typescript
106
- import { ttc } from 'ttc-rpc';
107
- import { z } from 'zod';
108
-
109
- export class Calculator {
110
- @ttc.describe({
111
- name: 'add',
112
- description: 'Adds two numbers',
113
- input: z.object({
114
- a: z.number(),
115
- b: z.number()
116
- }),
117
- output: z.number()
118
- })
119
- add(input: { a: number; b: number }): number {
120
- return input.a + input.b;
121
- }
122
-
123
- @ttc.describe({
124
- name: 'multiply',
125
- description: 'Multiplies two numbers',
126
- input: z.object({
127
- a: z.number(),
128
- b: z.number()
129
- }),
130
- output: z.number()
131
- })
132
- multiply(input: { a: number; b: number }): number {
133
- return input.a * input.b;
134
- }
135
- }
136
- ```
87
+ Refer to the [`ttc-rpc` npm package](https://www.npmjs.com/package/ttc-rpc) for full documentation on the `@ttc.describe` decorator and its options.
137
88
 
138
89
  ## Development
139
90
 
140
91
  ```bash
141
- # Clone the repository
142
92
  git clone https://github.com/tentarcles/ttc-origin-server.git
143
93
  cd ttc-origin-server
144
-
145
- # Install dependencies
146
94
  bun install
147
-
148
- # Run in development mode (hot reload)
149
95
  bun run dev
150
-
151
- # Build for production
152
- bun run build
153
96
  ```
154
97
 
155
98
  ## License
@@ -0,0 +1,12 @@
1
+ import express from 'express';
2
+ export declare const runServer: (config: {
3
+ name: string;
4
+ description?: string;
5
+ modules: any[];
6
+ port: number;
7
+ requireAuth?: boolean;
8
+ modifyable?: boolean;
9
+ authCb: (req: any) => Promise<boolean>;
10
+ app?: express.Express;
11
+ }) => void;
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,SAAS,CAAC;AAI9B,eAAO,MAAM,SAAS,GAAI,QAAQ;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,GAAG,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,GAAG,CAAC,EAAE,OAAO,CAAC,OAAO,CAAA;CACxB,SAkDA,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runServer = void 0;
7
+ const ttc_rpc_1 = require("ttc-rpc");
8
+ const express_1 = __importDefault(require("express"));
9
+ const runServer = (config) => {
10
+ const { modules, port, app } = config;
11
+ const appInstance = app || (0, express_1.default)();
12
+ config.name = config.name.replace(/\s+/g, '_').toLowerCase();
13
+ // authenticate to the ttc server
14
+ // the server will get the definition and Qualities and url etc
15
+ appInstance.get('/rpc/info', (req, res) => {
16
+ res.json({
17
+ name: config.name,
18
+ description: config.description || '',
19
+ requireAuth: config.requireAuth,
20
+ directory: config.modifyable ? process.cwd() : undefined
21
+ });
22
+ });
23
+ appInstance.get('/rpc/functions', (req, res) => {
24
+ const queryParams = req.query;
25
+ const assistant = queryParams.assistant;
26
+ console.log(`${assistant} is accessing the RPC definitions..`);
27
+ const info = (0, ttc_rpc_1.generateRPCMethodsInfo)();
28
+ const finalFunctions = [];
29
+ Object.keys(info).forEach((module) => {
30
+ const functions = info[module]?.map((func) => {
31
+ return {
32
+ ...func,
33
+ name: `${config.name}.${module}.${func.name}`
34
+ };
35
+ }) || [];
36
+ finalFunctions.push(...functions);
37
+ });
38
+ console.log(JSON.stringify(finalFunctions, null, 2));
39
+ res.json({
40
+ functions: finalFunctions
41
+ });
42
+ });
43
+ ttc_rpc_1.ttc.init({
44
+ app: appInstance,
45
+ modules: modules,
46
+ generate_client: false,
47
+ authCb: async (req) => {
48
+ // authorization for fetching functions will come through here
49
+ if (config.authCb) {
50
+ return await config.authCb(req);
51
+ }
52
+ },
53
+ socketCb: async (socket) => { }
54
+ }).listen(port);
55
+ };
56
+ exports.runServer = runServer;
57
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,qCAA0E;AAC1E,sDAA8B;AAIvB,MAAM,SAAS,GAAG,CAAC,MASzB,EAAE,EAAE;IACD,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;IACtC,MAAM,WAAW,GAAG,GAAG,IAAI,IAAA,iBAAO,GAAE,CAAC;IAErC,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAE7D,iCAAiC;IACjC,+DAA+D;IAC/D,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACtC,GAAG,CAAC,IAAI,CAAC;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE;YACrC,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS;SAC3D,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,WAAW,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC3C,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC;QAC9B,MAAM,SAAS,GAAG,WAAW,CAAC,SAA+B,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,GAAG,SAAS,qCAAqC,CAAC,CAAC;QAC/D,MAAM,IAAI,GAAoC,IAAA,gCAAsB,GAAE,CAAC;QACvE,MAAM,cAAc,GAAoB,EAAE,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,MAAc,EAAE,EAAE;YACzC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC,IAAmB,EAAE,EAAE;gBACxD,OAAO;oBACH,GAAG,IAAI;oBACP,IAAI,EAAE,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE;iBAChD,CAAA;YACL,CAAC,CAAC,IAAI,EAAE,CAAC;YACT,cAAc,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACrD,GAAG,CAAC,IAAI,CAAC;YACL,SAAS,EAAE,cAAc;SAC5B,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,aAAG,CAAC,IAAI,CAAC;QACL,GAAG,EAAE,WAAW;QAChB,OAAO,EAAE,OAAO;QAChB,eAAe,EAAE,KAAK;QACtB,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAClB,8DAA8D;YAC9D,IAAG,MAAM,CAAC,MAAM,EAAC,CAAC;gBACd,OAAO,MAAM,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACpC,CAAC;QACL,CAAC;QACD,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC;KAClC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC,CAAA;AA3DY,QAAA,SAAS,aA2DrB"}
package/dist/test.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export declare class HelloWorldModule {
2
+ hello(name: string): string;
3
+ }
4
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"AAKA,qBAAa,gBAAgB;IAYzB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAG9B"}
package/dist/test.js ADDED
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.HelloWorldModule = void 0;
16
+ const ttc_rpc_1 = require("ttc-rpc");
17
+ const zod_1 = __importDefault(require("zod"));
18
+ class HelloWorldModule {
19
+ hello(name) {
20
+ return `Hello, ${name}!`;
21
+ }
22
+ }
23
+ exports.HelloWorldModule = HelloWorldModule;
24
+ __decorate([
25
+ ttc_rpc_1.ttc.describe({
26
+ doc: 'some info',
27
+ inputSchema: zod_1.default.object({
28
+ name: zod_1.default.string()
29
+ }),
30
+ outputSchema: zod_1.default.string(),
31
+ validate: true,
32
+ auth: true
33
+ }),
34
+ __metadata("design:type", Function),
35
+ __metadata("design:paramtypes", [String]),
36
+ __metadata("design:returntype", String)
37
+ ], HelloWorldModule.prototype, "hello", null);
38
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,qCAA8B;AAC9B,8CAAoB;AAIpB,MAAa,gBAAgB;IAYzB,KAAK,CAAC,IAAY;QACd,OAAO,UAAU,IAAI,GAAG,CAAC;IAC7B,CAAC;CACJ;AAfD,4CAeC;AAHG;IATC,aAAG,CAAC,QAAQ,CAAC;QACV,GAAG,EAAE,WAAW;QAChB,WAAW,EAAE,aAAC,CAAC,MAAM,CAAC;YAClB,IAAI,EAAE,aAAC,CAAC,MAAM,EAAE;SACnB,CAAC;QACF,YAAY,EAAE,aAAC,CAAC,MAAM,EAAE;QACxB,QAAQ,EAAE,IAAI;QACd,IAAI,EAAE,IAAI;KACb,CAAC;;;;6CAGD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ttc-origin-server",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "A lightweight server for TTC Origins - run RPC services with decorator-based endpoints",
5
5
  "main": "dist/index.js",
6
6
  "module": "src/index.ts",
package/src/test.ts ADDED
@@ -0,0 +1,21 @@
1
+ import { ttc } from "ttc-rpc";
2
+ import z from "zod";
3
+
4
+
5
+
6
+ export class HelloWorldModule {
7
+
8
+
9
+ @ttc.describe({
10
+ doc: 'some info',
11
+ inputSchema: z.object({
12
+ name: z.string()
13
+ }),
14
+ outputSchema: z.string(),
15
+ validate: true,
16
+ auth: true
17
+ })
18
+ hello(name: string): string {
19
+ return `Hello, ${name}!`;
20
+ }
21
+ }