@gloocan/cat-inspector 0.1.1 → 0.1.3
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 +239 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# @gloocan/cat-inspector
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for **registering allowlisted backend functions** so QA and inspection tools get a **catalog** (ids, parameters, return metadata, optional JSON Schema), then **invoke** those units over a **versioned** wire protocol—embedded WebSocket, Socket.IO, or remote bridge—not arbitrary code execution from the network.
|
|
4
|
+
|
|
5
|
+
**Typical host:** Node.js with **Express** (or similar). Types ship with the package (`dist/*.d.ts`).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @gloocan/cat-inspector
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Install **peer** packages you actually use in your app (npm does not install peers for you):
|
|
16
|
+
|
|
17
|
+
| Peer | When you need it |
|
|
18
|
+
| --------------- | ----------------------------------------------------- |
|
|
19
|
+
| `express` | Express integration (`registerCatPipeline`, etc.). |
|
|
20
|
+
| `socket.io` | Socket.IO transport (`@gloocan/cat-inspector/socket-io`). Optional. |
|
|
21
|
+
| `minio` | Optional host-side object storage helpers. |
|
|
22
|
+
|
|
23
|
+
Always install **`reflect-metadata`** if you use **`@Cat`** decorators (see TypeScript below).
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Package entry points
|
|
28
|
+
|
|
29
|
+
The package is **ESM** (`"type": "module"`).
|
|
30
|
+
|
|
31
|
+
| Import from | Use for |
|
|
32
|
+
| ----------------------------------- | ------- |
|
|
33
|
+
| `@gloocan/cat-inspector` | Main API: registration, `bootstrap`, Express, RPC, WebSocket server, types, policy, validation, etc. |
|
|
34
|
+
| `@gloocan/cat-inspector/socket-io` | `attachCatRPC`, Socket.IO–oriented helpers. Requires `socket.io` as a dependency. |
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## TypeScript and decorators
|
|
39
|
+
|
|
40
|
+
For **`@Cat`** (and related metadata), enable decorator emit and load reflect metadata **before** other app imports:
|
|
41
|
+
|
|
42
|
+
1. `npm install reflect-metadata`
|
|
43
|
+
2. At the **top** of your app entry (e.g. `server.ts`): `import 'reflect-metadata'`
|
|
44
|
+
3. In `tsconfig.json`:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"compilerOptions": {
|
|
49
|
+
"experimentalDecorators": true,
|
|
50
|
+
"emitDecoratorMetadata": true
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
If you only use the **functional** API (`cat()`, `catModule()`, …), decorators may be unnecessary; still follow the docs for your chosen registration style.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Quick examples: registration
|
|
60
|
+
|
|
61
|
+
Each example uses a **stable function id** (`fnKey`) such as `Orders.find`—that id is what the catalog and RPC clients use. Pick ids that stay stable across refactors.
|
|
62
|
+
|
|
63
|
+
### `cat()` — one function
|
|
64
|
+
|
|
65
|
+
Wrap a plain function and give it a unique key. For HTTP-style handlers you can pass `route` / `method` so the catalog knows the path.
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { cat, Return, Throw } from '@gloocan/cat-inspector'
|
|
69
|
+
|
|
70
|
+
export const findUser = cat('Users.findById', function findUser(id: string) {
|
|
71
|
+
if (!id) return Throw('INVALID', new Error('id required'))
|
|
72
|
+
return Return('OK', { id, name: 'Ada' })
|
|
73
|
+
})
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Call `findUser('42')` as normal; the wrapper records **which labeled branch** ran for inspector UIs.
|
|
77
|
+
|
|
78
|
+
### `@Cat` — class methods
|
|
79
|
+
|
|
80
|
+
Requires `reflect-metadata` and the `tsconfig.json` flags above. Registration runs when the class is **loaded**.
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import 'reflect-metadata'
|
|
84
|
+
import { Cat, Return } from '@gloocan/cat-inspector'
|
|
85
|
+
|
|
86
|
+
export class Billing {
|
|
87
|
+
@Cat
|
|
88
|
+
estimate(total: number) {
|
|
89
|
+
return Return('QUOTE', { cents: Math.round(total * 100) })
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The catalog entry key becomes **`Billing.estimate`** (class name + method name).
|
|
95
|
+
|
|
96
|
+
### `catModule()` — a namespace of functions
|
|
97
|
+
|
|
98
|
+
Registers every export under **`${moduleName}.${methodName}`** in one call.
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { catModule, Return } from '@gloocan/cat-inspector'
|
|
102
|
+
|
|
103
|
+
export const inventory = catModule('Inventory', {
|
|
104
|
+
list() {
|
|
105
|
+
return Return('LIST', [{ sku: 'a1' }])
|
|
106
|
+
},
|
|
107
|
+
reserve(sku: string) {
|
|
108
|
+
return Return('RESERVED', { sku, qty: 1 })
|
|
109
|
+
},
|
|
110
|
+
})
|
|
111
|
+
// Keys: Inventory.list, Inventory.reserve — call inventory.list() as usual.
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Optional third argument lets you attach per-method `params`, `declaredReturn`, or `paramsJsonSchema` (see typings).
|
|
115
|
+
|
|
116
|
+
### `registerCatPipeline()` — Express route + middleware chain
|
|
117
|
+
|
|
118
|
+
Pass an Express `Router`, HTTP method, route path, and an array of **already wrapped** `cat()` handlers. The **last** handler is the route endpoint; earlier entries are treated as middleware (`req`, `res`, `next`).
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import express from 'express'
|
|
122
|
+
import type { Request, Response, NextFunction } from 'express'
|
|
123
|
+
import { cat, registerCatPipeline, Return } from '@gloocan/cat-inspector'
|
|
124
|
+
|
|
125
|
+
const router = express.Router()
|
|
126
|
+
|
|
127
|
+
const requireAuth = cat('Api.requireAuth', (req: Request, res: Response, next: NextFunction) => {
|
|
128
|
+
// …validate session, then:
|
|
129
|
+
next()
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
const getProfile = cat('Api.getProfile', (req: Request, res: Response) => {
|
|
133
|
+
return Return('BODY', { userId: req.params['id'] })
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
registerCatPipeline(router, 'get', '/users/:id', [requireAuth, getProfile])
|
|
137
|
+
// app.use('/v1', router)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The SDK aligns all handlers in the array with one **pipeline id** (e.g. `GET /users/:id`) so tools see middleware + endpoint as one HTTP unit.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## `Return()` and `Throw()` — labels for tooling
|
|
145
|
+
|
|
146
|
+
These helpers are **no-ops for business data**: they return or throw the same values you would use without Cat Inspector. Their job is to attach a **string label** so QA clients and the catalog can distinguish branches (success variants, validation failures, expected errors) without parsing your whole codebase.
|
|
147
|
+
|
|
148
|
+
| Helper | What you write | What QA / catalog sees |
|
|
149
|
+
| ------ | -------------- | ---------------------- |
|
|
150
|
+
| `Return(label, value)` | `return Return('CREATED', entity)` | Outcome tied to label **`CREATED`**; payload is `value` (types/shapes can be captured for assertions). |
|
|
151
|
+
| `Throw(label, error)` | `return Throw('NOT_FOUND', new Error('…'))` | Expected error path **`NOT_FOUND`** with message/stack; still throws `error` to callers. |
|
|
152
|
+
|
|
153
|
+
**Labels** are arbitrary string literals you choose (`'OK'`, `'INVALID'`, `'QUOTE'`, …). Use short, stable names: they become part of how teams author **assertions** (“expect `Users.findById` to resolve with label `OK`”).
|
|
154
|
+
|
|
155
|
+
**Data:** the second argument to `Return` is whatever your function would normally return. `Throw` always takes an `Error` (or subclass); use normal `throw new Error()` for unexpected failures you do **not** want labeled.
|
|
156
|
+
|
|
157
|
+
Combine with `cat` / `@Cat` / `catModule` so the inspector knows **which function** is active when a label fires (`ActiveContext` is managed by the wrappers).
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Minimal integration shape
|
|
162
|
+
|
|
163
|
+
Exact APIs depend on your stack; most setups touch these ideas in order:
|
|
164
|
+
|
|
165
|
+
1. **Register** testable units (`@Cat`, `cat`, `catModule`, class helpers, `registerInstance`, …).
|
|
166
|
+
2. **Wire Express** (e.g. `registerCatPipeline`, correlation middleware) so HTTP routes map to catalog entries.
|
|
167
|
+
3. **Expose a transport** so a QA client can load the catalog and call `invoke`—e.g. `startInspectorWebSocket`, or `attachCatRPC` from the `socket-io` entry after you create your `socket.io` `Server`.
|
|
168
|
+
|
|
169
|
+
Example (illustrative only—adapt ports, CORS, and auth to your environment):
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
import 'reflect-metadata'
|
|
173
|
+
|
|
174
|
+
import express from 'express'
|
|
175
|
+
import http from 'node:http'
|
|
176
|
+
import { Server as SocketIOServer } from 'socket.io'
|
|
177
|
+
|
|
178
|
+
import {
|
|
179
|
+
createInspectorCorrelationMiddleware,
|
|
180
|
+
attachCatRPC,
|
|
181
|
+
} from '@gloocan/cat-inspector/socket-io'
|
|
182
|
+
|
|
183
|
+
const app = express()
|
|
184
|
+
app.use(express.json())
|
|
185
|
+
app.use('/api', createInspectorCorrelationMiddleware())
|
|
186
|
+
|
|
187
|
+
const server = http.createServer(app)
|
|
188
|
+
const io = new SocketIOServer(server, {
|
|
189
|
+
cors: { origin: 'http://localhost:3013' },
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
attachCatRPC(io, {
|
|
193
|
+
scanRoots: [new URL('.', import.meta.url).pathname],
|
|
194
|
+
serverId: 'my-service',
|
|
195
|
+
isDevelopment: process.env.NODE_ENV !== 'production',
|
|
196
|
+
// bootstrap, upload, auth: see docs and PROTOCOL.md in the source repo
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
server.listen(5050)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
For **`executeRPC`**, validation, serialization limits, pre-invoke hooks, and audits, import from `@gloocan/cat-inspector`.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Wire protocol and versioning
|
|
207
|
+
|
|
208
|
+
Clients and hosts must agree on JSON message shapes. The SDK exports **`PROTOCOL_VERSION`** from the main entry—bump-aware clients should read it and follow the contract documented alongside the source tree.
|
|
209
|
+
|
|
210
|
+
**Note:** The **published npm tarball** contains **`dist/`** (compiled JS + declarations) plus standard metadata. Markdown references such as **`PROTOCOL.md`** live in the **source repository** (use the **Repository** link on the [npm package page](https://www.npmjs.com/package/@gloocan/cat-inspector) if your maintainers have set `repository` in `package.json`).
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Security (read before production)
|
|
215
|
+
|
|
216
|
+
- Only **registered** functions are invokable—treat registration as an **allowlist**.
|
|
217
|
+
- **Authenticate** transports in non-dev environments; do not expose invoke surfaces anonymously on the public internet.
|
|
218
|
+
- Prefer **read-only** or sandbox data for QA; avoid putting production secrets in tool-visible payloads.
|
|
219
|
+
- Configure **serialization limits**, **rate limits**, and **pre-invoke** hooks where appropriate (`setRpcSerializationConfig`, `configureInvokeRateLimit`, `registerPreInvoke`, …—see typings and docs).
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Documentation and examples
|
|
224
|
+
|
|
225
|
+
- **Product / docs site:** [cat-inspector.gloocan.com](https://cat-inspector.gloocan.com) (when available for your deployment).
|
|
226
|
+
- **Deep reference:** your team’s Nextra or internal doc site, if published.
|
|
227
|
+
- **Runnable monorepo example:** an Express + Socket.IO backend under the same repository as this package (search for `examples/cat-demo` in the SDK source tree).
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Public API surface
|
|
232
|
+
|
|
233
|
+
The supported public API is whatever **`@gloocan/cat-inspector` re-exports** from its main module (registration, `bootstrap`, Express helpers, `executeRPC`, transports, `PROTOCOL_VERSION`, wire types such as `RegistryEntry` and `RpcResponse`, validation helpers, policy hooks, uploads, coverage/OpenAPI helpers, sessions, etc.). Prefer importing from the package root rather than deep paths into `dist/`, which are not a stable contract.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## License
|
|
238
|
+
|
|
239
|
+
MIT — see the `license` field in `package.json`.
|