@blueprint-ts/core 1.0.0
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.
- package/.editorconfig +508 -0
- package/.eslintrc.cjs +15 -0
- package/.prettierrc.json +8 -0
- package/LICENSE +21 -0
- package/README.md +1 -0
- package/docker-compose.yaml +8 -0
- package/docs/.vitepress/config.ts +68 -0
- package/docs/.vitepress/theme/Layout.vue +14 -0
- package/docs/.vitepress/theme/components/VersionSelector.vue +64 -0
- package/docs/.vitepress/theme/index.js +13 -0
- package/docs/index.md +70 -0
- package/docs/services/laravel/pagination.md +54 -0
- package/docs/services/laravel/requests.md +62 -0
- package/docs/services/requests/index.md +74 -0
- package/docs/vue/forms.md +326 -0
- package/docs/vue/requests/route-model-binding.md +66 -0
- package/docs/vue/state.md +293 -0
- package/env.d.ts +1 -0
- package/eslint.config.js +15 -0
- package/examples/files/7z2404-x64.exe +0 -0
- package/examples/index.html +14 -0
- package/examples/js/app.js +8 -0
- package/examples/js/router.js +22 -0
- package/examples/js/view/App.vue +49 -0
- package/examples/js/view/layout/DemoPage.vue +28 -0
- package/examples/js/view/pagination/Pagination.vue +28 -0
- package/examples/js/view/pagination/components/errorPagination/ErrorPagination.vue +71 -0
- package/examples/js/view/pagination/components/errorPagination/GetProductsRequest.ts +54 -0
- package/examples/js/view/pagination/components/infiniteScrolling/GetProductsRequest.ts +50 -0
- package/examples/js/view/pagination/components/infiniteScrolling/InfiniteScrolling.vue +57 -0
- package/examples/js/view/pagination/components/tablePagination/GetProductsRequest.ts +50 -0
- package/examples/js/view/pagination/components/tablePagination/TablePagination.vue +63 -0
- package/examples/js/view/requests/Requests.vue +34 -0
- package/examples/js/view/requests/components/abortableRequest/AbortableRequest.vue +36 -0
- package/examples/js/view/requests/components/abortableRequest/GetProductsRequest.ts +25 -0
- package/examples/js/view/requests/components/fileDownloadRequest/DownloadFileRequest.ts +15 -0
- package/examples/js/view/requests/components/fileDownloadRequest/FileDownloadRequest.vue +44 -0
- package/examples/js/view/requests/components/getRequestWithDynamicParams/GetProductsRequest.ts +34 -0
- package/examples/js/view/requests/components/getRequestWithDynamicParams/GetRequestWithDynamicParams.vue +59 -0
- package/examples/js/view/requests/components/serverErrorRequest/ServerErrorRequest.ts +21 -0
- package/examples/js/view/requests/components/serverErrorRequest/ServerErrorRequest.vue +53 -0
- package/package.json +81 -0
- package/release-tool.json +7 -0
- package/src/helpers.ts +78 -0
- package/src/service/bulkRequests/BulkRequestEvent.enum.ts +4 -0
- package/src/service/bulkRequests/BulkRequestSender.ts +184 -0
- package/src/service/bulkRequests/BulkRequestWrapper.ts +49 -0
- package/src/service/bulkRequests/index.ts +6 -0
- package/src/service/laravel/pagination/contracts/PaginationParamsContract.ts +4 -0
- package/src/service/laravel/pagination/contracts/PaginationResponseBodyContract.ts +6 -0
- package/src/service/laravel/pagination/dataDrivers/RequestDriver.ts +32 -0
- package/src/service/laravel/pagination/index.ts +7 -0
- package/src/service/laravel/requests/JsonBaseRequest.ts +35 -0
- package/src/service/laravel/requests/PaginationJsonBaseRequest.ts +29 -0
- package/src/service/laravel/requests/index.ts +9 -0
- package/src/service/laravel/requests/responses/JsonResponse.ts +8 -0
- package/src/service/laravel/requests/responses/PaginationResponse.ts +16 -0
- package/src/service/pagination/InfiniteScroller.ts +21 -0
- package/src/service/pagination/Paginator.ts +149 -0
- package/src/service/pagination/contracts/PaginateableRequestContract.ts +13 -0
- package/src/service/pagination/contracts/PaginationDataDriverContract.ts +5 -0
- package/src/service/pagination/contracts/PaginationResponseContract.ts +7 -0
- package/src/service/pagination/contracts/PaginatorLoadDataOptions.ts +4 -0
- package/src/service/pagination/contracts/ViewDriverContract.ts +12 -0
- package/src/service/pagination/contracts/ViewDriverFactoryContract.ts +5 -0
- package/src/service/pagination/dataDrivers/ArrayDriver.ts +28 -0
- package/src/service/pagination/dtos/PaginationDataDto.ts +14 -0
- package/src/service/pagination/factories/VuePaginationDriverFactory.ts +9 -0
- package/src/service/pagination/frontendDrivers/VuePaginationDriver.ts +61 -0
- package/src/service/pagination/index.ts +16 -0
- package/src/service/persistenceDrivers/LocalStorageDriver.ts +22 -0
- package/src/service/persistenceDrivers/NonPersistentDriver.ts +12 -0
- package/src/service/persistenceDrivers/SessionStorageDriver.ts +22 -0
- package/src/service/persistenceDrivers/index.ts +8 -0
- package/src/service/persistenceDrivers/types/PersistenceDriver.ts +5 -0
- package/src/service/requests/BaseRequest.ts +197 -0
- package/src/service/requests/ErrorHandler.ts +64 -0
- package/src/service/requests/RequestEvents.enum.ts +3 -0
- package/src/service/requests/RequestMethod.enum.ts +8 -0
- package/src/service/requests/bodies/FormDataBody.ts +41 -0
- package/src/service/requests/bodies/JsonBody.ts +16 -0
- package/src/service/requests/contracts/AbortableRequestContract.ts +3 -0
- package/src/service/requests/contracts/BaseRequestContract.ts +36 -0
- package/src/service/requests/contracts/BodyContract.ts +7 -0
- package/src/service/requests/contracts/BodyFactoryContract.ts +5 -0
- package/src/service/requests/contracts/DriverConfigContract.ts +7 -0
- package/src/service/requests/contracts/HeadersContract.ts +5 -0
- package/src/service/requests/contracts/RequestDriverContract.ts +15 -0
- package/src/service/requests/contracts/RequestLoaderContract.ts +5 -0
- package/src/service/requests/contracts/RequestLoaderFactoryContract.ts +5 -0
- package/src/service/requests/contracts/ResponseContract.ts +7 -0
- package/src/service/requests/drivers/contracts/ResponseHandlerContract.ts +10 -0
- package/src/service/requests/drivers/fetch/FetchDriver.ts +115 -0
- package/src/service/requests/drivers/fetch/FetchResponse.ts +30 -0
- package/src/service/requests/exceptions/NoResponseReceivedException.ts +3 -0
- package/src/service/requests/exceptions/NotFoundException.ts +3 -0
- package/src/service/requests/exceptions/PageExpiredException.ts +3 -0
- package/src/service/requests/exceptions/ResponseBodyException.ts +15 -0
- package/src/service/requests/exceptions/ResponseException.ts +11 -0
- package/src/service/requests/exceptions/ServerErrorException.ts +3 -0
- package/src/service/requests/exceptions/UnauthorizedException.ts +3 -0
- package/src/service/requests/exceptions/ValidationException.ts +3 -0
- package/src/service/requests/exceptions/index.ts +19 -0
- package/src/service/requests/factories/FormDataFactory.ts +9 -0
- package/src/service/requests/factories/JsonBodyFactory.ts +9 -0
- package/src/service/requests/index.ts +50 -0
- package/src/service/requests/responses/BaseResponse.ts +41 -0
- package/src/service/requests/responses/BlobResponse.ts +19 -0
- package/src/service/requests/responses/JsonResponse.ts +15 -0
- package/src/service/requests/responses/PlainTextResponse.ts +15 -0
- package/src/service/support/DeferredPromise.ts +67 -0
- package/src/service/support/index.ts +3 -0
- package/src/vue/composables/useConfirmDialog.ts +59 -0
- package/src/vue/composables/useGlobalCheckbox.ts +145 -0
- package/src/vue/composables/useIsEmpty.ts +34 -0
- package/src/vue/composables/useIsOpen.ts +37 -0
- package/src/vue/composables/useIsOpenFromVar.ts +61 -0
- package/src/vue/composables/useModelWrapper.ts +24 -0
- package/src/vue/composables/useOnOpen.ts +34 -0
- package/src/vue/contracts/ModelValueOptions.ts +3 -0
- package/src/vue/contracts/ModelValueProps.ts +3 -0
- package/src/vue/forms/BaseForm.ts +1074 -0
- package/src/vue/forms/PropertyAwareArray.ts +78 -0
- package/src/vue/forms/index.ts +11 -0
- package/src/vue/forms/types/PersistedForm.ts +6 -0
- package/src/vue/forms/validation/ValidationMode.enum.ts +14 -0
- package/src/vue/forms/validation/index.ts +12 -0
- package/src/vue/forms/validation/rules/BaseRule.ts +7 -0
- package/src/vue/forms/validation/rules/ConfirmedRule.ts +39 -0
- package/src/vue/forms/validation/rules/MinRule.ts +61 -0
- package/src/vue/forms/validation/rules/RequiredRule.ts +19 -0
- package/src/vue/forms/validation/rules/UrlRule.ts +24 -0
- package/src/vue/forms/validation/types/BidirectionalRule.ts +11 -0
- package/src/vue/index.ts +14 -0
- package/src/vue/requests/factories/VueRequestLoaderFactory.ts +9 -0
- package/src/vue/requests/index.ts +5 -0
- package/src/vue/requests/loaders/VueRequestBatchLoader.ts +30 -0
- package/src/vue/requests/loaders/VueRequestLoader.ts +18 -0
- package/src/vue/router/routeModelBinding/RouteModelRequestResolver.ts +11 -0
- package/src/vue/router/routeModelBinding/defineRoute.ts +31 -0
- package/src/vue/router/routeModelBinding/index.ts +8 -0
- package/src/vue/router/routeModelBinding/installRouteInjection.ts +73 -0
- package/src/vue/router/routeModelBinding/types.ts +46 -0
- package/src/vue/state/State.ts +391 -0
- package/src/vue/state/index.ts +3 -0
- package/tests/service/helpers/mergeDeep.test.ts +53 -0
- package/tests/service/laravel/pagination/dataDrivers/RequestDriver.test.ts +84 -0
- package/tests/service/laravel/requests/JsonBaseRequest.test.ts +43 -0
- package/tests/service/laravel/requests/PaginationJsonBaseRequest.test.ts +58 -0
- package/tests/service/laravel/requests/responses/JsonResponse.test.ts +59 -0
- package/tests/service/laravel/requests/responses/PaginationResponse.test.ts +127 -0
- package/tests/service/pagination/dtos/PaginationDataDto.test.ts +35 -0
- package/tests/service/pagination/factories/VuePaginationDriverFactory.test.ts +32 -0
- package/tests/service/pagination/frontendDrivers/VuePaginationDriver.test.ts +66 -0
- package/tests/service/requests/ErrorHandler.test.ts +141 -0
- package/tsconfig.json +114 -0
- package/vite.config.ts +34 -0
- package/vitest.config.ts +14 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ResponseHandlerContract } from '../drivers/contracts/ResponseHandlerContract'
|
|
2
|
+
|
|
3
|
+
export interface ResponseContract<ResponseBodyInterface> {
|
|
4
|
+
getAcceptHeader(): string
|
|
5
|
+
|
|
6
|
+
setResponse(response: ResponseHandlerContract): Promise<ResponseBodyInterface>
|
|
7
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type HeadersContract } from '../../contracts/HeadersContract'
|
|
2
|
+
|
|
3
|
+
export interface ResponseHandlerContract {
|
|
4
|
+
getStatusCode(): number | undefined
|
|
5
|
+
getHeaders(): HeadersContract
|
|
6
|
+
getRawResponse(): Response
|
|
7
|
+
json<ResponseBodyInterface>(): Promise<ResponseBodyInterface>
|
|
8
|
+
text(): Promise<string>
|
|
9
|
+
blob(): Promise<Blob>
|
|
10
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { ResponseException } from '../../exceptions/ResponseException'
|
|
2
|
+
import { FetchResponse } from './FetchResponse'
|
|
3
|
+
import { RequestMethodEnum } from '../../RequestMethod.enum'
|
|
4
|
+
import { type HeadersContract, type HeaderValue } from '../../contracts/HeadersContract'
|
|
5
|
+
import { type BodyContract } from '../../contracts/BodyContract'
|
|
6
|
+
import { type RequestDriverContract } from '../../contracts/RequestDriverContract'
|
|
7
|
+
import { type DriverConfigContract } from '../../contracts/DriverConfigContract'
|
|
8
|
+
import { type ResponseHandlerContract } from '../contracts/ResponseHandlerContract'
|
|
9
|
+
|
|
10
|
+
enum FetchDriverCredentialConfigEnum {
|
|
11
|
+
OMIT = 'omit',
|
|
12
|
+
INCLUDE = 'include'
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface FetchDriverConfig {
|
|
16
|
+
method: RequestMethodEnum
|
|
17
|
+
headers: HeadersContract
|
|
18
|
+
credentials?: FetchDriverCredentialConfigEnum | undefined
|
|
19
|
+
signal?: AbortSignal | undefined
|
|
20
|
+
body?: string | FormData | Blob | ArrayBuffer | ArrayBufferView | URLSearchParams | undefined
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class FetchDriver implements RequestDriverContract {
|
|
24
|
+
public constructor(protected config?: DriverConfigContract) {}
|
|
25
|
+
|
|
26
|
+
public async send(
|
|
27
|
+
url: URL | string,
|
|
28
|
+
method: RequestMethodEnum,
|
|
29
|
+
headers: HeadersContract,
|
|
30
|
+
body?: BodyContract,
|
|
31
|
+
requestConfig?: DriverConfigContract
|
|
32
|
+
): Promise<ResponseHandlerContract> {
|
|
33
|
+
const mergedConfig: DriverConfigContract = {
|
|
34
|
+
// Global config
|
|
35
|
+
...this.config,
|
|
36
|
+
|
|
37
|
+
// Request specific overrides
|
|
38
|
+
...(requestConfig ?? {})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const mergedHeaders: HeadersContract = {
|
|
42
|
+
// Set global headers
|
|
43
|
+
...this.config?.headers,
|
|
44
|
+
|
|
45
|
+
// Set headers from the request
|
|
46
|
+
...headers,
|
|
47
|
+
|
|
48
|
+
// Set Content-Type header
|
|
49
|
+
...body?.getHeaders()
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const resolvedHeaders = this.resolveHeaders(mergedHeaders)
|
|
53
|
+
|
|
54
|
+
const fetchConfig = this.buildRequestConfig(mergedConfig, method, resolvedHeaders, body)
|
|
55
|
+
|
|
56
|
+
const response = await fetch(url, fetchConfig as RequestInit)
|
|
57
|
+
|
|
58
|
+
const fetchResponse = new FetchResponse(response)
|
|
59
|
+
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
throw new ResponseException(fetchResponse)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return fetchResponse
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
protected buildRequestConfig(
|
|
68
|
+
config: DriverConfigContract,
|
|
69
|
+
method: RequestMethodEnum,
|
|
70
|
+
headers: HeadersContract,
|
|
71
|
+
body?: BodyContract
|
|
72
|
+
): FetchDriverConfig {
|
|
73
|
+
return {
|
|
74
|
+
method: method,
|
|
75
|
+
headers: headers,
|
|
76
|
+
credentials: this.getCorsWithCredentials(config.corsWithCredentials),
|
|
77
|
+
signal: config.abortSignal ?? undefined,
|
|
78
|
+
body: [RequestMethodEnum.GET, RequestMethodEnum.HEAD].includes(method) ? undefined : body?.getContent()
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
protected getCorsWithCredentials(corsWithCredentials: boolean | undefined): FetchDriverCredentialConfigEnum {
|
|
83
|
+
// Request takes precedence
|
|
84
|
+
if (corsWithCredentials === true) {
|
|
85
|
+
return FetchDriverCredentialConfigEnum.INCLUDE
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (corsWithCredentials === false) {
|
|
89
|
+
return FetchDriverCredentialConfigEnum.OMIT
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Fallback to default config
|
|
93
|
+
if (this.config) {
|
|
94
|
+
return this.config.corsWithCredentials ? FetchDriverCredentialConfigEnum.INCLUDE : FetchDriverCredentialConfigEnum.OMIT
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Fallback to safe option if no default set
|
|
98
|
+
return FetchDriverCredentialConfigEnum.OMIT
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
protected resolveHeaders(headers: HeadersContract): HeadersContract {
|
|
102
|
+
const resolved: HeadersContract = {}
|
|
103
|
+
for (const key in headers) {
|
|
104
|
+
const value: HeaderValue | undefined = headers[key]
|
|
105
|
+
|
|
106
|
+
if (value === undefined) {
|
|
107
|
+
continue
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
resolved[key] = typeof value === 'function' ? value() : value
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return resolved
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type HeadersContract } from '../../contracts/HeadersContract'
|
|
2
|
+
import { type ResponseHandlerContract } from '../contracts/ResponseHandlerContract'
|
|
3
|
+
|
|
4
|
+
export class FetchResponse implements ResponseHandlerContract {
|
|
5
|
+
public constructor(protected response: Response) {}
|
|
6
|
+
|
|
7
|
+
public getStatusCode(): number | undefined {
|
|
8
|
+
return this.response.status
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public getHeaders(): HeadersContract {
|
|
12
|
+
return Object.fromEntries(this.response.headers)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public getRawResponse(): Response {
|
|
16
|
+
return this.response
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public async json<ResponseBodyInterface>(): Promise<ResponseBodyInterface> {
|
|
20
|
+
return await this.response.json()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public async text(): Promise<string> {
|
|
24
|
+
return await this.response.text()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public async blob(): Promise<Blob> {
|
|
28
|
+
return await this.response.blob()
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ResponseException } from './ResponseException'
|
|
2
|
+
import { type ResponseHandlerContract } from '../drivers/contracts/ResponseHandlerContract'
|
|
3
|
+
|
|
4
|
+
export class ResponseBodyException<ResponseErrorBody> extends ResponseException {
|
|
5
|
+
public constructor(
|
|
6
|
+
response: ResponseHandlerContract,
|
|
7
|
+
protected body: ResponseErrorBody
|
|
8
|
+
) {
|
|
9
|
+
super(response)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public getBody(): ResponseErrorBody {
|
|
13
|
+
return this.body
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ResponseHandlerContract } from '../drivers/contracts/ResponseHandlerContract'
|
|
2
|
+
|
|
3
|
+
export class ResponseException extends Error {
|
|
4
|
+
constructor(protected response: ResponseHandlerContract) {
|
|
5
|
+
super()
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
public getResponse(): ResponseHandlerContract {
|
|
9
|
+
return this.response
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ValidationException } from './ValidationException'
|
|
2
|
+
import { NotFoundException } from './NotFoundException'
|
|
3
|
+
import { NoResponseReceivedException } from './NoResponseReceivedException'
|
|
4
|
+
import { UnauthorizedException } from './UnauthorizedException'
|
|
5
|
+
import { PageExpiredException } from './PageExpiredException'
|
|
6
|
+
import { ServerErrorException } from './ServerErrorException'
|
|
7
|
+
import { ResponseException } from './ResponseException'
|
|
8
|
+
import { ResponseBodyException } from './ResponseBodyException'
|
|
9
|
+
|
|
10
|
+
export {
|
|
11
|
+
ValidationException,
|
|
12
|
+
NotFoundException,
|
|
13
|
+
NoResponseReceivedException,
|
|
14
|
+
UnauthorizedException,
|
|
15
|
+
PageExpiredException,
|
|
16
|
+
ServerErrorException,
|
|
17
|
+
ResponseException,
|
|
18
|
+
ResponseBodyException
|
|
19
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FormDataBody } from '../bodies/FormDataBody'
|
|
2
|
+
import { type BodyFactoryContract } from '../contracts/BodyFactoryContract'
|
|
3
|
+
import { type BodyContract } from '../contracts/BodyContract'
|
|
4
|
+
|
|
5
|
+
export class FormDataFactory<RequestBodyInterface> implements BodyFactoryContract<RequestBodyInterface> {
|
|
6
|
+
public make(body: RequestBodyInterface): BodyContract {
|
|
7
|
+
return new FormDataBody<RequestBodyInterface>(body)
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { JsonBody } from '../bodies/JsonBody'
|
|
2
|
+
import { type BodyFactoryContract } from '../contracts/BodyFactoryContract'
|
|
3
|
+
import { type BodyContract } from '../contracts/BodyContract'
|
|
4
|
+
|
|
5
|
+
export class JsonBodyFactory<RequestBodyInterface> implements BodyFactoryContract<RequestBodyInterface> {
|
|
6
|
+
public make(body: RequestBodyInterface): BodyContract {
|
|
7
|
+
return new JsonBody<RequestBodyInterface>(body)
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { FetchDriver } from './drivers/fetch/FetchDriver'
|
|
2
|
+
import { BaseResponse } from './responses/BaseResponse'
|
|
3
|
+
import { JsonResponse } from './responses/JsonResponse'
|
|
4
|
+
import { PlainTextResponse } from './responses/PlainTextResponse'
|
|
5
|
+
import { BlobResponse } from './responses/BlobResponse'
|
|
6
|
+
import { BaseRequest } from './BaseRequest'
|
|
7
|
+
import { ErrorHandler } from './ErrorHandler'
|
|
8
|
+
import { RequestEvents } from './RequestEvents.enum'
|
|
9
|
+
import { RequestMethodEnum } from './RequestMethod.enum'
|
|
10
|
+
import { JsonBodyFactory } from './factories/JsonBodyFactory'
|
|
11
|
+
import { FormDataFactory } from './factories/FormDataFactory'
|
|
12
|
+
import { type BodyContract } from './contracts/BodyContract'
|
|
13
|
+
import { type RequestLoaderContract } from './contracts/RequestLoaderContract'
|
|
14
|
+
import { type RequestDriverContract } from './contracts/RequestDriverContract'
|
|
15
|
+
import { type PaginationParamsContract } from '../laravel/pagination/contracts/PaginationParamsContract'
|
|
16
|
+
import { type RequestLoaderFactoryContract } from './contracts/RequestLoaderFactoryContract'
|
|
17
|
+
import { type DriverConfigContract } from './contracts/DriverConfigContract'
|
|
18
|
+
import { type BodyFactoryContract } from './contracts/BodyFactoryContract'
|
|
19
|
+
import { type ResponseHandlerContract } from './drivers/contracts/ResponseHandlerContract'
|
|
20
|
+
import { type BaseRequestContract } from './contracts/BaseRequestContract'
|
|
21
|
+
import { ResponseException } from './exceptions/ResponseException'
|
|
22
|
+
import { type HeadersContract } from './contracts/HeadersContract'
|
|
23
|
+
|
|
24
|
+
export {
|
|
25
|
+
FetchDriver,
|
|
26
|
+
BaseResponse,
|
|
27
|
+
JsonResponse,
|
|
28
|
+
BlobResponse,
|
|
29
|
+
PlainTextResponse,
|
|
30
|
+
BaseRequest,
|
|
31
|
+
ErrorHandler,
|
|
32
|
+
RequestEvents,
|
|
33
|
+
RequestMethodEnum,
|
|
34
|
+
ResponseException,
|
|
35
|
+
JsonBodyFactory,
|
|
36
|
+
FormDataFactory
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type {
|
|
40
|
+
PaginationParamsContract,
|
|
41
|
+
RequestDriverContract,
|
|
42
|
+
RequestLoaderContract,
|
|
43
|
+
BodyContract,
|
|
44
|
+
RequestLoaderFactoryContract,
|
|
45
|
+
DriverConfigContract,
|
|
46
|
+
BodyFactoryContract,
|
|
47
|
+
ResponseHandlerContract,
|
|
48
|
+
BaseRequestContract,
|
|
49
|
+
HeadersContract
|
|
50
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type ResponseHandlerContract } from '../drivers/contracts/ResponseHandlerContract'
|
|
2
|
+
import { type HeadersContract } from '../contracts/HeadersContract'
|
|
3
|
+
import { type ResponseContract } from '../contracts/ResponseContract'
|
|
4
|
+
|
|
5
|
+
export abstract class BaseResponse<ResponseInterface> implements ResponseContract<ResponseInterface> {
|
|
6
|
+
private body?: ResponseInterface
|
|
7
|
+
|
|
8
|
+
protected response?: ResponseHandlerContract
|
|
9
|
+
|
|
10
|
+
public abstract getAcceptHeader(): string
|
|
11
|
+
|
|
12
|
+
protected abstract resolveBody(): Promise<ResponseInterface>
|
|
13
|
+
|
|
14
|
+
public async setResponse(response: ResponseHandlerContract): Promise<ResponseInterface> {
|
|
15
|
+
this.response = response
|
|
16
|
+
|
|
17
|
+
this.body = await this.resolveBody()
|
|
18
|
+
|
|
19
|
+
return this.body
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public getRawResponse(): Response | undefined {
|
|
23
|
+
return this.response?.getRawResponse()
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public getStatusCode(): number | undefined {
|
|
27
|
+
return this.response?.getStatusCode()
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public getHeaders(): HeadersContract | undefined {
|
|
31
|
+
return this.response?.getHeaders()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public getBody(): ResponseInterface {
|
|
35
|
+
if (this.body === undefined) {
|
|
36
|
+
throw new Error('Response body is not set')
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return this.body
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BaseResponse } from './BaseResponse'
|
|
2
|
+
|
|
3
|
+
export class BlobResponse extends BaseResponse<Blob> {
|
|
4
|
+
public constructor(protected mimeType: string = 'application/octet-stream') {
|
|
5
|
+
super()
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
public getAcceptHeader(): string {
|
|
9
|
+
return this.mimeType
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
protected resolveBody(): Promise<Blob> {
|
|
13
|
+
if (!this.response) {
|
|
14
|
+
throw new Error('Response is not set')
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return this.response.blob()
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseResponse } from './BaseResponse'
|
|
2
|
+
|
|
3
|
+
export class JsonResponse<ResponseBodyInterface> extends BaseResponse<ResponseBodyInterface> {
|
|
4
|
+
public getAcceptHeader(): string {
|
|
5
|
+
return 'application/json'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
protected resolveBody(): Promise<ResponseBodyInterface> {
|
|
9
|
+
if (!this.response) {
|
|
10
|
+
throw new Error('Response is not set')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return this.response.json<ResponseBodyInterface>()
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseResponse } from './BaseResponse'
|
|
2
|
+
|
|
3
|
+
export class PlainTextResponse extends BaseResponse<string> {
|
|
4
|
+
public getAcceptHeader(): string {
|
|
5
|
+
return 'text/plain'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
protected resolveBody(): Promise<string> {
|
|
9
|
+
if (!this.response) {
|
|
10
|
+
throw new Error('Response is not set')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return this.response.text()
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A new instance of deferred is constructed by calling `new DeferredPromse<T>()`.
|
|
3
|
+
* The purpose of the deferred object is to expose the associated Promise
|
|
4
|
+
* instance APIs that can be used for signaling the successful
|
|
5
|
+
* or unsuccessful completion, as well as the state of the task.
|
|
6
|
+
* @export
|
|
7
|
+
* @class DeferredPromise
|
|
8
|
+
* @implements {Promise<T>}
|
|
9
|
+
* @template T
|
|
10
|
+
* @example
|
|
11
|
+
* const deferred = new DeferredPromse<string>();
|
|
12
|
+
* console.log(deferred.state); // 'pending'
|
|
13
|
+
*
|
|
14
|
+
* deferred
|
|
15
|
+
* .then(str => console.log(str))
|
|
16
|
+
* .catch(err => console.error(err));
|
|
17
|
+
*
|
|
18
|
+
* deferred.resolve('Foo');
|
|
19
|
+
* console.log(deferred.state); // 'fulfilled'
|
|
20
|
+
* // deferred.reject('Bar');
|
|
21
|
+
*
|
|
22
|
+
* https://gist.github.com/GFoley83/5877f6c09fbcfd62569c51dc91444cf0
|
|
23
|
+
*/
|
|
24
|
+
export class DeferredPromise<T> implements Promise<T> {
|
|
25
|
+
readonly [Symbol.toStringTag]: 'Promise' = 'Promise'
|
|
26
|
+
|
|
27
|
+
private _promise: Promise<T>
|
|
28
|
+
private _resolve!: (value: T | PromiseLike<T>) => void
|
|
29
|
+
private _reject!: (reason?: unknown) => void
|
|
30
|
+
private _state: 'pending' | 'fulfilled' | 'rejected' = 'pending'
|
|
31
|
+
|
|
32
|
+
public get state(): 'pending' | 'fulfilled' | 'rejected' {
|
|
33
|
+
return this._state
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public constructor() {
|
|
37
|
+
this._promise = new Promise<T>((resolve, reject) => {
|
|
38
|
+
this._resolve = resolve
|
|
39
|
+
this._reject = reject
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public then<TResult1 = T, TResult2 = never>(
|
|
44
|
+
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
|
|
45
|
+
onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null
|
|
46
|
+
): Promise<TResult1 | TResult2> {
|
|
47
|
+
return this._promise.then(onfulfilled, onrejected)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null): Promise<T | TResult> {
|
|
51
|
+
return this._promise.catch(onrejected)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public finally(onfinally?: (() => void) | null): Promise<T> {
|
|
55
|
+
return this._promise.finally(onfinally)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public resolve(value: T | PromiseLike<T>): void {
|
|
59
|
+
this._resolve(value)
|
|
60
|
+
this._state = 'fulfilled'
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public reject(reason?: unknown): void {
|
|
64
|
+
this._reject(reason)
|
|
65
|
+
this._state = 'rejected'
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { getCurrentInstance, h, onUnmounted, render } from 'vue'
|
|
2
|
+
import { type Component } from 'vue'
|
|
3
|
+
|
|
4
|
+
export type ConfirmDialogSeverity = 'info' | 'warning' | 'danger'
|
|
5
|
+
|
|
6
|
+
export interface ConfirmDialogOptions {
|
|
7
|
+
getMessage(): string
|
|
8
|
+
|
|
9
|
+
getSeverity(): ConfirmDialogSeverity
|
|
10
|
+
|
|
11
|
+
getTitle(): string
|
|
12
|
+
|
|
13
|
+
getOkText(): string
|
|
14
|
+
|
|
15
|
+
getCancelText(): string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The provided component needs to expose an "open" method, which
|
|
20
|
+
* should return a promise resolving into true or false.
|
|
21
|
+
*/
|
|
22
|
+
export default function (confirmDialogComponent: Component, querySelector: string = 'body') {
|
|
23
|
+
const self = getCurrentInstance()
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* https://stackoverflow.com/a/78448128
|
|
27
|
+
*/
|
|
28
|
+
function mountConfirmDialog(options: ConfirmDialogOptions) {
|
|
29
|
+
if (!self?.appContext) {
|
|
30
|
+
throw new Error('ConfirmationDialog: useConfirmDialog must be called inside a setup function')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const vNode = h(confirmDialogComponent, { options })
|
|
34
|
+
vNode.key = Symbol()
|
|
35
|
+
vNode.appContext = self.appContext
|
|
36
|
+
render(vNode, document.querySelector(querySelector) as Element)
|
|
37
|
+
return vNode.component
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function unmountConfirmDialog() {
|
|
41
|
+
render(null, document.querySelector(querySelector) as Element)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
onUnmounted(() => {
|
|
45
|
+
unmountConfirmDialog()
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
async function openConfirmDialog(options: ConfirmDialogOptions): Promise<boolean> {
|
|
49
|
+
const dialogComponent = mountConfirmDialog(options)
|
|
50
|
+
|
|
51
|
+
if (dialogComponent?.exposed == undefined || dialogComponent?.exposed['open'] === undefined) {
|
|
52
|
+
throw new Error('ConfirmationDialog: Provided component does not expose an "open" method')
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return dialogComponent?.exposed['open']
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return { openConfirmDialog }
|
|
59
|
+
}
|