@anthonylzq/simba.js 4.2.0 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,72 @@
1
+ const { platform } = require('os')
2
+ const { promisify } = require('util')
3
+ const exec = promisify(require('child_process').exec)
4
+ const writeFile = require('../../utils/writeFile')
5
+
6
+ /**
7
+ * @param {Object} args
8
+ * @param {String} args.projectName
9
+ */
10
+ module.exports = async ({ projectName }) => {
11
+ const createFoldersCommand = `mkdir ${projectName}/src/schemas`
12
+
13
+ if (platform() === 'win32')
14
+ await exec(createFoldersCommand.replaceAll('/', '\\'))
15
+ else await exec(createFoldersCommand)
16
+
17
+ const schemas = {
18
+ index: {
19
+ content: `import { Static, Type } from '@sinclair/typebox'
20
+
21
+ const id = Type.String({
22
+ pattern: '^[a-zA-Z0-9]{24,}$'
23
+ })
24
+
25
+ type Id = Static<typeof id>
26
+
27
+ const idSchema = Type.Object({ id })
28
+
29
+ type IdSchema = Static<typeof idSchema>
30
+
31
+ export { id, Id, idSchema, IdSchema }
32
+ export * from './user'
33
+ `,
34
+ file: `${projectName}/src/schemas/index.ts`
35
+ },
36
+ user: {
37
+ content: `import { Static, Type } from '@sinclair/typebox'
38
+
39
+ import { id } from '.'
40
+
41
+ const user = Type.Object({
42
+ lastName: Type.String(),
43
+ name: Type.String()
44
+ })
45
+
46
+ type User = Static<typeof user>
47
+
48
+ const userDto = Type.Object({
49
+ id: Type.Optional(id),
50
+ lastName: Type.String(),
51
+ name: Type.String(),
52
+ createdAt: Type.Optional(Type.String()),
53
+ updatedAt: Type.Optional(Type.String())
54
+ })
55
+
56
+ type UserDTO = Static<typeof userDto>
57
+
58
+ const storeUserSchema = Type.Object({
59
+ args: user
60
+ })
61
+
62
+ type StoreUser = Static<typeof storeUserSchema>
63
+
64
+ export { userDto, UserDTO, user, User, storeUserSchema, StoreUser }
65
+ `,
66
+ file: `${projectName}/src/schemas/user.ts`
67
+ }
68
+ }
69
+
70
+ await writeFile(schemas.index.file, schemas.index.content)
71
+ await writeFile(schemas.user.file, schemas.user.content)
72
+ }
@@ -0,0 +1,218 @@
1
+ const { platform } = require('os')
2
+ const { promisify } = require('util')
3
+ const exec = promisify(require('child_process').exec)
4
+ const writeFile = require('../../utils/writeFile')
5
+
6
+ /**
7
+ * @param {Object} args
8
+ * @param {String} args.projectName
9
+ */
10
+ module.exports = async ({ projectName }) => {
11
+ const createFoldersCommand = `mkdir ${projectName}/src/services \
12
+ ${projectName}/src/services/utils \
13
+ ${projectName}/src/services/utils/messages`
14
+
15
+ if (platform() === 'win32')
16
+ await exec(createFoldersCommand.replaceAll('/', '\\'))
17
+ else await exec(createFoldersCommand)
18
+
19
+ const services = {
20
+ index: {
21
+ content: "export * from './user'\n",
22
+ file: `${projectName}/src/services/index.ts`
23
+ },
24
+ user: {
25
+ content: `import httpErrors from 'http-errors'
26
+
27
+ import { store, remove, get, update } from 'database'
28
+ import { UserDTO } from 'schemas'
29
+ import { EFU, MFU, GE, errorHandling } from './utils'
30
+
31
+ type Process = {
32
+ type: 'store' | 'getAll' | 'deleteAll' | 'getOne' | 'update' | 'delete'
33
+ }
34
+
35
+ type Arguments = {
36
+ id?: string
37
+ userDto?: UserDTO
38
+ userDtoWithoutId?: Omit<UserDTO, 'id'>
39
+ }
40
+
41
+ class UserService {
42
+ #args: Arguments
43
+
44
+ constructor(args: Arguments = {}) {
45
+ this.#args = args
46
+ }
47
+
48
+ public process({ type }: Process): Promise<string | UserDTO | UserDTO[]> {
49
+ switch (type) {
50
+ case 'store':
51
+ return this.#store()
52
+ case 'getAll':
53
+ return this.#getAll()
54
+ case 'deleteAll':
55
+ return this.#deleteAll()
56
+ case 'getOne':
57
+ return this.#getOne()
58
+ case 'update':
59
+ return this.#update()
60
+ case 'delete':
61
+ return this.#delete()
62
+ default:
63
+ throw new httpErrors.InternalServerError(GE.INTERNAL_SERVER_ERROR)
64
+ }
65
+ }
66
+
67
+ async #store(): Promise<UserDTO> {
68
+ try {
69
+ if (!this.#args.userDtoWithoutId)
70
+ throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
71
+
72
+ const result = await store({
73
+ ...this.#args.userDtoWithoutId
74
+ })
75
+
76
+ return result
77
+ } catch (e) {
78
+ return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
79
+ }
80
+ }
81
+
82
+ async #getAll(): Promise<UserDTO[]> {
83
+ try {
84
+ const users = (await get()) as UserDTO[]
85
+
86
+ return users
87
+ } catch (e) {
88
+ return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
89
+ }
90
+ }
91
+
92
+ async #deleteAll(): Promise<string> {
93
+ try {
94
+ const usersDeleted = (await remove()) as number
95
+
96
+ if (usersDeleted >= 1) return MFU.ALL_USERS_DELETED
97
+
98
+ if (usersDeleted === 0)
99
+ throw new httpErrors.Conflict(EFU.NOTHING_TO_DELETE)
100
+
101
+ throw new httpErrors.InternalServerError(GE.INTERNAL_SERVER_ERROR)
102
+ } catch (e) {
103
+ return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
104
+ }
105
+ }
106
+
107
+ async #getOne(): Promise<UserDTO> {
108
+ try {
109
+ if (!this.#args.id)
110
+ throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
111
+
112
+ const { id } = this.#args
113
+ const user = (await get(id)) as UserDTO | null
114
+
115
+ if (!user) throw new httpErrors.NotFound(EFU.NOT_FOUND)
116
+
117
+ return user
118
+ } catch (e) {
119
+ return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
120
+ }
121
+ }
122
+
123
+ async #update(): Promise<UserDTO> {
124
+ try {
125
+ if (!this.#args.userDto || !this.#args.userDto.id)
126
+ throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
127
+
128
+ const updatedUser = await update(this.#args.userDto)
129
+
130
+ if (!updatedUser) throw new httpErrors.NotFound(EFU.NOT_FOUND)
131
+
132
+ return updatedUser
133
+ } catch (e) {
134
+ return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
135
+ }
136
+ }
137
+
138
+ async #delete(): Promise<string> {
139
+ try {
140
+ if (!this.#args.id)
141
+ throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
142
+
143
+ const { id } = this.#args
144
+ const deletedUser = await remove(id)
145
+
146
+ if (!deletedUser) throw new httpErrors.NotFound(EFU.NOT_FOUND)
147
+
148
+ return MFU.USER_DELETED
149
+ } catch (e) {
150
+ return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
151
+ }
152
+ }
153
+ }
154
+
155
+ export { UserService }
156
+ `,
157
+ file: `${projectName}/src/services/user.ts`
158
+ },
159
+ utils: {
160
+ index: {
161
+ content: `import httpErrors from 'http-errors'
162
+
163
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
164
+ const errorHandling = (e: any, message?: string): never => {
165
+ console.error(e)
166
+
167
+ if (e instanceof httpErrors.HttpError) throw e
168
+
169
+ throw new httpErrors.InternalServerError(message ?? e.message)
170
+ }
171
+
172
+ export { errorHandling }
173
+ export * from './messages'
174
+ `,
175
+ file: `${projectName}/src/services/utils/index.ts`
176
+ }
177
+ },
178
+ 'utils/messages': {
179
+ index: {
180
+ content: `enum GenericErrors {
181
+ INTERNAL_SERVER_ERROR = 'Something went wrong'
182
+ }
183
+
184
+ export { GenericErrors as GE }
185
+ export * from './user'
186
+ `,
187
+ file: `${projectName}/src/services/utils/messages/index.ts`
188
+ },
189
+ user: {
190
+ content: `enum ErrorForUser {
191
+ NOT_FOUND = 'The requested user does not exists',
192
+ NOTHING_TO_DELETE = 'There is no user to be deleted'
193
+ }
194
+
195
+ enum MessageForUser {
196
+ ALL_USERS_DELETED = 'All the users were deleted successfully',
197
+ USER_DELETED = 'The requested user was successfully deleted'
198
+ }
199
+
200
+ export { ErrorForUser as EFU, MessageForUser as MFU }
201
+ `,
202
+ file: `${projectName}/src/services/utils/messages/user.ts`
203
+ }
204
+ }
205
+ }
206
+
207
+ await writeFile(services.index.file, services.index.content)
208
+ await writeFile(services.user.file, services.user.content)
209
+ await writeFile(services.utils.index.file, services.utils.index.content)
210
+ await writeFile(
211
+ services['utils/messages'].index.file,
212
+ services['utils/messages'].index.content
213
+ )
214
+ await writeFile(
215
+ services['utils/messages'].user.file,
216
+ services['utils/messages'].user.content
217
+ )
218
+ }
@@ -0,0 +1,80 @@
1
+ const { platform } = require('os')
2
+ const { promisify } = require('util')
3
+ const exec = promisify(require('child_process').exec)
4
+ const writeFile = require('../../utils/writeFile')
5
+
6
+ /**
7
+ * @param {Object} args
8
+ * @param {Boolean} args.express
9
+ * @param {String} args.projectName
10
+ */
11
+ module.exports = async ({ express, projectName }) => {
12
+ const createFoldersCommand = `mkdir ${projectName}/src/@types \
13
+ ${projectName}/src/@types/models \
14
+ ${express ? `${projectName}/src/@types/custom` : ''}`
15
+
16
+ if (platform() === 'win32')
17
+ await exec(createFoldersCommand.replaceAll('/', '\\'))
18
+ else await exec(createFoldersCommand)
19
+
20
+ const types = {
21
+ index: {
22
+ content: `/* eslint-disable no-var */
23
+ declare global {}
24
+
25
+ export {}
26
+ `,
27
+ file: `${projectName}/src/@types/index.d.ts`
28
+ },
29
+ models: {
30
+ user: {
31
+ content: `interface UserDBO {
32
+ id: string
33
+ name: string
34
+ lastName: string
35
+ createdAt: Date
36
+ updatedAt: Date
37
+ }
38
+ `,
39
+ file: `${projectName}/src/@types/models/user.d.ts`
40
+ }
41
+ },
42
+ ...(express && {
43
+ custom: {
44
+ request: {
45
+ content: `type ExpressRequest = import('express').Request
46
+
47
+ interface CustomRequest extends ExpressRequest {
48
+ body: {
49
+ args?: import('schemas').UserDTO
50
+ }
51
+ // We can add custom headers via intersection, remember that for some reason
52
+ // headers must be in Snake-Pascal-Case
53
+ headers: import('http').IncomingHttpHeaders & {
54
+ 'Custom-Header'?: string
55
+ }
56
+ }
57
+ `,
58
+ file: `${projectName}/src/@types/custom/request.d.ts`
59
+ },
60
+ response: {
61
+ content: `type ExpressResponse = import('express').Response
62
+
63
+ interface CustomResponse extends ExpressResponse {
64
+ newValue?: string
65
+ }
66
+ `,
67
+ file: `${projectName}/src/@types/custom/response.d.ts`
68
+ }
69
+ }
70
+ })
71
+ }
72
+
73
+ await writeFile(types.index.file, types.index.content)
74
+ await writeFile(types.models.user.file, types.models.user.content)
75
+
76
+ if (express) {
77
+ await writeFile(types.custom.request.file, types.custom.request.content)
78
+ await writeFile(types.custom.response.file, types.custom.response.content)
79
+ }
80
+ }