UNPKG

mongoose-tsgen

Version:

A Typescript interface generator for Mongoose that works out of the box.

142 lines (141 loc) 6.85 kB
"use strict"; const tslib_1 = require("tslib"); const core_1 = require("@oclif/core"); const tsReader = (0, tslib_1.__importStar)(require("./helpers/tsReader")); const paths = (0, tslib_1.__importStar)(require("./helpers/paths")); const formatter = (0, tslib_1.__importStar)(require("./helpers/formatter")); const generator = (0, tslib_1.__importStar)(require("./helpers/generator")); const cli = (0, tslib_1.__importStar)(require("./helpers/cli")); const utils_1 = require("./parser/utils"); class MongooseTsgen extends core_1.Command { constructor(argv = [], config = new core_1.Config({ root: __dirname })) { super(argv, config); } async getConfig(customConfig) { var _a, _b, _c, _d; const configFileFlags = paths.getConfigFromFile(customConfig.flags.config); return { flags: { ...configFileFlags, ...customConfig.flags, // We dont need the config field anymore now that we've merged the config file here config: undefined, // we cant set flags as `default` using the official oclif method since the defaults would overwrite flags provided in the config file. // instead, well just set "output" and "project" as default manually if theyre still missing after merge with configFile. output: (_b = (_a = configFileFlags === null || configFileFlags === void 0 ? void 0 : configFileFlags.output) !== null && _a !== void 0 ? _a : customConfig.flags.output) !== null && _b !== void 0 ? _b : "./src/interfaces", project: (_d = (_c = configFileFlags === null || configFileFlags === void 0 ? void 0 : configFileFlags.project) !== null && _c !== void 0 ? _c : customConfig.flags.project) !== null && _d !== void 0 ? _d : "./" }, args: { ...configFileFlags, ...customConfig.args } }; } async run() { const customConfig = await this.parse(MongooseTsgen); try { await this.generateDefinitions(customConfig); } catch (error) { this.error(error, { exit: 1 }); } } async generateDefinitions(customConfig) { core_1.ux.action.start("Generating mongoose typescript definitions"); const { flags, args } = await this.getConfig(customConfig); if (flags.debug) { this.log("Debug mode enabled"); process.env.DEBUG = "1"; } const modelsPaths = paths.getModelsPaths(args.model_path); const cleanupTs = tsReader.registerUserTs(flags.project); const generatedFilePath = paths.cleanOutputPath(flags.output); let sourceFile = generator.createSourceFile(generatedFilePath); const noMongoose = flags["no-mongoose"]; const datesAsStrings = flags["dates-as-strings"]; sourceFile = generator.generateTypes({ modelsPaths, sourceFile, imports: flags.imports, noMongoose, datesAsStrings }); const modelTypes = tsReader.getModelTypes(modelsPaths); const models = (0, utils_1.loadModels)(modelsPaths); generator.replaceModelTypes(sourceFile, modelTypes, models); // only get model types (methods, statics, queries & virtuals) if user does not specify `noMongoose`, if (noMongoose) { this.log("Skipping TS model parsing and sourceFile model type replacement"); } else { // add populate helpers await generator.addPopulateHelpers(sourceFile); // add mongoose.Query.populate overloads if (!flags["no-populate-overload"]) { await generator.overloadQueryPopulate(sourceFile); } } cleanupTs === null || cleanupTs === void 0 ? void 0 : cleanupTs(); if (flags["dry-run"]) { this.log("Dry run detected, generated interfaces will be printed to console:\n"); this.log(sourceFile.getFullText()); } else { this.log(`Writing interfaces to ${generatedFilePath}`); generator.saveFile({ generatedFilePath, sourceFile }); if (!flags["no-format"]) await formatter.format([generatedFilePath]); this.log("Writing complete 🐒"); } core_1.ux.action.stop(); return { generatedFilePath, sourceFile }; } } MongooseTsgen.id = "."; MongooseTsgen.description = "Generate a Typescript file containing Mongoose Schema typings.\nSpecify the directory of your Mongoose model definitions using `MODEL_PATH`. If left blank, all sub-directories will be searched for `models/*.ts` (ignores `index.ts` files). Files found are expected to export a Mongoose model."; MongooseTsgen.flags = { config: core_1.Flags.string({ char: "c", description: "[default: ./] Path of `mtgen.config.json` or its root folder. CLI flag options will take precendence over settings in `mtgen.config.json`." }), "dry-run": core_1.Flags.boolean({ char: "d", description: "Print output rather than writing to file." }), help: cli.helpFlag({ char: "h" }), imports: core_1.Flags.string({ char: "i", description: "Custom import statements to add to the output file. Useful if you use third-party types in your mongoose schema definitions. For multiple imports, specify this flag more than once.", multiple: true }), "no-format": core_1.Flags.boolean({ description: "Disable formatting generated files with prettier." }), output: core_1.Flags.string({ char: "o", description: "[default: ./src/interfaces] Path of output file to write generated typings. If a folder path is passed, the generator will create a `mongoose.gen.ts` file in the specified folder." }), project: core_1.Flags.string({ char: "p", description: "[default: ./] Path of `tsconfig.json` or its root folder." }), debug: core_1.Flags.boolean({ description: "Print debug information if anything isn't working" }), "no-mongoose": core_1.Flags.boolean({ description: "Don't generate types that reference mongoose (i.e. documents). Replace ObjectId with string." }), "dates-as-strings": core_1.Flags.boolean({ description: "Dates will be typed as strings. Useful for types returned to a frontend by API requests." }), "no-populate-overload": core_1.Flags.boolean({ description: "Disable augmenting mongoose with Query.populate overloads (the overloads narrow the return type of populated documents queries)." }) }; // path of mongoose models folder MongooseTsgen.args = { model_path: core_1.Args.string() }; module.exports = MongooseTsgen;