feat: align auth api with front convention (#370)

* feat: align auth api with front convention

* fix: email password auth

* fix: proper file naming

* Fix login

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Jérémy M
2023-06-24 07:43:54 +02:00
committed by GitHub
parent c6708b2c1f
commit 31145c5518
23 changed files with 222 additions and 293 deletions

View File

@ -0,0 +1,45 @@
import { OperationType } from './operation-type';
const operationTypeColors = {
query: '#03A9F4',
mutation: '#61A600',
subscription: '#61A600',
error: '#F51818',
default: '#61A600',
};
const getOperationColor = (operationType: OperationType) => {
return operationTypeColors[operationType] ?? operationTypeColors.default;
};
const formatTitle = (
operationType: OperationType,
schemaName: string,
queryName: string,
time: string | number,
) => {
const headerCss = [
'color: gray; font-weight: lighter', // title
`color: ${getOperationColor(operationType)}; font-weight: bold;`, // operationType
'color: gray; font-weight: lighter;', // schemaName
'color: black; font-weight: bold;', // queryName
];
const parts = [
'%c apollo',
`%c${operationType}`,
`%c${schemaName}::%c${queryName}`,
];
if (operationType !== OperationType.Subscription) {
parts.push(`%c(in ${time} ms)`);
headerCss.push('color: gray; font-weight: lighter;'); // time
} else {
parts.push(`%c(@ ${time})`);
headerCss.push('color: gray; font-weight: lighter;'); // time
}
return [parts.join(' '), ...headerCss];
};
export default formatTitle;

View File

@ -0,0 +1,102 @@
import { ApolloLink, gql, Operation } from '@apollo/client';
import formatTitle from './format-title';
const getGroup = (collapsed: boolean) =>
collapsed
? console.groupCollapsed.bind(console)
: console.group.bind(console);
const parseQuery = (queryString: string) => {
const queryObj = gql`
${queryString}
`;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { name } = queryObj.definitions[0] as any;
return [name ? name.value : 'Generic', queryString.trim()];
};
export const loggerLink = (getSchemaName: (operation: Operation) => string) =>
new ApolloLink((operation, forward) => {
const schemaName = getSchemaName(operation);
operation.setContext({ start: Date.now() });
const { variables } = operation;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const operationType = (operation.query.definitions[0] as any).operation;
const headers = operation.getContext().headers;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const [queryName, query] = parseQuery(operation.query.loc!.source.body);
if (operationType === 'subscription') {
const date = new Date().toLocaleTimeString();
const titleArgs = formatTitle(operationType, schemaName, queryName, date);
console.groupCollapsed(...titleArgs);
if (variables && Object.keys(variables).length !== 0) {
console.log('VARIABLES', variables);
}
console.log('QUERY', query);
console.groupEnd();
return forward(operation);
}
return forward(operation).map((result) => {
const time = Date.now() - operation.getContext().start;
const errors = result.errors ?? result.data?.[queryName]?.errors;
const hasError = Boolean(errors);
try {
const titleArgs = formatTitle(
operationType,
schemaName,
queryName,
time,
);
getGroup(!hasError)(...titleArgs);
if (errors) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
errors.forEach((err: any) => {
console.log(
`%c${err.message}`,
'color: #F51818; font-weight: lighter',
);
});
}
console.log('HEADERS: ', headers);
if (variables && Object.keys(variables).length !== 0) {
console.log('VARIABLES', variables);
}
console.log('QUERY', query);
if (result.data) {
console.log('RESULT', result.data);
}
if (errors) {
console.log('ERRORS', errors);
}
console.groupEnd();
} catch {
// this may happen if console group is not supported
console.log(
`${operationType} ${schemaName}::${queryName} (in ${time} ms)`,
);
if (errors) {
console.error(errors);
}
}
return result;
});
});

View File

@ -0,0 +1,6 @@
export enum OperationType {
Query = 'query',
Mutation = 'mutation',
Subscription = 'subscription',
Error = 'error',
}

View File

@ -1,12 +1,6 @@
import Cookies, { CookieAttributes } from 'js-cookie';
type Listener = (
newValue: string | undefined,
oldValue: string | undefined,
) => void;
class CookieStorage {
private listeners: Record<string, Listener[]> = {};
private keys: Set<string> = new Set();
getItem(key: string): string | undefined {
@ -14,49 +8,18 @@ class CookieStorage {
}
setItem(key: string, value: string, attributes?: CookieAttributes): void {
const oldValue = this.getItem(key);
this.keys.add(key);
Cookies.set(key, value, attributes);
this.dispatch(key, value, oldValue);
}
removeItem(key: string): void {
const oldValue = this.getItem(key);
this.keys.delete(key);
Cookies.remove(key);
this.dispatch(key, undefined, oldValue);
}
clear(): void {
this.keys.forEach((key) => this.removeItem(key));
}
private dispatch(
key: string,
newValue: string | undefined,
oldValue: string | undefined,
): void {
if (this.listeners[key]) {
this.listeners[key].forEach((callback) => callback(newValue, oldValue));
}
}
addEventListener(key: string, callback: Listener): void {
if (!this.listeners[key]) {
this.listeners[key] = [];
}
this.listeners[key].push(callback);
}
removeEventListener(key: string, callback: Listener): void {
if (this.listeners[key]) {
this.listeners[key] = this.listeners[key].filter(
(listener) => listener !== callback,
);
}
}
}
export const cookieStorage = new CookieStorage();