Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
name: 'Helsinki Region',
countryCode: 'FI',
countryDefault: true,
zipCode: '00100',
location: { lat: 60.1699, lon: 24.9384 },
active: true,
hidden: false,
geometryId: 2,
created: 1553687004207,
modified: 0,
currency: 'EUR',
},
balance: 1234,
},
];
export const examplesCustomer = nonEmptyArray(Customer).decode(examplesCustomerJson);
export default Customer;
// Success
name: 'Development Environments',
envs: [
{
id: 'fantasyTopping',
api: 'https://fantasy.example.com/api/',
live: false,
contact: { name: 'Dennis Developer' },
name: 'Fantasy Topping',
description: 'Add support for pizza customization',
},
],
},
],
},
];
export const examplesEnvironments = nonEmptyArray(Environments).decode(
examplesEnvironmentsJson,
);
export default Environments;
// Success
'Environment',
);
export interface EnvironmentBrand {
readonly Environment: unique symbol;
}
/** examplesEnvironment // => { _tag: 'Right', right: examplesEnvironmentJson } */
export const examplesEnvironmentJson: NonEmptyArray = [
{
id: 'production',
api: 'https://production.example.com/api/',
live: true,
contact: { name: 'Alisha Admin', email: 'admin@example.com' },
description: 'Production environment',
},
];
export const examplesEnvironment = nonEmptyArray(Environment).decode(
examplesEnvironmentJson,
);
// DevEnvironment
// The purpose of this remains a mystery
export type DevEnvironment = t.Branded<
Environment &
({
live?: false;
} & {
live: Defined;
}),
DevEnvironmentBrand
>;
export const DevEnvironment = t.brand(
t.intersection([
// Email
// Rough validation of a valid e-mail address, see https://davidcel.is/posts/stop-validating-email-addresses-with-regex/
export type Email = t.Branded;
export const Email = t.brand(
t.string,
(x): x is t.Branded =>
(typeof x !== 'string' || x.match(RegExp('^.+@.+\\..+$')) !== null) &&
(typeof x !== 'string' || x.length <= 64),
'Email',
);
export interface EmailBrand {
readonly Email: unique symbol;
}
/** examplesEmail // => { _tag: 'Right', right: examplesEmailJson } */
export const examplesEmailJson: NonEmptyArray = ['joe.customer@example.com'];
export const examplesEmail = nonEmptyArray(Email).decode(examplesEmailJson);
// PaymentSourceId
// The purpose of this remains a mystery
export type PaymentSourceId = t.Branded;
export const PaymentSourceId = t.brand(
t.string,
(x): x is t.Branded =>
(typeof x !== 'string' || x.length >= 3) &&
(typeof x !== 'string' || x.length <= 255),
'PaymentSourceId',
);
export interface PaymentSourceIdBrand {
readonly PaymentSourceId: unique symbol;
}
// AppInstanceId
// Phone
// ITU-T E.164 phone number, see https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s03.html
export type Phone = t.Branded;
export const Phone = t.brand(
t.string,
(x): x is t.Branded =>
typeof x !== 'string' || x.match(RegExp('^\\+(?:\\d){6,14}\\d$')) !== null,
'Phone',
);
export interface PhoneBrand {
readonly Phone: unique symbol;
}
/** examplesPhone // => { _tag: 'Right', right: examplesPhoneJson } */
export const examplesPhoneJson: NonEmptyArray = ['+358401234567'];
export const examplesPhone = nonEmptyArray(Phone).decode(examplesPhoneJson);
// RawPhone
// Slightly looser definition of phone number
export type RawPhone = t.Branded;
export const RawPhone = t.brand(
t.string,
(x): x is t.Branded =>
typeof x !== 'string' || x.match(RegExp('^\\+?(?:\\d){6,14}\\d$')) !== null,
'RawPhone',
);
export interface RawPhoneBrand {
readonly RawPhone: unique symbol;
}
// Email
// Rough validation of a valid e-mail address, see https://davidcel.is/posts/stop-validating-email-addresses-with-regex/
t.string,
(x): x is t.Branded =>
typeof x !== 'string' ||
x.match(
RegExp('^[aepus]{2}-[\\w]{4}-\\d:[a-f\\d]{8}(-[a-f\\d]{4}){3}-[a-f\\d]{12}$'),
) !== null,
'ObsoleteIdentityId',
);
export interface ObsoleteIdentityIdBrand {
readonly ObsoleteIdentityId: unique symbol;
}
/** examplesObsoleteIdentityId // => { _tag: 'Right', right: examplesObsoleteIdentityIdJson } */
export const examplesObsoleteIdentityIdJson: NonEmptyArray = [
'eu-west-1:4828507e-683f-41bf-9d87-689808fbf958',
];
export const examplesObsoleteIdentityId = nonEmptyArray(ObsoleteIdentityId).decode(
examplesObsoleteIdentityIdJson,
);
// IdentityId
// The purpose of this remains a mystery
export type IdentityId = t.Branded;
export const IdentityId = t.brand(
t.union([ObsoleteIdentityId, Uuid]),
(x): x is t.Branded => true,
'IdentityId',
);
export interface IdentityIdBrand {
readonly IdentityId: unique symbol;
}
/** examplesIdentityId // => { _tag: 'Right', right: examplesIdentityIdJson } */
export const examplesIdentityIdJson: NonEmptyArray = [
//
// business logic
//
const UserNotFound = 'UserNotFound' as const
const InvalidArguments = 'InvalidArguments' as const
const JSONError = 'JSONError' as const
type UserError = typeof InvalidArguments | typeof UserNotFound | typeof JSONError
/** Parses the `user_id` param */
const getUserId: H.Middleware = pipe(
H.decodeParam('user_id', NonEmptyString.decode),
H.mapLeft(() => InvalidArguments)
)
/** Loads a `User` from a database (fake) */
function loadUser(userId: NonEmptyString): H.Middleware {
return userId === 'ab' ? H.right({ name: 'User name...' }) : H.left(UserNotFound)
}
/** Sends a `User` to the client */
function sendUser(user: User): H.Middleware {
return pipe(
H.status(H.Status.OK),
H.ichain(() => H.json(user, () => JSONError))
)
}
interface User {
name: string
}
//
// business logic
//
const UserNotFound: 'UserNotFound' = 'UserNotFound'
const InvalidArguments: 'InvalidArguments' = 'InvalidArguments'
type UserError = typeof InvalidArguments | typeof UserNotFound | AuthenticationError
/** Parses the `user_id` param */
const getUserId = decodeParam('user_id', NonEmptyString.decode).mapLeft(() => InvalidArguments)
/** Sends a `User` to the client */
const sendUser = (user: User) =>
status(Status.OK)
.closeHeaders()
.send(`Hello ${user.name}!`)
/**
* Loads a `User` from a database. The resulting middleware requires a successful authentication upstream because of the
* `AuthenticatedOpen` constraint
*/
const loadUser = (userId: UserId): Middleware =>
userId === 'ab' ? of({ name: 'User name...' }) : fromLeft(UserNotFound)
// const getUser = getUserId
// .ichain(loadUser) // static error! Property 'AuthenticatedOpen' is missing in type 'StatusOpen' but required in type 'AuthenticatedOpen'
return new Middleware(c => {
// dummy authentication logic
if (NonEmptyString.is(c.getHeader('token'))) {
return middleware.run(c) as any
} else {
return fromLeft(AuthenticationError)
}
})
}
import { literal, string, type, union } from 'io-ts';
import { optionFromNullable } from 'io-ts-types/lib/optionFromNullable';
export interface WebsocketsChannelBindingObject {
readonly method: Option<'GET' | 'POST'>;
readonly query: Option;
readonly headers: Option;
readonly bindingVersion: Option;
}
export const WebsocketsChannelBindingObjectCodec: Codec = type(
{
method: optionFromNullable(union([literal('GET'), literal('POST')])),
query: optionFromNullable(ObjectSchemaObjectCodec),
headers: optionFromNullable(ObjectSchemaObjectCodec),
bindingVersion: optionFromNullable(string),
},
'WebsocketsChannelBindingObject',
);