fix: resolve TypeScript type errors across codebase
- Add experimentalDecorators support in tsconfig.node.json for TypeORM entities - Fix mssql module import in order-resolver.ts (static vs dynamic import) - Extend ISqlType parameter types in sql-server.ts for NVarChar compatibility - Fix variable naming and type assertions in bip-users-dao.ts - Add proper type assertions for IPC call results in renderer hooks (useAuth, useCleaner, useExtractor, useValidation) - Add definite assignment assertions in config-manager.ts
This commit is contained in:
@@ -147,8 +147,8 @@ function validateEditableFields(settings: Partial<SettingsData>): {
|
|||||||
*/
|
*/
|
||||||
export class ConfigManager {
|
export class ConfigManager {
|
||||||
private static instance: ConfigManager | null = null
|
private static instance: ConfigManager | null = null
|
||||||
private envPath: string
|
private envPath!: string
|
||||||
private backupPath: string
|
private backupPath!: string
|
||||||
private configCache: Map<string, string> = new Map()
|
private configCache: Map<string, string> = new Map()
|
||||||
private initialized: boolean = false
|
private initialized: boolean = false
|
||||||
|
|
||||||
@@ -214,6 +214,8 @@ export class ConfigManager {
|
|||||||
* @param key - Configuration key
|
* @param key - Configuration key
|
||||||
* @param defaultValue - Default value if key doesn't exist
|
* @param defaultValue - Default value if key doesn't exist
|
||||||
*/
|
*/
|
||||||
|
public get(key: string): string | undefined
|
||||||
|
public get(key: string, defaultValue: string): string
|
||||||
public get(key: string, defaultValue?: string): string | undefined {
|
public get(key: string, defaultValue?: string): string | undefined {
|
||||||
return this.configCache.get(key) ?? defaultValue
|
return this.configCache.get(key) ?? defaultValue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,13 @@ export class SqlServerService implements IDatabaseService {
|
|||||||
*/
|
*/
|
||||||
async queryWithParams(
|
async queryWithParams(
|
||||||
sqlString: string,
|
sqlString: string,
|
||||||
params: Record<string, { value: unknown; type?: sql.ISqlType }>
|
params: Record<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
value: unknown
|
||||||
|
type?: sql.ISqlType | sql.ISqlTypeFactoryWithLength | sql.ISqlTypeWithLength
|
||||||
|
}
|
||||||
|
>
|
||||||
): Promise<QueryResult> {
|
): Promise<QueryResult> {
|
||||||
if (!this.pool) {
|
if (!this.pool) {
|
||||||
throw new Error('Not connected to SQL Server. Call connect() first.')
|
throw new Error('Not connected to SQL Server. Call connect() first.')
|
||||||
|
|||||||
@@ -14,18 +14,10 @@
|
|||||||
import type { IDatabaseService } from '../database'
|
import type { IDatabaseService } from '../database'
|
||||||
import { SqlServerService } from '../database/sql-server'
|
import { SqlServerService } from '../database/sql-server'
|
||||||
import { createLogger } from '../logger'
|
import { createLogger } from '../logger'
|
||||||
|
import sql from 'mssql'
|
||||||
|
|
||||||
const log = createLogger('OrderResolver')
|
const log = createLogger('OrderResolver')
|
||||||
|
|
||||||
// Dynamically import mssql for SQL Server parameter types
|
|
||||||
let mssql: typeof import('mssql') | null = null
|
|
||||||
async function getMssql() {
|
|
||||||
if (!mssql) {
|
|
||||||
mssql = await import('mssql')
|
|
||||||
}
|
|
||||||
return mssql
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Order mapping result
|
* Order mapping result
|
||||||
*/
|
*/
|
||||||
@@ -251,18 +243,26 @@ export class OrderNumberResolver {
|
|||||||
const isSqlServer = this.dbService.type === 'sqlserver'
|
const isSqlServer = this.dbService.type === 'sqlserver'
|
||||||
const tableName = this.getTableName(DB_CONFIG.TABLE_NAME)
|
const tableName = this.getTableName(DB_CONFIG.TABLE_NAME)
|
||||||
|
|
||||||
log.debug('Resolving production IDs', { count: productionIds.length, dbType: this.dbService.type })
|
log.debug('Resolving production IDs', {
|
||||||
|
count: productionIds.length,
|
||||||
|
dbType: this.dbService.type
|
||||||
|
})
|
||||||
|
|
||||||
let result
|
let result
|
||||||
|
|
||||||
if (isSqlServer) {
|
if (isSqlServer) {
|
||||||
// Use queryWithParams for SQL Server with explicit parameter types
|
// Use queryWithParams for SQL Server with explicit parameter types
|
||||||
const sql = await getMssql()
|
|
||||||
const placeholders = productionIds.map((_, idx) => `@p${idx}`).join(', ')
|
const placeholders = productionIds.map((_, idx) => `@p${idx}`).join(', ')
|
||||||
const params: Record<string, { value: string; type: sql.ISqlType }> = {}
|
const params: Record<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
value: string
|
||||||
|
type: sql.ISqlType | sql.ISqlTypeFactoryWithLength | sql.ISqlTypeWithLength
|
||||||
|
}
|
||||||
|
> = {}
|
||||||
|
|
||||||
productionIds.forEach((id, idx) => {
|
productionIds.forEach((id, idx) => {
|
||||||
params[`p${idx}`] = { value: id, type: sql.NVarChar }
|
params[`p${idx}`] = { value: id, type: sql.NVarChar(255) }
|
||||||
})
|
})
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
@@ -351,12 +351,17 @@ export class OrderNumberResolver {
|
|||||||
|
|
||||||
if (isSqlServer) {
|
if (isSqlServer) {
|
||||||
// Use queryWithParams for SQL Server with explicit parameter types
|
// Use queryWithParams for SQL Server with explicit parameter types
|
||||||
const sql = await getMssql()
|
|
||||||
const placeholders = orderNumbers.map((_, idx) => `@p${idx}`).join(', ')
|
const placeholders = orderNumbers.map((_, idx) => `@p${idx}`).join(', ')
|
||||||
const params: Record<string, { value: string; type: sql.ISqlType }> = {}
|
const params: Record<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
value: string
|
||||||
|
type: sql.ISqlType | sql.ISqlTypeFactoryWithLength | sql.ISqlTypeWithLength
|
||||||
|
}
|
||||||
|
> = {}
|
||||||
|
|
||||||
orderNumbers.forEach((id, idx) => {
|
orderNumbers.forEach((id, idx) => {
|
||||||
params[`p${idx}`] = { value: id, type: sql.NVarChar }
|
params[`p${idx}`] = { value: id, type: sql.NVarChar(255) }
|
||||||
})
|
})
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
|
|||||||
@@ -121,8 +121,8 @@ export class BIPUsersDAO {
|
|||||||
`
|
`
|
||||||
|
|
||||||
const result = await (dbService as SqlServerService).queryWithParams(sqlString, {
|
const result = await (dbService as SqlServerService).queryWithParams(sqlString, {
|
||||||
username: { value: username, type: sql.NVarChar },
|
username: { value: username, type: sql.NVarChar(255) },
|
||||||
password: { value: password, type: sql.NVarChar }
|
password: { value: password, type: sql.NVarChar(255) }
|
||||||
})
|
})
|
||||||
|
|
||||||
if (result.rows.length > 0) {
|
if (result.rows.length > 0) {
|
||||||
@@ -177,7 +177,7 @@ export class BIPUsersDAO {
|
|||||||
`
|
`
|
||||||
|
|
||||||
const result = await (dbService as SqlServerService).queryWithParams(sqlString, {
|
const result = await (dbService as SqlServerService).queryWithParams(sqlString, {
|
||||||
computerName: { value: computerName, type: sql.NVarChar }
|
computerName: { value: computerName, type: sql.NVarChar(255) }
|
||||||
})
|
})
|
||||||
|
|
||||||
if (result.rows.length > 0) {
|
if (result.rows.length > 0) {
|
||||||
@@ -265,49 +265,55 @@ export class BIPUsersDAO {
|
|||||||
const tableName = this.getTableName()
|
const tableName = this.getTableName()
|
||||||
|
|
||||||
if (this.dbType === 'sqlserver') {
|
if (this.dbType === 'sqlserver') {
|
||||||
let sql: string
|
let sqlString: string
|
||||||
let params: Record<string, { value: unknown; type?: sql.ISqlType }>
|
let params: Record<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
value: unknown
|
||||||
|
type?: sql.ISqlType | sql.ISqlTypeFactoryWithLength | sql.ISqlTypeWithLength
|
||||||
|
}
|
||||||
|
>
|
||||||
|
|
||||||
if (computerName) {
|
if (computerName) {
|
||||||
sql = `
|
sqlString = `
|
||||||
INSERT INTO ${tableName}
|
INSERT INTO ${tableName}
|
||||||
(UserName, Password, UserType, ComputerNmae)
|
(UserName, Password, UserType, ComputerNmae)
|
||||||
VALUES (@username, @password, @userType, @computerName)
|
VALUES (@username, @password, @userType, @computerName)
|
||||||
`
|
`
|
||||||
params = {
|
params = {
|
||||||
username: { value: username, type: sql.NVarChar },
|
username: { value: username, type: sql.NVarChar(255) },
|
||||||
password: { value: password, type: sql.NVarChar },
|
password: { value: password, type: sql.NVarChar(255) },
|
||||||
userType: { value: userType, type: sql.NVarChar },
|
userType: { value: userType, type: sql.NVarChar(255) },
|
||||||
computerName: { value: computerName, type: sql.NVarChar }
|
computerName: { value: computerName, type: sql.NVarChar(255) }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sql = `
|
sqlString = `
|
||||||
INSERT INTO ${tableName}
|
INSERT INTO ${tableName}
|
||||||
(UserName, Password, UserType)
|
(UserName, Password, UserType)
|
||||||
VALUES (@username, @password, @userType)
|
VALUES (@username, @password, @userType)
|
||||||
`
|
`
|
||||||
params = {
|
params = {
|
||||||
username: { value: username, type: sql.NVarChar },
|
username: { value: username, type: sql.NVarChar(255) },
|
||||||
password: { value: password, type: sql.NVarChar },
|
password: { value: password, type: sql.NVarChar(255) },
|
||||||
userType: { value: userType, type: sql.NVarChar }
|
userType: { value: userType, type: sql.NVarChar(255) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await (dbService as SqlServerService).queryWithParams(sqlString, params)
|
await (dbService as SqlServerService).queryWithParams(sqlString, params)
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
let sql: string
|
let sqlString: string
|
||||||
let params: any[]
|
let params: unknown[]
|
||||||
|
|
||||||
if (computerName) {
|
if (computerName) {
|
||||||
sql = `
|
sqlString = `
|
||||||
INSERT INTO ${tableName}
|
INSERT INTO ${tableName}
|
||||||
(UserName, Password, UserType, ComputerNmae)
|
(UserName, Password, UserType, ComputerNmae)
|
||||||
VALUES (?, ?, ?, ?)
|
VALUES (?, ?, ?, ?)
|
||||||
`
|
`
|
||||||
params = [username, password, userType, computerName]
|
params = [username, password, userType, computerName]
|
||||||
} else {
|
} else {
|
||||||
sql = `
|
sqlString = `
|
||||||
INSERT INTO ${tableName}
|
INSERT INTO ${tableName}
|
||||||
(UserName, Password, UserType)
|
(UserName, Password, UserType)
|
||||||
VALUES (?, ?, ?)
|
VALUES (?, ?, ?)
|
||||||
@@ -343,8 +349,8 @@ export class BIPUsersDAO {
|
|||||||
`
|
`
|
||||||
|
|
||||||
await (dbService as SqlServerService).queryWithParams(sqlString, {
|
await (dbService as SqlServerService).queryWithParams(sqlString, {
|
||||||
username: { value: username, type: sql.NVarChar },
|
username: { value: username, type: sql.NVarChar(255) },
|
||||||
userType: { value: userType, type: sql.NVarChar }
|
userType: { value: userType, type: sql.NVarChar(255) }
|
||||||
})
|
})
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
@@ -382,8 +388,8 @@ export class BIPUsersDAO {
|
|||||||
`
|
`
|
||||||
|
|
||||||
await (dbService as SqlServerService).queryWithParams(sqlString, {
|
await (dbService as SqlServerService).queryWithParams(sqlString, {
|
||||||
username: { value: username, type: sql.NVarChar },
|
username: { value: username, type: sql.NVarChar(255) },
|
||||||
newPassword: { value: newPassword, type: sql.NVarChar }
|
newPassword: { value: newPassword, type: sql.NVarChar(255) }
|
||||||
})
|
})
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
@@ -419,7 +425,7 @@ export class BIPUsersDAO {
|
|||||||
`
|
`
|
||||||
|
|
||||||
await (dbService as SqlServerService).queryWithParams(sqlString, {
|
await (dbService as SqlServerService).queryWithParams(sqlString, {
|
||||||
username: { value: username, type: sql.NVarChar }
|
username: { value: username, type: sql.NVarChar(255) }
|
||||||
})
|
})
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
@@ -455,7 +461,7 @@ export class BIPUsersDAO {
|
|||||||
`
|
`
|
||||||
|
|
||||||
const result = await (dbService as SqlServerService).queryWithParams(sqlString, {
|
const result = await (dbService as SqlServerService).queryWithParams(sqlString, {
|
||||||
username: { value: username, type: sql.NVarChar }
|
username: { value: username, type: sql.NVarChar(255) }
|
||||||
})
|
})
|
||||||
return result.rows.length > 0 && (result.rows[0].count as number) > 0
|
return result.rows.length > 0 && (result.rows[0].count as number) > 0
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -53,7 +53,11 @@ export function useAuth(): UseAuthReturn {
|
|||||||
setState((prev) => ({ ...prev, loading: true, error: null }))
|
setState((prev) => ({ ...prev, loading: true, error: null }))
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await window.electron.ipcRenderer.invoke('auth:login', credentials)
|
const result = (await window.electron.ipcRenderer.invoke('auth:login', credentials)) as {
|
||||||
|
success: boolean
|
||||||
|
userInfo?: UserInfo
|
||||||
|
error?: string
|
||||||
|
}
|
||||||
|
|
||||||
if (result.success && result.userInfo) {
|
if (result.success && result.userInfo) {
|
||||||
setState({
|
setState({
|
||||||
@@ -85,7 +89,12 @@ export function useAuth(): UseAuthReturn {
|
|||||||
setState((prev) => ({ ...prev, loading: true, error: null }))
|
setState((prev) => ({ ...prev, loading: true, error: null }))
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await window.electron.ipcRenderer.invoke('auth:silentLogin')
|
const result = (await window.electron.ipcRenderer.invoke('auth:silentLogin')) as {
|
||||||
|
success: boolean
|
||||||
|
userInfo?: UserInfo
|
||||||
|
error?: string
|
||||||
|
requiresUserSelection?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
if (result.success && result.userInfo) {
|
if (result.success && result.userInfo) {
|
||||||
setState({
|
setState({
|
||||||
@@ -126,14 +135,18 @@ export function useAuth(): UseAuthReturn {
|
|||||||
|
|
||||||
const getCurrentUser = useCallback(async (): Promise<UserInfo | null> => {
|
const getCurrentUser = useCallback(async (): Promise<UserInfo | null> => {
|
||||||
try {
|
try {
|
||||||
const result = await window.electron.ipcRenderer.invoke('auth:getCurrentUser')
|
const result = (await window.electron.ipcRenderer.invoke('auth:getCurrentUser')) as {
|
||||||
|
isAuthenticated: boolean
|
||||||
|
userInfo?: UserInfo
|
||||||
|
}
|
||||||
if (result.isAuthenticated && result.userInfo) {
|
if (result.isAuthenticated && result.userInfo) {
|
||||||
|
const userInfo = result.userInfo
|
||||||
setState((prev) => ({
|
setState((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
user: result.userInfo,
|
user: userInfo,
|
||||||
isAuthenticated: true
|
isAuthenticated: true
|
||||||
}))
|
}))
|
||||||
return result.userInfo
|
return userInfo
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
} catch {
|
} catch {
|
||||||
@@ -143,7 +156,7 @@ export function useAuth(): UseAuthReturn {
|
|||||||
|
|
||||||
const getAllUsers = useCallback(async (): Promise<UserInfo[]> => {
|
const getAllUsers = useCallback(async (): Promise<UserInfo[]> => {
|
||||||
try {
|
try {
|
||||||
return await window.electron.ipcRenderer.invoke('auth:getAllUsers')
|
return (await window.electron.ipcRenderer.invoke('auth:getAllUsers')) as UserInfo[]
|
||||||
} catch {
|
} catch {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@@ -153,7 +166,11 @@ export function useAuth(): UseAuthReturn {
|
|||||||
setState((prev) => ({ ...prev, loading: true, error: null }))
|
setState((prev) => ({ ...prev, loading: true, error: null }))
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await window.electron.ipcRenderer.invoke('auth:switchUser', userInfo)
|
const result = (await window.electron.ipcRenderer.invoke('auth:switchUser', userInfo)) as {
|
||||||
|
success: boolean
|
||||||
|
userInfo?: UserInfo
|
||||||
|
error?: string
|
||||||
|
}
|
||||||
|
|
||||||
if (result.success && result.userInfo) {
|
if (result.success && result.userInfo) {
|
||||||
setState({
|
setState({
|
||||||
@@ -180,7 +197,7 @@ export function useAuth(): UseAuthReturn {
|
|||||||
|
|
||||||
const isAdmin = useCallback(async (): Promise<boolean> => {
|
const isAdmin = useCallback(async (): Promise<boolean> => {
|
||||||
try {
|
try {
|
||||||
return await window.electron.ipcRenderer.invoke('auth:isAdmin')
|
return (await window.electron.ipcRenderer.invoke('auth:isAdmin')) as boolean
|
||||||
} catch {
|
} catch {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,9 +44,13 @@ export function useCleaner(): UseCleanerReturn {
|
|||||||
setState({ loading: true, data: null, error: null })
|
setState({ loading: true, data: null, error: null })
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await window.electron.ipcRenderer.invoke('cleaner:run', input)
|
const result = (await window.electron.ipcRenderer.invoke('cleaner:run', input)) as {
|
||||||
|
success: boolean
|
||||||
|
data?: CleanerResult
|
||||||
|
error?: string
|
||||||
|
}
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success && result.data) {
|
||||||
setState({ loading: false, data: result.data, error: null })
|
setState({ loading: false, data: result.data, error: null })
|
||||||
return result.data
|
return result.data
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -43,9 +43,13 @@ export function useExtractor(): UseExtractorReturn {
|
|||||||
setState({ loading: true, data: null, error: null })
|
setState({ loading: true, data: null, error: null })
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await window.electron.ipcRenderer.invoke('extractor:run', input)
|
const result = (await window.electron.ipcRenderer.invoke('extractor:run', input)) as {
|
||||||
|
success: boolean
|
||||||
|
data?: ExtractorResult
|
||||||
|
error?: string
|
||||||
|
}
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success && result.data) {
|
||||||
setState({ loading: false, data: result.data, error: null })
|
setState({ loading: false, data: result.data, error: null })
|
||||||
return result.data
|
return result.data
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -68,13 +68,18 @@ export function useValidation(): UseValidationReturn {
|
|||||||
setState((prev) => ({ ...prev, loading: true, error: null }))
|
setState((prev) => ({ ...prev, loading: true, error: null }))
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await window.electron.ipcRenderer.invoke('validation:validate', request)
|
const result = (await window.electron.ipcRenderer.invoke(
|
||||||
|
'validation:validate',
|
||||||
|
request
|
||||||
|
)) as ValidationResponse
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
|
const results = result.results || null
|
||||||
|
const stats = result.stats || null
|
||||||
setState({
|
setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
data: result.results || null,
|
data: results,
|
||||||
stats: result.stats || null,
|
stats: stats,
|
||||||
error: null
|
error: null
|
||||||
})
|
})
|
||||||
return result
|
return result
|
||||||
@@ -105,7 +110,9 @@ export function useValidation(): UseValidationReturn {
|
|||||||
|
|
||||||
const getSharedProductionIds = useCallback(async (): Promise<string[]> => {
|
const getSharedProductionIds = useCallback(async (): Promise<string[]> => {
|
||||||
try {
|
try {
|
||||||
const result = await window.electron.ipcRenderer.invoke('validation:getSharedProductionIds')
|
const result = (await window.electron.ipcRenderer.invoke(
|
||||||
|
'validation:getSharedProductionIds'
|
||||||
|
)) as { productionIds?: string[] }
|
||||||
return result?.productionIds || []
|
return result?.productionIds || []
|
||||||
} catch {
|
} catch {
|
||||||
return []
|
return []
|
||||||
@@ -117,7 +124,11 @@ export function useValidation(): UseValidationReturn {
|
|||||||
materialCodes: string[]
|
materialCodes: string[]
|
||||||
} | null> => {
|
} | null> => {
|
||||||
try {
|
try {
|
||||||
const result = await window.electron.ipcRenderer.invoke('validation:getCleanerData')
|
const result = (await window.electron.ipcRenderer.invoke('validation:getCleanerData')) as {
|
||||||
|
success: boolean
|
||||||
|
orderNumbers?: string[]
|
||||||
|
materialCodes?: string[]
|
||||||
|
}
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
return {
|
return {
|
||||||
orderNumbers: result.orderNumbers || [],
|
orderNumbers: result.orderNumbers || [],
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
"noUnusedParameters": false,
|
"noUnusedParameters": false,
|
||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"esModuleInterop": true
|
"esModuleInterop": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"emitDecoratorMetadata": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user