"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.generator = exports.generatorId = void 0;
const path = __importStar(require("node:path"));
const Generator = __importStar(require("@postxl/generator"));
const backend_core_1 = require("../backend-core");
const backend_view_1 = require("../backend-view");
const base_1 = require("../base");
const decoders_1 = require("../decoders");
const types_1 = require("../types");
const model_controller_generator_1 = require("./generators/model-controller.generator");
const rest_api_module_generator_1 = require("./generators/rest-api-module.generator");
exports.generatorId = Generator.toGeneratorInterfaceId('backend-rest-api');
exports.generator = {
    id: exports.generatorId,
    requires: [backend_core_1.backendGeneratorId, base_1.baseGeneratorId, types_1.typesGeneratorId, backend_view_1.backendViewGeneratorId, decoders_1.decodersGeneratorId],
    register: (context) => {
        context.backend.packageJson.dependencies.push({ packageName: '@fastify/static', version: '^8.2.0' }, { packageName: '@nestjs/swagger', version: '^11.2.0' }, { packageName: 'nestjs-zod', version: '^5.0.1' });
        const module = {
            name: Generator.toClassName('RestApiModule'),
            location: Generator.toBackendModuleLocation('@restApi/restApi.module'),
        };
        const restApiModule = {
            name: Generator.toBackendModuleName('restApi'),
            moduleClass: module,
            apiModuleRegistration: {
                import: Generator.ts(`
import { APP_FILTER, APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core'
import { ZodSerializerInterceptor, ZodValidationPipe } from 'nestjs-zod'
import { ZodExceptionFilter } from '@restApi/zod-exception.filter'
`),
                code: Generator.ts('RestApiModule.forRoot()'),
                provider: [
                    Generator.ts('{ provide: APP_PIPE, useClass: ZodValidationPipe }'),
                    Generator.ts('{ provide: APP_INTERCEPTOR, useClass: ZodSerializerInterceptor }'),
                    Generator.ts('{ provide: APP_FILTER, useClass: ZodExceptionFilter }'),
                ],
            },
            bootStrap: {
                import: Generator.ts("import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'\nimport { cleanupOpenApiDoc } from 'nestjs-zod'"),
                code: Generator.ts(`const openApiDoc = SwaggerModule.createDocument(\n    app,\n    new DocumentBuilder().setTitle('${context.schema.name} REST API').setVersion('1.0').build(),\n  )\n\n  SwaggerModule.setup('openApi', app, cleanupOpenApiDoc(openApiDoc))`),
            },
        };
        const models = new Map();
        for (const [modelName, model] of context.models) {
            models.set(modelName, registerModel(model));
        }
        context.backend.modules.push(restApiModule);
        const restApi = { module };
        return { ...context, restApi, models };
    },
    generate: async (context) => {
        const vfsLibSrc = new Generator.VirtualFileSystem();
        for (const model of context.models.values()) {
            vfsLibSrc.write(model.restApi.controller._filePath, (0, model_controller_generator_1.generateModelController)({ model, context }));
        }
        vfsLibSrc.write(Generator.toLocalFile(context.restApi.module), (0, rest_api_module_generator_1.generateRestApiModule)(context));
        const vfsLib = new Generator.VirtualFileSystem();
        vfsLib.insertFromVfs({ targetPath: 'src', vfs: vfsLibSrc });
        vfsLib.write('/tsconfig.lib.json', Generator.generateTsConfig('restApi'));
        const vfs = new Generator.VirtualFileSystem();
        vfs.insertFromVfs({ targetPath: 'libs/restApi', vfs: vfsLib });
        // Load static template file
        await vfs.loadFile({
            diskPath: path.resolve(__dirname, './template/zod-exception.filter.ts'),
            targetPath: 'libs/restApi/src/zod-exception.filter.ts',
        });
        context.vfs.insertFromVfs({ targetPath: '/backend', vfs });
        return context;
    },
};
function registerModel(model) {
    const controller = {
        name: Generator.toClassName(`${model._conjugated.PascalCase}Controller`),
        location: Generator.toBackendModuleLocation(`@restApi/${model._conjugated.camelCase}.controller`),
        _filePath: Generator.toFilePath(`./${model._conjugated.camelCase}.controller.ts`),
    };
    return { ...model, restApi: { controller } };
}
//# sourceMappingURL=rest-api.generator.js.map