@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 CHANGED
@@ -1,3 +1,95 @@
1
- # Temporary Holding Version
1
+ # `@usu-accessibility/anumber-service-handler`
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
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`.
@@ -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": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
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
+ }