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
|
@@ -1550,7 +1550,6 @@ export class BaseApiClient {
|
|
|
1550
1550
|
retryDelay, retryCondition, validateResponse, skipAuth,
|
|
1551
1551
|
responseSchema, requestId, [...this.middleware, ...middleware],
|
|
1552
1552
|
cacheTags, revalidate, connection, updateTag
|
|
1553
|
-
cacheTags, revalidate, connection, updateTag
|
|
1554
1553
|
)
|
|
1555
1554
|
|
|
1556
1555
|
requestCache.set(dedupeKey, requestPromise)
|
|
@@ -1568,7 +1567,6 @@ export class BaseApiClient {
|
|
|
1568
1567
|
retryDelay, retryCondition, validateResponse, skipAuth,
|
|
1569
1568
|
responseSchema, requestId, [...this.middleware, ...middleware],
|
|
1570
1569
|
cacheTags, revalidate, connection, updateTag
|
|
1571
|
-
cacheTags, revalidate, connection, updateTag
|
|
1572
1570
|
)
|
|
1573
1571
|
}
|
|
1574
1572
|
|
|
@@ -2724,7 +2722,9 @@ var SchemaGenerator = class {
|
|
|
2724
2722
|
].join("\n");
|
|
2725
2723
|
let content = this.removeUnusedCode(contentWithImports);
|
|
2726
2724
|
if (!content.includes('import { z } from "zod"') && !content.includes("import { z } from 'zod'")) {
|
|
2727
|
-
content =
|
|
2725
|
+
content = `import { z } from "zod"
|
|
2726
|
+
|
|
2727
|
+
${content}`;
|
|
2728
2728
|
}
|
|
2729
2729
|
return {
|
|
2730
2730
|
path: "schemas/index.ts",
|
|
@@ -3135,6 +3135,166 @@ var ActionGenerator = class {
|
|
|
3135
3135
|
static {
|
|
3136
3136
|
__name(this, "ActionGenerator");
|
|
3137
3137
|
}
|
|
3138
|
+
get loggingEnabled() {
|
|
3139
|
+
return this.configuration.dev?.logging !== false;
|
|
3140
|
+
}
|
|
3141
|
+
get validationEnabled() {
|
|
3142
|
+
return this.configuration.dev?.validation !== false;
|
|
3143
|
+
}
|
|
3144
|
+
get commentsEnabled() {
|
|
3145
|
+
return this.configuration.generation?.comments !== false;
|
|
3146
|
+
}
|
|
3147
|
+
get documentationEnabled() {
|
|
3148
|
+
return this.configuration.generation?.documentation !== false;
|
|
3149
|
+
}
|
|
3150
|
+
commentLine(text, indent = 2) {
|
|
3151
|
+
if (!this.commentsEnabled) {
|
|
3152
|
+
return "";
|
|
3153
|
+
}
|
|
3154
|
+
return `${" ".repeat(indent)}// ${text}
|
|
3155
|
+
`;
|
|
3156
|
+
}
|
|
3157
|
+
buildDocBlock(endpoint, featuresDescription) {
|
|
3158
|
+
if (!this.documentationEnabled) {
|
|
3159
|
+
return "";
|
|
3160
|
+
}
|
|
3161
|
+
const summary = endpoint.summary || endpoint.description || `${endpoint.method} ${endpoint.path}`;
|
|
3162
|
+
return `/**
|
|
3163
|
+
* ${summary}
|
|
3164
|
+
* @generated from ${endpoint.method} ${endpoint.path}
|
|
3165
|
+
* Features: ${featuresDescription}
|
|
3166
|
+
*/
|
|
3167
|
+
`;
|
|
3168
|
+
}
|
|
3169
|
+
buildUtilityFunctions() {
|
|
3170
|
+
const parts = [];
|
|
3171
|
+
if (this.commentsEnabled) {
|
|
3172
|
+
parts.push("// Utility functions for enhanced server actions");
|
|
3173
|
+
}
|
|
3174
|
+
parts.push(`async function getClientInfo() {
|
|
3175
|
+
const headersList = await headers()
|
|
3176
|
+
const userAgent = headersList.get('user-agent') || 'unknown'
|
|
3177
|
+
const ip = headersList.get('x-forwarded-for') || headersList.get('x-real-ip') || 'unknown'
|
|
3178
|
+
|
|
3179
|
+
return { userAgent, ip }
|
|
3180
|
+
}`);
|
|
3181
|
+
if (this.validationEnabled) {
|
|
3182
|
+
parts.push(`async function validateAndSanitizeInput<T>(schema: z.ZodSchema<T>, input: unknown): Promise<T> {
|
|
3183
|
+
try {
|
|
3184
|
+
return await schema.parseAsync(input)
|
|
3185
|
+
} catch (error) {
|
|
3186
|
+
if (error instanceof z.ZodError) {
|
|
3187
|
+
const errorMessages = error.issues.map(issue => {
|
|
3188
|
+
const path = issue.path.length > 0 ? \`\${issue.path.join('.')}: \` : ''
|
|
3189
|
+
return \`\${path}\${issue.message}\`
|
|
3190
|
+
}).join(', ')
|
|
3191
|
+
throw new ActionError(\`Input validation failed: \${errorMessages}\`, 'VALIDATION_ERROR')
|
|
3192
|
+
}
|
|
3193
|
+
throw new ActionError('Invalid input format', 'VALIDATION_ERROR')
|
|
3194
|
+
}
|
|
3195
|
+
}`);
|
|
3196
|
+
}
|
|
3197
|
+
const actionErrorBlock = `${this.commentsEnabled ? "// Enhanced error handling with context\n" : ""}class ActionExecutionError extends ActionError {
|
|
3198
|
+
constructor(
|
|
3199
|
+
message: string,
|
|
3200
|
+
public readonly context: {
|
|
3201
|
+
endpoint: string
|
|
3202
|
+
method: string
|
|
3203
|
+
timestamp: number
|
|
3204
|
+
},
|
|
3205
|
+
public readonly originalError?: unknown
|
|
3206
|
+
) {
|
|
3207
|
+
super(message, 'EXECUTION_ERROR')
|
|
3208
|
+
}
|
|
3209
|
+
}`;
|
|
3210
|
+
parts.push(actionErrorBlock);
|
|
3211
|
+
if (this.loggingEnabled) {
|
|
3212
|
+
const loggingHeader = this.commentsEnabled ? "// Logging utility for server actions\n" : "";
|
|
3213
|
+
parts.push(`${loggingHeader}async function logActionExecution(
|
|
3214
|
+
action: string,
|
|
3215
|
+
success: boolean,
|
|
3216
|
+
duration: number,
|
|
3217
|
+
context?: Record<string, any>
|
|
3218
|
+
) {
|
|
3219
|
+
if (process.env.NODE_ENV === 'development') {
|
|
3220
|
+
console.log(\`[ACTION] \${action} - \${success ? 'SUCCESS' : 'FAILED'} (\${duration}ms)\`, context)
|
|
3221
|
+
}
|
|
3222
|
+
|
|
3223
|
+
${this.commentsEnabled ? " // In production, send to your logging service\n // await analytics.track('server_action_executed', { action, success, duration, ...context })" : ""}
|
|
3224
|
+
}`);
|
|
3225
|
+
}
|
|
3226
|
+
return parts.join("\n\n");
|
|
3227
|
+
}
|
|
3228
|
+
buildCombinedValidationSnippet(operationName, schemaName) {
|
|
3229
|
+
if (this.validationEnabled) {
|
|
3230
|
+
return `
|
|
3231
|
+
${this.commentLine("Validate and sanitize input payload", 6)} const { body, params } = await validateAndSanitizeInput(${schemaName}, parsedInput)
|
|
3232
|
+
const validatedBody = body
|
|
3233
|
+
const validatedParams = params as z.infer<typeof ${operationName}ParamsSchema>`;
|
|
3234
|
+
}
|
|
3235
|
+
return `
|
|
3236
|
+
${this.commentLine("Runtime validation disabled - trusting provided payload", 6)} const { body, params } = parsedInput as {
|
|
3237
|
+
body: z.infer<typeof ${operationName}RequestSchema>
|
|
3238
|
+
params: z.infer<typeof ${operationName}ParamsSchema>
|
|
3239
|
+
}
|
|
3240
|
+
const validatedBody = body
|
|
3241
|
+
const validatedParams = params`;
|
|
3242
|
+
}
|
|
3243
|
+
buildBodyValidationSnippet(schemaName) {
|
|
3244
|
+
if (schemaName === "z.void()") {
|
|
3245
|
+
return "";
|
|
3246
|
+
}
|
|
3247
|
+
if (this.validationEnabled) {
|
|
3248
|
+
return `
|
|
3249
|
+
${this.commentLine("Validate and sanitize request body", 6)} const validatedBody = await validateAndSanitizeInput(${schemaName}, parsedInput)`;
|
|
3250
|
+
}
|
|
3251
|
+
return `
|
|
3252
|
+
${this.commentLine("Runtime validation disabled - trusting request body", 6)} const validatedBody = parsedInput as z.infer<typeof ${schemaName}>`;
|
|
3253
|
+
}
|
|
3254
|
+
buildParamsValidationSnippet(operationName, schemaName) {
|
|
3255
|
+
if (schemaName === "z.void()") {
|
|
3256
|
+
return "";
|
|
3257
|
+
}
|
|
3258
|
+
if (this.validationEnabled) {
|
|
3259
|
+
return `
|
|
3260
|
+
${this.commentLine("Validate and sanitize parameters", 6)} const validatedParams = await validateAndSanitizeInput(${schemaName}, parsedInput) as z.infer<typeof ${operationName}ParamsSchema>`;
|
|
3261
|
+
}
|
|
3262
|
+
return `
|
|
3263
|
+
${this.commentLine("Runtime validation disabled - trusting parameters", 6)} const validatedParams = parsedInput as z.infer<typeof ${operationName}ParamsSchema>`;
|
|
3264
|
+
}
|
|
3265
|
+
buildSuccessLoggingBlock(actionName, endpoint, indent, isStreaming = false) {
|
|
3266
|
+
if (!this.loggingEnabled) {
|
|
3267
|
+
return "";
|
|
3268
|
+
}
|
|
3269
|
+
if (isStreaming) {
|
|
3270
|
+
return `
|
|
3271
|
+
${this.commentLine("Background tasks (Next.js 15 feature)", indent)}${" ".repeat(indent)}after(async () => {
|
|
3272
|
+
${this.commentLine("Perform background tasks after response is sent", indent + 2)}${" ".repeat(indent + 2)}await logActionExecution('${actionName}', true, Date.now() - startTime, {
|
|
3273
|
+
${" ".repeat(indent + 4)}method: '${endpoint.method}',
|
|
3274
|
+
${" ".repeat(indent + 4)}path: '${endpoint.path}'
|
|
3275
|
+
${" ".repeat(indent + 2)}})
|
|
3276
|
+
${" ".repeat(indent)}})`;
|
|
3277
|
+
}
|
|
3278
|
+
return `
|
|
3279
|
+
${this.commentLine("Log successful execution", indent)}${" ".repeat(indent)}const duration = Date.now() - startTime
|
|
3280
|
+
${" ".repeat(indent)}await logActionExecution('${actionName}', true, duration, {
|
|
3281
|
+
${" ".repeat(indent + 2)}method: '${endpoint.method}',
|
|
3282
|
+
${" ".repeat(indent + 2)}path: '${endpoint.path}'
|
|
3283
|
+
${" ".repeat(indent)}})`;
|
|
3284
|
+
}
|
|
3285
|
+
buildErrorLoggingBlock(actionName, endpoint, indent) {
|
|
3286
|
+
if (!this.loggingEnabled) {
|
|
3287
|
+
return "";
|
|
3288
|
+
}
|
|
3289
|
+
return `
|
|
3290
|
+
${" ".repeat(indent)}const duration = Date.now() - startTime
|
|
3291
|
+
|
|
3292
|
+
${this.commentLine("Enhanced error logging", indent)}${" ".repeat(indent)}await logActionExecution('${actionName}', false, duration, {
|
|
3293
|
+
${" ".repeat(indent + 2)}method: '${endpoint.method}',
|
|
3294
|
+
${" ".repeat(indent + 2)}path: '${endpoint.path}',
|
|
3295
|
+
${" ".repeat(indent + 2)}error: error instanceof Error ? error.message : 'Unknown error'
|
|
3296
|
+
${" ".repeat(indent)}})`;
|
|
3297
|
+
}
|
|
3138
3298
|
buildImportPath(relativePath) {
|
|
3139
3299
|
const outputDirectory = this.configuration.outputDir || "generated";
|
|
3140
3300
|
const cleanPath = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
|
|
@@ -3199,8 +3359,7 @@ var ActionGenerator = class {
|
|
|
3199
3359
|
] : []
|
|
3200
3360
|
].filter(Boolean).join("\n");
|
|
3201
3361
|
const rateLimitSetup = hasRateLimit ? `
|
|
3202
|
-
// Rate limiting setup
|
|
3203
|
-
const redis = new Redis({
|
|
3362
|
+
${this.commentsEnabled ? "// Rate limiting setup\n" : ""}const redis = new Redis({
|
|
3204
3363
|
url: process.env.UPSTASH_REDIS_REST_URL!,
|
|
3205
3364
|
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
|
|
3206
3365
|
})
|
|
@@ -3210,60 +3369,7 @@ const ratelimit = new Ratelimit({
|
|
|
3210
3369
|
limiter: Ratelimit.slidingWindow(10, '1 m'),
|
|
3211
3370
|
analytics: true,
|
|
3212
3371
|
})` : "";
|
|
3213
|
-
const utilityFunctions =
|
|
3214
|
-
// Utility functions for enhanced server actions
|
|
3215
|
-
async function getClientInfo() {
|
|
3216
|
-
const headersList = await headers()
|
|
3217
|
-
const userAgent = headersList.get('user-agent') || 'unknown'
|
|
3218
|
-
const ip = headersList.get('x-forwarded-for') || headersList.get('x-real-ip') || 'unknown'
|
|
3219
|
-
|
|
3220
|
-
return { userAgent, ip }
|
|
3221
|
-
}
|
|
3222
|
-
|
|
3223
|
-
async function validateAndSanitizeInput<T>(schema: z.ZodSchema<T>, input: unknown): Promise<T> {
|
|
3224
|
-
try {
|
|
3225
|
-
return await schema.parseAsync(input)
|
|
3226
|
-
} catch (error) {
|
|
3227
|
-
if (error instanceof z.ZodError) {
|
|
3228
|
-
const errorMessages = error.issues.map(issue => {
|
|
3229
|
-
const path = issue.path.length > 0 ? \`\${issue.path.join('.')}: \` : ''
|
|
3230
|
-
return \`\${path}\${issue.message}\`
|
|
3231
|
-
}).join(', ')
|
|
3232
|
-
throw new ActionError(\`Input validation failed: \${errorMessages}\`, 'VALIDATION_ERROR')
|
|
3233
|
-
}
|
|
3234
|
-
throw new ActionError('Invalid input format', 'VALIDATION_ERROR')
|
|
3235
|
-
}
|
|
3236
|
-
}
|
|
3237
|
-
|
|
3238
|
-
// Enhanced error handling with context
|
|
3239
|
-
class ActionExecutionError extends ActionError {
|
|
3240
|
-
constructor(
|
|
3241
|
-
message: string,
|
|
3242
|
-
public readonly context: {
|
|
3243
|
-
endpoint: string
|
|
3244
|
-
method: string
|
|
3245
|
-
timestamp: number
|
|
3246
|
-
},
|
|
3247
|
-
public readonly originalError?: unknown
|
|
3248
|
-
) {
|
|
3249
|
-
super(message, 'EXECUTION_ERROR')
|
|
3250
|
-
}
|
|
3251
|
-
}
|
|
3252
|
-
|
|
3253
|
-
// Logging utility for server actions
|
|
3254
|
-
async function logActionExecution(
|
|
3255
|
-
action: string,
|
|
3256
|
-
success: boolean,
|
|
3257
|
-
duration: number,
|
|
3258
|
-
context?: Record<string, any>
|
|
3259
|
-
) {
|
|
3260
|
-
if (process.env.NODE_ENV === 'development') {
|
|
3261
|
-
console.log(\`[ACTION] \${action} - \${success ? 'SUCCESS' : 'FAILED'} (\${duration}ms)\`, context)
|
|
3262
|
-
}
|
|
3263
|
-
|
|
3264
|
-
// In production, send to your logging service
|
|
3265
|
-
// await analytics.track('server_action_executed', { action, success, duration, ...context })
|
|
3266
|
-
}`;
|
|
3372
|
+
const utilityFunctions = this.buildUtilityFunctions();
|
|
3267
3373
|
const content = `${imports}
|
|
3268
3374
|
${rateLimitSetup}
|
|
3269
3375
|
${utilityFunctions}
|
|
@@ -3280,8 +3386,8 @@ ${actions}`;
|
|
|
3280
3386
|
}
|
|
3281
3387
|
});
|
|
3282
3388
|
}
|
|
3283
|
-
const
|
|
3284
|
-
${Object.keys(endpointsByTag).map((tag) => `export * from './${toValidIdentifier(tag)}'`).join("\n")}`;
|
|
3389
|
+
const indexHeader = this.commentsEnabled ? "// Auto-generated actions index\n" : "";
|
|
3390
|
+
const indexContent = `${indexHeader}${Object.keys(endpointsByTag).map((tag) => `export * from './${toValidIdentifier(tag)}'`).join("\n")}`;
|
|
3285
3391
|
generatedFiles.push({
|
|
3286
3392
|
path: "actions/index.ts",
|
|
3287
3393
|
content: indexContent,
|
|
@@ -3330,54 +3436,48 @@ ${Object.keys(endpointsByTag).map((tag) => `export * from './${toValidIdentifier
|
|
|
3330
3436
|
body: ${operationName}RequestSchema,
|
|
3331
3437
|
params: ${operationName}ParamsSchema
|
|
3332
3438
|
})`;
|
|
3333
|
-
parameterProcessing =
|
|
3334
|
-
// Validate and sanitize input
|
|
3335
|
-
const { body, params } = await validateAndSanitizeInput(${schemaName}, parsedInput)
|
|
3336
|
-
const validatedBody = body
|
|
3337
|
-
const validatedParams = params as z.infer<typeof ${operationName}ParamsSchema>`;
|
|
3439
|
+
parameterProcessing = this.buildCombinedValidationSnippet(operationName, schemaName);
|
|
3338
3440
|
requestOptionsParams = this.buildRequestOptions(pathParameters, queryParameters, true, true);
|
|
3339
3441
|
} else if (hasRequestBody) {
|
|
3340
3442
|
schemaName = `${operationName}RequestSchema`;
|
|
3341
|
-
parameterProcessing =
|
|
3342
|
-
// Validate and sanitize request body
|
|
3343
|
-
const validatedBody = await validateAndSanitizeInput(${schemaName}, parsedInput)`;
|
|
3443
|
+
parameterProcessing = this.buildBodyValidationSnippet(schemaName);
|
|
3344
3444
|
requestOptionsParams = `body: validatedBody`;
|
|
3345
3445
|
} else if (hasAnyParams) {
|
|
3346
3446
|
schemaName = `${operationName}ParamsSchema`;
|
|
3347
|
-
parameterProcessing =
|
|
3348
|
-
// Validate and sanitize parameters
|
|
3349
|
-
const validatedParams = await validateAndSanitizeInput(${schemaName}, parsedInput) as z.infer<typeof ${operationName}ParamsSchema>`;
|
|
3447
|
+
parameterProcessing = this.buildParamsValidationSnippet(operationName, schemaName);
|
|
3350
3448
|
requestOptionsParams = this.buildRequestOptions(pathParameters, queryParameters, false, true);
|
|
3351
3449
|
} else {
|
|
3352
3450
|
schemaName = "z.void()";
|
|
3353
3451
|
parameterProcessing = "";
|
|
3354
3452
|
requestOptionsParams = "";
|
|
3355
3453
|
}
|
|
3454
|
+
const parsedInputType = hasRequestBody || hasAnyParams ? `z.infer<typeof ${schemaName}>` : "void";
|
|
3455
|
+
const ctxType = requiresAuth || hasRateLimit ? "{ user?: any; ratelimit?: { remaining: number } }" : "any";
|
|
3456
|
+
const ctxDeclaration = requiresAuth || hasRateLimit ? `ctx: ${ctxType}` : "ctx?: any";
|
|
3457
|
+
const actionArgsType = `{ parsedInput: ${parsedInputType}; ${ctxDeclaration} }`;
|
|
3356
3458
|
const clientName = requiresAuth || hasRateLimit ? "authActionClient" : "actionClientWithMeta";
|
|
3357
3459
|
const rateLimitCode = hasRateLimit ? `
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
}` : "";
|
|
3460
|
+
${this.commentLine("Rate limiting", 6)} const { userAgent, ip } = await getClientInfo()
|
|
3461
|
+
const identifier = \`\${ip}-\${userAgent}\`
|
|
3462
|
+
const { success, limit, reset, remaining } = await ratelimit.limit(identifier)
|
|
3463
|
+
|
|
3464
|
+
if (!success) {
|
|
3465
|
+
throw new ActionError(
|
|
3466
|
+
\`Rate limit exceeded. Try again in \${Math.round((reset - Date.now()) / 1000)} seconds.\`,
|
|
3467
|
+
'RATE_LIMIT_EXCEEDED'
|
|
3468
|
+
)
|
|
3469
|
+
}` : "";
|
|
3369
3470
|
const revalidationCode = revalidationTags.length > 0 ? revalidationTags.map(
|
|
3370
|
-
(tag) => ` updateTag('${tag}')
|
|
3371
|
-
console.log('Updated tag: ${tag}')`
|
|
3471
|
+
(tag) => ` updateTag('${tag}')${this.loggingEnabled ? `
|
|
3472
|
+
console.log('Updated tag: ${tag}')` : ""}`
|
|
3372
3473
|
).join("\n") : "";
|
|
3373
3474
|
const kebabActionName = actionName.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
|
|
3374
3475
|
if (isQuery) {
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
export const ${actionName} = cache(
|
|
3476
|
+
const docBlock = this.buildDocBlock(
|
|
3477
|
+
endpoint,
|
|
3478
|
+
"React cache, input validation, error handling"
|
|
3479
|
+
);
|
|
3480
|
+
return `${docBlock}export const ${actionName} = cache(
|
|
3381
3481
|
${clientName}
|
|
3382
3482
|
.metadata({
|
|
3383
3483
|
name: "${kebabActionName}",
|
|
@@ -3385,7 +3485,7 @@ export const ${actionName} = cache(
|
|
|
3385
3485
|
rateLimit: { requests: ${endpoint.metadata.rateLimit?.requests || 10}, window: "${endpoint.metadata.rateLimit?.window || "1m"}" }` : ""}
|
|
3386
3486
|
})
|
|
3387
3487
|
.schema(${schemaName})
|
|
3388
|
-
.action(async ({ parsedInput, ctx }:
|
|
3488
|
+
.action(async ({ parsedInput, ctx }: ${actionArgsType}) => {
|
|
3389
3489
|
const startTime = Date.now()
|
|
3390
3490
|
|
|
3391
3491
|
try {${rateLimitCode}${parameterProcessing}
|
|
@@ -3400,23 +3500,11 @@ export const ${actionName} = cache(
|
|
|
3400
3500
|
}
|
|
3401
3501
|
})
|
|
3402
3502
|
|
|
3403
|
-
|
|
3404
|
-
const duration = Date.now() - startTime
|
|
3405
|
-
await logActionExecution('${actionName}', true, duration, {
|
|
3406
|
-
method: '${endpoint.method}',
|
|
3407
|
-
path: '${endpoint.path}'
|
|
3408
|
-
})
|
|
3503
|
+
${this.buildSuccessLoggingBlock(actionName, endpoint, 8)}
|
|
3409
3504
|
|
|
3410
3505
|
return response.data
|
|
3411
3506
|
} catch (error) {
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
// Enhanced error logging
|
|
3415
|
-
await logActionExecution('${actionName}', false, duration, {
|
|
3416
|
-
method: '${endpoint.method}',
|
|
3417
|
-
path: '${endpoint.path}',
|
|
3418
|
-
error: error instanceof Error ? error.message : 'Unknown error'
|
|
3419
|
-
})
|
|
3507
|
+
${this.buildErrorLoggingBlock(actionName, endpoint, 8)}
|
|
3420
3508
|
|
|
3421
3509
|
// Throw enhanced error with context
|
|
3422
3510
|
throw new ActionExecutionError(
|
|
@@ -3433,50 +3521,37 @@ export const ${actionName} = cache(
|
|
|
3433
3521
|
)`;
|
|
3434
3522
|
}
|
|
3435
3523
|
const redirectCode = `
|
|
3436
|
-
|
|
3437
|
-
if (response.status === 201 && response.headers.get('location')) {
|
|
3524
|
+
${this.commentLine("Handle potential redirects based on response", 8)} if (response.status === 201 && response.headers.get('location')) {
|
|
3438
3525
|
const location = response.headers.get('location')!
|
|
3439
3526
|
redirect(location)
|
|
3440
3527
|
}`;
|
|
3441
3528
|
const streamingCode = `
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
// Process streaming response
|
|
3445
|
-
return response.data
|
|
3529
|
+
${this.commentLine("Handle streaming responses", 8)} if (response.headers.get('content-type')?.includes('text/stream')) {
|
|
3530
|
+
${this.commentLine("Process streaming response", 10)} return response.data
|
|
3446
3531
|
}`;
|
|
3447
3532
|
const fileUploadCode = hasFileUpload ? uploadStrategy === "external" && uploadProvider === "vercel-blob" ? `
|
|
3448
|
-
|
|
3449
|
-
if (validatedBody && typeof validatedBody === 'object' && 'file' in validatedBody) {
|
|
3533
|
+
${this.commentLine("Handle file uploads with Vercel Blob", 8)} if (validatedBody && typeof validatedBody === 'object' && 'file' in validatedBody) {
|
|
3450
3534
|
const file = (validatedBody as any).file as File
|
|
3451
3535
|
const blob = await put(file.name, file, { access: 'public' })
|
|
3452
3536
|
Object.assign(validatedBody, { fileUrl: blob.url })
|
|
3453
3537
|
}` : uploadStrategy === "external" && uploadProvider === "uploadthing" ? `
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
const file = (validatedBody as any).file as File
|
|
3465
|
-
// Process file with compression and validation if enabled
|
|
3466
|
-
}` : "";
|
|
3467
|
-
return `/**
|
|
3468
|
-
* ${endpoint.summary || endpoint.description || `${endpoint.method} ${endpoint.path}`}
|
|
3469
|
-
* @generated from ${endpoint.method} ${endpoint.path}
|
|
3470
|
-
* Features: Input validation, revalidation, error handling
|
|
3471
|
-
*/
|
|
3472
|
-
export const ${actionName} = ${clientName}
|
|
3538
|
+
${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) {
|
|
3539
|
+
${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)} }` : `
|
|
3540
|
+
${this.commentLine("Handle file uploads with standard FormData", 8)} if (validatedBody && typeof validatedBody === 'object' && 'file' in validatedBody) {
|
|
3541
|
+
${this.commentLine("Standard file upload handling", 10)} const file = (validatedBody as any).file as File
|
|
3542
|
+
${this.commentLine("Process file with compression and validation if enabled", 10)} }` : "";
|
|
3543
|
+
const mutationDocBlock = this.buildDocBlock(
|
|
3544
|
+
endpoint,
|
|
3545
|
+
"Input validation, revalidation, error handling"
|
|
3546
|
+
);
|
|
3547
|
+
return `${mutationDocBlock}export const ${actionName} = ${clientName}
|
|
3473
3548
|
.metadata({
|
|
3474
3549
|
name: "${kebabActionName}",
|
|
3475
3550
|
requiresAuth: ${requiresAuth}${hasRateLimit ? `,
|
|
3476
3551
|
rateLimit: { requests: ${endpoint.metadata.rateLimit?.requests || 10}, window: "${endpoint.metadata.rateLimit?.window || "1m"}" }` : ""}
|
|
3477
3552
|
})
|
|
3478
3553
|
.schema(${schemaName})
|
|
3479
|
-
.action(async ({ parsedInput, ctx }:
|
|
3554
|
+
.action(async ({ parsedInput, ctx }: ${actionArgsType}) => {
|
|
3480
3555
|
const startTime = Date.now()
|
|
3481
3556
|
|
|
3482
3557
|
try {${rateLimitCode}${parameterProcessing}${fileUploadCode}
|
|
@@ -3491,33 +3566,13 @@ export const ${actionName} = ${clientName}
|
|
|
3491
3566
|
}
|
|
3492
3567
|
})${streamingCode}${redirectCode}
|
|
3493
3568
|
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
// Background tasks (Next.js 15 feature)
|
|
3498
|
-
${isStreaming ? `after(async () => {
|
|
3499
|
-
// Perform background tasks after response is sent
|
|
3500
|
-
await logActionExecution('${actionName}', true, Date.now() - startTime, {
|
|
3501
|
-
method: '${endpoint.method}',
|
|
3502
|
-
path: '${endpoint.path}'
|
|
3503
|
-
})
|
|
3504
|
-
})` : `// Log successful execution
|
|
3505
|
-
const duration = Date.now() - startTime
|
|
3506
|
-
await logActionExecution('${actionName}', true, duration, {
|
|
3507
|
-
method: '${endpoint.method}',
|
|
3508
|
-
path: '${endpoint.path}'
|
|
3509
|
-
})`}
|
|
3569
|
+
${revalidationCode ? `${this.commentLine("Revalidate cache after successful mutation", 6)}${revalidationCode}
|
|
3570
|
+
` : ""}
|
|
3571
|
+
${this.buildSuccessLoggingBlock(actionName, endpoint, 6, isStreaming)}
|
|
3510
3572
|
|
|
3511
3573
|
return response.data
|
|
3512
3574
|
} catch (error) {
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
// Enhanced error logging
|
|
3516
|
-
await logActionExecution('${actionName}', false, duration, {
|
|
3517
|
-
method: '${endpoint.method}',
|
|
3518
|
-
path: '${endpoint.path}',
|
|
3519
|
-
error: error instanceof Error ? error.message : 'Unknown error'
|
|
3520
|
-
})
|
|
3575
|
+
${this.buildErrorLoggingBlock(actionName, endpoint, 6)}
|
|
3521
3576
|
|
|
3522
3577
|
// Throw enhanced error with context
|
|
3523
3578
|
throw new ActionExecutionError(
|
|
@@ -3676,7 +3731,6 @@ var HookGenerator = class {
|
|
|
3676
3731
|
if (hasInfiniteQueries) reactQueryImports.push("useInfiniteQuery");
|
|
3677
3732
|
const reactImports = [];
|
|
3678
3733
|
if (hasMutations) reactImports.push("useOptimistic", "useTransition");
|
|
3679
|
-
if (hasQueries) reactImports.push("useCallback");
|
|
3680
3734
|
const imports = [
|
|
3681
3735
|
"'use client'",
|
|
3682
3736
|
"",
|
|
@@ -3788,19 +3842,19 @@ ${Object.keys(endpointsByTag).map((tag) => `export * from './${toValidIdentifier
|
|
|
3788
3842
|
* @returns useQuery result with data of type ${returnType}
|
|
3789
3843
|
*/
|
|
3790
3844
|
export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join(", ")}, ` : ""}options?: ${optionsType}) {
|
|
3791
|
-
const [searchParams
|
|
3845
|
+
const [searchParams] = useQueryStates(searchParamsParser)
|
|
3792
3846
|
const { initialData, ...restOptions } = options ?? {}
|
|
3793
3847
|
|
|
3794
3848
|
return useQuery({
|
|
3795
3849
|
queryKey: [...${queryKey}, searchParams],
|
|
3796
|
-
queryFn:
|
|
3850
|
+
queryFn: async ({ signal }: { signal?: AbortSignal }) => {
|
|
3797
3851
|
try {
|
|
3798
3852
|
const result = await ${actionName}(${actionCallParams.replace(queryParamObject, "{ ...searchParams }")})
|
|
3799
3853
|
return result
|
|
3800
3854
|
} catch (error) {
|
|
3801
3855
|
handleActionError(error)
|
|
3802
3856
|
}
|
|
3803
|
-
},
|
|
3857
|
+
},
|
|
3804
3858
|
staleTime: ${staleTime},
|
|
3805
3859
|
gcTime: ${staleTime * 2}, // React Query v5: gcTime replaces cacheTime
|
|
3806
3860
|
enabled: ${enabledCondition} && (options?.enabled ?? true),
|
|
@@ -3832,14 +3886,14 @@ export function ${hookName.replace("use", "useInfinite")}(${parameterTypes.lengt
|
|
|
3832
3886
|
|
|
3833
3887
|
return useInfiniteQuery({
|
|
3834
3888
|
queryKey: [...${queryKey}, 'infinite', searchParams],
|
|
3835
|
-
queryFn:
|
|
3889
|
+
queryFn: async ({ pageParam = 1, signal }: { pageParam?: number; signal?: AbortSignal }) => {
|
|
3836
3890
|
try {
|
|
3837
3891
|
const result = await ${actionName}(${actionCallParams.replace(queryParamObject, "{ ...searchParams, page: pageParam, limit: searchParams.limit }")})
|
|
3838
3892
|
return result
|
|
3839
3893
|
} catch (error) {
|
|
3840
3894
|
handleActionError(error)
|
|
3841
3895
|
}
|
|
3842
|
-
},
|
|
3896
|
+
},
|
|
3843
3897
|
getNextPageParam: (lastPage: ${returnType}, allPages: ${returnType}[]) => {
|
|
3844
3898
|
if (lastPage?.hasMore || (Array.isArray(lastPage) && lastPage.length === searchParams.limit)) {
|
|
3845
3899
|
return allPages.length + 1
|
|
@@ -3869,10 +3923,10 @@ export function ${hookName.replace("use", "useSuspense")}(${parameterTypes.lengt
|
|
|
3869
3923
|
|
|
3870
3924
|
return useSuspenseQuery({
|
|
3871
3925
|
queryKey: ${queryKey},
|
|
3872
|
-
queryFn:
|
|
3926
|
+
queryFn: async () => {
|
|
3873
3927
|
const result = await ${actionName}(${actionCallParams})
|
|
3874
3928
|
return result
|
|
3875
|
-
},
|
|
3929
|
+
},
|
|
3876
3930
|
staleTime: ${staleTime},
|
|
3877
3931
|
initialData: initialData as ${returnType} | undefined,
|
|
3878
3932
|
...restOptions
|
|
@@ -3889,14 +3943,14 @@ export function ${hookName}(${parameterTypes.length > 0 ? `${parameterTypes.join
|
|
|
3889
3943
|
|
|
3890
3944
|
return useQuery({
|
|
3891
3945
|
queryKey: ${queryKey},
|
|
3892
|
-
queryFn:
|
|
3946
|
+
queryFn: async ({ signal }: { signal?: AbortSignal }) => {
|
|
3893
3947
|
try {
|
|
3894
3948
|
const result = await ${actionName}(${actionCallParams})
|
|
3895
3949
|
return result
|
|
3896
3950
|
} catch (error) {
|
|
3897
3951
|
handleActionError(error)
|
|
3898
3952
|
}
|
|
3899
|
-
},
|
|
3953
|
+
},
|
|
3900
3954
|
staleTime: ${staleTime},
|
|
3901
3955
|
gcTime: ${staleTime * 2}, // React Query v5: gcTime replaces cacheTime
|
|
3902
3956
|
enabled: ${enabledCondition} && (options?.enabled ?? true),
|
|
@@ -3927,10 +3981,10 @@ export function ${hookName.replace("use", "useSuspense")}(${parameterTypes.lengt
|
|
|
3927
3981
|
|
|
3928
3982
|
return useSuspenseQuery({
|
|
3929
3983
|
queryKey: ${queryKey},
|
|
3930
|
-
queryFn:
|
|
3984
|
+
queryFn: async () => {
|
|
3931
3985
|
const result = await ${actionName}(${actionCallParams})
|
|
3932
3986
|
return result
|
|
3933
|
-
},
|
|
3987
|
+
},
|
|
3934
3988
|
staleTime: ${staleTime},
|
|
3935
3989
|
initialData: initialData as ${returnType} | undefined,
|
|
3936
3990
|
...restOptions
|
|
@@ -3963,8 +4017,6 @@ export function ${hookName.replace("use", "useSuspense")}(${parameterTypes.lengt
|
|
|
3963
4017
|
const relatedQueries = this.findRelatedQueries(endpoint, context);
|
|
3964
4018
|
const invalidationCode = this.buildInvalidationCode(endpoint, relatedQueries, invalidationTags);
|
|
3965
4019
|
const cancelQueriesCode = this.buildCancelQueriesCode(endpoint, relatedQueries);
|
|
3966
|
-
const snapshotCode = this.buildSnapshotCode(endpoint, relatedQueries);
|
|
3967
|
-
const rollbackCode = this.buildRollbackCode(endpoint, relatedQueries);
|
|
3968
4020
|
return `/**
|
|
3969
4021
|
* Optimized mutation hook for ${endpoint.method} ${endpoint.path}
|
|
3970
4022
|
* Features: Optimistic updates, smart invalidation, error handling
|
|
@@ -3985,7 +4037,7 @@ export function ${hookName}(options?: {
|
|
|
3985
4037
|
mutationFn: async (variables: ${inputType}): Promise<${outputType}> => {
|
|
3986
4038
|
try {
|
|
3987
4039
|
const result = await ${actionName}(${variablesParam === "undefined" ? "" : "variables"})
|
|
3988
|
-
return result
|
|
4040
|
+
return (result ?? ({} as ${outputType}))
|
|
3989
4041
|
} catch (error) {
|
|
3990
4042
|
handleActionError(error)
|
|
3991
4043
|
}
|
|
@@ -3993,16 +4045,14 @@ export function ${hookName}(options?: {
|
|
|
3993
4045
|
|
|
3994
4046
|
onMutate: async (variables: ${inputType}) => {
|
|
3995
4047
|
${cancelQueriesCode}
|
|
3996
|
-
|
|
3997
|
-
${snapshotCode}
|
|
3998
|
-
|
|
4048
|
+
|
|
3999
4049
|
// Optimistic update (if provided)
|
|
4000
4050
|
if (options?.optimisticUpdate) {
|
|
4001
4051
|
const optimisticValue = options.optimisticUpdate(variables)
|
|
4002
4052
|
setOptimisticData(optimisticValue)
|
|
4003
4053
|
}
|
|
4004
4054
|
|
|
4005
|
-
return {
|
|
4055
|
+
return {}
|
|
4006
4056
|
},
|
|
4007
4057
|
|
|
4008
4058
|
onSuccess: (data, variables) => {
|
|
@@ -4011,17 +4061,11 @@ ${snapshotCode}
|
|
|
4011
4061
|
toast.success('${this.getSuccessMessage(endpoint)}')
|
|
4012
4062
|
}
|
|
4013
4063
|
|
|
4014
|
-
// Invalidate and refetch related queries
|
|
4015
|
-
${invalidationCode}
|
|
4016
|
-
|
|
4017
4064
|
// Custom success handler
|
|
4018
4065
|
options?.onSuccess?.(data, variables)
|
|
4019
4066
|
},
|
|
4020
4067
|
|
|
4021
|
-
onError: (error: Error, variables: ${inputType}
|
|
4022
|
-
// Rollback optimistic update
|
|
4023
|
-
${rollbackCode}
|
|
4024
|
-
|
|
4068
|
+
onError: (error: Error, variables: ${inputType}) => {
|
|
4025
4069
|
// Show error toast
|
|
4026
4070
|
if (options?.showToast !== false) {
|
|
4027
4071
|
toast.error(error.message || '${this.getErrorMessage(endpoint)}')
|
|
@@ -4031,7 +4075,7 @@ ${rollbackCode}
|
|
|
4031
4075
|
options?.onError?.(error as Error, variables)
|
|
4032
4076
|
},
|
|
4033
4077
|
|
|
4034
|
-
onSettled: () => {
|
|
4078
|
+
onSettled: async () => {
|
|
4035
4079
|
// Always refetch after error or success
|
|
4036
4080
|
${invalidationCode}
|
|
4037
4081
|
}
|
|
@@ -4057,100 +4101,81 @@ ${invalidationCode}
|
|
|
4057
4101
|
return [];
|
|
4058
4102
|
}
|
|
4059
4103
|
const relatedQueries = [];
|
|
4060
|
-
const
|
|
4104
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4061
4105
|
const mutationTag = endpoint.tags[0];
|
|
4062
|
-
const
|
|
4106
|
+
const mutationSegments = this.getResourceSegments(endpoint.path);
|
|
4107
|
+
const mutationResource = mutationSegments[0];
|
|
4063
4108
|
context.schema.endpoints.forEach((queryEndpoint) => {
|
|
4064
4109
|
if (queryEndpoint.method !== "GET") return;
|
|
4065
|
-
const
|
|
4110
|
+
const queryId = queryEndpoint.operationId || queryEndpoint.id;
|
|
4111
|
+
if (seen.has(queryId)) return;
|
|
4066
4112
|
const queryTag = queryEndpoint.tags[0];
|
|
4067
|
-
|
|
4113
|
+
const querySegments = this.getResourceSegments(queryEndpoint.path);
|
|
4114
|
+
const queryResource = querySegments[0];
|
|
4115
|
+
if (mutationTag && queryTag === mutationTag) {
|
|
4068
4116
|
relatedQueries.push(queryEndpoint);
|
|
4117
|
+
seen.add(queryId);
|
|
4069
4118
|
return;
|
|
4070
4119
|
}
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
if (baseMatch) {
|
|
4075
|
-
relatedQueries.push(queryEndpoint);
|
|
4076
|
-
}
|
|
4120
|
+
if (mutationResource && queryResource && mutationResource === queryResource) {
|
|
4121
|
+
relatedQueries.push(queryEndpoint);
|
|
4122
|
+
seen.add(queryId);
|
|
4077
4123
|
}
|
|
4078
4124
|
});
|
|
4079
4125
|
return relatedQueries;
|
|
4080
4126
|
}
|
|
4127
|
+
getResourceSegments(path3) {
|
|
4128
|
+
return path3.split("/").filter(Boolean).filter((segment) => segment.toLowerCase() !== "api" && !/^v\d+/i.test(segment));
|
|
4129
|
+
}
|
|
4081
4130
|
/**
|
|
4082
4131
|
* Build invalidation code for related queries
|
|
4083
4132
|
*/
|
|
4084
4133
|
buildInvalidationCode(endpoint, relatedQueries, invalidationTags) {
|
|
4085
|
-
const invalidations =
|
|
4134
|
+
const invalidations = /* @__PURE__ */ new Set();
|
|
4086
4135
|
relatedQueries.forEach((queryEndpoint) => {
|
|
4087
|
-
const
|
|
4088
|
-
invalidations.
|
|
4136
|
+
const queryKeyPrefix = toActionName(queryEndpoint.operationId || queryEndpoint.id);
|
|
4137
|
+
invalidations.add(`queryClient.invalidateQueries({ queryKey: ['${queryKeyPrefix}'] })`);
|
|
4089
4138
|
});
|
|
4090
4139
|
invalidationTags.forEach((tag) => {
|
|
4091
|
-
|
|
4092
|
-
invalidations.push(` queryClient.invalidateQueries({ queryKey: ['${tag}'] })`);
|
|
4093
|
-
}
|
|
4140
|
+
invalidations.add(`queryClient.invalidateQueries({ queryKey: ['${tag}'] })`);
|
|
4094
4141
|
});
|
|
4095
|
-
if (invalidations.
|
|
4142
|
+
if (invalidations.size === 0) {
|
|
4096
4143
|
const inferredKey = this.inferQueryKeyFromPath(endpoint);
|
|
4097
4144
|
if (inferredKey) {
|
|
4098
|
-
invalidations.
|
|
4145
|
+
invalidations.add(`queryClient.invalidateQueries({ queryKey: ${inferredKey} })`);
|
|
4099
4146
|
}
|
|
4100
4147
|
}
|
|
4101
|
-
|
|
4148
|
+
if (invalidations.size === 0) {
|
|
4149
|
+
return " // No specific cache invalidation needed";
|
|
4150
|
+
}
|
|
4151
|
+
if (invalidations.size === 1) {
|
|
4152
|
+
const [statement] = Array.from(invalidations);
|
|
4153
|
+
return ` await ${statement}`;
|
|
4154
|
+
}
|
|
4155
|
+
return ` await Promise.all([
|
|
4156
|
+
${Array.from(invalidations).join(",\n ")}
|
|
4157
|
+
])`;
|
|
4102
4158
|
}
|
|
4103
4159
|
/**
|
|
4104
4160
|
* Build cancel queries code
|
|
4105
4161
|
* Uses query key patterns to cancel all related queries regardless of parameters
|
|
4106
4162
|
*/
|
|
4107
4163
|
buildCancelQueriesCode(endpoint, relatedQueries) {
|
|
4108
|
-
const cancels =
|
|
4164
|
+
const cancels = /* @__PURE__ */ new Set();
|
|
4109
4165
|
relatedQueries.forEach((queryEndpoint) => {
|
|
4110
|
-
const queryKeyPrefix =
|
|
4111
|
-
cancels.
|
|
4166
|
+
const queryKeyPrefix = toActionName(queryEndpoint.operationId || queryEndpoint.id);
|
|
4167
|
+
cancels.add(`queryClient.cancelQueries({ queryKey: ['${queryKeyPrefix}'] })`);
|
|
4112
4168
|
});
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
/**
|
|
4116
|
-
* Build snapshot code for rollback
|
|
4117
|
-
* Note: We can't snapshot specific queries with parameters in onMutate scope
|
|
4118
|
-
* Instead, we'll invalidate all related queries on error
|
|
4119
|
-
*/
|
|
4120
|
-
buildSnapshotCode(endpoint, relatedQueries) {
|
|
4121
|
-
if (relatedQueries.length === 0) {
|
|
4122
|
-
return " // No queries to snapshot";
|
|
4123
|
-
}
|
|
4124
|
-
return " // Snapshot handled via query invalidation";
|
|
4125
|
-
}
|
|
4126
|
-
/**
|
|
4127
|
-
* Build rollback code
|
|
4128
|
-
*/
|
|
4129
|
-
buildRollbackCode(endpoint, relatedQueries) {
|
|
4130
|
-
if (relatedQueries.length === 0) {
|
|
4131
|
-
return " // No queries to rollback";
|
|
4169
|
+
if (cancels.size === 0) {
|
|
4170
|
+
return " // No queries to cancel";
|
|
4132
4171
|
}
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
const varName = `previous${this.toPascalCase(toActionName(queryEndpoint.operationId || queryEndpoint.id))}`;
|
|
4137
|
-
rollbacks.push(` if (context?.${varName}) {
|
|
4138
|
-
queryClient.setQueryData(${queryKey}, context.${varName})
|
|
4139
|
-
}`);
|
|
4140
|
-
});
|
|
4141
|
-
return rollbacks.join("\n");
|
|
4142
|
-
}
|
|
4143
|
-
/**
|
|
4144
|
-
* Get snapshot return names for context
|
|
4145
|
-
*/
|
|
4146
|
-
getSnapshotReturnNames(relatedQueries) {
|
|
4147
|
-
if (relatedQueries.length === 0) {
|
|
4148
|
-
return "previousData: null";
|
|
4172
|
+
if (cancels.size === 1) {
|
|
4173
|
+
const [statement] = Array.from(cancels);
|
|
4174
|
+
return ` await ${statement}`;
|
|
4149
4175
|
}
|
|
4150
|
-
return
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
}).join(", ");
|
|
4176
|
+
return ` await Promise.all([
|
|
4177
|
+
${Array.from(cancels).join(",\n ")}
|
|
4178
|
+
])`;
|
|
4154
4179
|
}
|
|
4155
4180
|
/**
|
|
4156
4181
|
* Infer query key from mutation path
|
|
@@ -9400,7 +9425,8 @@ var bridgeConfigSchema = zod.z.object({
|
|
|
9400
9425
|
logging: zod.z.boolean().default(true),
|
|
9401
9426
|
validation: zod.z.boolean().default(true),
|
|
9402
9427
|
mocking: zod.z.boolean().default(false),
|
|
9403
|
-
watch: zod.z.boolean().default(false)
|
|
9428
|
+
watch: zod.z.boolean().default(false),
|
|
9429
|
+
hotReload: zod.z.boolean().default(false)
|
|
9404
9430
|
}).optional(),
|
|
9405
9431
|
plugins: zod.z.array(
|
|
9406
9432
|
zod.z.object({
|
|
@@ -9413,6 +9439,7 @@ var bridgeConfigSchema = zod.z.object({
|
|
|
9413
9439
|
typescript: zod.z.boolean().default(true),
|
|
9414
9440
|
strict: zod.z.boolean().default(true),
|
|
9415
9441
|
comments: zod.z.boolean().default(true),
|
|
9442
|
+
documentation: zod.z.boolean().default(true),
|
|
9416
9443
|
examples: zod.z.boolean().default(false),
|
|
9417
9444
|
tests: zod.z.boolean().default(false)
|
|
9418
9445
|
}).optional()
|
|
@@ -9518,12 +9545,14 @@ ${errorMessages}`,
|
|
|
9518
9545
|
logging: true,
|
|
9519
9546
|
validation: true,
|
|
9520
9547
|
mocking: false,
|
|
9521
|
-
watch: false
|
|
9548
|
+
watch: false,
|
|
9549
|
+
hotReload: false
|
|
9522
9550
|
},
|
|
9523
9551
|
generation: {
|
|
9524
9552
|
typescript: true,
|
|
9525
9553
|
strict: true,
|
|
9526
9554
|
comments: true,
|
|
9555
|
+
documentation: true,
|
|
9527
9556
|
examples: false,
|
|
9528
9557
|
tests: false
|
|
9529
9558
|
}
|
|
@@ -9590,5 +9619,5 @@ exports.VersionChecker = VersionChecker;
|
|
|
9590
9619
|
exports.__name = __name;
|
|
9591
9620
|
exports.checkAndNotifyUpdates = checkAndNotifyUpdates;
|
|
9592
9621
|
exports.createBridgeVersionChecker = createBridgeVersionChecker;
|
|
9593
|
-
//# sourceMappingURL=chunk-
|
|
9594
|
-
//# sourceMappingURL=chunk-
|
|
9622
|
+
//# sourceMappingURL=chunk-OOY4PCDK.cjs.map
|
|
9623
|
+
//# sourceMappingURL=chunk-OOY4PCDK.cjs.map
|