@lenne.tech/cli
Version:
lenne.Tech CLI: lt
499 lines (497 loc) • 45.6 kB
JavaScript
;
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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