@s2script/sdk 0.21.0 → 0.23.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 +12 -4
- package/clients.d.ts +2 -7
- package/commands.d.ts +52 -5
- package/config.d.ts +5 -0
- package/damage.d.ts +12 -7
- package/dist/cli.js +363 -129
- package/entity.d.ts +1 -1
- package/events.d.ts +4 -3
- package/index.d.ts +47 -0
- package/package.json +8 -2
- package/phrases.d.ts +5 -4
- package/plugin.d.ts +103 -43
- package/sdkhooks.d.ts +543 -0
- package/server.d.ts +5 -5
- package/translations.d.ts +6 -4
- package/unsafe.d.ts +28 -8
package/entity.d.ts
CHANGED
|
@@ -220,7 +220,7 @@ export type EntityKeyValueMap = { [key: string]: string | number | boolean };
|
|
|
220
220
|
*/
|
|
221
221
|
export declare function createEntity(className: string, keyvalues?: EntityKeyValueMap): EntityRef | null;
|
|
222
222
|
|
|
223
|
-
/** The payload delivered to an `
|
|
223
|
+
/** The payload delivered to an `onOutput` handler. */
|
|
224
224
|
export interface OutputEvent {
|
|
225
225
|
/** The output's name (e.g. "OnTrigger", "OnPressed", "OnStartTouch"). */
|
|
226
226
|
output: string;
|
package/events.d.ts
CHANGED
|
@@ -52,9 +52,9 @@ export type HookResultValue = 0 | 1 | 2 | 3;
|
|
|
52
52
|
* Events.fire("player_changename", { userid: p.userId, oldname, newname });
|
|
53
53
|
*/
|
|
54
54
|
export declare const Events: {
|
|
55
|
-
/** Fire a game event.
|
|
55
|
+
/** Fire a game event (SourceMod `FireEvent`). Other plugins' `on` / `onPre`
|
|
56
|
+
* handlers run before this returns. Returns the engine FireEvent result. */
|
|
56
57
|
fire(name: string, fields?: Record<string, number | string | boolean | bigint>, dontBroadcast?: boolean): boolean;
|
|
57
|
-
/** Fire a game event to ONE client (SourceMod FireToClient). Same field type-inference as `fire`. Returns false on miss. */
|
|
58
58
|
/**
|
|
59
59
|
* Restrict the event currently being pre-dispatched to `slots`, instead of hiding it from everyone.
|
|
60
60
|
*
|
|
@@ -73,6 +73,7 @@ export declare const Events: {
|
|
|
73
73
|
* });
|
|
74
74
|
*/
|
|
75
75
|
setRecipients(slots: readonly number[]): void;
|
|
76
|
-
|
|
76
|
+
/** Fire a game event to ONE client (SourceMod `FireToClient`). Does not go through
|
|
77
|
+
* `IGameEventManager2::FireEvent` (no `onPre`). Returns false on miss. */
|
|
77
78
|
fireToClient(slot: number, name: string, fields?: Record<string, string | number | boolean | bigint>): boolean;
|
|
78
79
|
};
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@s2script/sdk` — the engine-generic authoring barrel.
|
|
3
|
+
*
|
|
4
|
+
* Subpath imports (`@s2script/sdk/commands`, `@s2script/sdk/plugin`, …) stay valid.
|
|
5
|
+
* This root re-exports the same names so a plugin can write:
|
|
6
|
+
*
|
|
7
|
+
* import { command, hook, HookResult, ADMFLAG } from "@s2script/sdk";
|
|
8
|
+
*
|
|
9
|
+
* `Player` / `Pawn` / CS2 schema types are NOT here — they live on `@s2script/cs2`.
|
|
10
|
+
* `@s2script/sdk/unsafe` stays a deliberate subpath (not re-exported).
|
|
11
|
+
*
|
|
12
|
+
* NO runtime code in this file: the engine injects `globalThis.__s2pkg_sdk` at load
|
|
13
|
+
* (`__s2require("@s2script/sdk")`).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export * from "./admin";
|
|
17
|
+
export * from "./bans";
|
|
18
|
+
export * from "./chat";
|
|
19
|
+
export * from "./clients";
|
|
20
|
+
export * from "./commands";
|
|
21
|
+
export * from "./config";
|
|
22
|
+
export * from "./cookies";
|
|
23
|
+
export * from "./damage";
|
|
24
|
+
export * from "./db";
|
|
25
|
+
export * from "./entity";
|
|
26
|
+
export * from "./events";
|
|
27
|
+
export * from "./http";
|
|
28
|
+
export * from "./interfaces";
|
|
29
|
+
export * from "./math";
|
|
30
|
+
export * from "./menu";
|
|
31
|
+
export * from "./net";
|
|
32
|
+
export * from "./phrases";
|
|
33
|
+
export * from "./plugin";
|
|
34
|
+
export * from "./plugins";
|
|
35
|
+
export * from "./sdkhooks";
|
|
36
|
+
export * from "./server";
|
|
37
|
+
export * from "./sound";
|
|
38
|
+
export * from "./timers";
|
|
39
|
+
export * from "./topmenu";
|
|
40
|
+
export * from "./trace";
|
|
41
|
+
export * from "./translations";
|
|
42
|
+
export * from "./transmit";
|
|
43
|
+
export * from "./usercmd";
|
|
44
|
+
export * from "./usermessages";
|
|
45
|
+
export * from "./voice";
|
|
46
|
+
export * from "./votes";
|
|
47
|
+
export * from "./ws";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@s2script/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"license": "MIT OR Apache-2.0",
|
|
5
5
|
"description": "s2script SDK — the builtin capability types (imported as @s2script/sdk/entity, …) plus the `s2s` CLI for building Source 2 / CS2 plugins.",
|
|
6
6
|
"type": "module",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"test": "node --experimental-strip-types --no-warnings --test test/*.test.mjs"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@s2script/eslint-plugin": "0.2.
|
|
16
|
+
"@s2script/eslint-plugin": "0.2.1",
|
|
17
17
|
"esbuild": "^0.25.0",
|
|
18
18
|
"eslint": "^10.7.0",
|
|
19
19
|
"typescript": "^5.6.0"
|
|
@@ -35,6 +35,9 @@
|
|
|
35
35
|
"contracts"
|
|
36
36
|
],
|
|
37
37
|
"exports": {
|
|
38
|
+
".": {
|
|
39
|
+
"types": "./index.d.ts"
|
|
40
|
+
},
|
|
38
41
|
"./admin": {
|
|
39
42
|
"types": "./admin.d.ts"
|
|
40
43
|
},
|
|
@@ -92,6 +95,9 @@
|
|
|
92
95
|
"./plugins": {
|
|
93
96
|
"types": "./plugins.d.ts"
|
|
94
97
|
},
|
|
98
|
+
"./sdkhooks": {
|
|
99
|
+
"types": "./sdkhooks.d.ts"
|
|
100
|
+
},
|
|
95
101
|
"./server": {
|
|
96
102
|
"types": "./server.d.ts"
|
|
97
103
|
},
|
package/phrases.d.ts
CHANGED
|
@@ -6,13 +6,14 @@
|
|
|
6
6
|
* from the phrase files you load.
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* import { translations } from "@s2script/sdk";
|
|
10
|
+
* export function OnPluginStart(): void {
|
|
11
|
+
* translations.load("basecomm", "common");
|
|
11
12
|
*
|
|
12
13
|
* cmd.replyT("Usage Gag"); // ok — in translations/basecomm.phrases.json
|
|
13
14
|
* cmd.replyT("No matching players"); // ok — in translations/common.phrases.json
|
|
14
15
|
* cmd.replyT("Usage Gagg"); // compile error — no such key in either
|
|
15
|
-
* }
|
|
16
|
+
* }
|
|
16
17
|
*
|
|
17
18
|
* ## Writing phrases
|
|
18
19
|
*
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
*
|
|
30
31
|
* ## How the checking works
|
|
31
32
|
*
|
|
32
|
-
* The build reads your `
|
|
33
|
+
* The build reads your `translations.load(...)` call and writes `src/phrases.generated.d.ts`,
|
|
33
34
|
* filling in {@link PhraseKeys} with the keys of exactly those files. Load a file and its keys
|
|
34
35
|
* become valid; don't, and they don't — so a forgotten `load` is a compile error rather than raw key
|
|
35
36
|
* text printed to a player at runtime. SourceMod enforces the same rule, but only when it happens.
|
package/plugin.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @s2script/sdk/plugin —
|
|
3
|
-
* and
|
|
4
|
-
*
|
|
2
|
+
* @s2script/sdk/plugin — load-window authoring (`hook`, `publish`, `translations`, `Scope`)
|
|
3
|
+
* and the internal load-scoped {@link PluginContext} types. NO runtime code: the engine injects
|
|
4
|
+
* the implementation at load time (`__s2pkg_plugin`).
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* The plugin artifact is `export function OnPluginStart` (plus optional named publics).
|
|
7
|
+
* See docs/superpowers/specs/2026-08-30-drop-plugin-factory-design.md.
|
|
7
8
|
*/
|
|
8
9
|
import type { GameEvent, HookResultValue } from "./events";
|
|
9
10
|
import type { Client } from "./clients";
|
|
10
11
|
import type { EntityRef, OutputEvent } from "./entity";
|
|
11
|
-
import type {
|
|
12
|
-
import type { CommandInvocation } from "./commands";
|
|
12
|
+
import type { CommandHandler } from "./commands";
|
|
13
13
|
import type { Config } from "./config";
|
|
14
14
|
import type { PublishHandle } from "./interfaces";
|
|
15
15
|
import type { TopMenuItem } from "./topmenu";
|
|
@@ -30,7 +30,7 @@ export interface CtxEvents {
|
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
32
|
* Handlers fire for clients that connect AFTER Active. To cover already-connected clients, seed
|
|
33
|
-
* explicitly in
|
|
33
|
+
* explicitly in OnPluginStart: `for (const c of Clients.all()) { … }` — there is no framework
|
|
34
34
|
* replay (replaying `onConnect` for pre-existing clients would fire auth/ban/reservation logic
|
|
35
35
|
* out of its real order).
|
|
36
36
|
*/
|
|
@@ -56,7 +56,7 @@ export interface CtxClients {
|
|
|
56
56
|
/** Per-tick usercmd hook (SM `OnPlayerRunCmd`): read/modify {@link UserCmdView}; return `Handled` to block the tick. */
|
|
57
57
|
onRunCmd(handler: (cmd: UserCmdView, info: { slot: number }) => HookResultValue | void): void;
|
|
58
58
|
}
|
|
59
|
-
/** Entity lifecycle
|
|
59
|
+
/** Entity lifecycle / I/O subscriptions on this plugin's load-scope ({@link PluginContext.entities}). */
|
|
60
60
|
export interface CtxEntities {
|
|
61
61
|
/** An entity of `className` was created (not yet spawned). @param className - match, or `"*"` for all. */
|
|
62
62
|
onCreate(className: string, handler: (entity: EntityRef | null, className: string) => void): void;
|
|
@@ -66,17 +66,9 @@ export interface CtxEntities {
|
|
|
66
66
|
onDelete(className: string, handler: (entity: EntityRef | null, className: string) => void): void;
|
|
67
67
|
/** Hook a named entity output (`FireOutputInternal`); return a {@link HookResultValue} to suppress it. */
|
|
68
68
|
onOutput(classname: string, output: string, handler: (ev: OutputEvent) => HookResultValue | void): void;
|
|
69
|
-
/**
|
|
70
|
-
* Damage pre-hook (SDKHooks-equivalent): read/modify {@link DamageInfo}; return `Handled` semantics via `info`.
|
|
71
|
-
* @example
|
|
72
|
-
* // plugins/basecommands/src/plugin.ts:81 — halve incoming damage
|
|
73
|
-
* ctx.entities.onDamage((info) => { info.damage = info.damage / 2; });
|
|
74
|
-
*/
|
|
75
|
-
onDamage(handler: (info: DamageInfo) => HookResultValue | void): void;
|
|
76
69
|
}
|
|
77
70
|
/** Per-frame + map/precache hooks on this plugin's load-scope ({@link PluginContext.server}). */
|
|
78
71
|
export interface CtxServer {
|
|
79
|
-
/** Run `fn` every game frame. @param opts - `priority` orders it within the frame (`monitor` runs last, read-only). */
|
|
80
72
|
/**
|
|
81
73
|
* Run `fn` every game frame.
|
|
82
74
|
*
|
|
@@ -97,11 +89,11 @@ export interface CtxServer {
|
|
|
97
89
|
/** Console/chat command registration on this plugin's load-scope ({@link PluginContext.commands}). */
|
|
98
90
|
export interface CtxCommands {
|
|
99
91
|
/** Register a public command (any client may run it). */
|
|
100
|
-
register(name: string, handler:
|
|
92
|
+
register(name: string, handler: CommandHandler): void;
|
|
101
93
|
/** Register a server-only command (console/rcon, not client-runnable). */
|
|
102
|
-
registerServer(name: string, handler:
|
|
94
|
+
registerServer(name: string, handler: CommandHandler): void;
|
|
103
95
|
/** Register an admin command gated by `flags` (an `ADMFLAG` bitmask; fail-safe default-deny). */
|
|
104
|
-
registerAdmin(name: string, flags: number, handler:
|
|
96
|
+
registerAdmin(name: string, flags: number, handler: CommandHandler): void;
|
|
105
97
|
/**
|
|
106
98
|
* Observe an existing CLIENT command by name — SourceMod's `AddCommandListener`.
|
|
107
99
|
*
|
|
@@ -162,7 +154,7 @@ export interface Scope {
|
|
|
162
154
|
readonly events: CtxEvents;
|
|
163
155
|
/** Client-lifecycle subscriptions bound to this scope. */
|
|
164
156
|
readonly clients: CtxClients;
|
|
165
|
-
/** Entity/
|
|
157
|
+
/** Entity lifecycle / I/O subscriptions bound to this scope. */
|
|
166
158
|
readonly entities: CtxEntities;
|
|
167
159
|
/** Per-frame/map subscriptions bound to this scope. */
|
|
168
160
|
readonly server: CtxServer;
|
|
@@ -175,8 +167,9 @@ export interface Scope {
|
|
|
175
167
|
}
|
|
176
168
|
|
|
177
169
|
/**
|
|
178
|
-
* The load-scoped context
|
|
179
|
-
*
|
|
170
|
+
* The load-scoped context the host builds for one plugin load. Public authoring uses
|
|
171
|
+
* {@link hook} / {@link command} / named publics instead of receiving this object.
|
|
172
|
+
* {@link Scope} reuses the same subscription namespaces.
|
|
180
173
|
*/
|
|
181
174
|
export interface PluginContext {
|
|
182
175
|
/** This plugin's id (manifest `id`). */
|
|
@@ -187,7 +180,7 @@ export interface PluginContext {
|
|
|
187
180
|
readonly events: CtxEvents;
|
|
188
181
|
/** Client-lifecycle subscriptions ({@link CtxClients}). */
|
|
189
182
|
readonly clients: CtxClients;
|
|
190
|
-
/** Entity/
|
|
183
|
+
/** Entity lifecycle / I/O subscriptions ({@link CtxEntities}). */
|
|
191
184
|
readonly entities: CtxEntities;
|
|
192
185
|
/** Per-frame/map/precache subscriptions ({@link CtxServer}). */
|
|
193
186
|
readonly server: CtxServer;
|
|
@@ -201,7 +194,7 @@ export interface PluginContext {
|
|
|
201
194
|
readonly topmenu: CtxTopMenu;
|
|
202
195
|
/** Publish this plugin's manifest-declared interface. Buffered; goes live at Active. */
|
|
203
196
|
publish<T extends object>(name: string, impl: T): PublishHandle;
|
|
204
|
-
/** Resolve a HARD dep (must be in `pluginDependencies`). Immediate — the proxy is callable
|
|
197
|
+
/** Resolve a HARD dep (must be in `pluginDependencies`). Immediate — the proxy is callable during OnPluginStart. */
|
|
205
198
|
use<T extends object>(name: string): InterfaceHandle<T>;
|
|
206
199
|
/** Resolve an OPTIONAL dep (must be in `optionalPluginDependencies`); null while unpublished. */
|
|
207
200
|
tryUse<T extends object>(name: string): InterfaceHandle<T> | null;
|
|
@@ -209,31 +202,98 @@ export interface PluginContext {
|
|
|
209
202
|
createScope(): Scope;
|
|
210
203
|
}
|
|
211
204
|
|
|
212
|
-
/** Optional lifecycle hooks a
|
|
205
|
+
/** Optional lifecycle hooks a plugin may return to participate in unload + hot-reload.
|
|
206
|
+
* Public authoring uses `export function OnPluginEnd` / `OnPluginState` instead. */
|
|
213
207
|
export interface PluginHooks {
|
|
214
208
|
/** Best-effort cleanup at unload (the ledger remains the teardown authority). */
|
|
215
209
|
onUnload?(): void;
|
|
216
|
-
/** Hot-reload handoff capture; JSON-serialized (EntityRef-aware) and revived as the next instance's
|
|
210
|
+
/** Hot-reload handoff capture; JSON-serialized (EntityRef-aware) and revived as the next instance's {@link previous}. */
|
|
217
211
|
state?(): unknown;
|
|
218
212
|
}
|
|
213
|
+
|
|
219
214
|
/**
|
|
220
|
-
*
|
|
221
|
-
*
|
|
215
|
+
* Named publics the host finds on `module.exports` (missing export = not subscribed):
|
|
216
|
+
*
|
|
217
|
+
* Plugin: `OnPluginStart` / `OnPluginEnd` / `OnPluginState` / `OnAllPluginsLoaded` / `OnConfigsExecuted`
|
|
218
|
+
* Map/frame: `OnMapStart(map)` / `OnMapEnd()` / `OnGameFrame()` / `OnPrecache(pc)`
|
|
219
|
+
* Client: `OnClientConnected` / `PutInServer` / `Active` / `PostAdminCheck` / `Disconnect` /
|
|
220
|
+
* `SayCommand` / `SettingsChanged` / `Voice` / `CookiesCached` / `OnPlayerRunCmd`
|
|
221
|
+
* Entity: `OnEntityCreated` / `OnEntitySpawned` / `OnEntityDestroyed`
|
|
222
|
+
*
|
|
223
|
+
* `OnGameFrame` is SourceMod's public (before simulation). Post-simulation paint is
|
|
224
|
+
* {@link Scope}'s `server.onGameFrame(fn, { phase: "post" })` — Metamod's post hook, not a SM public.
|
|
225
|
+
* Filtered entity I/O is {@link onOutput}, not a public — SourceMod `HookEntityOutput`.
|
|
226
|
+
* Per-entity damage is `SDKHook` (`SDKHookType.OnTakeDamage`), not a named public.
|
|
222
227
|
*/
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Game-event catalog. Load-window only — throws after settle (same window as {@link command}).
|
|
231
|
+
*
|
|
232
|
+
* `hook.on` is post-fire; `hook.onPre` is pre (`Handled`/`Stop` suppress the client broadcast).
|
|
233
|
+
* The {@link GameEvent} is valid only synchronously.
|
|
234
|
+
*/
|
|
235
|
+
export declare const hook: {
|
|
236
|
+
/** Post-phase (`ctx.events.on`). */
|
|
237
|
+
on(name: string, handler: (ev: GameEvent) => void): void;
|
|
238
|
+
/**
|
|
239
|
+
* Pre-phase (`ctx.events.onPre`). Return {@link HookResultValue} `Handled`/`Stop` to suppress
|
|
240
|
+
* the client broadcast.
|
|
241
|
+
*/
|
|
242
|
+
onPre(name: string, handler: (ev: GameEvent) => HookResultValue | void): void;
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Load-window entity I/O subscribe (SourceMod `HookEntityOutput`). Keyed by `(classname, output)`
|
|
247
|
+
* at the native mux — use `"*"` for either side. Throws after settle.
|
|
248
|
+
*/
|
|
249
|
+
export declare function onOutput(
|
|
250
|
+
classname: string,
|
|
251
|
+
output: string,
|
|
252
|
+
handler: (ev: OutputEvent) => HookResultValue | void,
|
|
253
|
+
): void;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* The revived hot-reload handoff (the previous instance's `OnPluginState` return), or `undefined`.
|
|
257
|
+
* Load-window only.
|
|
258
|
+
*/
|
|
259
|
+
export declare function previous(): unknown;
|
|
260
|
+
/**
|
|
261
|
+
* This plugin's id (manifest `id`). Load-window only.
|
|
262
|
+
*/
|
|
263
|
+
export declare function pluginId(): string;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Allocate a disposable subscription scope. Load-window only — same contract as
|
|
267
|
+
* {@link PluginContext.createScope}.
|
|
268
|
+
*/
|
|
269
|
+
export declare function createScope(): Scope;
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Publish this plugin's manifest-declared interface. Load-window only (buffered, armed at Active).
|
|
273
|
+
* Same contract as {@link PluginContext.publish}.
|
|
274
|
+
*/
|
|
275
|
+
export declare function publish<T extends object>(name: string, impl: T): PublishHandle;
|
|
276
|
+
/**
|
|
277
|
+
* Resolve a HARD dep (must be in `pluginDependencies`). Load-window only.
|
|
278
|
+
* Same contract as {@link PluginContext.use}. Prefer `import { greet } from "@demo/greeter"` for
|
|
279
|
+
* the producer-as-import form; `use()` remains the explicit load-window form and the optional-dep path.
|
|
280
|
+
*/
|
|
281
|
+
export declare function use<T extends object>(name: string): InterfaceHandle<T>;
|
|
282
|
+
/**
|
|
283
|
+
* Resolve an OPTIONAL dep (must be in `optionalPluginDependencies`); null while unpublished.
|
|
284
|
+
* Load-window only. Same contract as {@link PluginContext.tryUse}.
|
|
285
|
+
*/
|
|
286
|
+
export declare function tryUse<T extends object>(name: string): InterfaceHandle<T> | null;
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Load-window TopMenu contribution. Same contract as {@link PluginContext.topmenu}.
|
|
290
|
+
* Throws after settle.
|
|
291
|
+
*/
|
|
292
|
+
export declare const topmenu: CtxTopMenu;
|
|
293
|
+
|
|
229
294
|
/**
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
* // examples/greeter-plugin/src/plugin.ts:8
|
|
234
|
-
* export default plugin((ctx) => {
|
|
235
|
-
* const handle = ctx.publish("@demo/greeter", impl);
|
|
236
|
-
* ctx.server.onGameFrame(() => handle.emit("greeted", { slot: 0 }));
|
|
237
|
-
* });
|
|
295
|
+
* Load-window phrase-file declaration. Same contract as {@link PluginContext.translations}.
|
|
296
|
+
* Throws after settle. `s2s build` / `sync-phrase-types.mjs` collect `translations.load(...)`
|
|
297
|
+
* the same way they collect `ctx.translations.load(...)`.
|
|
238
298
|
*/
|
|
239
|
-
export declare
|
|
299
|
+
export declare const translations: CtxTranslations;
|