Prettier (#852)
* add prettier * lint-staged * prettier * upgrade husky
This commit is contained in:
@@ -1,2 +1,2 @@
|
||||
export const defaultCover =
|
||||
"https://github.com/LNReader/lnreader-sources/blob/main/icons/src/coverNotAvailable.jpg?raw=true";
|
||||
'https://github.com/LNReader/lnreader-sources/blob/main/icons/src/coverNotAvailable.jpg?raw=true';
|
||||
|
||||
+116
-109
@@ -1,53 +1,53 @@
|
||||
import { parse as parseProto } from 'protobufjs';
|
||||
|
||||
type FetchInit = {
|
||||
headers?: Record<string, string | undefined> | Headers;
|
||||
method?: string;
|
||||
body?: FormData | string;
|
||||
[x: string]:
|
||||
| string
|
||||
| Record<string, string | undefined>
|
||||
| undefined
|
||||
| FormData
|
||||
| Headers;
|
||||
headers?: Record<string, string | undefined> | Headers;
|
||||
method?: string;
|
||||
body?: FormData | string;
|
||||
[x: string]:
|
||||
| string
|
||||
| Record<string, string | undefined>
|
||||
| undefined
|
||||
| FormData
|
||||
| Headers;
|
||||
};
|
||||
|
||||
const makeInit = async (init?: FetchInit) => {
|
||||
let defaultHeaders: Record<string, string> = {
|
||||
'Connection': 'keep-alive',
|
||||
'Accept': '*/*',
|
||||
'Accept-Language': '*',
|
||||
'Sec-Fetch-Mode': 'cors',
|
||||
'Accept-Encoding': 'gzip, deflate',
|
||||
'Cache-Control': 'max-age=0',
|
||||
let defaultHeaders: Record<string, string> = {
|
||||
'Connection': 'keep-alive',
|
||||
'Accept': '*/*',
|
||||
'Accept-Language': '*',
|
||||
'Sec-Fetch-Mode': 'cors',
|
||||
'Accept-Encoding': 'gzip, deflate',
|
||||
'Cache-Control': 'max-age=0',
|
||||
};
|
||||
try {
|
||||
const { getHeaders } = await import('../index.js');
|
||||
defaultHeaders = {
|
||||
...defaultHeaders,
|
||||
...getHeaders(),
|
||||
};
|
||||
try {
|
||||
const { getHeaders } = await import("../index.js");
|
||||
defaultHeaders = {
|
||||
...defaultHeaders,
|
||||
...getHeaders()
|
||||
};
|
||||
} catch {
|
||||
// nothing to do
|
||||
}
|
||||
if (init?.headers) {
|
||||
if (init.headers instanceof Headers) {
|
||||
for (const [name, value] of Object.entries(defaultHeaders)) {
|
||||
if (!init.headers.get(name)) init.headers.set(name, value);
|
||||
}
|
||||
} else {
|
||||
init.headers = {
|
||||
...defaultHeaders,
|
||||
...init.headers,
|
||||
};
|
||||
}
|
||||
} catch {
|
||||
// nothing to do
|
||||
}
|
||||
if (init?.headers) {
|
||||
if (init.headers instanceof Headers) {
|
||||
for (const [name, value] of Object.entries(defaultHeaders)) {
|
||||
if (!init.headers.get(name)) init.headers.set(name, value);
|
||||
}
|
||||
} else {
|
||||
init = {
|
||||
...init,
|
||||
headers: defaultHeaders,
|
||||
};
|
||||
init.headers = {
|
||||
...defaultHeaders,
|
||||
...init.headers,
|
||||
};
|
||||
}
|
||||
return init;
|
||||
} else {
|
||||
init = {
|
||||
...init,
|
||||
headers: defaultHeaders,
|
||||
};
|
||||
}
|
||||
return init;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -57,10 +57,10 @@ const makeInit = async (init?: FetchInit) => {
|
||||
* @returns response as normal fetch
|
||||
*/
|
||||
export async function fetchApi(url: string, init?: FetchInit) {
|
||||
init = await makeInit(init);
|
||||
// console.log(init.headers);
|
||||
// console.log(url, init);
|
||||
return await fetch(url, init as RequestInit);
|
||||
init = await makeInit(init);
|
||||
// console.log(init.headers);
|
||||
// console.log(url, init);
|
||||
return await fetch(url, init as RequestInit);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,16 +71,16 @@ export async function fetchApi(url: string, init?: FetchInit) {
|
||||
* @example fetchFile('https://avatars.githubusercontent.com/u/81222734?s=48&v=4');
|
||||
*/
|
||||
export const fetchFile = async function (url: string, init?: FetchInit) {
|
||||
init = await makeInit(init);
|
||||
console.log(url, init);
|
||||
try {
|
||||
const res = await fetch(url, init as RequestInit);
|
||||
if (!res.ok) return "";
|
||||
const arrayBuffer = await res.arrayBuffer();
|
||||
return Buffer.from(arrayBuffer).toString("base64");
|
||||
} catch (e) {
|
||||
return "";
|
||||
}
|
||||
init = await makeInit(init);
|
||||
console.log(url, init);
|
||||
try {
|
||||
const res = await fetch(url, init as RequestInit);
|
||||
if (!res.ok) return '';
|
||||
const arrayBuffer = await res.arrayBuffer();
|
||||
return Buffer.from(arrayBuffer).toString('base64');
|
||||
} catch (e) {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -92,67 +92,74 @@ export const fetchFile = async function (url: string, init?: FetchInit) {
|
||||
* @example fetchText('https://github.com/LNReader/lnreader', {}, 'gbk');
|
||||
*/
|
||||
export const fetchText = async function (
|
||||
url: string,
|
||||
init?: FetchInit,
|
||||
encoding?: string
|
||||
url: string,
|
||||
init?: FetchInit,
|
||||
encoding?: string,
|
||||
): Promise<string> {
|
||||
init = await makeInit(init);
|
||||
console.log(url, init);
|
||||
try {
|
||||
const res = await fetch(url, init as RequestInit);
|
||||
if (!res.ok) return "";
|
||||
const arrayBuffer = await res.arrayBuffer();
|
||||
const decoder = new TextDecoder(encoding);
|
||||
return decoder.decode(arrayBuffer);
|
||||
} catch (e) {
|
||||
return "";
|
||||
}
|
||||
init = await makeInit(init);
|
||||
console.log(url, init);
|
||||
try {
|
||||
const res = await fetch(url, init as RequestInit);
|
||||
if (!res.ok) return '';
|
||||
const arrayBuffer = await res.arrayBuffer();
|
||||
const decoder = new TextDecoder(encoding);
|
||||
return decoder.decode(arrayBuffer);
|
||||
} catch (e) {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
interface ProtoRequestInit {
|
||||
// merged .proto file
|
||||
proto: string;
|
||||
requestType: string;
|
||||
requestData?: any;
|
||||
responseType: string;
|
||||
// merged .proto file
|
||||
proto: string;
|
||||
requestType: string;
|
||||
requestData?: any;
|
||||
responseType: string;
|
||||
}
|
||||
|
||||
const BYTE_MARK = BigInt((1 << 8) - 1);
|
||||
|
||||
export const fetchProto = async function<ReturnType> (
|
||||
protoInit: ProtoRequestInit,
|
||||
url: string,
|
||||
init?: FetchInit,
|
||||
export const fetchProto = async function <ReturnType>(
|
||||
protoInit: ProtoRequestInit,
|
||||
url: string,
|
||||
init?: FetchInit,
|
||||
) {
|
||||
const protoRoot = parseProto(protoInit.proto).root;
|
||||
const RequestMessge = protoRoot.lookupType(protoInit.requestType);
|
||||
if (RequestMessge.verify(protoInit.requestData)){
|
||||
throw new Error('Invalid Proto');
|
||||
}
|
||||
// encode request data
|
||||
const encodedrequest = RequestMessge.encode(protoInit.requestData).finish();
|
||||
const requestLength = BigInt(encodedrequest.length);
|
||||
const headers = new Uint8Array(
|
||||
Array(5).fill(0).map((v, idx) => {
|
||||
if(idx === 0) return 0;
|
||||
return Number((requestLength >> BigInt(8 * (5 - idx - 1))) & BYTE_MARK);
|
||||
})
|
||||
);
|
||||
init = await makeInit(init);
|
||||
const bodyArray = new Uint8Array(headers.length + encodedrequest.length)
|
||||
bodyArray.set(headers, 0)
|
||||
bodyArray.set(encodedrequest, headers.length)
|
||||
return fetch(url, {
|
||||
method: 'POST',
|
||||
...init,
|
||||
body: bodyArray
|
||||
} as RequestInit
|
||||
).then(r => r.arrayBuffer())
|
||||
const protoRoot = parseProto(protoInit.proto).root;
|
||||
const RequestMessge = protoRoot.lookupType(protoInit.requestType);
|
||||
if (RequestMessge.verify(protoInit.requestData)) {
|
||||
throw new Error('Invalid Proto');
|
||||
}
|
||||
// encode request data
|
||||
const encodedrequest = RequestMessge.encode(protoInit.requestData).finish();
|
||||
const requestLength = BigInt(encodedrequest.length);
|
||||
const headers = new Uint8Array(
|
||||
Array(5)
|
||||
.fill(0)
|
||||
.map((v, idx) => {
|
||||
if (idx === 0) return 0;
|
||||
return Number((requestLength >> BigInt(8 * (5 - idx - 1))) & BYTE_MARK);
|
||||
}),
|
||||
);
|
||||
init = await makeInit(init);
|
||||
const bodyArray = new Uint8Array(headers.length + encodedrequest.length);
|
||||
bodyArray.set(headers, 0);
|
||||
bodyArray.set(encodedrequest, headers.length);
|
||||
return fetch(url, {
|
||||
method: 'POST',
|
||||
...init,
|
||||
body: bodyArray,
|
||||
} as RequestInit)
|
||||
.then(r => r.arrayBuffer())
|
||||
.then(arr => {
|
||||
// decode response data
|
||||
const payload = new Uint8Array(arr);
|
||||
const length = Number(BigInt(payload[1] << 24) | BigInt(payload[2] << 16) | BigInt(payload[3] << 8) | BigInt(payload[4]));
|
||||
const ResponseMessage = protoRoot.lookupType(protoInit.responseType);
|
||||
return ResponseMessage.decode(payload.slice(5, 5 + length));
|
||||
}) as ReturnType
|
||||
}
|
||||
// decode response data
|
||||
const payload = new Uint8Array(arr);
|
||||
const length = Number(
|
||||
BigInt(payload[1] << 24) |
|
||||
BigInt(payload[2] << 16) |
|
||||
BigInt(payload[3] << 8) |
|
||||
BigInt(payload[4]),
|
||||
);
|
||||
const ResponseMessage = protoRoot.lookupType(protoInit.responseType);
|
||||
return ResponseMessage.decode(payload.slice(5, 5 + length));
|
||||
}) as ReturnType;
|
||||
};
|
||||
|
||||
+50
-50
@@ -1,78 +1,78 @@
|
||||
export interface FilterOption {
|
||||
readonly label: string;
|
||||
readonly value: string;
|
||||
readonly label: string;
|
||||
readonly value: string;
|
||||
}
|
||||
|
||||
export enum FilterTypes {
|
||||
TextInput = "Text",
|
||||
Picker = "Picker",
|
||||
CheckboxGroup = "Checkbox",
|
||||
Switch = "Switch",
|
||||
ExcludableCheckboxGroup = "XCheckbox",
|
||||
TextInput = 'Text',
|
||||
Picker = 'Picker',
|
||||
CheckboxGroup = 'Checkbox',
|
||||
Switch = 'Switch',
|
||||
ExcludableCheckboxGroup = 'XCheckbox',
|
||||
}
|
||||
|
||||
type SwitchFilter = {
|
||||
type: FilterTypes.Switch;
|
||||
/** Default value */
|
||||
value: boolean;
|
||||
type: FilterTypes.Switch;
|
||||
/** Default value */
|
||||
value: boolean;
|
||||
};
|
||||
|
||||
type TextFilter = {
|
||||
type: FilterTypes.TextInput;
|
||||
/** Default value */
|
||||
value: string;
|
||||
type: FilterTypes.TextInput;
|
||||
/** Default value */
|
||||
value: string;
|
||||
};
|
||||
|
||||
type CheckboxFilter = {
|
||||
type: FilterTypes.CheckboxGroup;
|
||||
options: readonly FilterOption[];
|
||||
/** Default value */
|
||||
value: string[];
|
||||
type: FilterTypes.CheckboxGroup;
|
||||
options: readonly FilterOption[];
|
||||
/** Default value */
|
||||
value: string[];
|
||||
};
|
||||
type PickerFilter = {
|
||||
type: FilterTypes.Picker;
|
||||
options: readonly FilterOption[];
|
||||
/** Default value */
|
||||
value: string;
|
||||
type: FilterTypes.Picker;
|
||||
options: readonly FilterOption[];
|
||||
/** Default value */
|
||||
value: string;
|
||||
};
|
||||
|
||||
type ExcludableCheckboxFilter = {
|
||||
type: FilterTypes.ExcludableCheckboxGroup;
|
||||
options: readonly FilterOption[];
|
||||
value: { include?: string[]; exclude?: string[] };
|
||||
type: FilterTypes.ExcludableCheckboxGroup;
|
||||
options: readonly FilterOption[];
|
||||
value: { include?: string[]; exclude?: string[] };
|
||||
};
|
||||
|
||||
export type Filters = Record<
|
||||
string,
|
||||
| { label: string } & (
|
||||
| PickerFilter
|
||||
| CheckboxFilter
|
||||
| TextFilter
|
||||
| SwitchFilter
|
||||
| ExcludableCheckboxFilter
|
||||
)
|
||||
string,
|
||||
{ label: string } & (
|
||||
| PickerFilter
|
||||
| CheckboxFilter
|
||||
| TextFilter
|
||||
| SwitchFilter
|
||||
| ExcludableCheckboxFilter
|
||||
)
|
||||
>;
|
||||
|
||||
export type FilterToValues<
|
||||
T extends Record<string, { type: FilterTypes }> | undefined
|
||||
T extends Record<string, { type: FilterTypes }> | undefined,
|
||||
> = T extends undefined
|
||||
? undefined
|
||||
: {
|
||||
[K in keyof T]: Omit<
|
||||
{ type: NonNullable<T>[K]["type"] } & Filters[string],
|
||||
"label" | "options"
|
||||
>;
|
||||
};
|
||||
? undefined
|
||||
: {
|
||||
[K in keyof T]: Omit<
|
||||
{ type: NonNullable<T>[K]['type'] } & Filters[string],
|
||||
'label' | 'options'
|
||||
>;
|
||||
};
|
||||
|
||||
export type ValueOfFilter<T extends FilterTypes> =
|
||||
T extends FilterTypes.CheckboxGroup
|
||||
? CheckboxFilter["value"]
|
||||
: T extends FilterTypes.Picker
|
||||
? PickerFilter["value"]
|
||||
: T extends FilterTypes.Switch
|
||||
? SwitchFilter["value"]
|
||||
T extends FilterTypes.CheckboxGroup
|
||||
? CheckboxFilter['value']
|
||||
: T extends FilterTypes.Picker
|
||||
? PickerFilter['value']
|
||||
: T extends FilterTypes.Switch
|
||||
? SwitchFilter['value']
|
||||
: T extends FilterTypes.TextInput
|
||||
? TextFilter["value"]
|
||||
: T extends FilterTypes.ExcludableCheckboxGroup
|
||||
? ExcludableCheckboxFilter["value"]
|
||||
: never;
|
||||
? TextFilter['value']
|
||||
: T extends FilterTypes.ExcludableCheckboxGroup
|
||||
? ExcludableCheckboxFilter['value']
|
||||
: never;
|
||||
|
||||
+21
-21
@@ -1,23 +1,23 @@
|
||||
export const isUrlAbsolute = (url: string) => {
|
||||
if (url) {
|
||||
if (url.indexOf("//") === 0) {
|
||||
return true;
|
||||
} // URL is protocol-relative (= absolute)
|
||||
if (url.indexOf("://") === -1) {
|
||||
return false;
|
||||
} // URL has no protocol (= relative)
|
||||
if (url.indexOf(".") === -1) {
|
||||
return false;
|
||||
} // URL does not contain a dot, i.e. no TLD (= relative, possibly REST)
|
||||
if (url.indexOf("/") === -1) {
|
||||
return false;
|
||||
} // URL does not contain a single slash (= relative)
|
||||
if (url.indexOf(":") > url.indexOf("/")) {
|
||||
return false;
|
||||
} // The first colon comes after the first slash (= relative)
|
||||
if (url.indexOf("://") < url.indexOf(".")) {
|
||||
return true;
|
||||
} // Protocol is defined before first dot (= absolute)
|
||||
}
|
||||
return false; // Anything else must be relative
|
||||
if (url) {
|
||||
if (url.indexOf('//') === 0) {
|
||||
return true;
|
||||
} // URL is protocol-relative (= absolute)
|
||||
if (url.indexOf('://') === -1) {
|
||||
return false;
|
||||
} // URL has no protocol (= relative)
|
||||
if (url.indexOf('.') === -1) {
|
||||
return false;
|
||||
} // URL does not contain a dot, i.e. no TLD (= relative, possibly REST)
|
||||
if (url.indexOf('/') === -1) {
|
||||
return false;
|
||||
} // URL does not contain a single slash (= relative)
|
||||
if (url.indexOf(':') > url.indexOf('/')) {
|
||||
return false;
|
||||
} // The first colon comes after the first slash (= relative)
|
||||
if (url.indexOf('://') < url.indexOf('.')) {
|
||||
return true;
|
||||
} // Protocol is defined before first dot (= absolute)
|
||||
}
|
||||
return false; // Anything else must be relative
|
||||
};
|
||||
|
||||
+15
-15
@@ -1,17 +1,17 @@
|
||||
export const languages = {
|
||||
Arabic: "العربية",
|
||||
Chinese: "中文, 汉语, 漢語",
|
||||
English: "English",
|
||||
French: "Français",
|
||||
Indonesian: "Bahasa Indonesia",
|
||||
Japanese: "日本語",
|
||||
Korean: "조선말, 한국어",
|
||||
Polish: "Polski",
|
||||
Portuguese: "Português",
|
||||
Russian: "Русский",
|
||||
Spanish: "Español",
|
||||
Thai: "ไทย",
|
||||
Turkish: "Türkçe",
|
||||
Ukrainian: "Українська",
|
||||
Vietnamese: "Tiếng Việt",
|
||||
Arabic: 'العربية',
|
||||
Chinese: '中文, 汉语, 漢語',
|
||||
English: 'English',
|
||||
French: 'Français',
|
||||
Indonesian: 'Bahasa Indonesia',
|
||||
Japanese: '日本語',
|
||||
Korean: '조선말, 한국어',
|
||||
Polish: 'Polski',
|
||||
Portuguese: 'Português',
|
||||
Russian: 'Русский',
|
||||
Spanish: 'Español',
|
||||
Thai: 'ไทย',
|
||||
Turkish: 'Türkçe',
|
||||
Ukrainian: 'Українська',
|
||||
Vietnamese: 'Tiếng Việt',
|
||||
} as const;
|
||||
|
||||
+8
-8
@@ -1,9 +1,9 @@
|
||||
export const NovelStatus = {
|
||||
Unknown: "Unknown",
|
||||
Ongoing: "Ongoing",
|
||||
Completed: "Completed",
|
||||
Licensed: "Licensed",
|
||||
PublishingFinished: "Publishing Finished",
|
||||
Cancelled: "Cancelled",
|
||||
OnHiatus: "On Hiatus",
|
||||
} as const;
|
||||
Unknown: 'Unknown',
|
||||
Ongoing: 'Ongoing',
|
||||
Completed: 'Completed',
|
||||
Licensed: 'Licensed',
|
||||
PublishingFinished: 'Publishing Finished',
|
||||
Cancelled: 'Cancelled',
|
||||
OnHiatus: 'On Hiatus',
|
||||
} as const;
|
||||
|
||||
Reference in New Issue
Block a user