Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More

@platformatic/config

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@platformatic/config - npm Package Compare versions

Comparing version 0.21.1 to 0.22.0

@@ -9,4 +9,5 @@ 'use strict'

const dotenv = require('dotenv')
const { request } = require('undici')
const { FileWatcher } = require('@platformatic/utils')
const { getParser, analyze } = require('@platformatic/metaconfig')
const { getParser, analyze, upgrade } = require('@platformatic/metaconfig')

@@ -46,2 +47,3 @@ class ConfigManager extends EventEmitter {

this.schemaOptions = opts.schemaOptions || {}
this._providedSchema = !!opts.schema
this._originalEnv = opts.env || {}

@@ -139,5 +141,3 @@ this.env = this.purgeEnv(this._originalEnv)

let meta = await analyze({ config: this.current })
while (typeof meta.up === 'function') {
meta = meta.up()
}
meta = upgrade(meta)
this.current = meta.config

@@ -148,2 +148,17 @@ } catch {

}
if (!this._providedSchema && this.current.$schema) {
// The user did not provide a schema, but we have a link to the schema
// in $schema. Try to fetch the schema and ignore anything that goes
// wrong.
try {
const { body, statusCode } = await request(this.current.$schema)
if (statusCode === 200) {
this.schema = await body.json()
}
} catch {
// Ignore error.
}
}
const validationResult = this.validate()

@@ -181,2 +196,5 @@ if (!validationResult) {

validate: (schema, path, parentSchema, data) => {
if (typeof path !== 'string' || path.trim() === '') {
return false
}
const resolved = resolve(this.dirname, path)

@@ -228,4 +246,44 @@ data.parentData[data.parentDataProperty] = resolved

}
static listConfigFiles (type) {
if (type) {
// A config type (service, db, etc.) was explicitly provided.
return [
`platformatic.${type}.json`,
`platformatic.${type}.json5`,
`platformatic.${type}.yaml`,
`platformatic.${type}.yml`,
`platformatic.${type}.toml`,
`platformatic.${type}.tml`
]
} else {
// A config type was not provided. Search for all known types and
// formats. Unfortunately, this means the ConfigManager needs to be
// aware of the different application types (but that should be small).
return [
...this.listConfigFiles('service'),
...this.listConfigFiles('db')
]
}
}
static async findConfigFile (directory, type) {
directory ??= process.cwd()
const configFileNames = this.listConfigFiles(type)
const configFilesAccessibility = await Promise.all(configFileNames.map((fileName) => isFileAccessible(fileName, directory)))
const accessibleConfigFilename = configFileNames.find((value, index) => configFilesAccessibility[index])
return accessibleConfigFilename
}
}
async function isFileAccessible (filename, directory) {
try {
const filePath = resolve(directory, filename)
await access(filePath)
return true
} catch (err) {
return false
}
}
module.exports = ConfigManager
{
"name": "@platformatic/config",
"version": "0.21.1",
"version": "0.22.0",
"description": "Platformatic DB Config Manager",

@@ -17,9 +17,9 @@ "main": "index.js",

"devDependencies": {
"fastify": "^4.13.0",
"@iarna/toml": "^2.2.5",
"fastify": "^4.17.0",
"json5": "^2.2.3",
"snazzy": "^9.0.0",
"standard": "^17.0.0",
"json5": "^2.2.3",
"yaml": "^2.2.1",
"@iarna/toml": "^2.2.5",
"tap": "^16.3.4"
"tap": "^16.3.4",
"yaml": "^2.2.2"
},

@@ -30,4 +30,6 @@ "dependencies": {

"pupa": "^3.1.0",
"@platformatic/utils": "0.21.1",
"@platformatic/metaconfig": "0.21.1"
"semver": "^7.5.0",
"undici": "^5.22.0",
"@platformatic/metaconfig": "0.22.0",
"@platformatic/utils": "0.22.0"
},

@@ -34,0 +36,0 @@ "scripts": {

'use strict'
const { test } = require('tap')
const { resolve } = require('path')
const { join, resolve } = require('path')
const ConfigManager = require('..')

@@ -255,1 +255,69 @@ const path = require('path')

})
test('ConfigManager.listConfigFiles() lists possible configs by type', async ({ plan, same }) => {
plan(2)
same(ConfigManager.listConfigFiles('db'), [
'platformatic.db.json',
'platformatic.db.json5',
'platformatic.db.yaml',
'platformatic.db.yml',
'platformatic.db.toml',
'platformatic.db.tml'
])
same(ConfigManager.listConfigFiles('service'), [
'platformatic.service.json',
'platformatic.service.json5',
'platformatic.service.yaml',
'platformatic.service.yml',
'platformatic.service.toml',
'platformatic.service.tml'
])
})
test('ConfigManager.listConfigFiles() lists all possible configs', async ({ plan, same }) => {
plan(1)
same(ConfigManager.listConfigFiles(), [
'platformatic.service.json',
'platformatic.service.json5',
'platformatic.service.yaml',
'platformatic.service.yml',
'platformatic.service.toml',
'platformatic.service.tml',
'platformatic.db.json',
'platformatic.db.json5',
'platformatic.db.yaml',
'platformatic.db.yml',
'platformatic.db.toml',
'platformatic.db.tml'
])
})
test('ConfigManager.findConfigFile() finds configs by type', async ({ plan, same }) => {
plan(2)
const fixturesDir = join(__dirname, 'fixtures')
same(
await ConfigManager.findConfigFile(fixturesDir, 'db'),
'platformatic.db.json'
)
same(
await ConfigManager.findConfigFile(fixturesDir, 'service'),
'platformatic.service.json'
)
})
test('ConfigManager.findConfigFile() finds configs without type', async ({ plan, same }) => {
plan(1)
const fixturesDir = join(__dirname, 'fixtures')
same(
await ConfigManager.findConfigFile(fixturesDir),
'platformatic.service.json'
)
})
test('ConfigManager.findConfigFile() searches cwd by default', async ({ plan, same }) => {
plan(1)
same(
await ConfigManager.findConfigFile(),
undefined
)
})
'use strict'
const { test } = require('tap')
const { resolve } = require('path')
const { join, resolve } = require('path')
const ConfigManager = require('..')
const pkg = require('../package.json')
const { MockAgent, setGlobalDispatcher, getGlobalDispatcher } = require('undici')
const { schema } = require('../../db') // avoid circular dependency on pnpm

@@ -114,8 +116,33 @@ test('should throw if file is not found', async ({ match, fail }) => {

test('should automatically update', async ({ same }) => {
test('should automatically update', async ({ same, teardown, pass, plan }) => {
plan(2)
const _agent = getGlobalDispatcher()
const mockAgent = new MockAgent()
setGlobalDispatcher(mockAgent)
teardown(() => {
setGlobalDispatcher(_agent)
})
// Provide the base url to the request
const mockPool = mockAgent.get('https://platformatic.dev')
mockAgent.disableNetConnect()
// intercept the request
mockPool.intercept({
path: `/schemas/v${pkg.version.replace(/\.\d+$/, '.0')}/db`,
method: 'GET'
}).reply(404, () => {
pass('should have called the mock server')
return {
message: 'not found'
}
})
const fixturesDir = join(__dirname, 'fixtures')
const cm = new ConfigManager({
source: resolve(__dirname, './fixtures/db-0.16.0.json'),
source: join(fixturesDir, 'db-0.16.0.json'),
env: { PLT_FOOBAR: 'foobar' }
})
await cm.parse()
same(cm.current, {

@@ -131,3 +158,6 @@ $schema: `https://platformatic.dev/schemas/v${pkg.version.replace(/\.\d+$/, '.0')}/db`,

},
migrations: { dir: './demo/migrations', validateChecksums: false },
migrations: {
dir: './demo/migrations',
validateChecksums: false
},
dashboard: { path: '/' },

@@ -137,1 +167,49 @@ authorization: { adminSecret: 'plt-db' }

})
test('should use the remote schema', async ({ same, teardown, pass, plan }) => {
plan(2)
const _agent = getGlobalDispatcher()
const mockAgent = new MockAgent()
setGlobalDispatcher(mockAgent)
teardown(() => {
setGlobalDispatcher(_agent)
})
// Provide the base url to the request
const mockPool = mockAgent.get('https://platformatic.dev')
mockAgent.disableNetConnect()
// intercept the request
mockPool.intercept({
path: `/schemas/v${pkg.version.replace(/\.\d+$/, '.0')}/db`,
method: 'GET'
}).reply(200, () => {
pass('should have called the mock server')
return JSON.stringify(schema)
})
const fixturesDir = join(__dirname, 'fixtures')
const cm = new ConfigManager({
source: join(fixturesDir, 'db-0.16.0.json'),
env: { PLT_FOOBAR: 'foobar' }
})
await cm.parse()
same(cm.current, {
$schema: `https://platformatic.dev/schemas/v${pkg.version.replace(/\.\d+$/, '.0')}/db`,
server: { hostname: '127.0.0.1', port: '3042', logger: { level: 'info' } },
metrics: { auth: { username: 'plt-db', password: 'plt-db' } },
plugins: { paths: [join(fixturesDir, 'plugin-sum.js')] },
db: {
connectionString: 'postgres://postgres:postgres@localhost:5432/postgres',
graphiql: true,
ignore: { versions: true }
},
migrations: {
dir: join(fixturesDir, 'demo', 'migrations'),
validateChecksums: false
},
dashboard: { path: '/' },
authorization: { adminSecret: 'plt-db' }
})
})

@@ -7,3 +7,3 @@ 'use strict'

test('do not emit event for not allowed files', async ({ teardown, equal, fail }) => {
test('do not emit event for not allowed files', async ({ equal }) => {
const configFile = path.join(__dirname, 'fixtures', 'onepath.json')

@@ -28,1 +28,19 @@ const cm = new ConfigManager({

})
test('do not emit event for empty paths', async ({ equal }) => {
const cm = new ConfigManager({
source: { path: '' },
schema: {
type: 'object',
properties: {
path: {
type: 'string',
resolvePath: true
}
}
}
})
const parseResult = await cm.parse()
equal(parseResult, false)
})