Commit a6b1aeb2 authored by Mark Stenglein's avatar Mark Stenglein

A bunch of work...CI will still fail here

- I put a lot more work here into the API
  - Now uses a bit better organization where the base param class
  is only going to enforce string contents. Implementations of
  specific kinds of parameters need to add their own datatypes and
  be sure to update the string value whenever the set method is
  called for their class. The parent class will take care of ensuring
  that anything written to this value (which is used directly in the
  generate step) is valid. Any higher level validations can then be
  taken care of by the higher level implementations, which shouldn't
  need to worry about the lower level validations.

- All of these new things really need test cases written for them
so that we can be sure that it works. It's going to get hairy looking
for bugs on the higher level classes if this doesn't have a solid test
foundation.
parent c49f577c
import { isIamaToken, isAlpha } from "./util";
import { ICalElement } from "./ICalElement";
import Parameter from "./Parameter";
const CRLF: string = "/r/n"
const CRLF: string = "/r/n";
/**
* Implementation of a Content Line from RFC 5545
......@@ -15,9 +16,9 @@ const CRLF: string = "/r/n"
* @author Mark Stenglein <mark@stengle.in>
* @since 0.1.0
*/
export default class ContentLine {
export default class ContentLine implements ICalElement {
private _name: string;
private _params: Parameter[] = [];
private _params: Parameter[];
private _value: string;
constructor(inName: string, inParams: Parameter[], inValue: string) {
......
/**
* Generic ICalElement interface which requires a generate command
*
* @author Mark Stenglein <mark@stengle.in>
* @since 0.1.0
*/
export interface ICalElement {
generate(): string;
}
import { isAlpha, isIamaToken, isXName } from "./util";
import { ParameterValue } from "./ParameterValue";
import { ICalElement } from "./ICalElement";
/**
* Implementation of a Content Line Parameter from RFC 5545
......@@ -8,41 +8,54 @@ import { ParameterValue } from "./ParameterValue";
* will utilize an abstract Class which is meant to be extended by specific
* types of parameters.
*
* param = param-name "=" param-value *("," param-value)
* ; Each property defines the specific ABNF for the parameters
* ; allowed on the property. Refer to specific properties for
* ; precise parameter ABNF.
*
* @author Mark Stenglein <mark@stengle.in>
*/
export default class Parameter {
export default class Parameter implements ICalElement {
private _paramName: string;
private _paramValues: string[] | Date[];
private _paramValues: string[];
/**
* Constructor builds the Parameter from the parameter name and an array of
* values.
*
*
* For more specific implementations that use non-string datatypes, look at
* extended implementations of this class.
*
* @author Mark Stenglein
* @since 0.1.0
* @param inName string The name of the new Parameter in iama-token / x-name
* @param inValues string[] | Date[] array of values
* @param inValues string[] array of string values
*/
constructor(inName: string, inValues: string[] | Date[]) {
constructor(inName: string, inValues: string[]) {
this.paramName = inName;
this.paramValues = inValues
this.paramValues = inValues;
}
/** Get Methods */
get paramName() {
return this._paramName;
}
get paramValues() {
return this.paramValues;
}
/** Set Methods */
/**
* Validates input param names and saves them to the object.
*
* param-name = iana-token / x-name
*
* @author Mark Stenglein <mark@stengle.in>
* @since 0.1.0
* @param newName The new name to be tested and saved.
......@@ -54,7 +67,7 @@ export default class Parameter {
* Note that the X-Name also passes these rules, the X-Name can be
* defined separately.
*/
if (isIamaToken(newName)) {
if (isIamaToken(newName) || isXName(newName)) {
this._paramName = newName;
}
else {
......@@ -62,17 +75,32 @@ export default class Parameter {
}
}
/**
* Validates input param values and saves them to the object.
*
*
* param-value = paramtext / quoted-string
*
* @author
* @since 0.1.0
* @param newValues The input values to be tested and saved.
*/
set paramValues(newValues: string[] | Date[]) {
set paramValues(newValues: string[]) {
newValues.forEach(newValue => {
if (
!(Parameter.isParamText(newValue)) ||
!(Parameter.isQuotedString(newValue))
) {
throw new TypeError(
"param-value must either be valid paramtext or" +
"quoted-string"
);
}
})
this._paramValues = newValues;
}
/**
* Generates the proper string representation for a Parameter as defined by
* RFC 5545:
......@@ -85,7 +113,6 @@ export default class Parameter {
*/
public generate(): string {
let outputString = this.paramName;
/**
* Goes through each parameter value and adds it, being sure to place
* the comma for the 2nd parameter onwards.
......@@ -99,4 +126,81 @@ export default class Parameter {
return outputString;
}
/**
* Tests to make sure input is compliant with the definition of `param-text`
*
* paramtext = *SAFE-CHAR
*
* @author Mark Stenglein
* @since 0.1.0
* @param testString string to be tested
* @returns boolean If the input is valid param-test
*/
public static isParamText(testString: string): boolean {
return Parameter.isSafeChar(testString);
}
/**
* Tests to make sure the input is compliant with the definition of
* `SAFE-CHAR`
*
* SAFE-CHAR = WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E / NON-US-ASCII
* ; Any character except CONTROL, DQUOTE, ";", ":", ","
*
* @author Mark Stenglein
* @since 0.1.0
* @param testString string to be tested
* @returns boolean If the input is valid SAFE-CHAR
*
* TODO: verify this regex
*/
public static isSafeChar(testString: string): boolean {
return /[\s\x21\x23-\x2b\x2d-\x39\x3c-\x7e\x80-\xff]/.test(testString);
}
/**
* Tests to make sure the input is compliant with the definition of
* `quoted-string`
*
* quoted-string = DQUOTE *QSAFE-CHAR DQUOTE
*
* @author Mark Stenglein
* @since 0.1.0
* @param testString string to be tested
* @returns boolean If the input is a valid `quoted-string`
*/
public static isQuotedString(test: string): boolean {
let result = false;
if (
test.charAt(0) === "\"" &&
test.charAt(test.length - 1) === "\"" &&
Parameter.isQSafeChar(test.substring(1, test.length - 1))
) {
result = true;
}
return result;
}
/**
* Tests to make sure the input is compliant with the definition of
* `QSAFE-CHAR`
*
* QSAFE-CHAR = WSP / %x21 / %x23-7E / NON-US-ASCII
* ; Any character except CONTROL and DQUOTE
*
* @author Mark Stenglein
* @since 0.1.0
* @param test string to be tested
* @returns boolean If the input is a valid `QSAFE-CHAR` string
*
* TODO: verify this regex
*/
public static isQSafeChar(test: string): boolean {
return /[\s\x21\x23-\x7e\x80-\xff]/.test(test);
}
}
export interface ParameterValue {
toString(): string;
}
\ No newline at end of file
......@@ -53,4 +53,4 @@ export function isIamaToken(input: string): boolean {
*/
export function isXName(input: string): boolean {
return true;
}
\ No newline at end of file
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment