Comparing version 0.4.3 to 0.5.0
@@ -16,3 +16,3 @@ /** | ||
normal: {}, | ||
lenient: {} | ||
jsdoc: {} | ||
}; | ||
@@ -28,4 +28,4 @@ | ||
return null; | ||
} else if (options.lenient === true) { | ||
return typeExpressionCache.lenient; | ||
} else if (options.jsdoc === true) { | ||
return typeExpressionCache.jsdoc; | ||
} else { | ||
@@ -37,3 +37,3 @@ return typeExpressionCache.normal; | ||
function getParsedTypeCache(options) { | ||
if (options.useCache === false) { | ||
if (options.useCache === false || options.links !== null || options.links !== undefined) { | ||
return null; | ||
@@ -47,4 +47,10 @@ } else if (options.htmlSafe === true) { | ||
// can't return the original if any of the following are true: | ||
// 1. restringification was requested | ||
// 2. htmlSafe option was requested | ||
// 3. links option was provided | ||
// 4. typeExpression property is missing | ||
function canReturnOriginalExpression(parsedType, options) { | ||
return options.restringify !== true && options.htmlSafe !== true && | ||
(options.links === null || options.links === undefined) && | ||
Object.prototype.hasOwnProperty.call(parsedType, 'typeExpression'); | ||
@@ -66,4 +72,4 @@ } | ||
}, | ||
lenient: { | ||
value: options.lenient === true ? true : false | ||
jsdoc: { | ||
value: options.jsdoc === true ? true : false | ||
} | ||
@@ -70,0 +76,0 @@ }); |
@@ -5,3 +5,5 @@ 'use strict'; | ||
function Stringifier() { | ||
function Stringifier(options) { | ||
this._options = options || {}; | ||
// in a list of function signature params, repeatable params are stringified differently | ||
@@ -11,3 +13,3 @@ this._inFunctionSignatureParams = false; | ||
Stringifier.prototype.applications = function(applications, options) { | ||
Stringifier.prototype.applications = function(applications) { | ||
if (!applications) { | ||
@@ -24,3 +26,3 @@ return ''; | ||
if (options.htmlSafe) { | ||
if (this._options.htmlSafe) { | ||
result = '.<'; | ||
@@ -115,7 +117,6 @@ } else { | ||
Stringifier.prototype.type = function(type, options) { | ||
Stringifier.prototype.type = function(type) { | ||
if (!type) { | ||
return ''; | ||
} | ||
options = options || {}; | ||
@@ -141,3 +142,3 @@ // nullable comes first | ||
result += this.type(type.expression); | ||
result += this.applications(type.applications, options); | ||
result += this.applications(type.applications); | ||
break; | ||
@@ -210,3 +211,14 @@ case Types.UndefinedLiteral: | ||
var typeString = type.type ? this.type(type.type) : ''; | ||
var cssClass; | ||
var openTag; | ||
// replace the type with an HTML link if necessary | ||
if (this._options.links && Object.prototype.hasOwnProperty.call(this._options.links, | ||
nameString)) { | ||
cssClass = this._options.cssClass ? ' class="' + this._options.cssClass + '"' : ''; | ||
openTag = '<a href="' + this._options.links[nameString] + '"' + cssClass + '>'; | ||
nameString = openTag + nameString + '</a>'; | ||
} | ||
if (type.repeatable === true) { | ||
@@ -250,3 +262,3 @@ return this._formatRepeatable(nameString, typeString); | ||
module.exports = function(type, options) { | ||
return new Stringifier().stringify(type, options); | ||
return new Stringifier(options).stringify(type); | ||
}; |
{ | ||
"version": "0.4.3", | ||
"version": "0.5.0", | ||
"name": "catharsis", | ||
"description": "A JavaScript parser for Google Closure Compiler type expressions.", | ||
"description": "A JavaScript parser for Google Closure Compiler and JSDoc type expressions.", | ||
"author": "Jeff Williams <jeffrey.l.williams@gmail.com>", | ||
@@ -16,2 +16,3 @@ "repository": { | ||
"should": "1.2.2", | ||
"uglify-js": "2.2.5", | ||
"underscore": "1.4.4" | ||
@@ -23,3 +24,4 @@ }, | ||
"scripts": { | ||
"prepublish": "pegjs ./lib/parser.pegjs", | ||
"build": "pegjs ./lib/parser.pegjs", | ||
"prepublish": "pegjs ./lib/parser.pegjs; uglifyjs ./lib/parser.js -o ./lib/parser.js", | ||
"test": "mocha" | ||
@@ -26,0 +28,0 @@ }, |
# Catharsis # | ||
A JavaScript parser for Google Closure Compiler | ||
[type expressions](https://developers.google.com/closure/compiler/docs/js-for-compiler#types). | ||
A JavaScript parser for | ||
[Google Closure Compiler](https://developers.google.com/closure/compiler/docs/js-for-compiler#types) | ||
and [JSDoc](https://github.com/jsdoc3/jsdoc) type expressions. | ||
@@ -12,5 +13,4 @@ Catharsis is designed to be: | ||
+ **Fast**. Parse results are cached, so the parser is invoked only when necessary. | ||
+ **Flexible**. Catharsis can convert parse results back into type expressions. In addition, it | ||
provides a lenient mode that also accepts [JSDoc](https://github.com/jsdoc3/jsdoc)-style type | ||
expressions. | ||
+ **Flexible**. Catharsis can convert parse results back into type expressions. In addition, it can | ||
parse [JSDoc](https://github.com/jsdoc3/jsdoc)-style type expressions. | ||
@@ -24,22 +24,22 @@ | ||
var jsdocType; | ||
var parsedType; | ||
var parsedType; | ||
var parsedJsdocType; | ||
// normal parsing | ||
try { | ||
// Google Closure Compiler parsing | ||
try { | ||
type = '!Object'; | ||
parsedType = catharsis.parse(type); | ||
console.log('%j', parsedType); // {"type":"NameExpression,"name":"Object","nullable":false} | ||
} | ||
catch(e) { | ||
console.error('unable to parse %s: %s', type, e); | ||
} | ||
parsedType = catharsis.parse(type); | ||
console.log('%j', parsedType); // {"type":"NameExpression,"name":"Object","nullable":false} | ||
} | ||
catch(e) { | ||
console.error('unable to parse %s: %s', type, e); | ||
} | ||
// lenient parsing | ||
// JSDoc-style type expressions enabled | ||
try { | ||
jsdocType = 'number|string'; // should be (number|string) | ||
parsedJsdocType = catharsis.parse(jsdocType, {lenient: true}); | ||
jsdocType = 'number|string'; // Closure Compiler expects (number|string) | ||
parsedJsdocType = catharsis.parse(jsdocType, {jsdoc: true}); | ||
} | ||
catch (e) { | ||
console.error('you will not see this error, thanks to lenient mode!'); | ||
console.error('unable to parse %s: %s', jsdocType, e); | ||
} | ||
@@ -58,9 +58,9 @@ | ||
### parse(type, options) ### | ||
Parse the Closure Compiler type `type`, and return the parse results. Throws an error if the type | ||
cannot be parsed. | ||
### parse(typeExpression, options) ### | ||
Parse `typeExpression`, and return the parse results. Throws an error if the type expression cannot | ||
be parsed. | ||
When called without options, Catharsis attempts to parse type expressions in the same way as | ||
Closure Compiler. When the `lenient` option is enabled, Catharsis can also parse several kinds of | ||
type expressions that are used in [JSDoc](https://github.com/jsdoc3/jsdoc): | ||
Closure Compiler. When the `jsdoc` option is enabled, Catharsis can also parse several kinds of | ||
type expressions that are permitted in [JSDoc](https://github.com/jsdoc3/jsdoc): | ||
@@ -81,3 +81,4 @@ + The string `function` is treated as a function type with no parameters. | ||
+ `options`: Options for parsing the type expression. | ||
+ `options.lenient`: Specifies whether to enable lenient mode. Defaults to `false`. | ||
+ `options.jsdoc`: Specifies whether to enable parsing of JSDoc-style type expressions. Defaults | ||
to `false`. | ||
+ `options.useCache`: Specifies whether to use the cache of parsed types. Defaults to `true`. | ||
@@ -91,8 +92,8 @@ | ||
+ `lenient`: A boolean indicating whether the type expression was parsed in lenient mode. | ||
+ `jsdoc`: A boolean indicating whether the type expression was parsed with JSDoc support enabled. | ||
+ `typeExpression`: A string containing the type expression that was parsed. | ||
### stringify(parsedType, options) ### | ||
Stringify the parsed Closure Compiler type expression `parsedType`, and return the type expression. | ||
If validation is enabled, throws an error if the stringified type expression cannot be parsed. | ||
Stringify `parsedType`, and return the type expression. If validation is enabled, throws an error if | ||
the stringified type expression cannot be parsed. | ||
@@ -102,12 +103,20 @@ #### Parameters #### | ||
+ `options`: Options for stringifying the parse results. | ||
+ `options.cssClass`: A CSS class to add to HTML links. Used only if `options.links` is | ||
provided. By default, no CSS class is added. | ||
+ `options.htmlSafe`: Specifies whether to return an HTML-safe string that replaces left angle | ||
brackets (`<`) with the corresponding entity (`<`). **Note**: Characters in name expressions | ||
are not escaped. | ||
+ `options.links`: An object whose keys are name expressions and whose values are URIs. If a | ||
name expression matches a key in `options.links`, the name expression will be wrapped in an | ||
HTML <a> tag that links to the URI. If `options.cssClass` is specified, the <a> tag will include | ||
a `class` attribute. **Note**: When using this option, parsed types are always restringified, | ||
and the resulting string is not cached. | ||
+ `options.restringify`: Forces Catharsis to restringify the parsed type. If this option is not | ||
specified, and the parsed type object includes a `typeExpression` property, Catharsis will | ||
return the `typeExpression` property without modification. Defaults to `false`. | ||
return the `typeExpression` property without modification when possible. Defaults to `false`. | ||
+ `options.useCache`: Specifies whether to use the cache of stringified parse results. Defaults | ||
to `true`. | ||
+ `options.validate`: Specifies whether to validate the stringified parse results by attempting | ||
to parse them as a type expression. Defaults to `false`. | ||
to parse them as a type expression. If the stringified results are not parsable by default, you | ||
must also provide the appropriate options to pass to the `parse()` method. Defaults to `false`. | ||
@@ -143,2 +152,7 @@ #### Returns #### | ||
+ 0.5.0 (March 2013): | ||
+ The `parse()` method's `lenient` option has been renamed to `jsdoc`. **Note**: This change is | ||
not backwards-compatible with previous versions. | ||
+ The `stringify()` method now accepts `cssClass` and `links` options, which you can use to | ||
add HTML links to a type expression. | ||
+ 0.4.3 (March 2013): | ||
@@ -145,0 +159,0 @@ + The `stringify()` method no longer caches HTML-safe type expressions as if they were normal |
@@ -37,3 +37,3 @@ /*global describe: true, it: true, xit: true */ | ||
it('should return an object with nonenumerable "typeExpression" and "lenient" properties', | ||
it('should return an object with nonenumerable "typeExpression" and "jsdoc" properties', | ||
function() { | ||
@@ -47,3 +47,3 @@ var parsedType = catharsis.parse('foo'); | ||
descriptor = Object.getOwnPropertyDescriptor(parsedType, 'lenient'); | ||
descriptor = Object.getOwnPropertyDescriptor(parsedType, 'jsdoc'); | ||
descriptor.enumerable.should.equal(false); | ||
@@ -62,10 +62,10 @@ descriptor.value.should.equal(false); | ||
it('should pass the specified options to the parser', function() { | ||
function lenient() { | ||
catharsis.parse('number|string', {lenient: true}); | ||
function jsdoc() { | ||
catharsis.parse('number|string', {jsdoc: true}); | ||
} | ||
lenient.should.not.throw(); | ||
jsdoc.should.not.throw(); | ||
}); | ||
it('should use the regular cache when lenient mode is disabled', function() { | ||
it('should use the regular cache when JSDoc mode is disabled', function() { | ||
// parse twice to make sure we're getting a cached version | ||
@@ -75,11 +75,11 @@ var bar = catharsis.parse('bar'); | ||
bar.lenient.should.equal(false); | ||
bar.jsdoc.should.equal(false); | ||
}); | ||
it('should use the lenient cache when lenient mode is enabled', function() { | ||
it('should use the JSDoc cache when JSDoc mode is enabled', function() { | ||
// parse twice to make sure we're getting a cached version | ||
var baz = catharsis.parse('baz', {lenient: true}); | ||
baz = catharsis.parse('baz', {lenient: true}); | ||
var baz = catharsis.parse('baz', {jsdoc: true}); | ||
baz = catharsis.parse('baz', {jsdoc: true}); | ||
baz.lenient.should.equal(true); | ||
baz.jsdoc.should.equal(true); | ||
}); | ||
@@ -164,2 +164,16 @@ }); | ||
it('should not return the typeExpression property if the links option is provided', | ||
function() { | ||
var typeAppString = catharsis.stringify({ | ||
type: Types.NameExpression, | ||
name: 'string', | ||
typeExpression: 'fake type expression' | ||
}, | ||
{ | ||
links: {} | ||
}); | ||
typeAppString.should.equal('string'); | ||
}); | ||
// used for multiple tests | ||
@@ -166,0 +180,0 @@ var typeApp = { |
@@ -47,3 +47,3 @@ /*global describe: true, it: true */ | ||
var specs = './test/specs'; | ||
var lenientSpecs = path.join(specs, 'lenient'); | ||
var jsdocSpecs = path.join(specs, 'jsdoc'); | ||
@@ -56,5 +56,6 @@ function tester(specPath, basename) { | ||
function lenientTester(specPath, basename) { | ||
it('can parse types in the "' + basename + '" spec when in lenient mode', function() { | ||
checkTypes(path.join(specPath, basename), {lenient: true}); | ||
function jsdocTester(specPath, basename) { | ||
it('can parse types in the "' + basename + '" spec when JSDoc type parsing is enabled', | ||
function() { | ||
checkTypes(path.join(specPath, basename), {jsdoc: true}); | ||
}); | ||
@@ -64,4 +65,4 @@ } | ||
helper.testSpecs(specs, tester); | ||
helper.testSpecs(lenientSpecs, lenientTester); | ||
helper.testSpecs(jsdocSpecs, jsdocTester); | ||
}); | ||
}); |
@@ -48,5 +48,12 @@ /*global describe: true, it: true */ | ||
var specs = './test/specs'; | ||
var htmlSpecs = './test/specs/html'; | ||
var lenientSpecs = './test/specs/lenient'; | ||
var htmlSpecs = path.join(specs, 'html'); | ||
var jsdocSpecs = path.join(specs, 'jsdoc'); | ||
var linkSpecs = path.join(specs, 'link'); | ||
var linkCssSpecs = path.join(specs, 'linkcss'); | ||
var links = { | ||
Foo: 'Foo.html', | ||
'module:foo/bar/baz~Qux': 'foobarbazqux.html' | ||
}; | ||
function tester(specPath, basename, options) { | ||
@@ -59,4 +66,17 @@ it('can stringify types in the "' + basename + '" spec', function() { | ||
helper.testSpecs(specs, tester, {}); | ||
helper.testSpecs(lenientSpecs, tester, {lenient: true}); | ||
helper.testSpecs(jsdocSpecs, tester, {jsdoc: true}); | ||
helper.testSpecs(htmlSpecs, tester, {htmlSafe: true, validate: false}); | ||
helper.testSpecs(linkSpecs, tester, { | ||
htmlSafe: true, | ||
jsdoc: true, | ||
links: links, | ||
validate: false | ||
}); | ||
helper.testSpecs(linkCssSpecs, tester, { | ||
cssClass: 'my-class', | ||
htmlSafe: true, | ||
jsdoc: true, | ||
links: links, | ||
validate: false | ||
}); | ||
}); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
26
209
272157
5
2641
3
1