mulink 1.0.4 → 1.0.5
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/dist/.tsbuildinfo +1 -1
- package/dist/lib/{chunk-KCNMWAI2.js → chunk-7Y66DW7M.js} +279 -250
- package/dist/lib/chunk-7Y66DW7M.js.map +1 -0
- package/dist/lib/{chunk-GKRRC2YD.cjs → chunk-OOY4PCDK.cjs} +279 -250
- package/dist/lib/chunk-OOY4PCDK.cjs.map +1 -0
- package/dist/lib/cli.cjs +16 -16
- package/dist/lib/cli.js +1 -1
- package/dist/lib/client.cjs +18 -18
- package/dist/lib/client.d.cts +2 -2
- package/dist/lib/client.d.ts +2 -2
- package/dist/lib/client.js +2 -2
- package/dist/lib/index.cjs +15 -15
- package/dist/lib/index.d.cts +2 -2
- package/dist/lib/index.d.ts +2 -2
- package/dist/lib/index.js +1 -1
- package/dist/lib/{version-checker-BWdifiXN.d.cts → version-checker-uF6o5ziX.d.cts} +2 -0
- package/dist/lib/{version-checker-BWdifiXN.d.ts → version-checker-uF6o5ziX.d.ts} +2 -0
- package/package.json +1 -1
- package/dist/lib/chunk-GKRRC2YD.cjs.map +0 -1
- package/dist/lib/chunk-KCNMWAI2.js.map +0 -1
|
@@ -1544,7 +1544,6 @@ export class BaseApiClient {
|
|
|
1544
1544
|
retryDelay, retryCondition, validateResponse, skipAuth,
|
|
1545
1545
|
responseSchema, requestId, [...this.middleware, ...middleware],
|
|
1546
1546
|
cacheTags, revalidate, connection, updateTag
|
|
1547
|
-
cacheTags, revalidate, connection, updateTag
|
|
1548
1547
|
)
|
|
1549
1548
|
|
|
1550
1549
|
requestCache.set(dedupeKey, requestPromise)
|
|
@@ -1562,7 +1561,6 @@ export class BaseApiClient {
|
|
|
1562
1561
|
retryDelay, retryCondition, validateResponse, skipAuth,
|
|
1563
1562
|
responseSchema, requestId, [...this.middleware, ...middleware],
|
|
1564
1563
|
cacheTags, revalidate, connection, updateTag
|
|
1565
|
-
cacheTags, revalidate, connection, updateTag
|
|
1566
1564
|
)
|
|
1567
1565
|
}
|
|
1568
1566
|
|
|
@@ -2718,7 +2716,9 @@ var SchemaGenerator = class {
|
|
|
2718
2716
|
].join("\n");
|
|
2719
2717
|
let content = this.removeUnusedCode(contentWithImports);
|
|
2720
2718
|
if (!content.includes('import { z } from "zod"') && !content.includes("import { z } from 'zod'")) {
|
|
2721
|
-
content =
|
|
2719
|
+
content = `import { z } from "zod"
|
|
2720
|
+
|
|
2721
|
+
${content}`;
|
|
2722
2722
|
}
|
|
2723
2723
|
return {
|
|
2724
2724
|
path: "schemas/index.ts",
|
|
@@ -3129,6 +3129,166 @@ var ActionGenerator = class {
|
|
|
3129
3129
|
static {
|
|
3130
3130
|
__name(this, "ActionGenerator");
|
|
3131
3131
|
}
|
|
3132
|
+
get loggingEnabled() {
|
|
3133
|
+
return this.configuration.dev?.logging !== false;
|
|
3134
|
+
}
|
|
3135
|
+
get validationEnabled() {
|
|
3136
|
+
return this.configuration.dev?.validation !== false;
|
|
3137
|
+
}
|
|
3138
|
+
get commentsEnabled() {
|
|
3139
|
+
return this.configuration.generation?.comments !== false;
|
|
3140
|
+
}
|
|
3141
|
+
get documentationEnabled() {
|
|
3142
|
+
return this.configuration.generation?.documentation !== false;
|
|
3143
|
+
}
|
|
3144
|
+
commentLine(text, indent = 2) {
|
|
3145
|
+
if (!this.commentsEnabled) {
|
|
3146
|
+
return "";
|
|
3147
|
+
}
|
|
3148
|
+
return `${" ".repeat(indent)}// ${text}
|
|
3149
|
+
`;
|
|
3150
|
+
}
|
|
3151
|
+
buildDocBlock(endpoint, featuresDescription) {
|
|
3152
|
+
if (!this.documentationEnabled) {
|
|
3153
|
+
return "";
|
|
3154
|
+
}
|
|
3155
|
+
const summary = endpoint.summary || endpoint.description || `${endpoint.method} ${endpoint.path}`;
|
|
3156
|
+
return `/**
|
|
3157
|
+
* ${summary}
|
|
3158
|
+
* @generated from ${endpoint.method} ${endpoint.path}
|
|
3159
|
+
* Features: ${featuresDescription}
|
|
3160
|
+
*/
|
|
3161
|
+
`;
|
|
3162
|
+
}
|
|
3163
|
+
buildUtilityFunctions() {
|
|
3164
|
+
const parts = [];
|
|
3165
|
+
if (this.commentsEnabled) {
|
|
3166
|
+
parts.push("// Utility functions for enhanced server actions");
|
|
3167
|
+
}
|
|
3168
|
+
parts.push(`async function getClientInfo() {
|
|
3169
|
+
const headersList = await headers()
|
|
3170
|
+
const userAgent = headersList.get('user-agent') || 'unknown'
|
|
3171
|
+
const ip = headersList.get('x-forwarded-for') || headersList.get('x-real-ip') || 'unknown'
|
|
3172
|
+
|
|
3173
|
+
return { userAgent, ip }
|
|
3174
|
+
}`);
|
|
3175
|
+
if (this.validationEnabled) {
|
|
3176
|
+
parts.push(`async function validateAndSanitizeInput<T>(schema: z.ZodSchema<T>, input: unknown): Promise<T> {
|
|
3177
|
+
try {
|
|
3178
|
+
return await schema.parseAsync(input)
|
|
3179
|
+
} catch (error) {
|
|
3180
|
+
if (error instanceof z.ZodError) {
|
|
3181
|
+
const errorMessages = error.issues.map(issue => {
|
|
3182
|
+
const path = issue.path.length > 0 ? \`\${issue.path.join('.')}: \` : ''
|
|
3183
|
+
return \`\${path}\${issue.message}\`
|
|
3184
|
+
}).join(', ')
|
|
3185
|
+
throw new ActionError(\`Input validation failed: \${errorMessages}\`, 'VALIDATION_ERROR')
|
|
3186
|
+
}
|
|
3187
|
+
throw new ActionError('Invalid input format', 'VALIDATION_ERROR')
|
|
3188
|
+
}
|
|
3189
|
+
}`);
|
|
3190
|
+
}
|
|
3191
|
+
const actionErrorBlock = `${this.commentsEnabled ? "// Enhanced error handling with context\n" : ""}class ActionExecutionError extends ActionError {
|
|
3192
|
+
constructor(
|
|
3193
|
+
message: string,
|
|
3194
|
+
public readonly context: {
|
|
3195
|
+
endpoint: string
|
|
3196
|
+
method: string
|
|
3197
|
+
timestamp: number
|
|
3198
|
+
},
|
|
3199
|
+
public readonly originalError?: unknown
|
|
3200
|
+
) {
|
|
3201
|
+
super(message, 'EXECUTION_ERROR')
|
|
3202
|
+
}
|
|
3203
|
+
}`;
|
|
3204
|
+
parts.push(actionErrorBlock);
|
|
3205
|
+
if (this.loggingEnabled) {
|
|
3206
|
+
const loggingHeader = this.commentsEnabled ? "// Logging utility for server actions\n" : "";
|
|
3207
|
+
parts.push(`${loggingHeader}async function logActionExecution(
|
|
3208
|
+
action: string,
|
|
3209
|
+
success: boolean,
|
|
3210
|
+
duration: number,
|
|
3211
|
+
context?: Record<string, any>
|
|
3212
|
+
) {
|
|
3213
|
+
if (process.env.NODE_ENV === 'development') {
|
|
3214
|
+
console.log(\`[ACTION] \${action} - \${success ? 'SUCCESS' : 'FAILED'} (\${duration}ms)\`, context)
|
|
3215
|
+
}
|
|
3216
|
+
|
|
3217
|
+
${this.commentsEnabled ? " // In production, send to your logging service\n // await analytics.track('server_action_executed', { action, success, duration, ...context })" : ""}
|
|
3218
|
+
}`);
|
|
3219
|
+
}
|
|
3220
|
+
return parts.join("\n\n");
|
|
3221
|
+
}
|
|
3222
|
+
buildCombinedValidationSnippet(operationName, schemaName) {
|
|
3223
|
+
if (this.validationEnabled) {
|
|
3224
|
+
return `
|
|
3225
|
+
${this.commentLine("Validate and sanitize input payload", 6)} const { body, params } = await validateAndSanitizeInput(${schemaName}, parsedInput)
|
|
3226
|
+
const validatedBody = body
|
|
3227
|
+
const validatedParams = params as z.infer<typeof ${operationName}ParamsSchema>`;
|
|
3228
|
+
}
|
|
3229
|
+
return `
|
|
3230
|
+
${this.commentLine("Runtime validation disabled - trusting provided payload", 6)} const { body, params } = parsedInput as {
|
|
3231
|
+
body: z.infer<typeof ${operationName}RequestSchema>
|
|
3232
|
+
params: z.infer<typeof ${operationName}ParamsSchema>
|
|
3233
|
+
}
|
|
3234
|
+
const validatedBody = body
|
|
3235
|
+
const validatedParams = params`;
|
|
3236
|
+
}
|
|
3237
|
+
buildBodyValidationSnippet(schemaName) {
|
|
3238
|
+
if (schemaName === "z.void()") {
|
|
3239
|
+
return "";
|
|
3240
|
+
}
|
|
3241
|
+
if (this.validationEnabled) {
|
|
3242
|
+
return `
|
|
3243
|
+
${this.commentLine("Validate and sanitize request body", 6)} const validatedBody = await validateAndSanitizeInput(${schemaName}, parsedInput)`;
|
|
3244
|
+
}
|
|
3245
|
+
return `
|
|
3246
|
+
${this.commentLine("Runtime validation disabled - trusting request body", 6)} const validatedBody = parsedInput as z.infer<typeof ${schemaName}>`;
|
|
3247
|
+
}
|
|
3248
|
+
buildParamsValidationSnippet(operationName, schemaName) {
|
|
3249
|
+
if (schemaName === "z.void()") {
|
|
3250
|
+
return "";
|
|
3251
|
+
}
|
|
3252
|
+
if (this.validationEnabled) {
|
|
3253
|
+
return `
|
|
3254
|
+
${this.commentLine("Validate and sanitize parameters", 6)} const validatedParams = await validateAndSanitizeInput(${schemaName}, parsedInput) as z.infer<typeof ${operationName}ParamsSchema>`;
|
|
3255
|
+
}
|
|
3256
|
+
return `
|
|
3257
|
+
${this.commentLine("Runtime validation disabled - trusting parameters", 6)} const validatedParams = parsedInput as z.infer<typeof ${operationName}ParamsSchema>`;
|
|
3258
|
+
}
|
|
3259
|
+
buildSuccessLoggingBlock(actionName, endpoint, indent, isStreaming = false) {
|
|
3260
|
+
if (!this.loggingEnabled) {
|
|
3261
|
+
return "";
|
|
3262
|
+
}
|
|
3263
|
+
if (isStreaming) {
|
|
3264
|
+
return `
|
|
3265
|
+
${this.commentLine("Background tasks (Next.js 15 feature)", indent)}${" ".repeat(indent)}after(async () => {
|
|
3266
|
+
${this.commentLine("Perform background tasks after response is sent", indent + 2)}${" ".repeat(indent + 2)}await logActionExecution('${actionName}', true, Date.now() - startTime, {
|
|
3267
|
+
${" ".repeat(indent + 4)}method: '${endpoint.method}',
|
|
3268
|
+
${" ".repeat(indent + 4)}path: '${endpoint.path}'
|
|
3269
|
+
${" ".repeat(indent + 2)}})
|
|
3270
|
+
${" ".repeat(indent)}})`;
|
|
3271
|
+
}
|
|
3272
|
+
return `
|
|
3273
|
+
${this.commentLine("Log successful execution", indent)}${" ".repeat(indent)}const duration = Date.now() - startTime
|
|
3274
|
+
${" ".repeat(indent)}await logActionExecution('${actionName}', true, duration, {
|
|
3275
|
+
${" ".repeat(indent + 2)}method: '${endpoint.method}',
|
|
3276
|
+
${" ".repeat(indent + 2)}path: '${endpoint.path}'
|
|
3277
|
+
${" ".repeat(indent)}})`;
|
|
3278
|
+
}
|
|
3279
|
+
buildErrorLoggingBlock(actionName, endpoint, indent) {
|
|
3280
|
+
if (!this.loggingEnabled) {
|
|
3281
|
+
return "";
|
|
3282
|
+
}
|
|
3283
|
+
return `
|
|
3284
|
+
${" ".repeat(indent)}const duration = Date.now() - startTime
|
|
3285
|
+
|
|
3286
|
+
${this.commentLine("Enhanced error logging", indent)}${" ".repeat(indent)}await logActionExecution('${actionName}', false, duration, {
|
|
3287
|
+
${" ".repeat(indent + 2)}method: '${endpoint.method}',
|
|
3288
|
+
${" ".repeat(indent + 2)}path: '${endpoint.path}',
|
|
3289
|
+
${" ".repeat(indent + 2)}error: error instanceof Error ? error.message : 'Unknown error'
|
|
3290
|
+
${" ".repeat(indent)}})`;
|
|
3291
|
+
}
|
|
3132
3292
|
buildImportPath(relativePath) {
|
|
3133
3293
|
const outputDirectory = this.configuration.outputDir || "generated";
|
|
3134
3294
|
const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
|
|
@@ -3193,8 +3353,7 @@ var ActionGenerator = class {
|
|
|
3193
3353
|
] : []
|
|
3194
3354
|
].filter(Boolean).join("\n");
|
|
3195
3355
|
const rateLimitSetup = hasRateLimit ? `
|
|
3196
|
-
// Rate limiting setup
|
|
3197
|
-
const redis = new Redis({
|
|
3356
|
+
${this.commentsEnabled ? "// Rate limiting setup\n" : ""}const redis = new Redis({
|
|
3198
3357
|
url: process.env.UPSTASH_REDIS_REST_URL!,
|
|
3199
3358
|
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
|
|
3200
3359
|
})
|
|
@@ -3204,60 +3363,7 @@ const ratelimit = new Ratelimit({
|
|
|
3204
3363
|
limiter: Ratelimit.slidingWindow(10, '1 m'),
|
|
3205
3364
|
analytics: true,
|
|
3206
3365
|
})` : "";
|
|
3207
|
-
const utilityFunctions =
|
|
3208
|
-
// Utility functions for enhanced server actions
|
|
3209
|
-
async function getClientInfo() {
|
|
3210
|
-
const headersList = await headers()
|
|
3211
|
-
const userAgent = headersList.get('user-agent') || 'unknown'
|
|
3212
|
-
const ip = headersList.get('x-forwarded-for') || headersList.get('x-real-ip') || 'unknown'
|
|
3213
|
-
|
|
3214
|
-
return { userAgent, ip }
|
|
3215
|
-
}
|
|
3216
|
-
|
|
3217
|
-
async function validateAndSanitizeInput<T>(schema: z.ZodSchema<T>, input: unknown): Promise<T> {
|
|
3218
|
-
try {
|
|
3219
|
-
return await schema.parseAsync(input)
|
|
3220
|
-
} catch (error) {
|
|
3221
|
-
if (error instanceof z.ZodError) {
|
|
3222
|
-
const errorMessages = error.issues.map(issue => {
|
|
3223
|
-
const path = issue.path.length > 0 ? \`\${issue.path.join('.')}: \` : ''
|
|
3224
|
-
return \`\${path}\${issue.message}\`
|
|
3225
|
-
}).join(', ')
|
|
3226
|
-
throw new ActionError(\`Input validation failed: \${errorMessages}\`, 'VALIDATION_ERROR')
|
|
3227
|
-
}
|
|
3228
|
-
throw new ActionError('Invalid input format', 'VALIDATION_ERROR')
|
|
3229
|
-
}
|
|
3230
|
-
}
|
|
3231
|
-
|
|
3232
|
-
// Enhanced error handling with context
|
|
3233
|
-
class ActionExecutionError extends ActionError {
|
|
3234
|
-
constructor(
|
|
3235
|
-
message: string,
|
|
3236
|
-
public readonly context: {
|
|
3237
|
-
endpoint: string
|
|
3238
|
-
method: string
|
|
3239
|
-
timestamp: number
|
|
3240
|
-
},
|
|
3241
|
-
public readonly originalError?: unknown
|
|
3242
|
-
) {
|
|
3243
|
-
super(message, 'EXECUTION_ERROR')
|
|
3244
|
-
}
|
|
3245
|
-
}
|
|
3246
|
-
|
|
3247
|
-
// Logging utility for server actions
|
|
3248
|
-
async function logActionExecution(
|
|
3249
|
-
action: string,
|
|
3250
|
-
success: boolean,
|
|
3251
|
-
duration: number,
|
|
3252
|
-
context?: Record<string, any>
|
|
3253
|
-
) {
|
|
3254
|
-
if (process.env.NODE_ENV === 'development') {
|
|
3255
|
-
console.log(\`[ACTION] \${action} - \${success ? 'SUCCESS' : 'FAILED'} (\${duration}ms)\`, context)
|
|
3256
|
-
}
|
|
3257
|
-
|
|
3258
|
-
// In production, send to your logging service
|
|
3259
|
-
// await analytics.track('server_action_executed', { action, success, duration, ...context })
|
|
3260
|
-
}`;
|
|
3366
|
+
const utilityFunctions = this.buildUtilityFunctions();
|
|
3261
3367
|
const content = `${imports}
|
|
3262
3368
|
${rateLimitSetup}
|
|
3263
3369
|
${utilityFunctions}
|
|
@@ -3274,8 +3380,8 @@ ${actions}`;
|
|
|
3274
3380
|
}
|
|
3275
3381
|
});
|
|
3276
3382
|
}
|
|
3277
|
-
const
|
|
3278
|
-
${Object.keys(endpointsByTag).map((tag) => `export * from './${toValidIdentifier(tag)}'`).join("\n")}`;
|
|
3383
|
+
const indexHeader = this.commentsEnabled ? "// Auto-generated actions index\n" : "";
|
|
3384
|
+
const indexContent = `${indexHeader}${Object.keys(endpointsByTag).map((tag) => `export * from './${toValidIdentifier(tag)}'`).join("\n")}`;
|
|
3279
3385
|
generatedFiles.push({
|
|
3280
3386
|
path: "actions/index.ts",
|
|
3281
3387
|
content: indexContent,
|
|
@@ -3324,54 +3430,48 @@ ${Object.keys(endpointsByTag).map((tag) => `export * from './${toValidIdentifier
|
|
|
3324
3430
|
body: ${operationName}RequestSchema,
|
|
3325
3431
|
params: ${operationName}ParamsSchema
|
|
3326
3432
|
})`;
|
|
3327
|
-
parameterProcessing =
|
|
3328
|
-
// Validate and sanitize input
|
|
3329
|
-
const { body, params } = await validateAndSanitizeInput(${schemaName}, parsedInput)
|
|
3330
|
-
const validatedBody = body
|
|
3331
|
-
const validatedParams = params as z.infer<typeof ${operationName}ParamsSchema>`;
|
|
3433
|
+
parameterProcessing = this.buildCombinedValidationSnippet(operationName, schemaName);
|
|
3332
3434
|
requestOptionsParams = this.buildRequestOptions(pathParameters, queryParameters, true, true);
|
|
3333
3435
|
} else if (hasRequestBody) {
|
|
3334
3436
|
schemaName = `${operationName}RequestSchema`;
|
|
3335
|
-
parameterProcessing =
|
|
3336
|
-
// Validate and sanitize request body
|
|
3337
|
-
const validatedBody = await validateAndSanitizeInput(${schemaName}, parsedInput)`;
|
|
3437
|
+
parameterProcessing = this.buildBodyValidationSnippet(schemaName);
|
|
3338
3438
|
requestOptionsParams = `body: validatedBody`;
|
|
3339
3439
|
} else if (hasAnyParams) {
|
|
3340
3440
|
schemaName = `${operationName}ParamsSchema`;
|
|
3341
|
-
parameterProcessing =
|
|
3342
|
-
// Validate and sanitize parameters
|
|
3343
|
-
const validatedParams = await validateAndSanitizeInput(${schemaName}, parsedInput) as z.infer<typeof ${operationName}ParamsSchema>`;
|
|
3441
|
+
parameterProcessing = this.buildParamsValidationSnippet(operationName, schemaName);
|
|
3344
3442
|
requestOptionsParams = this.buildRequestOptions(pathParameters, queryParameters, false, true);
|
|
3345
3443
|
} else {
|
|
3346
3444
|
schemaName = "z.void()";
|
|
3347
3445
|
parameterProcessing = "";
|
|
3348
3446
|
requestOptionsParams = "";
|
|
3349
3447
|
}
|
|
3448
|
+
const parsedInputType = hasRequestBody || hasAnyParams ? `z.infer<typeof ${schemaName}>` : "void";
|
|
3449
|
+
const ctxType = requiresAuth || hasRateLimit ? "{ user?: any; ratelimit?: { remaining: number } }" : "any";
|
|
3450
|
+
const ctxDeclaration = requiresAuth || hasRateLimit ? `ctx: ${ctxType}` : "ctx?: any";
|
|
3451
|
+
const actionArgsType = `{ parsedInput: ${parsedInputType}; ${ctxDeclaration} }`;
|
|
3350
3452
|
const clientName = requiresAuth || hasRateLimit ? "authActionClient" : "actionClientWithMeta";
|
|
3351
3453
|
const rateLimitCode = hasRateLimit ? `
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
}` : "";
|
|
3454
|
+
${this.commentLine("Rate limiting", 6)} const { userAgent, ip } = await getClientInfo()
|
|
3455
|
+
const identifier = \`\${ip}-\${userAgent}\`
|
|
3456
|
+
const { success, limit, reset, remaining } = await ratelimit.limit(identifier)
|
|
3457
|
+
|
|
3458
|
+
if (!success) {
|
|
3459
|
+
throw new ActionError(
|
|
3460
|
+
\`Rate limit exceeded. Try again in \${Math.round((reset - Date.now()) / 1000)} seconds.\`,
|
|
3461
|
+
'RATE_LIMIT_EXCEEDED'
|
|
3462
|
+
)
|
|
3463
|
+
}` : "";
|
|
3363
3464
|
const revalidationCode = revalidationTags.length > 0 ? revalidationTags.map(
|
|
3364
|
-
(tag) => ` updateTag('${tag}')
|
|
3365
|
-
console.log('Updated tag: ${tag}')`
|
|
3465
|
+
(tag) => ` updateTag('${tag}')${this.loggingEnabled ? `
|
|
3466
|
+
console.log('Updated tag: ${tag}')` : ""}`
|
|
3366
3467
|
).join("\n") : "";
|
|
3367
3468
|
const kebabActionName = actionName.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
|
|
3368
3469
|
if (isQuery) {
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
export const ${actionName} = cache(
|
|
3470
|
+
const docBlock = this.buildDocBlock(
|
|
3471
|
+
endpoint,
|
|
3472
|
+
"React cache, input validation, error handling"
|
|
3473
|
+
);
|
|
3474
|
+
return `${docBlock}export const ${actionName} = cache(
|
|
3375
3475
|
${clientName}
|
|
3376
3476
|
.metadata({
|
|
3377
3477
|
name: "${kebabActionName}",
|
|
@@ -3379,7 +3479,7 @@ export const ${actionName} = cache(
|
|
|
3379
3479
|
rateLimit: { requests: ${endpoint.metadata.rateLimit?.requests || 10}, window: "${endpoint.metadata.rateLimit?.window || "1m"}" }` : ""}
|
|
3380
3480
|
})
|
|
3381
3481
|
.schema(${schemaName})
|
|
3382
|
-
.action(async ({ parsedInput, ctx }:
|
|
3482
|
+
.action(async ({ parsedInput, ctx }: ${actionArgsType}) => {
|
|
3383
3483
|
const startTime = Date.now()
|
|
3384
3484
|
|
|
3385
3485
|
try {${rateLimitCode}${parameterProcessing}
|
|
@@ -3394,23 +3494,11 @@ export const ${actionName} = cache(
|
|
|
3394
3494
|
}
|
|
3395
3495
|
})
|
|
3396
3496
|
|
|
3397
|
-
|
|
3398
|
-
const duration = Date.now() - startTime
|
|
3399
|
-
await logActionExecution('${actionName}', true, duration, {
|
|
3400
|
-
method: '${endpoint.method}',
|
|
3401
|
-
path: '${endpoint.path}'
|
|
3402
|
-
})
|
|
3497
|
+
${this.buildSuccessLoggingBlock(actionName, endpoint, 8)}
|
|
3403
3498
|
|
|
3404
3499
|
return response.data
|
|
3405
3500
|
} catch (error) {
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
// Enhanced error logging
|
|
3409
|
-
await logActionExecution('${actionName}', false, duration, {
|
|
3410
|
-
method: '${endpoint.method}',
|
|
3411
|
-
path: '${endpoint.path}',
|
|
3412
|
-
error: error instanceof Error ? error.message : 'Unknown error'
|
|
3413
|
-
})
|
|
3501
|
+
${this.buildErrorLoggingBlock(actionName, endpoint, 8)}
|
|
3414
3502
|
|
|
3415
3503
|
// Throw enhanced error with context
|
|
3416
3504
|
throw new ActionExecutionError(
|
|
@@ -3427,50 +3515,37 @@ export const ${actionName} = cache(
|
|
|
3427
3515
|
)`;
|
|
3428
3516
|
}
|
|
3429
3517
|
const redirectCode = `
|
|
3430
|
-
|
|
3431
|
-
if (response.status === 201 && response.headers.get('location')) {
|
|
3518
|
+
${this.commentLine("Handle potential redirects based on response", 8)} if (response.status === 201 && response.headers.get('location')) {
|
|
3432
3519
|
const location = response.headers.get('location')!
|
|
3433
3520
|
redirect(location)
|
|
3434
3521
|
}`;
|
|
3435
3522
|
const streamingCode = `
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
// Process streaming response
|
|
3439
|
-
return response.data
|
|
3523
|
+
${this.commentLine("Handle streaming responses", 8)} if (response.headers.get('content-type')?.includes('text/stream')) {
|
|
3524
|
+
${this.commentLine("Process streaming response", 10)} return response.data
|
|
3440
3525
|
}`;
|
|
3441
3526
|
const fileUploadCode = hasFileUpload ? uploadStrategy === "external" && uploadProvider === "vercel-blob" ? `
|
|
3442
|
-
|
|
3443
|
-
if (validatedBody && typeof validatedBody === 'object' && 'file' in validatedBody) {
|
|
3527
|
+
${this.commentLine("Handle file uploads with Vercel Blob", 8)} if (validatedBody && typeof validatedBody === 'object' && 'file' in validatedBody) {
|
|
3444
3528
|
const file = (validatedBody as any).file as File
|
|
3445
3529
|
const blob = await put(file.name, file, { access: 'public' })
|
|
3446
3530
|
Object.assign(validatedBody, { fileUrl: blob.url })
|
|
3447
3531
|
}` : uploadStrategy === "external" && uploadProvider === "uploadthing" ? `
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
const file = (validatedBody as any).file as File
|
|
3459
|
-
// Process file with compression and validation if enabled
|
|
3460
|
-
}` : "";
|
|
3461
|
-
return `/**
|
|
3462
|
-
* ${endpoint.summary || endpoint.description || `${endpoint.method} ${endpoint.path}`}
|
|
3463
|
-
* @generated from ${endpoint.method} ${endpoint.path}
|
|
3464
|
-
* Features: Input validation, revalidation, error handling
|
|
3465
|
-
*/
|
|
3466
|
-
export const ${actionName} = ${clientName}
|
|
3532
|
+
${this.commentLine("Handle file uploads with UploadThing", 8)}${this.commentLine("UploadThing requires a separate route handler setup", 8)}${this.commentLine("See: https://docs.uploadthing.com/getting-started/appdir", 8)} if (validatedBody && typeof validatedBody === 'object' && 'file' in validatedBody) {
|
|
3533
|
+
${this.commentLine("UploadThing file handling should be done via their route handler", 10)}${this.commentLine("This is a placeholder - implement according to UploadThing docs", 10)} }` : `
|
|
3534
|
+
${this.commentLine("Handle file uploads with standard FormData", 8)} if (validatedBody && typeof validatedBody === 'object' && 'file' in validatedBody) {
|
|
3535
|
+
${this.commentLine("Standard file upload handling", 10)} const file = (validatedBody as any).file as File
|
|
3536
|
+
${this.commentLine("Process file with compression and validation if enabled", 10)} }` : "";
|
|
3537
|
+
const mutationDocBlock = this.buildDocBlock(
|
|
3538
|
+
endpoint,
|
|
3539
|
+
"Input validation, revalidation, error handling"
|
|
3540
|
+
);
|
|
3541
|
+
return `${mutationDocBlock}export const ${actionName} = ${clientName}
|
|
3467
3542
|
.metadata({
|
|
3468
3543
|
name: "${kebabActionName}",
|
|
3469
3544
|
requiresAuth: ${requiresAuth}${hasRateLimit ? `,
|
|
3470
3545
|
rateLimit: { requests: ${endpoint.metadata.rateLimit?.requests || 10}, window: "${endpoint.metadata.rateLimit?.window || "1m"}" }` : ""}
|
|
3471
3546
|
})
|
|
3472
3547
|
.schema(${schemaName})
|
|
3473
|
-
.action(async ({ parsedInput, ctx }:
|
|
3548
|
+
.action(async ({ parsedInput, ctx }: ${actionArgsType}) => {
|
|
3474
3549
|
const startTime = Date.now()
|
|
3475
3550
|
|
|
3476
3551
|
try {${rateLimitCode}${parameterProcessing}${fileUploadCode}
|
|
@@ -3485,33 +3560,13 @@ export const ${actionName} = ${clientName}
|
|
|
3485
3560
|
}
|
|
3486
3561
|
})${streamingCode}${redirectCode}
|
|
3487
3562
|
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
// Background tasks (Next.js 15 feature)
|
|
3492
|
-
${isStreaming ? `after(async () => {
|
|
3493
|
-
// Perform background tasks after response is sent
|
|
3494
|
-
await logActionExecution('${actionName}', true, Date.now() - startTime, {
|
|
3495
|
-
method: '${endpoint.method}',
|
|
3496
|
-
path: '${endpoint.path}'
|
|
3497
|
-
})
|
|
3498
|
-
})` : `// Log successful execution
|
|
3499
|
-
const duration = Date.now() - startTime
|
|
3500
|
-
await logActionExecution('${actionName}', true, duration, {
|
|
3501
|
-
method: '${endpoint.method}',
|
|
3502
|
-
path: '${endpoint.path}'
|
|
3503
|
-
})`}
|
|
3563
|
+
${revalidationCode ? `${this.commentLine("Revalidate cache after successful mutation", 6)}${revalidationCode}
|
|
3564
|
+
` : ""}
|
|
3565
|
+
${this.buildSuccessLoggingBlock(actionName, endpoint, 6, isStreaming)}
|
|
3504
3566
|
|
|
3505
3567
|
return response.data
|
|
3506
3568
|
} catch (error) {
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
// Enhanced error logging
|
|
3510
|
-
await logActionExecution('${actionName}', false, duration, {
|
|
3511
|
-
method: '${endpoint.method}',
|
|
3512
|
-
path: '${endpoint.path}',
|
|
3513
|
-
error: error instanceof Error ? error.message : 'Unknown error'
|
|
3514
|
-
})
|
|
3569
|
+
${this.buildErrorLoggingBlock(actionName, endpoint, 6)}
|
|
3515
3570
|
|
|
3516
3571
|
// Throw enhanced error with context
|
|
3517
3572
|
throw new ActionExecutionError(
|
|
@@ -3670,7 +3725,6 @@ var HookGenerator = class {
|
|
|
3670
3725
|
if (hasInfiniteQueries) reactQueryImports.push("useInfiniteQuery");
|
|
3671
3726
|
const reactImports = [];
|
|
3672
3727
|
if (hasMutations) reactImports.push("useOptimistic", "useTransition");
|
|
3673
|
-
if (hasQueries) reactImports.push("useCallback");
|
|
3674
3728
|
const imports = [
|
|
3675
3729
|
"'use client'",
|
|
3676
3730
|
"",
|
|
@@ -3782,19 +3836,19 @@ ${Object.keys(endpointsByTag).map((tag) => `export * from './${toValidIdentifier
|
|
|
3782
3836
|
* @returns useQuery result with data of type ${returnType}
|
|
3783
3837
|
*/
|
|
3784
3838
|
export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
|
|
3785
|
-
const [searchParams
|
|
3839
|
+
const [searchParams] = useQueryStates(searchParamsParser)
|
|
3786
3840
|
const { initialData, ...restOptions } = options ?? {}
|
|
3787
3841
|
|
|
3788
3842
|
return useQuery({
|
|
3789
3843
|
queryKey: [...${queryKey}, searchParams],
|
|
3790
|
-
queryFn:
|
|
3844
|
+
queryFn: async ({ signal }: { signal?: AbortSignal }) => {
|
|
3791
3845
|
try {
|
|
3792
3846
|
const result = await ${actionName}(${actionCallParams.replace(queryParamObject, "{ ...searchParams }")})
|
|
3793
3847
|
return result
|
|
3794
3848
|
} catch (error) {
|
|
3795
3849
|
handleActionError(error)
|
|
3796
3850
|
}
|
|
3797
|
-
},
|
|
3851
|
+
},
|
|
3798
3852
|
staleTime: ${staleTime},
|
|
3799
3853
|
gcTime: ${staleTime * 2}, // React Query v5: gcTime replaces cacheTime
|
|
3800
3854
|
enabled: ${enabledCondition} && (options?.enabled ?? true),
|
|
@@ -3826,14 +3880,14 @@ export function ${hookName.replace("use", "useInfinite")}(${parameterTypes.lengt
|
|
|
3826
3880
|
|
|
3827
3881
|
return useInfiniteQuery({
|
|
3828
3882
|
queryKey: [...${queryKey}, 'infinite', searchParams],
|
|
3829
|
-
queryFn:
|
|
3883
|
+
queryFn: async ({ pageParam = 1, signal }: { pageParam?: number; signal?: AbortSignal }) => {
|
|
3830
3884
|
try {
|
|
3831
3885
|
const result = await ${actionName}(${actionCallParams.replace(queryParamObject, "{ ...searchParams, page: pageParam, limit: searchParams.limit }")})
|
|
3832
3886
|
return result
|
|
3833
3887
|
} catch (error) {
|
|
3834
3888
|
handleActionError(error)
|
|
3835
3889
|
}
|
|
3836
|
-
},
|
|
3890
|
+
},
|
|
3837
3891
|
getNextPageParam: (lastPage: ${returnType}, allPages: ${returnType}[]) => {
|
|
3838
3892
|
if (lastPage?.hasMore || (Array.isArray(lastPage) && lastPage.length === searchParams.limit)) {
|
|
3839
3893
|
return allPages.length + 1
|
|
@@ -3863,10 +3917,10 @@ export function ${hookName.replace("use", "useSuspense")}(${parameterTypes.lengt
|
|
|
3863
3917
|
|
|
3864
3918
|
return useSuspenseQuery({
|
|
3865
3919
|
queryKey: ${queryKey},
|
|
3866
|
-
queryFn:
|
|
3920
|
+
queryFn: async () => {
|
|
3867
3921
|
const result = await ${actionName}(${actionCallParams})
|
|
3868
3922
|
return result
|
|
3869
|
-
},
|
|
3923
|
+
},
|
|
3870
3924
|
staleTime: ${staleTime},
|
|
3871
3925
|
initialData: initialData as ${returnType} | undefined,
|
|
3872
3926
|
...restOptions
|
|
@@ -3883,14 +3937,14 @@ export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join
|
|
|
3883
3937
|
|
|
3884
3938
|
return useQuery({
|
|
3885
3939
|
queryKey: ${queryKey},
|
|
3886
|
-
queryFn:
|
|
3940
|
+
queryFn: async ({ signal }: { signal?: AbortSignal }) => {
|
|
3887
3941
|
try {
|
|
3888
3942
|
const result = await ${actionName}(${actionCallParams})
|
|
3889
3943
|
return result
|
|
3890
3944
|
} catch (error) {
|
|
3891
3945
|
handleActionError(error)
|
|
3892
3946
|
}
|
|
3893
|
-
},
|
|
3947
|
+
},
|
|
3894
3948
|
staleTime: ${staleTime},
|
|
3895
3949
|
gcTime: ${staleTime * 2}, // React Query v5: gcTime replaces cacheTime
|
|
3896
3950
|
enabled: ${enabledCondition} && (options?.enabled ?? true),
|
|
@@ -3921,10 +3975,10 @@ export function ${hookName.replace("use", "useSuspense")}(${parameterTypes.lengt
|
|
|
3921
3975
|
|
|
3922
3976
|
return useSuspenseQuery({
|
|
3923
3977
|
queryKey: ${queryKey},
|
|
3924
|
-
queryFn:
|
|
3978
|
+
queryFn: async () => {
|
|
3925
3979
|
const result = await ${actionName}(${actionCallParams})
|
|
3926
3980
|
return result
|
|
3927
|
-
},
|
|
3981
|
+
},
|
|
3928
3982
|
staleTime: ${staleTime},
|
|
3929
3983
|
initialData: initialData as ${returnType} | undefined,
|
|
3930
3984
|
...restOptions
|
|
@@ -3957,8 +4011,6 @@ export function ${hookName.replace("use", "useSuspense")}(${parameterTypes.lengt
|
|
|
3957
4011
|
const relatedQueries = this.findRelatedQueries(endpoint, context);
|
|
3958
4012
|
const invalidationCode = this.buildInvalidationCode(endpoint, relatedQueries, invalidationTags);
|
|
3959
4013
|
const cancelQueriesCode = this.buildCancelQueriesCode(endpoint, relatedQueries);
|
|
3960
|
-
const snapshotCode = this.buildSnapshotCode(endpoint, relatedQueries);
|
|
3961
|
-
const rollbackCode = this.buildRollbackCode(endpoint, relatedQueries);
|
|
3962
4014
|
return `/**
|
|
3963
4015
|
* Optimized mutation hook for ${endpoint.method} ${endpoint.path}
|
|
3964
4016
|
* Features: Optimistic updates, smart invalidation, error handling
|
|
@@ -3979,7 +4031,7 @@ export function ${hookName}(options?: {
|
|
|
3979
4031
|
mutationFn: async (variables: ${inputType}): Promise<${outputType}> => {
|
|
3980
4032
|
try {
|
|
3981
4033
|
const result = await ${actionName}(${variablesParam === "undefined" ? "" : "variables"})
|
|
3982
|
-
return result
|
|
4034
|
+
return (result ?? ({} as ${outputType}))
|
|
3983
4035
|
} catch (error) {
|
|
3984
4036
|
handleActionError(error)
|
|
3985
4037
|
}
|
|
@@ -3987,16 +4039,14 @@ export function ${hookName}(options?: {
|
|
|
3987
4039
|
|
|
3988
4040
|
onMutate: async (variables: ${inputType}) => {
|
|
3989
4041
|
${cancelQueriesCode}
|
|
3990
|
-
|
|
3991
|
-
${snapshotCode}
|
|
3992
|
-
|
|
4042
|
+
|
|
3993
4043
|
// Optimistic update (if provided)
|
|
3994
4044
|
if (options?.optimisticUpdate) {
|
|
3995
4045
|
const optimisticValue = options.optimisticUpdate(variables)
|
|
3996
4046
|
setOptimisticData(optimisticValue)
|
|
3997
4047
|
}
|
|
3998
4048
|
|
|
3999
|
-
return {
|
|
4049
|
+
return {}
|
|
4000
4050
|
},
|
|
4001
4051
|
|
|
4002
4052
|
onSuccess: (data, variables) => {
|
|
@@ -4005,17 +4055,11 @@ ${snapshotCode}
|
|
|
4005
4055
|
toast.success('${this.getSuccessMessage(endpoint)}')
|
|
4006
4056
|
}
|
|
4007
4057
|
|
|
4008
|
-
// Invalidate and refetch related queries
|
|
4009
|
-
${invalidationCode}
|
|
4010
|
-
|
|
4011
4058
|
// Custom success handler
|
|
4012
4059
|
options?.onSuccess?.(data, variables)
|
|
4013
4060
|
},
|
|
4014
4061
|
|
|
4015
|
-
onError: (error: Error, variables: ${inputType}
|
|
4016
|
-
// Rollback optimistic update
|
|
4017
|
-
${rollbackCode}
|
|
4018
|
-
|
|
4062
|
+
onError: (error: Error, variables: ${inputType}) => {
|
|
4019
4063
|
// Show error toast
|
|
4020
4064
|
if (options?.showToast !== false) {
|
|
4021
4065
|
toast.error(error.message || '${this.getErrorMessage(endpoint)}')
|
|
@@ -4025,7 +4069,7 @@ ${rollbackCode}
|
|
|
4025
4069
|
options?.onError?.(error as Error, variables)
|
|
4026
4070
|
},
|
|
4027
4071
|
|
|
4028
|
-
onSettled: () => {
|
|
4072
|
+
onSettled: async () => {
|
|
4029
4073
|
// Always refetch after error or success
|
|
4030
4074
|
${invalidationCode}
|
|
4031
4075
|
}
|
|
@@ -4051,100 +4095,81 @@ ${invalidationCode}
|
|
|
4051
4095
|
return [];
|
|
4052
4096
|
}
|
|
4053
4097
|
const relatedQueries = [];
|
|
4054
|
-
const
|
|
4098
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4055
4099
|
const mutationTag = endpoint.tags[0];
|
|
4056
|
-
const
|
|
4100
|
+
const mutationSegments = this.getResourceSegments(endpoint.path);
|
|
4101
|
+
const mutationResource = mutationSegments[0];
|
|
4057
4102
|
context.schema.endpoints.forEach((queryEndpoint) => {
|
|
4058
4103
|
if (queryEndpoint.method !== "GET") return;
|
|
4059
|
-
const
|
|
4104
|
+
const queryId = queryEndpoint.operationId || queryEndpoint.id;
|
|
4105
|
+
if (seen.has(queryId)) return;
|
|
4060
4106
|
const queryTag = queryEndpoint.tags[0];
|
|
4061
|
-
|
|
4107
|
+
const querySegments = this.getResourceSegments(queryEndpoint.path);
|
|
4108
|
+
const queryResource = querySegments[0];
|
|
4109
|
+
if (mutationTag && queryTag === mutationTag) {
|
|
4062
4110
|
relatedQueries.push(queryEndpoint);
|
|
4111
|
+
seen.add(queryId);
|
|
4063
4112
|
return;
|
|
4064
4113
|
}
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
if (baseMatch) {
|
|
4069
|
-
relatedQueries.push(queryEndpoint);
|
|
4070
|
-
}
|
|
4114
|
+
if (mutationResource && queryResource && mutationResource === queryResource) {
|
|
4115
|
+
relatedQueries.push(queryEndpoint);
|
|
4116
|
+
seen.add(queryId);
|
|
4071
4117
|
}
|
|
4072
4118
|
});
|
|
4073
4119
|
return relatedQueries;
|
|
4074
4120
|
}
|
|
4121
|
+
getResourceSegments(path3) {
|
|
4122
|
+
return path3.split("/").filter(Boolean).filter((segment) => segment.toLowerCase() !== "api" && !/^v\d+/i.test(segment));
|
|
4123
|
+
}
|
|
4075
4124
|
/**
|
|
4076
4125
|
* Build invalidation code for related queries
|
|
4077
4126
|
*/
|
|
4078
4127
|
buildInvalidationCode(endpoint, relatedQueries, invalidationTags) {
|
|
4079
|
-
const invalidations =
|
|
4128
|
+
const invalidations = /* @__PURE__ */ new Set();
|
|
4080
4129
|
relatedQueries.forEach((queryEndpoint) => {
|
|
4081
|
-
const
|
|
4082
|
-
invalidations.
|
|
4130
|
+
const queryKeyPrefix = toActionName(queryEndpoint.operationId || queryEndpoint.id);
|
|
4131
|
+
invalidations.add(`queryClient.invalidateQueries({ queryKey: ['${queryKeyPrefix}'] })`);
|
|
4083
4132
|
});
|
|
4084
4133
|
invalidationTags.forEach((tag) => {
|
|
4085
|
-
|
|
4086
|
-
invalidations.push(` queryClient.invalidateQueries({ queryKey: ['${tag}'] })`);
|
|
4087
|
-
}
|
|
4134
|
+
invalidations.add(`queryClient.invalidateQueries({ queryKey: ['${tag}'] })`);
|
|
4088
4135
|
});
|
|
4089
|
-
if (invalidations.
|
|
4136
|
+
if (invalidations.size === 0) {
|
|
4090
4137
|
const inferredKey = this.inferQueryKeyFromPath(endpoint);
|
|
4091
4138
|
if (inferredKey) {
|
|
4092
|
-
invalidations.
|
|
4139
|
+
invalidations.add(`queryClient.invalidateQueries({ queryKey: ${inferredKey} })`);
|
|
4093
4140
|
}
|
|
4094
4141
|
}
|
|
4095
|
-
|
|
4142
|
+
if (invalidations.size === 0) {
|
|
4143
|
+
return " // No specific cache invalidation needed";
|
|
4144
|
+
}
|
|
4145
|
+
if (invalidations.size === 1) {
|
|
4146
|
+
const [statement] = Array.from(invalidations);
|
|
4147
|
+
return ` await ${statement}`;
|
|
4148
|
+
}
|
|
4149
|
+
return ` await Promise.all([
|
|
4150
|
+
${Array.from(invalidations).join(",\n ")}
|
|
4151
|
+
])`;
|
|
4096
4152
|
}
|
|
4097
4153
|
/**
|
|
4098
4154
|
* Build cancel queries code
|
|
4099
4155
|
* Uses query key patterns to cancel all related queries regardless of parameters
|
|
4100
4156
|
*/
|
|
4101
4157
|
buildCancelQueriesCode(endpoint, relatedQueries) {
|
|
4102
|
-
const cancels =
|
|
4158
|
+
const cancels = /* @__PURE__ */ new Set();
|
|
4103
4159
|
relatedQueries.forEach((queryEndpoint) => {
|
|
4104
|
-
const queryKeyPrefix =
|
|
4105
|
-
cancels.
|
|
4160
|
+
const queryKeyPrefix = toActionName(queryEndpoint.operationId || queryEndpoint.id);
|
|
4161
|
+
cancels.add(`queryClient.cancelQueries({ queryKey: ['${queryKeyPrefix}'] })`);
|
|
4106
4162
|
});
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
/**
|
|
4110
|
-
* Build snapshot code for rollback
|
|
4111
|
-
* Note: We can't snapshot specific queries with parameters in onMutate scope
|
|
4112
|
-
* Instead, we'll invalidate all related queries on error
|
|
4113
|
-
*/
|
|
4114
|
-
buildSnapshotCode(endpoint, relatedQueries) {
|
|
4115
|
-
if (relatedQueries.length === 0) {
|
|
4116
|
-
return " // No queries to snapshot";
|
|
4117
|
-
}
|
|
4118
|
-
return " // Snapshot handled via query invalidation";
|
|
4119
|
-
}
|
|
4120
|
-
/**
|
|
4121
|
-
* Build rollback code
|
|
4122
|
-
*/
|
|
4123
|
-
buildRollbackCode(endpoint, relatedQueries) {
|
|
4124
|
-
if (relatedQueries.length === 0) {
|
|
4125
|
-
return " // No queries to rollback";
|
|
4163
|
+
if (cancels.size === 0) {
|
|
4164
|
+
return " // No queries to cancel";
|
|
4126
4165
|
}
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
const varName = `previous${this.toPascalCase(toActionName(queryEndpoint.operationId || queryEndpoint.id))}`;
|
|
4131
|
-
rollbacks.push(` if (context?.${varName}) {
|
|
4132
|
-
queryClient.setQueryData(${queryKey}, context.${varName})
|
|
4133
|
-
}`);
|
|
4134
|
-
});
|
|
4135
|
-
return rollbacks.join("\n");
|
|
4136
|
-
}
|
|
4137
|
-
/**
|
|
4138
|
-
* Get snapshot return names for context
|
|
4139
|
-
*/
|
|
4140
|
-
getSnapshotReturnNames(relatedQueries) {
|
|
4141
|
-
if (relatedQueries.length === 0) {
|
|
4142
|
-
return "previousData: null";
|
|
4166
|
+
if (cancels.size === 1) {
|
|
4167
|
+
const [statement] = Array.from(cancels);
|
|
4168
|
+
return ` await ${statement}`;
|
|
4143
4169
|
}
|
|
4144
|
-
return
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
}).join(", ");
|
|
4170
|
+
return ` await Promise.all([
|
|
4171
|
+
${Array.from(cancels).join(",\n ")}
|
|
4172
|
+
])`;
|
|
4148
4173
|
}
|
|
4149
4174
|
/**
|
|
4150
4175
|
* Infer query key from mutation path
|
|
@@ -9394,7 +9419,8 @@ var bridgeConfigSchema = z.object({
|
|
|
9394
9419
|
logging: z.boolean().default(true),
|
|
9395
9420
|
validation: z.boolean().default(true),
|
|
9396
9421
|
mocking: z.boolean().default(false),
|
|
9397
|
-
watch: z.boolean().default(false)
|
|
9422
|
+
watch: z.boolean().default(false),
|
|
9423
|
+
hotReload: z.boolean().default(false)
|
|
9398
9424
|
}).optional(),
|
|
9399
9425
|
plugins: z.array(
|
|
9400
9426
|
z.object({
|
|
@@ -9407,6 +9433,7 @@ var bridgeConfigSchema = z.object({
|
|
|
9407
9433
|
typescript: z.boolean().default(true),
|
|
9408
9434
|
strict: z.boolean().default(true),
|
|
9409
9435
|
comments: z.boolean().default(true),
|
|
9436
|
+
documentation: z.boolean().default(true),
|
|
9410
9437
|
examples: z.boolean().default(false),
|
|
9411
9438
|
tests: z.boolean().default(false)
|
|
9412
9439
|
}).optional()
|
|
@@ -9512,12 +9539,14 @@ ${errorMessages}`,
|
|
|
9512
9539
|
logging: true,
|
|
9513
9540
|
validation: true,
|
|
9514
9541
|
mocking: false,
|
|
9515
|
-
watch: false
|
|
9542
|
+
watch: false,
|
|
9543
|
+
hotReload: false
|
|
9516
9544
|
},
|
|
9517
9545
|
generation: {
|
|
9518
9546
|
typescript: true,
|
|
9519
9547
|
strict: true,
|
|
9520
9548
|
comments: true,
|
|
9549
|
+
documentation: true,
|
|
9521
9550
|
examples: false,
|
|
9522
9551
|
tests: false
|
|
9523
9552
|
}
|
|
@@ -9570,5 +9599,5 @@ ${errorMessages}`,
|
|
|
9570
9599
|
};
|
|
9571
9600
|
|
|
9572
9601
|
export { BridgeCore, BridgeError, BridgeLogger, ConfigurationLoader, FileSystemManager, GenerationError, LogLevel, NextJsCodeGenerator, OpenApiSchemaParser, SchemaParseError, ValidationError, VersionChecker, __name, checkAndNotifyUpdates, createBridgeVersionChecker };
|
|
9573
|
-
//# sourceMappingURL=chunk-
|
|
9574
|
-
//# sourceMappingURL=chunk-
|
|
9602
|
+
//# sourceMappingURL=chunk-7Y66DW7M.js.map
|
|
9603
|
+
//# sourceMappingURL=chunk-7Y66DW7M.js.map
|