UNPKG

@lenne.tech/cli

Version:

lenne.Tech CLI: lt

499 lines (497 loc) 45.6 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Server = void 0; const crypto = require("crypto"); const path_1 = require("path"); /** * Server helper functions */ class Server { /** * Constructor for integration of toolbox */ constructor(toolbox) { this.toolbox = toolbox; // Specific imports for default modells this.imports = { 'CoreFileInfo': 'import { CoreFileInfo } from \'@lenne.tech/nest-server\';', 'FileUpload': 'import type { FileUpload } from \'graphql-upload/processRequest.js\';', 'GraphQLUpload': 'import * as GraphQLUpload from \'graphql-upload/GraphQLUpload.js\';', 'Record<string, unknown>': 'import { JSON } from \'@lenne.tech/nest-server\';', }; // Specific types for properties in input fields this.inputFieldTypes = { Boolean: 'Boolean', Date: 'Date', File: 'GraphQLUpload', FileInfo: 'GraphQLUpload', ID: 'String', Id: 'String', JSON: 'JSON', Json: 'JSON', Number: 'Number', ObjectId: 'String', String: 'String', Upload: 'GraphQLUpload', }; // Specific types for properties in input classes this.inputClassTypes = { Boolean: 'boolean', Date: 'Date', File: 'FileUpload', FileInfo: 'FileUpload', ID: 'string', Id: 'string', JSON: 'Record<string, unknown>', Json: 'Record<string, unknown>', Number: 'number', ObjectId: 'string', String: 'string', Upload: 'FileUpload', }; // Specific types for properties in model fields this.modelFieldTypes = { Boolean: 'Boolean', Date: 'Date', File: 'CoreFileInfo', FileInfo: 'CoreFileInfo', ID: 'String', Id: 'String', JSON: 'JSON', Json: 'JSON', Number: 'Number', ObjectId: 'String', String: 'String', Upload: 'CoreFileInfo', }; // Specific types for properties in model class this.modelClassTypes = { Boolean: 'boolean', Date: 'Date', File: 'CoreFileInfo', FileInfo: 'CoreFileInfo', ID: 'string', Id: 'string', JSON: 'Record<string, unknown>', Json: 'Record<string, unknown>', Number: 'number', ObjectId: 'string', String: 'string', Upload: 'CoreFileInfo', }; // Additional string for ID properties this.propertySuffixTypes = { ID: 'Id', Id: 'Id', ObjectId: 'Id', }; // Standard types: primitives and default JavaScript classes this.standardTypes = ['boolean', 'string', 'number', 'Date']; this.ask = toolbox.prompt.ask; this.camelCase = toolbox.strings.camelCase; this.confirm = toolbox.prompt.confirm; this.filesystem = toolbox.filesystem; this.kebabCase = toolbox.strings.kebabCase; this.pascalCase = toolbox.strings.pascalCase; } /** * Construct the addition for the create.input.ts */ constructCreateInputPatchString(propObj, moduleToEdit) { return `\n /** * ${this.pascalCase(propObj.name)} of ${this.pascalCase(moduleToEdit)} */ @Restricted(RoleEnum.ADMIN) @Field(() => ${propObj.isArray ? `[${propObj.type === 'ObjectId' ? propObj.reference : this.pascalCase(propObj.type)}]` : propObj.type === 'ObjectId' ? propObj.reference : this.pascalCase(propObj.type)}, { description: '${this.pascalCase(propObj.name)} of ${this.pascalCase(moduleToEdit)}', nullable: ${propObj.nullable}, }) ${propObj.nullable ? '@IsOptional()' : ''}${propObj.nullable ? '\n' : ''} override ${propObj.name}${propObj.nullable ? '?' : ''}: ${propObj.isArray ? `${propObj.type === 'ObjectId' ? propObj.reference : this.pascalCase(propObj.type)}[]` : propObj.type === 'ObjectId' ? propObj.reference : this.pascalCase(propObj.type)} = undefined;`; } /** * Construct the Addition for the normal input.ts */ constructInputPatchString(propObj, moduleToEdit) { const fieldType = propObj.isArray ? `[${propObj.type === 'ObjectId' ? propObj.reference : this.pascalCase(propObj.type)}]` : propObj.type === 'ObjectId' ? propObj.reference : this.pascalCase(propObj.type); return `\n /** * ${this.pascalCase(propObj.name)} of ${this.pascalCase(moduleToEdit)} */ @Restricted(RoleEnum.ADMIN) @Field(() => ${fieldType}, { description: '${this.pascalCase(propObj.name)} of ${this.pascalCase(moduleToEdit)}', nullable: ${propObj.nullable}, }) ${propObj.nullable ? '@IsOptional()' : ''}${propObj.nullable ? '\n' : ''} override ${propObj.name}${propObj.nullable ? '?' : ''}: ${propObj.isArray ? `${propObj.type === 'ObjectId' ? propObj.reference : this.pascalCase(propObj.type)}[]` : propObj.type === 'ObjectId' ? propObj.reference : this.pascalCase(propObj.type)} = undefined; `; } /** * Construct the addition for the Model */ constructModelPatchString(propObj, moduleToEdit) { return `\n /** * ${this.pascalCase(propObj.name)} of ${this.pascalCase(moduleToEdit)} */ @Restricted(RoleEnum.ADMIN) @Field(() => ${propObj.isArray ? `[${propObj.type === 'ObjectId' ? propObj.reference : this.pascalCase(propObj.type)}]` : propObj.type === 'ObjectId' ? propObj.reference : this.pascalCase(propObj.type)}, { description: '${this.pascalCase(propObj.name)} of ${this.pascalCase(moduleToEdit)}', nullable: ${propObj.nullable}, }) @Prop(${propObj.type === 'ObjectId' ? `{ ref: ${propObj.reference}, type: Schema.Types.ObjectId }` : ''}) ${propObj.name}: ${propObj.isArray ? `${propObj.type === 'ObjectId' ? propObj.reference : this.pascalCase(propObj.type)}[]` : propObj.type === 'ObjectId' ? propObj.reference : this.pascalCase(propObj.type)} = undefined;`; } /** * Add properties to model */ addProperties(options) { return __awaiter(this, void 0, void 0, function* () { const { objectsToAdd, referencesToAdd } = Object.assign({ objectsToAdd: [], referencesToAdd: [] }, options); // Set props const props = {}; const setProps = true; let refsSet = false; let schemaSet = false; while (setProps) { const name = (yield this.ask({ message: 'Enter property name (e.g. myProperty) of the property or leave empty (ENTER)', name: 'input', type: 'input', })).input; if (!name.trim()) { break; } let type = (yield this.ask([ { choices: ['boolean', 'string', 'number', 'ObjectId / Reference', 'Date', 'enum', 'SubObject', 'Use own', 'JSON / any'], message: 'Choose property type', name: 'input', type: 'select', }, ])).input; if (type === 'ObjectId / Reference') { type = 'ObjectId'; } else if (type === 'JSON / any') { type = 'JSON'; } let schema; if (type === 'SubObject') { type = (yield this.ask({ initial: this.pascalCase(name), message: 'Enter property type (e.g. MyClass)', name: 'input', type: 'input', })).input; schema = type; schemaSet = true; if (type) { refsSet = true; } if (type === null || type === void 0 ? void 0 : type.trim()) { let createObjAfter = false; const cwd = this.filesystem.cwd(); const path = cwd.substr(0, cwd.lastIndexOf('src')); const objectsDir = (0, path_1.join)(path, 'src', 'server', 'common', 'objects', this.kebabCase(type)); if (!this.filesystem.exists(objectsDir)) { createObjAfter = yield this.confirm('Create this Object after all the other Properties?', true); } if (createObjAfter && !objectsToAdd.find(obj => obj.object === this.kebabCase(type))) { objectsToAdd.push({ object: this.kebabCase(type), property: name }); } } } let reference; let enumRef; if (type === 'ObjectId') { reference = (yield this.ask({ initial: this.pascalCase(name), message: 'Enter reference for ObjectId', name: 'input', type: 'input', })).input; if (reference) { refsSet = true; } if (reference === null || reference === void 0 ? void 0 : reference.trim()) { let createRefAfter = false; const cwd = this.filesystem.cwd(); const path = cwd.substr(0, cwd.lastIndexOf('src')); const moduleDir = (0, path_1.join)(path, 'src', 'server', 'modules', this.kebabCase(reference)); if (!this.filesystem.exists(moduleDir)) { createRefAfter = yield this.confirm('Create this Module after all the other Properties?', true); } if (createRefAfter && !referencesToAdd.find(ref => ref.reference === this.kebabCase(reference))) { referencesToAdd.push({ property: name, reference: this.kebabCase(reference) }); } } } else if (type === 'enum') { enumRef = (yield this.ask({ initial: `${this.pascalCase(name)}Enum`, message: 'Enter enum type', name: 'input', type: 'input', })).input; if (enumRef) { refsSet = true; } } const arrayEnding = type.endsWith('[]'); type = type.replace('[]', ''); const isArray = arrayEnding || (yield this.confirm('Array?')); const nullable = yield this.confirm('Nullable?', true); props[name] = { enumRef, isArray, name, nullable, reference, schema, type }; } return { objectsToAdd, props, referencesToAdd, refsSet, schemaSet }; }); } /** * Create template string for properties in model */ propsForModel(props, options) { var _a, _b, _c; // Preparations const config = Object.assign({ useDefault: true }, options); const { modelName, useDefault } = config; let result = ''; // Check parameters if (!props || !(typeof props !== 'object') || !Object.keys(props).length) { if (!useDefault) { return { imports: '', mappings: 'this;', props: '' }; } // Use default if (!Object.keys(props).length && useDefault) { return { imports: '', mappings: 'mapClasses(input, {user: User}, this);', props: ` /** * Description of properties */ @Restricted(RoleEnum.ADMIN, RoleEnum.S_CREATOR) @Field(() => [String], { description: 'Properties of ${this.pascalCase(modelName)}', nullable: 'items'}) @Prop([String]) properties: string[] = undefined; /** * User who has tested the ${this.pascalCase(modelName)} */ @Field(() => User, { description: 'User who has tested the ${this.pascalCase(modelName)}', nullable: true, }) @Prop({ type: Schema.Types.ObjectId, ref: 'User' }) testedBy: User = undefined; `, }; } } // Process configuration const imports = {}; const mappings = {}; for (const [name, item] of Object.entries(props)) { const propName = this.camelCase(name); const reference = ((_a = item.reference) === null || _a === void 0 ? void 0 : _a.trim()) ? this.pascalCase(item.reference.trim()) : ''; const schema = ((_b = item.schema) === null || _b === void 0 ? void 0 : _b.trim()) ? this.pascalCase(item.schema.trim()) : ''; const enumRef = ((_c = item.enumRef) === null || _c === void 0 ? void 0 : _c.trim()) ? this.pascalCase(item.enumRef.trim()) : ''; const modelFieldType = enumRef ? 'String' : this.modelFieldTypes[this.pascalCase(item.type)] || this.pascalCase(item.type); const isArray = item.isArray; const modelClassType = this.modelClassTypes[this.pascalCase(item.type)] || (this.standardTypes.includes(item.type) ? item.type : this.pascalCase(item.type)); const type = this.standardTypes.includes(item.type) ? item.type : this.pascalCase(item.type); if (!this.standardTypes.includes(type) && type !== 'ObjectId' && type !== 'Enum' && type !== 'Json') { mappings[propName] = type; } if (reference) { mappings[propName] = reference; } if (this.imports[modelClassType]) { imports[modelClassType] = this.imports[modelClassType]; } result += ` /** * ${this.pascalCase(propName) + (modelName ? ` of ${this.pascalCase(modelName)}` : '')} */ @Restricted(RoleEnum.S_EVERYONE) @Field(() => ${(isArray ? '[' : '') + (reference ? reference : modelFieldType) + (isArray ? ']' : '')}, { description: '${this.pascalCase(propName) + (modelName ? ` of ${this.pascalCase(modelName)}` : '')}', nullable: ${item.nullable}, }) @Prop(${reference ? `${isArray ? '[' : ''}{ ref: '${reference}', type: Schema.Types.ObjectId }${isArray ? ']' : ''}` : schema ? `${isArray ? '[' : ''}{ type: ${schema}Schema }${isArray ? ']' : ''}` : enumRef ? `${isArray ? '[' : ''}{ enum: ${item.nullable ? `Object.values(${enumRef}).concat([null])` : enumRef}, type: String }${isArray ? ']' : ''}` : type === 'Json' ? `${isArray ? '[' : ''}{ type: Object }${isArray ? ']' : ''}` : ''}) ${propName}: ${(reference ? reference : enumRef || modelClassType) + (isArray ? '[]' : '') // (reference ? ' | ' + reference + (isArray ? '[]' : '') : '') } = undefined; `; } // Process imports let importsResult = ''; for (const value of Object.values(imports)) { importsResult += `\n${value}`; } // Process mappings const mappingsResult = []; for (const [key, value] of Object.entries(mappings)) { mappingsResult.push(`${key}: ${value}`); } // Return template data return { imports: importsResult, mappings: mappingsResult.length ? `mapClasses(input, { ${mappingsResult.join(', ')} }, this);` : 'this;', props: result, }; } /** * Create template string for properties in input */ propsForInput(props, options) { // Preparations const config = Object.assign({ useDefault: true }, options); const { create, modelName, nullable, useDefault } = config; let result = ''; // Check parameters if (!props || !(typeof props !== 'object') || !Object.keys(props).length) { if (!useDefault) { return { imports: '', props: '' }; } // Use default if (!Object.keys(props).length && useDefault) { return { imports: '', props: ` /** * Description of properties */ @Restricted(RoleEnum.ADMIN, RoleEnum.S_CREATOR) @Field(() => [String], { description: 'Properties of ${this.pascalCase(modelName)}', nullable: ${config.nullable ? config.nullable : '\'items\''}}) properties: string[] = undefined; /** * User how has tested the ${this.pascalCase(modelName)} */ @Field(() => User, { description: 'User who has tested the ${this.pascalCase(modelName)}', nullable: ${config.nullable}, }) testedBy: User = undefined; `, }; } // Process configuration const imports = {}; for (const [name, item] of Object.entries(props)) { let inputFieldType = this.inputFieldTypes[this.pascalCase(item.type)] || (item.enumRef ? this.pascalCase(item.enumRef) : this.pascalCase(item.type) + (create ? 'CreateInput' : 'Input')); inputFieldType = this.modelFieldTypes[item.type] ? this.modelFieldTypes[item.type] : inputFieldType; const inputClassType = this.inputClassTypes[this.pascalCase(item.type)] || (this.standardTypes.includes(item.type) ? item.type : item.enumRef ? this.pascalCase(item.enumRef) : this.pascalCase(item.type) + (create ? 'CreateInput' : 'Input')); const propertySuffix = this.propertySuffixTypes[this.pascalCase(item.type)] || ''; const overrideFlag = create ? 'override ' : ''; if (this.imports[inputFieldType]) { imports[inputFieldType] = this.imports[inputFieldType]; } if (this.imports[inputClassType]) { imports[inputClassType] = this.imports[inputClassType]; } result += ` /** * ${this.pascalCase(name) + propertySuffix + (modelName ? ` of ${this.pascalCase(modelName)}` : '')} */ @Restricted(RoleEnum.S_EVERYONE) @Field(() => ${(item.isArray ? '[' : '') + inputFieldType + (item.isArray ? ']' : '')}, { description: '${this.pascalCase(name) + propertySuffix + (modelName ? ` of ${this.pascalCase(modelName)}` : '')}', nullable: ${nullable || item.nullable}, })${nullable || item.nullable ? '\n @IsOptional()' : ''} ${overrideFlag + this.camelCase(name)}${nullable || item.nullable ? '?' : ''}: ${inputClassType + (item.isArray ? '[]' : '')} = undefined; `; } // Process imports let importsResult = ''; for (const value of Object.values(imports)) { importsResult += `\n${value}`; } // Return template data return { imports: importsResult, props: result, }; } } /** * Replace secret or private keys in string (e.g. for config files) */ replaceSecretOrPrivateKeys(configContent) { // Matches SECRET_OR_PRIVATE_KEY then any amount of anything until there is a ' const regex = /SECRET_OR_PRIVATE_KEY[^']*/gm; const count = (str, pattern) => { const re = new RegExp(pattern, 'gi'); return ((str || '').match(re) || []).length; }; const secretArr = []; // -1 because we don't need to replace the first occurrence. for (let i = 0; i < count(configContent, regex) - 1; i++) { secretArr.push(crypto.randomBytes(512).toString('base64')); } // Getting the config content and using native ts to replace the content, patching.update doesn't accept regex let secretIndex = 0; let occurrenceCount = 0; return configContent.replace(regex, (match) => { occurrenceCount++; // Skip the first occurrence if (occurrenceCount === 1) { return match; } const secret = secretArr[secretIndex]; secretIndex++; return secret; }); } } exports.Server = Server; /** * Extend toolbox */ exports.default = (toolbox) => { toolbox.server = new Server(toolbox); }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2V4dGVuc2lvbnMvc2VydmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLGlDQUFpQztBQUlqQywrQkFBNEI7QUFRNUI7O0dBRUc7QUFDSCxNQUFhLE1BQU07SUE2RmpCOztPQUVHO0lBQ0gsWUFBc0IsT0FBK0I7UUFBL0IsWUFBTyxHQUFQLE9BQU8sQ0FBd0I7UUFyRnJELHVDQUF1QztRQUN2QyxZQUFPLEdBQTJCO1lBQ2hDLGNBQWMsRUFBRSwyREFBMkQ7WUFDM0UsWUFBWSxFQUFFLHVFQUF1RTtZQUNyRixlQUFlLEVBQUUscUVBQXFFO1lBQ3RGLHlCQUF5QixFQUFFLG1EQUFtRDtTQUMvRSxDQUFDO1FBRUYsZ0RBQWdEO1FBQ2hELG9CQUFlLEdBQTJCO1lBQ3hDLE9BQU8sRUFBRSxTQUFTO1lBQ2xCLElBQUksRUFBRSxNQUFNO1lBQ1osSUFBSSxFQUFFLGVBQWU7WUFDckIsUUFBUSxFQUFFLGVBQWU7WUFDekIsRUFBRSxFQUFFLFFBQVE7WUFDWixFQUFFLEVBQUUsUUFBUTtZQUNaLElBQUksRUFBRSxNQUFNO1lBQ1osSUFBSSxFQUFFLE1BQU07WUFDWixNQUFNLEVBQUUsUUFBUTtZQUNoQixRQUFRLEVBQUUsUUFBUTtZQUNsQixNQUFNLEVBQUUsUUFBUTtZQUNoQixNQUFNLEVBQUUsZUFBZTtTQUN4QixDQUFDO1FBRUYsaURBQWlEO1FBQ2pELG9CQUFlLEdBQTJCO1lBQ3hDLE9BQU8sRUFBRSxTQUFTO1lBQ2xCLElBQUksRUFBRSxNQUFNO1lBQ1osSUFBSSxFQUFFLFlBQVk7WUFDbEIsUUFBUSxFQUFFLFlBQVk7WUFDdEIsRUFBRSxFQUFFLFFBQVE7WUFDWixFQUFFLEVBQUUsUUFBUTtZQUNaLElBQUksRUFBRSx5QkFBeUI7WUFDL0IsSUFBSSxFQUFFLHlCQUF5QjtZQUMvQixNQUFNLEVBQUUsUUFBUTtZQUNoQixRQUFRLEVBQUUsUUFB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