"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 node_path_1 = require("node:path");
const Generator = __importStar(require("@postxl/generator"));
const backend_actions_1 = require("../backend-actions");
const backend_authentication_1 = require("../backend-authentication");
const backend_core_1 = require("../backend-core");
const backend_repositories_1 = require("../backend-repositories");
const backend_update_1 = require("../backend-update");
const backend_view_1 = require("../backend-view");
const base_1 = require("../base");
const types_1 = require("../types");
const app_routes_generator_1 = require("./generators/app-routes.generator");
const audit_log_route_generator_1 = require("./generators/audit-log-route.generator");
const middleware_generator_1 = require("./generators/middleware.generator");
const model_routes_generator_1 = require("./generators/model-routes.generator");
const trpc_plugin_generator_1 = require("./generators/trpc-plugin.generator");
const trpc_router_module_generator_1 = require("./generators/trpc-router-module.generator");
const trpc_shared_generator_1 = require("./generators/trpc-shared.generator");
const packageVersions = {
    trpc: '11.7.1',
    superJSON: '1.13.1',
};
exports.generatorId = Generator.toGeneratorInterfaceId('backend-router-trpc');
exports.generator = {
    id: exports.generatorId,
    requires: [
        backend_core_1.backendGeneratorId,
        base_1.baseGeneratorId,
        types_1.typesGeneratorId,
        backend_actions_1.backendActionsGeneratorId,
        backend_repositories_1.backendRepositoriesGeneratorId,
        backend_view_1.backendViewGeneratorId,
        backend_update_1.backendUpdateGeneratorId,
        backend_authentication_1.backendAuthenticationGeneratorId,
    ],
    register: (context) => {
        const moduleName = Generator.toBackendModuleName('router-trpc');
        context.backend.packageJson.dependencies.push(
        // Register backend module
        { packageName: '@trpc/server', version: packageVersions.trpc }, 
        // Do not upgrade to 2.x, as it requires ESM and NestJS does not support it yet.
        { packageName: 'superjson', version: packageVersions.superJSON });
        const module = {
            name: Generator.toClassName('RouterTrpcModule'),
            location: Generator.toBackendModuleLocation(`@router-trpc/router-trpc.module`),
        };
        const routerModule = {
            name: moduleName,
            moduleClass: module,
            bootStrap: {
                import: Generator.ts(`import { TrpcPlugin } from '@router-trpc/trpc.plugin'`),
                code: Generator.ts(`await app.get(TrpcPlugin).register(app, {urlPrefix: config.data.urlPrefix})`),
            },
        };
        context.backend.modules.push(routerModule);
        const models = new Map();
        for (const [modelName, model] of context.models) {
            const modelWithRouters = registerModelRouter(model);
            models.set(modelName, modelWithRouters);
        }
        const trpcLocation = Generator.toBackendModuleLocation(`@router-trpc/trpc-shared`);
        const middlewareLocation = Generator.toBackendModuleLocation(`@router-trpc/middleware`);
        const appRoutesLocation = Generator.toBackendModuleLocation(`@router-trpc/routes/app-routes`);
        const trpcRouter = {
            packageVersions,
            module,
            plugin: {
                name: Generator.toClassName('TrpcPlugin'),
                location: Generator.toBackendModuleLocation(`@router-trpc/trpc.plugin`),
                _filePath: Generator.toFilePath(`./trpc.plugin.ts`),
            },
            appRoutes: {
                name: Generator.toConstantName('appRoutes'),
                location: appRoutesLocation,
                _filePath: Generator.toFilePath(`./routes/app-routes.ts`),
                type: {
                    name: Generator.toTypeName('AppRoutes'),
                    location: appRoutesLocation,
                },
            },
            auditLogRoute: {
                name: Generator.toFunctionName('auditLogs'),
                location: Generator.toBackendModuleLocation('@router-trpc/routes/audit-log.route'),
                _filePath: Generator.toFilePath(`./routes/audit-log.route.ts`),
            },
            defaultMethodNames: {
                create: Generator.toFunctionName('create'),
                update: Generator.toFunctionName('update'),
                delete: Generator.toFunctionName('delete'),
            },
            _shared: {
                _filePath: Generator.toFilePath(`./trpc-shared.ts`),
                router: { name: Generator.toFunctionName('router'), location: trpcLocation },
                procedure: { name: Generator.toFunctionName('procedure'), location: trpcLocation },
                middleware: { name: Generator.toFunctionName('middleware'), location: trpcLocation },
                context: { name: Generator.toTypeName('InitialContext'), location: trpcLocation },
            },
            _middleware: {
                _filePath: Generator.toFilePath(`./middleware.ts`),
                auth: {
                    name: Generator.toFunctionName('authMiddleware'),
                    location: middlewareLocation,
                    context: {
                        name: Generator.toTypeName('ContextWithAuth'),
                        location: middlewareLocation,
                    },
                },
                debugLogger: {
                    name: Generator.toFunctionName('debugLogger'),
                    location: middlewareLocation,
                },
            },
        };
        return {
            ...context,
            trpcRouter,
            models,
        };
    },
    generate: async (context) => {
        const vfsSrc = new Generator.VirtualFileSystem();
        vfsSrc.write(Generator.toLocalFile(context.trpcRouter.module), (0, trpc_router_module_generator_1.generateTrpcRouterModule)(context));
        vfsSrc.write(context.trpcRouter.plugin._filePath, (0, trpc_plugin_generator_1.generateTrpc)(context));
        vfsSrc.write(context.trpcRouter.appRoutes._filePath, (0, app_routes_generator_1.generateAppRoutes)({ context }));
        vfsSrc.write(context.trpcRouter._shared._filePath, (0, trpc_shared_generator_1.generateTrpcShared)(context));
        vfsSrc.write(context.trpcRouter._middleware._filePath, (0, middleware_generator_1.generateMiddleware)(context));
        vfsSrc.write(context.trpcRouter.auditLogRoute._filePath, (0, audit_log_route_generator_1.generateAuditLogRoute)({ context }));
        for (const model of context.models.values()) {
            vfsSrc.write(model.trpcRoute._filePath, (0, model_routes_generator_1.generateModelRoutes)({ model, context }));
        }
        const vfs = new Generator.VirtualFileSystem();
        vfs.insertFromVfs({ targetPath: 'src', vfs: vfsSrc });
        vfs.write('/tsconfig.lib.json', Generator.generateTsConfig('router-trpc'));
        await vfs.loadFile({
            diskPath: (0, node_path_1.resolve)(__dirname, './template', 'viewer.router.ts'),
            targetPath: 'src/routes/viewer.router.ts',
        });
        context.vfs.insertFromVfs({ targetPath: 'backend/libs/router-trpc', vfs });
        return context;
    },
};
function registerModelRouter(model) {
    const location = Generator.toBackendModuleLocation(`@router-trpc/routes/${model._conjugated.camelCase}.route`);
    const router = {
        name: Generator.toFunctionName(`${model._conjugated.camelCasePlural}`),
        location,
        _filePath: Generator.toFilePath(`./routes/${model._conjugated.camelCase}.route.ts`),
        get: { name: Generator.toFunctionName(`get`), location },
        getMap: { name: Generator.toFunctionName(`getMap`), location },
        getList: { name: Generator.toFunctionName(`getList`), location },
    };
    return { ...model, trpcRoute: router };
}
//# sourceMappingURL=router-trpc.generator.js.map