@fzgame/sdk 0.0.0-stage → 0.1.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/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2026 Fanzeal
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,139 @@
1
- # Temporary Holding Version
1
+ # @fzgame/sdk
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
+ Typed client for the GameHub server API. The types come from the server's own OpenAPI document, so
4
+ every path, parameter, and response you touch is checked at compile time.
5
+
6
+ The client is `openapi-fetch` underneath and has no other runtime dependency. The root entry works in
7
+ Node and in the browser; the optional `@fzgame/sdk/react` entry adds a React component for apps that
8
+ want the client configured from a component tree.
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ pnpm add @fzgame/sdk
14
+ ```
15
+
16
+ React is a peer dependency, and only the `/react` entry needs it. Install React 18.2 or 19 if you use
17
+ that entry.
18
+
19
+ ## Where credentials may live
20
+
21
+ An app key and app secret authorize an *application*, so they belong to server-side code. Anything
22
+ marked `NEXT_PUBLIC_*` is inlined into the browser bundle your players download, which publishes the
23
+ secret. In a browser, keep the secret on your own backend and send the player a short-lived token
24
+ instead.
25
+
26
+ ## Configure a client
27
+
28
+ `initializeSDK` sets the process-wide client that `fetchClient` proxies to:
29
+
30
+ ```ts
31
+ import { fetchClient, initializeSDK } from '@fzgame/sdk'
32
+
33
+ initializeSDK({
34
+ apiUrl: 'https://api.example.com',
35
+ appKey: process.env.FZ_APP_KEY,
36
+ appSecret: process.env.FZ_APP_SECRET,
37
+ })
38
+
39
+ const { data, error } = await fetchClient.GET('/sdk/app/current')
40
+ ```
41
+
42
+ `createSdkClient` returns an independent client, which is what to use when one process serves more
43
+ than one app:
44
+
45
+ ```ts
46
+ import { createSdkClient } from '@fzgame/sdk'
47
+
48
+ const tenantA = createSdkClient({ apiUrl: 'https://api.example.com', appKey: 'a', appSecret: 'sa' })
49
+ const tenantB = createSdkClient({ apiUrl: 'https://api.example.com', appKey: 'b', appSecret: 'sb' })
50
+ ```
51
+
52
+ From React:
53
+
54
+ ```tsx
55
+ import { SDKInitializer } from '@fzgame/sdk/react'
56
+
57
+ export function Providers() {
58
+ return <SDKInitializer apiUrl="https://api.example.com" appKey="..." appSecret="..." />
59
+ }
60
+ ```
61
+
62
+ The effect depends on each value, so a rotated secret or a tenant switch reconfigures the client
63
+ instead of being dropped after the first render.
64
+
65
+ ### `InitOptions`
66
+
67
+ | Option | Type | Meaning |
68
+ | --- | --- | --- |
69
+ | `apiUrl` | `string` | Base URL of the API. Required; a trailing slash is trimmed. |
70
+ | `appKey` | `string` | Value of the `x-app-key` header: the app's `id`, which is what the guard looks the app up by. |
71
+ | `appSecret` | `string` | Value of the `x-app-secret` header: one of the app's credential `clientSecret` values. |
72
+ | `timeoutMs` | `number` | Abort a request after this many milliseconds. `0` or unset means no deadline. |
73
+ | `fetch` | `typeof fetch` | Override the fetch implementation, for a Node polyfill or a test. |
74
+
75
+ Credentials travel in headers, which the server's OpenAPI document does not declare, so attach them
76
+ with `initializeSDK` or `createSdkClient` rather than by hand. The exported header names are
77
+ `APP_KEY_HEADER` (`x-app-key`) and `APP_SECRET_HEADER` (`x-app-secret`) if you need to set them
78
+ yourself.
79
+
80
+ A timeout is combined with any `AbortSignal` you pass to a request, so your own cancellation keeps
81
+ working.
82
+
83
+ ## Errors
84
+
85
+ | Error | Thrown when |
86
+ | --- | --- |
87
+ | `SdkConfigError` | `apiUrl` is missing or blank. |
88
+ | `SdkNotInitializedError` | A call on `fetchClient` happens before `initializeSDK` or `<SDKInitializer>` ran. |
89
+
90
+ Both are exported so a caller can branch on them. `fetchClient` throws rather than sending a request
91
+ to a placeholder origin, so a mis-ordered import fails where it happens.
92
+
93
+ Failed requests do not throw: `openapi-fetch` returns `{ data, error }`, and `error` carries the
94
+ status and the parsed body.
95
+
96
+ ## Types
97
+
98
+ `@fzgame/sdk` re-exports the generated types, so you can name a response shape without importing the
99
+ document separately:
100
+
101
+ ```ts
102
+ import type { components, paths } from '@fzgame/sdk'
103
+
104
+ type App = components['schemas']['App']
105
+ type GameInstanceId = paths['/sdk/game-instances/{id}']['get']['parameters']['path']['id']
106
+ ```
107
+
108
+ `src/types/schema.d.ts` is generated from the server document that the workspace build writes to
109
+ `apps/server/public/openapi-sdk.json`. Regenerate it after a server API change:
110
+
111
+ ```bash
112
+ pnpm --filter @fzgame/sdk compile
113
+ ```
114
+
115
+ That path is inside this monorepo, so the script runs for contributors here. Consumers of the
116
+ published package get the types that were generated at release time.
117
+
118
+ ## Entry points
119
+
120
+ | Specifier | Contents |
121
+ | --- | --- |
122
+ | `@fzgame/sdk` | Client, errors, header names, generated types. No React. |
123
+ | `@fzgame/sdk/react` | `SDKInitializer`. Requires React 18.2 or 19. |
124
+ | `@fzgame/sdk/package.json` | The manifest, for tooling that reads it. |
125
+
126
+ Both entries ship ESM and CommonJS, each with matching type declarations.
127
+
128
+ ## Development
129
+
130
+ ```bash
131
+ pnpm --filter @fzgame/sdk check-types
132
+ pnpm --filter @fzgame/sdk test:run
133
+ pnpm --filter @fzgame/sdk build
134
+ pnpm --filter @fzgame/sdk smoke # packs the tarball and consumes it from CJS and ESM
135
+ ```
136
+
137
+ ## License
138
+
139
+ ISC