deepsource-autofix-76c6eb20
Dan Gowans 2024-10-29 13:59:16 -04:00
parent c7ccdfed5b
commit 7011ab1adc
36 changed files with 184 additions and 153 deletions

View File

@ -1,13 +1,14 @@
import cluster from 'node:cluster'; import cluster from 'node:cluster';
import os from 'node:os'; import os from 'node:os';
import { dirname } from 'node:path'; import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import ntfyPublish from '@cityssm/ntfy-publish'; import ntfyPublish from '@cityssm/ntfy-publish';
import { secondsToMillis } from '@cityssm/to-millis';
import Debug from 'debug'; import Debug from 'debug';
import exitHook from 'exit-hook'; import exitHook from 'exit-hook';
import { getConfigProperty } from '../helpers/functions.config.js'; import { getConfigProperty } from '../helpers/functions.config.js';
const debug = Debug(`lot-occupancy-system:www:${process.pid}`); const debug = Debug(`lot-occupancy-system:www:${process.pid}`);
const directoryName = dirname(fileURLToPath(import.meta.url)); const directoryName = path.dirname(fileURLToPath(import.meta.url));
const processCount = Math.min(getConfigProperty('application.maximumProcesses'), os.cpus().length); const processCount = Math.min(getConfigProperty('application.maximumProcesses'), os.cpus().length);
process.title = `${getConfigProperty('application.applicationName')} (Primary)`; process.title = `${getConfigProperty('application.applicationName')} (Primary)`;
debug(`Primary pid: ${process.pid}`); debug(`Primary pid: ${process.pid}`);
@ -68,7 +69,7 @@ if (process.env.STARTUP_TEST === 'true') {
debug(`Killing processes in ${killSeconds} seconds...`); debug(`Killing processes in ${killSeconds} seconds...`);
setTimeout(() => { setTimeout(() => {
debug('Killing processes'); debug('Killing processes');
// eslint-disable-next-line n/no-process-exit, unicorn/no-process-exit // eslint-disable-next-line unicorn/no-process-exit
process.exit(0); process.exit(0);
}, 10_000); }, secondsToMillis(killSeconds));
} }

View File

@ -1,9 +1,10 @@
import cluster, { type Worker } from 'node:cluster' import cluster, { type Worker } from 'node:cluster'
import os from 'node:os' import os from 'node:os'
import { dirname } from 'node:path' import path from 'node:path'
import { fileURLToPath } from 'node:url' import { fileURLToPath } from 'node:url'
import ntfyPublish, { type NtfyMessageOptions } from '@cityssm/ntfy-publish' import ntfyPublish, { type NtfyMessageOptions } from '@cityssm/ntfy-publish'
import { secondsToMillis } from '@cityssm/to-millis'
import Debug from 'debug' import Debug from 'debug'
import exitHook from 'exit-hook' import exitHook from 'exit-hook'
@ -12,7 +13,7 @@ import type { WorkerMessage } from '../types/applicationTypes.js'
const debug = Debug(`lot-occupancy-system:www:${process.pid}`) const debug = Debug(`lot-occupancy-system:www:${process.pid}`)
const directoryName = dirname(fileURLToPath(import.meta.url)) const directoryName = path.dirname(fileURLToPath(import.meta.url))
const processCount = Math.min( const processCount = Math.min(
getConfigProperty('application.maximumProcesses'), getConfigProperty('application.maximumProcesses'),
@ -98,7 +99,7 @@ if (process.env.STARTUP_TEST === 'true') {
setTimeout(() => { setTimeout(() => {
debug('Killing processes') debug('Killing processes')
// eslint-disable-next-line n/no-process-exit, unicorn/no-process-exit // eslint-disable-next-line unicorn/no-process-exit
process.exit(0) process.exit(0)
}, 10_000) }, secondsToMillis(killSeconds))
} }

View File

@ -1,5 +1,5 @@
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable n/no-process-exit, unicorn/no-process-exit */ /* eslint-disable unicorn/no-process-exit */
import http from 'node:http'; import http from 'node:http';
import Debug from 'debug'; import Debug from 'debug';
import exitHook from 'exit-hook'; import exitHook from 'exit-hook';
@ -12,7 +12,6 @@ function onError(error) {
} }
// handle specific listen errors with friendly messages // handle specific listen errors with friendly messages
switch (error.code) { switch (error.code) {
// eslint-disable-next-line no-fallthrough
case 'EACCES': { case 'EACCES': {
debug('Requires elevated privileges'); debug('Requires elevated privileges');
process.exit(1); process.exit(1);

View File

@ -1,5 +1,5 @@
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable n/no-process-exit, unicorn/no-process-exit */ /* eslint-disable unicorn/no-process-exit */
import http from 'node:http' import http from 'node:http'
@ -23,7 +23,6 @@ function onError(error: ServerError): void {
// handle specific listen errors with friendly messages // handle specific listen errors with friendly messages
switch (error.code) { switch (error.code) {
// eslint-disable-next-line no-fallthrough
case 'EACCES': { case 'EACCES': {
debug('Requires elevated privileges') debug('Requires elevated privileges')
process.exit(1) process.exit(1)

View File

@ -1,4 +1,3 @@
/* eslint-disable node/no-unpublished-import */
import 'cypress-axe'; import 'cypress-axe';
export const logout = () => { export const logout = () => {
cy.visit('/logout'); cy.visit('/logout');

View File

@ -1,5 +1,3 @@
/* eslint-disable node/no-unpublished-import */
import 'cypress-axe' import 'cypress-axe'
export const logout = (): void => { export const logout = (): void => {

View File

@ -1,2 +1,3 @@
export declare const config: import("../types/configTypes.js").Config; import type { Config } from '../types/configTypes.js';
export declare const config: Config;
export default config; export default config;

View File

@ -1,5 +1,5 @@
import { config as baseConfig } from './config.base.js'; import { config as baseConfig } from './config.base.js';
export const config = Object.assign({}, baseConfig); export const config = { ...baseConfig };
config.application = { config.application = {
applicationName: 'Cemetery Management System', applicationName: 'Cemetery Management System',
backgroundURL: '/images/cemetery-background.jpg', backgroundURL: '/images/cemetery-background.jpg',

View File

@ -1,3 +1,4 @@
export declare const config: import("../types/configTypes.js").Config; import type { Config } from '../types/configTypes.js';
export declare const config: Config;
export declare function lotNameSortNameFunction(lotName: string): string; export declare function lotNameSortNameFunction(lotName: string): string;
export default config; export default config;

View File

@ -1,6 +1,6 @@
import NodeCache from 'node-cache'; import NodeCache from 'node-cache';
import { config as cemeteryConfig } from './config.cemetery.ontario.js'; import { config as cemeteryConfig } from './config.cemetery.ontario.js';
export const config = Object.assign({}, cemeteryConfig); export const config = { ...cemeteryConfig };
config.aliases.occupancyStartDate = 'Purchase Date'; config.aliases.occupancyStartDate = 'Purchase Date';
config.aliases.externalReceiptNumber = 'GP Receipt Number'; config.aliases.externalReceiptNumber = 'GP Receipt Number';
config.settings.lot.lotNamePattern = config.settings.lot.lotNamePattern =

View File

@ -1,8 +1,10 @@
import NodeCache from 'node-cache' import NodeCache from 'node-cache'
import type { Config } from '../types/configTypes.js'
import { config as cemeteryConfig } from './config.cemetery.ontario.js' import { config as cemeteryConfig } from './config.cemetery.ontario.js'
export const config = Object.assign({}, cemeteryConfig) export const config: Config = { ...cemeteryConfig}
config.aliases.occupancyStartDate = 'Purchase Date' config.aliases.occupancyStartDate = 'Purchase Date'
config.aliases.externalReceiptNumber = 'GP Receipt Number' config.aliases.externalReceiptNumber = 'GP Receipt Number'

View File

@ -1,6 +1,8 @@
import type { Config } from '../types/configTypes.js'
import { config as baseConfig } from './config.base.js' import { config as baseConfig } from './config.base.js'
export const config = Object.assign({}, baseConfig) export const config: Config = { ...baseConfig }
config.application = { config.application = {
applicationName: 'Cemetery Management System', applicationName: 'Cemetery Management System',

View File

@ -1,5 +1,6 @@
import { hoursToMillis } from '@cityssm/to-millis';
export const configDefaultValues = { export const configDefaultValues = {
'activeDirectory': undefined, activeDirectory: undefined,
'application.applicationName': 'Lot Occupancy System', 'application.applicationName': 'Lot Occupancy System',
'application.backgroundURL': '/images/cemetery-background.jpg', 'application.backgroundURL': '/images/cemetery-background.jpg',
'application.logoURL': '/images/cemetery-logo.png', 'application.logoURL': '/images/cemetery-logo.png',
@ -13,7 +14,7 @@ export const configDefaultValues = {
'reverseProxy.urlPrefix': '', 'reverseProxy.urlPrefix': '',
'session.cookieName': 'lot-occupancy-system-user-sid', 'session.cookieName': 'lot-occupancy-system-user-sid',
'session.secret': 'cityssm/lot-occupancy-system', 'session.secret': 'cityssm/lot-occupancy-system',
'session.maxAgeMillis': 60 * 60 * 1000, 'session.maxAgeMillis': hoursToMillis(1),
'session.doKeepAlive': false, 'session.doKeepAlive': false,
'users.testing': [], 'users.testing': [],
'users.canLogin': ['administrator'], 'users.canLogin': ['administrator'],

View File

@ -1,9 +1,14 @@
import { hoursToMillis } from '@cityssm/to-millis'
import type { config as MSSQLConfig } from 'mssql' import type { config as MSSQLConfig } from 'mssql'
import type { ConfigActiveDirectory, ConfigNtfyStartup, DynamicsGPLookup } from '../types/configTypes.js' import type {
ConfigActiveDirectory,
ConfigNtfyStartup,
DynamicsGPLookup
} from '../types/configTypes.js'
export const configDefaultValues = { export const configDefaultValues = {
'activeDirectory': undefined as unknown as ConfigActiveDirectory, activeDirectory: undefined as unknown as ConfigActiveDirectory,
'application.applicationName': 'Lot Occupancy System', 'application.applicationName': 'Lot Occupancy System',
'application.backgroundURL': '/images/cemetery-background.jpg', 'application.backgroundURL': '/images/cemetery-background.jpg',
@ -21,7 +26,7 @@ export const configDefaultValues = {
'session.cookieName': 'lot-occupancy-system-user-sid', 'session.cookieName': 'lot-occupancy-system-user-sid',
'session.secret': 'cityssm/lot-occupancy-system', 'session.secret': 'cityssm/lot-occupancy-system',
'session.maxAgeMillis': 60 * 60 * 1000, 'session.maxAgeMillis': hoursToMillis(1),
'session.doKeepAlive': false, 'session.doKeepAlive': false,
'users.testing': [] as string[], 'users.testing': [] as string[],
@ -66,7 +71,9 @@ export const configDefaultValues = {
'settings.adminCleanup.recordDeleteAgeDays': 60, 'settings.adminCleanup.recordDeleteAgeDays': 60,
'settings.printPdf.contentDisposition': 'attachment' as 'attachment' | 'inline', 'settings.printPdf.contentDisposition': 'attachment' as
| 'attachment'
| 'inline',
'settings.dynamicsGP.integrationIsEnabled': false, 'settings.dynamicsGP.integrationIsEnabled': false,
'settings.dynamicsGP.mssqlConfig': undefined as unknown as MSSQLConfig, 'settings.dynamicsGP.mssqlConfig': undefined as unknown as MSSQLConfig,

View File

@ -1,2 +1,3 @@
export declare const config: import("../types/configTypes.js").Config; import type { Config } from '../types/configTypes.js';
export declare const config: Config;
export default config; export default config;

View File

@ -1,5 +1,5 @@
import { config as cemeteryConfig } from './config.cemetery.ssm.js'; import { config as cemeteryConfig } from './config.cemetery.ssm.js';
export const config = Object.assign({}, cemeteryConfig); export const config = { ...cemeteryConfig };
config.application.useTestDatabases = true; config.application.useTestDatabases = true;
config.session.doKeepAlive = true; config.session.doKeepAlive = true;
config.users = { config.users = {

View File

@ -1,6 +1,8 @@
import type { Config } from '../types/configTypes.js'
import { config as cemeteryConfig } from './config.cemetery.ssm.js' import { config as cemeteryConfig } from './config.cemetery.ssm.js'
export const config = Object.assign({}, cemeteryConfig) export const config: Config = { ...cemeteryConfig }
config.application.useTestDatabases = true config.application.useTestDatabases = true

View File

@ -1,4 +1,4 @@
import { type PoolConnection } from 'better-sqlite-pool'; import type { PoolConnection } from 'better-sqlite-pool';
import type { FeeCategory } from '../types/recordTypes.js'; import type { FeeCategory } from '../types/recordTypes.js';
interface GetFeeCategoriesFilters { interface GetFeeCategoriesFilters {
occupancyTypeId?: number | string; occupancyTypeId?: number | string;

View File

@ -1,4 +1,4 @@
import { type PoolConnection } from 'better-sqlite-pool' import type { PoolConnection } from 'better-sqlite-pool'
import type { FeeCategory } from '../types/recordTypes.js' import type { FeeCategory } from '../types/recordTypes.js'

View File

@ -20,7 +20,7 @@ export default async function getLotOccupancyComments(lotOccupancyId, connectedD
and lotOccupancyId = ? and lotOccupancyId = ?
order by lotOccupancyCommentDate desc, lotOccupancyCommentTime desc, lotOccupancyCommentId desc`) order by lotOccupancyCommentDate desc, lotOccupancyCommentTime desc, lotOccupancyCommentId desc`)
.all(lotOccupancyId); .all(lotOccupancyId);
if (connectedDatabase === null) { if (connectedDatabase === undefined) {
database.release(); database.release();
} }
return lotComments; return lotComments;

View File

@ -39,7 +39,7 @@ export default async function getLotOccupancyComments(
) )
.all(lotOccupancyId) as LotOccupancyComment[] .all(lotOccupancyId) as LotOccupancyComment[]
if (connectedDatabase === null) { if (connectedDatabase === undefined) {
database.release() database.release()
} }

View File

@ -14,9 +14,11 @@ export default async function getNextMapId(
order by mapName order by mapName
limit 1` limit 1`
) )
.get(mapId) as { .get(mapId) as
mapId: number | {
} mapId: number
}
| undefined
database.release() database.release()

View File

@ -7,9 +7,7 @@ export default async function getNextWorkOrderNumber(connectedDatabase) {
const regex = new RegExp(`^${currentYearString}-\\d+$`); const regex = new RegExp(`^${currentYearString}-\\d+$`);
database.function( database.function(
// eslint-disable-next-line no-secrets/no-secrets // eslint-disable-next-line no-secrets/no-secrets
'userFn_matchesWorkOrderNumberSyntax', (workOrderNumber) => { 'userFn_matchesWorkOrderNumberSyntax', (workOrderNumber) => (regex.test(workOrderNumber) ? 1 : 0));
return regex.test(workOrderNumber) ? 1 : 0;
});
const workOrderNumberRecord = database const workOrderNumberRecord = database
.prepare( .prepare(
// eslint-disable-next-line no-secrets/no-secrets // eslint-disable-next-line no-secrets/no-secrets
@ -21,7 +19,7 @@ export default async function getNextWorkOrderNumber(connectedDatabase) {
database.release(); database.release();
} }
let workOrderNumberIndex = 0; let workOrderNumberIndex = 0;
if (workOrderNumberRecord) { if (workOrderNumberRecord !== undefined) {
workOrderNumberIndex = Number.parseInt(workOrderNumberRecord.workOrderNumber.split('-')[1], 10); workOrderNumberIndex = Number.parseInt(workOrderNumberRecord.workOrderNumber.split('-')[1], 10);
} }
workOrderNumberIndex += 1; workOrderNumberIndex += 1;

View File

@ -19,9 +19,7 @@ export default async function getNextWorkOrderNumber(
database.function( database.function(
// eslint-disable-next-line no-secrets/no-secrets // eslint-disable-next-line no-secrets/no-secrets
'userFn_matchesWorkOrderNumberSyntax', 'userFn_matchesWorkOrderNumberSyntax',
(workOrderNumber: string) => { (workOrderNumber: string) => (regex.test(workOrderNumber) ? 1 : 0)
return regex.test(workOrderNumber) ? 1 : 0
}
) )
const workOrderNumberRecord = database const workOrderNumberRecord = database
@ -31,9 +29,11 @@ export default async function getNextWorkOrderNumber(
where userFn_matchesWorkOrderNumberSyntax(workOrderNumber) = 1 where userFn_matchesWorkOrderNumberSyntax(workOrderNumber) = 1
order by cast(substr(workOrderNumber, instr(workOrderNumber, '-') + 1) as integer) desc` order by cast(substr(workOrderNumber, instr(workOrderNumber, '-') + 1) as integer) desc`
) )
.get() as { .get() as
workOrderNumber: string | {
} workOrderNumber: string
}
| undefined
if (connectedDatabase === undefined) { if (connectedDatabase === undefined) {
database.release() database.release()
@ -41,7 +41,7 @@ export default async function getNextWorkOrderNumber(
let workOrderNumberIndex = 0 let workOrderNumberIndex = 0
if (workOrderNumberRecord) { if (workOrderNumberRecord !== undefined) {
workOrderNumberIndex = Number.parseInt( workOrderNumberIndex = Number.parseInt(
workOrderNumberRecord.workOrderNumber.split('-')[1], workOrderNumberRecord.workOrderNumber.split('-')[1],
10 10

View File

@ -9,12 +9,11 @@ export default async function getPastLotOccupancyOccupants(filters, options) {
if (searchFilterPiece === '') { if (searchFilterPiece === '') {
continue; continue;
} }
sqlWhereClause += sqlWhereClause += ` and (o.occupantName like '%' || ? || '%'
" and (o.occupantName like '%' || ? || '%'" + or o.occupantFamilyName like '%' || ? || '%'
" or o.occupantFamilyName like '%' || ? || '%'" + or o.occupantAddress1 like '%' || ? || '%'
" or o.occupantAddress1 like '%' || ? || '%'" + or o.occupantAddress2 like '%' || ? || '%'
" or o.occupantAddress2 like '%' || ? || '%'" + or o.occupantCity like '%' || ? || '%')`;
" or o.occupantCity like '%' || ? || '%')";
sqlParameters.push(searchFilterPiece, searchFilterPiece, searchFilterPiece, searchFilterPiece, searchFilterPiece); sqlParameters.push(searchFilterPiece, searchFilterPiece, searchFilterPiece, searchFilterPiece, searchFilterPiece);
} }
} }
@ -24,14 +23,14 @@ export default async function getPastLotOccupancyOccupants(filters, options) {
o.occupantPhoneNumber, o.occupantEmailAddress, o.occupantPhoneNumber, o.occupantEmailAddress,
count(*) as lotOccupancyIdCount, count(*) as lotOccupancyIdCount,
max(o.recordUpdate_timeMillis) as recordUpdate_timeMillisMax max(o.recordUpdate_timeMillis) as recordUpdate_timeMillisMax
from LotOccupancyOccupants o from LotOccupancyOccupants o
left join LotOccupancies l on o.lotOccupancyId = l.lotOccupancyId left join LotOccupancies l on o.lotOccupancyId = l.lotOccupancyId
${sqlWhereClause} ${sqlWhereClause}
group by occupantName, occupantAddress1, occupantAddress2, group by occupantName, occupantAddress1, occupantAddress2,
occupantCity, occupantProvince, occupantPostalCode, occupantCity, occupantProvince, occupantPostalCode,
occupantPhoneNumber, occupantEmailAddress occupantPhoneNumber, occupantEmailAddress
order by lotOccupancyIdCount desc, recordUpdate_timeMillisMax desc order by lotOccupancyIdCount desc, recordUpdate_timeMillisMax desc
limit ${options.limit}`; limit ${options.limit}`;
const lotOccupancyOccupants = database const lotOccupancyOccupants = database
.prepare(sql) .prepare(sql)
.all(sqlParameters); .all(sqlParameters);

View File

@ -29,12 +29,11 @@ export default async function getPastLotOccupancyOccupants(
continue continue
} }
sqlWhereClause += sqlWhereClause += ` and (o.occupantName like '%' || ? || '%'
" and (o.occupantName like '%' || ? || '%'" + or o.occupantFamilyName like '%' || ? || '%'
" or o.occupantFamilyName like '%' || ? || '%'" + or o.occupantAddress1 like '%' || ? || '%'
" or o.occupantAddress1 like '%' || ? || '%'" + or o.occupantAddress2 like '%' || ? || '%'
" or o.occupantAddress2 like '%' || ? || '%'" + or o.occupantCity like '%' || ? || '%')`
" or o.occupantCity like '%' || ? || '%')"
sqlParameters.push( sqlParameters.push(
searchFilterPiece, searchFilterPiece,
@ -52,14 +51,14 @@ export default async function getPastLotOccupancyOccupants(
o.occupantPhoneNumber, o.occupantEmailAddress, o.occupantPhoneNumber, o.occupantEmailAddress,
count(*) as lotOccupancyIdCount, count(*) as lotOccupancyIdCount,
max(o.recordUpdate_timeMillis) as recordUpdate_timeMillisMax max(o.recordUpdate_timeMillis) as recordUpdate_timeMillisMax
from LotOccupancyOccupants o from LotOccupancyOccupants o
left join LotOccupancies l on o.lotOccupancyId = l.lotOccupancyId left join LotOccupancies l on o.lotOccupancyId = l.lotOccupancyId
${sqlWhereClause} ${sqlWhereClause}
group by occupantName, occupantAddress1, occupantAddress2, group by occupantName, occupantAddress1, occupantAddress2,
occupantCity, occupantProvince, occupantPostalCode, occupantCity, occupantProvince, occupantPostalCode,
occupantPhoneNumber, occupantEmailAddress occupantPhoneNumber, occupantEmailAddress
order by lotOccupancyIdCount desc, recordUpdate_timeMillisMax desc order by lotOccupancyIdCount desc, recordUpdate_timeMillisMax desc
limit ${options.limit}` limit ${options.limit}`
const lotOccupancyOccupants = database const lotOccupancyOccupants = database
.prepare(sql) .prepare(sql)

View File

@ -20,9 +20,11 @@ export default async function getPreviousLotId(
order by userFn_lotNameSortName(lotName) desc order by userFn_lotNameSortName(lotName) desc
limit 1` limit 1`
) )
.get(lotId) as { .get(lotId) as
lotId: number | {
} lotId: number
}
| undefined
database.release() database.release()

View File

@ -13,9 +13,11 @@ export default async function getPreviousMapId(
order by mapName desc order by mapName desc
limit 1` limit 1`
) )
.get(mapId) as { .get(mapId) as
mapId: number | {
} mapId: number
}
| undefined
database.release() database.release()

View File

@ -1,5 +1,3 @@
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable no-case-declarations */
import { dateIntegerToString, dateStringToInteger, dateToInteger, timeIntegerToString } from '@cityssm/utils-datetime'; import { dateIntegerToString, dateStringToInteger, dateToInteger, timeIntegerToString } from '@cityssm/utils-datetime';
import camelCase from 'camelcase'; import camelCase from 'camelcase';
import { getConfigProperty } from '../helpers/functions.config.js'; import { getConfigProperty } from '../helpers/functions.config.js';
@ -38,7 +36,7 @@ const occupantEmailAddressAlias = `${occupantCamelCase}EmailAddress`;
const occupantCommentTitleAlias = `${occupantCamelCase}CommentTitle`; const occupantCommentTitleAlias = `${occupantCamelCase}CommentTitle`;
const occupantCommentAlias = `${occupantCamelCase}Comment`; const occupantCommentAlias = `${occupantCamelCase}Comment`;
export default async function getReportData(reportName, reportParameters = {}) { export default async function getReportData(reportName, reportParameters = {}) {
let sql; let sql = '';
const sqlParameters = []; const sqlParameters = [];
// eslint-disable-next-line sonarjs/max-switch-cases // eslint-disable-next-line sonarjs/max-switch-cases
switch (reportName) { switch (reportName) {

View File

@ -1,6 +1,3 @@
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable no-case-declarations */
import { import {
type DateString, type DateString,
dateIntegerToString, dateIntegerToString,
@ -57,7 +54,7 @@ export default async function getReportData(
reportName: string, reportName: string,
reportParameters: ReportParameters = {} reportParameters: ReportParameters = {}
): Promise<unknown[] | undefined> { ): Promise<unknown[] | undefined> {
let sql: string let sql = ''
const sqlParameters: unknown[] = [] const sqlParameters: unknown[] = []
// eslint-disable-next-line sonarjs/max-switch-cases // eslint-disable-next-line sonarjs/max-switch-cases

View File

@ -12,8 +12,8 @@ recordIdColumns.set('WorkOrderTypes', 'workOrderTypeId');
function getCurrentOrderNumber(recordTable, recordId, database) { function getCurrentOrderNumber(recordTable, recordId, database) {
const currentOrderNumber = database const currentOrderNumber = database
.prepare(`select orderNumber .prepare(`select orderNumber
from ${recordTable} from ${recordTable}
where ${recordIdColumns.get(recordTable)} = ?`) where ${recordIdColumns.get(recordTable)} = ?`)
.get(recordId).orderNumber; .get(recordId).orderNumber;
return currentOrderNumber; return currentOrderNumber;
} }
@ -36,8 +36,8 @@ export async function moveRecordDownToBottom(recordTable, recordId) {
const currentOrderNumber = getCurrentOrderNumber(recordTable, recordId, database); const currentOrderNumber = getCurrentOrderNumber(recordTable, recordId, database);
const maxOrderNumber = database const maxOrderNumber = database
.prepare(`select max(orderNumber) as maxOrderNumber .prepare(`select max(orderNumber) as maxOrderNumber
from ${recordTable} from ${recordTable}
where recordDelete_timeMillis is null`) where recordDelete_timeMillis is null`)
.get().maxOrderNumber; .get().maxOrderNumber;
if (currentOrderNumber !== maxOrderNumber) { if (currentOrderNumber !== maxOrderNumber) {
updateRecordOrderNumber(recordTable, recordId, maxOrderNumber + 1, database); updateRecordOrderNumber(recordTable, recordId, maxOrderNumber + 1, database);

View File

@ -32,8 +32,8 @@ function getCurrentOrderNumber(
database database
.prepare( .prepare(
`select orderNumber `select orderNumber
from ${recordTable} from ${recordTable}
where ${recordIdColumns.get(recordTable)!} = ?` where ${recordIdColumns.get(recordTable)!} = ?`
) )
.get(recordId) as { orderNumber: number } .get(recordId) as { orderNumber: number }
).orderNumber ).orderNumber
@ -92,8 +92,8 @@ export async function moveRecordDownToBottom(
database database
.prepare( .prepare(
`select max(orderNumber) as maxOrderNumber `select max(orderNumber) as maxOrderNumber
from ${recordTable} from ${recordTable}
where recordDelete_timeMillis is null` where recordDelete_timeMillis is null`
) )
.get() as { maxOrderNumber: number } .get() as { maxOrderNumber: number }
).maxOrderNumber ).maxOrderNumber

View File

@ -1,10 +1,20 @@
import { configWebApp, tseslint } from 'eslint-config-cityssm'; import { configWebApp, cspellWords, tseslint } from 'eslint-config-cityssm';
export const config = tseslint.config(...configWebApp, { export const config = tseslint.config(...configWebApp, {
languageOptions: { languageOptions: {
parserOptions: { parserOptions: {
// eslint-disable-next-line @cspell/spellchecker // eslint-disable-next-line @cspell/spellchecker
project: ['./tsconfig.json', './public/javascripts/tsconfig.json'] project: ['./tsconfig.json', './public/javascripts/tsconfig.json']
} }
},
rules: {
'@cspell/spellchecker': [
'warn',
{
cspell: {
words: [...cspellWords, 'ical', 'ntfy']
}
}
]
} }
}); });
export default config; export default config;

View File

@ -1,4 +1,4 @@
import { configWebApp, tseslint } from 'eslint-config-cityssm' import { configWebApp, cspellWords, tseslint } from 'eslint-config-cityssm'
export const config = tseslint.config(...configWebApp, { export const config = tseslint.config(...configWebApp, {
languageOptions: { languageOptions: {
@ -6,6 +6,16 @@ export const config = tseslint.config(...configWebApp, {
// eslint-disable-next-line @cspell/spellchecker // eslint-disable-next-line @cspell/spellchecker
project: ['./tsconfig.json', './public/javascripts/tsconfig.json'] project: ['./tsconfig.json', './public/javascripts/tsconfig.json']
} }
},
rules: {
'@cspell/spellchecker': [
'warn',
{
cspell: {
words: [...cspellWords, 'ical', 'ntfy']
}
}
]
} }
}) })

106
package-lock.json generated
View File

@ -81,7 +81,7 @@
"bulma-tooltip": "^3.0.2", "bulma-tooltip": "^3.0.2",
"cypress": "^13.15.1", "cypress": "^13.15.1",
"cypress-axe": "^1.5.0", "cypress-axe": "^1.5.0",
"eslint-config-cityssm": "^14.0.2", "eslint-config-cityssm": "^14.1.0",
"gulp": "^5.0.0", "gulp": "^5.0.0",
"gulp-sass": "^5.1.0", "gulp-sass": "^5.1.0",
"nodemon": "^3.1.7", "nodemon": "^3.1.7",
@ -4877,14 +4877,14 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "8.11.0", "version": "8.12.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.11.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.12.2.tgz",
"integrity": "sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ==", "integrity": "sha512-gPLpLtrj9aMHOvxJkSbDBmbRuYdtiEbnvO25bCMza3DhMjTQw0u7Y1M+YR5JPbMsXXnSPuCf5hfq0nEkQDL/JQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.11.0", "@typescript-eslint/types": "8.12.2",
"@typescript-eslint/visitor-keys": "8.11.0" "@typescript-eslint/visitor-keys": "8.12.2"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -5051,9 +5051,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "8.11.0", "version": "8.12.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.11.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.12.2.tgz",
"integrity": "sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw==", "integrity": "sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -5065,14 +5065,14 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "8.11.0", "version": "8.12.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.11.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.12.2.tgz",
"integrity": "sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg==", "integrity": "sha512-mME5MDwGe30Pq9zKPvyduyU86PH7aixwqYR2grTglAdB+AN8xXQ1vFGpYaUSJ5o5P/5znsSBeNcs5g5/2aQwow==",
"dev": true, "dev": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.11.0", "@typescript-eslint/types": "8.12.2",
"@typescript-eslint/visitor-keys": "8.11.0", "@typescript-eslint/visitor-keys": "8.12.2",
"debug": "^4.3.4", "debug": "^4.3.4",
"fast-glob": "^3.3.2", "fast-glob": "^3.3.2",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -5120,16 +5120,16 @@
} }
}, },
"node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/utils": {
"version": "8.11.0", "version": "8.12.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.11.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.12.2.tgz",
"integrity": "sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g==", "integrity": "sha512-UTTuDIX3fkfAz6iSVa5rTuSfWIYZ6ATtEocQ/umkRSyC9O919lbZ8dcH7mysshrCdrAM03skJOEYaBugxN+M6A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.4.0", "@eslint-community/eslint-utils": "^4.4.0",
"@typescript-eslint/scope-manager": "8.11.0", "@typescript-eslint/scope-manager": "8.12.2",
"@typescript-eslint/types": "8.11.0", "@typescript-eslint/types": "8.12.2",
"@typescript-eslint/typescript-estree": "8.11.0" "@typescript-eslint/typescript-estree": "8.12.2"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -5143,13 +5143,13 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "8.11.0", "version": "8.12.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.11.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz",
"integrity": "sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw==", "integrity": "sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.11.0", "@typescript-eslint/types": "8.12.2",
"eslint-visitor-keys": "^3.4.3" "eslint-visitor-keys": "^3.4.3"
}, },
"engines": { "engines": {
@ -8128,9 +8128,9 @@
} }
}, },
"node_modules/eslint-config-cityssm": { "node_modules/eslint-config-cityssm": {
"version": "14.0.2", "version": "14.1.0",
"resolved": "https://registry.npmjs.org/eslint-config-cityssm/-/eslint-config-cityssm-14.0.2.tgz", "resolved": "https://registry.npmjs.org/eslint-config-cityssm/-/eslint-config-cityssm-14.1.0.tgz",
"integrity": "sha512-eCQHo5VoJGXvuhSYaJ6erZ7NS/KwDP+D9pkB0GtJMdk8NNBuN0NJyvJojJJwdwYTVFzG+Jhcc9LJvd05mpoufA==", "integrity": "sha512-tBu9pX9xnPtyp0dJBiv4MYgKQKgHN7pGwGkrQf8+9KTtwFhgXr+gDqNzkzxPbTcBjdVfKbtqp4BrYAGBJNusiQ==",
"dev": true, "dev": true,
"license": "Unlicense", "license": "Unlicense",
"dependencies": { "dependencies": {
@ -8151,7 +8151,7 @@
"eslint-plugin-unicorn": "^56.0.0", "eslint-plugin-unicorn": "^56.0.0",
"eslint-plugin-woke": "github:cityssm/eslint-plugin-woke", "eslint-plugin-woke": "github:cityssm/eslint-plugin-woke",
"eslint-plugin-write-good-comments": "^0.2.0", "eslint-plugin-write-good-comments": "^0.2.0",
"typescript-eslint": "^8.11.0" "typescript-eslint": "^8.12.2"
} }
}, },
"node_modules/eslint-config-cityssm/node_modules/@eslint/eslintrc": { "node_modules/eslint-config-cityssm/node_modules/@eslint/eslintrc": {
@ -16023,15 +16023,15 @@
} }
}, },
"node_modules/typescript-eslint": { "node_modules/typescript-eslint": {
"version": "8.11.0", "version": "8.12.2",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.11.0.tgz", "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.12.2.tgz",
"integrity": "sha512-cBRGnW3FSlxaYwU8KfAewxFK5uzeOAp0l2KebIlPDOT5olVi65KDG/yjBooPBG0kGW/HLkoz1c/iuBFehcS3IA==", "integrity": "sha512-UbuVUWSrHVR03q9CWx+JDHeO6B/Hr9p4U5lRH++5tq/EbFq1faYZe50ZSBePptgfIKLEti0aPQ3hFgnPVcd8ZQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/eslint-plugin": "8.11.0", "@typescript-eslint/eslint-plugin": "8.12.2",
"@typescript-eslint/parser": "8.11.0", "@typescript-eslint/parser": "8.12.2",
"@typescript-eslint/utils": "8.11.0" "@typescript-eslint/utils": "8.12.2"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -16047,17 +16047,17 @@
} }
}, },
"node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.11.0", "version": "8.12.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.11.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.12.2.tgz",
"integrity": "sha512-KhGn2LjW1PJT2A/GfDpiyOfS4a8xHQv2myUagTM5+zsormOmBlYsnQ6pobJ8XxJmh6hnHwa2Mbe3fPrDJoDhbA==", "integrity": "sha512-gQxbxM8mcxBwaEmWdtLCIGLfixBMHhQjBqR8sVWNTPpcj45WlYL2IObS/DNMLH1DBP0n8qz+aiiLTGfopPEebw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/regexpp": "^4.10.0", "@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.11.0", "@typescript-eslint/scope-manager": "8.12.2",
"@typescript-eslint/type-utils": "8.11.0", "@typescript-eslint/type-utils": "8.12.2",
"@typescript-eslint/utils": "8.11.0", "@typescript-eslint/utils": "8.12.2",
"@typescript-eslint/visitor-keys": "8.11.0", "@typescript-eslint/visitor-keys": "8.12.2",
"graphemer": "^1.4.0", "graphemer": "^1.4.0",
"ignore": "^5.3.1", "ignore": "^5.3.1",
"natural-compare": "^1.4.0", "natural-compare": "^1.4.0",
@ -16081,16 +16081,16 @@
} }
}, },
"node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": {
"version": "8.11.0", "version": "8.12.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.11.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.12.2.tgz",
"integrity": "sha512-lmt73NeHdy1Q/2ul295Qy3uninSqi6wQI18XwSpm8w0ZbQXUpjCAWP1Vlv/obudoBiIjJVjlztjQ+d/Md98Yxg==", "integrity": "sha512-MrvlXNfGPLH3Z+r7Tk+Z5moZAc0dzdVjTgUgwsdGweH7lydysQsnSww3nAmsq8blFuRD5VRlAr9YdEFw3e6PBw==",
"dev": true, "dev": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "8.11.0", "@typescript-eslint/scope-manager": "8.12.2",
"@typescript-eslint/types": "8.11.0", "@typescript-eslint/types": "8.12.2",
"@typescript-eslint/typescript-estree": "8.11.0", "@typescript-eslint/typescript-estree": "8.12.2",
"@typescript-eslint/visitor-keys": "8.11.0", "@typescript-eslint/visitor-keys": "8.12.2",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -16110,14 +16110,14 @@
} }
}, },
"node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": { "node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": {
"version": "8.11.0", "version": "8.12.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.11.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.12.2.tgz",
"integrity": "sha512-ItiMfJS6pQU0NIKAaybBKkuVzo6IdnAhPFZA/2Mba/uBjuPQPet/8+zh5GtLHwmuFRShZx+8lhIs7/QeDHflOg==", "integrity": "sha512-bwuU4TAogPI+1q/IJSKuD4shBLc/d2vGcRT588q+jzayQyjVK2X6v/fbR4InY2U2sgf8MEvVCqEWUzYzgBNcGQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/typescript-estree": "8.11.0", "@typescript-eslint/typescript-estree": "8.12.2",
"@typescript-eslint/utils": "8.11.0", "@typescript-eslint/utils": "8.12.2",
"debug": "^4.3.4", "debug": "^4.3.4",
"ts-api-utils": "^1.3.0" "ts-api-utils": "^1.3.0"
}, },

View File

@ -105,7 +105,7 @@
"bulma-tooltip": "^3.0.2", "bulma-tooltip": "^3.0.2",
"cypress": "^13.15.1", "cypress": "^13.15.1",
"cypress-axe": "^1.5.0", "cypress-axe": "^1.5.0",
"eslint-config-cityssm": "^14.0.2", "eslint-config-cityssm": "^14.1.0",
"gulp": "^5.0.0", "gulp": "^5.0.0",
"gulp-sass": "^5.1.0", "gulp-sass": "^5.1.0",
"nodemon": "^3.1.7", "nodemon": "^3.1.7",