* add prettier

* lint-staged

* prettier

* upgrade husky
This commit is contained in:
nyagami
2024-03-23 22:00:29 +07:00
committed by GitHub
parent c22979b10f
commit 5f9a067ab9
113 changed files with 79244 additions and 50841 deletions
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;