@wvdsh/api 0.1.48 → 0.1.49

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.
@@ -207,6 +207,28 @@ export declare const UrlParams: {
207
207
  readonly SdkConfig: "sdkconfig";
208
208
  readonly Caller: "caller";
209
209
  readonly GameSlug: "gameSlug";
210
+ readonly UgcUploadExpires: "exp";
211
+ readonly UgcUploadSignature: "sig";
212
+ };
213
+ /** @internal UGC/userfs storage contract shared by Convex and the play worker — not game-facing API. */
214
+ export declare const UgcStorage: {
215
+ readonly KEY_INFIX: "/ugcid/";
216
+ readonly buildKey: (gameCloudId: GenericId<"gameClouds">, uuid: string) => string;
217
+ readonly isUgcKey: (key: string) => boolean;
218
+ readonly USERFS_INFIX: "/userfs/";
219
+ readonly userfsPrefix: (gameCloudId: GenericId<"gameClouds">, userId: GenericId<"users">) => string;
220
+ readonly parseUserfsKey: (key: string) => {
221
+ gameCloudId: GenericId<"gameClouds">;
222
+ userId: GenericId<"users">;
223
+ path: string;
224
+ } | null;
225
+ readonly buildUploadSignaturePayload: (args: {
226
+ exp: string | number;
227
+ sub: string;
228
+ objectKey: string;
229
+ }) => string;
230
+ readonly encodeKeyPath: (objectKey: string) => string;
231
+ readonly decodeKeyPath: (pathname: string) => string;
210
232
  };
211
233
  export declare const PlayRouteCaller: {
212
234
  readonly Wavedash: "wavedash";
@@ -130,7 +130,62 @@ export const UrlParams = {
130
130
  SdkConfig: 'sdkconfig',
131
131
  Caller: 'caller',
132
132
  // Read by the cross-origin play iframe for its Sentry tags — it can't read this URL.
133
- GameSlug: 'gameSlug'
133
+ GameSlug: 'gameSlug',
134
+ // Signed upload URL params authorizing a UGC/userfs PUT (see createUgcUploadUrl).
135
+ UgcUploadExpires: 'exp',
136
+ UgcUploadSignature: 'sig'
137
+ };
138
+ /** @internal UGC/userfs storage contract shared by Convex and the play worker — not game-facing API. */
139
+ export const UgcStorage = {
140
+ // UGC keys: `{gameCloudId}/ugcid/{uuid}`
141
+ KEY_INFIX: '/ugcid/',
142
+ buildKey(gameCloudId, uuid) {
143
+ return `${gameCloudId}${UgcStorage.KEY_INFIX}${uuid}`;
144
+ },
145
+ // Cheap UGC-vs-userfs classifier used by the R2 event webhook
146
+ isUgcKey(key) {
147
+ return key.indexOf(UgcStorage.KEY_INFIX) > 0;
148
+ },
149
+ // userfs (cloud-save) keys: `{gameCloudId}/userfs/{userId}/{path}`
150
+ USERFS_INFIX: '/userfs/',
151
+ // R2 key prefix covering all of a user's cloud saves in a game cloud
152
+ userfsPrefix(gameCloudId, userId) {
153
+ return `${gameCloudId}${UgcStorage.USERFS_INFIX}${userId}/`;
154
+ },
155
+ // Inverse of userfsPrefix; null when the key isn't a userfs key
156
+ parseUserfsKey(key) {
157
+ const infix = key.indexOf(UgcStorage.USERFS_INFIX);
158
+ if (infix <= 0)
159
+ return null;
160
+ const gameCloudId = key.slice(0, infix);
161
+ const afterInfix = key.slice(infix + UgcStorage.USERFS_INFIX.length);
162
+ const slash = afterInfix.indexOf('/');
163
+ if (slash <= 0)
164
+ return null;
165
+ const userId = afterInfix.slice(0, slash);
166
+ const path = afterInfix.slice(slash + 1);
167
+ if (!path)
168
+ return null;
169
+ return { gameCloudId, userId, path };
170
+ },
171
+ // Signed into upload URLs; digits-only exp + fixed-length sub keep the split unambiguous
172
+ buildUploadSignaturePayload(args) {
173
+ return `${args.exp}@${args.sub}@${args.objectKey}`;
174
+ },
175
+ // Object key → URL path, per segment so keys never encode to `%2F`
176
+ encodeKeyPath(objectKey) {
177
+ return objectKey.split('/').map(encodeURIComponent).join('/');
178
+ },
179
+ // Inverse of encodeKeyPath; malformed escapes fall back to the raw path (matches the worker)
180
+ decodeKeyPath(pathname) {
181
+ const rawPath = pathname.startsWith('/') ? pathname.slice(1) : pathname;
182
+ try {
183
+ return decodeURIComponent(rawPath);
184
+ }
185
+ catch {
186
+ return rawPath;
187
+ }
188
+ }
134
189
  };
135
190
  export const PlayRouteCaller = {
136
191
  Wavedash: 'wavedash'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wvdsh/api",
3
- "version": "0.1.48",
3
+ "version": "0.1.49",
4
4
  "description": "Public API types and shared constants for the Wavedash platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",