Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 0 additions & 32 deletions .babelrc

This file was deleted.

20 changes: 9 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ FROM node:jod-slim AS build

WORKDIR /usr/src/app

COPY package.json yarn.lock tsconfig.json .babelrc ./
COPY package.json yarn.lock tsconfig.json build.mjs ./

RUN yarn install --production=false
RUN yarn install --frozen-lockfile --production=false

COPY ./src/ ./src/

Expand Down Expand Up @@ -56,20 +56,18 @@ RUN \
--shell /usr/sbin/nologin \
hcf_api

USER hcf_api

WORKDIR /home/hcf_api/app

COPY package.json yarn.lock ./
COPY --chown=hcf_api:hcf_api package.json yarn.lock ./

RUN yarn install --production && \
RUN yarn install --frozen-lockfile --production && \
yarn cache clean --force

COPY --from=build /usr/src/app/dist ./dist
COPY ./public ./public
COPY src/reports/assets/fonts/*.ttf /usr/share/fonts/truetype/

RUN chown -R hcf_api:hcf_api /home/hcf_api

USER hcf_api
COPY --from=build --chown=hcf_api:hcf_api /usr/src/app/dist ./dist
COPY --chown=hcf_api:hcf_api ./public ./public
COPY --from=build --chmod=664 /usr/src/app/dist/reports/assets/fonts/*.ttf /usr/share/fonts/truetype/

EXPOSE $PORT

Expand Down
26 changes: 26 additions & 0 deletions build.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { rmSync } from 'node:fs'
import { build } from 'esbuild'
import { globSync } from 'glob'

rmSync('dist', { recursive: true, force: true })

const assets = globSync('src/**/*.{ejs,html,ttf,css}')

await build({
Comment thread
edvaldoszy marked this conversation as resolved.
entryPoints: [
...assets,
'src/index.js',
],
outdir: 'dist',
bundle: true,
minify: true,
platform: 'node',
target: 'node20',
packages: 'external',
loader: {
'.ejs': 'copy',
'.html': 'copy',
'.ttf': 'copy',
'.css': 'copy',
}
})
8 changes: 7 additions & 1 deletion docker-compose.yml → compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ services:
context: .
dockerfile: Dockerfile
platform: linux/amd64
image: hcf-api:local
image: herbario-api:local
container_name: herbario_api
env_file: .env
environment:
PG_HOST: postgres
ports:
- $PORT:$PORT
networks:
- herbario_network
depends_on:
- postgres

nginx:
image: nginx:1.17-alpine
Expand All @@ -43,3 +47,5 @@ services:
- ./uploads:/usr/share/nginx/html
ports:
- 8080:80
depends_on:
- api
5 changes: 3 additions & 2 deletions eslint.config.mts → eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import js from '@eslint/js'
Comment thread
edvaldoszy marked this conversation as resolved.
import stylistic from '@stylistic/eslint-plugin'
import type { ESLint } from 'eslint'
// @ts-expect-error: No declaration file found
import importHelpers from 'eslint-plugin-import-helpers'
import { defineConfig } from 'eslint/config'
Expand All @@ -15,6 +14,8 @@ export default defineConfig([
'public/',
'coverage/',
'node_modules/',
'build.mjs',
'eslint.config.mjs',
'.pnp.cjs',
'.pnp.loader.mjs',
'.yarn/',
Expand All @@ -27,7 +28,7 @@ export default defineConfig([
js,
stylistic,
tseslint,
'import-helpers': importHelpers as unknown as ESLint.Plugin
"import-helpers": importHelpers
},
languageOptions: {
parserOptions: {
Expand Down
21 changes: 5 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@
"tsc:check": "tsc --noEmit",
"lint:eslint": "eslint --cache",
"lint": "run-p tsc:check lint:eslint",
"clean": "rimraf dist",
"build:app": "babel -d ./dist -x '.js,.ts,.tsx' --copy-files --no-copy-ignored ./src",
"start": "nodemon --ext 'js,ts,tsx' --exec babel-node --extensions '.js,.ts,.tsx' ./src/index.js",
"build": "run-s clean build:app",
"start": "tsx --watch --env-file=.env src/index.js",
"build": "node build.mjs",
"test": "vitest --run",
"test:coverage": "vitest --run --coverage",
"prepare": "husky",
Expand Down Expand Up @@ -58,36 +56,27 @@
"swagger-jsdoc": "6.2.8",
"swagger-ui-express": "5.0.1",
"throttled-queue": "3.0.0",
"tsx": "4.20.6",
"uuid": "13.0.0",
"wkx": "^0.5.0"
},
"devDependencies": {
"@babel/cli": "7.28.3",
"@babel/core": "7.28.5",
"@babel/node": "7.28.0",
"@babel/plugin-proposal-class-properties": "7.18.6",
"@babel/preset-env": "7.28.5",
"@babel/preset-react": "7.28.5",
"@babel/preset-typescript": "7.28.5",
"@eslint/js": "9.39.1",
"@stylistic/eslint-plugin": "5.5.0",
"@types/express": "5.0.5",
"@types/pg": "^8.16.0",
"@types/react": "19.2.2",
"@types/react-dom": "19.2.2",
"@vitest/coverage-v8": "4.0.7",
"babel-plugin-module-resolver": "5.0.2",
"chai": "6.2.0",
"chai-http": "^5.1.2",
"esbuild": "0.28.0",
"eslint": "9.39.1",
"eslint-plugin-import-helpers": "2.0.1",
"glob": "10.5.0",
"globals": "16.5.0",
"husky": "9.1.7",
"jiti": "2.6.1",
"nodemon": "3.1.10",
"npm-run-all": "4.1.5",
"rimraf": "6.1.2",
"tsx": "4.21.0",
"typescript": "5.9.3",
"typescript-eslint": "8.46.3",
"vitest": "4.0.7"
Expand Down
22 changes: 18 additions & 4 deletions src/config/directory.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
import { existsSync } from 'node:fs';
import { resolve } from 'node:path';

const { UPLOAD_PATH, STORAGE_PATH } = process.env;
const { UPLOAD_PATH, STORAGE_PATH, SOURCE_ROOT } = process.env;

export const assets = resolve(__dirname, '../../public');
export const upload = UPLOAD_PATH || resolve(__dirname, '../../uploads');
export const storage = STORAGE_PATH || resolve(__dirname, '../../storage');
function getSourceRoot() {
if (SOURCE_ROOT) {
return SOURCE_ROOT;
}

if (!existsSync(resolve('src/views')) && existsSync(resolve('dist/views'))) {
return 'dist';
}

return 'src';
}

export const resolveSource = (...parts) => resolve(getSourceRoot(), ...parts);
export const assets = resolve('public');
export const upload = UPLOAD_PATH || resolve('uploads');
export const storage = STORAGE_PATH || resolve('storage');

export default {};
6 changes: 2 additions & 4 deletions src/controllers/fichas-tombos-controller.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import moment from 'moment-timezone';
import path from 'path';

import { converteDecimalParaGrausMinutosSegundos } from '~/helpers/coordenadas';

// import identificador from '~/routes/identificador';

import { resolveSource } from '../config/directory';
import formataColunasSeparadas from '../helpers/formata-colunas-separadas';
import renderizaArquivoHtml from '../helpers/renderiza-arquivo-html';
import models from '../models';
Expand Down Expand Up @@ -342,7 +340,7 @@ export default function fichaTomboController(request, response, next) {
codigo_barras_selecionado: code,
};

const caminhoArquivoHtml = path.resolve(__dirname, '../views/ficha-tombo.ejs');
const caminhoArquivoHtml = resolveSource('views/ficha-tombo.ejs');
return renderizaArquivoHtml(caminhoArquivoHtml, parametros)
.then(html => {
response.status(200).send(html);
Expand Down
4 changes: 2 additions & 2 deletions src/controllers/tombos-controller.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ForeignKeyConstraintError } from 'sequelize';
import { ForeignKeyConstraintError, fn, col } from 'sequelize';

import { padronizarNomeDarwincore } from '~/helpers/padroniza-nome-darwincore';

Expand All @@ -21,7 +21,7 @@ const SRID = {
const {
Solo, Relevo, Cidade, Estado, Vegetacao, FaseSucessional, Pais, Tipo, LocalColeta, Familia, sequelize,
Genero, Subfamilia, Autor, Coletor, Variedade, Subespecie, TomboFoto, Identificador,
ColecaoAnexa, Especie, Herbario, Tombo, Alteracao, TomboIdentificador, ColetorComplementar, Sequelize: { Op, fn, col },
ColecaoAnexa, Especie, Herbario, Tombo, Alteracao, TomboIdentificador, ColetorComplementar, Sequelize: { Op },
} = models;

function parseDataTombo(valor) {
Expand Down
5 changes: 2 additions & 3 deletions src/controllers/tombos-exportacoes-controller.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import path from 'path';

import { resolveSource } from '../config/directory';
import BadRequestException from '../errors/bad-request-exception';
import PreconditionFailedException from '../errors/precondition-failed-exception';
import knex from '../factories/knex';
Expand Down Expand Up @@ -189,7 +188,7 @@ export default function exportacoes(request, response, next) {
.sort(a => a == 'codigo_barra' ? 1 : -1);
const parametros = { colunas, tombos };

const caminhoArquivoHtml = path.resolve(__dirname, '../views/exportacao-tombos.ejs');
const caminhoArquivoHtml = resolveSource('views/exportacao-tombos.ejs');
return renderizaArquivoHtml(caminhoArquivoHtml, parametros)
.then(html => {
response.status(200).send(html);
Expand Down
16 changes: 13 additions & 3 deletions src/database/migration-file-system.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Knex } from 'knex'
import fs from 'node:fs'
import path from 'node:path'
import { pathToFileURL } from 'node:url'

interface Dependencies {
knex: Knex
Expand Down Expand Up @@ -30,6 +31,7 @@ export class MigrationFileSystem {
const fileName = `${timestamp}_${name}`

const upFilePath = path.join(this.migrationsPath, `${fileName}.ts`)
.replace(/\\/g, '/')

fs.writeFileSync(upFilePath, MIGRATION_TEMPLATE)

Expand All @@ -41,17 +43,25 @@ export class MigrationFileSystem {
return files
.filter(file => /\.[jt]s$/.test(file))
.sort()
.map(file => path.join(this.migrationsPath, file))
.map(file => path.join(this.migrationsPath, file).replace(/\\/g, '/'))
}

private async importMigrationModule(name: string): Promise<{ run: (knex: Knex) => Promise<void> }> {
const filePathWithoutExtension = path.join(this.migrationsPath, name)
const isAbsolute = path.isAbsolute(this.migrationsPath)
Comment thread
edvaldoszy marked this conversation as resolved.

const toSpecifier = (fsPath: string): string => {
if (isAbsolute) {
return pathToFileURL(fsPath).href
}
return fsPath.replace(/\\/g, '/')
}

let migrationModule: { run: (knex: Knex) => Promise<void> }
if (fs.existsSync(`${filePathWithoutExtension}.ts`)) {
migrationModule = await import(`${filePathWithoutExtension}.ts`) as { run: (knex: Knex) => Promise<void> }
migrationModule = await import(toSpecifier(`${filePathWithoutExtension}.ts`)) as { run: (knex: Knex) => Promise<void> }
} else if (fs.existsSync(`${filePathWithoutExtension}.js`)) {
migrationModule = await import(`${filePathWithoutExtension}.js`) as { run: (knex: Knex) => Promise<void> }
migrationModule = await import(toSpecifier(`${filePathWithoutExtension}.js`)) as { run: (knex: Knex) => Promise<void> }
} else {
throw new Error(`Migration file ${name} not found`)
}
Expand Down
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable no-console */
import './setup';
import './setup.js';
import cluster from 'cluster';
import http from 'http';
import os from 'os';
Expand Down
Loading
Loading