New data structures for handling configuration load

This commit is contained in:
2026-05-26 22:12:16 -07:00
parent 4a74e1bca5
commit c93c038153
3 changed files with 59 additions and 9 deletions

View File

@@ -2,8 +2,8 @@
"stores": [
{
"name": "kroger",
"base_url": "https://shockrah.xyz",
"roducts": []
"base_url": "https://api-ce.kroger.com/v1/",
"products": []
}
]
}

View File

@@ -1,4 +1,4 @@
import fsPromises from 'fs/promises';
import fsPromises from 'fs/promises'
interface Product {
name: string,
@@ -14,25 +14,59 @@ export interface Store {
/*
* NOTE: ConentConfig defines what content we actually want; it has
* almost nothing to do with key definitions and is meant to be fully public.
*
* Here we control what stores and what products we are going to query
* from the configuration since the collector is basically just a oneshot
* tool
*/
export interface Config {
export interface ContentConfig {
stores: Array<Store>
}
/*
* Sets up the API keys that we pull in from the environment
* WARN: this should never mix wth the Config type to keep things
* from leaking out into a plaintext file. Config's are considered to be
* expendable and public facing and as such can be committed ( for my
* purposes )
*/
export interface Keys {
kroger_id: string|undefined
kroger_secret: string|undefined
}
/*
* Environment variable names to look out for for key values
*/
export const EnvVars = {
kroger_id: 'KROGER_CLIENT_ID',
kroger_secret: 'KROGER_SECRET'
}
/**
* Loads the values from the env const
*
*/
export function LoadKeys() : Keys {
return {
kroger_id: process.env.KROGER_CLIENT_ID,
kroger_secret: process.env.KROGER_SECRET,
}
}
/*
* Handling the validation of our configuration
*
*/
function valid(data: any) : data is Config {
function valid(data: any) : data is ContentConfig {
if('stores' in data) {
if(!(data['stores'] instanceof Array)) {
console.error('stores is not an array!')
return false
}
for(const store in data['stores']) {
for(const store of data['stores']) {
// TODO: i don't like this check but it's fine for now :thinking:
const keys = Object.keys(store);
return keys.includes('name') && keys.includes('base_url') && keys.includes('products')
@@ -46,13 +80,14 @@ function valid(data: any) : data is Config {
* Handling the loading and generation of the Configuration that we'll use
* during the run of data fetching.
*/
export async function LoadConfig(path: string) : Promise<Config|null> {
export async function LoadConfig(path: string) : Promise<ContentConfig|null> {
try {
const file = await fsPromises.readFile(path);
const config: Config = JSON.parse(file.toString())
const config: ContentConfig = JSON.parse(file.toString())
return valid(config) ? config : null;
} catch {
// TODO: fix this catch block to be more explicit
console.error('bro')
return null;
}
}

View File

@@ -0,0 +1,15 @@
export class EnvVarError extends Error {
constructor(message: string) {
super(message)
this.name = 'EnvVarError'
this.message = message
}
}
export class ConfigurationError extends Error {
constructor(message: string) {
super(message)
this.name = 'CollectorConfigurationError'
this.message = message
}
}