Skip to content

Commit

Permalink
Merge pull request #13 from mfellner/bugfixes
Browse files Browse the repository at this point in the history
Fix misc. bugs
  • Loading branch information
mfellner authored Mar 1, 2018
2 parents cfac622 + 1b0010c commit 669d89c
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 16 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ TypeConf supports different storage backends for configuration values:

#### Browser only:

* **withDOMNode(id: string)** DOM element with encoded `value` attribute
* **withDOMNode(id: string, attribute?: string)** DOM element with encoded `content` attribute

Backends are queried for existing values in the reverse order that they were added. For example:

Expand Down Expand Up @@ -124,12 +124,12 @@ conf.getObject('object') === { a: 'a', b: { bb: 'bb' } };

**Node.js only.** Use a configuration file as a source. JSON and YAML (requires [js-yaml](https://www.npmjs.com/package/js-yaml)) are supported.

### withDOMNode(id: string): TypeConf
### withDOMNode(id: string, attribute?: string): TypeConf

**Browser only.** Use a DOM element with a `value` attribute as a source. The value must be a Base64-encoded JSON string. For example:
**Browser only.** Use a DOM element as a source. The configuration must be a Base64-encoded JSON string in an attribute of the element (default: `content`). For example:

```html
<meta id="conf" value="eyJhIjoiYiJ9" />
<meta id="conf" content="eyJhIjoiYiJ9" />
```

### set(key: string, value: any): TypeConf
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "typeconf",
"version": "0.6.1",
"description": "A typesafe hierarchical configuration manager for Node.js and the browser.",
"browser": "dist/TypeConf.js",
"browser": "dist/TypeConfBrowser.js",
"main": "dist/TypeConfNode.js",
"types": "./dist/TypeConfNode.d.ts",
"repository": "https://github.com/mfellner/typeconf",
Expand Down
5 changes: 3 additions & 2 deletions src/TypeConf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,11 @@ export interface TypeConf {
*
* Browser only.
*
* @param id ID attribute of the DOM element.
* @param id ID attribute value of the DOM element.
* @param attribute Content attribute name of the DOM element (default: 'content').
* @return This TypeConf instance.
*/
withDOMNode(id: string): TypeConf;
withDOMNode(id: string, attribute?: string): TypeConf;

/**
* Set an override value.
Expand Down
8 changes: 4 additions & 4 deletions src/TypeConfBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ import TypeConfBase from './TypeConfBase';
import { createStore, ObjectSupplier } from './util';

export default class TypeConfBrowser extends TypeConfBase {
public withDOMNode(id: string): TypeConf {
public withDOMNode(id: string, attribute: string = 'content'): TypeConf {
const element = document.getElementById(id);
if (!element || !element.hasAttribute('value')) {
if (!element || !element.hasAttribute(attribute)) {
return this;
}
const encodedString = element.getAttribute('value');
const encodedString = element.getAttribute(attribute);
if (!encodedString) {
return this;
}
let storage: { [key: string]: any };
try {
storage = JSON.parse(atob(encodedString));
} catch (e) {
throw new StoreError(`cannot read value of DOM node ${id}`, e);
throw new StoreError(`cannot read attribute ${attribute} of DOM node ${id}`, e);
}
const store = createStore(new ObjectSupplier(storage));
this.addStore(store, `__DOM_${id}__`);
Expand Down
7 changes: 5 additions & 2 deletions src/TypeConfNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,11 @@ export default class TypeConfNode extends TypeConfBase {
get(name: string) {
const envName = getEnvName(name);
const result = process.env[envName];
if (result !== undefined) return result;
return aggregateContainerValues(process.env, envName, separator, camelCase);
if (typeof result !== 'undefined') return result;
const aggregate = aggregateContainerValues(process.env, envName, separator, camelCase);
if (Object.keys(aggregate).length > 0) {
return aggregate;
}
},
aggregate() {
// We can only find relevant environment variables if a prefix is specified.
Expand Down
6 changes: 3 additions & 3 deletions test/TypeConfBrowser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('TypeConfBrowser', () => {
const storage = { number: 42 };
const element = document.createElement('meta');
element.setAttribute('id', 'typeconf');
element.setAttribute('value', btoa(JSON.stringify(storage)));
element.setAttribute('content', btoa(JSON.stringify(storage)));
document.head.appendChild(element);

const conf = new TypeConfBrowser().withDOMNode('typeconf');
Expand All @@ -31,7 +31,7 @@ describe('TypeConfBrowser', () => {
test('TypeConfBrowser.getString with DOM node with empty value attribute', () => {
const element = document.createElement('meta');
element.setAttribute('id', 'typeconf');
element.setAttribute('value', '');
element.setAttribute('content', '');
document.head.appendChild(element);

expect(new TypeConfBrowser().withDOMNode('typeconf')).toBeInstanceOf(TypeConfBrowser);
Expand All @@ -40,7 +40,7 @@ describe('TypeConfBrowser', () => {
test('TypeConfBrowser.getString with DOM node should throw', () => {
const element = document.createElement('meta');
element.setAttribute('id', 'typeconf');
element.setAttribute('value', 'invalid');
element.setAttribute('content', 'invalid');
document.head.appendChild(element);

expect(() => new TypeConfBrowser().withDOMNode('typeconf')).toThrowError(StoreError);
Expand Down
5 changes: 5 additions & 0 deletions test/TypeConfNode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ describe('TypeConfNode', () => {
expect(conf.getBoolean('object')).toEqual(true);
});

test('conf.get with empty env', () => {
const conf = new TypeConfNode().withEnv();
expect(conf.get('test')).toBeUndefined();
});

test('conf.getObject withFile and YAML file', () => {
const conf = new TypeConfNode().withFile(path.resolve(__dirname, 'conf.yaml'));
expect(conf.getObject('object')).toEqual({ string: 'string' });
Expand Down

0 comments on commit 669d89c

Please sign in to comment.