Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: changed all options except schema to be optional #10

Merged
merged 2 commits into from
Oct 13, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
34 changes: 6 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,22 @@ This package allows you to configure various options for loading and managing co

### `configName`
- **Type**: `string`
- **Optional**: `false`
- **Optional**: `true`
-
- **Description**: The name of the remote configuration.
- **Environment Variable**: `CONFIG_NAME`

### `version`
- **Type**: `'latest' | number`
- **Optional**: `false`
- **Optional**: `true`
- **Default**: `latest`
- **Description**: The version of the remote configuration. It can be either `'latest'` or a number.
- **Environment Variable**: `CONFIG_VERSION`

### `configServerUrl`
- **Type**: `string`
- **Optional**: `false`
- **Optional**: `true`
- **Default**: `http://localhost:8080`
- **Description**: The URL of the configuration server.
- **Environment Variable**: `CONFIG_SERVER_URL`

Expand All @@ -111,31 +114,6 @@ This package allows you to configure various options for loading and managing co
- **Default**: `./config`
- **Description**: The path to the local configuration folder.

## JSON Schema

The options are validated against the following JSON schema:

```json
{
  "required": ["configName", "configServerUrl", "version"],
  "additionalProperties": false,
  "type": "object",
  "properties": {
    "configName": { "type": "string" },
    "version": {
      "oneOf": [
        { "type": "string", "const": "latest" },
        { "type": "integer", "minimum": 1 }
      ]
    },
    "configServerUrl": { "type": "string" },
    "offlineMode": { "type": "boolean", "nullable": true },
    "ignoreServerIsOlderVersionError": { "type": "boolean", "nullable": true },
    "localConfigPath": { "type": "string", "default": "./config" }
  }
}
```

## Environment Variable Configuration

The following environment variables can be used to configure the options:
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { readPackageJsonSync } from '@map-colonies/read-pkg';

const schemasPackagePathBuildPath = require.resolve('@map-colonies/schemas').substring(0, require.resolve('@map-colonies/schemas').indexOf('build'));
export const LOCAL_SCHEMAS_PACKAGE_VERSION = readPackageJsonSync(path.join(schemasPackagePathBuildPath, 'package.json')).version as string;
export const PACKAGE_NAME = readPackageJsonSync('package.json').name ?? 'package-name-not-defined';

export const SCHEMA_DOMAIN = 'https://mapcolonies.com/';

Expand Down
12 changes: 9 additions & 3 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@ import { BaseOptions, optionsSchema } from './types';
import { ajvOptionsValidator, validate } from './validator';
import { createDebug } from './utils/debug';
import { createConfigError } from './errors';
import { PACKAGE_NAME } from './constants';

const debug = createDebug('options');

const defaultOptions: BaseOptions = {
configName: PACKAGE_NAME,
configServerUrl: 'http://localhost:8080',
version: 'latest',
};

const envOptions: Partial<Record<keyof BaseOptions, string>> = {
configName: process.env.CONFIG_NAME,
configServerUrl: process.env.CONFIG_SERVER_URL,
Expand All @@ -24,9 +31,8 @@ for (const key in envOptions) {
let baseOptions: BaseOptions | undefined = undefined;

export function initializeOptions(options: Partial<BaseOptions>): BaseOptions {
debug('initializing options with %j and env %j', options, envOptions);
const mergedOptions = deepmerge(options, envOptions);

debug('initializing options with default options: %j function input: %j and environment variables: %j', defaultOptions, options, envOptions);
const mergedOptions = deepmerge.all([defaultOptions, options, envOptions]);
debug('merged options: %j', mergedOptions);

const [errors, validatedOptions] = validate(ajvOptionsValidator, optionsSchema, mergedOptions);
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export interface BaseOptions {
* Represents the options for configuration.
*/
export type ConfigOptions<T extends SchemaWithType> = Prettify<
BaseOptions & {
Partial<BaseOptions> & {
/**
* The schema of the configuration object.
*/
Expand Down
7 changes: 4 additions & 3 deletions tests/config.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Interceptable, MockAgent, setGlobalDispatcher } from 'undici';
import { commonDbPartialV1, commonS3PartialV2 } from '@map-colonies/schemas';
import { commonDbPartialV1, commonS3PartialV1 } from '@map-colonies/schemas';
import { StatusCodes } from 'http-status-codes';
import { config } from '../src/config';

Expand Down Expand Up @@ -138,13 +138,14 @@ describe('config', () => {
jest.resetModules();
process.env.S3_ACCESS_KEY = 'access';
process.env.S3_SECRET_KEY = 'secret';
process.env.S3_ENDPOINT = 'http://localhost:9000';

// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
const { config } = require('../src/config') as typeof import('../src/config');
const configInstance = await config({
configName: 'name',
version: 1,
schema: commonS3PartialV2,
schema: commonS3PartialV1,
configServerUrl: URL,
localConfigPath: './tests/config',
offlineMode: true,
Expand Down Expand Up @@ -236,7 +237,7 @@ describe('config', () => {
const promise = config({
configName: 'name',
version: 1,
schema: commonS3PartialV2,
schema: commonS3PartialV1,
configServerUrl: URL,
localConfigPath: './tests/config',
});
Expand Down
3 changes: 1 addition & 2 deletions tests/options.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,12 @@ describe('options', () => {
});

it('should throw an error if options are invalid', () => {
process.env.CONFIG_VERSION = 'latest';
process.env.CONFIG_SERVER_URL = 'http://localhost:8080';

const { initializeOptions } = require('../src/options');

expect(() => {
initializeOptions({});
initializeOptions({ version: 'avi' });
}).toThrow();
});

Expand Down
2 changes: 1 addition & 1 deletion tests/schemas.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('schemas', () => {

const dereferencedSchema = await loadSchema(schema);

expect(dereferencedSchema).toHaveProperty('allOf[0].$id', 'https://mapcolonies.com/common/db/partial/v1');
expect(dereferencedSchema).toHaveProperty('allOf[0].title', 'commonDbPartialV1');
});

it('should throw an error if the schema is not found', async () => {
Expand Down
Loading