diff --git a/CHANGELOG.md b/CHANGELOG.md index 72a1fc4b1..6c435d0c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,34 @@ +# [0.64.0](https://github.com/dzangolab/fastify/compare/v0.63.0...v0.64.0) (2024-03-23) + + +### Features + +* **user:** add permissions while creating role ([#622](https://github.com/dzangolab/fastify/issues/622)) ([5023a51](https://github.com/dzangolab/fastify/commit/5023a5151a210b4a6d71b83be53e08c16e2a4cd3)) + + + +# [0.63.0](https://github.com/dzangolab/fastify/compare/v0.62.4...v0.63.0) (2024-03-22) + + +### Features + +* **config:** add multi-stream support for logger config ([#616](https://github.com/dzangolab/fastify/issues/616)) ([d9ebb2e](https://github.com/dzangolab/fastify/commit/d9ebb2efc4a5785d5e2b6519b4decb1014f6f1af)) + + + +## [0.62.4](https://github.com/dzangolab/fastify/compare/v0.62.3...v0.62.4) (2024-03-21) + + +### Bug Fixes + +* update db filter input type ([#624](https://github.com/dzangolab/fastify/issues/624)) ([7a24d4c](https://github.com/dzangolab/fastify/commit/7a24d4c1a1f308fc9d33d0f387d3866b8dac1e05)) + + + +## [0.62.3](https://github.com/dzangolab/fastify/compare/v0.62.2...v0.62.3) (2024-03-20) + + + ## [0.62.2](https://github.com/dzangolab/fastify/compare/v0.62.1...v0.62.2) (2024-03-07) diff --git a/package.json b/package.json index 2bd30ab82..7bb10cfa0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dzangolab/fastify", - "version": "0.62.2", + "version": "0.64.0", "private": true, "repository": { "type": "git", diff --git a/packages/config/package.json b/packages/config/package.json index f50ebbe95..b59c075e8 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,6 +1,6 @@ { "name": "@dzangolab/fastify-config", - "version": "0.62.2", + "version": "0.64.0", "description": "Fastify config plugin", "homepage": "https://github.com/dzangolab/fastify/tree/main/packages/config#readme", "repository": { @@ -36,11 +36,12 @@ "@typescript-eslint/parser": "5.62.0", "@vitest/coverage-istanbul": "0.32.2", "eslint": "8.56.0", - "eslint-config-custom": "0.62.2", + "eslint-config-custom": "0.64.0", "fastify": "4.10.2", "fastify-plugin": "4.4.0", "prettier": "2.8.8", - "tsconfig": "0.62.2", + "pino": "8.8.0", + "tsconfig": "0.64.0", "typescript": "4.9.5", "vite": "4.3.9", "vitest": "0.32.0" diff --git a/packages/config/src/types.ts b/packages/config/src/types.ts index a3049371e..59b0eea14 100644 --- a/packages/config/src/types.ts +++ b/packages/config/src/types.ts @@ -1,3 +1,10 @@ +import type { + DestinationStream, + Level, + LoggerOptions, + StreamEntry, +} from "pino"; + interface AppConfig { id: number; name: string; @@ -5,6 +12,8 @@ interface AppConfig { supportedRoles: string[]; } +type Compressor = (source: string, destination: string) => string; + interface ApiConfig { appName: string; appOrigin: string[]; @@ -12,15 +21,31 @@ interface ApiConfig { baseUrl: string; env: string; logger: { - level: string; - transport?: { - target: string; + base?: LoggerOptions["base"]; + formatters?: LoggerOptions["formatters"]; + level: Level; + prettyPrint?: { options: { colorize: boolean; ignore: string; translateTime: string; }; }; + rotation?: { + enabled: boolean; + options: { + compress?: boolean | string | Compressor; + filenames: string[]; + interval?: string; + maxFiles?: number; + maxSize?: string; + path: string; + size?: string; + }; + }; + streams?: (DestinationStream | StreamEntry)[]; + transport?: LoggerOptions["transport"]; + timestamp?: LoggerOptions["timestamp"]; }; name: string; pagination?: { diff --git a/packages/firebase/package.json b/packages/firebase/package.json index c8b423c3c..287083357 100644 --- a/packages/firebase/package.json +++ b/packages/firebase/package.json @@ -1,6 +1,6 @@ { "name": "@dzangolab/fastify-firebase", - "version": "0.62.2", + "version": "0.64.0", "description": "Fastify firebase plugin", "homepage": "https://github.com/dzangolab/fastify/tree/main/packages/firebase#readme", "repository": { @@ -35,30 +35,30 @@ "zod": "3.22.4" }, "devDependencies": { - "@dzangolab/fastify-config": "0.62.2", - "@dzangolab/fastify-mercurius": "0.62.2", - "@dzangolab/fastify-slonik": "0.62.2", + "@dzangolab/fastify-config": "0.64.0", + "@dzangolab/fastify-mercurius": "0.64.0", + "@dzangolab/fastify-slonik": "0.64.0", "@types/node": "18.16.18", "@typescript-eslint/eslint-plugin": "5.62.0", "@typescript-eslint/parser": "5.62.0", "@vitest/coverage-istanbul": "0.32.2", "eslint": "8.56.0", - "eslint-config-custom": "0.62.2", + "eslint-config-custom": "0.64.0", "fastify": "4.10.2", "fastify-plugin": "4.4.0", "mercurius": "12.2.0", "prettier": "2.8.8", "slonik": "37.2.0", "supertokens-node": "15.0.4", - "tsconfig": "0.62.2", + "tsconfig": "0.64.0", "typescript": "4.9.5", "vite": "4.3.9", "vitest": "0.32.0" }, "peerDependencies": { - "@dzangolab/fastify-config": "0.62.2", - "@dzangolab/fastify-mercurius": "0.62.2", - "@dzangolab/fastify-slonik": "0.62.2", + "@dzangolab/fastify-config": "0.64.0", + "@dzangolab/fastify-mercurius": "0.64.0", + "@dzangolab/fastify-slonik": "0.64.0", "fastify": ">=4.10.2", "fastify-plugin": ">=4.4.0", "firebase-admin": "12.0.0", diff --git a/packages/mailer/package.json b/packages/mailer/package.json index 2afd9b81d..a9cbbc051 100644 --- a/packages/mailer/package.json +++ b/packages/mailer/package.json @@ -1,6 +1,6 @@ { "name": "@dzangolab/fastify-mailer", - "version": "0.62.2", + "version": "0.64.0", "description": "Fastify mailer plugin", "homepage": "https://github.com/dzangolab/fastify/tree/main/packages/mailer#readme", "repository": { @@ -39,7 +39,7 @@ "nodemailer-mjml": "1.2.24" }, "devDependencies": { - "@dzangolab/fastify-config": "0.62.2", + "@dzangolab/fastify-config": "0.64.0", "@types/mjml": "4.7.4", "@types/node": "18.16.18", "@types/nodemailer": "6.4.14", @@ -48,18 +48,18 @@ "@typescript-eslint/parser": "5.62.0", "@vitest/coverage-istanbul": "0.32.2", "eslint": "8.56.0", - "eslint-config-custom": "0.62.2", + "eslint-config-custom": "0.64.0", "fastify": "4.10.2", "fastify-plugin": "4.4.0", "mjml": "4.14.1", "prettier": "2.8.8", - "tsconfig": "0.62.2", + "tsconfig": "0.64.0", "typescript": "4.9.5", "vite": "4.3.9", "vitest": "0.32.2" }, "peerDependencies": { - "@dzangolab/fastify-config": "0.62.2", + "@dzangolab/fastify-config": "0.64.0", "fastify": ">=4.9.2", "fastify-plugin": ">=4.3.0", "mjml": ">=4.13.0" diff --git a/packages/mercurius/package.json b/packages/mercurius/package.json index 2992e5564..a2af81b19 100644 --- a/packages/mercurius/package.json +++ b/packages/mercurius/package.json @@ -1,6 +1,6 @@ { "name": "@dzangolab/fastify-mercurius", - "version": "0.62.2", + "version": "0.64.0", "description": "Fastify mercurius plugin", "homepage": "https://github.com/dzangolab/fastify/tree/main/packages/mercurius#readme", "repository": { @@ -31,28 +31,28 @@ "typecheck": "tsc --noEmit -p tsconfig.json --composite false" }, "devDependencies": { - "@dzangolab/fastify-config": "0.62.2", - "@dzangolab/fastify-slonik": "0.62.2", + "@dzangolab/fastify-config": "0.64.0", + "@dzangolab/fastify-slonik": "0.64.0", "@types/node": "18.16.18", "@typescript-eslint/eslint-plugin": "5.62.0", "@typescript-eslint/parser": "5.62.0", "@vitest/coverage-istanbul": "0.32.2", "eslint": "8.56.0", - "eslint-config-custom": "0.62.2", + "eslint-config-custom": "0.64.0", "fastify": "4.10.2", "fastify-plugin": "4.4.0", "graphql": "16.6.0", "mercurius": "12.2.0", "prettier": "2.8.8", "slonik": "37.2.0", - "tsconfig": "0.62.2", + "tsconfig": "0.64.0", "typescript": "4.9.5", "vite": "4.3.9", "vitest": "0.32.2" }, "peerDependencies": { - "@dzangolab/fastify-config": "0.62.2", - "@dzangolab/fastify-slonik": "0.62.2", + "@dzangolab/fastify-config": "0.64.0", + "@dzangolab/fastify-slonik": "0.64.0", "fastify": ">=4.9.2", "fastify-plugin": ">=4.3.0", "graphql": ">=16.6.0", diff --git a/packages/multi-tenant/package.json b/packages/multi-tenant/package.json index 4aa737ac2..76dff0d65 100644 --- a/packages/multi-tenant/package.json +++ b/packages/multi-tenant/package.json @@ -1,6 +1,6 @@ { "name": "@dzangolab/fastify-multi-tenant", - "version": "0.62.2", + "version": "0.64.0", "description": "Fastify multi-tenant plugin", "homepage": "https://github.com/dzangolab/fastify/tree/main/packages/multi-tenant#readme", "repository": { @@ -37,10 +37,10 @@ "pg": "8.11.3" }, "devDependencies": { - "@dzangolab/fastify-config": "0.62.2", - "@dzangolab/fastify-mercurius": "0.62.2", - "@dzangolab/fastify-slonik": "0.62.2", - "@dzangolab/fastify-user": "0.62.2", + "@dzangolab/fastify-config": "0.64.0", + "@dzangolab/fastify-mercurius": "0.64.0", + "@dzangolab/fastify-slonik": "0.64.0", + "@dzangolab/fastify-user": "0.64.0", "@types/humps": "2.0.6", "@types/lodash.merge": "4.6.9", "@types/node": "18.16.18", @@ -49,14 +49,14 @@ "@typescript-eslint/parser": "5.62.0", "@vitest/coverage-istanbul": "0.32.2", "eslint": "8.56.0", - "eslint-config-custom": "0.62.2", + "eslint-config-custom": "0.64.0", "fastify": "4.10.2", "fastify-plugin": "4.4.0", "mercurius": "12.2.0", "prettier": "2.8.8", "slonik": "37.2.0", "supertokens-node": "15.0.4", - "tsconfig": "0.62.2", + "tsconfig": "0.64.0", "typescript": "4.9.5", "vite": "4.3.9", "vite-tsconfig-paths": "4.2.3", @@ -64,10 +64,10 @@ "zod": "3.22.4" }, "peerDependencies": { - "@dzangolab/fastify-config": "0.62.2", - "@dzangolab/fastify-mercurius": "0.62.2", - "@dzangolab/fastify-slonik": "0.62.2", - "@dzangolab/fastify-user": "0.62.2", + "@dzangolab/fastify-config": "0.64.0", + "@dzangolab/fastify-mercurius": "0.64.0", + "@dzangolab/fastify-slonik": "0.64.0", + "@dzangolab/fastify-user": "0.64.0", "fastify": ">=4.9.2", "fastify-plugin": ">=4.3.0", "mercurius": ">=12.2.0", diff --git a/packages/multi-tenant/src/lib/validateTenantSchema.ts b/packages/multi-tenant/src/lib/validateTenantSchema.ts index e6ae63b67..656fc68b5 100644 --- a/packages/multi-tenant/src/lib/validateTenantSchema.ts +++ b/packages/multi-tenant/src/lib/validateTenantSchema.ts @@ -33,9 +33,21 @@ const validateTenantInput = ( const validationResult = tenantInputSchema.safeParse(mappedTenantInput); if (!validationResult.success) { + if ( + validationResult.error.issues.some((issue) => { + return issue.path.includes("slug"); + }) + ) { + throw { + name: "ERROR_INVALID_SLUG", + message: "Invalid slug", + statusCode: 422, + }; + } + throw { - message: validationResult.error.issues[0].message, - issues: validationResult.error.issues, + name: "ERROR_INVALID_DOMAIN", + message: "Invalid domain", statusCode: 422, }; } @@ -59,8 +71,8 @@ const validateTenantUpdate = ( if (!validationResult.success) { throw { - message: validationResult.error.issues[0].message, - issues: validationResult.error.issues, + name: "ERROR_INVALID_DOMAIN", + message: "Invalid domain", statusCode: 422, }; } diff --git a/packages/multi-tenant/src/model/tenants/service.ts b/packages/multi-tenant/src/model/tenants/service.ts index 48764c442..8910c2cd4 100644 --- a/packages/multi-tenant/src/model/tenants/service.ts +++ b/packages/multi-tenant/src/model/tenants/service.ts @@ -48,7 +48,7 @@ class TenantService< if (getAllReservedSlugs(this.config).includes(data[slugColumn] as string)) { throw { - name: "CREATE_TENANT_FAILED", + name: "ERROR_RESERVED_SLUG", message: `The requested ${slugColumn} "${data[slugColumn]}" is reserved and cannot be used`, statusCode: 422, }; @@ -58,7 +58,7 @@ class TenantService< getAllReservedDomains(this.config).includes(data[domainColumn] as string) ) { throw { - name: "CREATE_TENANT_FAILED", + name: "ERROR_RESERVED_DOMAIN", message: `The requested ${domainColumn} "${data[domainColumn]}" is reserved and cannot be used`, statusCode: 422, }; @@ -106,9 +106,17 @@ class TenantService< const { slug: slugColumn, domain: domainColumn } = multiTenantConfig.table.columns; + if (tenants.some((tenant) => tenant[slugColumn] === slug)) { + throw { + name: "ERROR_SLUG_ALREADY_EXISTS", + message: `The specified ${slugColumn} "${slug}" already exits`, + statusCode: 422, + }; + } + throw { - name: "FIELD_VALIDATION_FAILED", - message: `The specified ${slugColumn} "${slug}" or ${domainColumn} "${domain}" already exits`, + name: "ERROR_DOMAIN_ALREADY_EXISTS", + message: `The specified ${domainColumn} "${domain}" already exits`, statusCode: 422, }; } diff --git a/packages/s3/package.json b/packages/s3/package.json index d7beed03b..3658c33da 100644 --- a/packages/s3/package.json +++ b/packages/s3/package.json @@ -1,6 +1,6 @@ { "name": "@dzangolab/fastify-s3", - "version": "0.62.2", + "version": "0.64.0", "description": "Fastify S3 plugin", "homepage": "https://github.com/dzangolab/fastify/tree/main/packages/s3#readme", "repository": { @@ -43,28 +43,28 @@ "zod": "3.22.4" }, "devDependencies": { - "@dzangolab/fastify-config": "0.62.2", - "@dzangolab/fastify-mercurius": "0.62.2", - "@dzangolab/fastify-slonik": "0.62.2", + "@dzangolab/fastify-config": "0.64.0", + "@dzangolab/fastify-mercurius": "0.64.0", + "@dzangolab/fastify-slonik": "0.64.0", "@types/node": "18.16.18", "@typescript-eslint/eslint-plugin": "5.62.0", "@typescript-eslint/parser": "5.62.0", "@vitest/coverage-istanbul": "0.32.2", "eslint": "8.56.0", - "eslint-config-custom": "0.62.2", + "eslint-config-custom": "0.64.0", "fastify": "4.10.2", "fastify-plugin": "4.4.0", "prettier": "2.8.8", "slonik": "37.2.0", - "tsconfig": "0.62.2", + "tsconfig": "0.64.0", "typescript": "4.9.5", "vite": "4.3.9", "vitest": "0.32.2" }, "peerDependencies": { - "@dzangolab/fastify-config": "0.62.2", - "@dzangolab/fastify-mercurius": "0.62.2", - "@dzangolab/fastify-slonik": "0.62.2", + "@dzangolab/fastify-config": "0.64.0", + "@dzangolab/fastify-mercurius": "0.64.0", + "@dzangolab/fastify-slonik": "0.64.0", "fastify": ">=4.10.2", "fastify-plugin": ">=4.4.0", "slonik": ">=37.2.0", diff --git a/packages/slonik/package.json b/packages/slonik/package.json index c5f01c03b..67b6760f4 100644 --- a/packages/slonik/package.json +++ b/packages/slonik/package.json @@ -1,6 +1,6 @@ { "name": "@dzangolab/fastify-slonik", - "version": "0.62.2", + "version": "0.64.0", "description": "Fastify slonik plugin", "homepage": "https://github.com/dzangolab/fastify/tree/main/packages/slonik#readme", "repository": { @@ -36,7 +36,7 @@ "pg": "8.11.3" }, "devDependencies": { - "@dzangolab/fastify-config": "0.62.2", + "@dzangolab/fastify-config": "0.64.0", "@types/humps": "2.0.6", "@types/node": "18.16.18", "@types/pg": "8.10.9", @@ -44,19 +44,19 @@ "@typescript-eslint/parser": "5.62.0", "@vitest/coverage-istanbul": "0.32.2", "eslint": "8.56.0", - "eslint-config-custom": "0.62.2", + "eslint-config-custom": "0.64.0", "fastify": "4.10.2", "fastify-plugin": "4.4.0", "prettier": "2.8.8", "slonik": "37.2.0", - "tsconfig": "0.62.2", + "tsconfig": "0.64.0", "typescript": "4.9.5", "vite": "4.3.9", "vitest": "0.32.2", "zod": "3.22.4" }, "peerDependencies": { - "@dzangolab/fastify-config": "0.62.2", + "@dzangolab/fastify-config": "0.64.0", "fastify": ">=4.9.2", "fastify-plugin": ">=4.3.0", "slonik": ">=37.2.0", diff --git a/packages/slonik/src/__test__/helpers/utils.ts b/packages/slonik/src/__test__/helpers/utils.ts index 0cd0295ed..5183e614b 100644 --- a/packages/slonik/src/__test__/helpers/utils.ts +++ b/packages/slonik/src/__test__/helpers/utils.ts @@ -1,24 +1,45 @@ +import { ApiConfig } from "@dzangolab/fastify-config"; + import type { FilterInput, SortInput } from "../../types"; -import type { ApiConfig } from "@dzangolab/fastify-config"; -const getFilterDataset = () => { +const getFilterDataset = (): FilterInput[] => { return [ - { key: "name", operator: "ct", value: "Test" }, - { key: "name", operator: "ew", value: "t1" }, - { key: "name", operator: "sw", value: "Test" }, - { key: "name", operator: "eq", value: "Test" }, - { key: "id", operator: "gt", value: 10 }, - { key: "id", operator: "gte", value: 10 }, - { key: "id", operator: "lt", value: 10 }, - { key: "id", operator: "lte", value: 10 }, - { key: "name", operator: "in", value: "Test1, Test2" }, - { key: "id", operator: "bt", value: "10, 20" }, - { key: "id", not: true, operator: "bt", value: "10, 20" }, - { key: "name", operator: "eq", value: "null" }, - { key: "name", not: true, operator: "eq", value: "NULL" }, - { key: "countryCode", operator: "eq", value: "FR" }, - { key: "country_code", operator: "eq", value: "FR" }, - ] as FilterInput[]; + { key: "name", operator: "sw", value: "s" }, + { + AND: [ + { key: "name", operator: "sw", value: "s" }, + { key: "latitude", operator: "gt", value: "40" }, + ], + }, + { + OR: [ + { key: "name", operator: "sw", value: "Test" }, + { key: "name", operator: "ew", value: "t1" }, + ], + }, + { + AND: [ + { key: "id", operator: "gt", value: "10" }, + { + OR: [ + { key: "name", operator: "sw", value: "Test" }, + { key: "name", operator: "ew", value: "t1" }, + ], + }, + ], + }, + { + OR: [ + { key: "id", operator: "gt", value: "10" }, + { + AND: [ + { key: "name", operator: "sw", value: "Test" }, + { key: "name", operator: "ew", value: "t1" }, + ], + }, + ], + }, + ]; }; const getLimitAndOffsetDataset = async (count: number, config: ApiConfig) => { @@ -84,7 +105,7 @@ const getLimitAndOffsetDataset = async (count: number, config: ApiConfig) => { ]; }; -const getSortDataset = () => { +const getSortDataset = (): SortInput[][] => { return [ [{ key: "name", direction: "ASC" }], [{ key: "id", direction: "DESC" }], @@ -94,7 +115,7 @@ const getSortDataset = () => { { key: "id", direction: "DESC" }, { key: "name", direction: "ASC" }, ], - ] as SortInput[][]; + ]; }; export { getFilterDataset, getLimitAndOffsetDataset, getSortDataset }; diff --git a/packages/slonik/src/dbFilters.ts b/packages/slonik/src/dbFilters.ts index 94a2ff8d3..4455ccb07 100644 --- a/packages/slonik/src/dbFilters.ts +++ b/packages/slonik/src/dbFilters.ts @@ -1,13 +1,12 @@ import humps from "humps"; import { sql } from "slonik"; -import { FilterInput } from "./types"; - +import type { BaseFilterInput, FilterInput } from "./types"; import type { IdentifierSqlToken, FragmentSqlToken } from "slonik"; const applyFilter = ( - filter: FilterInput, - tableIdentifier: IdentifierSqlToken + tableIdentifier: IdentifierSqlToken, + filter: BaseFilterInput ) => { const key = humps.decamelize(filter.key); const operator = filter.operator || "eq"; @@ -87,16 +86,16 @@ const applyFiltersToQuery = ( tableIdentifier: IdentifierSqlToken, not = false ) => { - if (filters.AND) { + if ("AND" in filters) { for (const filterData of filters.AND) { applyFilters(filterData, tableIdentifier); } - } else if (filters.OR) { + } else if ("OR" in filters) { for (const filterData of filters.OR) { applyFilters(filterData, tableIdentifier, true); } } else { - const query = applyFilter(filters, tableIdentifier); + const query = applyFilter(tableIdentifier, filters as BaseFilterInput); if (not) { orFilter.push(query); @@ -114,7 +113,9 @@ const applyFiltersToQuery = ( sql.fragment`(${sql.join(andFilter, sql.fragment` AND `)})`, sql.fragment`(${sql.join(orFilter, sql.fragment` OR `)})`, ], - sql.fragment`${filters.AND ? sql.fragment` AND ` : sql.fragment` OR `}` + sql.fragment`${ + "AND" in filters ? sql.fragment` AND ` : sql.fragment` OR ` + }` ); } else if (andFilter.length > 0) { queryFilter = sql.join(andFilter, sql.fragment` AND `); diff --git a/packages/slonik/src/index.ts b/packages/slonik/src/index.ts index bf5bfdea8..3e501007a 100644 --- a/packages/slonik/src/index.ts +++ b/packages/slonik/src/index.ts @@ -52,6 +52,7 @@ export { default as formatDate } from "./formatDate"; export { default as migrationPlugin } from "./migrationPlugin"; export type { + BaseFilterInput, Database, FilterInput, PaginatedList, diff --git a/packages/slonik/src/types/database.ts b/packages/slonik/src/types/database.ts index a8c95fb69..7a9f1293f 100644 --- a/packages/slonik/src/types/database.ts +++ b/packages/slonik/src/types/database.ts @@ -18,15 +18,22 @@ type operator = | "in" | "bt"; -type FilterInput = { - AND: FilterInput[]; - OR: FilterInput[]; +type BaseFilterInput = { key: string; operator: operator; - not: boolean; + not?: boolean; value: string; }; +type FilterInput = + | BaseFilterInput + | { + AND: FilterInput[]; + } + | { + OR: FilterInput[]; + }; + type SortDirection = "ASC" | "DESC"; type SortInput = { @@ -34,4 +41,10 @@ type SortInput = { direction: SortDirection; }; -export type { Database, FilterInput, SortDirection, SortInput }; +export type { + BaseFilterInput, + Database, + FilterInput, + SortDirection, + SortInput, +}; diff --git a/packages/slonik/src/types/index.ts b/packages/slonik/src/types/index.ts index e08a0a102..ede149f7c 100644 --- a/packages/slonik/src/types/index.ts +++ b/packages/slonik/src/types/index.ts @@ -5,6 +5,7 @@ export type { FilterInput, SortDirection, SortInput, + BaseFilterInput, } from "./database"; export type { PaginatedList, Service } from "./service"; diff --git a/packages/user/package.json b/packages/user/package.json index da722d57b..17718a8cf 100644 --- a/packages/user/package.json +++ b/packages/user/package.json @@ -1,6 +1,6 @@ { "name": "@dzangolab/fastify-user", - "version": "0.62.2", + "version": "0.64.0", "description": "Fastify user plugin", "homepage": "https://github.com/dzangolab/fastify/tree/main/packages/user#readme", "repository": { @@ -36,10 +36,10 @@ "zod": "3.22.4" }, "devDependencies": { - "@dzangolab/fastify-config": "0.62.2", - "@dzangolab/fastify-mailer": "0.62.2", - "@dzangolab/fastify-mercurius": "0.62.2", - "@dzangolab/fastify-slonik": "0.62.2", + "@dzangolab/fastify-config": "0.64.0", + "@dzangolab/fastify-mailer": "0.64.0", + "@dzangolab/fastify-mercurius": "0.64.0", + "@dzangolab/fastify-slonik": "0.64.0", "@fastify/cors": "8.3.0", "@fastify/formbody": "7.4.0", "@types/humps": "2.0.6", @@ -49,7 +49,7 @@ "@typescript-eslint/parser": "5.62.0", "@vitest/coverage-istanbul": "0.32.2", "eslint": "8.56.0", - "eslint-config-custom": "0.62.2", + "eslint-config-custom": "0.64.0", "fastify": "4.10.2", "fastify-plugin": "4.4.0", "mercurius": "12.2.0", @@ -57,16 +57,16 @@ "prettier": "2.8.8", "slonik": "37.2.0", "supertokens-node": "15.0.4", - "tsconfig": "0.62.2", + "tsconfig": "0.64.0", "typescript": "4.9.5", "vite": "4.3.9", "vitest": "0.32.2" }, "peerDependencies": { - "@dzangolab/fastify-config": "0.62.2", - "@dzangolab/fastify-mailer": "0.62.2", - "@dzangolab/fastify-mercurius": "0.62.2", - "@dzangolab/fastify-slonik": "0.62.2", + "@dzangolab/fastify-config": "0.64.0", + "@dzangolab/fastify-mailer": "0.64.0", + "@dzangolab/fastify-mercurius": "0.64.0", + "@dzangolab/fastify-slonik": "0.64.0", "@fastify/cors": ">=8.2.0", "@fastify/formbody": ">=7.4.0", "fastify": ">=4.10.2", diff --git a/packages/user/src/customApiError.ts b/packages/user/src/customApiError.ts new file mode 100644 index 000000000..750b32949 --- /dev/null +++ b/packages/user/src/customApiError.ts @@ -0,0 +1,20 @@ +interface CustomApiErrorType { + message: string; + name: string; + statusCode: number; +} + +class CustomApiError extends Error { + public statusCode: number; + + constructor({ message, name, statusCode }: CustomApiErrorType) { + super(message); + this.message = message; + this.name = name; + this.statusCode = statusCode; + } +} + +export default CustomApiError; + +export type { CustomApiErrorType }; diff --git a/packages/user/src/model/invitations/resolver.ts b/packages/user/src/model/invitations/resolver.ts index 24c419798..96c71c59b 100644 --- a/packages/user/src/model/invitations/resolver.ts +++ b/packages/user/src/model/invitations/resolver.ts @@ -3,7 +3,7 @@ import mercurius from "mercurius"; import { createNewSession } from "supertokens-node/recipe/session"; import { emailPasswordSignUp } from "supertokens-node/recipe/thirdpartyemailpassword"; -import { ROLE_ADMIN, TENANT_ID } from "../../constants"; +import { ROLE_USER, TENANT_ID } from "../../constants"; import computeInvitationExpiresAt from "../../lib/computeInvitationExpiresAt"; import getInvitationService from "../../lib/getInvitationService"; import isInvitationValid from "../../lib/isInvitationValid"; @@ -185,7 +185,7 @@ const Mutation = { email, expiresAt: computeInvitationExpiresAt(config, expiresAt), invitedById: user.id, - role: role || config.user.role || ROLE_ADMIN, + role: role || config.user.role || ROLE_USER, }; const app = config.apps?.find((app) => app.id == appId); diff --git a/packages/user/src/model/roles/controller.ts b/packages/user/src/model/roles/controller.ts index 964ad9fd8..5140ae553 100644 --- a/packages/user/src/model/roles/controller.ts +++ b/packages/user/src/model/roles/controller.ts @@ -8,6 +8,14 @@ const plugin = async ( options: unknown, done: () => void ) => { + fastify.delete( + ROUTE_ROLES, + { + preHandler: [fastify.verifySession()], + }, + handlers.deleteRole + ); + fastify.get( ROUTE_ROLES, { diff --git a/packages/user/src/model/roles/handlers/createRole.ts b/packages/user/src/model/roles/handlers/createRole.ts index 528ac25a0..415558fc5 100644 --- a/packages/user/src/model/roles/handlers/createRole.ts +++ b/packages/user/src/model/roles/handlers/createRole.ts @@ -6,15 +6,17 @@ import type { SessionRequest } from "supertokens-node/framework/fastify"; const createRole = async (request: SessionRequest, reply: FastifyReply) => { const { body, log } = request; - const { role } = body as { + const { role, permissions } = body as { role: string; + permissions: string[]; }; try { const service = new RoleService(); - await service.createRole(role); - return reply.send({ role }); + const createResponse = await service.createRole(role, permissions); + + return reply.send(createResponse); } catch (error) { log.error(error); reply.status(500); diff --git a/packages/user/src/model/roles/handlers/deleteRole.ts b/packages/user/src/model/roles/handlers/deleteRole.ts new file mode 100644 index 000000000..79a137523 --- /dev/null +++ b/packages/user/src/model/roles/handlers/deleteRole.ts @@ -0,0 +1,61 @@ +import CustomApiError from "../../../customApiError"; +import RoleService from "../service"; + +import type { FastifyReply } from "fastify"; +import type { SessionRequest } from "supertokens-node/framework/fastify"; + +const deleteRole = async (request: SessionRequest, reply: FastifyReply) => { + const { log, query } = request; + + try { + let { role } = query as { role?: string }; + + if (role) { + try { + role = JSON.parse(role) as string; + } catch { + /* empty */ + } + + if (typeof role != "string") { + throw new CustomApiError({ + name: "UNKNOWN_ROLE_ERROR", + message: `Invalid role`, + statusCode: 422, + }); + } + + const service = new RoleService(); + + const deleteResponse = await service.deleteRole(role); + + return reply.send(deleteResponse); + } + + throw new CustomApiError({ + name: "UNKNOWN_ROLE_ERROR", + message: `Invalid role`, + statusCode: 422, + }); + } catch (error) { + if (error instanceof CustomApiError) { + reply.status(error.statusCode); + + return reply.send({ + message: error.message, + name: error.name, + statusCode: error.statusCode, + }); + } + + log.error(error); + reply.status(500); + + return reply.send({ + status: "ERROR", + message: "Oops! Something went wrong", + }); + } +}; + +export default deleteRole; diff --git a/packages/user/src/model/roles/handlers/getPermissions.ts b/packages/user/src/model/roles/handlers/getPermissions.ts index e70ccac79..dcda6ae2f 100644 --- a/packages/user/src/model/roles/handlers/getPermissions.ts +++ b/packages/user/src/model/roles/handlers/getPermissions.ts @@ -8,9 +8,19 @@ const getPermissions = async (request: SessionRequest, reply: FastifyReply) => { let permissions: string[] = []; try { - const { role } = query as { role?: string }; + let { role } = query as { role?: string }; if (role) { + try { + role = JSON.parse(role) as string; + } catch { + /* empty */ + } + + if (typeof role != "string") { + return reply.send({ permissions }); + } + const service = new RoleService(); permissions = await service.getPermissionsForRole(role); diff --git a/packages/user/src/model/roles/handlers/index.ts b/packages/user/src/model/roles/handlers/index.ts index 990facb3b..9176aedec 100644 --- a/packages/user/src/model/roles/handlers/index.ts +++ b/packages/user/src/model/roles/handlers/index.ts @@ -1,9 +1,11 @@ import createRole from "./createRole"; +import deleteRole from "./deleteRole"; import getPermissions from "./getPermissions"; import getRoles from "./getRoles"; import updatePermissions from "./updatePermissions"; export default { + deleteRole, createRole, getRoles, getPermissions, diff --git a/packages/user/src/model/roles/handlers/updatePermissions.ts b/packages/user/src/model/roles/handlers/updatePermissions.ts index 97bc2f083..2bb89c5c9 100644 --- a/packages/user/src/model/roles/handlers/updatePermissions.ts +++ b/packages/user/src/model/roles/handlers/updatePermissions.ts @@ -1,3 +1,4 @@ +import CustomApiError from "../../../customApiError"; import RoleService from "../service"; import type { FastifyReply } from "fastify"; @@ -16,13 +17,23 @@ const updatePermissions = async ( }; const service = new RoleService(); - const updatedPermissions = await service.updateRolePermissions( + const updatedPermissionsResponse = await service.updateRolePermissions( role, permissions ); - return reply.send({ permissions: updatedPermissions }); + return reply.send(updatedPermissionsResponse); } catch (error) { + if (error instanceof CustomApiError) { + reply.status(error.statusCode); + + return reply.send({ + message: error.message, + name: error.name, + statusCode: error.statusCode, + }); + } + log.error(error); reply.status(500); diff --git a/packages/user/src/model/roles/resolver.ts b/packages/user/src/model/roles/resolver.ts index 543ee7a5b..ba1b2ab28 100644 --- a/packages/user/src/model/roles/resolver.ts +++ b/packages/user/src/model/roles/resolver.ts @@ -1,11 +1,44 @@ import mercurius from "mercurius"; import RoleService from "./service"; +import CustomApiError from "../../customApiError"; import type { MercuriusContext } from "mercurius"; const Mutation = { createRole: async ( + parent: unknown, + arguments_: { + role: string; + permissions: string[]; + }, + context: MercuriusContext + ) => { + const { app } = context; + + try { + const service = new RoleService(); + + const createResponse = await service.createRole( + arguments_.role, + arguments_.permissions + ); + + return createResponse; + } catch (error) { + app.log.error(error); + + const mercuriusError = new mercurius.ErrorWithProps( + "Oops, Something went wrong" + ); + + mercuriusError.statusCode = 500; + + return mercuriusError; + } + }, + + deleteRole: async ( parent: unknown, arguments_: { role: string; @@ -16,10 +49,21 @@ const Mutation = { try { const service = new RoleService(); - await service.createRole(arguments_.role); - return arguments_.role; + const { role } = arguments_; + + const deleteResponse = await service.deleteRole(role); + + return deleteResponse; } catch (error) { + if (error instanceof CustomApiError) { + const mercuriusError = new mercurius.ErrorWithProps(error.name); + + mercuriusError.statusCode = error.statusCode; + + return mercuriusError; + } + app.log.error(error); const mercuriusError = new mercurius.ErrorWithProps( @@ -31,6 +75,7 @@ const Mutation = { return mercuriusError; } }, + updateRolePermissions: async ( parent: unknown, arguments_: { @@ -44,13 +89,21 @@ const Mutation = { try { const service = new RoleService(); - const updatedPermissions = await service.updateRolePermissions( + const updatedPermissionsResponse = await service.updateRolePermissions( role, permissions ); - return updatedPermissions; + return updatedPermissionsResponse; } catch (error) { + if (error instanceof CustomApiError) { + const mercuriusError = new mercurius.ErrorWithProps(error.name); + + mercuriusError.statusCode = error.statusCode; + + return mercuriusError; + } + app.log.error(error); const mercuriusError = new mercurius.ErrorWithProps( diff --git a/packages/user/src/model/roles/service.ts b/packages/user/src/model/roles/service.ts index a1ba2ed6f..d21e54838 100644 --- a/packages/user/src/model/roles/service.ts +++ b/packages/user/src/model/roles/service.ts @@ -1,8 +1,43 @@ import UserRoles from "supertokens-node/recipe/userroles"; +import { TENANT_ID } from "../../constants"; +import CustomApiError from "../../customApiError"; + class RoleService { - createRole = async (role: string) => { - await UserRoles.createNewRoleOrAddPermissions(role, []); + createRole = async (role: string, permissions?: string[]) => { + const createRoleResponse = await UserRoles.createNewRoleOrAddPermissions( + role, + permissions || [] + ); + + return createRoleResponse; + }; + + deleteRole = async ( + role: string + ): Promise<{ status: "OK"; didRoleExist: boolean }> => { + const response = await UserRoles.getUsersThatHaveRole(TENANT_ID, role); + + if (response.status === "UNKNOWN_ROLE_ERROR") { + throw new CustomApiError({ + name: response.status, + message: `Invalid role`, + statusCode: 422, + }); + } + + if (response.users.length > 0) { + throw new CustomApiError({ + name: "ROLE_IN_USE", + message: + "The role is currently assigned to one or more users and cannot be deleted", + statusCode: 422, + }); + } + + const deleteRoleResponse = await UserRoles.deleteRole(role); + + return deleteRoleResponse; }; getPermissionsForRole = async (role: string): Promise => { @@ -17,13 +52,23 @@ class RoleService { return permissions; }; - getRoles = async (): Promise => { - let roles: string[] = []; + getRoles = async (): Promise<{ role: string; permissions: string[] }[]> => { + let roles: { role: string; permissions: string[] }[] = []; const response = await UserRoles.getAllRoles(); if (response.status === "OK") { - roles = response.roles; + // [DU 2024-MAR-20] This is N+1 problem + roles = await Promise.all( + response.roles.map(async (role) => { + const response = await UserRoles.getPermissionsForRole(role); + + return { + role, + permissions: response.status === "OK" ? response.permissions : [], + }; + }) + ); } return roles; @@ -32,11 +77,15 @@ class RoleService { updateRolePermissions = async ( role: string, permissions: string[] - ): Promise => { + ): Promise<{ status: "OK"; permissions: string[] }> => { const response = await UserRoles.getPermissionsForRole(role); if (response.status === "UNKNOWN_ROLE_ERROR") { - throw new Error("UNKNOWN_ROLE_ERROR"); + throw new CustomApiError({ + name: "UNKNOWN_ROLE_ERROR", + message: `Invalid role`, + statusCode: 422, + }); } const rolePermissions = response.permissions; @@ -52,7 +101,12 @@ class RoleService { await UserRoles.removePermissionsFromRole(role, removedPermissions); await UserRoles.createNewRoleOrAddPermissions(role, newPermissions); - return this.getPermissionsForRole(role); + const permissionsResponse = await this.getPermissionsForRole(role); + + return { + status: "OK", + permissions: permissionsResponse, + }; }; } diff --git a/packages/user/src/model/users/handlers/adminSignUp.ts b/packages/user/src/model/users/handlers/adminSignUp.ts index 9ee74bcee..eea8da59f 100644 --- a/packages/user/src/model/users/handlers/adminSignUp.ts +++ b/packages/user/src/model/users/handlers/adminSignUp.ts @@ -2,7 +2,7 @@ import { createNewSession } from "supertokens-node/recipe/session"; import { emailPasswordSignUp } from "supertokens-node/recipe/thirdpartyemailpassword"; import UserRoles from "supertokens-node/recipe/userroles"; -import { ROLE_ADMIN, TENANT_ID } from "../../../constants"; +import { ROLE_ADMIN, ROLE_SUPER_ADMIN, TENANT_ID } from "../../../constants"; import validateEmail from "../../../validator/email"; import validatePassword from "../../../validator/password"; @@ -25,13 +25,23 @@ const adminSignUp = async (request: FastifyRequest, reply: FastifyReply) => { TENANT_ID, ROLE_ADMIN ); + const superAdminUsers = await UserRoles.getUsersThatHaveRole( + TENANT_ID, + ROLE_SUPER_ADMIN + ); - if (adminUsers.status === "UNKNOWN_ROLE_ERROR") { + if ( + adminUsers.status === "UNKNOWN_ROLE_ERROR" && + superAdminUsers.status === "UNKNOWN_ROLE_ERROR" + ) { return reply.send({ status: "ERROR", message: adminUsers.status, }); - } else if (adminUsers.users.length > 0) { + } else if ( + (adminUsers.status === "OK" && adminUsers.users.length > 0) || + (superAdminUsers.status === "OK" && superAdminUsers.users.length > 0) + ) { return reply.send({ status: "ERROR", message: "First admin user already exists", @@ -65,7 +75,10 @@ const adminSignUp = async (request: FastifyRequest, reply: FastifyReply) => { password, { autoVerifyEmail: true, - roles: [ROLE_ADMIN], + roles: [ + ROLE_ADMIN, + ...(superAdminUsers.status === "OK" ? [ROLE_SUPER_ADMIN] : []), + ], _default: { request: { request, @@ -81,13 +94,7 @@ const adminSignUp = async (request: FastifyRequest, reply: FastifyReply) => { // create new session so the user be logged in on signup await createNewSession(request, reply, TENANT_ID, signUpResponse.user.id); - reply.send({ - ...signUpResponse, - user: { - ...signUpResponse.user, - roles: [ROLE_ADMIN], - }, - }); + reply.send(signUpResponse); } catch (error) { log.error(error); reply.status(500); diff --git a/packages/user/src/model/users/handlers/canAdminSignUp.ts b/packages/user/src/model/users/handlers/canAdminSignUp.ts index 7f42fbc8a..1e1db60f7 100644 --- a/packages/user/src/model/users/handlers/canAdminSignUp.ts +++ b/packages/user/src/model/users/handlers/canAdminSignUp.ts @@ -1,6 +1,6 @@ import UserRoles from "supertokens-node/recipe/userroles"; -import { ROLE_ADMIN, TENANT_ID } from "../../../constants"; +import { ROLE_ADMIN, ROLE_SUPER_ADMIN, TENANT_ID } from "../../../constants"; import type { FastifyReply, FastifyRequest } from "fastify"; @@ -13,13 +13,23 @@ const canAdminSignUp = async (request: FastifyRequest, reply: FastifyReply) => { TENANT_ID, ROLE_ADMIN ); + const superAdminUsers = await UserRoles.getUsersThatHaveRole( + TENANT_ID, + ROLE_SUPER_ADMIN + ); - if (adminUsers.status === "UNKNOWN_ROLE_ERROR") { + if ( + adminUsers.status === "UNKNOWN_ROLE_ERROR" && + superAdminUsers.status === "UNKNOWN_ROLE_ERROR" + ) { return reply.send({ status: "ERROR", message: adminUsers.status, }); - } else if (adminUsers.users.length > 0) { + } else if ( + (adminUsers.status === "OK" && adminUsers.users.length > 0) || + (superAdminUsers.status === "OK" && superAdminUsers.users.length > 0) + ) { return reply.send({ signUp: false }); } diff --git a/packages/user/src/model/users/resolver.ts b/packages/user/src/model/users/resolver.ts index c8af084eb..4d8ae98d6 100644 --- a/packages/user/src/model/users/resolver.ts +++ b/packages/user/src/model/users/resolver.ts @@ -4,7 +4,7 @@ import { emailPasswordSignUp } from "supertokens-node/recipe/thirdpartyemailpass import UserRoles from "supertokens-node/recipe/userroles"; import filterUserUpdateInput from "./filterUserUpdateInput"; -import { ROLE_ADMIN, TENANT_ID } from "../../constants"; +import { ROLE_ADMIN, ROLE_SUPER_ADMIN, TENANT_ID } from "../../constants"; import getUserService from "../../lib/getUserService"; import validateEmail from "../../validator/email"; import validatePassword from "../../validator/password"; @@ -34,12 +34,22 @@ const Mutation = { TENANT_ID, ROLE_ADMIN ); + const superAdminUsers = await UserRoles.getUsersThatHaveRole( + TENANT_ID, + ROLE_SUPER_ADMIN + ); let errorMessage: string | undefined; - if (adminUsers.status === "UNKNOWN_ROLE_ERROR") { + if ( + adminUsers.status === "UNKNOWN_ROLE_ERROR" && + superAdminUsers.status === "UNKNOWN_ROLE_ERROR" + ) { errorMessage = adminUsers.status; - } else if (adminUsers.users.length > 0) { + } else if ( + (adminUsers.status === "OK" && adminUsers.users.length > 0) || + (superAdminUsers.status === "OK" && superAdminUsers.users.length > 0) + ) { errorMessage = "First admin user already exists"; } @@ -78,7 +88,10 @@ const Mutation = { password, { autoVerifyEmail: true, - roles: [ROLE_ADMIN], + roles: [ + ROLE_ADMIN, + ...(superAdminUsers.status === "OK" ? [ROLE_SUPER_ADMIN] : []), + ], _default: { request: { request: reply.request, @@ -103,13 +116,7 @@ const Mutation = { signUpResponse.user.id ); - return { - ...signUpResponse, - user: { - ...signUpResponse.user, - roles: [ROLE_ADMIN], - }, - }; + return signUpResponse; } catch (error) { // FIXME [OP 28 SEP 2022] app.log.error(error); @@ -270,12 +277,22 @@ const Query = { TENANT_ID, ROLE_ADMIN ); + const superAdminUsers = await UserRoles.getUsersThatHaveRole( + TENANT_ID, + ROLE_SUPER_ADMIN + ); - if (adminUsers.status === "UNKNOWN_ROLE_ERROR") { + if ( + adminUsers.status === "UNKNOWN_ROLE_ERROR" && + superAdminUsers.status === "UNKNOWN_ROLE_ERROR" + ) { const mercuriusError = new mercurius.ErrorWithProps(adminUsers.status); return mercuriusError; - } else if (adminUsers.users.length > 0) { + } else if ( + (adminUsers.status === "OK" && adminUsers.users.length > 0) || + (superAdminUsers.status === "OK" && superAdminUsers.users.length > 0) + ) { return { signUp: false }; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e0fbab6aa..8a8cd475b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,7 +25,7 @@ importers: version: 0.26.3 turbo: specifier: latest - version: 1.6.3 + version: 1.12.5 packages/config: devDependencies: @@ -45,7 +45,7 @@ importers: specifier: 8.56.0 version: 8.56.0 eslint-config-custom: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/eslint-config-custom fastify: specifier: 4.10.2 @@ -53,11 +53,14 @@ importers: fastify-plugin: specifier: 4.4.0 version: 4.4.0 + pino: + specifier: 8.8.0 + version: 8.8.0 prettier: specifier: 2.8.8 version: 2.8.8 tsconfig: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/tsconfig typescript: specifier: 4.9.5 @@ -79,13 +82,13 @@ importers: version: 3.22.4 devDependencies: '@dzangolab/fastify-config': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../config '@dzangolab/fastify-mercurius': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../mercurius '@dzangolab/fastify-slonik': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../slonik '@types/node': specifier: 18.16.18 @@ -103,7 +106,7 @@ importers: specifier: 8.56.0 version: 8.56.0 eslint-config-custom: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/eslint-config-custom fastify: specifier: 4.10.2 @@ -124,7 +127,7 @@ importers: specifier: 15.0.4 version: 15.0.4 tsconfig: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/tsconfig typescript: specifier: 4.9.5 @@ -158,7 +161,7 @@ importers: version: 1.2.24(nodemailer@6.9.8) devDependencies: '@dzangolab/fastify-config': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../config '@types/mjml': specifier: 4.7.4 @@ -185,7 +188,7 @@ importers: specifier: 8.56.0 version: 8.56.0 eslint-config-custom: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/eslint-config-custom fastify: specifier: 4.10.2 @@ -200,7 +203,7 @@ importers: specifier: 2.8.8 version: 2.8.8 tsconfig: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/tsconfig typescript: specifier: 4.9.5 @@ -215,10 +218,10 @@ importers: packages/mercurius: devDependencies: '@dzangolab/fastify-config': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../config '@dzangolab/fastify-slonik': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../slonik '@types/node': specifier: 18.16.18 @@ -236,7 +239,7 @@ importers: specifier: 8.56.0 version: 8.56.0 eslint-config-custom: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/eslint-config-custom fastify: specifier: 4.10.2 @@ -257,7 +260,7 @@ importers: specifier: 37.2.0 version: 37.2.0(zod@3.22.4) tsconfig: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/tsconfig typescript: specifier: 4.9.5 @@ -285,16 +288,16 @@ importers: version: 8.11.3 devDependencies: '@dzangolab/fastify-config': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../config '@dzangolab/fastify-mercurius': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../mercurius '@dzangolab/fastify-slonik': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../slonik '@dzangolab/fastify-user': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../user '@types/humps': specifier: 2.0.6 @@ -321,7 +324,7 @@ importers: specifier: 8.56.0 version: 8.56.0 eslint-config-custom: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/eslint-config-custom fastify: specifier: 4.10.2 @@ -342,7 +345,7 @@ importers: specifier: 15.0.4 version: 15.0.4 tsconfig: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/tsconfig typescript: specifier: 4.9.5 @@ -394,13 +397,13 @@ importers: version: 3.22.4 devDependencies: '@dzangolab/fastify-config': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../config '@dzangolab/fastify-mercurius': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../mercurius '@dzangolab/fastify-slonik': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../slonik '@types/node': specifier: 18.16.18 @@ -418,7 +421,7 @@ importers: specifier: 8.56.0 version: 8.56.0 eslint-config-custom: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/eslint-config-custom fastify: specifier: 4.10.2 @@ -433,7 +436,7 @@ importers: specifier: 37.2.0 version: 37.2.0(zod@3.22.4) tsconfig: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/tsconfig typescript: specifier: 4.9.5 @@ -458,7 +461,7 @@ importers: version: 8.11.3 devDependencies: '@dzangolab/fastify-config': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../config '@types/humps': specifier: 2.0.6 @@ -482,7 +485,7 @@ importers: specifier: 8.56.0 version: 8.56.0 eslint-config-custom: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/eslint-config-custom fastify: specifier: 4.10.2 @@ -497,7 +500,7 @@ importers: specifier: 37.2.0 version: 37.2.0(zod@3.22.4) tsconfig: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/tsconfig typescript: specifier: 4.9.5 @@ -525,16 +528,16 @@ importers: version: 3.22.4 devDependencies: '@dzangolab/fastify-config': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../config '@dzangolab/fastify-mailer': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../mailer '@dzangolab/fastify-mercurius': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../mercurius '@dzangolab/fastify-slonik': - specifier: 0.62.2 + specifier: 0.64.0 version: link:../slonik '@fastify/cors': specifier: 8.3.0 @@ -564,7 +567,7 @@ importers: specifier: 8.56.0 version: 8.56.0 eslint-config-custom: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/eslint-config-custom fastify: specifier: 4.10.2 @@ -588,7 +591,7 @@ importers: specifier: 15.0.4 version: 15.0.4 tsconfig: - specifier: 0.62.2 + specifier: 0.64.0 version: link:../../tools/tsconfig typescript: specifier: 4.9.5 @@ -5192,7 +5195,7 @@ packages: content-type: 1.0.5 find-my-way: 7.3.1 light-my-request: 5.7.0 - pino: 8.7.0 + pino: 8.8.0 process-warning: 2.0.0 proxy-addr: 2.0.7 rfdc: 1.3.0 @@ -7684,8 +7687,8 @@ packages: resolution: {integrity: sha512-mMMOwSKrmyl+Y12Ri2xhH1lbzQxwwpuru9VjyJpgFIH4asSj88F2csdMwN6+M5g1Ll4rmsYghHLQJw81tgZ7LQ==} dev: true - /pino@8.7.0: - resolution: {integrity: sha512-l9sA5uPxmZzwydhMWUcm1gI0YxNnYl8MfSr2h8cwLvOAzQLBLewzF247h/vqHe3/tt6fgtXeG9wdjjoetdI/vA==} + /pino@8.8.0: + resolution: {integrity: sha512-cF8iGYeu2ODg2gIwgAHcPrtR63ILJz3f7gkogaHC/TXVVXxZgInmNYiIpDYEwgEkxZti2Se6P2W2DxlBIZe6eQ==} hasBin: true dependencies: atomic-sleep: 1.0.0 @@ -8902,65 +8905,64 @@ packages: tslib: 1.14.1 typescript: 4.9.5 - /turbo-darwin-64@1.6.3: - resolution: {integrity: sha512-QmDIX0Yh1wYQl0bUS0gGWwNxpJwrzZU2GIAYt3aOKoirWA2ecnyb3R6ludcS1znfNV2MfunP+l8E3ncxUHwtjA==} + /turbo-darwin-64@1.12.5: + resolution: {integrity: sha512-0GZ8reftwNQgIQLHkHjHEXTc/Z1NJm+YjsrBP+qhM/7yIZ3TEy9gJhuogDt2U0xIWwFgisTyzbtU7xNaQydtoA==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.6.3: - resolution: {integrity: sha512-75DXhFpwE7CinBbtxTxH08EcWrxYSPFow3NaeFwsG8aymkWXF+U2aukYHJA6I12n9/dGqf7yRXzkF0S/9UtdyQ==} + /turbo-darwin-arm64@1.12.5: + resolution: {integrity: sha512-8WpOLNNzvH6kohQOjihD+gaWL+ZFNfjvBwhOF0rjEzvW+YR3Pa7KjhulrjWyeN2yMFqAPubTbZIGOz1EVXLuQA==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.6.3: - resolution: {integrity: sha512-O9uc6J0yoRPWdPg9THRQi69K6E2iZ98cRHNvus05lZbcPzZTxJYkYGb5iagCmCW/pq6fL4T4oLWAd6evg2LGQA==} + /turbo-linux-64@1.12.5: + resolution: {integrity: sha512-INit73+bNUpwqGZCxgXCR3I+cQsdkQ3/LkfkgSOibkpg+oGqxJRzeXw3sp990d7SCoE8QOcs3iw+PtiFX/LDAA==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.6.3: - resolution: {integrity: sha512-dCy667qqEtZIhulsRTe8hhWQNCJO0i20uHXv7KjLHuFZGCeMbWxB8rsneRoY+blf8+QNqGuXQJxak7ayjHLxiA==} + /turbo-linux-arm64@1.12.5: + resolution: {integrity: sha512-6lkRBvxtI/GQdGtaAec9LvVQUoRw6nXFp0kM+Eu+5PbZqq7yn6cMkgDJLI08zdeui36yXhone8XGI8pHg8bpUQ==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.6.3: - resolution: {integrity: sha512-lKRqwL3mrVF09b9KySSaOwetehmGknV9EcQTF7d2dxngGYYX1WXoQLjFP9YYH8ZV07oPm+RUOAKSCQuDuMNhiA==} + /turbo-windows-64@1.12.5: + resolution: {integrity: sha512-gQYbOhZg5Ww0bQ/bC0w/4W6yQRwBumUUnkB+QPo15VznwxZe2a7bo6JM+9Xy9dKLa/kn+p7zTqme4OEp6M3/Yg==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.6.3: - resolution: {integrity: sha512-BXY1sDPEA1DgPwuENvDCD8B7Hb0toscjus941WpL8CVd10hg9pk/MWn9CNgwDO5Q9ks0mw+liDv2EMnleEjeNA==} + /turbo-windows-arm64@1.12.5: + resolution: {integrity: sha512-auvhZ9FrhnvQ4mgBlY9O68MT4dIfprYGvd2uPICba/mHUZZvVy5SGgbHJ0KbMwaJfnnFoPgLJO6M+3N2gDprKw==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.6.3: - resolution: {integrity: sha512-FtfhJLmEEtHveGxW4Ye/QuY85AnZ2ZNVgkTBswoap7UMHB1+oI4diHPNyqrQLG4K1UFtCkjOlVoLsllUh/9QRw==} + /turbo@1.12.5: + resolution: {integrity: sha512-FATU5EnhrYG8RvQJYFJnDd18DpccDjyvd53hggw9T9JEg9BhWtIEoeaKtBjYbpXwOVrJQMDdXcIB4f2nD3QPPg==} hasBin: true - requiresBuild: true optionalDependencies: - turbo-darwin-64: 1.6.3 - turbo-darwin-arm64: 1.6.3 - turbo-linux-64: 1.6.3 - turbo-linux-arm64: 1.6.3 - turbo-windows-64: 1.6.3 - turbo-windows-arm64: 1.6.3 + turbo-darwin-64: 1.12.5 + turbo-darwin-arm64: 1.12.5 + turbo-linux-64: 1.12.5 + turbo-linux-arm64: 1.12.5 + turbo-windows-64: 1.12.5 + turbo-windows-arm64: 1.12.5 dev: true /twilio@4.12.0(debug@4.3.4): diff --git a/tools/eslint-config-custom/package.json b/tools/eslint-config-custom/package.json index 4c92f3498..9a910b7c6 100644 --- a/tools/eslint-config-custom/package.json +++ b/tools/eslint-config-custom/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-custom", - "version": "0.62.2", + "version": "0.64.0", "license": "MIT", "main": "index.js", "scripts": { diff --git a/tools/tsconfig/package.json b/tools/tsconfig/package.json index f4b11e1f8..2b7d691a9 100644 --- a/tools/tsconfig/package.json +++ b/tools/tsconfig/package.json @@ -1,6 +1,6 @@ { "name": "tsconfig", - "version": "0.62.2", + "version": "0.64.0", "private": true, "files": [ "base.json"