mirror of
https://github.com/wassname/talk.git
synced 2026-07-24 13:20:47 +08:00
[CORL-678] Transition to eslint (#2634)
* chore: setup eslint * chore: tslint checks with types & check for import order * chore: complete eslint transition * fix: tests * fix: linting after rebase, faster lint for lint-staged * chore: remove line * fix: lint rules * feat: add a11y linter and fix errors * fix: tests
This commit is contained in:
@@ -4,11 +4,10 @@ import React, { FunctionComponent } from "react";
|
||||
import { Omit, PropTypesOf } from "coral-framework/types";
|
||||
import { PasswordField as PasswordFieldUI } from "coral-ui/components";
|
||||
|
||||
export interface Props
|
||||
extends Omit<
|
||||
PropTypesOf<typeof PasswordFieldUI>,
|
||||
"showPasswordTitle" | "hidePasswordTitle"
|
||||
> {}
|
||||
type Props = Omit<
|
||||
PropTypesOf<typeof PasswordFieldUI>,
|
||||
"showPasswordTitle" | "hidePasswordTitle"
|
||||
>;
|
||||
|
||||
const PasswordField: FunctionComponent<Props> = props => (
|
||||
<Localized
|
||||
|
||||
@@ -152,7 +152,7 @@ class MarkdownEditor extends Component<Props> {
|
||||
this.editor.codemirror.on("change", this.onChange);
|
||||
}
|
||||
|
||||
public componentWillReceiveProps(nextProps: Props) {
|
||||
public UNSAFE_componentWillReceiveProps(nextProps: Props) {
|
||||
if (
|
||||
this.props.value !== nextProps.value &&
|
||||
nextProps.value !== this.editor!.value()
|
||||
@@ -198,18 +198,20 @@ let enhanced = withGetMessage(MarkdownEditor);
|
||||
|
||||
if (process.env.NODE_ENV === "test") {
|
||||
// Replace with simple texteditor because it won't work in a jsdom environment.
|
||||
enhanced = ({ onChange, ...rest }) => (
|
||||
<div className={styles.wrapper}>
|
||||
<textarea
|
||||
{...rest}
|
||||
onChange={(e: ChangeEvent<HTMLTextAreaElement> | string) => {
|
||||
if (onChange) {
|
||||
onChange(typeof e === "string" ? e : e.target.value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
enhanced = function MarkdownEditorTest({ onChange, ...rest }) {
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<textarea
|
||||
{...rest}
|
||||
onChange={(e: ChangeEvent<HTMLTextAreaElement> | string) => {
|
||||
if (onChange) {
|
||||
onChange(typeof e === "string" ? e : e.target.value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default enhanced;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import { lookup } from "coral-framework/lib/relay";
|
||||
import { GQLUser } from "coral-framework/schema";
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import getViewerSourceID from "./getViewerSourceID";
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ function resolveStoryURL() {
|
||||
return canonical.href;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
"This page does not include a canonical link tag. Coral has inferred this story_url from the window object. Query params have been stripped, which may cause a single thread to be present across multiple pages."
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Child } from "pym.js";
|
||||
import React from "react";
|
||||
|
||||
import withContext from "./withContext";
|
||||
|
||||
interface Props {
|
||||
|
||||
@@ -132,7 +132,7 @@ function createManagedCoralContextProvider(
|
||||
initLocalState: InitLocalState,
|
||||
localesData: LocalesData
|
||||
) {
|
||||
const ManagedCoralContextProvider = class extends Component<
|
||||
const ManagedCoralContextProvider = class ManagedCoralContextProvider extends Component<
|
||||
{},
|
||||
{ context: CoralContext }
|
||||
> {
|
||||
@@ -294,7 +294,7 @@ export default async function createManaged({
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
// tslint:disable:next-line: no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Using locales ${JSON.stringify(locales)}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createContextHOC } from "coral-framework/helpers";
|
||||
|
||||
import { CoralContext, CoralContextConsumer } from "./CoralContext";
|
||||
|
||||
const withContext = createContextHOC<CoralContext>(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ERROR_CODES } from "coral-common/errors";
|
||||
import { FORM_ERROR } from "final-form";
|
||||
|
||||
import { ERROR_CODES } from "coral-common/errors";
|
||||
|
||||
/**
|
||||
* Shape of the `InvalidRequest` extension as
|
||||
* the client requires. Note: the only crucial
|
||||
@@ -41,7 +42,7 @@ export default class InvalidRequestError extends Error
|
||||
this.message = extension.message || extension.code;
|
||||
}
|
||||
|
||||
get invalidArgs() {
|
||||
public get invalidArgs() {
|
||||
if (this.param) {
|
||||
return {
|
||||
[this.param.substr("input.".length)]: this.message,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { areWeInIframe } from "coral-framework/utils";
|
||||
import { Child as PymChild } from "pym.js";
|
||||
|
||||
import { areWeInIframe } from "coral-framework/utils";
|
||||
|
||||
export interface ExternalConfig {
|
||||
accessToken?: string;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ class SubmitHookContainer extends React.Component<Props> {
|
||||
if (error instanceof InvalidRequestError) {
|
||||
return error.invalidArgs;
|
||||
}
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createContextHOC } from "coral-framework/helpers";
|
||||
|
||||
import {
|
||||
SubmitHookContext,
|
||||
SubmitHookContextConsumer,
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import "fluent-intl-polyfill/compat";
|
||||
import { FluentBundle } from "fluent/compat";
|
||||
|
||||
import * as functions from "./functions";
|
||||
import { LocalesData } from "./locales";
|
||||
|
||||
import "fluent-intl-polyfill/compat";
|
||||
|
||||
// Don't warn in production.
|
||||
let decorateWarnMissing = (bundle: FluentBundle) => bundle;
|
||||
|
||||
@@ -16,11 +17,9 @@ if (process.env.NODE_ENV !== "production") {
|
||||
bundle.hasMessage = (id: string) => {
|
||||
const result = original.apply(bundle, [id]);
|
||||
if (!result) {
|
||||
const warn = `${
|
||||
bundle.locales
|
||||
} translation for key "${id}" not found`;
|
||||
const warn = `${bundle.locales} translation for key "${id}" not found`;
|
||||
if (!warnings.includes(warn)) {
|
||||
// tslint:disable:next-line: no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(warn);
|
||||
warnings.push(warn);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ export default function getMessage<T extends {}>(
|
||||
const res = bundles.reduce((val, bundle) => {
|
||||
const message = bundle.getMessage(key);
|
||||
if (!message && process.env.NODE_ENV !== "production") {
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(`Translation ${key} was not found for ${bundle.locales}`);
|
||||
}
|
||||
if (!args) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { toPairs } from "lodash";
|
||||
|
||||
import { getShortNumberCode, validateFormat } from "./FluentShortNumber";
|
||||
|
||||
describe("getShortNumberCode", () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { FluentBundle, FluentNumber, FluentType } from "fluent/compat";
|
||||
|
||||
const formatRegExp = /^(0+|0+\.0+)[^\d\.]+$/;
|
||||
const formatRegExp = /^(0+|0+\.0+)[^\d.]+$/;
|
||||
|
||||
export function validateFormat(fmt: string) {
|
||||
return formatRegExp.test(fmt);
|
||||
@@ -48,7 +48,7 @@ export default class FluentShortNumber extends FluentNumber {
|
||||
if (!fmt) {
|
||||
const message = `Missing translation key for ${key} for languages ${bundle.locales.toString()}`;
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(message);
|
||||
} else {
|
||||
throw new Error(message);
|
||||
@@ -60,7 +60,7 @@ export default class FluentShortNumber extends FluentNumber {
|
||||
if (!validateFormat(fmt)) {
|
||||
const message = `Invalid Short Number Format ${fmt}`;
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(message);
|
||||
} else {
|
||||
throw new Error(message);
|
||||
|
||||
@@ -52,6 +52,7 @@ export interface ManagedSubscriptionClient {
|
||||
|
||||
/**
|
||||
* Creates a ManagedSubscriptionClient
|
||||
*
|
||||
* @param url url of the graphql live server
|
||||
* @param clientID a clientID that is provided to the graphql live server
|
||||
*/
|
||||
|
||||
@@ -18,7 +18,7 @@ function isCoralError(err: any): err is CoralError {
|
||||
|
||||
export default function extractError(
|
||||
err: CoralError,
|
||||
unknownErrorMessage: string = "Unknown error"
|
||||
unknownErrorMessage = "Unknown error"
|
||||
): Error {
|
||||
if (!isCoralError(err)) {
|
||||
return new UnknownServerError(unknownErrorMessage, err);
|
||||
|
||||
@@ -9,7 +9,7 @@ export class PostMessageService {
|
||||
|
||||
constructor(
|
||||
scope = "coral",
|
||||
origin: string = `${location.protocol}//${location.host}`
|
||||
origin = `${location.protocol}//${location.host}`
|
||||
) {
|
||||
this.origin = origin;
|
||||
this.scope = scope;
|
||||
@@ -17,6 +17,7 @@ export class PostMessageService {
|
||||
|
||||
/**
|
||||
* Send a message over the postMessage API
|
||||
*
|
||||
* @param name string name of the message
|
||||
* @param value string value of the message
|
||||
* @param target Window target window, e.g. window.opener
|
||||
@@ -36,6 +37,7 @@ export class PostMessageService {
|
||||
|
||||
/**
|
||||
* Subscribe to messages
|
||||
*
|
||||
* @param name string Name of the message
|
||||
* @param handler PostMessageHandler
|
||||
*/
|
||||
@@ -43,7 +45,7 @@ export class PostMessageService {
|
||||
const listener = (event: MessageEvent) => {
|
||||
if (!event.origin) {
|
||||
if (process.env.NODE_ENV !== "test") {
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn("empty origin received in postMessage", name);
|
||||
}
|
||||
} else if (event.origin !== this.origin) {
|
||||
|
||||
@@ -10,7 +10,7 @@ type RecordSourceProxy<T> = T extends object
|
||||
? ReadonlyArray<RecordSourceProxy<U>>
|
||||
: T[P] extends ReadonlyArray<infer V>
|
||||
? ReadonlyArray<RecordSourceProxy<V>>
|
||||
: RecordSourceProxy<T[P]>
|
||||
: RecordSourceProxy<T[P]>;
|
||||
}
|
||||
: T;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCallback } from "react";
|
||||
import React, { useCallback } from "react";
|
||||
import { InferableComponentEnhancer } from "recompose";
|
||||
import { Disposable, Environment } from "relay-runtime";
|
||||
|
||||
@@ -75,7 +75,7 @@ export function withSubscription<N extends string, V, R>(
|
||||
return (BaseComponent: React.ComponentType<any>) => {
|
||||
{
|
||||
const sub = useSubscription(subscription);
|
||||
return props => {
|
||||
return function WithSubscription(props) {
|
||||
const finalProps = {
|
||||
...props,
|
||||
[subscription.name]: sub,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { _RefType } from "react-relay";
|
||||
|
||||
export type FragmentKeys<T> = {
|
||||
[P in keyof T]: T[P] extends _RefType<any> | null ? P : never
|
||||
[P in keyof T]: T[P] extends _RefType<any> | null ? P : never;
|
||||
}[keyof T];
|
||||
|
||||
export type FragmentKeysNoLocal<T> = Exclude<FragmentKeys<T>, "local">;
|
||||
|
||||
@@ -18,7 +18,7 @@ export default function useLoadMore(
|
||||
relay.loadMore(count, error => {
|
||||
setIsLoadingMore(false);
|
||||
if (error) {
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
|
||||
import { OmitFragments } from "coral-framework/testHelpers/removeFragmentRefs";
|
||||
import { DeepPartial } from "coral-framework/types";
|
||||
import { _RefType } from "react-relay";
|
||||
|
||||
import { useCoralContext } from "../bootstrap";
|
||||
import { LOCAL_ID, LOCAL_TYPE } from "./localState";
|
||||
@@ -31,6 +30,7 @@ function isAdvancedUpdater(t: LocalUpdater<any>): t is AdvancedUpdater {
|
||||
/**
|
||||
* applySimplified takes selections defined in a fragment, an object
|
||||
* containing data changes and smartly applies it to the record proxy.
|
||||
*
|
||||
* @param record Record Proxy poing to Local Record
|
||||
* @param selections Selections of the fragment
|
||||
* @param data Data you want to set
|
||||
|
||||
@@ -25,7 +25,7 @@ export default function useRefetch<V = Variables>(
|
||||
error => {
|
||||
setRefetching(false);
|
||||
if (error) {
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import {
|
||||
_RefType,
|
||||
createFragmentContainer,
|
||||
FragmentOrRegularProp,
|
||||
GraphQLTaggedNode,
|
||||
} from "react-relay";
|
||||
import { InferableComponentEnhancerWithProps } from "recompose";
|
||||
import { wrapDisplayName } from "recompose";
|
||||
import {
|
||||
InferableComponentEnhancerWithProps,
|
||||
wrapDisplayName,
|
||||
} from "recompose";
|
||||
|
||||
import hideForwardRef from "./hideForwardRef";
|
||||
import { FragmentKeysNoLocal } from "./types";
|
||||
|
||||
@@ -76,6 +76,7 @@ function withLocalStateContainer(
|
||||
const nextState = { data: snapshot.data };
|
||||
// State has not been initialized yet.
|
||||
if (!this.state) {
|
||||
// eslint-disable-next-line react/no-direct-mutation-state
|
||||
this.state = nextState;
|
||||
return;
|
||||
}
|
||||
@@ -86,7 +87,7 @@ function withLocalStateContainer(
|
||||
this.subscription.dispose();
|
||||
}
|
||||
|
||||
public componentWillReceiveProps(next: Props) {
|
||||
public UNSAFE_componentWillReceiveProps(next: Props) {
|
||||
if (this.props.relayEnvironment !== next.relayEnvironment) {
|
||||
this.unsubscribe();
|
||||
this.subscribe(next.relayEnvironment);
|
||||
|
||||
@@ -12,13 +12,13 @@ export default function wrapFetchWithLogger(
|
||||
try {
|
||||
const result = await (fetch as any)(...args);
|
||||
if (options.logResult) {
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(JSON.stringify(result));
|
||||
}
|
||||
return result;
|
||||
} catch (err) {
|
||||
if (!options.muteErrors) {
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err);
|
||||
}
|
||||
throw err;
|
||||
|
||||
@@ -31,7 +31,13 @@ function withRouteConfig<
|
||||
(component as any).routeConfig = {
|
||||
...config,
|
||||
Component: component,
|
||||
render: ({ error, props: data, retry, match, Component }: any) => {
|
||||
render: function WitRouteConfig({
|
||||
error,
|
||||
props: data,
|
||||
retry,
|
||||
match,
|
||||
Component,
|
||||
}: any) {
|
||||
if (config.render) {
|
||||
return config.render({ error, data, retry, match, Component });
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ class InMemoryStorage implements Storage {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
get length() {
|
||||
public get length() {
|
||||
return Object.keys(this.data).length;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class BackedPromisifedStorage implements PromisifiedStorage {
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
get length() {
|
||||
public get length() {
|
||||
return Promise.resolve(this.storage.length);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Child, Parent } from "pym.js";
|
||||
import uuid from "uuid/v1";
|
||||
|
||||
import { PromisifiedStorage } from "./PromisifiedStorage";
|
||||
|
||||
type Pym = Child | Parent;
|
||||
@@ -55,7 +56,7 @@ class PymStorage implements PromisifiedStorage {
|
||||
this.listen();
|
||||
}
|
||||
|
||||
get length() {
|
||||
public get length() {
|
||||
return this.call<number>("length");
|
||||
}
|
||||
public key(n: number) {
|
||||
@@ -78,8 +79,9 @@ class PymStorage implements PromisifiedStorage {
|
||||
/**
|
||||
* Creates a storage that put requests onto pym.
|
||||
* This is the counterpart of `connectStorageToPym`.
|
||||
*
|
||||
* @param {string} pym pym
|
||||
* @return {Object} storage
|
||||
* @returns {object} storage
|
||||
*/
|
||||
export default function createPymStorage(
|
||||
pym: Pym,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import sinon from "sinon";
|
||||
|
||||
import createInMemoryStorage from "./InMemoryStorage";
|
||||
import prefixStorage from "./prefixStorage";
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class PrefixedStorage implements Storage {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
get length() {
|
||||
public get length() {
|
||||
let count = 0;
|
||||
for (let i = 0; i < this.storage.length; i++) {
|
||||
const key = this.storage.key(i);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import { CoralContext } from "coral-framework/lib/bootstrap";
|
||||
import { createMutationContainer } from "coral-framework/lib/relay";
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import signOut from "../rest/signOut";
|
||||
import SetAccessTokenMutation from "./SetAccessTokenMutation";
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
* This should be generated by `graphql-schema-typescript`.
|
||||
*/
|
||||
|
||||
import { RelayEnumLiteral } from "../types";
|
||||
import {
|
||||
GQLCOMMENT_FLAG_DETECTED_REASON,
|
||||
GQLCOMMENT_FLAG_REASON,
|
||||
@@ -18,6 +17,8 @@ import {
|
||||
GQLUSER_STATUS,
|
||||
} from "./__generated__/types";
|
||||
|
||||
import { RelayEnumLiteral } from "../types";
|
||||
|
||||
export type GQLMODERATION_QUEUE_RL = RelayEnumLiteral<
|
||||
typeof GQLMODERATION_QUEUE
|
||||
>;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { withContext } from "coral-framework/lib/bootstrap";
|
||||
import { Location, Match, Router, withRouter } from "found";
|
||||
import React, { useEffect } from "react";
|
||||
|
||||
import { withContext } from "coral-framework/lib/bootstrap";
|
||||
|
||||
interface Props {
|
||||
/** router is injected by `withRouter` HOC */
|
||||
router: Router;
|
||||
|
||||
@@ -77,7 +77,7 @@ export function queryAllByLabelText(
|
||||
x.props["aria-labelledby"] === i.props.id
|
||||
)
|
||||
);
|
||||
} catch {} // tslint:disable-line:no-empty
|
||||
} catch {} // eslint-disable-line no-empty
|
||||
}
|
||||
});
|
||||
// Find matching labels.
|
||||
@@ -90,7 +90,7 @@ export function queryAllByLabelText(
|
||||
x => typeof x.type === "string" && x.props.id === i.props.htmlFor
|
||||
)
|
||||
);
|
||||
} catch {} // tslint:disable-line:no-empty
|
||||
} catch {} // eslint-disable-line no-empty
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -7,6 +7,7 @@ import matchText, { TextMatchOptions, TextMatchPattern } from "./matchText";
|
||||
/**
|
||||
* Turns list of children of a dom element into a string.
|
||||
* This will also handle React Fragments.
|
||||
*
|
||||
* @param children list of children
|
||||
*/
|
||||
const childrenToString = (children: ReactTestInstance["children"]) => {
|
||||
|
||||
@@ -12,14 +12,14 @@ export type Callbackify<T> = T extends object
|
||||
? Array<Callbackify<U>>
|
||||
: T[P] extends (ReadonlyArray<infer V> | undefined)
|
||||
? ReadonlyArray<Callbackify<V>>
|
||||
: Callbackify<T[P]>
|
||||
: Callbackify<T[P]>;
|
||||
}
|
||||
| (() => {
|
||||
[P in keyof T]: T[P] extends (Array<infer U> | undefined)
|
||||
? Array<Callbackify<U>>
|
||||
: T[P] extends (ReadonlyArray<infer V> | undefined)
|
||||
? ReadonlyArray<Callbackify<V>>
|
||||
: Callbackify<T[P]>
|
||||
: Callbackify<T[P]>;
|
||||
})
|
||||
: T | (() => T);
|
||||
|
||||
@@ -32,7 +32,7 @@ export type WithTypename<T> = T extends object
|
||||
? Array<WithTypename<U>>
|
||||
: T[P] extends (ReadonlyArray<infer V> | undefined)
|
||||
? ReadonlyArray<WithTypename<V>>
|
||||
: WithTypename<T[P]>
|
||||
: WithTypename<T[P]>;
|
||||
} & { __typename?: string }
|
||||
: T;
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import "fluent-intl-polyfill/compat";
|
||||
import { FluentBundle } from "fluent/compat";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
import * as functions from "coral-framework/lib/i18n/functions";
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import "fluent-intl-polyfill/compat";
|
||||
|
||||
// These locale prefixes are always loaded.
|
||||
const commonPrefixes = ["ui", "common", "framework"];
|
||||
@@ -17,7 +17,7 @@ function decorateErrorWhenMissing(bundle: FluentBundle) {
|
||||
const result = originalHasMessage.apply(bundle, [id]);
|
||||
if (!result) {
|
||||
const msg = `${bundle.locales} translation for key "${id}" not found`;
|
||||
// tslint:disable-next-line:no-console
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(msg);
|
||||
missing.push(id);
|
||||
}
|
||||
@@ -26,7 +26,7 @@ function decorateErrorWhenMissing(bundle: FluentBundle) {
|
||||
return true;
|
||||
};
|
||||
bundle.getMessage = (id: string) => {
|
||||
if (missing.indexOf(id) !== -1) {
|
||||
if (missing.includes(id)) {
|
||||
return `Missing translation "${id}"`;
|
||||
}
|
||||
return originalGetMessage.apply(bundle, [id]);
|
||||
@@ -47,6 +47,7 @@ function createFluentBundle(
|
||||
files.forEach(f => {
|
||||
prefixes.forEach(prefix => {
|
||||
if (f.startsWith(prefix)) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
bundle.addMessages(require(path.resolve(pathToLocale, f)));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Omit } from "coral-framework/types";
|
||||
import { identity, omit } from "lodash";
|
||||
import sinon from "sinon";
|
||||
|
||||
import { Omit } from "coral-framework/types";
|
||||
|
||||
import { Fixture } from "./createFixture";
|
||||
import { Resolver } from "./createTestRenderer";
|
||||
|
||||
@@ -38,7 +39,7 @@ export default function createMutationResolverStub<
|
||||
expectAndFail(clientMutationId).toBeTruthy();
|
||||
expectAndFail(lastClientMutationIds).not.toContain(clientMutationId);
|
||||
lastClientMutationIds.push(clientMutationId);
|
||||
const result = await callback({
|
||||
const result = callback({
|
||||
variables: omit(data.input, "clientMutationId"),
|
||||
callCount: callCount++,
|
||||
typecheck: identity,
|
||||
|
||||
@@ -11,6 +11,11 @@ import {
|
||||
Store,
|
||||
} from "relay-runtime";
|
||||
|
||||
import { loadSchema } from "coral-common/graphql";
|
||||
import {
|
||||
InvalidRequestError,
|
||||
ModerationNudgeError,
|
||||
} from "coral-framework/lib/errors";
|
||||
import {
|
||||
createAndRetain,
|
||||
LOCAL_ID,
|
||||
@@ -18,12 +23,6 @@ import {
|
||||
wrapFetchWithLogger,
|
||||
} from "coral-framework/lib/relay";
|
||||
|
||||
import { loadSchema } from "coral-common/graphql";
|
||||
import {
|
||||
InvalidRequestError,
|
||||
ModerationNudgeError,
|
||||
} from "coral-framework/lib/errors";
|
||||
|
||||
import { SubscriptionHandler } from "./createSubscriptionHandler";
|
||||
|
||||
export interface CreateRelayEnvironmentNetworkParams {
|
||||
@@ -180,7 +179,7 @@ export default function createRelayEnvironment(
|
||||
);
|
||||
root.setLinkedRecord(localRecord, "local");
|
||||
if (typeof params.initLocalState === "function") {
|
||||
params.initLocalState!(localRecord, sourceProxy, environment);
|
||||
params.initLocalState(localRecord, sourceProxy, environment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -13,12 +13,12 @@ export interface ResolversTemplate<T extends Resolvers = any> {
|
||||
Query?: {
|
||||
[P in keyof Required<T>["Query"]]: QueryResolverCallback<
|
||||
Required<T>["Query"][P]
|
||||
>
|
||||
>;
|
||||
};
|
||||
Mutation?: {
|
||||
[P in keyof Required<T>["Mutation"]]: MutationResolverCallback<
|
||||
Required<T>["Mutation"][P]
|
||||
>
|
||||
>;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { GQLSubscription } from "coral-framework/schema";
|
||||
|
||||
import { DeepPartial } from "coral-framework/types";
|
||||
|
||||
export type SubscriptionVariables<
|
||||
@@ -42,6 +41,7 @@ export interface SubscriptionHandlerReadOnly {
|
||||
* dispatch will look for subscriptions of the field `field` and
|
||||
* calls the `callback` for each of them. If `callback` returns data,
|
||||
* it'll be dispatched to that subscription.
|
||||
*
|
||||
* @param field name of subscription field to look for.
|
||||
* @param callback callback is called for every subscription on this field.
|
||||
*/
|
||||
@@ -70,7 +70,7 @@ export default function createSubscriptionHandler(): SubscriptionHandler {
|
||||
dispatch: (field, callback) => {
|
||||
subscriptions.forEach(s => {
|
||||
if (s.field === field) {
|
||||
const data = callback(s.variables as any);
|
||||
const data = callback(s.variables);
|
||||
if (data) {
|
||||
s.dispatch(data);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import path from "path";
|
||||
import React from "react";
|
||||
import TestRenderer, { ReactTestRenderer } from "react-test-renderer";
|
||||
import { Environment, RecordProxy, RecordSourceProxy } from "relay-runtime";
|
||||
import sinon from "sinon";
|
||||
|
||||
import { RequireProperty } from "coral-common/types";
|
||||
import {
|
||||
@@ -16,7 +17,6 @@ import { RestClient } from "coral-framework/lib/rest";
|
||||
import { createPromisifiedStorage } from "coral-framework/lib/storage";
|
||||
import { createUUIDGenerator } from "coral-framework/testHelpers";
|
||||
|
||||
import sinon from "sinon";
|
||||
import createFluentBundle from "./createFluentBundle";
|
||||
import createRelayEnvironment from "./createRelayEnvironment";
|
||||
import createSubscriptionHandler, {
|
||||
|
||||
@@ -4,7 +4,7 @@ import createQueryResolverStub, {
|
||||
import { Resolver, Resolvers, TestResolvers } from "./createTestRenderer";
|
||||
|
||||
type ValueOrCallbackRecursive<T> = {
|
||||
[P in keyof T]?: ValueOrCallbackRecursive<T[P]> | (() => void)
|
||||
[P in keyof T]?: ValueOrCallbackRecursive<T[P]> | (() => void);
|
||||
};
|
||||
|
||||
type ResolverResult<T extends Resolver<any, any>> = T extends Resolver<
|
||||
@@ -17,7 +17,7 @@ type ResolverResult<T extends Resolver<any, any>> = T extends Resolver<
|
||||
type OverwriteQueryResolverTemplate<T extends Resolvers = any> = {
|
||||
[P in keyof Required<T>["Query"]]: ValueOrCallbackRecursive<
|
||||
ResolverResult<Required<T>["Query"][P]>
|
||||
>
|
||||
>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -47,7 +47,7 @@ function overwriteRecursive(original: any, overwrite: any) {
|
||||
if (typeof overwrite[k] === "function") {
|
||||
// Resolve overwrite resolver and return it's value
|
||||
// or if undefined the original resolved value.
|
||||
const result = (overwrite as any)[k](...args);
|
||||
const result = overwrite[k](...args);
|
||||
return result !== undefined ? result : resolve();
|
||||
}
|
||||
// The overwrite is an Object, so we will recurse into it,
|
||||
@@ -72,6 +72,7 @@ function overwriteRecursive(original: any, overwrite: any) {
|
||||
* but allows you to return `void` which would then fallback to the original resolver.
|
||||
*
|
||||
* Given a `ResolverType` from the Schema it'll provide types as well!.
|
||||
*
|
||||
* @param callback resolver callback
|
||||
*/
|
||||
export function createQueryResolverOverwrite<T extends Resolver<any, any>>(
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ComponentType } from "react";
|
||||
export type OmitFragments<T> = Pick<
|
||||
T,
|
||||
{
|
||||
[P in keyof T]: P extends " $fragmentRefs" | " $refType" ? never : P
|
||||
[P in keyof T]: P extends " $fragmentRefs" | " $refType" ? never : P;
|
||||
}[keyof T]
|
||||
>;
|
||||
|
||||
|
||||
@@ -32,12 +32,12 @@ type RemoveFirstArgument<T, R> = T extends [any, any, any, any?]
|
||||
? Func0<R>
|
||||
: unknown;
|
||||
|
||||
// tslint:disable
|
||||
// @TODO: currently tslint fails to parse this: `...any[]`.
|
||||
function applyContainer<T extends [ReactTestInstance, ...any[]], R>(container: ReactTestInstance, fn: (...args: T) => R): RemoveFirstArgument<T, R> {
|
||||
return ((...args: any[]) => fn(...[container, ...args] as any)) as any;
|
||||
function applyContainer<T extends [ReactTestInstance, ...any[]], R>(
|
||||
container: ReactTestInstance,
|
||||
fn: (...args: T) => R
|
||||
): RemoveFirstArgument<T, R> {
|
||||
return ((...args: any[]) => fn(...([container, ...args] as any))) as any;
|
||||
}
|
||||
// tslint:enable
|
||||
|
||||
export default function within(container: ReactTestInstance) {
|
||||
return {
|
||||
|
||||
@@ -6,7 +6,7 @@ export default function buildURL({
|
||||
search = window.location.search,
|
||||
hash = window.location.hash,
|
||||
} = {}) {
|
||||
if (search && search[0] !== "?") {
|
||||
if (search && !search.startsWith("?")) {
|
||||
search = `?${search}`;
|
||||
} else if (search === "?") {
|
||||
search = "";
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/**
|
||||
* Initiate a jsonp request.
|
||||
* @argument endpoint jsonp endpoint
|
||||
* @argument callback name of global callback to receive response
|
||||
* @argument args args to send along the jsonp request.
|
||||
*
|
||||
* @param endpoint jsonp endpoint
|
||||
* @param callback name of global callback to receive response
|
||||
* @param args args to send along the jsonp request.
|
||||
*/
|
||||
function jsonp(
|
||||
endpoint: string,
|
||||
|
||||
@@ -4,7 +4,7 @@ export default function parseQueryHash(
|
||||
hash: string
|
||||
): Record<string, string | undefined> {
|
||||
let normalized = hash;
|
||||
if (normalized[0] === "#") {
|
||||
if (normalized.startsWith("#")) {
|
||||
normalized = normalized.substr(1);
|
||||
}
|
||||
return parseQuery(normalized);
|
||||
|
||||
Reference in New Issue
Block a user