tslint, check name, nullability, requiredValue -> required
This commit is contained in:
parent
2b8b5c0902
commit
1667eb10bf
|
@ -19,7 +19,7 @@ const Post = GQLiteralObject("Post", (t) => {
|
|||
t.field("author", "User", { description: "Author of the field" });
|
||||
t.string("title", {
|
||||
description: "Title of the Post",
|
||||
defaultValue: "Untitled Post",
|
||||
default: "Untitled Post",
|
||||
});
|
||||
t.string("body", { description: "Body of the Post, formatted as Markdown" });
|
||||
t.field("status", "StatusEnum", {
|
||||
|
|
|
@ -10,7 +10,7 @@ GQLiteral aims to combine the simplicity and ease of development of schema-first
|
|||
|
||||
It builds upon the primitives of `graphql-js` and similar to the schema-first approach, it uses the type names rather than per-type object references to build the schema. What this means is you won't end up with a ton of confusing imports just to build out your types, side-stepping the dreaded circular import problem.
|
||||
|
||||
GQLiteral was designed with TypeScript/JavaScript intellisense in mind, and aims to leverage generics and type generation tools to provide as much type coverage as possible to aid in development. Read more about how you can [configure](typescript-setup.md) your project to best take advantage of this.
|
||||
GQLiteral was designed with TypeScript/JavaScript intellisense in mind, and makes use of TypeScript generics, conditional types, and type merging to provide as much type coverage as possible out of the box. Read more about how you can [configure](typescript-setup.md) your project to best take advantage of this.
|
||||
|
||||
## Installation
|
||||
|
||||
|
@ -73,7 +73,7 @@ const schema = GQLiteralSchema({
|
|||
});
|
||||
```
|
||||
|
||||
## Nullability & defaultValue
|
||||
## Nullability & default
|
||||
|
||||
One benefit of GraphQL is the strict enforcement and guarentees of null values it provides in the type definitions. One opinion held by GraphQL is that fields should be considered nullable by default. The GraphQL documentation provides [this explanation](https://graphql.org/learn/best-practices/#nullability):
|
||||
|
||||
|
@ -87,13 +87,17 @@ If you find yourself wanting this the other way around, there is a `defaultNull`
|
|||
|
||||
This can also be configured on a per-type basis, using the `defaultNull` method on the type definition object. This comes in handy where you want to "mix" an `AbstractType` into an `ObjectType` and an `InputObjectType`, and the fields should be considered nullable by default on input, and required by default on output.
|
||||
|
||||
#### defaultValue
|
||||
```
|
||||
|
||||
Enforcing non-null guarantees at the resolver layer can be tedious, so GQLiteral also provides a `defaultValue` option; a value used when the resolved type is otherwise `null` or `undefined`. Providing the `defaultValue` will set the schema definition for the field to non-null regardless of root schema configuration, unless `nullable: true` is set explicitly on the field.
|
||||
```
|
||||
|
||||
#### default
|
||||
|
||||
Enforcing non-null guarantees at the resolver layer can be tedious, so GQLiteral also provides a `default` option; a value used when the resolved type is otherwise `null` or `undefined`. Providing the `default` will set the schema definition for the field to non-null regardless of root schema configuration, unless `nullable: true` is set explicitly on the field.
|
||||
|
||||
```ts
|
||||
const AccountInfo = GQLiteralObject("AccountInfo", (t) => {
|
||||
t.string("description", { defaultValue: "N/A" });
|
||||
t.string("description", { default: "N/A" });
|
||||
t.int("linkedAccountId", { nullable: true });
|
||||
});
|
||||
```
|
||||
|
|
|
@ -41,7 +41,9 @@ const context = async ({ req }: { req: Request }) => {
|
|||
const email = new Buffer(auth, "base64").toString("ascii");
|
||||
|
||||
// if the email isn't formatted validly, return null for user
|
||||
if (!isEmail.validate(email)) return { user: null };
|
||||
if (!isEmail.validate(email)) {
|
||||
return { user: null };
|
||||
}
|
||||
// find a user by their email
|
||||
const users = await store.users.findOrCreate({ where: { email } });
|
||||
const user = users && users[0] ? users[0] : null;
|
||||
|
|
|
@ -6,6 +6,6 @@ export const Droid = GQLiteralObject<Gen, "Droid">("Droid", (t) => {
|
|||
t.implements("Character");
|
||||
t.string("primaryFunction", {
|
||||
description: "The primary function of the droid.",
|
||||
defaultValue: "N/A",
|
||||
default: "N/A",
|
||||
});
|
||||
});
|
||||
|
|
12
package.json
12
package.json
|
@ -2,12 +2,16 @@
|
|||
"name": "gqliteral",
|
||||
"version": "0.1.0",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
"types": "dist/index.d.ts",
|
||||
"license": "MIT",
|
||||
"description": "Scalable, strongly typed GraphQL schema development",
|
||||
"scripts": {
|
||||
"dev": "tsc -w",
|
||||
"test": "jest"
|
||||
"test": "jest",
|
||||
"build": "tsc",
|
||||
"lint": "tslint -p tsconfig.json",
|
||||
"clean": "rm -rf dist",
|
||||
"prepublish": "yarn clean && yarn lint && yarn build"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
|
@ -34,8 +38,10 @@
|
|||
"lint-staged": "^7.3.0",
|
||||
"typescript": "^3.1.3",
|
||||
"tslint": "^5.11.0",
|
||||
"tslint-config-prettier": "^1.15.0",
|
||||
"jest": "^23.6.0",
|
||||
"ts-jest": "^23.10.4"
|
||||
"ts-jest": "^23.10.4",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"prettier": "^1.15.1",
|
||||
|
|
|
@ -36,7 +36,7 @@ import {
|
|||
} from "graphql";
|
||||
import { GQLiteralTypeWrapper } from "./definitions";
|
||||
import * as Types from "./types";
|
||||
import suggestionList, { propertyFieldResolver } from "./utils";
|
||||
import { suggestionList, propertyFieldResolver } from "./utils";
|
||||
import { GQLiteralAbstract, GQLiteralDirectiveType } from "./objects";
|
||||
|
||||
const isPromise = (val: any): val is Promise<any> =>
|
||||
|
@ -172,8 +172,8 @@ export class SchemaBuilder {
|
|||
...rest,
|
||||
args: args.reduce(
|
||||
(result: GraphQLFieldConfigArgumentMap, arg) => {
|
||||
const { name, ...rest } = arg;
|
||||
result[name] = rest;
|
||||
const { name, ...argRest } = arg;
|
||||
result[name] = argRest;
|
||||
return result;
|
||||
},
|
||||
{}
|
||||
|
@ -446,10 +446,20 @@ export class SchemaBuilder {
|
|||
|
||||
protected decorateInputType(
|
||||
type: GraphQLInputType,
|
||||
fieldConfig: Types.FieldConfig,
|
||||
fieldConfig: Types.InputFieldConfig,
|
||||
typeConfig: Types.InputTypeConfig
|
||||
) {
|
||||
return this.decorateType(type, fieldConfig, typeConfig, true);
|
||||
const { required: _required, requiredListItem, ...rest } = fieldConfig;
|
||||
const newOpts = rest;
|
||||
if (typeof _required !== "undefined") {
|
||||
newOpts.nullable = !_required;
|
||||
}
|
||||
if (typeof requiredListItem !== "undefined") {
|
||||
if (rest.list) {
|
||||
newOpts.listItemNullable = !requiredListItem;
|
||||
}
|
||||
}
|
||||
return this.decorateType(type, newOpts, typeConfig, true);
|
||||
}
|
||||
|
||||
protected decorateOutputType(
|
||||
|
@ -640,8 +650,8 @@ export class SchemaBuilder {
|
|||
} else if (fieldOptions.property) {
|
||||
resolver = propertyFieldResolver(fieldOptions.property);
|
||||
}
|
||||
if (typeof fieldOptions.defaultValue !== "undefined") {
|
||||
resolver = withDefaultValue(resolver, fieldOptions.defaultValue);
|
||||
if (typeof fieldOptions.default !== "undefined") {
|
||||
resolver = withDefaultValue(resolver, fieldOptions.default);
|
||||
}
|
||||
return resolver;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
printSchema,
|
||||
GraphQLScalarType,
|
||||
GraphQLObjectType,
|
||||
assertValidName,
|
||||
} from "graphql";
|
||||
import * as Types from "./types";
|
||||
import {
|
||||
|
@ -45,7 +46,7 @@ export class GQLiteralTypeWrapper<
|
|||
* @param {object} options
|
||||
*/
|
||||
export function GQLiteralScalar(name: string, options: Types.ScalarOpts) {
|
||||
return new GraphQLScalarType({ name, ...options });
|
||||
return new GraphQLScalarType({ name: assertValidName(name), ...options });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,7 +58,9 @@ export function GQLiteralObject<
|
|||
GenTypes = GQLiteralGen,
|
||||
TypeName extends string = any
|
||||
>(name: TypeName, fn: (arg: GQLiteralObjectType<GenTypes, TypeName>) => void) {
|
||||
const factory = new GQLiteralObjectType<GenTypes, TypeName>(name);
|
||||
const factory = new GQLiteralObjectType<GenTypes, TypeName>(
|
||||
assertValidName(name)
|
||||
);
|
||||
fn(factory);
|
||||
return new GQLiteralTypeWrapper(name, factory);
|
||||
}
|
||||
|
@ -72,7 +75,9 @@ export function GQLiteralInterface<
|
|||
name: TypeName,
|
||||
fn: (arg: GQLiteralInterfaceType<GenTypes, TypeName>) => void
|
||||
) {
|
||||
const factory = new GQLiteralInterfaceType<GenTypes, TypeName>(name);
|
||||
const factory = new GQLiteralInterfaceType<GenTypes, TypeName>(
|
||||
assertValidName(name)
|
||||
);
|
||||
fn(factory);
|
||||
return new GQLiteralTypeWrapper(name, factory);
|
||||
}
|
||||
|
@ -98,7 +103,7 @@ export function GQLiteralUnion<
|
|||
GenTypes = GQLiteralGen,
|
||||
TypeName extends string = any
|
||||
>(name: TypeName, fn: (arg: GQLiteralUnionType<GenTypes, TypeName>) => void) {
|
||||
const factory = new GQLiteralUnionType<GenTypes>(name);
|
||||
const factory = new GQLiteralUnionType<GenTypes>(assertValidName(name));
|
||||
fn(factory);
|
||||
return new GQLiteralTypeWrapper(name, factory);
|
||||
}
|
||||
|
@ -140,7 +145,7 @@ export function GQLiteralEnum<
|
|||
| string[]
|
||||
| Record<string, string | number | object | boolean>
|
||||
) {
|
||||
const factory = new GQLiteralEnumType<GenTypes>(name);
|
||||
const factory = new GQLiteralEnumType<GenTypes>(assertValidName(name));
|
||||
if (typeof fn === "function") {
|
||||
fn(factory);
|
||||
} else {
|
||||
|
@ -156,7 +161,7 @@ export function GQLiteralInputObject<
|
|||
GenTypes = GQLiteralGen,
|
||||
TypeName extends string = any
|
||||
>(name: TypeName, fn: (arg: GQLiteralInputObjectType<GenTypes>) => void) {
|
||||
const factory = new GQLiteralInputObjectType<GenTypes>(name);
|
||||
const factory = new GQLiteralInputObjectType<GenTypes>(assertValidName(name));
|
||||
fn(factory);
|
||||
return new GQLiteralTypeWrapper(name, factory);
|
||||
}
|
||||
|
@ -213,7 +218,7 @@ export function GQLiteralDirective<
|
|||
| Types.DirectiveConfig<GenTypes, DirectiveName>
|
||||
| ((arg: GQLiteralDirectiveType<GenTypes>) => void)
|
||||
) {
|
||||
const directive = new GQLiteralDirectiveType<GenTypes>(name);
|
||||
const directive = new GQLiteralDirectiveType<GenTypes>(assertValidName(name));
|
||||
if (typeof config === "function") {
|
||||
config(directive);
|
||||
} else {
|
||||
|
@ -232,14 +237,14 @@ export function GQLiteralDirective<
|
|||
export function GQLiteralSchema(options: Types.SchemaConfig) {
|
||||
const { types: typeMap, directives } = buildTypes(options.types, options);
|
||||
|
||||
if (!isObjectType(typeMap["Query"])) {
|
||||
if (!isObjectType(typeMap.Query)) {
|
||||
throw new Error("Missing a Query type");
|
||||
}
|
||||
|
||||
const schema = new GraphQLSchema({
|
||||
query: typeMap["Query"] as Types.Maybe<GraphQLObjectType>,
|
||||
mutation: typeMap["Mutation"] as Types.Maybe<GraphQLObjectType>,
|
||||
subscription: typeMap["Subscription"] as Types.Maybe<GraphQLObjectType>,
|
||||
query: typeMap.Query as Types.Maybe<GraphQLObjectType>,
|
||||
mutation: typeMap.Mutation as Types.Maybe<GraphQLObjectType>,
|
||||
subscription: typeMap.Subscription as Types.Maybe<GraphQLObjectType>,
|
||||
directives: directives.definitions,
|
||||
types: Object.keys(typeMap).reduce((result: GraphQLNamedType[], key) => {
|
||||
result.push(typeMap[key]);
|
||||
|
@ -250,7 +255,10 @@ export function GQLiteralSchema(options: Types.SchemaConfig) {
|
|||
// Only in development do we want to worry about regenerating the
|
||||
// schema definition and/or generated types.
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
const sortedSchema = lexicographicSortSchema(schema);
|
||||
let sortedSchema = schema;
|
||||
if (typeof lexicographicSortSchema !== "undefined") {
|
||||
sortedSchema = lexicographicSortSchema(schema);
|
||||
}
|
||||
const generatedSchema = addDirectives(
|
||||
printSchema(sortedSchema),
|
||||
directives
|
||||
|
|
|
@ -10,3 +10,5 @@ export {
|
|||
GQLiteralAbstractType,
|
||||
GQLiteralDirective,
|
||||
} from "./definitions";
|
||||
import * as GQLiteralTypes from "./types";
|
||||
export { GQLiteralTypes };
|
||||
|
|
|
@ -38,7 +38,7 @@ export class GQLiteralEnumType<GenTypes = GQLiteralGen> {
|
|||
};
|
||||
}
|
||||
|
||||
mix<EnumName extends Types.EnumName<GenTypes>>(
|
||||
mix<EnumName extends Types.EnumNames<GenTypes>>(
|
||||
typeName: EnumName,
|
||||
mixOptions?: Types.MixOpts<Types.EnumMembers<GenTypes, EnumName>>
|
||||
) {
|
||||
|
@ -64,16 +64,16 @@ export class GQLiteralEnumType<GenTypes = GQLiteralGen> {
|
|||
* Sets the members of the enum
|
||||
*/
|
||||
members(info: Array<Types.EnumMemberInfo | string>) {
|
||||
info.forEach((info) => {
|
||||
if (typeof info === "string") {
|
||||
info.forEach((member) => {
|
||||
if (typeof member === "string") {
|
||||
return this.typeConfig.members.push({
|
||||
item: Types.NodeType.ENUM_MEMBER,
|
||||
info: { name: info, value: info },
|
||||
info: { name: member, value: member },
|
||||
});
|
||||
}
|
||||
this.typeConfig.members.push({
|
||||
item: Types.NodeType.ENUM_MEMBER,
|
||||
info,
|
||||
info: member,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ export class GQLiteralObjectType<
|
|||
* abstract type.
|
||||
*
|
||||
* At this point the type will not change, but the resolver,
|
||||
* defaultValue, property, or description fields can.
|
||||
* default, property, or description fields can.
|
||||
*/
|
||||
modify<FieldName extends Types.ObjectTypeFields<GenTypes, TypeName>>(
|
||||
field: FieldName,
|
||||
|
@ -365,6 +365,20 @@ export class GQLiteralObjectType<
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the nullability config for the type
|
||||
*/
|
||||
nullability(nullability: Types.NullabilityConfig) {
|
||||
if (this.typeConfig.nullability) {
|
||||
console.warn(
|
||||
`nullability has already been set for type ${
|
||||
this.typeConfig.name
|
||||
}, the previous value will be replaced`
|
||||
);
|
||||
}
|
||||
this.typeConfig.nullability = nullability;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only. Creates the configuration to create
|
||||
* the GraphQL named type.
|
||||
|
@ -600,6 +614,20 @@ export class GQLiteralInputObjectType<GenTypes = GQLiteralGen> {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the nullability config for the type
|
||||
*/
|
||||
nullability(nullability: Types.NullabilityConfig) {
|
||||
if (this.typeConfig.nullability) {
|
||||
console.warn(
|
||||
`nullability has already been set for type ${
|
||||
this.typeConfig.name
|
||||
}, the previous value will be replaced`
|
||||
);
|
||||
}
|
||||
this.typeConfig.nullability = nullability;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only. Creates the configuration to create
|
||||
* the GraphQL named type.
|
||||
|
@ -702,7 +730,7 @@ export class GQLiteralDirectiveType<GenTypes = GQLiteralGen> {
|
|||
this.typeConfig = {
|
||||
name,
|
||||
locations: [],
|
||||
args: [],
|
||||
directiveArgs: [],
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -772,7 +800,7 @@ export class GQLiteralDirectiveType<GenTypes = GQLiteralGen> {
|
|||
type: Types.AllInputTypes<GenTypes> | Types.BaseScalars,
|
||||
options?: Types.InputFieldOpts
|
||||
) {
|
||||
this.typeConfig.args.push({
|
||||
this.typeConfig.directiveArgs.push({
|
||||
name,
|
||||
type,
|
||||
...options,
|
||||
|
|
|
@ -290,14 +290,14 @@ function nonInterfaceFields(
|
|||
ctx: SchemaTemplateContext,
|
||||
t: SchemaTemplateContext["types"][0]
|
||||
) {
|
||||
const interfaceFields = new Set<string>();
|
||||
const allInterfaceFields = new Set<string>();
|
||||
t.interfaces.forEach((name) => {
|
||||
const iface = ctx.interfaces.find((i) => i.name === name);
|
||||
if (iface) {
|
||||
iface.fields.forEach((field) => {
|
||||
interfaceFields.add(field.name);
|
||||
allInterfaceFields.add(field.name);
|
||||
});
|
||||
}
|
||||
});
|
||||
return t.fields.filter((field) => !interfaceFields.has(field.name));
|
||||
return t.fields.filter((field) => !allInterfaceFields.has(field.name));
|
||||
}
|
||||
|
|
33
src/types.ts
33
src/types.ts
|
@ -48,6 +48,11 @@ export interface FieldConfig extends OutputFieldOpts<any, any, any> {
|
|||
type: any;
|
||||
}
|
||||
|
||||
export interface InputFieldConfig extends InputFieldOpts {
|
||||
name: string;
|
||||
type: any;
|
||||
}
|
||||
|
||||
export type FieldDefType = MixDef | MixAbstractDef | FieldDef;
|
||||
|
||||
export type EnumDefType =
|
||||
|
@ -204,7 +209,12 @@ export interface OutputFieldOpts<
|
|||
/**
|
||||
* Default value for the field, if none is returned.
|
||||
*/
|
||||
defaultValue?: any;
|
||||
default?: any;
|
||||
/**
|
||||
* Synchronous validation for the field, runs just after the
|
||||
* built-in "validate", at the root level prior to execution.
|
||||
*/
|
||||
validate?: (info: GraphQLResolveInfo) => boolean | Error;
|
||||
}
|
||||
|
||||
export interface AbstractFieldOpts<GenTypes, FieldName> extends FieldOpts {}
|
||||
|
@ -214,7 +224,16 @@ export type ModifyFieldOpts<GenTypes, TypeName, FieldName> = Omit<
|
|||
"args" | "list" | "listItemNullable" | "nullable"
|
||||
>;
|
||||
|
||||
export interface InputFieldOpts extends FieldOpts {}
|
||||
export interface InputFieldOpts extends FieldOpts {
|
||||
/**
|
||||
* Setting this to true is the same as setting `nullable: false`
|
||||
*/
|
||||
required?: boolean;
|
||||
/**
|
||||
* Whether the item in the list is required
|
||||
*/
|
||||
requiredListItem?: boolean;
|
||||
}
|
||||
|
||||
export interface ScalarOpts
|
||||
extends Omit<
|
||||
|
@ -314,7 +333,7 @@ export interface AbstractTypeConfig {
|
|||
export interface DirectiveTypeConfig extends Named {
|
||||
description?: string;
|
||||
locations: DirectiveLocationEnum[];
|
||||
args: DirectiveArgDefinition[];
|
||||
directiveArgs: DirectiveArgDefinition[];
|
||||
}
|
||||
|
||||
export interface InterfaceTypeConfig
|
||||
|
@ -420,7 +439,7 @@ export type TypeResolver<GenTypes, TypeName> = (
|
|||
root: RootValue<GenTypes, TypeName>,
|
||||
context: ContextValue<GenTypes>,
|
||||
info: GraphQLResolveInfo
|
||||
) => MaybePromise<Maybe<InterfaceName<GenTypes, TypeName>>>;
|
||||
) => MaybePromise<Maybe<InterfaceNames<GenTypes, TypeName>>>;
|
||||
|
||||
/**
|
||||
* Helpers for handling the generated schema
|
||||
|
@ -441,17 +460,17 @@ export type OutputNames<GenTypes> = GenTypes extends GenTypesShape
|
|||
? Extract<keyof GenTypes["objects"], string>
|
||||
: never;
|
||||
|
||||
export type InterfaceName<GenTypes, TypeName> = GenTypes extends GenTypesShape
|
||||
export type InterfaceNames<GenTypes, TypeName> = GenTypes extends GenTypesShape
|
||||
? TypeName extends keyof GenTypes["interfaces"]
|
||||
? GenTypes["interfaces"][TypeName]["implementingTypes"]
|
||||
: never
|
||||
: never;
|
||||
|
||||
export type EnumName<GenTypes> = GenTypes extends GenTypesShape
|
||||
export type EnumNames<GenTypes> = GenTypes extends GenTypesShape
|
||||
? Extract<keyof GenTypes["enums"], string>
|
||||
: never;
|
||||
|
||||
export type UnionName<GenTypes> = GenTypes extends GenTypesShape
|
||||
export type UnionNames<GenTypes> = GenTypes extends GenTypesShape
|
||||
? Extract<keyof GenTypes["unions"], string>
|
||||
: never;
|
||||
|
||||
|
|
|
@ -134,10 +134,7 @@ export function addDirectives(
|
|||
* Given an invalid input string and a list of valid options, returns a filtered
|
||||
* list of valid options sorted based on their similarity with the input.
|
||||
*/
|
||||
export default function suggestionList(
|
||||
input: string,
|
||||
options: string[]
|
||||
): string[] {
|
||||
export function suggestionList(input: string, options: string[]): string[] {
|
||||
var optionsByDistance = Object.create(null);
|
||||
var oLength = options.length;
|
||||
var inputThreshold = input.length / 2;
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"skipLibCheck": true
|
||||
"skipLibCheck": true,
|
||||
"declaration": true,
|
||||
"importHelpers": true
|
||||
},
|
||||
"exclude": ["./examples", "./dist", "./src/__tests__"]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"extends": ["tslint-config-prettier"],
|
||||
"rules": {
|
||||
"ban": false,
|
||||
"class-name": true,
|
||||
"curly": true,
|
||||
"eofline": false,
|
||||
"forin": true,
|
||||
"indent": [true, "spaces"],
|
||||
"jsdoc-format": true,
|
||||
"label-position": true,
|
||||
"no-any": false,
|
||||
"no-arg": true,
|
||||
"no-bitwise": true,
|
||||
"no-consecutive-blank-lines": false,
|
||||
"no-construct": true,
|
||||
"no-debugger": false,
|
||||
"no-duplicate-variable": true,
|
||||
"no-empty": false,
|
||||
"no-eval": true,
|
||||
"no-default-export": true,
|
||||
"no-shadowed-variable": true,
|
||||
"no-string-literal": true,
|
||||
"no-switch-case-fall-through": true,
|
||||
"no-trailing-whitespace": false,
|
||||
"no-unused-expression": true,
|
||||
"one-line": [
|
||||
true,
|
||||
"check-catch",
|
||||
"check-else",
|
||||
"check-open-brace",
|
||||
"check-whitespace"
|
||||
],
|
||||
"radix": true,
|
||||
"restrict-plus-operands": true,
|
||||
"trailing-comma": [false],
|
||||
"triple-equals": [true, "allow-null-check"],
|
||||
"whitespace": false
|
||||
},
|
||||
"linterOptions": {
|
||||
"exclude": ["**/*.json"]
|
||||
}
|
||||
}
|
|
@ -3611,10 +3611,14 @@ ts-log@2.1.3:
|
|||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ts-log/-/ts-log-2.1.3.tgz#9e30aca1baffe7693a2e4142b8f07ecb01cb8340"
|
||||
|
||||
tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0:
|
||||
tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
|
||||
|
||||
tslint-config-prettier@^1.15.0:
|
||||
version "1.15.0"
|
||||
resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.15.0.tgz#76b9714399004ab6831fdcf76d89b73691c812cf"
|
||||
|
||||
tslint@^5.11.0:
|
||||
version "5.11.0"
|
||||
resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.11.0.tgz#98f30c02eae3cde7006201e4c33cb08b48581eed"
|
||||
|
|
Loading…
Reference in New Issue