This repository has been archived by the owner on Nov 8, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(text): add text serializer (#555)
- Loading branch information
1 parent
6197f8d
commit ec131f1
Showing
8 changed files
with
317 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ module.exports = { | |
'remote', | ||
'form', | ||
'json', | ||
'text', | ||
'deps', | ||
'deps-dev', | ||
]], | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Text Serializer Changelog | ||
|
||
## 0.1.0 | ||
|
||
Initial release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# API Elements: Text Serializer | ||
|
||
## Usage | ||
|
||
Takes an API Element data structure, and returns Text serialized data | ||
structures, for example: | ||
|
||
### Async | ||
|
||
```javascript | ||
const { Fury } = require('@apielements/core'); | ||
const textSerializer = require('@apielements/text-serializer'); | ||
|
||
const fury = new Fury(); | ||
fury.use(textSerializer); | ||
|
||
const api = new fury.minim.elements.String(); | ||
api.attributes.set('default', 'Doe'); | ||
|
||
const mediaType = 'text/plain'; | ||
fury.serialize({ api, mediaType }, (error, body) => { | ||
console.log(body); | ||
// "Doe" | ||
}); | ||
``` | ||
|
||
|
||
### Sync | ||
|
||
```javascript | ||
const { Fury } = require('@apielements/core'); | ||
const textSerializer = require('@apielements/text-serializer'); | ||
|
||
const fury = new Fury(); | ||
fury.use(textSerializer); | ||
|
||
const api = new fury.minim.elements.String('Doe'); | ||
const mediaType = 'text/plain'; | ||
try { | ||
const body = fury.serialize({ api, mediaType }); | ||
console.log(body); | ||
// Doe | ||
} catch (error) { | ||
console.log(error); | ||
// Only primitive elements can be serialized as text/plain | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
const serializeText = require('./serializeText'); | ||
|
||
const name = 'text'; | ||
const mediaTypes = [ | ||
'text/plain', | ||
]; | ||
|
||
function serialize({ api }) { | ||
return new Promise((resolve, reject) => { | ||
const done = (error, result) => { | ||
if (error) { | ||
reject(error); | ||
} else { | ||
resolve(result); | ||
} | ||
}; | ||
|
||
serializeText(api, done); | ||
}); | ||
} | ||
|
||
function serializeSync({ api }) { | ||
const done = (error, result) => { | ||
if (error) { | ||
throw error; | ||
} else { | ||
return result; | ||
} | ||
}; | ||
|
||
return serializeText(api, done); | ||
} | ||
|
||
module.exports = { | ||
name, mediaTypes, serialize, serializeSync, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
function collectElementByIDs(element) { | ||
const dataStructures = {}; | ||
const { parents } = element; | ||
|
||
if (!parents || parents.isEmpty) { | ||
return dataStructures; | ||
} | ||
|
||
const rootElement = parents.get(parents.length - 1); | ||
|
||
if (rootElement) { | ||
rootElement.recursiveChildren.forEach((element) => { | ||
// eslint-disable-next-line no-underscore-dangle | ||
const isNotEmptyStringElement = element._meta && element._meta.get('id'); | ||
|
||
if (isNotEmptyStringElement) { | ||
dataStructures[element.id.toValue()] = element; | ||
} | ||
}); | ||
} | ||
|
||
return dataStructures; | ||
} | ||
|
||
const isPrimitive = value => value !== undefined && (value !== Object(value)); | ||
|
||
function serializeText(element, done) { | ||
if (element.element === 'dataStructure') { | ||
return serializeText(element.content, done); | ||
} | ||
|
||
const dataStructures = collectElementByIDs(element); | ||
const value = element.valueOf(undefined, dataStructures); | ||
|
||
if (isPrimitive(value)) { | ||
return done(null, String(value)); | ||
} | ||
|
||
return done(new Error('Only primitive elements can be serialized as text/plain')); | ||
} | ||
|
||
module.exports = serializeText; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
"name": "@apielements/text-serializer", | ||
"version": "0.1.0", | ||
"description": "Text serializer for API Elements", | ||
"author": "Apiary.io <[email protected]>", | ||
"license": "MIT", | ||
"main": "./lib/adapter.js", | ||
"files": [ | ||
"lib/adapter.js", | ||
"lib/serializeText.js" | ||
], | ||
"homepage": "https://github.com/apiaryio/api-elements.js/tree/master/packages/text-serializer", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/apiaryio/api-elements.js.git", | ||
"directory": "packages/text-serializer" | ||
}, | ||
"scripts": { | ||
"lint": "eslint .", | ||
"lint:fix": "eslint . --fix", | ||
"test": "mocha test" | ||
}, | ||
"peerDependencies": { | ||
"@apielements/core": ">=0.1.0 <0.3.0" | ||
}, | ||
"devDependencies": { | ||
"@apielements/core": ">=0.1.0 <0.3.0", | ||
"chai": "^4.2.0", | ||
"eslint": "^5.16.0", | ||
"mocha": "^7.1.1" | ||
}, | ||
"engines": { | ||
"node": ">=8" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
const { expect } = require('chai'); | ||
const { Fury } = require('@apielements/core'); | ||
const adapter = require('../lib/adapter'); | ||
|
||
describe('Text Serializer Adapter', () => { | ||
let fury; | ||
|
||
before(() => { | ||
fury = new Fury(); | ||
fury.use(adapter); | ||
}); | ||
|
||
it('has a name', () => { | ||
expect(adapter.name).to.equal('text'); | ||
}); | ||
|
||
it('has a text/plain media type', () => { | ||
expect(adapter.mediaTypes).to.deep.equal(['text/plain']); | ||
}); | ||
|
||
describe('using serialize', () => { | ||
it('can serialize a primitive element', (done) => { | ||
const element = new fury.minim.elements.String('hello world'); | ||
|
||
fury.serialize({ api: element, mediaType: 'text/plain' }, (error, result) => { | ||
expect(error).to.be.null; | ||
expect(result).to.equal('hello world'); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('errors with a non-primitive element', (done) => { | ||
const element = new fury.minim.elements.Object({ message: 'Hello world' }); | ||
|
||
fury.serialize({ api: element, mediaType: 'text/plain' }, (error, result) => { | ||
expect(error.message).to.equal('Only primitive elements can be serialized as text/plain'); | ||
expect(result).to.be.undefined; | ||
done(); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('using serializeSync', () => { | ||
it('can serialize a primitive element', () => { | ||
const element = new fury.minim.elements.String('hello world'); | ||
const result = fury.serializeSync({ api: element, mediaType: 'text/plain' }); | ||
|
||
expect(result).to.equal('hello world'); | ||
}); | ||
|
||
it('errors with a non-primitive element', () => { | ||
const element = new fury.minim.elements.Object({ message: 'Hello world' }); | ||
|
||
expect(() => fury.serializeSync({ api: element, mediaType: 'text/plain' })) | ||
.to.throw('Only primitive elements can be serialized as text/plain'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
const { expect } = require('chai'); | ||
const { Fury } = require('@apielements/core'); | ||
const serializeText = require('../lib/serializeText'); | ||
|
||
const { minim: namespace } = new Fury(); | ||
|
||
const done = (error, result) => { | ||
if (error) { | ||
throw error; | ||
} else { | ||
return result; | ||
} | ||
}; | ||
|
||
describe('#serializeText', () => { | ||
it('can serialize a primitive element with value', () => { | ||
const stringElement = new namespace.elements.String('hello world'); | ||
const numberElement = new namespace.elements.Number(1); | ||
const booleanElement = new namespace.elements.Boolean(true); | ||
const nullElement = new namespace.elements.Null(); | ||
|
||
expect(serializeText(stringElement, done)).to.equal('hello world'); | ||
expect(serializeText(numberElement, done)).to.equal('1'); | ||
expect(serializeText(booleanElement, done)).to.equal('true'); | ||
expect(serializeText(nullElement, done)).to.equal('null'); | ||
}); | ||
|
||
it('can serialize an enum element with primitive values', () => { | ||
const enumElement = new namespace.elements.Enum(); | ||
enumElement.enumerations = ['north', 'east', 'south', 'west']; | ||
|
||
expect(serializeText(enumElement, done)).to.equal('north'); | ||
}); | ||
|
||
it('can serialize a primitive element with default value', () => { | ||
const element = new namespace.elements.String(); | ||
element.attributes.set('default', 'hello world'); | ||
|
||
expect(serializeText(element, done)).to.equal('hello world'); | ||
}); | ||
|
||
it('can serialize an element with references via parent tree', () => { | ||
const element = new namespace.elements.Element(); | ||
element.element = 'error'; | ||
|
||
const error = new namespace.elements.Element(); | ||
error.element = 'message'; | ||
error.id = 'error'; | ||
|
||
new namespace.elements.Category([ | ||
new namespace.elements.Category([ | ||
new namespace.elements.String('error message', { id: 'message' }), | ||
error, | ||
], { classes: ['dataStructures'] }), | ||
new namespace.elements.Category([ | ||
element, | ||
]), | ||
]).freeze(); | ||
|
||
expect(serializeText(element, done)).to.equal('error message'); | ||
}); | ||
|
||
it('can serialize a dataStructure element', () => { | ||
const element = new namespace.elements.DataStructure( | ||
new namespace.elements.String('hello world') | ||
); | ||
|
||
expect(serializeText(element, done)).to.equal('hello world'); | ||
}); | ||
|
||
it('can serialize from referenced element', () => { | ||
const element = new namespace.elements.Element(); | ||
element.element = 'ref'; | ||
element.content = 'message'; | ||
|
||
new namespace.elements.Category([ | ||
new namespace.elements.String('hello world', { id: 'message' }), | ||
element, | ||
]).freeze(); | ||
|
||
expect(serializeText(element, done)).to.equal('hello world'); | ||
}); | ||
|
||
it('errors with a non primitive element', () => { | ||
const objectElement = new namespace.elements.Object({ message: 'Hello world' }); | ||
const arrayElement = new namespace.elements.Array(['Hello', 'Doe']); | ||
const emptyEnumElement = new namespace.elements.Enum(); | ||
|
||
expect(() => serializeText(objectElement, done)).to.throw('Only primitive elements can be serialized as text/plain'); | ||
expect(() => serializeText(arrayElement, done)).to.throw('Only primitive elements can be serialized as text/plain'); | ||
expect(() => serializeText(emptyEnumElement, done)).to.throw('Only primitive elements can be serialized as text/plain'); | ||
}); | ||
}); |