Skip to content

Commit

Permalink
Feat/language resolution (#375)
Browse files Browse the repository at this point in the history
* Comments

* Added language choice

* wip

* it works

* Read lang files at startup

* validated lang files

* default language

* tests

* tests

* changelog

* lang files accept object structure

* beauty

---------

Co-authored-by: epessina <[email protected]>
Co-authored-by: Fabio Nappi <[email protected]>
  • Loading branch information
3 people authored Mar 18, 2024
1 parent eecb419 commit f7198a2
Show file tree
Hide file tree
Showing 16 changed files with 488 additions and 44 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## Unreleased

### Added

- Languange resolution via Content Negotiation

## [3.0.6] - 2023-12-14

### Versioning
Expand Down
103 changes: 103 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,16 @@
},
"dependencies": {
"@apidevtools/json-schema-ref-parser": "^11.1.0",
"@fastify/accepts": "^4.3.0",
"@mia-platform/custom-plugin-lib": "^6.0.0",
"ajv": "^8.12.0",
"commander": "^11.0.0",
"fast-json-patch": "^3.1.1",
"glob": "^10.3.10",
"js-yaml": "^4.1.0",
"jsonpath-plus": "^7.2.0",
"lodash.clonedeepwith": "^4.5.0",
"lodash.get": "^4.4.2",
"mkdirp": "^3.0.1"
},
"devDependencies": {
Expand All @@ -52,6 +55,8 @@
"@types/chai-as-promised": "^7.1.6",
"@types/glob": "^8.1.0",
"@types/js-yaml": "^4.0.6",
"@types/lodash.clonedeepwith": "^4.5.9",
"@types/lodash.get": "^4.4.9",
"@types/mocha": "^10.0.2",
"@types/node": "^20.7.1",
"@types/sinon": "^17.0.3",
Expand Down
40 changes: 37 additions & 3 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,46 @@
import { existsSync, readFileSync } from 'fs'
import { existsSync, readFileSync, readdirSync } from 'fs'
import path from 'path'

import * as defaults from './defaults'
import type { ContentTypeMap } from './schemas'
import type { EnvironmentVariables } from './schemas/environmentVariablesSchema'

type HeadersMap = Record<`/${string}`, Record<string, string>>;

interface LanguageConfig {
labelsMap: Record<string, unknown>
languageId: string
}

interface RuntimeConfig extends Required<EnvironmentVariables> {
CONTENT_TYPE_MAP: ContentTypeMap
LANGUAGES_CONFIG: LanguageConfig[]
PUBLIC_HEADERS_MAP: HeadersMap
USER_PROPERTIES_HEADER_KEY: string | undefined
}

const validateLanguages = (languageDirPath: string): LanguageConfig[] => {
if (!existsSync(languageDirPath)) {
return []
}

const languageFilenames = readdirSync(languageDirPath)
return languageFilenames.map((filename) => {
const filepath = path.join(languageDirPath, filename)
const fileContent = JSON.parse(readFileSync(filepath).toString()) as unknown
if (!fileContent
|| typeof fileContent !== 'object'
|| Array.isArray(fileContent)) {
throw new Error(`${filename} is not a valid language configuration`)
}

return {
labelsMap: fileContent as Record<string, unknown>,
languageId: path.basename(filename, '.json'),
}
})
}

const validateContentTypeMap = (contentTypeMap: unknown) => {
if (contentTypeMap === null || typeof contentTypeMap !== 'object') {
return defaults.CONTENT_TYPE_MAP
Expand Down Expand Up @@ -74,7 +103,10 @@ const getPublicHeadersMap = (input: unknown): HeadersMap => {
}

const parseConfig = (config: EnvironmentVariables & Record<string, string>): RuntimeConfig => {
const { SERVICE_CONFIG_PATH = defaults.SERVICE_CONFIG_PATH } = config
const {
LANGUAGES_DIRECTORY_PATH = defaults.LANGUAGES_DIRECTORY_PATH,
SERVICE_CONFIG_PATH = defaults.SERVICE_CONFIG_PATH,
} = config
let serviceConfig: unknown = defaults.PUBLIC_HEADERS_MAP

let configPath: string | undefined
Expand Down Expand Up @@ -103,6 +135,8 @@ const parseConfig = (config: EnvironmentVariables & Record<string, string>): Run

return {
CONTENT_TYPE_MAP: validateContentTypeMap(contentTypeMap),
LANGUAGES_CONFIG: validateLanguages(LANGUAGES_DIRECTORY_PATH),
LANGUAGES_DIRECTORY_PATH,
PUBLIC_DIRECTORY_PATH: config.PUBLIC_DIRECTORY_PATH ?? defaults.PUBLIC_DIRECTORY_PATH,
PUBLIC_HEADERS_MAP: getPublicHeadersMap(publicHeadersMap),
RESOURCES_DIRECTORY_PATH: config.RESOURCES_DIRECTORY_PATH ?? defaults.RESOURCES_DIRECTORY_PATH,
Expand All @@ -111,5 +145,5 @@ const parseConfig = (config: EnvironmentVariables & Record<string, string>): Run
}
}

export type { RuntimeConfig }
export type { LanguageConfig, RuntimeConfig }
export { parseConfig }
3 changes: 3 additions & 0 deletions src/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const RESOURCES_DIRECTORY_PATH = '/usr/static/configurations'

const PUBLIC_DIRECTORY_PATH = '/usr/static/public'

const LANGUAGES_DIRECTORY_PATH = '/usr/static/languages'

const SERVICE_CONFIG_PATH = '/usr/src/app/config/config.json'

const PUBLIC_HEADERS_MAP = {}
Expand All @@ -24,4 +26,5 @@ export {
SERVICE_CONFIG_PATH,
PUBLIC_DIRECTORY_PATH,
PUBLIC_HEADERS_MAP,
LANGUAGES_DIRECTORY_PATH,
}
Loading

0 comments on commit f7198a2

Please sign in to comment.