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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ test/plugin-test-config/plugin-config-data/
test/plugin-test-config/ssl-cert.pem
test/plugin-test-config/ssl-key.pem
test/plugin-test-config/baseDeltas.json
test/plugin-test-config/unitpreferences/

test/server-test-config/applicationData/
test/server-test-config/unitpreferences/
test/server-test-config/ssl-cert.pem
test/server-test-config/ssl-key.pem
test/server-test-config/plugin-config-data/
Expand Down
2 changes: 1 addition & 1 deletion src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ export function load(app: ConfigApp) {

// Load unit preferences
try {
loadUnitPreferences()
setApplicationDataPath(app.config.configPath)
loadUnitPreferences()
debug('Unit preferences loaded')
} catch (err) {
console.error('Failed to load unit preferences:', err)
Expand Down
107 changes: 66 additions & 41 deletions src/interfaces/unitpreferences-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,26 +124,6 @@ function validatePreset(preset, definitions) {
return null
}

/**
* Check if a preset name already exists
* @param {string} presetName - The preset filename (without .json)
* @returns {object|null} - { type: 'builtin'|'custom' } if exists, null if not
*/
function checkPresetExists(presetName) {
const builtInPath = path.join(UNITPREFS_DIR, 'presets', `${presetName}.json`)
if (fs.existsSync(builtInPath)) {
return { type: 'builtin' }
}
const customPath = path.join(
UNITPREFS_DIR,
'presets/custom',
`${presetName}.json`
)
if (fs.existsSync(customPath)) {
return { type: 'custom' }
}
return null
}
const {
getConfig,
getCategories,
Expand All @@ -156,9 +136,34 @@ const {
getDefaultCategory
} = require('../unitpreferences')

const UNITPREFS_DIR = path.join(__dirname, '../../unitpreferences')
const PACKAGE_UNITPREFS_DIR = path.join(__dirname, '../../unitpreferences')

module.exports = function (app) {
const CONFIG_UNITPREFS_DIR = path.join(
app.config.configPath,
'unitpreferences'
)

function checkPresetExists(presetName) {
const builtInPath = path.join(
PACKAGE_UNITPREFS_DIR,
'presets',
`${presetName}.json`
)
if (fs.existsSync(builtInPath)) {
return { type: 'builtin' }
}
const customPath = path.join(
CONFIG_UNITPREFS_DIR,
'presets/custom',
`${presetName}.json`
)
if (fs.existsSync(customPath)) {
return { type: 'custom' }
}
return null
}

const router = express.Router()

// GET /signalk/v1/unitpreferences/config
Expand All @@ -175,7 +180,7 @@ module.exports = function (app) {
// PUT /signalk/v1/unitpreferences/config
router.put('/config', (req, res) => {
try {
const configPath = path.join(UNITPREFS_DIR, 'config.json')
const configPath = path.join(CONFIG_UNITPREFS_DIR, 'config.json')
fs.writeFileSync(configPath, JSON.stringify(req.body, null, 2))
reloadPreset()
app.emit('unitpreferencesChanged', { type: 'global' })
Expand Down Expand Up @@ -212,7 +217,7 @@ module.exports = function (app) {
router.get('/custom-definitions', (req, res) => {
try {
const customPath = path.join(
UNITPREFS_DIR,
CONFIG_UNITPREFS_DIR,
'custom-units-definitions.json'
)
if (fs.existsSync(customPath)) {
Expand All @@ -238,7 +243,7 @@ module.exports = function (app) {
}

const customPath = path.join(
UNITPREFS_DIR,
CONFIG_UNITPREFS_DIR,
'custom-units-definitions.json'
)
fs.writeFileSync(customPath, JSON.stringify(req.body, null, 2))
Expand All @@ -265,7 +270,10 @@ module.exports = function (app) {
// PUT /signalk/v1/unitpreferences/custom-categories
router.put('/custom-categories', (req, res) => {
try {
const customPath = path.join(UNITPREFS_DIR, 'custom-categories.json')
const customPath = path.join(
CONFIG_UNITPREFS_DIR,
'custom-categories.json'
)
fs.writeFileSync(customPath, JSON.stringify(req.body, null, 2))
reloadCustomCategories()
app.emit('unitpreferencesChanged', { type: 'global' })
Expand All @@ -279,13 +287,13 @@ module.exports = function (app) {
// GET /signalk/v1/unitpreferences/presets
router.get('/presets', (req, res) => {
try {
const presetsDir = path.join(UNITPREFS_DIR, 'presets')
const customDir = path.join(presetsDir, 'custom')
const presetsDir = path.join(PACKAGE_UNITPREFS_DIR, 'presets')
const customDir = path.join(CONFIG_UNITPREFS_DIR, 'presets', 'custom')

const builtIn = []
const custom = []

// List built-in presets
// List built-in presets from package dir
const builtInFiles = fs.readdirSync(presetsDir)
for (const file of builtInFiles) {
if (file.endsWith('.json')) {
Expand All @@ -299,7 +307,7 @@ module.exports = function (app) {
}
}

// List custom presets
// List custom presets from config dir
if (fs.existsSync(customDir)) {
const customFiles = fs.readdirSync(customDir)
for (const file of customFiles) {
Expand Down Expand Up @@ -332,9 +340,9 @@ module.exports = function (app) {
return
}

// Check custom first
// Check custom presets in config dir first
const customPath = path.join(
UNITPREFS_DIR,
CONFIG_UNITPREFS_DIR,
'presets/custom',
`${presetName}.json`
)
Expand All @@ -344,9 +352,9 @@ module.exports = function (app) {
return
}

// Fall back to built-in
// Fall back to built-in in package dir
const builtInPath = path.join(
UNITPREFS_DIR,
PACKAGE_UNITPREFS_DIR,
'presets',
`${presetName}.json`
)
Expand Down Expand Up @@ -388,7 +396,7 @@ module.exports = function (app) {
return
}

const customDir = path.join(UNITPREFS_DIR, 'presets/custom')
const customDir = path.join(CONFIG_UNITPREFS_DIR, 'presets/custom')
if (!fs.existsSync(customDir)) {
fs.mkdirSync(customDir, { recursive: true })
}
Expand All @@ -413,7 +421,7 @@ module.exports = function (app) {
}

const presetPath = path.join(
UNITPREFS_DIR,
CONFIG_UNITPREFS_DIR,
'presets/custom',
`${presetName}.json`
)
Expand All @@ -435,18 +443,37 @@ module.exports = function (app) {
router.get('/active', (req, res) => {
try {
const preset = getActivePreset()
res.json(preset)
const definitions = getMergedDefinitions()
const result = {
...preset,
categories: { ...preset.categories }
}
for (const [category, catDef] of Object.entries(result.categories)) {
const unitDef = definitions[catDef.baseUnit]
const conversion = unitDef?.conversions?.[catDef.targetUnit]
if (conversion) {
result.categories[category] = {
...catDef,
formula: conversion.formula,
inverseFormula: conversion.inverseFormula,
symbol: conversion.symbol
}
}
}
res.json(result)
} catch (err) {
debug('Error getting active preset:', err)
res.status(500).json({ error: 'Failed to get active preset' })
}
})

// GET /signalk/v1/unitpreferences/default-categories
// Returns the full default-categories.json data
router.get('/default-categories', (req, res) => {
try {
const defaultCatPath = path.join(UNITPREFS_DIR, 'default-categories.json')
const defaultCatPath = path.join(
PACKAGE_UNITPREFS_DIR,
'default-categories.json'
)
if (fs.existsSync(defaultCatPath)) {
const data = JSON.parse(fs.readFileSync(defaultCatPath, 'utf-8'))
res.json(data)
Expand All @@ -460,7 +487,6 @@ module.exports = function (app) {
})

// GET /signalk/v1/unitpreferences/default-category/:path
// Returns the default category for a specific SignalK path
router.get('/default-category/*', (req, res) => {
try {
const signalkPath = req.params[0]
Expand All @@ -473,7 +499,6 @@ module.exports = function (app) {
})

// POST /signalk/v1/unitpreferences/presets/custom/upload
// Upload a custom preset file (admin only)
const MAX_PRESET_SIZE = 100 * 1024 // 100KB

router.post('/presets/custom/upload', (req, res) => {
Expand Down Expand Up @@ -569,7 +594,7 @@ module.exports = function (app) {
}

// Ensure custom directory exists
const customDir = path.join(UNITPREFS_DIR, 'presets/custom')
const customDir = path.join(CONFIG_UNITPREFS_DIR, 'presets/custom')
if (!fs.existsSync(customDir)) {
fs.mkdirSync(customDir, { recursive: true })
}
Expand Down
1 change: 1 addition & 0 deletions src/unitpreferences/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export {
getActivePreset,
getActivePresetForUser,
getDefaultCategory,
getConfigUnitprefsDir,
setApplicationDataPath,
DEFAULT_PRESET
} from './loader'
Expand Down
Loading
Loading