schemock 0.0.4-alpha.14 → 0.0.4-alpha.16
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/cli/index.js +65 -23
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +65 -23
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli.js +65 -23
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -3118,6 +3118,7 @@ function generateEndpointHandlers(endpoints) {
|
|
|
3118
3118
|
function generateHandler(code, endpoint) {
|
|
3119
3119
|
const { name, method, path, params, body, pathParams } = endpoint;
|
|
3120
3120
|
const httpMethod = method.toLowerCase();
|
|
3121
|
+
const hasBody = body.length > 0;
|
|
3121
3122
|
code.comment(`${method} ${path}`);
|
|
3122
3123
|
code.block(`http.${httpMethod}('${path}', async ({ request, params: pathParams }) => {`, () => {
|
|
3123
3124
|
if (method === "GET" && params.length > 0) {
|
|
@@ -3139,20 +3140,21 @@ function generateHandler(code, endpoint) {
|
|
|
3139
3140
|
}
|
|
3140
3141
|
}, "};");
|
|
3141
3142
|
code.line();
|
|
3143
|
+
} else {
|
|
3144
|
+
code.line("const params = {};");
|
|
3145
|
+
code.line();
|
|
3142
3146
|
}
|
|
3143
|
-
if (
|
|
3147
|
+
if (hasBody) {
|
|
3144
3148
|
code.line("const body = await request.json();");
|
|
3145
|
-
|
|
3149
|
+
} else {
|
|
3150
|
+
code.line("const body = {};");
|
|
3146
3151
|
}
|
|
3147
|
-
|
|
3148
|
-
if (params.length > 0 || pathParams.length > 0) ctxParts.push("params");
|
|
3149
|
-
if (body.length > 0) ctxParts.push("body");
|
|
3152
|
+
code.line();
|
|
3150
3153
|
code.line("const headers: Record<string, string> = {};");
|
|
3151
3154
|
code.line("request.headers.forEach((value, key) => { headers[key] = value; });");
|
|
3152
|
-
ctxParts.push("headers");
|
|
3153
3155
|
code.line();
|
|
3154
3156
|
code.block("try {", () => {
|
|
3155
|
-
code.line(`const result = await endpointResolvers.${name}({
|
|
3157
|
+
code.line(`const result = await endpointResolvers.${name}({ db, params, body, headers });`);
|
|
3156
3158
|
code.line("return HttpResponse.json(result);");
|
|
3157
3159
|
}, "} catch (error) {");
|
|
3158
3160
|
code.indent();
|
|
@@ -3197,15 +3199,24 @@ function generateEndpointResolvers(endpoints, outputDir) {
|
|
|
3197
3199
|
code.comment("consider using named exported functions instead - they will be automatically imported.");
|
|
3198
3200
|
code.line();
|
|
3199
3201
|
code.line("import type { Database } from './db';");
|
|
3202
|
+
code.line("import type * as Types from './types';");
|
|
3200
3203
|
code.line();
|
|
3201
|
-
code.comment("
|
|
3202
|
-
code.block("export interface ResolverContext {", () => {
|
|
3203
|
-
code.line("params:
|
|
3204
|
-
code.line("body:
|
|
3204
|
+
code.comment("Base resolver context with typed database access");
|
|
3205
|
+
code.block("export interface ResolverContext<TParams = Record<string, unknown>, TBody = Record<string, unknown>> {", () => {
|
|
3206
|
+
code.line("params: TParams;");
|
|
3207
|
+
code.line("body: TBody;");
|
|
3205
3208
|
code.line("db: Database;");
|
|
3206
3209
|
code.line("headers: Record<string, string>;");
|
|
3207
3210
|
});
|
|
3208
3211
|
code.line();
|
|
3212
|
+
code.comment("Per-endpoint typed resolver contexts");
|
|
3213
|
+
for (const endpoint of endpoints) {
|
|
3214
|
+
const { pascalName, params, body } = endpoint;
|
|
3215
|
+
const paramsType = params.length > 0 ? `Types.${pascalName}Params` : "Record<string, never>";
|
|
3216
|
+
const bodyType = body.length > 0 ? `Types.${pascalName}Body` : "Record<string, never>";
|
|
3217
|
+
code.line(`export type ${pascalName}ResolverContext = ResolverContext<${paramsType}, ${bodyType}>;`);
|
|
3218
|
+
}
|
|
3219
|
+
code.line();
|
|
3209
3220
|
code.comment("Error class for HTTP errors in resolvers");
|
|
3210
3221
|
code.block("export class HttpError extends Error {", () => {
|
|
3211
3222
|
code.line("readonly status: number;");
|
|
@@ -3237,7 +3248,8 @@ function generateEndpointResolvers(endpoints, outputDir) {
|
|
|
3237
3248
|
if (!inlineDependencies.has(key)) {
|
|
3238
3249
|
inlineDependencies.set(key, {
|
|
3239
3250
|
name: dep.name,
|
|
3240
|
-
importPath: dep.from
|
|
3251
|
+
importPath: dep.from,
|
|
3252
|
+
sourceFile: endpoint.sourceFile
|
|
3241
3253
|
});
|
|
3242
3254
|
}
|
|
3243
3255
|
}
|
|
@@ -3280,33 +3292,63 @@ function generateEndpointResolvers(endpoints, outputDir) {
|
|
|
3280
3292
|
if (inlineDependencies.size > 0) {
|
|
3281
3293
|
code.line();
|
|
3282
3294
|
code.comment("Dependencies used by inline resolvers");
|
|
3283
|
-
const
|
|
3284
|
-
for (const { name, importPath } of inlineDependencies.values()) {
|
|
3285
|
-
|
|
3286
|
-
|
|
3295
|
+
const importsByResolvedPath = /* @__PURE__ */ new Map();
|
|
3296
|
+
for (const { name, importPath, sourceFile } of inlineDependencies.values()) {
|
|
3297
|
+
let resolvedPath = importPath;
|
|
3298
|
+
if (importPath.startsWith(".") && sourceFile && outputDir) {
|
|
3299
|
+
const toPosix = (p) => p.replace(/\\/g, "/");
|
|
3300
|
+
const sourceDir = toPosix(sourceFile).replace(/\/[^/]+$/, "");
|
|
3301
|
+
const parts = sourceDir.split("/").filter(Boolean);
|
|
3302
|
+
const importParts = importPath.split("/");
|
|
3303
|
+
for (const part of importParts) {
|
|
3304
|
+
if (part === "..") {
|
|
3305
|
+
parts.pop();
|
|
3306
|
+
} else if (part !== ".") {
|
|
3307
|
+
parts.push(part);
|
|
3308
|
+
}
|
|
3309
|
+
}
|
|
3310
|
+
const absolutePath = "/" + parts.join("/");
|
|
3311
|
+
resolvedPath = calculateRelativePath(absolutePath);
|
|
3312
|
+
}
|
|
3313
|
+
if (!importsByResolvedPath.has(resolvedPath)) {
|
|
3314
|
+
importsByResolvedPath.set(resolvedPath, []);
|
|
3287
3315
|
}
|
|
3288
|
-
const names =
|
|
3316
|
+
const names = importsByResolvedPath.get(resolvedPath);
|
|
3289
3317
|
if (!names.includes(name)) {
|
|
3290
3318
|
names.push(name);
|
|
3291
3319
|
}
|
|
3292
3320
|
}
|
|
3293
|
-
for (const [
|
|
3294
|
-
code.line(`import { ${names.join(", ")} } from '${
|
|
3321
|
+
for (const [resolvedPath, names] of importsByResolvedPath) {
|
|
3322
|
+
code.line(`import { ${names.join(", ")} } from '${resolvedPath}';`);
|
|
3295
3323
|
}
|
|
3296
3324
|
}
|
|
3297
3325
|
code.line();
|
|
3298
|
-
code.
|
|
3326
|
+
code.comment("Typed resolver function types");
|
|
3327
|
+
for (const endpoint of endpoints) {
|
|
3328
|
+
const { pascalName } = endpoint;
|
|
3329
|
+
code.line(
|
|
3330
|
+
`type ${pascalName}ResolverFn = (ctx: ${pascalName}ResolverContext) => Types.${pascalName}Response | Promise<Types.${pascalName}Response>;`
|
|
3331
|
+
);
|
|
3332
|
+
}
|
|
3333
|
+
code.line();
|
|
3334
|
+
code.comment("Typed endpoint resolvers interface");
|
|
3335
|
+
code.block("export interface EndpointResolvers {", () => {
|
|
3336
|
+
for (const endpoint of endpoints) {
|
|
3337
|
+
const { name, pascalName } = endpoint;
|
|
3338
|
+
code.line(`${name}: ${pascalName}ResolverFn;`);
|
|
3339
|
+
}
|
|
3340
|
+
});
|
|
3299
3341
|
code.line();
|
|
3300
|
-
code.block("export const endpointResolvers:
|
|
3342
|
+
code.block("export const endpointResolvers: EndpointResolvers = {", () => {
|
|
3301
3343
|
for (const endpoint of endpoints) {
|
|
3302
3344
|
code.comment(`${endpoint.method} ${endpoint.path}`);
|
|
3303
3345
|
if (endpoint.description) {
|
|
3304
3346
|
code.comment(endpoint.description);
|
|
3305
3347
|
}
|
|
3306
3348
|
if (endpoint.mockResolverName) {
|
|
3307
|
-
code.line(`${endpoint.name}: ${endpoint.mockResolverName},`);
|
|
3349
|
+
code.line(`${endpoint.name}: ${endpoint.mockResolverName} as ${endpoint.pascalName}ResolverFn,`);
|
|
3308
3350
|
} else {
|
|
3309
|
-
code.line(`${endpoint.name}: ${endpoint.mockResolverSource},`);
|
|
3351
|
+
code.line(`${endpoint.name}: (${endpoint.mockResolverSource}) as ${endpoint.pascalName}ResolverFn,`);
|
|
3310
3352
|
}
|
|
3311
3353
|
code.line();
|
|
3312
3354
|
}
|