Skip to content

Commit

Permalink
feat(primitives): upgrade primitives to io-ts ^2.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
tangdrew committed Oct 24, 2019
1 parent 500652a commit 5d2bde4
Show file tree
Hide file tree
Showing 42 changed files with 354 additions and 414 deletions.
24 changes: 11 additions & 13 deletions packages/primitives/src/R4/base64Binary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,21 @@
* Base64Binary FHIR Primitive Runtime Type
*/

import { Type, success, failure, identity } from "io-ts";
import { Type, success, failure, identity, TypeOf } from "io-ts";

const BASE64_BINARY_REGEX = /(\s*([0-9a-zA-Z\+\=]){4}\s*)+/;

export class Base64BinaryType extends Type<string> {
readonly _tag: "Base64BinaryType" = "Base64BinaryType";
constructor() {
super(
"base64Binary",
(m): m is string => typeof m === "string" && BASE64_BINARY_REGEX.test(m),
(m, c) => (this.is(m) ? success(m) : failure(m, c)),
identity
);
}
}
const isBase64Binary = (m: unknown): m is string =>
typeof m === "string" && BASE64_BINARY_REGEX.test(m);

/**
* A stream of bytes, base64 encoded.
*/
export const base64Binary = new Base64BinaryType();
export const base64Binary = new Type<string>(
"base64Binary",
isBase64Binary,
(m, c) => (isBase64Binary(m) ? success(m) : failure(m, c)),
identity
);

export type base64Binary = TypeOf<typeof base64Binary>;
14 changes: 12 additions & 2 deletions packages/primitives/src/R4/boolean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
* Boolean FHIR Primitive Runtime Type
*/

import { BooleanType, boolean } from "io-ts";
import { Type, success, failure, identity } from "io-ts";

export { BooleanType, boolean };
const isBoolean = (m: unknown): m is boolean => typeof m === "boolean";

/**
* true | false
*/
export const boolean = new Type<boolean>(
"boolean",
isBoolean,
(m, c) => (isBoolean(m) ? success(m) : failure(m, c)),
identity
);
27 changes: 13 additions & 14 deletions packages/primitives/src/R4/canonical.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,21 @@
* Canonical URL FHIR Primitive Runtime Type
*/

import { uri } from "./uri";
import { Type, success, failure, identity } from "io-ts";
import { Type, success, failure, identity, TypeOf } from "io-ts";

export class CanonicalType extends Type<string> {
readonly _tag: "CanonicalType" = "CanonicalType";
constructor() {
super(
"canonical",
uri.is,
(m, c) => (this.is(m) ? success(m) : failure(m, c)),
identity
);
}
}
const CANONICAL_REGEX = /\S*/;

const isCanonical = (m: unknown): m is string =>
typeof m === "string" && CANONICAL_REGEX.test(m);

/**
* A URI that refers to a resource by its canonical URL.
*/
export const canonical = new CanonicalType();
export const canonical = new Type<string>(
"canonical",
isCanonical,
(m, c) => (isCanonical(m) ? success(m) : failure(m, c)),
identity
);

export type canonical = TypeOf<typeof canonical>;
24 changes: 11 additions & 13 deletions packages/primitives/src/R4/code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,22 @@
* Code FHIR Primitive Runtime Type
*/

import { Type, success, failure, identity } from "io-ts";
import { Type, success, failure, identity, TypeOf } from "io-ts";

// TODO: This regex seems incorrect as well
const CODE_REGEX = /[^\s]+(\s[^\s]+)*/;

export class CodeType extends Type<string> {
readonly _tag: "CodeType" = "CodeType";
constructor() {
super(
"code",
(m): m is string => typeof m === "string" && CODE_REGEX.test(m),
(m, c) => (this.is(m) ? success(m) : failure(m, c)),
identity
);
}
}
const isCode = (m: unknown): m is string =>
typeof m === "string" && CODE_REGEX.test(m);

/**
* Indicates that the value is taken from a set of controlled strings defined elsewhere.
*/
export const code = new CodeType();
export const code = new Type<string>(
"code",
isCode,
(m, c) => (isCode(m) ? success(m) : failure(m, c)),
identity
);

export type code = TypeOf<typeof code>;
24 changes: 11 additions & 13 deletions packages/primitives/src/R4/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,22 @@
* Date FHIR Primitive Runtime Type
*/

import { Type, success, failure, identity } from "io-ts";
import { Type, success, failure, identity, TypeOf } from "io-ts";

// TODO: This regex seems too permissive
const DATE_REGEX = /([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)(-(0[1-9]|1[0-2])(-(0[1-9]|[1-2][0-9]|3[0-1]))?)?/;

export class DateType extends Type<string> {
readonly _tag: "DateType" = "DateType";
constructor() {
super(
"date",
(m): m is string => typeof m === "string" && DATE_REGEX.test(m),
(m, c) => (this.is(m) ? success(m) : failure(m, c)),
identity
);
}
}
const isDate = (m: unknown): m is string =>
typeof m === "string" && DATE_REGEX.test(m);

/**
* A date, or partial date (e.g. just year or year + month) as used in human communication.
*/
export const date = new DateType();
export const date = new Type<string>(
"date",
isDate,
(m, c) => (isDate(m) ? success(m) : failure(m, c)),
identity
);

export type date = TypeOf<typeof date>;
24 changes: 11 additions & 13 deletions packages/primitives/src/R4/dateTime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,21 @@
* DateTime FHIR Primitive Runtime Type
*/

import { Type, success, failure, identity } from "io-ts";
import { Type, success, failure, identity, TypeOf } from "io-ts";

const DATE_TIME_REGEX = /([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)(-(0[1-9]|1[0-2])(-(0[1-9]|[1-2][0-9]|3[0-1])(T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\.[0-9]+)?(Z|(\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00)))?)?)?/;

export class DateTimeType extends Type<string> {
readonly _tag: "DateTimeType" = "DateTimeType";
constructor() {
super(
"dateTime",
(m): m is string => typeof m === "string" && DATE_TIME_REGEX.test(m),
(m, c) => (this.is(m) ? success(m) : failure(m, c)),
identity
);
}
}
const isDateTime = (m: unknown): m is string =>
typeof m === "string" && DATE_TIME_REGEX.test(m);

/**
* A date, date-time or partial date (e.g. just year or year + month) as used in human communication.
*/
export const dateTime = new DateTimeType();
export const dateTime = new Type<string>(
"dateTime",
isDateTime,
(m, c) => (isDateTime(m) ? success(m) : failure(m, c)),
identity
);

export type dateTime = TypeOf<typeof dateTime>;
118 changes: 65 additions & 53 deletions packages/primitives/src/R4/decimal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,73 @@
* Decimal FHIR Primitive Runtime Type
*/

import { Big } from "big.js";
import { Type, success, failure } from "io-ts";
// import { Big } from "big.js";
import { Type, success, failure, TypeOf, identity } from "io-ts";

/**
* Class that wraps big.js to maintain precision, including trailing zeros
*/
export class Decimal extends Big {
private dp: number;
constructor(n: string | number) {
super(n);
this.dp = this.decimalPlaces(n);
}

public toFixed(dp?: number) {
return super.toFixed(this.dp);
}

private decimalPlaces(n: string | number) {
// Coerce to string
const number = String(n);
const hasDecimal = number.includes(".");
const exponentialForm = number.includes("e");
if (hasDecimal) {
if (exponentialForm) {
const [mantissa, exponent] = number.split(".")[1].split("e");
return mantissa.length - parseInt(exponent);
} else {
return number.split(".")[1].length;
}
} else {
return 0;
}
}
}

export class DecimalType extends Type<Decimal, string, unknown> {
readonly _tag: "DecimalType" = "DecimalType";
constructor() {
super(
"decimal",
(m): m is Decimal => m instanceof Decimal,
(m, c) => {
try {
const decimal = new Decimal(<any>m);
return success(decimal);
} catch (e) {
return failure(m, c);
}
},
a => a.toFixed()
);
}
}
// /**
// * Class that wraps big.js to maintain precision, including trailing zeros
// */
// export class Decimal extends Big {
// private dp: number;
// constructor(n: string | number) {
// super(n);
// this.dp = this.decimalPlaces(n);
// }

// public toFixed() {
// return super.toFixed(this.dp);
// }

// private decimalPlaces(n: string | number) {
// // Coerce to string
// const number = String(n);
// const hasDecimal = number.includes(".");
// const exponentialForm = number.includes("e");
// if (hasDecimal) {
// if (exponentialForm) {
// const [mantissa, exponent] = number.split(".")[1].split("e");
// return mantissa.length - parseInt(exponent);
// } else {
// return number.split(".")[1].length;
// }
// } else {
// return 0;
// }
// }
// }

// const isDecimal = (m: unknown): m is Decimal => m instanceof Decimal;

// /**
// * Rational numbers that have a decimal representation.
// */
// export const decimal = new Type<Decimal, string>(
// "decimal",
// isDecimal,
// (m, c) => {
// try {
// const decimal = new Decimal(<any>m);
// return success(decimal);
// } catch (e) {
// return failure(m, c);
// }
// },
// a => a.toFixed()
// );

// export type decimal = TypeOf<typeof decimal>;

const isDecimal = (m: unknown): m is number => typeof m === "number";

/**
* Rational numbers that have a decimal representation.
* TODO: Implement precision persistence
*/
export const decimal = new DecimalType();
export const decimal = new Type<number>(
"decimal",
isDecimal,
(m, c) => (isDecimal(m) ? success(m) : failure(m, c)),
identity
);

export type decimal = TypeOf<typeof decimal>;
24 changes: 11 additions & 13 deletions packages/primitives/src/R4/id.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,23 @@
* ID FHIR Primitive Runtime Type
*/

import { Type, success, failure, identity } from "io-ts";
import { Type, success, failure, identity, TypeOf } from "io-ts";

// TODO: This regex seems incorrect as well
const ID_REGEX = /[A-Za-z0-9\-\.]{1,64}/;

export class IDType extends Type<string> {
readonly _tag: "IDType" = "IDType";
constructor() {
super(
"id",
(m): m is string => typeof m === "string" && ID_REGEX.test(m),
(m, c) => (this.is(m) ? success(m) : failure(m, c)),
identity
);
}
}
const isId = (m: unknown): m is string =>
typeof m === "string" && ID_REGEX.test(m);

/**
* Any combination of upper- or lower-case ASCII letters ('A'..'Z', and 'a'..'z', numerals ('0'..'9'),
* '-' and '.', with a length limit of 64 characters.
*/
export const id = new IDType();
export const id = new Type<string>(
"id",
isId,
(m, c) => (isId(m) ? success(m) : failure(m, c)),
identity
);

export type id = TypeOf<typeof id>;
Loading

0 comments on commit 5d2bde4

Please sign in to comment.