fraiseql 2.1.1
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 +784 -0
- package/dist/index.d.mts +1688 -0
- package/dist/index.d.ts +1688 -0
- package/dist/index.js +1345 -0
- package/dist/index.mjs +1265 -0
- package/package.json +82 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,1688 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type mapping and introspection for GraphQL schema generation.
|
|
3
|
+
*
|
|
4
|
+
* This module converts TypeScript type annotations to GraphQL type strings,
|
|
5
|
+
* enabling compile-time schema generation without runtime overhead.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Convert TypeScript type to GraphQL type string.
|
|
9
|
+
*
|
|
10
|
+
* @param type - TypeScript type annotation
|
|
11
|
+
* @returns Tuple of [graphql_type, is_nullable]
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* typeToGraphQL(String) => ["String", false]
|
|
15
|
+
* typeToGraphQL(String | null) => ["String", true]
|
|
16
|
+
* typeToGraphQL(Array<User>) => ["[User!]", false]
|
|
17
|
+
*/
|
|
18
|
+
declare function typeToGraphQL(type: unknown): [graphqlType: string, nullable: boolean];
|
|
19
|
+
/**
|
|
20
|
+
* Field information extracted from a class with type metadata.
|
|
21
|
+
*/
|
|
22
|
+
interface FieldInfo {
|
|
23
|
+
type: string;
|
|
24
|
+
nullable: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Extract field information from class property metadata.
|
|
28
|
+
*
|
|
29
|
+
* @param fields - Dictionary mapping field names to type annotations
|
|
30
|
+
* @returns Dictionary of field_name -> FieldInfo
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const fields = {
|
|
34
|
+
* id: "number",
|
|
35
|
+
* name: "string",
|
|
36
|
+
* email: "string | null"
|
|
37
|
+
* };
|
|
38
|
+
* extractFieldInfo(fields) => {
|
|
39
|
+
* id: { type: "Int", nullable: false },
|
|
40
|
+
* name: { type: "String", nullable: false },
|
|
41
|
+
* email: { type: "String", nullable: true }
|
|
42
|
+
* }
|
|
43
|
+
*/
|
|
44
|
+
declare function extractFieldInfo(fields: Record<string, unknown>): Record<string, FieldInfo>;
|
|
45
|
+
/**
|
|
46
|
+
* Argument information for a function parameter.
|
|
47
|
+
*/
|
|
48
|
+
interface ArgumentInfo {
|
|
49
|
+
name: string;
|
|
50
|
+
type: string;
|
|
51
|
+
nullable: boolean;
|
|
52
|
+
default?: unknown;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Return type information for a function.
|
|
56
|
+
*/
|
|
57
|
+
interface ReturnTypeInfo {
|
|
58
|
+
type: string;
|
|
59
|
+
nullable: boolean;
|
|
60
|
+
isList: boolean;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Function signature information extracted from a decorated function.
|
|
64
|
+
*/
|
|
65
|
+
interface FunctionSignature {
|
|
66
|
+
arguments: ArgumentInfo[];
|
|
67
|
+
returnType: ReturnTypeInfo;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Extract GraphQL-relevant information from function signature.
|
|
71
|
+
*
|
|
72
|
+
* @param name - Function name
|
|
73
|
+
* @param params - Dictionary mapping parameter names to type annotations
|
|
74
|
+
* @param returnType - Return type annotation
|
|
75
|
+
* @returns FunctionSignature with arguments and return type info
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* extractFunctionSignature(
|
|
79
|
+
* "users",
|
|
80
|
+
* { limit: "number", offset: "number" },
|
|
81
|
+
* "User[]"
|
|
82
|
+
* ) => {
|
|
83
|
+
* arguments: [
|
|
84
|
+
* { name: "limit", type: "Int", nullable: false },
|
|
85
|
+
* { name: "offset", type: "Int", nullable: false }
|
|
86
|
+
* ],
|
|
87
|
+
* returnType: { type: "[User!]", nullable: false, isList: true }
|
|
88
|
+
* }
|
|
89
|
+
*/
|
|
90
|
+
declare function extractFunctionSignature(_name: string, params: Record<string, unknown>, returnType: unknown): FunctionSignature;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* FraiseQL scalar type markers for schema authoring.
|
|
94
|
+
*
|
|
95
|
+
* These are branded type aliases used in TypeScript to generate the correct
|
|
96
|
+
* GraphQL scalar types in schema.json. They have no runtime behavior - validation
|
|
97
|
+
* and serialization happen in the Rust runtime after compilation.
|
|
98
|
+
*
|
|
99
|
+
* Architecture:
|
|
100
|
+
* TypeScript type annotation → schema.json type string → Rust FieldType → codegen/introspection
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* import { Type } from "fraiseql";
|
|
105
|
+
* import { ID, DateTime, Email, URL } from "fraiseql/scalars";
|
|
106
|
+
*
|
|
107
|
+
* @Type()
|
|
108
|
+
* class User {
|
|
109
|
+
* id: ID; // → "ID" in schema.json → FieldType::Id
|
|
110
|
+
* name: string; // → "String"
|
|
111
|
+
* email: Email; // → "Email" → FieldType::Scalar("Email")
|
|
112
|
+
* website: URL | null; // → "URL" (nullable)
|
|
113
|
+
* createdAt: DateTime; // → "DateTime" → FieldType::DateTime
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* FraiseQL Convention:
|
|
118
|
+
* - `id` fields should ALWAYS use `ID` type (UUID v4 at runtime)
|
|
119
|
+
* - Foreign keys (e.g., `authorId`) should also use `ID`
|
|
120
|
+
*
|
|
121
|
+
* Custom Scalars:
|
|
122
|
+
* You can define your own custom scalars using branded types:
|
|
123
|
+
*
|
|
124
|
+
* ```typescript
|
|
125
|
+
* type MyCustomScalar = string & { readonly __brand: "MyCustomScalar" };
|
|
126
|
+
* ```
|
|
127
|
+
*
|
|
128
|
+
* The scalar name will pass through to schema.json and be validated at runtime.
|
|
129
|
+
*
|
|
130
|
+
* @packageDocumentation
|
|
131
|
+
*/
|
|
132
|
+
/**
|
|
133
|
+
* Abstract base class for custom GraphQL scalars with validation.
|
|
134
|
+
*
|
|
135
|
+
* Subclasses must define a `name` property and implement
|
|
136
|
+
* the three validation methods (serialize, parseValue, parseLiteral).
|
|
137
|
+
*
|
|
138
|
+
* Use with the @Scalar decorator to register custom scalars with the schema.
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* class Email extends CustomScalar {
|
|
143
|
+
* name = "Email"
|
|
144
|
+
*
|
|
145
|
+
* serialize(value: unknown): string {
|
|
146
|
+
* return String(value)
|
|
147
|
+
* }
|
|
148
|
+
*
|
|
149
|
+
* parseValue(value: unknown): string {
|
|
150
|
+
* const str = String(value)
|
|
151
|
+
* if (!str.includes("@")) {
|
|
152
|
+
* throw new Error("Invalid email address")
|
|
153
|
+
* }
|
|
154
|
+
* return str
|
|
155
|
+
* }
|
|
156
|
+
*
|
|
157
|
+
* parseLiteral(ast: unknown): string {
|
|
158
|
+
* if (ast && typeof ast === "object" && "value" in ast) {
|
|
159
|
+
* return this.parseValue((ast as any).value)
|
|
160
|
+
* }
|
|
161
|
+
* throw new Error("Invalid email literal")
|
|
162
|
+
* }
|
|
163
|
+
* }
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
declare abstract class CustomScalar {
|
|
167
|
+
/**
|
|
168
|
+
* Scalar name (e.g., "Email"). Must be unique in schema.
|
|
169
|
+
*/
|
|
170
|
+
abstract name: string;
|
|
171
|
+
/**
|
|
172
|
+
* Convert value to output format (schema → response).
|
|
173
|
+
*
|
|
174
|
+
* Called when serializing a field value in GraphQL response.
|
|
175
|
+
*
|
|
176
|
+
* @param value - The internal representation (from database/object)
|
|
177
|
+
* @returns The value formatted for GraphQL response (usually string)
|
|
178
|
+
* @throws If value cannot be serialized
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```typescript
|
|
182
|
+
* serialize(value: Date): string {
|
|
183
|
+
* return value.toISOString()
|
|
184
|
+
* }
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
abstract serialize(value: unknown): unknown;
|
|
188
|
+
/**
|
|
189
|
+
* Validate and convert input value (client input → internal).
|
|
190
|
+
*
|
|
191
|
+
* Called when a scalar is passed as a variable in GraphQL query.
|
|
192
|
+
*
|
|
193
|
+
* @param value - Raw input value from client
|
|
194
|
+
* @returns Validated/converted value
|
|
195
|
+
* @throws If validation fails
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```typescript
|
|
199
|
+
* parseValue(value: unknown): string {
|
|
200
|
+
* const str = String(value)
|
|
201
|
+
* if (!str.includes("@")) {
|
|
202
|
+
* throw new Error("Invalid email address")
|
|
203
|
+
* }
|
|
204
|
+
* return str
|
|
205
|
+
* }
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
abstract parseValue(value: unknown): unknown;
|
|
209
|
+
/**
|
|
210
|
+
* Parse GraphQL literal (hardcoded value in query).
|
|
211
|
+
*
|
|
212
|
+
* Called when a scalar is hardcoded in the GraphQL query string
|
|
213
|
+
* (not as a variable).
|
|
214
|
+
*
|
|
215
|
+
* @param ast - GraphQL AST node representing the literal
|
|
216
|
+
* @returns Validated/converted value
|
|
217
|
+
* @throws If literal cannot be parsed
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```typescript
|
|
221
|
+
* parseLiteral(ast: unknown): string {
|
|
222
|
+
* if (ast && typeof ast === "object" && "value" in ast) {
|
|
223
|
+
* return this.parseValue((ast as any).value)
|
|
224
|
+
* }
|
|
225
|
+
* throw new Error(`Invalid email literal: ${ast}`)
|
|
226
|
+
* }
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
abstract parseLiteral(ast: unknown): unknown;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Creates a branded type for nominal typing.
|
|
233
|
+
* This allows TypeScript to distinguish between different scalar types at compile time.
|
|
234
|
+
*/
|
|
235
|
+
type Brand<T, B extends string> = T & {
|
|
236
|
+
readonly __brand: B;
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* GraphQL ID scalar - used for unique identifiers.
|
|
240
|
+
*
|
|
241
|
+
* FraiseQL enforces UUID v4 format for all ID fields at runtime.
|
|
242
|
+
* This is the REQUIRED type for `id` fields and foreign key references.
|
|
243
|
+
*/
|
|
244
|
+
type ID = Brand<string, "ID">;
|
|
245
|
+
/** ISO 8601 DateTime scalar (e.g., "2025-01-10T12:00:00Z"). */
|
|
246
|
+
type DateTime = Brand<string, "DateTime">;
|
|
247
|
+
/** ISO 8601 Date scalar (e.g., "2025-01-10"). */
|
|
248
|
+
type Date = Brand<string, "Date">;
|
|
249
|
+
/** ISO 8601 Time scalar (e.g., "12:00:00"). */
|
|
250
|
+
type Time = Brand<string, "Time">;
|
|
251
|
+
/** Date range scalar (e.g., "[2025-01-01,2025-12-31)"). */
|
|
252
|
+
type DateRange = Brand<string, "DateRange">;
|
|
253
|
+
/** ISO 8601 Duration scalar (e.g., "P1Y2M3D"). */
|
|
254
|
+
type Duration = Brand<string, "Duration">;
|
|
255
|
+
/** Arbitrary JSON value scalar. Maps to PostgreSQL JSONB. */
|
|
256
|
+
type Json = Brand<unknown, "Json">;
|
|
257
|
+
/** UUID scalar (explicit UUID type, distinct from ID). */
|
|
258
|
+
type UUID = Brand<string, "UUID">;
|
|
259
|
+
/** Decimal/BigDecimal scalar for precise numeric values. */
|
|
260
|
+
type Decimal = Brand<string, "Decimal">;
|
|
261
|
+
/** Vector scalar for pgvector embeddings. */
|
|
262
|
+
type Vector = Brand<number[], "Vector">;
|
|
263
|
+
/** Email address scalar with RFC 5322 validation. */
|
|
264
|
+
type Email = Brand<string, "Email">;
|
|
265
|
+
/** Phone number scalar (E.164 format recommended). */
|
|
266
|
+
type PhoneNumber = Brand<string, "PhoneNumber">;
|
|
267
|
+
/** URL scalar with RFC 3986 validation. */
|
|
268
|
+
type URL = Brand<string, "URL">;
|
|
269
|
+
/** Domain name scalar. */
|
|
270
|
+
type DomainName = Brand<string, "DomainName">;
|
|
271
|
+
/** Hostname scalar. */
|
|
272
|
+
type Hostname = Brand<string, "Hostname">;
|
|
273
|
+
/** Postal/ZIP code scalar. */
|
|
274
|
+
type PostalCode = Brand<string, "PostalCode">;
|
|
275
|
+
/** Latitude coordinate (-90 to 90). */
|
|
276
|
+
type Latitude = Brand<number, "Latitude">;
|
|
277
|
+
/** Longitude coordinate (-180 to 180). */
|
|
278
|
+
type Longitude = Brand<number, "Longitude">;
|
|
279
|
+
/** Geographic coordinates scalar (lat,lng or GeoJSON). */
|
|
280
|
+
type Coordinates = Brand<string, "Coordinates">;
|
|
281
|
+
/** IANA timezone identifier (e.g., "America/New_York"). */
|
|
282
|
+
type Timezone = Brand<string, "Timezone">;
|
|
283
|
+
/** Locale code scalar (e.g., "en-US"). */
|
|
284
|
+
type LocaleCode = Brand<string, "LocaleCode">;
|
|
285
|
+
/** ISO 639-1 language code (e.g., "en"). */
|
|
286
|
+
type LanguageCode = Brand<string, "LanguageCode">;
|
|
287
|
+
/** ISO 3166-1 alpha-2 country code (e.g., "US"). */
|
|
288
|
+
type CountryCode = Brand<string, "CountryCode">;
|
|
289
|
+
/** International Bank Account Number. */
|
|
290
|
+
type IBAN = Brand<string, "IBAN">;
|
|
291
|
+
/** CUSIP identifier for North American securities. */
|
|
292
|
+
type CUSIP = Brand<string, "CUSIP">;
|
|
293
|
+
/** International Securities Identification Number. */
|
|
294
|
+
type ISIN = Brand<string, "ISIN">;
|
|
295
|
+
/** Stock Exchange Daily Official List number. */
|
|
296
|
+
type SEDOL = Brand<string, "SEDOL">;
|
|
297
|
+
/** Legal Entity Identifier. */
|
|
298
|
+
type LEI = Brand<string, "LEI">;
|
|
299
|
+
/** Market Identifier Code. */
|
|
300
|
+
type MIC = Brand<string, "MIC">;
|
|
301
|
+
/** ISO 4217 currency code (e.g., "USD"). */
|
|
302
|
+
type CurrencyCode = Brand<string, "CurrencyCode">;
|
|
303
|
+
/** Monetary amount with currency (e.g., "USD 100.00"). */
|
|
304
|
+
type Money = Brand<string, "Money">;
|
|
305
|
+
/** Stock exchange code. */
|
|
306
|
+
type ExchangeCode = Brand<string, "ExchangeCode">;
|
|
307
|
+
/** Currency exchange rate. */
|
|
308
|
+
type ExchangeRate = Brand<string, "ExchangeRate">;
|
|
309
|
+
/** Stock ticker symbol. */
|
|
310
|
+
type StockSymbol = Brand<string, "StockSymbol">;
|
|
311
|
+
/** Percentage value (0-100 or 0-1 depending on context). */
|
|
312
|
+
type Percentage = Brand<number, "Percentage">;
|
|
313
|
+
/** URL-safe slug (lowercase, hyphens, no spaces). */
|
|
314
|
+
type Slug = Brand<string, "Slug">;
|
|
315
|
+
/** Semantic version string (e.g., "1.2.3"). */
|
|
316
|
+
type SemanticVersion = Brand<string, "SemanticVersion">;
|
|
317
|
+
/** SHA-256 hash string (64 hex characters). */
|
|
318
|
+
type HashSHA256 = Brand<string, "HashSHA256">;
|
|
319
|
+
/** API key string. */
|
|
320
|
+
type APIKey = Brand<string, "APIKey">;
|
|
321
|
+
/** Vehicle license plate number. */
|
|
322
|
+
type LicensePlate = Brand<string, "LicensePlate">;
|
|
323
|
+
/** Vehicle Identification Number. */
|
|
324
|
+
type VIN = Brand<string, "VIN">;
|
|
325
|
+
/** Shipping tracking number. */
|
|
326
|
+
type TrackingNumber = Brand<string, "TrackingNumber">;
|
|
327
|
+
/** Shipping container number (ISO 6346). */
|
|
328
|
+
type ContainerNumber = Brand<string, "ContainerNumber">;
|
|
329
|
+
/** IP address (IPv4 or IPv6). */
|
|
330
|
+
type IPAddress = Brand<string, "IPAddress">;
|
|
331
|
+
/** IPv4 address. */
|
|
332
|
+
type IPv4 = Brand<string, "IPv4">;
|
|
333
|
+
/** IPv6 address. */
|
|
334
|
+
type IPv6 = Brand<string, "IPv6">;
|
|
335
|
+
/** MAC address. */
|
|
336
|
+
type MACAddress = Brand<string, "MACAddress">;
|
|
337
|
+
/** CIDR notation for IP ranges. */
|
|
338
|
+
type CIDR = Brand<string, "CIDR">;
|
|
339
|
+
/** Network port number (0-65535). */
|
|
340
|
+
type Port = Brand<number, "Port">;
|
|
341
|
+
/** IATA airport code (e.g., "JFK"). */
|
|
342
|
+
type AirportCode = Brand<string, "AirportCode">;
|
|
343
|
+
/** UN/LOCODE port code. */
|
|
344
|
+
type PortCode = Brand<string, "PortCode">;
|
|
345
|
+
/** Flight number (e.g., "AA123"). */
|
|
346
|
+
type FlightNumber = Brand<string, "FlightNumber">;
|
|
347
|
+
/** Markdown-formatted text. */
|
|
348
|
+
type Markdown = Brand<string, "Markdown">;
|
|
349
|
+
/** HTML-formatted text. */
|
|
350
|
+
type HTML = Brand<string, "HTML">;
|
|
351
|
+
/** MIME type (e.g., "application/json"). */
|
|
352
|
+
type MimeType = Brand<string, "MimeType">;
|
|
353
|
+
/** Color value (hex, RGB, or named). */
|
|
354
|
+
type Color = Brand<string, "Color">;
|
|
355
|
+
/** Image reference (URL or base64). */
|
|
356
|
+
type Image = Brand<string, "Image">;
|
|
357
|
+
/** File reference (URL or path). */
|
|
358
|
+
type File = Brand<string, "File">;
|
|
359
|
+
/** PostgreSQL ltree path (e.g., "root.child.leaf"). */
|
|
360
|
+
type LTree = Brand<string, "LTree">;
|
|
361
|
+
/**
|
|
362
|
+
* Set of all known scalar type names.
|
|
363
|
+
* Used by the type system to recognize scalar types.
|
|
364
|
+
*/
|
|
365
|
+
declare const SCALAR_NAMES: Set<string>;
|
|
366
|
+
/**
|
|
367
|
+
* Check if a type name is a known scalar type.
|
|
368
|
+
*/
|
|
369
|
+
declare function isScalarType(typeName: string): boolean;
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Global schema registry for collecting types, queries, and mutations.
|
|
373
|
+
*
|
|
374
|
+
* This module maintains a singleton registry of all definitions made via decorators,
|
|
375
|
+
* which is then exported to schema.json for compilation.
|
|
376
|
+
*/
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Field metadata for access control and deprecation.
|
|
380
|
+
*/
|
|
381
|
+
interface FieldMetadata {
|
|
382
|
+
requiresScope?: string | string[];
|
|
383
|
+
deprecated?: boolean | string;
|
|
384
|
+
description?: string;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Field definition in a GraphQL type.
|
|
388
|
+
*/
|
|
389
|
+
interface Field extends FieldMetadata {
|
|
390
|
+
name: string;
|
|
391
|
+
type: string;
|
|
392
|
+
nullable: boolean;
|
|
393
|
+
default?: unknown;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* GraphQL type definition.
|
|
397
|
+
*/
|
|
398
|
+
interface TypeDefinition {
|
|
399
|
+
name: string;
|
|
400
|
+
fields: Field[];
|
|
401
|
+
description?: string;
|
|
402
|
+
relay?: boolean;
|
|
403
|
+
sql_source?: string;
|
|
404
|
+
jsonb_column?: string;
|
|
405
|
+
is_error?: boolean;
|
|
406
|
+
requires_role?: string;
|
|
407
|
+
implements?: string[];
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Argument definition for a query or mutation.
|
|
411
|
+
*/
|
|
412
|
+
interface ArgumentDefinition {
|
|
413
|
+
name: string;
|
|
414
|
+
type: string;
|
|
415
|
+
nullable: boolean;
|
|
416
|
+
default?: unknown;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* GraphQL query definition.
|
|
420
|
+
*/
|
|
421
|
+
interface QueryDefinition {
|
|
422
|
+
name: string;
|
|
423
|
+
return_type: string;
|
|
424
|
+
returns_list: boolean;
|
|
425
|
+
nullable: boolean;
|
|
426
|
+
arguments: ArgumentDefinition[];
|
|
427
|
+
description?: string;
|
|
428
|
+
[key: string]: unknown;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* GraphQL mutation definition.
|
|
432
|
+
*/
|
|
433
|
+
interface MutationDefinition {
|
|
434
|
+
name: string;
|
|
435
|
+
return_type: string;
|
|
436
|
+
returns_list: boolean;
|
|
437
|
+
nullable: boolean;
|
|
438
|
+
arguments: ArgumentDefinition[];
|
|
439
|
+
description?: string;
|
|
440
|
+
operation?: string;
|
|
441
|
+
[key: string]: unknown;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Measure definition in a fact table.
|
|
445
|
+
*/
|
|
446
|
+
interface Measure {
|
|
447
|
+
name: string;
|
|
448
|
+
sql_type: string;
|
|
449
|
+
nullable: boolean;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Dimension path in a fact table.
|
|
453
|
+
*/
|
|
454
|
+
interface DimensionPath {
|
|
455
|
+
name: string;
|
|
456
|
+
json_path: string;
|
|
457
|
+
data_type: string;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Dimension definition in a fact table.
|
|
461
|
+
*/
|
|
462
|
+
interface Dimension {
|
|
463
|
+
name: string;
|
|
464
|
+
paths: DimensionPath[];
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Denormalized filter in a fact table.
|
|
468
|
+
*/
|
|
469
|
+
interface DenormalizedFilter {
|
|
470
|
+
name: string;
|
|
471
|
+
sql_type: string;
|
|
472
|
+
indexed: boolean;
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Fact table definition.
|
|
476
|
+
*/
|
|
477
|
+
interface FactTableDefinition {
|
|
478
|
+
table_name: string;
|
|
479
|
+
measures: Measure[];
|
|
480
|
+
dimensions: Dimension;
|
|
481
|
+
denormalized_filters: DenormalizedFilter[];
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Aggregate query definition.
|
|
485
|
+
*/
|
|
486
|
+
interface AggregateQueryDefinition {
|
|
487
|
+
name: string;
|
|
488
|
+
fact_table: string;
|
|
489
|
+
auto_group_by: boolean;
|
|
490
|
+
auto_aggregates: boolean;
|
|
491
|
+
description?: string;
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* GraphQL subscription definition.
|
|
495
|
+
*
|
|
496
|
+
* Subscriptions in FraiseQL are compiled projections of database events.
|
|
497
|
+
* They are sourced from LISTEN/NOTIFY or CDC, not resolver-based.
|
|
498
|
+
*/
|
|
499
|
+
interface SubscriptionDefinition {
|
|
500
|
+
name: string;
|
|
501
|
+
entity_type: string;
|
|
502
|
+
nullable: boolean;
|
|
503
|
+
arguments: ArgumentDefinition[];
|
|
504
|
+
description?: string;
|
|
505
|
+
topic?: string;
|
|
506
|
+
operation?: string;
|
|
507
|
+
[key: string]: unknown;
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Observer action definition.
|
|
511
|
+
*/
|
|
512
|
+
interface ObserverAction {
|
|
513
|
+
type: "webhook" | "slack" | "email";
|
|
514
|
+
[key: string]: unknown;
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Observer retry configuration.
|
|
518
|
+
*/
|
|
519
|
+
interface ObserverRetryConfig {
|
|
520
|
+
max_attempts: number;
|
|
521
|
+
backoff_strategy: string;
|
|
522
|
+
initial_delay_ms: number;
|
|
523
|
+
max_delay_ms: number;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Observer definition.
|
|
527
|
+
*/
|
|
528
|
+
interface ObserverDefinition {
|
|
529
|
+
name: string;
|
|
530
|
+
entity: string;
|
|
531
|
+
event: string;
|
|
532
|
+
actions: ObserverAction[];
|
|
533
|
+
condition?: string;
|
|
534
|
+
retry: ObserverRetryConfig;
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Enum value definition.
|
|
538
|
+
*/
|
|
539
|
+
interface EnumValue {
|
|
540
|
+
name: string;
|
|
541
|
+
deprecated?: {
|
|
542
|
+
reason: string;
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* GraphQL enum definition.
|
|
547
|
+
*/
|
|
548
|
+
interface EnumDefinition {
|
|
549
|
+
name: string;
|
|
550
|
+
values: EnumValue[];
|
|
551
|
+
description?: string;
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* GraphQL interface definition.
|
|
555
|
+
*/
|
|
556
|
+
interface InterfaceDefinition {
|
|
557
|
+
name: string;
|
|
558
|
+
fields: Field[];
|
|
559
|
+
description?: string;
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* GraphQL input type definition.
|
|
563
|
+
*/
|
|
564
|
+
interface InputTypeDefinition {
|
|
565
|
+
name: string;
|
|
566
|
+
fields: Array<Field & {
|
|
567
|
+
default?: unknown;
|
|
568
|
+
}>;
|
|
569
|
+
description?: string;
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* GraphQL union definition.
|
|
573
|
+
*/
|
|
574
|
+
interface UnionDefinition {
|
|
575
|
+
name: string;
|
|
576
|
+
member_types: string[];
|
|
577
|
+
description?: string;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Complete schema definition.
|
|
581
|
+
*/
|
|
582
|
+
interface Schema {
|
|
583
|
+
types: TypeDefinition[];
|
|
584
|
+
queries: QueryDefinition[];
|
|
585
|
+
mutations: MutationDefinition[];
|
|
586
|
+
subscriptions: SubscriptionDefinition[];
|
|
587
|
+
enums?: EnumDefinition[];
|
|
588
|
+
interfaces?: InterfaceDefinition[];
|
|
589
|
+
input_types?: InputTypeDefinition[];
|
|
590
|
+
unions?: UnionDefinition[];
|
|
591
|
+
fact_tables?: FactTableDefinition[];
|
|
592
|
+
aggregate_queries?: AggregateQueryDefinition[];
|
|
593
|
+
observers?: ObserverDefinition[];
|
|
594
|
+
/** Apollo Federation v2 metadata, included when generateSchemaJson() is used. */
|
|
595
|
+
federation?: {
|
|
596
|
+
enabled: boolean;
|
|
597
|
+
version: string;
|
|
598
|
+
[key: string]: unknown;
|
|
599
|
+
};
|
|
600
|
+
/** Custom scalar definitions, included when scalars are registered. */
|
|
601
|
+
customScalars?: Record<string, {
|
|
602
|
+
name: string;
|
|
603
|
+
description: string;
|
|
604
|
+
validate: boolean;
|
|
605
|
+
}>;
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Global schema registry (singleton).
|
|
609
|
+
*
|
|
610
|
+
* Maintains maps of all registered types, queries, mutations, and analytics definitions.
|
|
611
|
+
* These are collected during decorator evaluation and exported to schema.json.
|
|
612
|
+
*/
|
|
613
|
+
declare class SchemaRegistry {
|
|
614
|
+
private static types;
|
|
615
|
+
private static queries;
|
|
616
|
+
private static mutations;
|
|
617
|
+
private static subscriptions;
|
|
618
|
+
private static enums;
|
|
619
|
+
private static interfaces;
|
|
620
|
+
private static inputTypes;
|
|
621
|
+
private static unions;
|
|
622
|
+
private static factTables;
|
|
623
|
+
private static aggregateQueries;
|
|
624
|
+
private static observers;
|
|
625
|
+
private static customScalars;
|
|
626
|
+
/**
|
|
627
|
+
* Register a GraphQL type.
|
|
628
|
+
*
|
|
629
|
+
* @param name - Type name (e.g., "User")
|
|
630
|
+
* @param fields - List of field definitions
|
|
631
|
+
* @param description - Optional type description
|
|
632
|
+
* @param options - Additional type options
|
|
633
|
+
*/
|
|
634
|
+
static registerType(name: string, fields: Field[], description?: string, options?: {
|
|
635
|
+
relay?: boolean;
|
|
636
|
+
sqlSource?: string;
|
|
637
|
+
jsonbColumn?: string;
|
|
638
|
+
isError?: boolean;
|
|
639
|
+
requiresRole?: string;
|
|
640
|
+
implements?: string[];
|
|
641
|
+
}): void;
|
|
642
|
+
/**
|
|
643
|
+
* Register a GraphQL query.
|
|
644
|
+
*
|
|
645
|
+
* @param name - Query name
|
|
646
|
+
* @param returnType - Return type name
|
|
647
|
+
* @param returnsList - Whether query returns a list
|
|
648
|
+
* @param nullable - Whether result can be null
|
|
649
|
+
* @param args - List of argument definitions
|
|
650
|
+
* @param description - Optional query description
|
|
651
|
+
* @param config - Additional configuration (sql_source, etc.)
|
|
652
|
+
*/
|
|
653
|
+
static registerQuery(name: string, returnType: string, returnsList: boolean, nullable: boolean, args: ArgumentDefinition[], description?: string, config?: Record<string, unknown>): void;
|
|
654
|
+
/**
|
|
655
|
+
* Register a GraphQL mutation.
|
|
656
|
+
*
|
|
657
|
+
* @param name - Mutation name
|
|
658
|
+
* @param returnType - Return type name
|
|
659
|
+
* @param returnsList - Whether mutation returns a list
|
|
660
|
+
* @param nullable - Whether result can be null
|
|
661
|
+
* @param args - List of argument definitions
|
|
662
|
+
* @param description - Optional mutation description
|
|
663
|
+
* @param config - Additional configuration (sql_source, operation, etc.)
|
|
664
|
+
*/
|
|
665
|
+
static registerMutation(name: string, returnType: string, returnsList: boolean, nullable: boolean, args: ArgumentDefinition[], description?: string, config?: Record<string, unknown>): void;
|
|
666
|
+
/**
|
|
667
|
+
* Register a GraphQL subscription.
|
|
668
|
+
*
|
|
669
|
+
* Subscriptions in FraiseQL are compiled projections of database events.
|
|
670
|
+
* They are sourced from LISTEN/NOTIFY or CDC, not resolver-based.
|
|
671
|
+
*
|
|
672
|
+
* @param name - Subscription name
|
|
673
|
+
* @param entityType - Entity type name being subscribed to
|
|
674
|
+
* @param nullable - Whether result can be null
|
|
675
|
+
* @param args - List of argument definitions (filters)
|
|
676
|
+
* @param description - Optional subscription description
|
|
677
|
+
* @param config - Additional configuration (topic, operation, etc.)
|
|
678
|
+
*/
|
|
679
|
+
static registerSubscription(name: string, entityType: string, nullable: boolean, args: ArgumentDefinition[], description?: string, config?: Record<string, unknown>): void;
|
|
680
|
+
/**
|
|
681
|
+
* Register a fact table definition.
|
|
682
|
+
*
|
|
683
|
+
* @param tableName - Fact table name
|
|
684
|
+
* @param measures - List of measure definitions
|
|
685
|
+
* @param dimensions - Dimension metadata
|
|
686
|
+
* @param denormalizedFilters - List of denormalized filter definitions
|
|
687
|
+
*/
|
|
688
|
+
static registerFactTable(tableName: string, measures: Measure[], dimensions: Dimension, denormalizedFilters: DenormalizedFilter[]): void;
|
|
689
|
+
/**
|
|
690
|
+
* Register an aggregate query definition.
|
|
691
|
+
*
|
|
692
|
+
* @param name - Query name
|
|
693
|
+
* @param factTable - Fact table name
|
|
694
|
+
* @param autoGroupBy - Auto-generate groupBy fields
|
|
695
|
+
* @param autoAggregates - Auto-generate aggregate fields
|
|
696
|
+
* @param description - Optional query description
|
|
697
|
+
*/
|
|
698
|
+
static registerAggregateQuery(name: string, factTable: string, autoGroupBy: boolean, autoAggregates: boolean, description?: string): void;
|
|
699
|
+
/**
|
|
700
|
+
* Register an observer.
|
|
701
|
+
*
|
|
702
|
+
* @param name - Observer function name
|
|
703
|
+
* @param entity - Entity type to observe
|
|
704
|
+
* @param event - Event type (INSERT, UPDATE, or DELETE)
|
|
705
|
+
* @param actions - List of action configurations
|
|
706
|
+
* @param condition - Optional condition expression
|
|
707
|
+
* @param retry - Retry configuration
|
|
708
|
+
*/
|
|
709
|
+
static registerObserver(name: string, entity: string, event: string, actions: ObserverAction[], condition?: string, retry?: ObserverRetryConfig): void;
|
|
710
|
+
/**
|
|
711
|
+
* Register a GraphQL enum type.
|
|
712
|
+
*
|
|
713
|
+
* @param name - Enum name (e.g., "OrderStatus")
|
|
714
|
+
* @param values - List of enum value definitions
|
|
715
|
+
* @param description - Optional enum description
|
|
716
|
+
*/
|
|
717
|
+
static registerEnum(name: string, values: EnumValue[], description?: string): void;
|
|
718
|
+
/**
|
|
719
|
+
* Register a GraphQL interface type.
|
|
720
|
+
*
|
|
721
|
+
* @param name - Interface name (e.g., "Node")
|
|
722
|
+
* @param fields - List of field definitions
|
|
723
|
+
* @param description - Optional interface description
|
|
724
|
+
*/
|
|
725
|
+
static registerInterface(name: string, fields: Field[], description?: string): void;
|
|
726
|
+
/**
|
|
727
|
+
* Register a GraphQL input type.
|
|
728
|
+
*
|
|
729
|
+
* @param name - Input type name (e.g., "CreateUserInput")
|
|
730
|
+
* @param fields - List of field definitions with optional defaults
|
|
731
|
+
* @param description - Optional input type description
|
|
732
|
+
*/
|
|
733
|
+
static registerInputType(name: string, fields: Array<Field & {
|
|
734
|
+
default?: unknown;
|
|
735
|
+
}>, description?: string): void;
|
|
736
|
+
/**
|
|
737
|
+
* Register a GraphQL union type.
|
|
738
|
+
*
|
|
739
|
+
* @param name - Union name (e.g., "SearchResult")
|
|
740
|
+
* @param memberTypes - List of member type names
|
|
741
|
+
* @param description - Optional union description
|
|
742
|
+
*/
|
|
743
|
+
static registerUnion(name: string, memberTypes: string[], description?: string): void;
|
|
744
|
+
/**
|
|
745
|
+
* Register a custom scalar.
|
|
746
|
+
*
|
|
747
|
+
* @param name - Scalar name (e.g., "Email")
|
|
748
|
+
* @param scalarClass - The CustomScalar subclass
|
|
749
|
+
* @param description - Optional scalar description
|
|
750
|
+
*
|
|
751
|
+
* @throws If scalar name is not unique
|
|
752
|
+
*/
|
|
753
|
+
static registerScalar(name: string, scalarClass: typeof CustomScalar, description?: string): void;
|
|
754
|
+
/**
|
|
755
|
+
* Get all registered custom scalars.
|
|
756
|
+
*
|
|
757
|
+
* @returns Map of scalar names to CustomScalar classes
|
|
758
|
+
*/
|
|
759
|
+
static getCustomScalars(): Map<string, typeof CustomScalar>;
|
|
760
|
+
/**
|
|
761
|
+
* Get the complete schema as an object.
|
|
762
|
+
*
|
|
763
|
+
* @returns Schema object with types, queries, mutations, subscriptions, and analytics sections
|
|
764
|
+
*/
|
|
765
|
+
static getSchema(): Schema;
|
|
766
|
+
/**
|
|
767
|
+
* Clear the registry (useful for testing).
|
|
768
|
+
*/
|
|
769
|
+
static clear(): void;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* Decorators for FraiseQL schema authoring (compile-time only).
|
|
774
|
+
*
|
|
775
|
+
* These decorators register type and query definitions with the schema registry
|
|
776
|
+
* for JSON export. NO runtime behavior - only metadata collection.
|
|
777
|
+
*/
|
|
778
|
+
|
|
779
|
+
/**
|
|
780
|
+
* Create field-level metadata for access control and deprecation.
|
|
781
|
+
*
|
|
782
|
+
* This function creates metadata for use with field definitions to add:
|
|
783
|
+
* - `requiresScope`: JWT scope required to access this field
|
|
784
|
+
* - `deprecated`: Deprecation marker with optional reason
|
|
785
|
+
* - `description`: Field description for GraphQL schema
|
|
786
|
+
*
|
|
787
|
+
* @param options - Field metadata options
|
|
788
|
+
* @returns Field metadata object
|
|
789
|
+
*
|
|
790
|
+
* @example
|
|
791
|
+
* ```typescript
|
|
792
|
+
* fraiseql.registerTypeFields("User", [
|
|
793
|
+
* { name: "id", type: "ID", nullable: false },
|
|
794
|
+
* {
|
|
795
|
+
* name: "salary",
|
|
796
|
+
* type: "Decimal",
|
|
797
|
+
* nullable: false,
|
|
798
|
+
* requiresScope: "read:User.salary" // Requires JWT scope
|
|
799
|
+
* },
|
|
800
|
+
* {
|
|
801
|
+
* name: "oldEmail",
|
|
802
|
+
* type: "String",
|
|
803
|
+
* nullable: true,
|
|
804
|
+
* deprecated: "Use email instead" // Deprecation marker
|
|
805
|
+
* }
|
|
806
|
+
* ]);
|
|
807
|
+
* ```
|
|
808
|
+
*/
|
|
809
|
+
declare function field(options: FieldMetadata): FieldMetadata;
|
|
810
|
+
/**
|
|
811
|
+
* Configuration for a Type decorator.
|
|
812
|
+
*/
|
|
813
|
+
interface TypeConfig {
|
|
814
|
+
description?: string;
|
|
815
|
+
relay?: boolean;
|
|
816
|
+
sqlSource?: string;
|
|
817
|
+
crud?: boolean | string[];
|
|
818
|
+
cascade?: boolean;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Decorator to mark a class as a GraphQL type.
|
|
822
|
+
*
|
|
823
|
+
* This decorator registers the class with the schema registry for JSON export.
|
|
824
|
+
* NO runtime behavior - only used for schema compilation.
|
|
825
|
+
*
|
|
826
|
+
* @param config - Optional configuration
|
|
827
|
+
* @returns Decorator function
|
|
828
|
+
*
|
|
829
|
+
* @example
|
|
830
|
+
* ```ts
|
|
831
|
+
* @Type()
|
|
832
|
+
* class User {
|
|
833
|
+
* id: number;
|
|
834
|
+
* name: string;
|
|
835
|
+
* email: string | null;
|
|
836
|
+
* }
|
|
837
|
+
* ```
|
|
838
|
+
*
|
|
839
|
+
* This generates JSON:
|
|
840
|
+
* ```json
|
|
841
|
+
* {
|
|
842
|
+
* "name": "User",
|
|
843
|
+
* "fields": [
|
|
844
|
+
* {"name": "id", "type": "Int", "nullable": false},
|
|
845
|
+
* {"name": "name", "type": "String", "nullable": false},
|
|
846
|
+
* {"name": "email", "type": "String", "nullable": true}
|
|
847
|
+
* ]
|
|
848
|
+
* }
|
|
849
|
+
* ```
|
|
850
|
+
*/
|
|
851
|
+
declare function Type(_config?: TypeConfig): <T extends {
|
|
852
|
+
new (...args: any[]): object;
|
|
853
|
+
}>(constructor: T) => T;
|
|
854
|
+
/**
|
|
855
|
+
* Configuration for Query and Mutation decorators.
|
|
856
|
+
*/
|
|
857
|
+
interface OperationConfig {
|
|
858
|
+
sqlSource?: string;
|
|
859
|
+
autoParams?: Record<string, boolean>;
|
|
860
|
+
operation?: string;
|
|
861
|
+
jsonbColumn?: string;
|
|
862
|
+
relay?: boolean;
|
|
863
|
+
[key: string]: unknown;
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
866
|
+
* Decorator to mark a function as a GraphQL query.
|
|
867
|
+
*
|
|
868
|
+
* This decorator registers the function with the schema registry for JSON export.
|
|
869
|
+
* NO runtime behavior - only used for schema compilation.
|
|
870
|
+
*
|
|
871
|
+
* Configuration is provided via parameters:
|
|
872
|
+
* - sqlSource: SQL view name or table name
|
|
873
|
+
* - autoParams: Auto-parameter configuration
|
|
874
|
+
* - Other configuration as needed
|
|
875
|
+
*
|
|
876
|
+
* @param config - Query configuration
|
|
877
|
+
* @returns Decorator function
|
|
878
|
+
*
|
|
879
|
+
* @example
|
|
880
|
+
* ```ts
|
|
881
|
+
* @Query({ sqlSource: "v_user" })
|
|
882
|
+
* function users(limit: number = 10, offset: number = 0): User[] {
|
|
883
|
+
* pass;
|
|
884
|
+
* }
|
|
885
|
+
* ```
|
|
886
|
+
*
|
|
887
|
+
* This generates JSON:
|
|
888
|
+
* ```json
|
|
889
|
+
* {
|
|
890
|
+
* "name": "users",
|
|
891
|
+
* "return_type": "User",
|
|
892
|
+
* "returns_list": true,
|
|
893
|
+
* "nullable": false,
|
|
894
|
+
* "arguments": [
|
|
895
|
+
* {"name": "limit", "type": "Int", "nullable": false, "default": 10},
|
|
896
|
+
* {"name": "offset", "type": "Int", "nullable": false, "default": 0}
|
|
897
|
+
* ],
|
|
898
|
+
* "sql_source": "v_user"
|
|
899
|
+
* }
|
|
900
|
+
* ```
|
|
901
|
+
*/
|
|
902
|
+
declare function Query(config?: OperationConfig): (_target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
903
|
+
/**
|
|
904
|
+
* Configuration for Mutation decorator.
|
|
905
|
+
*/
|
|
906
|
+
interface MutationConfig extends OperationConfig {
|
|
907
|
+
operation?: "CREATE" | "UPDATE" | "DELETE" | "CUSTOM";
|
|
908
|
+
}
|
|
909
|
+
/**
|
|
910
|
+
* Decorator to mark a function as a GraphQL mutation.
|
|
911
|
+
*
|
|
912
|
+
* This decorator registers the function with the schema registry for JSON export.
|
|
913
|
+
* NO runtime behavior - only used for schema compilation.
|
|
914
|
+
*
|
|
915
|
+
* @param config - Mutation configuration
|
|
916
|
+
* @returns Decorator function
|
|
917
|
+
*
|
|
918
|
+
* @example
|
|
919
|
+
* ```ts
|
|
920
|
+
* @Mutation({ sqlSource: "fn_create_user", operation: "CREATE" })
|
|
921
|
+
* function createUser(name: string, email: string): User {
|
|
922
|
+
* pass;
|
|
923
|
+
* }
|
|
924
|
+
* ```
|
|
925
|
+
*
|
|
926
|
+
* This generates JSON:
|
|
927
|
+
* ```json
|
|
928
|
+
* {
|
|
929
|
+
* "name": "createUser",
|
|
930
|
+
* "return_type": "User",
|
|
931
|
+
* "returns_list": false,
|
|
932
|
+
* "nullable": false,
|
|
933
|
+
* "arguments": [
|
|
934
|
+
* {"name": "name", "type": "String", "nullable": false},
|
|
935
|
+
* {"name": "email", "type": "String", "nullable": false}
|
|
936
|
+
* ],
|
|
937
|
+
* "sql_source": "fn_create_user",
|
|
938
|
+
* "operation": "CREATE"
|
|
939
|
+
* }
|
|
940
|
+
* ```
|
|
941
|
+
*/
|
|
942
|
+
declare function Mutation(config?: MutationConfig): (_target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
943
|
+
/**
|
|
944
|
+
* Configuration for Enum decorator.
|
|
945
|
+
*/
|
|
946
|
+
interface EnumConfig {
|
|
947
|
+
description?: string;
|
|
948
|
+
}
|
|
949
|
+
/**
|
|
950
|
+
* Decorator to mark an object as a GraphQL enum.
|
|
951
|
+
*
|
|
952
|
+
* This decorator registers the enum with the schema registry for JSON export.
|
|
953
|
+
* NO runtime behavior - only used for schema compilation.
|
|
954
|
+
*
|
|
955
|
+
* @param values - Object with enum values as keys (values are not used, only keys matter)
|
|
956
|
+
* @param config - Optional configuration
|
|
957
|
+
* @returns Decorator function
|
|
958
|
+
*
|
|
959
|
+
* @example
|
|
960
|
+
* ```ts
|
|
961
|
+
* const OrderStatus = enum('OrderStatus', {
|
|
962
|
+
* PENDING: 'pending',
|
|
963
|
+
* SHIPPED: 'shipped',
|
|
964
|
+
* DELIVERED: 'delivered'
|
|
965
|
+
* }, {
|
|
966
|
+
* description: 'The status of an order'
|
|
967
|
+
* })
|
|
968
|
+
* ```
|
|
969
|
+
*
|
|
970
|
+
* This generates JSON:
|
|
971
|
+
* ```json
|
|
972
|
+
* {
|
|
973
|
+
* "name": "OrderStatus",
|
|
974
|
+
* "description": "The status of an order",
|
|
975
|
+
* "values": [
|
|
976
|
+
* {"name": "PENDING"},
|
|
977
|
+
* {"name": "SHIPPED"},
|
|
978
|
+
* {"name": "DELIVERED"}
|
|
979
|
+
* ]
|
|
980
|
+
* }
|
|
981
|
+
* ```
|
|
982
|
+
*/
|
|
983
|
+
declare function enum_(name: string, values: Record<string, unknown>, config?: EnumConfig): Record<string, unknown>;
|
|
984
|
+
/**
|
|
985
|
+
* Configuration for Interface decorator.
|
|
986
|
+
*/
|
|
987
|
+
interface InterfaceConfig {
|
|
988
|
+
description?: string;
|
|
989
|
+
}
|
|
990
|
+
/**
|
|
991
|
+
* Decorator to mark a class as a GraphQL interface.
|
|
992
|
+
*
|
|
993
|
+
* This decorator registers the interface with the schema registry for JSON export.
|
|
994
|
+
* NO runtime behavior - only used for schema compilation.
|
|
995
|
+
*
|
|
996
|
+
* Interfaces define a common set of fields that multiple object types can implement.
|
|
997
|
+
* Per GraphQL spec §3.7, interfaces enable polymorphic queries.
|
|
998
|
+
*
|
|
999
|
+
* @param name - Interface name
|
|
1000
|
+
* @param fields - Field definitions
|
|
1001
|
+
* @param config - Optional configuration
|
|
1002
|
+
* @returns Interface marker object
|
|
1003
|
+
*
|
|
1004
|
+
* @example
|
|
1005
|
+
* ```ts
|
|
1006
|
+
* const Node = interface('Node', {
|
|
1007
|
+
* id: { type: 'ID', nullable: false },
|
|
1008
|
+
* createdAt: { type: 'DateTime', nullable: false }
|
|
1009
|
+
* }, {
|
|
1010
|
+
* description: 'An object with a globally unique ID'
|
|
1011
|
+
* })
|
|
1012
|
+
* ```
|
|
1013
|
+
*/
|
|
1014
|
+
declare function interface_(name: string, fields: Field[], config?: InterfaceConfig): Record<string, unknown>;
|
|
1015
|
+
/**
|
|
1016
|
+
* Configuration for Union decorator.
|
|
1017
|
+
*/
|
|
1018
|
+
interface UnionConfig {
|
|
1019
|
+
description?: string;
|
|
1020
|
+
}
|
|
1021
|
+
/**
|
|
1022
|
+
* Decorator to mark a class as a GraphQL union type.
|
|
1023
|
+
*
|
|
1024
|
+
* Per GraphQL spec §3.10, unions represent a type that could be one of
|
|
1025
|
+
* several object types. Unlike interfaces, unions don't define common fields.
|
|
1026
|
+
*
|
|
1027
|
+
* This decorator registers the union with the schema registry for JSON export.
|
|
1028
|
+
* NO runtime behavior - only used for schema compilation.
|
|
1029
|
+
*
|
|
1030
|
+
* @param name - Union name
|
|
1031
|
+
* @param memberTypes - List of member type names
|
|
1032
|
+
* @param config - Optional configuration
|
|
1033
|
+
* @returns Union marker object
|
|
1034
|
+
*
|
|
1035
|
+
* @example
|
|
1036
|
+
* ```ts
|
|
1037
|
+
* const SearchResult = union('SearchResult', ['User', 'Post', 'Comment'], {
|
|
1038
|
+
* description: 'Result of a search query'
|
|
1039
|
+
* })
|
|
1040
|
+
* ```
|
|
1041
|
+
*/
|
|
1042
|
+
declare function union(name: string, memberTypes: string[], config?: UnionConfig): Record<string, unknown>;
|
|
1043
|
+
/**
|
|
1044
|
+
* Configuration for Input decorator.
|
|
1045
|
+
*/
|
|
1046
|
+
interface InputConfig {
|
|
1047
|
+
description?: string;
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Decorator to mark a class as a GraphQL input type.
|
|
1051
|
+
*
|
|
1052
|
+
* This decorator registers the input type with the schema registry for JSON export.
|
|
1053
|
+
* NO runtime behavior - only used for schema compilation.
|
|
1054
|
+
*
|
|
1055
|
+
* @param name - Input type name
|
|
1056
|
+
* @param fields - Field definitions with optional defaults
|
|
1057
|
+
* @param config - Optional configuration
|
|
1058
|
+
* @returns Input marker object
|
|
1059
|
+
*
|
|
1060
|
+
* @example
|
|
1061
|
+
* ```ts
|
|
1062
|
+
* const CreateUserInput = input('CreateUserInput', [
|
|
1063
|
+
* { name: 'name', type: 'String', nullable: false },
|
|
1064
|
+
* { name: 'email', type: 'String', nullable: false },
|
|
1065
|
+
* { name: 'role', type: 'String', nullable: false, default: 'user' }
|
|
1066
|
+
* ], {
|
|
1067
|
+
* description: 'Input for creating a new user'
|
|
1068
|
+
* })
|
|
1069
|
+
* ```
|
|
1070
|
+
*/
|
|
1071
|
+
declare function input(name: string, fields: Array<Field & {
|
|
1072
|
+
default?: unknown;
|
|
1073
|
+
}>, config?: InputConfig): Record<string, unknown>;
|
|
1074
|
+
/**
|
|
1075
|
+
* Helper function to manually register type fields with metadata.
|
|
1076
|
+
*
|
|
1077
|
+
* Since TypeScript doesn't preserve type information at runtime by default,
|
|
1078
|
+
* this helper allows explicit field registration for types.
|
|
1079
|
+
*
|
|
1080
|
+
* @param typeName - Name of the type
|
|
1081
|
+
* @param fields - Field definitions
|
|
1082
|
+
* @param description - Optional type description
|
|
1083
|
+
*
|
|
1084
|
+
* @example
|
|
1085
|
+
* ```ts
|
|
1086
|
+
* @Type()
|
|
1087
|
+
* class User {
|
|
1088
|
+
* id: number;
|
|
1089
|
+
* name: string;
|
|
1090
|
+
* email: string | null;
|
|
1091
|
+
* }
|
|
1092
|
+
*
|
|
1093
|
+
* registerTypeFields("User", [
|
|
1094
|
+
* { name: "id", type: "Int", nullable: false },
|
|
1095
|
+
* { name: "name", type: "String", nullable: false },
|
|
1096
|
+
* { name: "email", type: "String", nullable: true }
|
|
1097
|
+
* ]);
|
|
1098
|
+
* ```
|
|
1099
|
+
*/
|
|
1100
|
+
declare function registerTypeFields(typeName: string, fields: Field[], description?: string, options?: {
|
|
1101
|
+
relay?: boolean;
|
|
1102
|
+
sqlSource?: string;
|
|
1103
|
+
jsonbColumn?: string;
|
|
1104
|
+
isError?: boolean;
|
|
1105
|
+
requiresRole?: string;
|
|
1106
|
+
implements?: string[];
|
|
1107
|
+
crud?: boolean | string[];
|
|
1108
|
+
cascade?: boolean;
|
|
1109
|
+
}): void;
|
|
1110
|
+
/**
|
|
1111
|
+
* Helper function to manually register query with full metadata.
|
|
1112
|
+
*
|
|
1113
|
+
* @param name - Query name
|
|
1114
|
+
* @param returnType - Return type name
|
|
1115
|
+
* @param returnsList - Whether query returns a list
|
|
1116
|
+
* @param nullable - Whether result can be null
|
|
1117
|
+
* @param args - Argument definitions
|
|
1118
|
+
* @param description - Optional query description
|
|
1119
|
+
* @param config - Additional configuration
|
|
1120
|
+
*
|
|
1121
|
+
* @example
|
|
1122
|
+
* ```ts
|
|
1123
|
+
* registerQuery(
|
|
1124
|
+
* "users",
|
|
1125
|
+
* "User",
|
|
1126
|
+
* true,
|
|
1127
|
+
* false,
|
|
1128
|
+
* [
|
|
1129
|
+
* { name: "limit", type: "Int", nullable: false, default: 10 },
|
|
1130
|
+
* { name: "offset", type: "Int", nullable: false, default: 0 }
|
|
1131
|
+
* ],
|
|
1132
|
+
* "Get list of users",
|
|
1133
|
+
* { sql_source: "v_user" }
|
|
1134
|
+
* );
|
|
1135
|
+
* ```
|
|
1136
|
+
*/
|
|
1137
|
+
declare function registerQuery(name: string, returnType: string, returnsList: boolean, nullable: boolean, args: ArgumentDefinition[], description?: string, config?: Record<string, unknown>): void;
|
|
1138
|
+
/**
|
|
1139
|
+
* Helper function to manually register mutation with full metadata.
|
|
1140
|
+
*
|
|
1141
|
+
* @param name - Mutation name
|
|
1142
|
+
* @param returnType - Return type name
|
|
1143
|
+
* @param returnsList - Whether mutation returns a list
|
|
1144
|
+
* @param nullable - Whether result can be null
|
|
1145
|
+
* @param args - Argument definitions
|
|
1146
|
+
* @param description - Optional mutation description
|
|
1147
|
+
* @param config - Additional configuration
|
|
1148
|
+
*/
|
|
1149
|
+
declare function registerMutation(name: string, returnType: string, returnsList: boolean, nullable: boolean, args: ArgumentDefinition[], description?: string, config?: Record<string, unknown>): void;
|
|
1150
|
+
/**
|
|
1151
|
+
* Configuration for Subscription decorator.
|
|
1152
|
+
*/
|
|
1153
|
+
interface SubscriptionConfig {
|
|
1154
|
+
entityType?: string;
|
|
1155
|
+
topic?: string;
|
|
1156
|
+
operation?: "CREATE" | "UPDATE" | "DELETE";
|
|
1157
|
+
[key: string]: unknown;
|
|
1158
|
+
}
|
|
1159
|
+
/**
|
|
1160
|
+
* Decorator to mark a function as a GraphQL subscription.
|
|
1161
|
+
*
|
|
1162
|
+
* This decorator registers the function with the schema registry for JSON export.
|
|
1163
|
+
* NO runtime behavior - only used for schema compilation.
|
|
1164
|
+
*
|
|
1165
|
+
* Subscriptions in FraiseQL are compiled projections of database events.
|
|
1166
|
+
* They are sourced from LISTEN/NOTIFY or CDC, not resolver-based.
|
|
1167
|
+
*
|
|
1168
|
+
* @param config - Subscription configuration
|
|
1169
|
+
* @returns Decorator function
|
|
1170
|
+
*
|
|
1171
|
+
* @example
|
|
1172
|
+
* ```ts
|
|
1173
|
+
* @Subscription({ topic: "order_events" })
|
|
1174
|
+
* function orderCreated(userId?: string): Order {
|
|
1175
|
+
* pass;
|
|
1176
|
+
* }
|
|
1177
|
+
* ```
|
|
1178
|
+
*
|
|
1179
|
+
* This generates JSON:
|
|
1180
|
+
* ```json
|
|
1181
|
+
* {
|
|
1182
|
+
* "name": "orderCreated",
|
|
1183
|
+
* "entity_type": "Order",
|
|
1184
|
+
* "nullable": false,
|
|
1185
|
+
* "arguments": [
|
|
1186
|
+
* {"name": "userId", "type": "String", "nullable": true}
|
|
1187
|
+
* ],
|
|
1188
|
+
* "topic": "order_events"
|
|
1189
|
+
* }
|
|
1190
|
+
* ```
|
|
1191
|
+
*/
|
|
1192
|
+
declare function Subscription(config?: SubscriptionConfig): (_target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
1193
|
+
/**
|
|
1194
|
+
* Helper function to manually register subscription with full metadata.
|
|
1195
|
+
*
|
|
1196
|
+
* @param name - Subscription name
|
|
1197
|
+
* @param entityType - Entity type being subscribed to
|
|
1198
|
+
* @param nullable - Whether result can be null
|
|
1199
|
+
* @param args - Argument definitions (filters)
|
|
1200
|
+
* @param description - Optional subscription description
|
|
1201
|
+
* @param config - Additional configuration (topic, operation)
|
|
1202
|
+
*
|
|
1203
|
+
* @example
|
|
1204
|
+
* ```ts
|
|
1205
|
+
* registerSubscription(
|
|
1206
|
+
* "orderCreated",
|
|
1207
|
+
* "Order",
|
|
1208
|
+
* false,
|
|
1209
|
+
* [
|
|
1210
|
+
* { name: "userId", type: "String", nullable: true }
|
|
1211
|
+
* ],
|
|
1212
|
+
* "Subscribe to new orders",
|
|
1213
|
+
* { topic: "order_events", operation: "CREATE" }
|
|
1214
|
+
* );
|
|
1215
|
+
* ```
|
|
1216
|
+
*/
|
|
1217
|
+
declare function registerSubscription(name: string, entityType: string, nullable: boolean, args: ArgumentDefinition[], description?: string, config?: Record<string, unknown>): void;
|
|
1218
|
+
/**
|
|
1219
|
+
* Decorator to register a custom scalar with the schema.
|
|
1220
|
+
*
|
|
1221
|
+
* This decorator registers the scalar globally so it can be:
|
|
1222
|
+
* 1. Used in type annotations
|
|
1223
|
+
* 2. Exported to schema.json
|
|
1224
|
+
* 3. Validated at runtime
|
|
1225
|
+
*
|
|
1226
|
+
* @param target - CustomScalar subclass
|
|
1227
|
+
* @returns The original class (unmodified)
|
|
1228
|
+
* @throws If scalar name is not unique
|
|
1229
|
+
* @throws If class doesn't extend CustomScalar
|
|
1230
|
+
*
|
|
1231
|
+
* @example
|
|
1232
|
+
* ```typescript
|
|
1233
|
+
* @Scalar()
|
|
1234
|
+
* class Email extends CustomScalar {
|
|
1235
|
+
* name = "Email"
|
|
1236
|
+
*
|
|
1237
|
+
* serialize(value: unknown): string {
|
|
1238
|
+
* return String(value)
|
|
1239
|
+
* }
|
|
1240
|
+
*
|
|
1241
|
+
* parseValue(value: unknown): string {
|
|
1242
|
+
* const str = String(value)
|
|
1243
|
+
* if (!str.includes("@")) {
|
|
1244
|
+
* throw new Error("Invalid email")
|
|
1245
|
+
* }
|
|
1246
|
+
* return str
|
|
1247
|
+
* }
|
|
1248
|
+
*
|
|
1249
|
+
* parseLiteral(ast: unknown): string {
|
|
1250
|
+
* if (ast && typeof ast === "object" && "value" in ast) {
|
|
1251
|
+
* return this.parseValue((ast as any).value)
|
|
1252
|
+
* }
|
|
1253
|
+
* throw new Error("Invalid email literal")
|
|
1254
|
+
* }
|
|
1255
|
+
* }
|
|
1256
|
+
*
|
|
1257
|
+
* // Use in type:
|
|
1258
|
+
* @Type()
|
|
1259
|
+
* class User {
|
|
1260
|
+
* id: string
|
|
1261
|
+
* email: Email // Uses registered Email scalar
|
|
1262
|
+
* name: string
|
|
1263
|
+
* }
|
|
1264
|
+
*
|
|
1265
|
+
* // Export schema
|
|
1266
|
+
* const schema = exportSchema("schema.json")
|
|
1267
|
+
* // schema contains: "customScalars": {"Email": {...}}
|
|
1268
|
+
* ```
|
|
1269
|
+
*
|
|
1270
|
+
* @remarks
|
|
1271
|
+
* - Decorator returns class unmodified (no runtime FFI)
|
|
1272
|
+
* - Registration is global (per-process)
|
|
1273
|
+
* - Name must be unique within schema
|
|
1274
|
+
* - Scalar must be defined before @Type that uses it
|
|
1275
|
+
*/
|
|
1276
|
+
declare function Scalar<T extends typeof CustomScalar>(target: T): T;
|
|
1277
|
+
|
|
1278
|
+
/**
|
|
1279
|
+
* CRUD operation generation for FraiseQL types.
|
|
1280
|
+
*
|
|
1281
|
+
* When `crud` is enabled on a type, this module auto-generates standard
|
|
1282
|
+
* GraphQL queries (get-by-ID, list) and mutations (create, update, delete)
|
|
1283
|
+
* following FraiseQL naming conventions.
|
|
1284
|
+
*/
|
|
1285
|
+
|
|
1286
|
+
/**
|
|
1287
|
+
* Generate CRUD queries and mutations for a type.
|
|
1288
|
+
*
|
|
1289
|
+
* @param typeName - The GraphQL type name (PascalCase)
|
|
1290
|
+
* @param fields - The type's field definitions
|
|
1291
|
+
* @param crud - `true` for all operations, or an array of specific operations
|
|
1292
|
+
* @param sqlSource - Optional SQL source override (defaults to `v_{snake_name}`)
|
|
1293
|
+
* @param cascade - Whether generated mutations include `cascade: true`
|
|
1294
|
+
*
|
|
1295
|
+
* @throws If `crud` contains unknown operation names
|
|
1296
|
+
* @throws If the type has no fields
|
|
1297
|
+
*/
|
|
1298
|
+
declare function generateCrudOperations(typeName: string, fields: Field[], crud: boolean | string[], sqlSource?: string, cascade?: boolean): void;
|
|
1299
|
+
|
|
1300
|
+
/**
|
|
1301
|
+
* Schema export functionality for FraiseQL.
|
|
1302
|
+
*
|
|
1303
|
+
* This module provides functions to export the schema registry to JSON files
|
|
1304
|
+
* that can be consumed by the fraiseql-cli compiler.
|
|
1305
|
+
*/
|
|
1306
|
+
|
|
1307
|
+
/**
|
|
1308
|
+
* Configuration helper for queries and mutations.
|
|
1309
|
+
*
|
|
1310
|
+
* This function is called inside decorated functions to specify SQL mapping
|
|
1311
|
+
* and other configuration. The config is stored temporarily and applied by
|
|
1312
|
+
* the decorator.
|
|
1313
|
+
*
|
|
1314
|
+
* @param config - Configuration options:
|
|
1315
|
+
* - sqlSource: SQL view name (queries) or function name (mutations)
|
|
1316
|
+
* - operation: Mutation operation type (CREATE, UPDATE, DELETE, CUSTOM)
|
|
1317
|
+
* - autoParams: Auto-parameter configuration (limit, offset, where, order_by)
|
|
1318
|
+
* - jsonbColumn: JSONB column name for flexible schemas
|
|
1319
|
+
*
|
|
1320
|
+
* @example
|
|
1321
|
+
* ```ts
|
|
1322
|
+
* @Query()
|
|
1323
|
+
* function users(limit: number = 10) {
|
|
1324
|
+
* return config({
|
|
1325
|
+
* sqlSource: "v_user",
|
|
1326
|
+
* autoParams: { limit: true, offset: true, where: true }
|
|
1327
|
+
* });
|
|
1328
|
+
* }
|
|
1329
|
+
*
|
|
1330
|
+
* @Mutation()
|
|
1331
|
+
* function createUser(name: string, email: string) {
|
|
1332
|
+
* return config({
|
|
1333
|
+
* sqlSource: "fn_create_user",
|
|
1334
|
+
* operation: "CREATE"
|
|
1335
|
+
* });
|
|
1336
|
+
* }
|
|
1337
|
+
* ```
|
|
1338
|
+
*/
|
|
1339
|
+
declare function config(configObj: Record<string, unknown>): void;
|
|
1340
|
+
/**
|
|
1341
|
+
* Export the schema registry to a JSON file.
|
|
1342
|
+
*
|
|
1343
|
+
* This function should be called after all decorators have been processed
|
|
1344
|
+
* (typically at the end of the schema definition file).
|
|
1345
|
+
*
|
|
1346
|
+
* @param outputPath - Path to output schema.json file
|
|
1347
|
+
* @param options - Export options
|
|
1348
|
+
*
|
|
1349
|
+
* @example
|
|
1350
|
+
* ```ts
|
|
1351
|
+
* // At end of schema.ts
|
|
1352
|
+
* if (require.main === module) {
|
|
1353
|
+
* exportSchema("schema.json");
|
|
1354
|
+
* }
|
|
1355
|
+
* ```
|
|
1356
|
+
*
|
|
1357
|
+
* Notes:
|
|
1358
|
+
* - Call this after all decorators have been applied
|
|
1359
|
+
* - The output schema.json is consumed by fraiseql-cli
|
|
1360
|
+
* - Pretty formatting is recommended for version control
|
|
1361
|
+
*/
|
|
1362
|
+
declare function exportSchema(outputPath: string, options?: {
|
|
1363
|
+
pretty?: boolean;
|
|
1364
|
+
}): void;
|
|
1365
|
+
/**
|
|
1366
|
+
* Get the current schema as a dictionary (without exporting to file).
|
|
1367
|
+
*
|
|
1368
|
+
* @returns Schema object with "types", "queries", and "mutations"
|
|
1369
|
+
*
|
|
1370
|
+
* @example
|
|
1371
|
+
* ```ts
|
|
1372
|
+
* const schema = getSchemaDict();
|
|
1373
|
+
* console.log(schema.types);
|
|
1374
|
+
* // [{ name: "User", fields: [...] }, ...]
|
|
1375
|
+
* ```
|
|
1376
|
+
*/
|
|
1377
|
+
declare function getSchemaDict(): Schema;
|
|
1378
|
+
/**
|
|
1379
|
+
* Export schema to a JSON string instead of a file.
|
|
1380
|
+
*
|
|
1381
|
+
* @param options - Export options
|
|
1382
|
+
* @returns JSON string representation of the schema
|
|
1383
|
+
*
|
|
1384
|
+
* @example
|
|
1385
|
+
* ```ts
|
|
1386
|
+
* const jsonString = exportSchemaToString({ pretty: true });
|
|
1387
|
+
* console.log(jsonString);
|
|
1388
|
+
* ```
|
|
1389
|
+
*/
|
|
1390
|
+
declare function exportSchemaToString(options?: {
|
|
1391
|
+
pretty?: boolean;
|
|
1392
|
+
}): string;
|
|
1393
|
+
/**
|
|
1394
|
+
* Export ONLY types to a minimal types.json file (TOML-based workflow).
|
|
1395
|
+
*
|
|
1396
|
+
* This is the new minimal export function for the TOML-based configuration approach.
|
|
1397
|
+
* It exports only the type definitions (types, enums, input_types, interfaces) without
|
|
1398
|
+
* queries, mutations, federation, security, observers, or analytics metadata.
|
|
1399
|
+
*
|
|
1400
|
+
* All configuration moves to fraiseql.toml, which is merged with this types.json
|
|
1401
|
+
* by the fraiseql-cli compile command.
|
|
1402
|
+
*
|
|
1403
|
+
* @param outputPath - Path to output types.json file
|
|
1404
|
+
* @param options - Export options
|
|
1405
|
+
*
|
|
1406
|
+
* @example
|
|
1407
|
+
* ```ts
|
|
1408
|
+
* // At end of schema.ts
|
|
1409
|
+
* if (require.main === module) {
|
|
1410
|
+
* exportTypes("user_types.json");
|
|
1411
|
+
* }
|
|
1412
|
+
* ```
|
|
1413
|
+
*
|
|
1414
|
+
* Notes:
|
|
1415
|
+
* - Call this after all decorators have been applied
|
|
1416
|
+
* - The output types.json contains only type definitions
|
|
1417
|
+
* - Queries, mutations, and all configuration moves to fraiseql.toml
|
|
1418
|
+
* - Use with: fraiseql compile fraiseql.toml --types user_types.json
|
|
1419
|
+
*/
|
|
1420
|
+
declare function exportTypes(outputPath: string, options?: {
|
|
1421
|
+
pretty?: boolean;
|
|
1422
|
+
}): void;
|
|
1423
|
+
|
|
1424
|
+
/**
|
|
1425
|
+
* Validation engine for custom GraphQL scalars.
|
|
1426
|
+
*/
|
|
1427
|
+
|
|
1428
|
+
/**
|
|
1429
|
+
* Raised when custom scalar validation fails.
|
|
1430
|
+
*/
|
|
1431
|
+
declare class ScalarValidationError extends Error {
|
|
1432
|
+
scalarName: string;
|
|
1433
|
+
context: "serialize" | "parseValue" | "parseLiteral";
|
|
1434
|
+
/**
|
|
1435
|
+
* Creates a new ScalarValidationError.
|
|
1436
|
+
*
|
|
1437
|
+
* @param scalarName - Name of the scalar that failed validation
|
|
1438
|
+
* @param context - The validation context ("serialize", "parseValue", or "parseLiteral")
|
|
1439
|
+
* @param message - The underlying error message
|
|
1440
|
+
*/
|
|
1441
|
+
constructor(scalarName: string, context: "serialize" | "parseValue" | "parseLiteral", message: string);
|
|
1442
|
+
}
|
|
1443
|
+
/**
|
|
1444
|
+
* Execute validation for a custom scalar.
|
|
1445
|
+
*
|
|
1446
|
+
* @param scalarClass - The CustomScalar subclass to validate with
|
|
1447
|
+
* @param value - The value to validate
|
|
1448
|
+
* @param context - One of "serialize", "parseValue", or "parseLiteral"
|
|
1449
|
+
* @returns The validated/converted value
|
|
1450
|
+
* @throws ScalarValidationError if validation fails
|
|
1451
|
+
* @throws Error if context is unknown
|
|
1452
|
+
*
|
|
1453
|
+
* @example
|
|
1454
|
+
* ```typescript
|
|
1455
|
+
* import { validateCustomScalar } from "fraiseql/validators"
|
|
1456
|
+
* import { Email } from "./scalars"
|
|
1457
|
+
*
|
|
1458
|
+
* // Parse a variable value from GraphQL
|
|
1459
|
+
* const emailValue = validateCustomScalar(Email, "user@example.com", "parseValue")
|
|
1460
|
+
* // Returns "user@example.com"
|
|
1461
|
+
*
|
|
1462
|
+
* // Validation fails
|
|
1463
|
+
* try {
|
|
1464
|
+
* validateCustomScalar(Email, "invalid-email", "parseValue")
|
|
1465
|
+
* } catch (e) {
|
|
1466
|
+
* // ScalarValidationError: Scalar "Email" validation failed in parseValue: Invalid email
|
|
1467
|
+
* }
|
|
1468
|
+
* ```
|
|
1469
|
+
*/
|
|
1470
|
+
declare function validateCustomScalar(scalarClass: typeof CustomScalar, value: unknown, context?: "serialize" | "parseValue" | "parseLiteral"): unknown;
|
|
1471
|
+
/**
|
|
1472
|
+
* Get all registered custom scalars.
|
|
1473
|
+
*
|
|
1474
|
+
* @returns Map of scalar names to CustomScalar classes
|
|
1475
|
+
*
|
|
1476
|
+
* @example
|
|
1477
|
+
* ```typescript
|
|
1478
|
+
* import { getAllCustomScalars } from "fraiseql/validators"
|
|
1479
|
+
*
|
|
1480
|
+
* const scalars = getAllCustomScalars()
|
|
1481
|
+
* // Map { "Email" => class Email, "Phone" => class Phone, ... }
|
|
1482
|
+
* ```
|
|
1483
|
+
*/
|
|
1484
|
+
declare function getAllCustomScalars(): Map<string, typeof CustomScalar>;
|
|
1485
|
+
|
|
1486
|
+
/**
|
|
1487
|
+
* Observer authoring API for FraiseQL event-driven workflows.
|
|
1488
|
+
*
|
|
1489
|
+
* Observers watch for database changes and trigger actions (webhooks, Slack, email).
|
|
1490
|
+
* NO runtime behavior - only used for schema compilation.
|
|
1491
|
+
*
|
|
1492
|
+
* @example
|
|
1493
|
+
* ```typescript
|
|
1494
|
+
* import { Observer, webhook, slack } from "fraiseql";
|
|
1495
|
+
*
|
|
1496
|
+
* class Observers {
|
|
1497
|
+
* @Observer({ entity: "Order", event: "INSERT", actions: [webhook("https://...")] })
|
|
1498
|
+
* onOrderCreated() {}
|
|
1499
|
+
* }
|
|
1500
|
+
* ```
|
|
1501
|
+
*/
|
|
1502
|
+
|
|
1503
|
+
/**
|
|
1504
|
+
* Retry configuration for observer actions.
|
|
1505
|
+
*/
|
|
1506
|
+
type RetryConfig = ObserverRetryConfig;
|
|
1507
|
+
/**
|
|
1508
|
+
* Default retry configuration used when no retry is specified.
|
|
1509
|
+
*/
|
|
1510
|
+
declare const DEFAULT_RETRY_CONFIG: RetryConfig;
|
|
1511
|
+
/**
|
|
1512
|
+
* Configuration for the @Observer decorator.
|
|
1513
|
+
*/
|
|
1514
|
+
interface ObserverConfig {
|
|
1515
|
+
entity: string;
|
|
1516
|
+
event: string;
|
|
1517
|
+
actions: ObserverAction[];
|
|
1518
|
+
condition?: string;
|
|
1519
|
+
retry?: RetryConfig;
|
|
1520
|
+
}
|
|
1521
|
+
/**
|
|
1522
|
+
* Method decorator to register an observer with the schema registry.
|
|
1523
|
+
*
|
|
1524
|
+
* @param config - Observer configuration
|
|
1525
|
+
* @returns Method decorator
|
|
1526
|
+
*/
|
|
1527
|
+
declare function Observer(config: ObserverConfig): (_target: any, propertyKey: string, _descriptor: PropertyDescriptor) => void;
|
|
1528
|
+
/**
|
|
1529
|
+
* Options for the webhook action factory.
|
|
1530
|
+
*/
|
|
1531
|
+
interface WebhookOptions {
|
|
1532
|
+
url_env?: string;
|
|
1533
|
+
headers?: Record<string, string>;
|
|
1534
|
+
body_template?: string;
|
|
1535
|
+
}
|
|
1536
|
+
/**
|
|
1537
|
+
* Create a webhook action.
|
|
1538
|
+
*
|
|
1539
|
+
* @param url - Static URL (mutually exclusive with url_env)
|
|
1540
|
+
* @param options - Additional options including url_env, headers, body_template
|
|
1541
|
+
* @returns Webhook action definition
|
|
1542
|
+
* @throws If neither url nor url_env is provided
|
|
1543
|
+
*/
|
|
1544
|
+
declare function webhook(url?: string, options?: WebhookOptions): ObserverAction;
|
|
1545
|
+
/**
|
|
1546
|
+
* Options for the slack action factory.
|
|
1547
|
+
*/
|
|
1548
|
+
interface SlackOptions {
|
|
1549
|
+
webhook_url?: string;
|
|
1550
|
+
webhook_url_env?: string;
|
|
1551
|
+
}
|
|
1552
|
+
/**
|
|
1553
|
+
* Create a Slack notification action.
|
|
1554
|
+
*
|
|
1555
|
+
* @param channel - Slack channel (e.g. "#orders")
|
|
1556
|
+
* @param message - Message template with {field} placeholders
|
|
1557
|
+
* @param options - Optional webhook URL or environment variable override
|
|
1558
|
+
* @returns Slack action definition
|
|
1559
|
+
*/
|
|
1560
|
+
declare function slack(channel: string, message: string, options?: SlackOptions): ObserverAction;
|
|
1561
|
+
/**
|
|
1562
|
+
* Options for the email action factory.
|
|
1563
|
+
*/
|
|
1564
|
+
interface EmailOptions {
|
|
1565
|
+
from_email?: string;
|
|
1566
|
+
}
|
|
1567
|
+
/**
|
|
1568
|
+
* Create an email notification action.
|
|
1569
|
+
*
|
|
1570
|
+
* @param to - Recipient email address
|
|
1571
|
+
* @param subject - Email subject template with {field} placeholders
|
|
1572
|
+
* @param body - Email body template with {field} placeholders
|
|
1573
|
+
* @param options - Optional sender override
|
|
1574
|
+
* @returns Email action definition
|
|
1575
|
+
*/
|
|
1576
|
+
declare function email(to: string, subject: string, body: string, options?: EmailOptions): ObserverAction;
|
|
1577
|
+
|
|
1578
|
+
/**
|
|
1579
|
+
* Error hierarchy for FraiseQL HTTP client.
|
|
1580
|
+
*/
|
|
1581
|
+
declare class FraiseQLError extends Error {
|
|
1582
|
+
constructor(message: string, options?: ErrorOptions);
|
|
1583
|
+
}
|
|
1584
|
+
interface GraphQLErrorEntry {
|
|
1585
|
+
message: string;
|
|
1586
|
+
locations?: Array<{
|
|
1587
|
+
line: number;
|
|
1588
|
+
column: number;
|
|
1589
|
+
}>;
|
|
1590
|
+
path?: Array<string | number>;
|
|
1591
|
+
extensions?: Record<string, unknown>;
|
|
1592
|
+
}
|
|
1593
|
+
declare class GraphQLError extends FraiseQLError {
|
|
1594
|
+
readonly errors: GraphQLErrorEntry[];
|
|
1595
|
+
constructor(errors: GraphQLErrorEntry[]);
|
|
1596
|
+
}
|
|
1597
|
+
declare class NetworkError extends FraiseQLError {
|
|
1598
|
+
constructor(message: string, options?: ErrorOptions);
|
|
1599
|
+
}
|
|
1600
|
+
declare class TimeoutError extends NetworkError {
|
|
1601
|
+
constructor(message?: string);
|
|
1602
|
+
}
|
|
1603
|
+
declare class AuthenticationError extends FraiseQLError {
|
|
1604
|
+
readonly statusCode: 401 | 403;
|
|
1605
|
+
constructor(statusCode: 401 | 403);
|
|
1606
|
+
}
|
|
1607
|
+
declare class RateLimitError extends FraiseQLError {
|
|
1608
|
+
readonly retryAfterMs?: number;
|
|
1609
|
+
constructor(retryAfterMs?: number);
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
/**
|
|
1613
|
+
* Retry logic for FraiseQL HTTP client operations.
|
|
1614
|
+
*/
|
|
1615
|
+
|
|
1616
|
+
interface HttpRetryConfig {
|
|
1617
|
+
maxAttempts?: number;
|
|
1618
|
+
baseDelayMs?: number;
|
|
1619
|
+
maxDelayMs?: number;
|
|
1620
|
+
jitter?: boolean;
|
|
1621
|
+
retryOn?: Array<new (...args: never[]) => FraiseQLError>;
|
|
1622
|
+
onRetry?: (attempt: number, error: FraiseQLError) => void;
|
|
1623
|
+
}
|
|
1624
|
+
declare function executeWithRetry<T>(fn: () => Promise<T>, config?: HttpRetryConfig): Promise<T>;
|
|
1625
|
+
|
|
1626
|
+
/**
|
|
1627
|
+
* FraiseQL HTTP client for executing GraphQL queries and mutations.
|
|
1628
|
+
*/
|
|
1629
|
+
|
|
1630
|
+
interface FraiseQLClientConfig {
|
|
1631
|
+
url: string;
|
|
1632
|
+
authorization?: string | (() => string | Promise<string>);
|
|
1633
|
+
timeoutMs?: number;
|
|
1634
|
+
retry?: HttpRetryConfig;
|
|
1635
|
+
headers?: Record<string, string>;
|
|
1636
|
+
fetch?: typeof fetch;
|
|
1637
|
+
}
|
|
1638
|
+
declare class FraiseQLClient {
|
|
1639
|
+
private readonly url;
|
|
1640
|
+
private readonly authorization?;
|
|
1641
|
+
private readonly timeoutMs;
|
|
1642
|
+
private readonly retry;
|
|
1643
|
+
private readonly extraHeaders;
|
|
1644
|
+
private readonly fetchFn;
|
|
1645
|
+
constructor(urlOrConfig: string | FraiseQLClientConfig);
|
|
1646
|
+
private resolveAuth;
|
|
1647
|
+
private buildHeaders;
|
|
1648
|
+
private executeRequest;
|
|
1649
|
+
query<T = Record<string, unknown>>(query: string, variables?: Record<string, unknown>, operationName?: string): Promise<T>;
|
|
1650
|
+
mutate<T = Record<string, unknown>>(mutation: string, variables?: Record<string, unknown>, operationName?: string): Promise<T>;
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
/**
|
|
1654
|
+
* FraiseQL v2 - TypeScript Schema Authoring.
|
|
1655
|
+
*
|
|
1656
|
+
* This module provides decorators for defining GraphQL schemas that are compiled
|
|
1657
|
+
* by the FraiseQL Rust engine. NO runtime FFI - decorators output JSON only.
|
|
1658
|
+
*
|
|
1659
|
+
* Architecture:
|
|
1660
|
+
* TypeScript @decorators → schema.json → fraiseql-cli → schema.compiled.json → Rust runtime
|
|
1661
|
+
*
|
|
1662
|
+
* @example
|
|
1663
|
+
* ```typescript
|
|
1664
|
+
* import * as fraiseql from "fraiseql";
|
|
1665
|
+
*
|
|
1666
|
+
* @fraiseql.Type()
|
|
1667
|
+
* class User {
|
|
1668
|
+
* id: number;
|
|
1669
|
+
* name: string;
|
|
1670
|
+
* email: string;
|
|
1671
|
+
* }
|
|
1672
|
+
*
|
|
1673
|
+
* @fraiseql.Query({ sqlSource: "v_user" })
|
|
1674
|
+
* function users(limit: number = 10): User[] {
|
|
1675
|
+
* // Function body not executed - only for type/metadata
|
|
1676
|
+
* }
|
|
1677
|
+
*
|
|
1678
|
+
* // Export minimal types.json (use fraiseql.toml for queries, security, etc.)
|
|
1679
|
+
* if (require.main === module) {
|
|
1680
|
+
* fraiseql.exportTypes("types.json");
|
|
1681
|
+
* }
|
|
1682
|
+
* ```
|
|
1683
|
+
*
|
|
1684
|
+
* @packageDocumentation
|
|
1685
|
+
*/
|
|
1686
|
+
declare const version = "2.0.0-alpha.1";
|
|
1687
|
+
|
|
1688
|
+
export { type APIKey, type AirportCode, type ArgumentDefinition, type ArgumentInfo, AuthenticationError, type CIDR, type CUSIP, type Color, type ContainerNumber, type Coordinates, type CountryCode, type CurrencyCode, CustomScalar, DEFAULT_RETRY_CONFIG, type Date, type DateRange, type DateTime, type Decimal, type DomainName, type Duration, type Email, type EnumConfig, type EnumDefinition, type EnumValue, type ExchangeCode, type ExchangeRate, type Field, type FieldInfo, type FieldMetadata, type File, type FlightNumber, FraiseQLClient, type FraiseQLClientConfig, FraiseQLError, type FunctionSignature, GraphQLError, type GraphQLErrorEntry, type HTML, type HashSHA256, type Hostname, type HttpRetryConfig, type IBAN, type ID, type IPAddress, type IPv4, type IPv6, type ISIN, type Image, type InputConfig, type InputTypeDefinition, type InterfaceConfig, type InterfaceDefinition, type Json, type LEI, type LTree, type LanguageCode, type Latitude, type LicensePlate, type LocaleCode, type Longitude, type MACAddress, type MIC, type Markdown, type MimeType, type Money, Mutation, type MutationConfig, type MutationDefinition, NetworkError, Observer, type OperationConfig, type Percentage, type PhoneNumber, type Port, type PortCode, type PostalCode, Query, type QueryDefinition, RateLimitError, type RetryConfig, type ReturnTypeInfo, SCALAR_NAMES, type SEDOL, Scalar, ScalarValidationError, type Schema, SchemaRegistry, type SemanticVersion, type Slug, type StockSymbol, Subscription, type SubscriptionConfig, type SubscriptionDefinition, type Time, TimeoutError, type Timezone, type TrackingNumber, Type, type TypeConfig, type TypeDefinition, type URL, type UUID, type UnionConfig, type UnionDefinition, type VIN, type Vector, config, email, enum_, executeWithRetry, exportSchema, exportSchemaToString, exportTypes, extractFieldInfo, extractFunctionSignature, field, generateCrudOperations, getAllCustomScalars, getSchemaDict, input, interface_, isScalarType, registerMutation, registerQuery, registerSubscription, registerTypeFields, slack, typeToGraphQL, union, validateCustomScalar, version, webhook };
|