@usu-accessibility/anumber-service-handler 0.0.0-stage → 1.0.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 +94 -2
- package/dist/index.d.ts +56 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/package.json +29 -4
package/README.md
CHANGED
|
@@ -1,3 +1,95 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `@usu-accessibility/anumber-service-handler`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A typed, server-side client for the A-Number Service. It authenticates with an
|
|
4
|
+
API key and exposes the service's oRPC procedures with inferred TypeScript
|
|
5
|
+
input and output types.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install @usu-accessibility/anumber-service-handler
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This package is ESM-only and requires a runtime with `fetch` support.
|
|
14
|
+
|
|
15
|
+
## Configure
|
|
16
|
+
|
|
17
|
+
Pass the service URL and authentication token when creating the client:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { createAnumberHandler } from "@usu-accessibility/anumber-service-handler";
|
|
21
|
+
|
|
22
|
+
const client = createAnumberHandler({
|
|
23
|
+
baseUrl: "https://anumber.example.edu",
|
|
24
|
+
authToken: process.env.ANUMBER_SERVICE_AUTH_TOKEN,
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The base URL should be the service origin, without `/rpc`. A trailing slash is
|
|
29
|
+
accepted.
|
|
30
|
+
|
|
31
|
+
Alternatively, configure both values through environment variables:
|
|
32
|
+
|
|
33
|
+
```dotenv
|
|
34
|
+
ANUMBER_SERVICE_URL=https://anumber.example.edu
|
|
35
|
+
ANUMBER_SERVICE_AUTH_TOKEN=...
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { createAnumberHandler } from "@usu-accessibility/anumber-service-handler";
|
|
40
|
+
|
|
41
|
+
const client = createAnumberHandler();
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Explicit options take precedence over environment variables. The constructor
|
|
45
|
+
throws when either value is missing. Keep the authentication token on the
|
|
46
|
+
server; do not bundle it into browser code.
|
|
47
|
+
|
|
48
|
+
## Encrypt A-Numbers
|
|
49
|
+
|
|
50
|
+
Use `client.anumber.encrypt` to convert A-Numbers into safe IDs:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
const result = await client.anumber.encrypt({
|
|
54
|
+
aNumbers: ["a12345678", "a87654321"],
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
console.log(result.data.a12345678); // "anum_..."
|
|
58
|
+
console.log(result.errors); // A-Numbers that could not be processed
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
A-Numbers must start with `a` followed by digits. Input is normalized to
|
|
62
|
+
lowercase. Encrypting the same A-Number repeatedly returns its existing safe
|
|
63
|
+
ID.
|
|
64
|
+
|
|
65
|
+
## Decrypt safe IDs
|
|
66
|
+
|
|
67
|
+
Use `client.anumber.decrypt` to resolve safe IDs:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
const result = await client.anumber.decrypt({
|
|
71
|
+
ids: ["anum_..."],
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
console.log(result.data["anum_..."]); // "a12345678"
|
|
75
|
+
console.log(result.errors); // IDs that were not found or could not be processed
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Safe IDs must start with `anum_`. Both operations return:
|
|
79
|
+
|
|
80
|
+
- `data` — a record mapping each input value to its resolved output.
|
|
81
|
+
- `errors` — inputs that could not be resolved.
|
|
82
|
+
|
|
83
|
+
Authentication and input-validation failures reject the call rather than being
|
|
84
|
+
included in `errors`.
|
|
85
|
+
|
|
86
|
+
## Build from this repository
|
|
87
|
+
|
|
88
|
+
From the repository root:
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
npm install
|
|
92
|
+
npm run build:handler
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The ESM bundle, source map, and TypeScript declarations are written to `dist`.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as _orpc_server from '@orpc/server';
|
|
2
|
+
import { RouterClient } from '@orpc/server';
|
|
3
|
+
import * as zod_v4_core from 'zod/v4/core';
|
|
4
|
+
import * as zod from 'zod';
|
|
5
|
+
import * as _usu_accessibility_auth_service_handler from '@usu-accessibility/auth-service-handler';
|
|
6
|
+
|
|
7
|
+
declare const router: {
|
|
8
|
+
anumber: {
|
|
9
|
+
encrypt: _orpc_server.DecoratedProcedure<{
|
|
10
|
+
headers: Headers;
|
|
11
|
+
} & object, {
|
|
12
|
+
user: {
|
|
13
|
+
type: "user";
|
|
14
|
+
user: _usu_accessibility_auth_service_handler.Session["user"];
|
|
15
|
+
} | {
|
|
16
|
+
type: "api_key";
|
|
17
|
+
user: {
|
|
18
|
+
aNumber?: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
}, zod.ZodObject<{
|
|
22
|
+
aNumbers: zod.ZodArray<zod.ZodString>;
|
|
23
|
+
}, zod_v4_core.$strip>, zod.ZodObject<{
|
|
24
|
+
data: zod.ZodRecord<zod.ZodString, zod.ZodString>;
|
|
25
|
+
errors: zod.ZodArray<zod.ZodString>;
|
|
26
|
+
}, zod_v4_core.$strip>, Record<never, never>>;
|
|
27
|
+
decrypt: _orpc_server.DecoratedProcedure<{
|
|
28
|
+
headers: Headers;
|
|
29
|
+
} & object, {
|
|
30
|
+
user: {
|
|
31
|
+
type: "user";
|
|
32
|
+
user: _usu_accessibility_auth_service_handler.Session["user"];
|
|
33
|
+
} | {
|
|
34
|
+
type: "api_key";
|
|
35
|
+
user: {
|
|
36
|
+
aNumber?: string;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
}, zod.ZodObject<{
|
|
40
|
+
ids: zod.ZodArray<zod.ZodString>;
|
|
41
|
+
}, zod_v4_core.$strip>, zod.ZodObject<{
|
|
42
|
+
data: zod.ZodRecord<zod.ZodString, zod.ZodString>;
|
|
43
|
+
errors: zod.ZodArray<zod.ZodString>;
|
|
44
|
+
}, zod_v4_core.$strip>, Record<never, never>>;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
type AppRouter = typeof router;
|
|
48
|
+
type Client = RouterClient<AppRouter>;
|
|
49
|
+
|
|
50
|
+
type CreateAnumberHandlerOptions = {
|
|
51
|
+
baseUrl?: string;
|
|
52
|
+
authToken?: string;
|
|
53
|
+
};
|
|
54
|
+
declare function createAnumberHandler(options?: CreateAnumberHandlerOptions): Client;
|
|
55
|
+
|
|
56
|
+
export { type Client, type CreateAnumberHandlerOptions, createAnumberHandler };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { createORPCClient } from "@orpc/client";
|
|
3
|
+
import { RPCLink } from "@orpc/client/fetch";
|
|
4
|
+
function resolveOptions(options) {
|
|
5
|
+
const baseUrl = options?.baseUrl ?? process.env.ANUMBER_SERVICE_URL;
|
|
6
|
+
const authToken = options?.authToken ?? process.env.ANUMBER_SERVICE_AUTH_TOKEN;
|
|
7
|
+
if (!baseUrl) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
"Missing baseUrl: pass options.baseUrl or set ANUMBER_SERVICE_URL"
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
if (!authToken) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
"Missing authToken: pass options.authToken or set ANUMBER_SERVICE_AUTH_TOKEN"
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
return { baseUrl, authToken };
|
|
18
|
+
}
|
|
19
|
+
function createAnumberHandler(options) {
|
|
20
|
+
const resolved = resolveOptions(options);
|
|
21
|
+
const link = new RPCLink({
|
|
22
|
+
origin: resolved.baseUrl.replace(/\/$/, ""),
|
|
23
|
+
url: "/rpc",
|
|
24
|
+
headers: {
|
|
25
|
+
Authorization: `Bearer ${resolved.authToken}`
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return createORPCClient(link);
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
createAnumberHandler
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { createORPCClient } from \"@orpc/client\";\nimport { RPCLink } from \"@orpc/client/fetch\";\nimport type { Client } from \"@anumber-service/web/rpc\";\n\nexport type { Client };\n\nexport type CreateAnumberHandlerOptions = {\n baseUrl?: string;\n authToken?: string;\n};\n\nfunction resolveOptions(options?: CreateAnumberHandlerOptions) {\n const baseUrl = options?.baseUrl ?? process.env.ANUMBER_SERVICE_URL;\n const authToken =\n options?.authToken ?? process.env.ANUMBER_SERVICE_AUTH_TOKEN;\n\n if (!baseUrl) {\n throw new Error(\n \"Missing baseUrl: pass options.baseUrl or set ANUMBER_SERVICE_URL\",\n );\n }\n\n if (!authToken) {\n throw new Error(\n \"Missing authToken: pass options.authToken or set ANUMBER_SERVICE_AUTH_TOKEN\",\n );\n }\n\n return { baseUrl, authToken };\n}\n\nexport function createAnumberHandler(\n options?: CreateAnumberHandlerOptions,\n): Client {\n const resolved = resolveOptions(options);\n\n const link = new RPCLink({\n origin: resolved.baseUrl.replace(/\\/$/, \"\"),\n url: \"/rpc\",\n headers: {\n Authorization: `Bearer ${resolved.authToken}`,\n },\n });\n\n return createORPCClient(link) as Client;\n}\n"],"mappings":";AAAA,SAAS,wBAAwB;AACjC,SAAS,eAAe;AAUxB,SAAS,eAAe,SAAuC;AAC7D,QAAM,UAAU,SAAS,WAAW,QAAQ,IAAI;AAChD,QAAM,YACJ,SAAS,aAAa,QAAQ,IAAI;AAEpC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,WAAW;AACd,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,UAAU;AAC9B;AAEO,SAAS,qBACd,SACQ;AACR,QAAM,WAAW,eAAe,OAAO;AAEvC,QAAM,OAAO,IAAI,QAAQ;AAAA,IACvB,QAAQ,SAAS,QAAQ,QAAQ,OAAO,EAAE;AAAA,IAC1C,KAAK;AAAA,IACL,SAAS;AAAA,MACP,eAAe,UAAU,SAAS,SAAS;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,SAAO,iBAAiB,IAAI;AAC9B;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usu-accessibility/anumber-service-handler",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsup"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@orpc/client": "2.0.0-beta.44",
|
|
21
|
+
"@orpc/server": "2.0.0-beta.44",
|
|
22
|
+
"@usu-accessibility/auth-service-handler": "^1.0.25",
|
|
23
|
+
"zod": "^4.6.7"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@anumber-service/web": "*",
|
|
27
|
+
"@types/node": "^20",
|
|
28
|
+
"tsup": "^8.5.0",
|
|
29
|
+
"typescript": "^5.8.3"
|
|
30
|
+
}
|
|
31
|
+
}
|