cajonzero 0.1.1 → 0.1.2
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 +13 -15
- package/dist/bin/cj0.js +403 -87
- package/dist/{config-YtU8BYQM.d.ts → config-BOzAyP7m.d.ts} +1 -1
- package/dist/core.d.ts +3 -3
- package/dist/core.js +9 -39
- package/dist/index.d.ts +5 -5
- package/dist/index.js +10 -68
- package/dist/{providers-Dh-umPQ6.d.ts → providers-BX7e4pNW.d.ts} +3 -17
- package/dist/scaffold.d.ts +60 -2
- package/dist/scaffold.js +306 -79
- package/dist/serve.d.ts +2 -2
- package/dist/serve.js +10 -68
- package/dist/ui/assets/index-Bhv7LV8L.css +2 -0
- package/dist/ui/assets/index-CaAHje8X.js +4404 -0
- package/dist/ui/assets/{main-DrPj1s7t.js → main-BeABKxzY.js} +26 -26
- package/dist/ui/index.html +2 -2
- package/package.json +7 -6
- package/dist/bin/cj0.js.map +0 -1
- package/dist/core.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/scaffold.js.map +0 -1
- package/dist/serve.js.map +0 -1
- package/dist/ui/assets/index-8g0ogAbk.js +0 -4404
- package/dist/ui/assets/index-W1HlDaw6.css +0 -2
package/dist/core.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { M as MapEntry, W as WorldSeed } from './providers-
|
|
2
|
-
export { c as EMPTY_MAP_CATALOG, E as EnvProvider, d as MapCatalog, e as Repos, R as Room, f as RoomOptions, g as RuntimeProviders, h as SETTINGS, i as SETTING_KEYS, a as SettingDefaults, j as SettingDefinition, k as Settings, l as SettingsError, m as SettingsErrorCode, n as SettingsService, o as StorageFactory, S as StorageSource, p as Store, q as WorldSeedReader, r as configureDefaultKV, s as createMemoryStore, t as createRepos, u as createSettingsService, v as createStore, w as findMap, x as getRuntimeProviders, y as isSettingKey, z as memoryDriver, A as parseMapCatalog, B as resolveAdminToken, C as resolveEnvironment, F as resolveRooms, G as resolveSessionSecret, H as resolveSettingDefaults, I as resolveStore, J as setRuntimeProviders, K as setStorageFactory } from './providers-
|
|
3
|
-
export { C as CajonzeroConfig, D as DEFAULT_CONFIG, G as GAME_NET_INBOUND_BASE, a as GAME_NET_OUTBOUND_BASE, I as INBOUND_LAYOUT, M as MAX_INBOUND_FRAME_BYTES, b as MapsConfig, N as NetCodec, c as NetCodecError, d as NetCodecErrorCode, e as NetCodecHandlers, f as NetCodecOptions, O as OFFICIAL_PREFIX, g as OUTBOUND_LAYOUT, P as ProtocolDirection, h as ProtocolLayout, i as ProtocolSchemaLike, R as RoomConfig, j as chainLayouts, l as layoutMessages, k as layoutProtocol, m as matchesLayout, n as messageIds, o as messageNameAt, r as readNetFrameHeader, p as readNetMessageType, q as resolveConfig } from './config-
|
|
1
|
+
import { M as MapEntry, W as WorldSeed } from './providers-BX7e4pNW.js';
|
|
2
|
+
export { c as EMPTY_MAP_CATALOG, E as EnvProvider, d as MapCatalog, e as Repos, R as Room, f as RoomOptions, g as RuntimeProviders, h as SETTINGS, i as SETTING_KEYS, a as SettingDefaults, j as SettingDefinition, k as Settings, l as SettingsError, m as SettingsErrorCode, n as SettingsService, o as StorageFactory, S as StorageSource, p as Store, q as WorldSeedReader, r as configureDefaultKV, s as createMemoryStore, t as createRepos, u as createSettingsService, v as createStore, w as findMap, x as getRuntimeProviders, y as isSettingKey, z as memoryDriver, A as parseMapCatalog, B as resolveAdminToken, C as resolveEnvironment, F as resolveRooms, G as resolveSessionSecret, H as resolveSettingDefaults, I as resolveStore, J as setRuntimeProviders, K as setStorageFactory } from './providers-BX7e4pNW.js';
|
|
3
|
+
export { C as CajonzeroConfig, D as DEFAULT_CONFIG, G as GAME_NET_INBOUND_BASE, a as GAME_NET_OUTBOUND_BASE, I as INBOUND_LAYOUT, M as MAX_INBOUND_FRAME_BYTES, b as MapsConfig, N as NetCodec, c as NetCodecError, d as NetCodecErrorCode, e as NetCodecHandlers, f as NetCodecOptions, O as OFFICIAL_PREFIX, g as OUTBOUND_LAYOUT, P as ProtocolDirection, h as ProtocolLayout, i as ProtocolSchemaLike, R as RoomConfig, j as chainLayouts, l as layoutMessages, k as layoutProtocol, m as matchesLayout, n as messageIds, o as messageNameAt, r as readNetFrameHeader, p as readNetMessageType, q as resolveConfig } from './config-BOzAyP7m.js';
|
|
4
4
|
import 'unstorage';
|
|
5
5
|
import 'gl-matrix';
|
|
6
6
|
import 'zod';
|
package/dist/core.js
CHANGED
|
@@ -4989,7 +4989,6 @@ var KEY_PREFIX = {
|
|
|
4989
4989
|
account: "account",
|
|
4990
4990
|
session: "session",
|
|
4991
4991
|
ban: "ban",
|
|
4992
|
-
ratelimit: "ratelimit",
|
|
4993
4992
|
settings: "settings",
|
|
4994
4993
|
mapStorage: "mapstorage"
|
|
4995
4994
|
};
|
|
@@ -5021,9 +5020,6 @@ function banAccountKey(subjectId) {
|
|
|
5021
5020
|
function banIdentityKey(kind, hash) {
|
|
5022
5021
|
return `ban:identity:${kind}:${seg2(hash)}`;
|
|
5023
5022
|
}
|
|
5024
|
-
function ratelimitKey(scope, hash) {
|
|
5025
|
-
return `ratelimit:${seg2(scope)}:${seg2(hash)}`;
|
|
5026
|
-
}
|
|
5027
5023
|
function settingsKey(key) {
|
|
5028
5024
|
return `settings:${seg2(key)}`;
|
|
5029
5025
|
}
|
|
@@ -5066,12 +5062,6 @@ function parseKey(key) {
|
|
|
5066
5062
|
}
|
|
5067
5063
|
return void 0;
|
|
5068
5064
|
}
|
|
5069
|
-
case KEY_PREFIX.ratelimit: {
|
|
5070
|
-
if (parts2.length !== 3) return void 0;
|
|
5071
|
-
const scope = decode(parts2[1]);
|
|
5072
|
-
const hash = decode(parts2[2]);
|
|
5073
|
-
return scope === void 0 || hash === void 0 ? void 0 : { kind: "ratelimit", scope, hash };
|
|
5074
|
-
}
|
|
5075
5065
|
case KEY_PREFIX.settings: {
|
|
5076
5066
|
if (parts2.length !== 2) return void 0;
|
|
5077
5067
|
const settingKey = decode(parts2[1]);
|
|
@@ -15214,34 +15204,6 @@ function banDetails(input, at) {
|
|
|
15214
15204
|
const expiresAt = input.expiresAt ?? (input.durationSeconds === void 0 ? void 0 : at + input.durationSeconds * 1e3);
|
|
15215
15205
|
return { reason: input.reason, expiresAt, createdBy: input.createdBy };
|
|
15216
15206
|
}
|
|
15217
|
-
function createRateLimitsRepo(store, now) {
|
|
15218
|
-
const repo = {
|
|
15219
|
-
async increment(scope, hash, options = {}) {
|
|
15220
|
-
const windowSeconds = Math.max(1, options.windowSeconds ?? 60);
|
|
15221
|
-
const amount = options.amount ?? 1;
|
|
15222
|
-
const at = now();
|
|
15223
|
-
const current = await repo.get(scope, hash);
|
|
15224
|
-
const windowStart = current !== void 0 && current.expiresAt > at ? current.windowStart : at;
|
|
15225
|
-
const expiresAt = windowStart + windowSeconds * 1e3;
|
|
15226
|
-
const next = {
|
|
15227
|
-
count: (current !== void 0 && current.expiresAt > at ? current.count : 0) + amount,
|
|
15228
|
-
windowStart,
|
|
15229
|
-
expiresAt
|
|
15230
|
-
};
|
|
15231
|
-
const ttl = Math.max(1, Math.ceil((expiresAt - at) / 1e3));
|
|
15232
|
-
await store.setItem(ratelimitKey(scope, hash), next, { ttl });
|
|
15233
|
-
return next;
|
|
15234
|
-
},
|
|
15235
|
-
async get(scope, hash) {
|
|
15236
|
-
const record = await store.getItem(ratelimitKey(scope, hash));
|
|
15237
|
-
return record ?? void 0;
|
|
15238
|
-
},
|
|
15239
|
-
async reset(scope, hash) {
|
|
15240
|
-
await store.removeItem(ratelimitKey(scope, hash));
|
|
15241
|
-
}
|
|
15242
|
-
};
|
|
15243
|
-
return repo;
|
|
15244
|
-
}
|
|
15245
15207
|
function createSettingsRepo(store) {
|
|
15246
15208
|
return {
|
|
15247
15209
|
async get(key) {
|
|
@@ -15506,7 +15468,6 @@ function createRepos(store, options = {}) {
|
|
|
15506
15468
|
accounts: createAccountsRepo(store, now),
|
|
15507
15469
|
sessions: createSessionsRepo(store, now),
|
|
15508
15470
|
bans: createBansRepo(store, now),
|
|
15509
|
-
ratelimits: createRateLimitsRepo(store, now),
|
|
15510
15471
|
settings: createSettingsRepo(store),
|
|
15511
15472
|
mapStorage: (scope, namespace) => createMapStorageRepo(store, {
|
|
15512
15473
|
scope,
|
|
@@ -16660,6 +16621,8 @@ var Room = class {
|
|
|
16660
16621
|
mapLoading;
|
|
16661
16622
|
worldReady = false;
|
|
16662
16623
|
snapshotRestored = false;
|
|
16624
|
+
/** One-shot guard for the "proof without sessionSecret" diagnostic. */
|
|
16625
|
+
guestWarningLogged = false;
|
|
16663
16626
|
persistence;
|
|
16664
16627
|
socketsStarted = false;
|
|
16665
16628
|
perf = { minPing: 0, maxPing: 0, avgPing: 0, pingCount: 0 };
|
|
@@ -17005,6 +16968,13 @@ var Room = class {
|
|
|
17005
16968
|
this.pendingIdentities.set(sessionId, identity2);
|
|
17006
16969
|
}
|
|
17007
16970
|
} else {
|
|
16971
|
+
const proof = extractSessionProof(request.headers.get("sec-websocket-protocol"));
|
|
16972
|
+
if (proof !== void 0 && !this.guestWarningLogged) {
|
|
16973
|
+
this.guestWarningLogged = true;
|
|
16974
|
+
this.logger.error(
|
|
16975
|
+
"cajonzero: a session proof was supplied but no sessionSecret is configured; players join as guest. Pass serve({ sessionSecret: (env) => env.<SECRET> })."
|
|
16976
|
+
);
|
|
16977
|
+
}
|
|
17008
16978
|
identity2 = guestIdentity(sessionId);
|
|
17009
16979
|
}
|
|
17010
16980
|
const ip = resolveClientIp(request);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Context, Hono } from 'hono';
|
|
2
2
|
import { ContentfulStatusCode } from 'hono/utils/http-status';
|
|
3
|
-
import { b as Env, d as MapCatalog, e as Repos, L as SessionsRepo, D as DurableObjectNamespace } from './providers-
|
|
3
|
+
import { b as Env, d as MapCatalog, e as Repos, L as SessionsRepo, D as DurableObjectNamespace } from './providers-BX7e4pNW.js';
|
|
4
4
|
import { Store, SettingDefaults } from './core.js';
|
|
5
|
-
export { c as EMPTY_MAP_CATALOG, M as MapEntry, R as Room, w as findMap, A as parseMapCatalog } from './providers-
|
|
6
|
-
import { C as CajonzeroConfig } from './config-
|
|
7
|
-
export { D as DEFAULT_CONFIG, G as GAME_NET_INBOUND_BASE, a as GAME_NET_OUTBOUND_BASE, b as MapsConfig, N as NetCodec, e as NetCodecHandlers, R as RoomConfig, q as resolveConfig } from './config-
|
|
5
|
+
export { c as EMPTY_MAP_CATALOG, M as MapEntry, R as Room, w as findMap, A as parseMapCatalog } from './providers-BX7e4pNW.js';
|
|
6
|
+
import { C as CajonzeroConfig } from './config-BOzAyP7m.js';
|
|
7
|
+
export { D as DEFAULT_CONFIG, G as GAME_NET_INBOUND_BASE, a as GAME_NET_OUTBOUND_BASE, b as MapsConfig, N as NetCodec, e as NetCodecHandlers, R as RoomConfig, q as resolveConfig } from './config-BOzAyP7m.js';
|
|
8
8
|
export { DO_CLASSES, ServeOptions, WorkersEntry, WorkersModule, serve } from './serve.js';
|
|
9
9
|
import 'unstorage';
|
|
10
10
|
import 'gl-matrix';
|
|
@@ -18,7 +18,7 @@ import 'zod';
|
|
|
18
18
|
* can read the version without creating a circular import.
|
|
19
19
|
*/
|
|
20
20
|
declare const NAME = "cajonzero";
|
|
21
|
-
declare const VERSION = "0.1.
|
|
21
|
+
declare const VERSION = "0.1.1";
|
|
22
22
|
|
|
23
23
|
/** The authenticated principal carried by a login session (T11 supplies it). */
|
|
24
24
|
interface SessionIdentity {
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ import 'unstorage/drivers/memory';
|
|
|
11
11
|
|
|
12
12
|
// src/version.ts
|
|
13
13
|
var NAME = "cajonzero";
|
|
14
|
-
var VERSION = "0.1.
|
|
14
|
+
var VERSION = "0.1.1";
|
|
15
15
|
|
|
16
16
|
// src/core/config.ts
|
|
17
17
|
var ConfigError = class extends Error {
|
|
@@ -288,7 +288,6 @@ var KEY_PREFIX = {
|
|
|
288
288
|
account: "account",
|
|
289
289
|
session: "session",
|
|
290
290
|
ban: "ban",
|
|
291
|
-
ratelimit: "ratelimit",
|
|
292
291
|
settings: "settings",
|
|
293
292
|
mapStorage: "mapstorage"
|
|
294
293
|
};
|
|
@@ -320,9 +319,6 @@ function banAccountKey(subjectId) {
|
|
|
320
319
|
function banIdentityKey(kind, hash) {
|
|
321
320
|
return `ban:identity:${kind}:${seg(hash)}`;
|
|
322
321
|
}
|
|
323
|
-
function ratelimitKey(scope, hash) {
|
|
324
|
-
return `ratelimit:${seg(scope)}:${seg(hash)}`;
|
|
325
|
-
}
|
|
326
322
|
function settingsKey(key) {
|
|
327
323
|
return `settings:${seg(key)}`;
|
|
328
324
|
}
|
|
@@ -365,12 +361,6 @@ function parseKey(key) {
|
|
|
365
361
|
}
|
|
366
362
|
return void 0;
|
|
367
363
|
}
|
|
368
|
-
case KEY_PREFIX.ratelimit: {
|
|
369
|
-
if (parts2.length !== 3) return void 0;
|
|
370
|
-
const scope = decode(parts2[1]);
|
|
371
|
-
const hash = decode(parts2[2]);
|
|
372
|
-
return scope === void 0 || hash === void 0 ? void 0 : { kind: "ratelimit", scope, hash };
|
|
373
|
-
}
|
|
374
364
|
case KEY_PREFIX.settings: {
|
|
375
365
|
if (parts2.length !== 2) return void 0;
|
|
376
366
|
const settingKey = decode(parts2[1]);
|
|
@@ -594,34 +584,6 @@ function banDetails(input, at) {
|
|
|
594
584
|
const expiresAt = input.expiresAt ?? (input.durationSeconds === void 0 ? void 0 : at + input.durationSeconds * 1e3);
|
|
595
585
|
return { reason: input.reason, expiresAt, createdBy: input.createdBy };
|
|
596
586
|
}
|
|
597
|
-
function createRateLimitsRepo(store, now) {
|
|
598
|
-
const repo = {
|
|
599
|
-
async increment(scope, hash, options = {}) {
|
|
600
|
-
const windowSeconds = Math.max(1, options.windowSeconds ?? 60);
|
|
601
|
-
const amount = options.amount ?? 1;
|
|
602
|
-
const at = now();
|
|
603
|
-
const current = await repo.get(scope, hash);
|
|
604
|
-
const windowStart = current !== void 0 && current.expiresAt > at ? current.windowStart : at;
|
|
605
|
-
const expiresAt = windowStart + windowSeconds * 1e3;
|
|
606
|
-
const next = {
|
|
607
|
-
count: (current !== void 0 && current.expiresAt > at ? current.count : 0) + amount,
|
|
608
|
-
windowStart,
|
|
609
|
-
expiresAt
|
|
610
|
-
};
|
|
611
|
-
const ttl = Math.max(1, Math.ceil((expiresAt - at) / 1e3));
|
|
612
|
-
await store.setItem(ratelimitKey(scope, hash), next, { ttl });
|
|
613
|
-
return next;
|
|
614
|
-
},
|
|
615
|
-
async get(scope, hash) {
|
|
616
|
-
const record = await store.getItem(ratelimitKey(scope, hash));
|
|
617
|
-
return record ?? void 0;
|
|
618
|
-
},
|
|
619
|
-
async reset(scope, hash) {
|
|
620
|
-
await store.removeItem(ratelimitKey(scope, hash));
|
|
621
|
-
}
|
|
622
|
-
};
|
|
623
|
-
return repo;
|
|
624
|
-
}
|
|
625
587
|
function createSettingsRepo(store) {
|
|
626
588
|
return {
|
|
627
589
|
async get(key) {
|
|
@@ -886,7 +848,6 @@ function createRepos(store, options = {}) {
|
|
|
886
848
|
accounts: createAccountsRepo(store, now),
|
|
887
849
|
sessions: createSessionsRepo(store, now),
|
|
888
850
|
bans: createBansRepo(store, now),
|
|
889
|
-
ratelimits: createRateLimitsRepo(store, now),
|
|
890
851
|
settings: createSettingsRepo(store),
|
|
891
852
|
mapStorage: (scope, namespace) => createMapStorageRepo(store, {
|
|
892
853
|
scope,
|
|
@@ -9331,8 +9292,6 @@ var skinRegistry = new SkinRegistry();
|
|
|
9331
9292
|
|
|
9332
9293
|
// src/core/identity/account-routes.ts
|
|
9333
9294
|
var SESSION_COOKIE_NAME = "cajonzero_session";
|
|
9334
|
-
var RATE_LIMIT_MAX_ATTEMPTS = 5;
|
|
9335
|
-
var RATE_LIMIT_WINDOW_SECONDS = 300;
|
|
9336
9295
|
var USERNAME_PATTERN = /^[a-zA-Z][a-zA-Z0-9_]{2,31}$/;
|
|
9337
9296
|
var MIN_PASSWORD_LENGTH = 10;
|
|
9338
9297
|
var MAX_PASSWORD_LENGTH = 128;
|
|
@@ -9401,22 +9360,6 @@ function clientIp(request) {
|
|
|
9401
9360
|
}
|
|
9402
9361
|
return "unknown";
|
|
9403
9362
|
}
|
|
9404
|
-
async function enforceAttempts(c, deps, attempts) {
|
|
9405
|
-
let retryAfter = null;
|
|
9406
|
-
for (const attempt of attempts) {
|
|
9407
|
-
const state = await deps.ratelimits.increment(attempt.scope, attempt.key, {
|
|
9408
|
-
windowSeconds: RATE_LIMIT_WINDOW_SECONDS
|
|
9409
|
-
});
|
|
9410
|
-
if (state.count > RATE_LIMIT_MAX_ATTEMPTS) {
|
|
9411
|
-
const seconds = Math.max(1, Math.ceil((state.expiresAt - deps.now()) / 1e3));
|
|
9412
|
-
retryAfter = retryAfter === null ? seconds : Math.max(retryAfter, seconds);
|
|
9413
|
-
}
|
|
9414
|
-
}
|
|
9415
|
-
if (retryAfter !== null) {
|
|
9416
|
-
c.header("Retry-After", String(retryAfter));
|
|
9417
|
-
throw new HttpError(429, "rate_limited");
|
|
9418
|
-
}
|
|
9419
|
-
}
|
|
9420
9363
|
async function issueSession(c, deps, account, ip) {
|
|
9421
9364
|
const minted = await mintSessionToken(
|
|
9422
9365
|
{
|
|
@@ -9449,10 +9392,6 @@ function accountRoutes(deps) {
|
|
|
9449
9392
|
const username = body.username;
|
|
9450
9393
|
const password = body.password;
|
|
9451
9394
|
const ip = clientIp(c.req.raw);
|
|
9452
|
-
await enforceAttempts(c, deps, [
|
|
9453
|
-
{ scope: "register-ip", key: ip },
|
|
9454
|
-
{ scope: "register-account", key: username.toLowerCase() }
|
|
9455
|
-
]);
|
|
9456
9395
|
const saltBytes = randomSalt();
|
|
9457
9396
|
const passwordHash = await derivePassword(password, saltBytes);
|
|
9458
9397
|
let account;
|
|
@@ -9477,11 +9416,6 @@ function accountRoutes(deps) {
|
|
|
9477
9416
|
const username = body.username;
|
|
9478
9417
|
const password = body.password;
|
|
9479
9418
|
const ip = clientIp(c.req.raw);
|
|
9480
|
-
const attempts = [{ scope: "login-ip", key: ip }];
|
|
9481
|
-
if (username.length > 0) {
|
|
9482
|
-
attempts.push({ scope: "login-account", key: username.toLowerCase() });
|
|
9483
|
-
}
|
|
9484
|
-
await enforceAttempts(c, deps, attempts);
|
|
9485
9419
|
const account = username.length > 0 ? await deps.accounts.getByUsername(username) : void 0;
|
|
9486
9420
|
if (account === void 0 || account.disabled) {
|
|
9487
9421
|
await dummyVerify(password);
|
|
@@ -10180,7 +10114,6 @@ function registerRoutes(app, deps) {
|
|
|
10180
10114
|
now: deps.now,
|
|
10181
10115
|
accounts: repos.accounts,
|
|
10182
10116
|
sessions: repos.sessions,
|
|
10183
|
-
ratelimits: repos.ratelimits,
|
|
10184
10117
|
getSession,
|
|
10185
10118
|
sessionSecret: deps.sessionSecret,
|
|
10186
10119
|
environment: deps.environment,
|
|
@@ -24633,6 +24566,8 @@ var Room = class {
|
|
|
24633
24566
|
mapLoading;
|
|
24634
24567
|
worldReady = false;
|
|
24635
24568
|
snapshotRestored = false;
|
|
24569
|
+
/** One-shot guard for the "proof without sessionSecret" diagnostic. */
|
|
24570
|
+
guestWarningLogged = false;
|
|
24636
24571
|
persistence;
|
|
24637
24572
|
socketsStarted = false;
|
|
24638
24573
|
perf = { minPing: 0, maxPing: 0, avgPing: 0, pingCount: 0 };
|
|
@@ -24978,6 +24913,13 @@ var Room = class {
|
|
|
24978
24913
|
this.pendingIdentities.set(sessionId, identity2);
|
|
24979
24914
|
}
|
|
24980
24915
|
} else {
|
|
24916
|
+
const proof = extractSessionProof(request.headers.get("sec-websocket-protocol"));
|
|
24917
|
+
if (proof !== void 0 && !this.guestWarningLogged) {
|
|
24918
|
+
this.guestWarningLogged = true;
|
|
24919
|
+
this.logger.error(
|
|
24920
|
+
"cajonzero: a session proof was supplied but no sessionSecret is configured; players join as guest. Pass serve({ sessionSecret: (env) => env.<SECRET> })."
|
|
24921
|
+
);
|
|
24922
|
+
}
|
|
24981
24923
|
identity2 = guestIdentity(sessionId);
|
|
24982
24924
|
}
|
|
24983
24925
|
const ip = resolveClientIp(request);
|
|
@@ -199,7 +199,7 @@ declare function createMemoryStore(): Store;
|
|
|
199
199
|
* cajonzero — typed repositories over the unstorage layer (T4).
|
|
200
200
|
*
|
|
201
201
|
* Thin, dependency-injected repositories for the embedded account system
|
|
202
|
-
* (`accounts`, `sessions`, `bans
|
|
202
|
+
* (`accounts`, `sessions`, `bans`), runtime settings, and the
|
|
203
203
|
* map-script storage-kv API (`mapStorage`). Each is a small closure over a
|
|
204
204
|
* {@link Store}; no repository knows about HTTP, Hono, or Cloudflare globals, so
|
|
205
205
|
* every one is exercisable on the in-memory driver.
|
|
@@ -332,21 +332,6 @@ interface BansRepo {
|
|
|
332
332
|
deleteByKey(key: string): Promise<boolean>;
|
|
333
333
|
isActive(ban: BanRecord, at?: number): boolean;
|
|
334
334
|
}
|
|
335
|
-
/** Fixed-window rate-limit state. */
|
|
336
|
-
interface RateLimitState {
|
|
337
|
-
count: number;
|
|
338
|
-
windowStart: number;
|
|
339
|
-
expiresAt: number;
|
|
340
|
-
}
|
|
341
|
-
interface RateLimitIncrementOptions {
|
|
342
|
-
readonly windowSeconds?: number;
|
|
343
|
-
readonly amount?: number;
|
|
344
|
-
}
|
|
345
|
-
interface RateLimitsRepo {
|
|
346
|
-
increment(scope: string, hash: string, options?: RateLimitIncrementOptions): Promise<RateLimitState>;
|
|
347
|
-
get(scope: string, hash: string): Promise<RateLimitState | undefined>;
|
|
348
|
-
reset(scope: string, hash: string): Promise<void>;
|
|
349
|
-
}
|
|
350
335
|
interface SettingsRepo {
|
|
351
336
|
get<T = JSONValue>(key: string): Promise<T | undefined>;
|
|
352
337
|
set(key: string, value: JSONValue): Promise<void>;
|
|
@@ -384,7 +369,6 @@ interface Repos {
|
|
|
384
369
|
readonly accounts: AccountsRepo;
|
|
385
370
|
readonly sessions: SessionsRepo;
|
|
386
371
|
readonly bans: BansRepo;
|
|
387
|
-
readonly ratelimits: RateLimitsRepo;
|
|
388
372
|
readonly settings: SettingsRepo;
|
|
389
373
|
/** Builds a map-script storage repo for one `(scope, namespace)`. */
|
|
390
374
|
mapStorage(scope: string, namespace: string): MapStorageRepo;
|
|
@@ -5093,6 +5077,8 @@ declare class Room {
|
|
|
5093
5077
|
private mapLoading;
|
|
5094
5078
|
private worldReady;
|
|
5095
5079
|
private snapshotRestored;
|
|
5080
|
+
/** One-shot guard for the "proof without sessionSecret" diagnostic. */
|
|
5081
|
+
private guestWarningLogged;
|
|
5096
5082
|
private persistence;
|
|
5097
5083
|
private socketsStarted;
|
|
5098
5084
|
private perf;
|
package/dist/scaffold.d.ts
CHANGED
|
@@ -146,5 +146,63 @@ declare function toPackageName(folder: string): string;
|
|
|
146
146
|
*/
|
|
147
147
|
declare function createProject(folder: string, options?: CreateProjectOptions): ScaffoldResult;
|
|
148
148
|
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
/** Where one setup value is written. */
|
|
150
|
+
type SetupKind = "var" | "secret";
|
|
151
|
+
/** One configurable value. */
|
|
152
|
+
interface SetupField {
|
|
153
|
+
readonly name: string;
|
|
154
|
+
/** Chinese prompt label. */
|
|
155
|
+
readonly label: string;
|
|
156
|
+
readonly kind: SetupKind;
|
|
157
|
+
/** `true` for the values a project cannot run without. */
|
|
158
|
+
readonly required: boolean;
|
|
159
|
+
/** Default shown in the prompt (secrets: generated when absent). */
|
|
160
|
+
readonly default?: string;
|
|
161
|
+
/** Short explanation printed next to the prompt. */
|
|
162
|
+
readonly hint?: string;
|
|
163
|
+
}
|
|
164
|
+
/** Every value `setup` manages. */
|
|
165
|
+
declare const SETUP_FIELDS: readonly SetupField[];
|
|
166
|
+
/** Files `setup` touched. */
|
|
167
|
+
interface SetupResult {
|
|
168
|
+
readonly configPath: string;
|
|
169
|
+
readonly devVarsPath: string;
|
|
170
|
+
/** Non-secret values written to `wrangler.jsonc`. */
|
|
171
|
+
readonly vars: Record<string, string>;
|
|
172
|
+
/** Secrets written to `.dev.vars`. */
|
|
173
|
+
readonly secrets: Record<string, string>;
|
|
174
|
+
}
|
|
175
|
+
interface SetupOptions {
|
|
176
|
+
readonly cwd?: string;
|
|
177
|
+
/** Wrangler config path (default `wrangler.jsonc`). */
|
|
178
|
+
readonly configPath?: string;
|
|
179
|
+
/** Values to write; managed keys absent here are removed. */
|
|
180
|
+
readonly values: Readonly<Record<string, string>>;
|
|
181
|
+
}
|
|
182
|
+
/** Generated default for a required secret. */
|
|
183
|
+
declare function generateSecret(): string;
|
|
184
|
+
/** Generated default for the owner token (shorter, URL-safe). */
|
|
185
|
+
declare function generateAdminToken(): string;
|
|
186
|
+
/** Default value for a field when it has no configured value yet. */
|
|
187
|
+
declare function suggestedValue(field: SetupField): string | undefined;
|
|
188
|
+
/** Parse `.dev.vars` (`KEY=value`, `#` comments). */
|
|
189
|
+
declare function parseDevVars(text: string): Record<string, string>;
|
|
190
|
+
/** Serialize `.dev.vars` (stable order, trailing newline). */
|
|
191
|
+
declare function serializeDevVars(values: Record<string, string>): string;
|
|
192
|
+
/**
|
|
193
|
+
* Merge `vars` into the `wrangler.jsonc` `"vars"` object.
|
|
194
|
+
*
|
|
195
|
+
* Keys not managed by cajonzero are preserved; managed keys absent from `vars`
|
|
196
|
+
* are removed so clearing a setting falls back to its default.
|
|
197
|
+
*/
|
|
198
|
+
declare function setWranglerVars(raw: string, vars: Readonly<Record<string, string>>): string;
|
|
199
|
+
/** Read currently configured values (wrangler vars + `.dev.vars`). */
|
|
200
|
+
declare function readSetupValues(cwd: string, configPath: string, devVarsPath: string): Record<string, string>;
|
|
201
|
+
/**
|
|
202
|
+
* Apply the answers: non-secret values to `wrangler.jsonc`, secrets to
|
|
203
|
+
* `.dev.vars`. Throws when the project files are missing.
|
|
204
|
+
*/
|
|
205
|
+
declare function applySetup(options: SetupOptions): SetupResult;
|
|
206
|
+
|
|
207
|
+
export { SCAFFOLD_COMPATIBILITY_DATE, SCAFFOLD_CONFIG_CONTENT, SCAFFOLD_ENTRY_CONTENT, SCAFFOLD_ENTRY_PATH, SCAFFOLD_KV_PLACEHOLDER_ID, SCAFFOLD_MAPS_CONTENT, SETUP_FIELDS, ScaffoldError, applySetup, buildScaffoldFiles, createProject, generateAdminToken, generateSecret, parseDevVars, readCajonzeroPackage, readSetupValues, serializeDevVars, setWranglerVars, suggestedValue, toPackageName };
|
|
208
|
+
export type { CajonzeroPackageInfo, CreateProjectOptions, ScaffoldErrorCode, ScaffoldFile, ScaffoldResult, ScaffoldTemplateOptions, SetupField, SetupKind, SetupOptions, SetupResult };
|