Skip to content

Commit

Permalink
Duplicate content converted to functions
Browse files Browse the repository at this point in the history
  • Loading branch information
kaihaase committed Oct 2, 2024
1 parent 5d45051 commit ae17eeb
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 318 deletions.
35 changes: 4 additions & 31 deletions src/commands/fullstack/init.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { GluegunCommand, patching } from 'gluegun';
import { ExtendedGluegunToolbox } from '../../interfaces/extended-gluegun-toolbox';
import * as fs from 'node:fs';
import * as crypto from 'crypto';


/**
* Create a new server
Expand All @@ -20,6 +19,7 @@ const NewCommand: GluegunCommand = {
parameters,
print: { error, info, spin, success },
prompt: { confirm, ask },
server,
strings: { kebabCase },
system,
} = toolbox;
Expand Down Expand Up @@ -162,35 +162,8 @@ const NewCommand: GluegunCommand = {
description: `API for ${name} app`,
version: '0.0.0',
});

const configContent = fs.readFileSync(`./${projectDir}/projects/api/src/config.env.ts`, 'utf8');

// Matches SECRET_OR_PRIVATE_KEY then any amount of anything until there is a '
const regex = /SECRET_OR_PRIVATE_KEY[^']*/gm;

// if str aint defined its empty, when
const count = (str, pattern) => {
const re = new RegExp(pattern, 'gi')
return ((str || '').match(re) || []).length
}

const secretArr: string[] = []

for (let i = 0; i < count(configContent, regex); i++) {
secretArr.push(crypto.randomBytes(512).toString('base64'));
}

// Getting the config content and using native ts to replace the content because patching.update doest accept regex
let secretIndex = 0;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const updatedContent = configContent.replace(regex, (match) => {
const secret = secretArr[secretIndex];
secretIndex++;
return secret;
});

// eslint-disable-next-line @typescript-eslint/no-unused-vars
await patching.update(`./${projectDir}/projects/api/src/config.env.ts`, (content) => updatedContent);

await patching.update(`./${projectDir}/projects/api/src/config.env.ts`, server.replaceSecretOrPrivateKeys);

// Check if git init is active
if (addToGit) {
Expand Down
197 changes: 59 additions & 138 deletions src/commands/server/add-property.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { GluegunCommand, patching } from 'gluegun';
import { join } from 'path';
import { ExtendedGluegunToolbox } from '../../interfaces/extended-gluegun-toolbox';
import { GluegunCommand, patching } from 'gluegun';
import { ServerProps } from '../../interfaces/ServerProps.interface';
import genModule from './module'
import genModule from './module';

/**
* Create a new server module
Expand All @@ -17,21 +16,22 @@ const NewCommand: GluegunCommand = {
const {
filesystem,
print: { error, info, success, spin, divider },
prompt: { ask, confirm },
prompt: { ask },
server,
strings: { pascalCase },
} = toolbox;

const refArray: string[] = []

const refArray: string[] = [];
function getModules() {
const cwd = filesystem.cwd();
const path = cwd.substr(0, cwd.lastIndexOf('src'));
const moduleDirs = join(path, 'src', 'server', 'modules');

return filesystem.subdirectories(moduleDirs, true);
}


const moduleToEdit = (
await ask([
{
Expand All @@ -42,8 +42,8 @@ const NewCommand: GluegunCommand = {
},
])
).input;


// Check if directory
const cwd = filesystem.cwd();
const path = cwd.substr(0, cwd.lastIndexOf('src'));
Expand All @@ -52,141 +52,60 @@ const NewCommand: GluegunCommand = {
error(`No src directory in "${path}".`);
return undefined;
}

// Set props
const props: Record<string, ServerProps> = {};
const setProps = true;
let refsSet = false;
let schemaSet = false;
while (setProps) {
const name = (
await ask({
type: 'input',
name: 'input',
message: `Enter property name (e.g. myProperty) of the new property or leave empty (ENTER)`,
})
).input;
if (!name.trim()) {
break;
}

let type = (
await ask([
{
type: 'select',
name: 'input',
message: 'Choose property type',
choices: ['boolean', 'string', 'number', 'ObjectId / Reference', 'Date', 'enum', 'Use own', 'JSON / any'],
},
])
).input;
if (type === 'ObjectId / Reference') {
type = 'ObjectId';
} else if (type === 'JSON / any') {
type = 'JSON';
}

let schema: string;
if (type === 'Subobject') {
type = (
await ask({
type: 'input',
name: 'input',
message: `Enter property type (e.g. MyClass)`,
})
).input;
schema = type;
schemaSet = true;
}

let reference: string;
let enumRef: string;
if (type === 'ObjectId') {
reference = (
await ask({
type: 'input',
name: 'input',
initial: pascalCase(name),
message: `Enter reference for ObjectId`,
})
).input;
if (reference) {
refsSet = true;
refArray.push(reference);
}


} else if (type === 'enum') {
enumRef = (
await ask({
type: 'input',
name: 'input',
initial: pascalCase(name) + 'Enum',
message: `Enter enum type`,
})
).input;
if (enumRef) {
refsSet = true;
}
}

const arrayEnding = type.endsWith('[]');
type = type.replace('[]', '');
const isArray = arrayEnding || (await confirm(`Array?`));

const nullable = await confirm(`Nullable?`, true);

props[name] = { name, nullable, isArray, type, reference, enumRef, schema };
}


const { props, refsSet, schemaSet } = await server.addProperties({ refArray });

const updateSpinner = spin('Updating files...');
// const inputTemplate = server.propsForInput(props, { modelName: name, nullable: true });
// const createTemplate = server.propsForInput(props, { modelName: name, nullable: false, create: true });
// const modelTemplate = server.propsForModel(props, { modelName: name });

const moduleModel = join(path, 'src', 'server', 'modules', moduleToEdit, `${moduleToEdit}.model.ts`);
const moduleInput = join(path, 'src', 'server', 'modules', moduleToEdit, 'inputs' ,`${moduleToEdit}.input.ts`);
const moduleCreateInput = join(path, 'src', 'server', 'modules', moduleToEdit, 'inputs' ,`${moduleToEdit}-create.input.ts`);

const moduleInput = join(path, 'src', 'server', 'modules', moduleToEdit, 'inputs', `${moduleToEdit}.input.ts`);
const moduleCreateInput = join(path, 'src', 'server', 'modules', moduleToEdit, 'inputs', `${moduleToEdit}-create.input.ts`);
for (const prop in props) {

const propObj = props[prop];

if(await patching.exists(moduleModel, `${propObj.name}`)) {
info('')
info(`Property ${propObj.name} already exists`)
if (await patching.exists(moduleModel, `${propObj.name}`)) {
info('');
info(`Property ${propObj.name} already exists`);
continue;
}

// Patch the model
// Patch the model
await patching.patch(moduleModel, {
insert: `\n\n
/**
* ${pascalCase(propObj.name)} of ${pascalCase(moduleToEdit)}
*/
@Restricted(RoleEnum.ADMIN)
@Field(() => ${propObj.isArray ? `[${propObj.type == 'ObjectId' ? propObj.reference : pascalCase(propObj.type)}]` : propObj.type == 'ObjectId' ? propObj.reference : pascalCase(propObj.type)}, {
@Field(() => ${propObj.isArray ? `[${propObj.type
== 'ObjectId' ? propObj.reference : pascalCase(propObj.type)}]` : propObj.type
== 'ObjectId' ? propObj.reference : pascalCase(propObj.type)}, {
description: '${pascalCase(propObj.name)} of ${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 : pascalCase(propObj.type)}[]` : propObj.type == 'ObjectId' ? propObj.reference : pascalCase(propObj.type)} = undefined;`,
${propObj.name}: ${propObj.isArray ? `${propObj.type
== 'ObjectId' ? propObj.reference : pascalCase(propObj.type)}[]` : propObj.type
== 'ObjectId' ? propObj.reference : pascalCase(propObj.type)} = undefined;`,
// after: new RegExp('export class \\w+(?: .+)? \\{'),
after: new RegExp('@Field[\\s\\S]*?undefined;(?![\\s\\S]*@Field)', 'g')
});

// Patch the input
// Patch the input
// Create the Field type string based on conditions
const fieldType = propObj.isArray
? `[${propObj.type === 'ObjectId' ? propObj.reference : pascalCase(propObj.type)}]`
: propObj.type === 'ObjectId'
? propObj.reference
: pascalCase(propObj.type);

const arraySuffix = propObj.isArray ? '[]' : ''




const arraySuffix = propObj.isArray ? '[]' : '';


const optionalSuffix = propObj.nullable ? '?' : '';

// Construct the property string
Expand All @@ -206,49 +125,51 @@ ${propObj.name}${optionalSuffix}: ${propObj.type}${arraySuffix} = undefined;
// Perform the patching
await patching.patch(moduleInput, {
insert: propertyString,
after: new RegExp('@Field[\\s\\S]*?undefined;(?![\\s\\S]*@Field)', 'g')
})



after: new RegExp('@Field[\\s\\S]*?undefined;(?![\\s\\S]*@Field)', 'g')
});


// Patch the create input
await patching.patch(moduleCreateInput, {
insert: ` \n\n
/**
* ${pascalCase(propObj.name)} of ${pascalCase(moduleToEdit)}
*/
@Restricted(RoleEnum.ADMIN)
@Field(() => ${propObj.isArray ? `[${propObj.type == 'ObjectId' ? propObj.reference : pascalCase(propObj.type)}]` : propObj.type == 'ObjectId' ? propObj.reference : pascalCase(propObj.type)}, {
@Field(() => ${propObj.isArray ? `[${propObj.type
== 'ObjectId' ? propObj.reference : pascalCase(propObj.type)}]` : propObj.type
== 'ObjectId' ? propObj.reference : pascalCase(propObj.type)}, {
description: '${pascalCase(propObj.name)} of ${pascalCase(moduleToEdit)}',
nullable: ${propObj.nullable},
})
${propObj.nullable ? '@IsOptional()' : ''}${propObj.nullable ? '\n' : ''}override ${propObj.name}${propObj.nullable ? '?' : ''}: ${propObj.isArray ? `${propObj.type == 'ObjectId' ? propObj.reference : pascalCase(propObj.type)}[]` : propObj.type == 'ObjectId' ? propObj.reference : pascalCase(propObj.type)} = undefined;`,

${propObj.nullable ? '@IsOptional()' : ''}${propObj.nullable ? '\n' : ''}override ${propObj.name}${propObj.nullable ? '?' : ''}: ${propObj.isArray ? `${propObj.type
== 'ObjectId' ? propObj.reference : pascalCase(propObj.type)}[]` : propObj.type
== 'ObjectId' ? propObj.reference : pascalCase(propObj.type)} = undefined;`,

after: new RegExp('@Field[\\s\\S]*?undefined;(?![\\s\\S]*@Field)', 'g')
})



});


}

updateSpinner.succeed('All files updated successfully.');

if (refArray.length > 0) {
divider()
divider();
const nextRef = refArray.shift();
return genModule.run(toolbox, refArray, nextRef);
}

if (refsSet || schemaSet) {
success(`HINT: References / Schemata have been added, so it is necessary to add the corresponding imports!`);
}

if (!toolbox.parameters.options.fromGluegunMenu) {
process.exit();
}

return `properties updated for ${name}`

return `properties updated for ${name}`;
},
};

Expand Down
Loading

0 comments on commit ae17eeb

Please sign in to comment.