tina4-nodejs 3.13.92 → 3.13.94

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.
Files changed (134) hide show
  1. package/CLAUDE.md +16 -3
  2. package/README.md +1 -1
  3. package/package.json +12 -9
  4. package/packages/cli/dist/bin.js +1260 -969
  5. package/packages/core/dist/index.js +1260 -969
  6. package/packages/core/src/devMailbox.ts +20 -44
  7. package/packages/core/src/index.ts +2 -2
  8. package/packages/core/src/messenger.ts +72 -0
  9. package/packages/core/src/queueBackends/kafkaBackend.ts +108 -12
  10. package/packages/core/src/sessionHandlers/childError.ts +72 -0
  11. package/packages/core/src/sessionHandlers/mongoClient.ts +9 -3
  12. package/packages/core/src/sessionHandlers/redisHandler.ts +18 -5
  13. package/packages/core/src/sessionHandlers/respClient.ts +5 -1
  14. package/packages/frond/dist/index.js +74 -31
  15. package/packages/frond/src/engine.ts +99 -33
  16. package/packages/orm/dist/index.js +3055 -2764
  17. package/packages/orm/src/adapters/sqlite.ts +4 -1
  18. package/packages/orm/src/database.ts +108 -8
  19. package/types/cli/src/bin.d.ts +92 -0
  20. package/types/cli/src/commands/build.d.ts +2 -0
  21. package/types/cli/src/commands/generate.d.ts +47 -0
  22. package/types/cli/src/commands/init.d.ts +1 -0
  23. package/types/cli/src/commands/metrics.d.ts +6 -0
  24. package/types/cli/src/commands/migrate.d.ts +1 -0
  25. package/types/cli/src/commands/migrateCreate.d.ts +1 -0
  26. package/types/cli/src/commands/migrateRollback.d.ts +1 -0
  27. package/types/cli/src/commands/migrateStatus.d.ts +1 -0
  28. package/types/cli/src/commands/queue.d.ts +20 -0
  29. package/types/cli/src/commands/routes.d.ts +1 -0
  30. package/types/cli/src/commands/seed.d.ts +1 -0
  31. package/types/cli/src/commands/serve.d.ts +6 -0
  32. package/types/cli/src/commands/test.d.ts +1 -0
  33. package/types/core/src/ai.d.ts +64 -0
  34. package/types/core/src/api.d.ts +262 -0
  35. package/types/core/src/auth.d.ts +154 -0
  36. package/types/core/src/authGate.d.ts +20 -0
  37. package/types/core/src/background.d.ts +34 -0
  38. package/types/core/src/cache.d.ts +160 -0
  39. package/types/core/src/constants.d.ts +38 -0
  40. package/types/core/src/container.d.ts +44 -0
  41. package/types/core/src/context/chunker.d.ts +31 -0
  42. package/types/core/src/context/index.d.ts +93 -0
  43. package/types/core/src/devAdmin.d.ts +179 -0
  44. package/types/core/src/devMailbox.d.ts +54 -0
  45. package/types/core/src/docs.d.ts +141 -0
  46. package/types/core/src/docsAutoDiscovery.d.ts +6 -0
  47. package/types/core/src/dotenv.d.ts +65 -0
  48. package/types/core/src/env.d.ts +28 -0
  49. package/types/core/src/errorOverlay.d.ts +36 -0
  50. package/types/core/src/events.d.ts +75 -0
  51. package/types/core/src/fakeData.d.ts +55 -0
  52. package/types/core/src/feedback.d.ts +90 -0
  53. package/types/core/src/graphql.d.ts +207 -0
  54. package/types/core/src/health.d.ts +22 -0
  55. package/types/core/src/htmlElement.d.ts +75 -0
  56. package/types/core/src/i18n.d.ts +37 -0
  57. package/types/core/src/index.d.ts +93 -0
  58. package/types/core/src/job.d.ts +39 -0
  59. package/types/core/src/logger.d.ts +123 -0
  60. package/types/core/src/mcp.d.ts +248 -0
  61. package/types/core/src/messenger.d.ts +191 -0
  62. package/types/core/src/metrics.d.ts +77 -0
  63. package/types/core/src/middleware.d.ts +207 -0
  64. package/types/core/src/mqtt.d.ts +257 -0
  65. package/types/core/src/mqttMessage.d.ts +67 -0
  66. package/types/core/src/plan.d.ts +96 -0
  67. package/types/core/src/projectIndex.d.ts +56 -0
  68. package/types/core/src/queue.d.ts +219 -0
  69. package/types/core/src/queueBackends/kafkaBackend.d.ts +117 -0
  70. package/types/core/src/queueBackends/liteBackend.d.ts +119 -0
  71. package/types/core/src/queueBackends/mongoBackend.d.ts +97 -0
  72. package/types/core/src/queueBackends/rabbitmqBackend.d.ts +55 -0
  73. package/types/core/src/rateLimiter.d.ts +49 -0
  74. package/types/core/src/request.d.ts +25 -0
  75. package/types/core/src/response.d.ts +28 -0
  76. package/types/core/src/routeDiscovery.d.ts +12 -0
  77. package/types/core/src/router.d.ts +355 -0
  78. package/types/core/src/scss.d.ts +19 -0
  79. package/types/core/src/server.d.ts +131 -0
  80. package/types/core/src/service.d.ts +115 -0
  81. package/types/core/src/session.d.ts +256 -0
  82. package/types/core/src/sessionHandlers/childError.d.ts +34 -0
  83. package/types/core/src/sessionHandlers/databaseHandler.d.ts +42 -0
  84. package/types/core/src/sessionHandlers/mongoClient.d.ts +24 -0
  85. package/types/core/src/sessionHandlers/mongoHandler.d.ts +61 -0
  86. package/types/core/src/sessionHandlers/redisHandler.d.ts +60 -0
  87. package/types/core/src/sessionHandlers/respClient.d.ts +22 -0
  88. package/types/core/src/sessionHandlers/valkeyHandler.d.ts +65 -0
  89. package/types/core/src/static.d.ts +2 -0
  90. package/types/core/src/test.d.ts +94 -0
  91. package/types/core/src/testClient.d.ts +36 -0
  92. package/types/core/src/testing.d.ts +58 -0
  93. package/types/core/src/types.d.ts +219 -0
  94. package/types/core/src/validator.d.ts +52 -0
  95. package/types/core/src/websocket.d.ts +376 -0
  96. package/types/core/src/websocketBackplane.d.ts +166 -0
  97. package/types/core/src/websocketConnection.d.ts +54 -0
  98. package/types/core/src/wsdl.d.ts +101 -0
  99. package/types/frond/src/engine.d.ts +263 -0
  100. package/types/frond/src/index.d.ts +2 -0
  101. package/types/orm/src/adapters/firebird.d.ts +138 -0
  102. package/types/orm/src/adapters/mongodb.d.ts +81 -0
  103. package/types/orm/src/adapters/mssql.d.ts +70 -0
  104. package/types/orm/src/adapters/mysql.d.ts +66 -0
  105. package/types/orm/src/adapters/odbc.d.ts +97 -0
  106. package/types/orm/src/adapters/postgres.d.ts +85 -0
  107. package/types/orm/src/adapters/sqlite.d.ts +56 -0
  108. package/types/orm/src/autoCrud.d.ts +73 -0
  109. package/types/orm/src/baseModel.d.ts +391 -0
  110. package/types/orm/src/cachedDatabase.d.ts +177 -0
  111. package/types/orm/src/database.d.ts +609 -0
  112. package/types/orm/src/databaseResult.d.ts +85 -0
  113. package/types/orm/src/docstore.d.ts +182 -0
  114. package/types/orm/src/fakeData.d.ts +22 -0
  115. package/types/orm/src/index.d.ts +40 -0
  116. package/types/orm/src/migration.d.ts +275 -0
  117. package/types/orm/src/model.d.ts +7 -0
  118. package/types/orm/src/query.d.ts +14 -0
  119. package/types/orm/src/queryBuilder.d.ts +173 -0
  120. package/types/orm/src/realtime/index.d.ts +7 -0
  121. package/types/orm/src/realtime/models/attachment.d.ts +43 -0
  122. package/types/orm/src/realtime/models/channel.d.ts +32 -0
  123. package/types/orm/src/realtime/models/channelMember.d.ts +32 -0
  124. package/types/orm/src/realtime/models/message.d.ts +36 -0
  125. package/types/orm/src/realtime/models/workspace.d.ts +26 -0
  126. package/types/orm/src/realtime/realtime.d.ts +24 -0
  127. package/types/orm/src/realtime/storage.d.ts +61 -0
  128. package/types/orm/src/seeder.d.ts +118 -0
  129. package/types/orm/src/sqlTranslator.d.ts +134 -0
  130. package/types/orm/src/types.d.ts +138 -0
  131. package/types/orm/src/validation.d.ts +6 -0
  132. package/types/swagger/src/generator.d.ts +46 -0
  133. package/types/swagger/src/index.d.ts +2 -0
  134. package/types/swagger/src/ui.d.ts +11 -0
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Tina4 Events — Simple observer pattern for decoupled communication.
3
+ *
4
+ * Zero-dependency event system. Fire events, register listeners.
5
+ *
6
+ * Events.on("user.created", (user) => console.log(`Welcome ${user.name}!`));
7
+ * Events.emit("user.created", { name: "Alice", email: "alice@example.com" });
8
+ *
9
+ * One-time listeners:
10
+ *
11
+ * Events.once("app.ready", () => console.log("App started!"));
12
+ */
13
+ export declare class Events {
14
+ /**
15
+ * Register a listener for an event.
16
+ * Higher priority runs first.
17
+ */
18
+ static on(event: string, callback: (...args: unknown[]) => void, priority?: number): void;
19
+ /**
20
+ * Register a listener that fires only once then auto-removes.
21
+ */
22
+ static once(event: string, callback: (...args: unknown[]) => void, priority?: number): void;
23
+ /**
24
+ * Remove a specific listener, or all listeners for an event.
25
+ *
26
+ * Events.off("user.created", handler) // remove specific
27
+ * Events.off("user.created") // remove all for event
28
+ */
29
+ static off(event: string, callback?: (...args: unknown[]) => void): void;
30
+ /**
31
+ * Fire an event synchronously. Returns array of listener results.
32
+ *
33
+ * Listener isolation (E1): each listener call is wrapped — a listener
34
+ * that THROWS does NOT abort the rest of emit(). The error is LOGGED
35
+ * (never silent) and the failed listener contributes a `null` slot, so
36
+ * N listeners always yield N results in priority order; surviving
37
+ * listeners run regardless of an earlier throw.
38
+ *
39
+ * Pass `{ strict: true }` to RE-RAISE on the first listener error
40
+ * instead of isolating it (later listeners then do NOT run).
41
+ *
42
+ * once() cleanup stays correct under isolation: the one-shot listener is
43
+ * spliced out BEFORE its callback runs, so a throw never leaves it
44
+ * registered.
45
+ */
46
+ static emit(event: string, ...args: unknown[]): unknown[];
47
+ static emit(event: string, options: {
48
+ strict?: boolean;
49
+ }, ...args: unknown[]): unknown[];
50
+ /**
51
+ * Emit an event and await all async listeners.
52
+ * Returns array of resolved results from each listener.
53
+ *
54
+ * Listener isolation (E1): identical to emit() — each awaited listener
55
+ * is isolated; a rejection/throw is LOGGED and contributes a `null`
56
+ * slot without aborting the others. `{ strict: true }` re-raises on the
57
+ * first error.
58
+ */
59
+ static emitAsync(event: string, ...args: unknown[]): Promise<unknown[]>;
60
+ static emitAsync(event: string, options: {
61
+ strict?: boolean;
62
+ }, ...args: unknown[]): Promise<unknown[]>;
63
+ /**
64
+ * Get all listener callbacks for an event (in priority order).
65
+ */
66
+ static listeners(event: string): Array<(...args: unknown[]) => void>;
67
+ /**
68
+ * List all registered event names.
69
+ */
70
+ static events(): string[];
71
+ /**
72
+ * Remove all listeners for all events.
73
+ */
74
+ static clear(): void;
75
+ }
@@ -0,0 +1,55 @@
1
+ export declare class FakeData {
2
+ private rng;
3
+ private seeded;
4
+ constructor(seed?: number);
5
+ /** Static factory — create a seeded FakeData instance. */
6
+ static seed(seed: number): FakeData;
7
+ /** Returns a random integer in [min, max) using the instance PRNG. */
8
+ private randInt;
9
+ /** Pick a random element from an array. */
10
+ private pick;
11
+ firstName(): string;
12
+ lastName(): string;
13
+ name(): string;
14
+ email(): string;
15
+ phone(): string;
16
+ address(): string;
17
+ city(): string;
18
+ country(): string;
19
+ zipCode(): string;
20
+ company(): string;
21
+ jobTitle(): string;
22
+ paragraph(sentences?: number): string;
23
+ sentence(words?: number): string;
24
+ word(): string;
25
+ integer(min?: number, max?: number): number;
26
+ numeric(min?: number, max?: number, decimals?: number): number;
27
+ boolean(): boolean;
28
+ date(start?: string, end?: string): string;
29
+ uuid(): string;
30
+ url(): string;
31
+ ipAddress(): string;
32
+ colorHex(): string;
33
+ /** Returns fake test credit card numbers (Luhn-valid test patterns). */
34
+ creditCard(): string;
35
+ currency(): string;
36
+ /**
37
+ * Returns multi-paragraph text.
38
+ * Matches Python's text() method.
39
+ */
40
+ text(paragraphs?: number): string;
41
+ /**
42
+ * Returns a random element from the given array.
43
+ * Matches Python's choice() method.
44
+ */
45
+ choice<T>(items: T[]): T;
46
+ /**
47
+ * Run seed files from a directory. Each file should export a default async function.
48
+ * Returns an array of executed file paths.
49
+ */
50
+ seedDir(seedDir?: string): Promise<string[]>;
51
+ /**
52
+ * Run a generator function `count` times and return the results.
53
+ */
54
+ run(fn: () => Record<string, unknown>, count?: number): Record<string, unknown>[];
55
+ }
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Customer feedback widget — Tier 4 port from tina4-python.
3
+ *
4
+ * End-users of a shipped Tina4 app give UX feedback via a floating bubble
5
+ * widget. Widget visibility + API are gated by TWO env flags:
6
+ *
7
+ * - TINA4_ENABLE_FEEDBACK master switch (explicit opt-in)
8
+ * - TINA4_FEEDBACK_WHITELIST comma-separated emails / user IDs
9
+ *
10
+ * Architecture (mirrors Python `tina4_python/dev_admin/__init__.py`
11
+ * lines 1440-1645):
12
+ *
13
+ * 1. Framework middleware injects <script src="/__feedback/widget.js">
14
+ * into HTML responses for whitelisted users only.
15
+ * 2. Widget POSTs to /__feedback/api/turn for each conversational turn.
16
+ * 3. That handler verifies whitelist + rate-limit, stamps the user
17
+ * identity server-side (client cannot fake `sender`), then forwards
18
+ * to the Rust agent's /feedback/intake.
19
+ *
20
+ * The widget is for END USERS of a shipped app — the /__dev paths get
21
+ * skipped so the dev admin's own chat bubble doesn't sit on top of the
22
+ * customer feedback bubble.
23
+ */
24
+ import type { RouteHandler, Tina4Request } from "./types.js";
25
+ import type { Router } from "./router.js";
26
+ /**
27
+ * Master switch — both this AND a non-empty whitelist must be set for
28
+ * the widget to render or the API to accept submissions. Mirrors
29
+ * Python's `_feedback_enabled()`.
30
+ */
31
+ export declare function feedbackEnabled(): boolean;
32
+ /**
33
+ * Comma-separated emails / user IDs in env, lowercased + trimmed.
34
+ * Returns [] when the master switch is off so callers can short-circuit
35
+ * with a single check. Mirrors Python's `_feedback_whitelist()`.
36
+ */
37
+ export declare function feedbackWhitelist(): string[];
38
+ /**
39
+ * Best-effort user identity from JWT/Bearer auth. Falls back to
40
+ * TINA4_FEEDBACK_DEV_USER (local dev convenience — lets the framework
41
+ * owner test the widget without a full auth setup). Mirrors Python's
42
+ * `_feedback_identify_user()`.
43
+ */
44
+ export declare function feedbackIdentifyUser(request: Tina4Request): string | null;
45
+ /**
46
+ * Returns [allowed, userId]. Both halves are required — feature off when
47
+ * either is falsy. Mirrors Python's `_feedback_is_whitelisted()`.
48
+ */
49
+ export declare function feedbackIsWhitelisted(request: Tina4Request): [boolean, string | null];
50
+ /**
51
+ * 5 turns/hour per user, sliding window. Prunes old timestamps lazily on
52
+ * every call (no background task needed). Mirrors Python's
53
+ * `_feedback_rate_limit_ok()`.
54
+ */
55
+ export declare function feedbackRateLimitOk(user: string): boolean;
56
+ /** Test-only: clear rate-limit state between cases. Not part of public API. */
57
+ export declare function _resetFeedbackRateLimit(): void;
58
+ /**
59
+ * Insert the widget <script> into HTML for whitelisted users. Called
60
+ * from the response pipeline right before the body is flushed. No-op if:
61
+ * - request path starts with /__dev or /__feedback (developer
62
+ * pages have their own chat trigger)
63
+ * - master switch / whitelist not set
64
+ * - user not in whitelist
65
+ * - html lacks </body>
66
+ * Idempotent — looks for the `data-tina4-feedback` marker and bails.
67
+ * Mirrors Python's `inject_feedback_widget()`.
68
+ */
69
+ export declare function injectFeedbackWidget(request: Tina4Request, html: string): string;
70
+ /**
71
+ * POST /__feedback/api/turn — proxy one conversational turn to the Rust
72
+ * agent's `/feedback/intake`. Server stamps `sender` from the verified
73
+ * identity so the client cannot inject who they are. Mirrors Python's
74
+ * `_api_feedback_turn()`.
75
+ */
76
+ export declare const handleFeedbackTurn: RouteHandler;
77
+ declare const WIDGET_BUNDLE_PATH: string;
78
+ /**
79
+ * GET /__feedback/widget.js — serve the widget bundle with no-cache
80
+ * headers so a broken bundle doesn't get stuck in browser caches.
81
+ * Mirrors Python's `_api_feedback_widget_js()`.
82
+ */
83
+ export declare const handleFeedbackWidgetJs: RouteHandler;
84
+ /**
85
+ * Register the two feedback routes on a Router. Called from the dev
86
+ * admin setup so the routes only exist when the dev surface is
87
+ * enabled — production deployments without TINA4_DEBUG also skip them.
88
+ */
89
+ export declare function registerFeedbackRoutes(router: Router): void;
90
+ export { WIDGET_BUNDLE_PATH };
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Tina4 GraphQL — Zero-dependency GraphQL engine.
3
+ *
4
+ * Recursive-descent parser, schema builder, and query executor.
5
+ *
6
+ * import { GraphQL } from "@tina4/core";
7
+ *
8
+ * const gql = new GraphQL();
9
+ * gql.addType("User", { id: { type: "ID" }, name: { type: "String" } });
10
+ * gql.addQuery("user", { id: "ID!" }, "User", (root, args) => getUser(args.id));
11
+ * const result = gql.execute('{ user(id: "1") { name } }');
12
+ *
13
+ * Supported:
14
+ * - Queries, mutations
15
+ * - Variables, default values
16
+ * - Aliases
17
+ * - Nested selections
18
+ * - List types ([Type])
19
+ * - Non-null types (Type!)
20
+ * - Error capture (resolver exceptions become GraphQL errors)
21
+ */
22
+ export interface GraphQLField {
23
+ type: string;
24
+ description?: string;
25
+ }
26
+ export type ResolverFn = (root: unknown, args: Record<string, unknown>, context?: Record<string, unknown>) => unknown;
27
+ export interface GraphQLResult {
28
+ data: Record<string, unknown> | null;
29
+ errors?: Array<{
30
+ message: string;
31
+ path?: string[];
32
+ }>;
33
+ }
34
+ interface Token {
35
+ type: string;
36
+ value: string;
37
+ pos: number;
38
+ }
39
+ export declare function tokenize(source: string): Token[];
40
+ export declare class ParseError extends Error {
41
+ constructor(message: string);
42
+ }
43
+ /**
44
+ * URL the GraphQL handler should be mounted at.
45
+ * `TINA4_GRAPHQL_ENDPOINT` overrides the default `/graphql`.
46
+ */
47
+ export declare function graphqlEndpoint(): string;
48
+ /**
49
+ * Whether to auto-generate the schema from registered ORM models.
50
+ * `TINA4_GRAPHQL_AUTO_SCHEMA=true` (default) lets the dev server build a
51
+ * usable schema with no manual wiring; set to `false` to require explicit
52
+ * `addType` / `addQuery` calls.
53
+ */
54
+ export declare function graphqlAutoSchemaEnabled(): boolean;
55
+ /**
56
+ * Maximum selection-set nesting depth. A deeply nested query (or a circular
57
+ * fragment) would otherwise recurse without bound — a classic GraphQL DoS /
58
+ * stack-overflow vector. `TINA4_GRAPHQL_MAX_DEPTH` overrides the default (50);
59
+ * set `<= 0` to disable the guard. A non-numeric value falls back to 50.
60
+ */
61
+ export declare function graphqlMaxDepth(): number;
62
+ export declare class GraphQL {
63
+ private types;
64
+ private queries;
65
+ private mutations;
66
+ /** Object-type field resolvers indexed by `[typeName][fieldName]`. */
67
+ private fieldResolvers;
68
+ private static classResolvers;
69
+ private static defaultInstance;
70
+ /**
71
+ * Maximum selection-set nesting depth (read from `TINA4_GRAPHQL_MAX_DEPTH`,
72
+ * default 50; `<= 0` disables the guard). Public so tests can set it and the
73
+ * dev app can introspect it. Counted per selection level AND per fragment
74
+ * spread / inline fragment, so circular fragments are caught too.
75
+ */
76
+ maxDepth: number;
77
+ /**
78
+ * Decorator-style resolver registration.
79
+ *
80
+ * Resolvers may be synchronous OR async (return a Promise) — `execute()`
81
+ * awaits every resolver, so an `async` resolver's value is resolved before
82
+ * the field is serialized. Return a value directly, or `await` your data
83
+ * (e.g. an async DB driver) and the executor will await it for you.
84
+ *
85
+ * GraphQL.resolve("Query", "products", async (root, args) =>
86
+ * (await db.fetch("SELECT * FROM products")).records);
87
+ *
88
+ * GraphQL.resolve("Mutation", "createProduct", async (root, args) => {
89
+ * const p = new Product(args.input);
90
+ * await p.save();
91
+ * return p.toDict();
92
+ * });
93
+ *
94
+ * GraphQL.resolve("Product", "reviews", async (product, args) =>
95
+ * (await db.fetch("SELECT * FROM reviews WHERE product_id = ?", [product.id])).records);
96
+ *
97
+ * Resolvers registered before any GraphQL instance exists accumulate
98
+ * in the class-level registry. `new GraphQL()` drains them into its
99
+ * schema. Resolvers registered after `setDefault(gql)` wire into the
100
+ * live schema immediately.
101
+ */
102
+ static resolve(typeName: string, fieldName: string, resolver: ResolverFn): void;
103
+ /**
104
+ * Designate `instance` as the default singleton. Post-startup
105
+ * `GraphQL.resolve()` calls wire into this instance's live schema.
106
+ */
107
+ static setDefault(instance: GraphQL): void;
108
+ /** Test-only — clear the class-level registry. */
109
+ static _clearClassResolvers(): void;
110
+ constructor();
111
+ /** Wire a single resolver into the live schema. */
112
+ private attachResolver;
113
+ /**
114
+ * Get the field resolver registered for an object type, if any.
115
+ * Used by the executor during nested field resolution.
116
+ */
117
+ getFieldResolver(typeName: string, fieldName: string): ResolverFn | undefined;
118
+ /**
119
+ * Return schema metadata for debugging.
120
+ */
121
+ introspect(): Record<string, unknown>;
122
+ /**
123
+ * Register a named type with its fields.
124
+ */
125
+ addType(name: string, fields: Record<string, GraphQLField>): GraphQL;
126
+ /**
127
+ * Register a query resolver.
128
+ */
129
+ addQuery(name: string, args: Record<string, string>, returnType: string, resolver: ResolverFn): GraphQL;
130
+ /**
131
+ * Register a mutation resolver.
132
+ */
133
+ addMutation(name: string, args: Record<string, string>, returnType: string, resolver: ResolverFn): GraphQL;
134
+ /**
135
+ * Execute a GraphQL query string.
136
+ */
137
+ execute(query: string, variables?: Record<string, unknown>, context?: Record<string, unknown>): Promise<GraphQLResult>;
138
+ /**
139
+ * Resolve a list of selections and merge results into the `target` dict.
140
+ * Fragment spreads and inline fragments are merged (not nested).
141
+ *
142
+ * `depth` is incremented on every recursive entry (field sub-selections,
143
+ * fragment spreads, inline fragments) and checked against `maxDepth` so an
144
+ * over-deep query or a circular fragment fails with a structured error
145
+ * instead of recursing until the interpreter stack overflows. Top-level
146
+ * starts at depth 1; `maxDepth <= 0` disables the guard.
147
+ */
148
+ private resolveSelectionsInto;
149
+ /**
150
+ * Generate SDL schema string.
151
+ */
152
+ schemaSdl(): string;
153
+ /**
154
+ * Auto-generate type, queries, and CRUD mutations from an ORM model class.
155
+ *
156
+ * The model class must have static `tableName` (string) and `fields`
157
+ * (Record<string, { type: string; primaryKey?: boolean }>).
158
+ *
159
+ * Creates:
160
+ * - A GraphQL type from the model's fields
161
+ * - Queries: {modelName}(id: ID!): Type, {modelNames}(limit: Int, offset: Int): [Type]
162
+ * - Mutations: create{ModelName}, update{ModelName}, delete{ModelName}
163
+ *
164
+ * @param modelClass - The model class with static tableName and fields
165
+ * @param adapter - Optional database adapter; if omitted, resolvers will
166
+ * import getAdapter from @tina4/orm at call time
167
+ */
168
+ fromOrm(modelClass: {
169
+ tableName: string;
170
+ fields: Record<string, {
171
+ type: string;
172
+ primaryKey?: boolean;
173
+ }>;
174
+ name?: string;
175
+ }, adapter?: {
176
+ query: <T = Record<string, unknown>>(sql: string, params?: unknown[]) => T[];
177
+ execute: (sql: string, params?: unknown[]) => unknown;
178
+ }): GraphQL;
179
+ private formatArgs;
180
+ private resolveField;
181
+ private resolveArgs;
182
+ /**
183
+ * Check directives: @skip, @include, @auth, @role, @guest.
184
+ * Returns true if the field should be included, false to skip.
185
+ */
186
+ private checkDirectives;
187
+ /**
188
+ * Validate resolved args against declared types.
189
+ */
190
+ private validateArgs;
191
+ private coerceValue;
192
+ }
193
+ /**
194
+ * Lightweight GraphQL type wrapper matching Ruby's GraphQLType.
195
+ */
196
+ export declare class GraphQLType {
197
+ static readonly SCALARS: string[];
198
+ name: string;
199
+ kind: string;
200
+ ofType: GraphQLType | null;
201
+ constructor(name: string, kind?: string, ofType?: GraphQLType | null);
202
+ /**
203
+ * Parse a GraphQL type string like "String", "String!", "[Int!]!".
204
+ */
205
+ static parse(typeStr: string): GraphQLType;
206
+ }
207
+ export {};
@@ -0,0 +1,22 @@
1
+ import type { RouteDefinition } from "./types.js";
2
+ /**
3
+ * Resolve the health route path. Priority:
4
+ * 1. `TINA4_HEALTH_PATH` env var
5
+ * 2. Default `/__health` (matches Python parity — under-prefix avoids
6
+ * colliding with app routes named /health)
7
+ */
8
+ export declare function healthPath(): string;
9
+ /**
10
+ * Create the primary health route definition.
11
+ *
12
+ * Tests use this directly. Server bootstrap goes through createHealthRoutes()
13
+ * to also register the legacy `/health` alias when TINA4_HEALTH_PATH points
14
+ * elsewhere — matching Python behaviour so existing probes don't break.
15
+ */
16
+ export declare function createHealthRoute(version?: string): RouteDefinition;
17
+ /**
18
+ * Create one or two health routes — the env-defined path always, plus a
19
+ * legacy `/health` alias when the env path differs. Mirrors
20
+ * tina4-python's two-line registration in `core/server.py`.
21
+ */
22
+ export declare function createHealthRoutes(version?: string): RouteDefinition[];
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Programmatic HTML builder — avoids string concatenation.
3
+ *
4
+ * Usage:
5
+ * const el = new HtmlElement("div", { class: "card" }, ["Hello"]);
6
+ * el.toString(); // '<div class="card">Hello</div>'
7
+ *
8
+ * // Builder pattern
9
+ * const el = htmlElement("div")(htmlElement("p")("Text"));
10
+ *
11
+ * // Helper functions
12
+ * const h: Record<string, any> = {};
13
+ * addHtmlHelpers(h);
14
+ * const html = h._div({ class: "card" }, h._p("Hello"));
15
+ */
16
+ /**
17
+ * Raw — marker for trusted, pre-sanitised HTML that must render UNESCAPED.
18
+ *
19
+ * String/scalar children of an HtmlElement are HTML-escaped by default to
20
+ * prevent stored/reflected XSS. Wrap a value in Raw to opt out of escaping
21
+ * when (and only when) you have already sanitised it yourself.
22
+ *
23
+ * new HtmlElement("div", {}, ["<b>x</b>"]).toString() // &lt;b&gt;x&lt;/b&gt; (escaped)
24
+ * new HtmlElement("div", {}, [new Raw("<b>x</b>")]).toString() // <b>x</b> (raw)
25
+ *
26
+ * Alias: SafeString.
27
+ */
28
+ export declare class Raw {
29
+ readonly value: string;
30
+ constructor(value: string);
31
+ toString(): string;
32
+ }
33
+ export declare const SafeString: typeof Raw;
34
+ type Attrs = Record<string, string | number | boolean | null | undefined>;
35
+ type Child = string | number | HtmlElement | Raw;
36
+ /**
37
+ * HtmlElement — a single HTML tag with attributes and children.
38
+ */
39
+ export declare class HtmlElement {
40
+ readonly tag: string;
41
+ readonly attrs: Attrs;
42
+ readonly children: Child[];
43
+ constructor(tag: string, attrs?: Attrs, children?: Child[]);
44
+ /**
45
+ * Render to HTML string.
46
+ */
47
+ toString(): string;
48
+ }
49
+ /**
50
+ * Create a callable HTML element builder.
51
+ * Returns a function that, when called with children/attrs, produces a new HtmlElement.
52
+ *
53
+ * Usage:
54
+ * const div = htmlElement("div");
55
+ * const el = div({ class: "card" }, "Hello");
56
+ * console.log(el.toString()); // '<div class="card">Hello</div>'
57
+ */
58
+ export declare function htmlElement(tag: string, attrs?: Attrs, children?: Child[]): {
59
+ (...args: (Child | Attrs | Child[])[]): /*elided*/ any;
60
+ tag: string;
61
+ attrs: Attrs;
62
+ children: Child[];
63
+ toString(): string;
64
+ _isHtmlElement: boolean;
65
+ };
66
+ /**
67
+ * Injects helper functions (_div, _p, _a, _span, etc.) into the target object.
68
+ *
69
+ * Usage:
70
+ * const h: Record<string, any> = {};
71
+ * addHtmlHelpers(h);
72
+ * const html = h._div({ class: "card" }, h._p("Hello"));
73
+ */
74
+ export declare function addHtmlHelpers(target: Record<string, unknown>): void;
75
+ export {};
@@ -0,0 +1,37 @@
1
+ export declare class I18n {
2
+ private _localeDir;
3
+ private _defaultLocale;
4
+ private _currentLocale;
5
+ private _translations;
6
+ /**
7
+ * @param locale Default locale code (e.g. "en"). Falls back to
8
+ * TINA4_LOCALE, then "en".
9
+ * @param path Directory holding the JSON/YAML locale files. Falls back to
10
+ * TINA4_LOCALE_DIR, then "src/locales".
11
+ *
12
+ * Arg order is (locale, path) to match the Python master `I18n(locale, path)`
13
+ * (BUG-7, BREAKING in 3.13.x — was previously (localeDir, defaultLocale)).
14
+ */
15
+ constructor(locale?: string, path?: string);
16
+ setLocale(locale: string): void;
17
+ getLocale(): string;
18
+ /**
19
+ * Translate a key. Supports {placeholder} interpolation.
20
+ * Falls back to default locale, then returns the key itself.
21
+ */
22
+ t(key: string, params?: Record<string, string>, locale?: string): string;
23
+ /** Alias for t() */
24
+ translate(key: string, params?: Record<string, string>, locale?: string): string;
25
+ /** Load and return translations for a locale. */
26
+ loadTranslations(locale: string): Record<string, string>;
27
+ /** Add a single translation key/value to a locale (in-memory only). */
28
+ addTranslation(locale: string, key: string, value: string): void;
29
+ /** List available locale codes based on JSON files in the locale directory. */
30
+ availableLocales(): string[];
31
+ /** Load a locale file if not already loaded. */
32
+ private _loadLocale;
33
+ /** Flatten nested objects: {"a": {"b": "c"}} → {"a.b": "c"} */
34
+ /** Zero-dep YAML parser for simple key: value locale files. */
35
+ private static _parseSimpleYaml;
36
+ private static _flatten;
37
+ }
@@ -0,0 +1,93 @@
1
+ export type { Tina4Request, Tina4Response, RouteHandler, RouteDefinition, RouteMeta, Tina4Config, Middleware, MiddlewareSpec, UploadedFile, CookieOptions, WebSocketRouteHandler, WebSocketRouteDefinition, } from "./types.js";
2
+ export { startServer, resolvePortAndHost, handle, start, stop, httpReason, resolveTemplate, resetTemplateCache, templateAutoRoutingEnabled, isBannerSuppressed } from "./server.js";
3
+ export { background, stopAllBackgroundTasks, backgroundTaskCount } from "./background.js";
4
+ export { Router, RouteGroup, RouteRef, WsRouteRef, defaultRouter, runRouteMiddlewares, resolveStringMiddleware, isTrailingSlashRedirectEnabled } from "./router.js";
5
+ export { get, post, put, patch, del, any, websocket, del as delete } from "./router.js";
6
+ export type { RouteInfo } from "./router.js";
7
+ export { discoverRoutes } from "./routeDiscovery.js";
8
+ export { MiddlewareChain, MiddlewareRunner, cors, requestLogger, CorsMiddleware, RateLimiterMiddleware, RequestLogger, SecurityHeadersMiddleware, CsrfMiddleware } from "./middleware.js";
9
+ export type { CorsConfig } from "./middleware.js";
10
+ export { createRequest, makeCaseInsensitiveHeaders } from "./request.js";
11
+ export { createResponse, errorResponse, setDefaultTemplatesDir, getFrond, setFrond, getFrameworkFrond } from "./response.js";
12
+ export { tryServeStatic } from "./static.js";
13
+ export { loadEnv, getEnv, requireEnv, hasEnv, allEnv, resetEnv, isTruthy } from "./dotenv.js";
14
+ export { Env } from "./env.js";
15
+ export { Log } from "./logger.js";
16
+ export { createHealthRoute, createHealthRoutes, healthPath } from "./health.js";
17
+ export { rateLimiter } from "./rateLimiter.js";
18
+ export type { RateLimiterConfig } from "./rateLimiter.js";
19
+ export { HTTP_OK, HTTP_CREATED, HTTP_ACCEPTED, HTTP_NO_CONTENT, HTTP_MOVED, HTTP_REDIRECT, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST, HTTP_UNAUTHORIZED, HTTP_FORBIDDEN, HTTP_NOT_FOUND, HTTP_METHOD_NOT_ALLOWED, HTTP_CONFLICT, HTTP_GONE, HTTP_UNPROCESSABLE, HTTP_TOO_MANY, HTTP_SERVER_ERROR, HTTP_BAD_GATEWAY, HTTP_UNAVAILABLE, APPLICATION_JSON, APPLICATION_XML, APPLICATION_FORM, APPLICATION_OCTET, TEXT_HTML, TEXT_PLAIN, TEXT_CSV, TEXT_XML, } from "./constants.js";
20
+ export { getToken, validToken, getPayload, hashPassword, checkPassword, authMiddleware, refreshToken, authenticateRequest, validateApiKey, ensureDevSecret, Auth, } from "./auth.js";
21
+ export { Session, FileSessionHandler, RedisSessionHandler, buildSessionCookie, isSecureScheme, sessionCookieName } from "./session.js";
22
+ export type { SessionConfig, SessionHandler } from "./session.js";
23
+ export { I18n } from "./i18n.js";
24
+ export { FakeData } from "./fakeData.js";
25
+ export { ScssCompiler } from "./scss.js";
26
+ export type { ScssConfig } from "./scss.js";
27
+ export { Queue } from "./queue.js";
28
+ export type { QueueConfig, QueueJob, ProcessOptions } from "./queue.js";
29
+ export { createJob } from "./job.js";
30
+ export type { JobData, JobQueueBridge } from "./job.js";
31
+ export { Mqtt, MqttError, MqttTimeoutError } from "./mqtt.js";
32
+ export type { MqttOptions, ParsedMqttUrl } from "./mqtt.js";
33
+ export { MqttMessage } from "./mqttMessage.js";
34
+ export type { MqttAcknowledger } from "./mqttMessage.js";
35
+ export { GraphQL, ParseError, graphqlEndpoint, graphqlAutoSchemaEnabled, graphqlMaxDepth } from "./graphql.js";
36
+ export type { GraphQLField, ResolverFn, GraphQLResult } from "./graphql.js";
37
+ export { WebSocketServer, devReloadWs, computeAcceptKey, parseUpgradeHeaders, buildFrame, parseFrame, originAllowed, wsToken, wsAuthorized, offeredBearerSubprotocol, serveWebSocketRoute, wsRouteManager, OP_TEXT, OP_BINARY, OP_CLOSE, OP_PING, OP_PONG, CLOSE_NORMAL, CLOSE_GOING_AWAY, CLOSE_PROTOCOL_ERROR, CLOSE_POLICY_VIOLATION, } from "./websocket.js";
38
+ export type { WebSocketClient } from "./websocket.js";
39
+ export { ServiceRunner, Tina4Service, matchCronField, matchesCron } from "./service.js";
40
+ export type { ServiceOptions, ServiceContext, ServiceHandler, ServiceInfo } from "./service.js";
41
+ export { responseCache, clearCache, cacheStats, cacheGet, cacheSet, cacheDelete, cacheClear, cacheBackendStats, createBackend, _resetBackend } from "./cache.js";
42
+ export type { ResponseCacheConfig, CacheBackend } from "./cache.js";
43
+ export { Api } from "./api.js";
44
+ export type { ApiResult, ApiOptions, ApiTransport, DownloadResult, UploadOptions } from "./api.js";
45
+ export { Context, defaultContext, existingContext, fts5Supported, _sharedContexts } from "./context/index.js";
46
+ export type { SearchHit } from "./context/index.js";
47
+ export { Events } from "./events.js";
48
+ export { DevAdmin, MessageLog, RequestInspector, ErrorTracker, DevMailboxStore, DevQueue, WsTracker, supervisorBaseUrl, devAdminLanguage } from "./devAdmin.js";
49
+ export { feedbackEnabled, feedbackWhitelist, feedbackIdentifyUser, feedbackIsWhitelisted, feedbackRateLimitOk, injectFeedbackWidget, handleFeedbackTurn, handleFeedbackWidgetJs, registerFeedbackRoutes, } from "./feedback.js";
50
+ export { Messenger, MessengerConnectionError, createMessenger } from "./messenger.js";
51
+ export type { SendResult, EmailMessage } from "./messenger.js";
52
+ export { DevMailbox } from "./devMailbox.js";
53
+ export { WSDLService, WSDLOperation } from "./wsdl.js";
54
+ export type { WSDLOperationMeta } from "./wsdl.js";
55
+ export { HtmlElement, htmlElement, addHtmlHelpers, Raw, SafeString } from "./htmlElement.js";
56
+ export { renderErrorOverlay, renderProductionError, isDebugMode } from "./errorOverlay.js";
57
+ export { AI_TOOLS, isInstalled, showMenu, installSelected, installAll, generateContext } from "./ai.js";
58
+ export type { AiTool } from "./ai.js";
59
+ export type { ImapMessage, ImapFullMessage } from "./messenger.js";
60
+ export { LiteBackend } from "./queueBackends/liteBackend.js";
61
+ export { RabbitMQBackend, parseAmqpUrl } from "./queueBackends/rabbitmqBackend.js";
62
+ export type { RabbitMQConfig } from "./queueBackends/rabbitmqBackend.js";
63
+ export { KafkaBackend, kafkaSecurityConfig } from "./queueBackends/kafkaBackend.js";
64
+ export type { KafkaConfig, KafkaSecurityConfig, KafkaClientConfig, } from "./queueBackends/kafkaBackend.js";
65
+ export { MongoBackend } from "./queueBackends/mongoBackend.js";
66
+ export type { MongoConfig as MongoQueueConfig } from "./queueBackends/mongoBackend.js";
67
+ export { DatabaseSessionHandler } from "./sessionHandlers/databaseHandler.js";
68
+ export type { DatabaseSessionConfig } from "./sessionHandlers/databaseHandler.js";
69
+ export { MongoSessionHandler } from "./sessionHandlers/mongoHandler.js";
70
+ export type { MongoSessionConfig } from "./sessionHandlers/mongoHandler.js";
71
+ export { ValkeySessionHandler } from "./sessionHandlers/valkeyHandler.js";
72
+ export type { ValkeySessionConfig } from "./sessionHandlers/valkeyHandler.js";
73
+ export { RedisNpmSessionHandler } from "./sessionHandlers/redisHandler.js";
74
+ export type { RedisNpmSessionConfig } from "./sessionHandlers/redisHandler.js";
75
+ export { tests, assertEqual, assertRaises, assertTrue, assertFalse, runAll, reset } from "./testing.js";
76
+ export { TestClient, TestResponse } from "./testClient.js";
77
+ export { Tina4Test, AssertionError as Tina4AssertionError } from "./test.js";
78
+ export type { TestRunResults } from "./test.js";
79
+ export { Container, container } from "./container.js";
80
+ export { Validator } from "./validator.js";
81
+ export type { ValidationError } from "./validator.js";
82
+ export type { WebSocketConnection } from "./websocketConnection.js";
83
+ export { RedisBackplane, NATSBackplane, createBackplane, WsBackplaneManager, buildEnvelope, WS_BACKPLANE_CHANNEL, } from "./websocketBackplane.js";
84
+ export type { WebSocketBackplane, WsEnvelope, WsEnvelopeKind, WsBackplaneLogger, } from "./websocketBackplane.js";
85
+ export { McpServer, mcpTool, mcpResource, registerDevTools, getDefaultDevServer, encodeResponse, encodeError, encodeNotification, decodeRequest, schemaFromParams, isLocalhost, isLoopback, mcpEnabled, isRequestAllowed, mcpPort, PARSE_ERROR, INVALID_REQUEST, METHOD_NOT_FOUND, INVALID_PARAMS, INTERNAL_ERROR, } from "./mcp.js";
86
+ export type { JsonRpcMessage, McpToolDefinition, McpResourceDefinition, JsonSchema, McpToolParam } from "./mcp.js";
87
+ export { Plan } from "./plan.js";
88
+ export type { PlanStep, ParsedPlan, PlanSummary, ExecutionSummary, CurrentPlan } from "./plan.js";
89
+ export { ProjectIndex } from "./projectIndex.js";
90
+ export type { FileEntry, FileRoute } from "./projectIndex.js";
91
+ export { Docs } from "./docs.js";
92
+ export type { DocsHit, ClassSpec, MethodSpec, IndexEntry, DriftHit } from "./docs.js";
93
+ export { writeMcpDiscovery } from "./docsAutoDiscovery.js";