From 6fd4b18063827782b30d6cad034a4a51308e46fb Mon Sep 17 00:00:00 2001 From: Rodrigo Oliveira Date: Tue, 4 Jul 2023 01:27:52 -0300 Subject: [PATCH 1/4] feat: generate id field using uuid --- src/generators/src/packagejson.js | 3 ++- src/templates/domain/useCases/create.ejs | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/generators/src/packagejson.js b/src/generators/src/packagejson.js index 8e634cb..6445841 100644 --- a/src/generators/src/packagejson.js +++ b/src/generators/src/packagejson.js @@ -54,7 +54,8 @@ module.exports = '"nodemon": "^2.0.19"', '"mocha": "^10.0.0"', '"lodash.camelcase": "^4.3.0"', - '"sugar-env": "^1.5.14"' + '"sugar-env": "^1.5.14"', + '"uuid": "^9.0.0"' ] for (const key of Object.keys(options)) { diff --git a/src/templates/domain/useCases/create.ejs b/src/templates/domain/useCases/create.ejs index 5f0f7ca..8830904 100644 --- a/src/templates/domain/useCases/create.ejs +++ b/src/templates/domain/useCases/create.ejs @@ -3,11 +3,12 @@ const { herbarium } = require('@herbsjs/herbarium') const <%- props.name.pascalCase %> = require('../../entities/<%- props.name.camelCase %>') const <%- props.name.pascalCase %>Repository = require('../../../infra/data/repositories/<%- props.name.camelCase %>Repository') +const uuid = require('uuid') const dependency = { <%- props.name.pascalCase %>Repository } const create<%- props.name.pascalCase %> = injection => usecase('Create <%- props.name.pascalCase %>', { - // Input/Request metadata and validation + // Input/Request metadata and validation request: request.from(<%- props.name.pascalCase %>, { ignoreIDs: true }), // Output/Response metadata @@ -22,17 +23,16 @@ const create<%- props.name.pascalCase %> = injection => //Step description and function 'Check if the <%- props.name.raw %> is valid': step(ctx => { ctx.<%- props.name.camelCase %> = <%- props.name.pascalCase %>.fromJSON(ctx.req) - <% if(!props.mongo){ %>ctx.<%- props.name.camelCase %>.id = Math.floor(Math.random() * 100000).toString()<% } %> - - if (!ctx.<%- props.name.camelCase %>.isValid()) + ctx.<%- props.name.camelCase %>.id = uuid.v4() + if (!ctx.<%- props.name.camelCase %>.isValid()) return Err.invalidEntity({ - message: 'The <%- props.name.raw %> entity is invalid', + message: 'The <%- props.name.raw %> entity is invalid', payload: { entity: '<%- props.name.raw %>' }, - cause: ctx.<%- props.name.camelCase %>.errors + cause: ctx.<%- props.name.camelCase %>.errors }) // returning Ok continues to the next step. Err stops the use case execution. - return Ok() + return Ok() }), 'Save the <%- props.name.raw %>': step(async ctx => { From c964c595a1aa6daef50ff58b6aeb8ac4cd33157a Mon Sep 17 00:00:00 2001 From: Rodrigo Oliveira Date: Tue, 29 Oct 2024 23:46:30 -0300 Subject: [PATCH 2/4] refactor: replace 'uuid' dependency with native crypto module for UUID generation --- src/generators/src/packagejson.js | 3 +-- src/templates/domain/useCases/create.ejs | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/generators/src/packagejson.js b/src/generators/src/packagejson.js index 6445841..8e634cb 100644 --- a/src/generators/src/packagejson.js +++ b/src/generators/src/packagejson.js @@ -54,8 +54,7 @@ module.exports = '"nodemon": "^2.0.19"', '"mocha": "^10.0.0"', '"lodash.camelcase": "^4.3.0"', - '"sugar-env": "^1.5.14"', - '"uuid": "^9.0.0"' + '"sugar-env": "^1.5.14"' ] for (const key of Object.keys(options)) { diff --git a/src/templates/domain/useCases/create.ejs b/src/templates/domain/useCases/create.ejs index 8830904..8d31371 100644 --- a/src/templates/domain/useCases/create.ejs +++ b/src/templates/domain/useCases/create.ejs @@ -1,9 +1,9 @@ const { usecase, step, Ok, Err, request } = require('@herbsjs/herbs') const { herbarium } = require('@herbsjs/herbarium') +const { randomUUID } = require('crypto') const <%- props.name.pascalCase %> = require('../../entities/<%- props.name.camelCase %>') const <%- props.name.pascalCase %>Repository = require('../../../infra/data/repositories/<%- props.name.camelCase %>Repository') -const uuid = require('uuid') const dependency = { <%- props.name.pascalCase %>Repository } const create<%- props.name.pascalCase %> = injection => @@ -23,7 +23,7 @@ const create<%- props.name.pascalCase %> = injection => //Step description and function 'Check if the <%- props.name.raw %> is valid': step(ctx => { ctx.<%- props.name.camelCase %> = <%- props.name.pascalCase %>.fromJSON(ctx.req) - ctx.<%- props.name.camelCase %>.id = uuid.v4() + ctx.<%- props.name.camelCase %>.id = randomUUID() if (!ctx.<%- props.name.camelCase %>.isValid()) return Err.invalidEntity({ message: 'The <%- props.name.raw %> entity is invalid', From 793d8db67a7b72d57187847b5ff2cb54fb5b2835 Mon Sep 17 00:00:00 2001 From: Rodrigo Oliveira Date: Wed, 30 Oct 2024 00:00:42 -0300 Subject: [PATCH 3/4] feat: add database-specific UUID handling for migrations --- .../src/infra/database/migrations/migrations.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/generators/src/infra/database/migrations/migrations.js b/src/generators/src/infra/database/migrations/migrations.js index 39eddd1..936fb94 100644 --- a/src/generators/src/infra/database/migrations/migrations.js +++ b/src/generators/src/infra/database/migrations/migrations.js @@ -35,6 +35,8 @@ module.exports = if (_type instanceof Boolean) return 'boolean' if (_type instanceof Date) return 'timestamp' } + + if (Type === 'UUID') return 'uuid' } function getDBType(appDir) { @@ -43,14 +45,23 @@ module.exports = return config.database.herbsCLI } - function createColumns(schema) { + function createColumns(schema, db) { const columns = [] Object.keys(schema).forEach((prop) => { const { name, type, options } = schema[prop] - columns.push(`table.${type2Str(type)}('${snakeCase(name)}')${options.isId ? '.primary()' : ''}`) + if (options.isId) { + if (type2Str(type) === 'uuid' && db.toLowerCase() === 'postgres') { + columns.push(`table.uuid('${snakeCase(name)}').primary().defaultTo(knex.raw('uuid_generate_v4()'))`) + } else { + columns.push(`table.${type2Str(type)}('${snakeCase(name)}').primary()`) + } + } else { + columns.push(`table.${type2Str(type)}('${snakeCase(name)}')`) + } }) return columns } + const db = getDBType(filesystem.cwd()) const migrationName = new Date() @@ -59,7 +70,7 @@ module.exports = .substring(0, 14) const migrationFullPath = path.normalize(`${migrationsPath}/${migrationName}_${camelCase(name)}s.js`) - const columns = createColumns(schema) + const columns = createColumns(schema, db) await generate({ template: `infra/data/database/${db.toLowerCase()}/migration.ejs`, From 238197329a2131bacb908aac3085361f5c6752e2 Mon Sep 17 00:00:00 2001 From: Rodrigo Oliveira Date: Wed, 30 Oct 2024 00:00:42 -0300 Subject: [PATCH 4/4] feat: add database-specific UUID handling for migrations --- .../src/infra/database/migrations/migrations.js | 17 ++++++++++++++--- src/templates/domain/useCases/create.ejs | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/generators/src/infra/database/migrations/migrations.js b/src/generators/src/infra/database/migrations/migrations.js index 39eddd1..936fb94 100644 --- a/src/generators/src/infra/database/migrations/migrations.js +++ b/src/generators/src/infra/database/migrations/migrations.js @@ -35,6 +35,8 @@ module.exports = if (_type instanceof Boolean) return 'boolean' if (_type instanceof Date) return 'timestamp' } + + if (Type === 'UUID') return 'uuid' } function getDBType(appDir) { @@ -43,14 +45,23 @@ module.exports = return config.database.herbsCLI } - function createColumns(schema) { + function createColumns(schema, db) { const columns = [] Object.keys(schema).forEach((prop) => { const { name, type, options } = schema[prop] - columns.push(`table.${type2Str(type)}('${snakeCase(name)}')${options.isId ? '.primary()' : ''}`) + if (options.isId) { + if (type2Str(type) === 'uuid' && db.toLowerCase() === 'postgres') { + columns.push(`table.uuid('${snakeCase(name)}').primary().defaultTo(knex.raw('uuid_generate_v4()'))`) + } else { + columns.push(`table.${type2Str(type)}('${snakeCase(name)}').primary()`) + } + } else { + columns.push(`table.${type2Str(type)}('${snakeCase(name)}')`) + } }) return columns } + const db = getDBType(filesystem.cwd()) const migrationName = new Date() @@ -59,7 +70,7 @@ module.exports = .substring(0, 14) const migrationFullPath = path.normalize(`${migrationsPath}/${migrationName}_${camelCase(name)}s.js`) - const columns = createColumns(schema) + const columns = createColumns(schema, db) await generate({ template: `infra/data/database/${db.toLowerCase()}/migration.ejs`, diff --git a/src/templates/domain/useCases/create.ejs b/src/templates/domain/useCases/create.ejs index 8d31371..13d658b 100644 --- a/src/templates/domain/useCases/create.ejs +++ b/src/templates/domain/useCases/create.ejs @@ -8,7 +8,7 @@ const dependency = { <%- props.name.pascalCase %>Repository } const create<%- props.name.pascalCase %> = injection => usecase('Create <%- props.name.pascalCase %>', { - // Input/Request metadata and validation + // Input/Request metadata and validation request: request.from(<%- props.name.pascalCase %>, { ignoreIDs: true }), // Output/Response metadata