@luminix/support 0.0.1-beta.0 → 0.0.1-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,46 +0,0 @@
1
- import { createNanoEvents, Unsubscribe } from 'nanoevents';
2
-
3
- export type Event<TData = any, TSource extends EventSource = EventSource> = TData & {
4
- source: TSource;
5
- };
6
-
7
- export type EventMap = {
8
- [key: string]: (event: Event) => void
9
- };
10
-
11
-
12
-
13
- export default class EventSource<TEvents extends EventMap = EventMap>
14
- {
15
- private emitter;
16
-
17
- constructor()
18
- {
19
- this.emitter = createNanoEvents<TEvents>();
20
- }
21
-
22
- on<E extends keyof TEvents>(event: E, callback: TEvents[E]): Unsubscribe
23
- {
24
- return this.emitter.on(event, callback);
25
- }
26
-
27
- once<E extends keyof TEvents>(event: E, callback: TEvents[E]): void
28
- {
29
- const off = this.emitter.on(event, ((e: Parameters<TEvents[E]>[0]) => {
30
- off();
31
- callback(e);
32
- }) as any);
33
- }
34
-
35
- emit<E extends keyof TEvents>(event: E, ...data: Parameters<TEvents[E]>): void
36
- {
37
- this.emitter.emit(event, ...data);
38
- }
39
-
40
- static foo() {
41
-
42
- return 'bar';
43
- }
44
- }
45
-
46
-
@@ -1,8 +0,0 @@
1
-
2
- export default class ReducerOverrideException extends Error {
3
- [Symbol.toStringTag] = 'ReducerOverrideException';
4
-
5
- constructor(name: string, target: unknown) {
6
- super(`[Luminix] Cannot create reducer '${name}' on '${target}' as it is a reserved property`);
7
- }
8
- }
@@ -1,139 +0,0 @@
1
-
2
- import { AxiosRequestConfig } from 'axios';
3
- import * as Obj from '../Obj';
4
- import Request from './Request';
5
-
6
-
7
- export type RequestOptions = Omit<AxiosRequestConfig, 'url' | 'method'>;
8
-
9
-
10
- export default class Client {
11
-
12
- constructor(
13
- protected options: AxiosRequestConfig = {}
14
- ) {}
15
-
16
- private parseData(data?: object) {
17
- if (Obj.get(this.options, 'headers[Content-Type]', 'application/json') === 'application/x-www-form-urlencoded' && data) {
18
- return Obj.toFormData(data || {});
19
- }
20
-
21
- return data;
22
- }
23
-
24
- baseUrl(baseUrl: string): this {
25
- Obj.set(this.options, 'baseURL', baseUrl);
26
-
27
- return this;
28
- }
29
-
30
- asForm(): this {
31
- Obj.set(this.options, 'headers[Content-Type]', 'application/x-www-form-urlencoded');
32
-
33
- return this;
34
- }
35
-
36
- accept(type: string): this {
37
- Obj.set(this.options, 'headers[Accept]', type);
38
-
39
- return this;
40
- }
41
-
42
- acceptJson(): this {
43
- return this.accept('application/json');
44
- }
45
-
46
- withHeaders(headers: Record<string, string>): this {
47
- Obj.set(this.options, 'headers', Obj.merge(this.options.headers, headers));
48
-
49
- return this;
50
- }
51
-
52
- replaceHeaders(headers: Record<string, string>): this {
53
- Obj.set(this.options, 'headers', headers);
54
-
55
- return this;
56
- }
57
-
58
- withOptions(options: RequestOptions): this {
59
- this.options = Obj.merge(this.options, options);
60
-
61
- return this;
62
- }
63
-
64
- replaceOptions(options: RequestOptions): this {
65
- this.options = options;
66
-
67
- return this;
68
- }
69
-
70
- withQueryParameters(params: string | object): this {
71
- Obj.set(this.options, 'params', Obj.merge(this.options.params, params));
72
-
73
- return this;
74
- }
75
-
76
- replaceQueryParameters(params: string | object): this {
77
- Obj.set(this.options, 'params', params);
78
-
79
- return this;
80
- }
81
-
82
- withBasicAuth(username: string, password: string): this {
83
- Obj.set(this.options, 'headers.Authorization', `Basic ${btoa(`${username}:${password}`)}`);
84
-
85
- return this;
86
- }
87
-
88
- withToken(token: string): this {
89
- Obj.set(this.options, 'headers.Authorization', `Bearer ${token}`);
90
-
91
- return this;
92
- }
93
-
94
- get<TResponse = any>(url: string, query?: string | object) {
95
- return new Request<TResponse>({
96
- ...this.options,
97
- params: query ?? this.options.params,
98
- url,
99
- });
100
- }
101
-
102
- post<TResponse = any, TData = any>(url: string, data?: TData) {
103
- return new Request<TResponse, TData>({
104
- ...this.options,
105
- method: 'post',
106
- url,
107
- data: this.parseData(data ?? this.options.data),
108
- });
109
- }
110
-
111
- put<TResponse = any, TData = any>(url: string, data?: TData) {
112
- return new Request<TResponse, TData>({
113
- ...this.options,
114
- method: 'put',
115
- url,
116
- data: this.parseData(data ?? this.options.data),
117
- });
118
- }
119
-
120
- patch<TResponse = any, TData = any>(url: string, data?: TData) {
121
- return new Request<TResponse, TData>({
122
- ...this.options,
123
- method: 'patch',
124
- url,
125
- data: this.parseData(data ?? this.options.data),
126
- });
127
- }
128
-
129
- delete<TResponse = any>(url: string, query?: string | object) {
130
- return new Request<TResponse>({
131
- ...this.options,
132
- method: 'delete',
133
- params: query ?? this.options.params,
134
- url,
135
- });
136
- }
137
-
138
- };
139
-
@@ -1,45 +0,0 @@
1
- import axios, { AxiosRequestConfig, isAxiosError } from "axios";
2
- import Response from "./Response";
3
-
4
- export default class Request<TResponse = any, TData = any> implements Promise<Response<TResponse, TData>> {
5
-
6
- private promise: Promise<Response<TResponse, TData>>;
7
- private response?: Response<TResponse, TData>;
8
-
9
- constructor(options: AxiosRequestConfig) {
10
- this.promise = new Promise<Response<TResponse, TData>>((resolve, reject) => {
11
- axios(options)
12
- .then((response) => {
13
- this.response = new Response(response);
14
- resolve(this.response);
15
- })
16
- .catch((error) => {
17
- if (isAxiosError(error) && error.response) {
18
- this.response = new Response(error.response, error);
19
- resolve(this.response);
20
- } else {
21
- reject(error);
22
- }
23
- });
24
- });
25
- }
26
-
27
- [Symbol.toStringTag]: string = 'Request';
28
-
29
- then<TResult1 = Response<TResponse, TData>, TResult2 = never>(
30
- onfulfilled?: ((value: Response<TResponse, TData>) => TResult1 | PromiseLike<TResult1>) | null | undefined,
31
- onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined
32
- ): Promise<TResult1 | TResult2> {
33
- return this.promise.then(onfulfilled, onrejected);
34
- }
35
-
36
- catch<TResult = never>(
37
- onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null | undefined
38
- ): Promise<Response<TResponse, TData> | TResult> {
39
- return this.promise.catch(onrejected);
40
- }
41
-
42
- finally(onfinally?: (() => void) | null | undefined): Promise<Response<TResponse, TData>> {
43
- return this.promise.finally(onfinally);
44
- }
45
- }
@@ -1,170 +0,0 @@
1
-
2
- import { AxiosResponse } from 'axios';
3
- import * as Obj from '../Obj';
4
-
5
- export default class Response<TResponse = any, TData = any> {
6
-
7
- constructor(
8
- private response: AxiosResponse<TResponse, TData>,
9
- private error?: Error
10
- ) {
11
-
12
- }
13
-
14
- body(): string {
15
- return typeof this.response.data === 'object'
16
- ? JSON.stringify(this.response.data)
17
- : String(this.response.data);
18
- }
19
-
20
- json(): TResponse;
21
- json<K extends keyof TResponse>(key: K): TResponse[K];
22
- json(key: string, defaultValue?: any): any;
23
- json(key?: string, defaultValue?: any): any {
24
-
25
- if (key) {
26
- return Obj.get(this.response.data, key, defaultValue);
27
- }
28
-
29
- return this.response.data;
30
- }
31
- // collect(key?: string): Collection {}
32
- status(): number {
33
- return Number(this.response.status);
34
- }
35
-
36
- successful(): boolean {
37
- return this.status() >= 200 && this.status() < 300;
38
- }
39
-
40
- redirect(): boolean {
41
- return this.status() >= 300 && this.status() < 400;
42
- }
43
-
44
- clientError(): boolean {
45
- return this.status() >= 400 && this.status() < 500;
46
- }
47
-
48
- serverError(): boolean {
49
- return this.status() >= 500;
50
- }
51
-
52
- failed(): boolean {
53
- return this.clientError() || this.serverError();
54
- }
55
-
56
- header(header: string): string {
57
- return this.response.headers[header];
58
- }
59
-
60
- headers(): Record<string, string> {
61
- return this.response.headers as Record<string, string>;
62
- }
63
-
64
- ok(): boolean {
65
- return this.status() === 200;
66
- }
67
-
68
- created(): boolean {
69
- return this.status() === 201;
70
- }
71
-
72
- accepted(): boolean {
73
- return this.status() === 202;
74
- }
75
-
76
- noContent(): boolean {
77
- return this.status() === 204;
78
- }
79
-
80
- movedPermanently(): boolean {
81
- return this.status() === 301;
82
- }
83
-
84
- found(): boolean {
85
- return this.status() === 302;
86
- }
87
-
88
- badRequest(): boolean {
89
- return this.status() === 400;
90
- }
91
-
92
- unauthorized(): boolean {
93
- return this.status() === 401;
94
- }
95
-
96
- paymentRequired(): boolean {
97
- return this.status() === 402;
98
- }
99
-
100
- forbidden(): boolean {
101
- return this.status() === 403;
102
- }
103
-
104
- notFound(): boolean {
105
- return this.status() === 404;
106
- }
107
-
108
- requestTimeout(): boolean {
109
- return this.status() === 408;
110
- }
111
-
112
- conflict(): boolean {
113
- return this.status() === 409;
114
- }
115
-
116
- unprocessableEntity(): boolean {
117
- return this.status() === 422;
118
- }
119
-
120
- tooManyRequests(): boolean {
121
- return this.status() === 429;
122
- }
123
-
124
- throw(): this {
125
- if (this.failed()) {
126
- throw this.error || new Error(this.body());
127
- }
128
-
129
- return this;
130
- }
131
-
132
- throwIf(condition: boolean | ((response: Response) => boolean)): this {
133
- if (typeof condition === 'function') {
134
- return condition(this) ? this.throw() : this;
135
- }
136
- return condition ? this.throw() : this;
137
- }
138
-
139
- throwUnless(condition: boolean | ((response: Response) => boolean)): this {
140
- if (typeof condition === 'function') {
141
- return condition(this) ? this : this.throw();
142
- }
143
- return condition ? this : this.throw();
144
- }
145
-
146
- throwIfStatus(statusCode: number | ((status: number, response: Response) => boolean)): this {
147
- if (typeof statusCode === 'function' && statusCode(this.status(), this)) {
148
- return this.throw();
149
- }
150
- return this.status() === statusCode ? this.throw() : this;
151
- }
152
-
153
- throwUnlessStatus(statusCode: number | ((status: number, response: Response) => boolean)): this {
154
- if (typeof statusCode === 'function' && !statusCode(this.status(), this)) {
155
- return this.throw();
156
- }
157
- return this.status() === statusCode ? this : this.throw();
158
- }
159
-
160
- throwIfClientError(): this {
161
- return this.clientError() ? this.throw() : this;
162
- }
163
-
164
- throwIfServerError(): this {
165
- return this.serverError() ? this.throw() : this;
166
- }
167
-
168
-
169
- };
170
-
package/src/Http/index.ts DELETED
@@ -1,90 +0,0 @@
1
- import Client, { RequestOptions } from "./Client";
2
- import Response from "./Response";
3
- import Request from "./Request";
4
- import Macroable from "../Mixins/Macroable";
5
-
6
- class HttpStatic {
7
-
8
- get Client() {
9
- return Client;
10
- }
11
-
12
- get Response() {
13
- return Response;
14
- }
15
-
16
- get Request() {
17
- return Request;
18
- }
19
-
20
- getClient(): Client {
21
- return new Client();
22
- }
23
-
24
- baseUrl(baseUrl: string): Client {
25
- return this.getClient().baseUrl(baseUrl);
26
- }
27
-
28
- asForm(): Client {
29
- return this.getClient().asForm();
30
- }
31
-
32
- accept(type: string): Client {
33
- return this.getClient().accept(type);
34
- }
35
-
36
- acceptJson(): Client {
37
- return this.getClient().acceptJson();
38
- }
39
-
40
- withHeaders(headers: Record<string, string>): Client {
41
- return this.getClient().withHeaders(headers);
42
- }
43
-
44
- withOptions(options: RequestOptions): Client {
45
- return this.getClient().withOptions(options);
46
- }
47
-
48
-
49
- withQueryParameters(params: string | object): Client {
50
- return this.getClient().withQueryParameters(params);
51
- }
52
-
53
- withBasicAuth(username: string, password: string): Client {
54
- return this.getClient().withBasicAuth(username, password);
55
- }
56
-
57
- withToken(token: string): Client {
58
- return this.getClient().withToken(token);
59
- }
60
-
61
- get<TResponse = any>(url: string, query?: string | object) {
62
- return this.getClient().get<TResponse>(url, query);
63
- }
64
-
65
-
66
- post<TResponse = any, TData = any>(url: string, data?: TData) {
67
- return this.getClient().post<TResponse, TData>(url, data);
68
- }
69
-
70
-
71
- put<TResponse = any, TData = any>(url: string, data?: TData) {
72
- return this.getClient().put<TResponse, TData>(url, data);
73
- }
74
-
75
-
76
- patch<TResponse = any, TData = any>(url: string, data?: TData) {
77
- return this.getClient().patch<TResponse, TData>(url, data);
78
- }
79
-
80
-
81
- delete<TResponse = any>(url: string, query?: string | object) {
82
- return this.getClient().delete<TResponse>(url, query);
83
- }
84
-
85
- }
86
-
87
- const Http = new (Macroable(HttpStatic))();
88
-
89
- export default Http;
90
-
@@ -1,81 +0,0 @@
1
-
2
- import { Constructor } from "../Js";
3
-
4
- export type MacroMethodMap = Record<string, (...args: any[]) => any>;
5
-
6
- export type MacroableInterface<TMacros extends MacroMethodMap> = {
7
- /**
8
- *
9
- * Register a custom macro
10
- *
11
- * @param name
12
- * @param macro
13
- */
14
- macro<K extends keyof TMacros>(name: K, macro: TMacros[K]): void;
15
-
16
- /**
17
- *
18
- * Checks if a macro is registered
19
- *
20
- * @param name
21
- */
22
- hasMacro(name: string): boolean;
23
-
24
- /**
25
- *
26
- * Flushes the existing macros.
27
- *
28
- */
29
- flushMacros(): void;
30
- };
31
-
32
- export type MacroableOf<TBase extends Constructor, TMacros extends MacroMethodMap> = Omit<TBase, 'new'> & {
33
- new (...args: ConstructorParameters<TBase>): InstanceType<TBase> & TMacros & MacroableInterface<TMacros>; /* & {
34
- [key: string]: (...args: any[]) => any;
35
- };*/
36
- };
37
-
38
- export default function Macroable<TMacros extends MacroMethodMap, TBase extends Constructor>(
39
- Base: TBase
40
- ): MacroableOf<TBase, TMacros>
41
- {
42
- return class MacroableBase extends Base {
43
-
44
- _macros: TMacros = {} as TMacros;
45
-
46
- constructor(...args: any[]) {
47
- super(...args);
48
-
49
- return new Proxy(this, {
50
- get(target, prop, receiver) {
51
- if (Reflect.has(target, prop)) {
52
- return Reflect.get(target, prop, receiver);
53
- }
54
-
55
- if (typeof prop === 'string' && target.hasMacro(prop)) {
56
- return target._macros[prop].bind(target);
57
- }
58
-
59
- return Reflect.get(target, prop, receiver);
60
- },
61
- });
62
- }
63
-
64
- macro<K extends keyof TMacros>(name: K, macro: TMacros[K]): void {
65
- if (typeof macro !== 'function') {
66
- throw new TypeError('Macro must be a function');
67
- }
68
-
69
- this._macros[name] = macro;
70
- }
71
-
72
- hasMacro(name: string): boolean {
73
- return name in this._macros && typeof this._macros[name] === 'function';
74
- }
75
-
76
- flushMacros(): void {
77
- this._macros = {} as TMacros;
78
- }
79
-
80
- } as any;
81
- }
@@ -1,126 +0,0 @@
1
- /* eslint-disable @typescript-eslint/ban-types */
2
- /* eslint-disable @typescript-eslint/no-explicit-any */
3
- import { isDraftable, produce } from 'immer';
4
-
5
- import { Constructor } from '../Js';
6
-
7
- import Collection from '../Collection';
8
- import ReducerOverrideException from '../Exceptions/ReducerOverrideException';
9
-
10
-
11
- export type ReducerRepository = {
12
- [reducer: string]: Collection<Reducer<any, any[]>>;
13
- };
14
-
15
- export type ReducerCallback<TValue = any, TParams extends any[] = any[]> = (value: TValue, ...params: TParams) => TValue;
16
-
17
- export interface Reducer<TValue = any, TParams extends any[] = any[]> {
18
- callback: ReducerCallback<TValue, TParams>,
19
- priority: number,
20
- }
21
-
22
- export type Unsubscribe = () => void;
23
-
24
- export type ReducerMethodMap = Record<string, (value: any, ...params: any[]) => any>;
25
-
26
- type First<T extends any[]> = T extends [infer A, ...any] ? A : unknown;
27
- type Tail<T extends any[]> = T extends [any, ...infer R] ? R : unknown[];
28
-
29
- export type ReducerCallbackFor<
30
- TReducers extends ReducerMethodMap,
31
- K extends keyof TReducers
32
- > = ReducerCallback<First<Parameters<TReducers[K]>>, Tail<Parameters<TReducers[K]>>>;
33
-
34
- export type ReducerFor<
35
- TReducers extends ReducerMethodMap,
36
- K extends keyof TReducers
37
- > = Reducer<First<Parameters<TReducers[K]>>, Tail<Parameters<TReducers[K]>>>;
38
-
39
- export type ReducibleInterface<TReducers extends ReducerMethodMap> = {
40
-
41
- reducer<K extends keyof TReducers>(name: K, callback: ReducerCallbackFor<TReducers, K>, priority?: number): Unsubscribe;
42
- removeReducer<K extends keyof TReducers>(name: K, callback: ReducerCallbackFor<TReducers, K>): void;
43
- getReducer<K extends keyof TReducers>(name: K): Collection<ReducerFor<TReducers, K>>;
44
- hasReducer(name: string): boolean;
45
- clearReducer(name: string): void;
46
- flushReducers(): void;
47
- };
48
-
49
- export type ReducibleOf<TBase extends Constructor, TReducers extends ReducerMethodMap> = Omit<TBase, 'new'> & {
50
- new (...args: ConstructorParameters<TBase>): InstanceType<TBase> & TReducers & ReducibleInterface<TReducers>; /* & {
51
- [key: string]: (value: any, ...args: any[]) => any;
52
- };*/
53
- };
54
-
55
- export default function Reducible<TReducers extends ReducerMethodMap, TBase extends Constructor>(Base: TBase): ReducibleOf<TBase, TReducers> {
56
- return class extends Base {
57
- _reducers: ReducerRepository = {};
58
-
59
- constructor(...args: any[]) {
60
- super(...args);
61
- return new Proxy(this, {
62
- get(target, prop, receiver) {
63
- if (typeof prop === 'symbol' || prop in target) {
64
- return Reflect.get(target, prop, receiver);
65
- }
66
- return (value: unknown, ...args: unknown[]) => {
67
- const { [prop]: reducers = new Collection<Reducer>() } = target._reducers;
68
-
69
- if (isDraftable(value)) {
70
- return produce(value, (draft: unknown) => {
71
- return reducers
72
- .sortBy('priority')
73
- .reduce((prevValue, item) => item.callback(prevValue, ...args), draft);
74
- });
75
- }
76
-
77
- return reducers
78
- .sortBy('priority')
79
- .reduce((prevValue, item) => item.callback(prevValue, ...args), value);
80
- };
81
- },
82
-
83
- });
84
- }
85
-
86
- reducer(name: string, callback: ReducerCallback, priority: number = 10) {
87
- if (name in this) {
88
- throw new ReducerOverrideException(name, this);
89
- }
90
- if (!this._reducers[name]) {
91
- this._reducers[name] = new Collection<Reducer>();
92
- }
93
-
94
- this._reducers[name].push({ callback, priority });
95
-
96
- return () => this.removeReducer(name, callback);
97
- }
98
-
99
- removeReducer(name: string, callback: ReducerCallback) {
100
- const index = this._reducers[name].search((reducer) => reducer.callback === callback);
101
- if (index === false) {
102
- return;
103
- }
104
- this._reducers[name].pull(index);
105
- }
106
-
107
- getReducer(name: string): Collection<Reducer> {
108
- if (!this._reducers[name]) {
109
- this._reducers[name] = new Collection<Reducer>();
110
- }
111
- return this._reducers[name];
112
- }
113
-
114
- hasReducer(name: string): boolean {
115
- return !!this._reducers[name] && this._reducers[name].count() > 0;
116
- }
117
-
118
- clearReducer(name: string) {
119
- this._reducers[name].splice(0, this._reducers[name].count());
120
- }
121
-
122
- flushReducers() {
123
- Object.values(this._reducers).forEach((collection) => collection.splice(0, collection.count()));
124
- }
125
- } as any;
126
- }