@gostack-framework/react 0.0.0-stage → 0.1.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/dist/api.d.ts +83 -0
- package/dist/api.js +170 -0
- package/dist/api.js.map +1 -0
- package/dist/auth.d.ts +60 -0
- package/dist/auth.js +136 -0
- package/dist/auth.js.map +1 -0
- package/dist/data.d.ts +25 -0
- package/dist/data.js +73 -0
- package/dist/data.js.map +1 -0
- package/dist/examples.d.ts +6 -0
- package/dist/examples.js +47 -0
- package/dist/examples.js.map +1 -0
- package/dist/hooks.d.ts +58 -0
- package/dist/hooks.js +109 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/layouts.d.ts +6 -0
- package/dist/layouts.js +34 -0
- package/dist/layouts.js.map +1 -0
- package/dist/line-flow/bus.d.ts +13 -0
- package/dist/line-flow/bus.js +52 -0
- package/dist/line-flow/bus.js.map +1 -0
- package/dist/line-flow/derived-line.d.ts +21 -0
- package/dist/line-flow/derived-line.js +122 -0
- package/dist/line-flow/derived-line.js.map +1 -0
- package/dist/line-flow/errors.d.ts +62 -0
- package/dist/line-flow/errors.js +91 -0
- package/dist/line-flow/errors.js.map +1 -0
- package/dist/line-flow/event-line.d.ts +16 -0
- package/dist/line-flow/event-line.js +81 -0
- package/dist/line-flow/event-line.js.map +1 -0
- package/dist/line-flow/index.d.ts +11 -0
- package/dist/line-flow/index.js +11 -0
- package/dist/line-flow/index.js.map +1 -0
- package/dist/line-flow/interchange.d.ts +17 -0
- package/dist/line-flow/interchange.js +86 -0
- package/dist/line-flow/interchange.js.map +1 -0
- package/dist/line-flow/lineflow.d.ts +12 -0
- package/dist/line-flow/lineflow.js +15 -0
- package/dist/line-flow/lineflow.js.map +1 -0
- package/dist/line-flow/network.d.ts +28 -0
- package/dist/line-flow/network.js +165 -0
- package/dist/line-flow/network.js.map +1 -0
- package/dist/line-flow/react/bridge.d.ts +23 -0
- package/dist/line-flow/react/bridge.js +40 -0
- package/dist/line-flow/react/bridge.js.map +1 -0
- package/dist/line-flow/react/hooks.d.ts +29 -0
- package/dist/line-flow/react/hooks.js +117 -0
- package/dist/line-flow/react/hooks.js.map +1 -0
- package/dist/line-flow/react/index.d.ts +3 -0
- package/dist/line-flow/react/index.js +4 -0
- package/dist/line-flow/react/index.js.map +1 -0
- package/dist/line-flow/react/provider.d.ts +15 -0
- package/dist/line-flow/react/provider.js +25 -0
- package/dist/line-flow/react/provider.js.map +1 -0
- package/dist/line-flow/scope.d.ts +21 -0
- package/dist/line-flow/scope.js +157 -0
- package/dist/line-flow/scope.js.map +1 -0
- package/dist/line-flow/state-line.d.ts +21 -0
- package/dist/line-flow/state-line.js +106 -0
- package/dist/line-flow/state-line.js.map +1 -0
- package/dist/line-flow/taxi.d.ts +15 -0
- package/dist/line-flow/taxi.js +81 -0
- package/dist/line-flow/taxi.js.map +1 -0
- package/dist/line-flow/types.d.ts +222 -0
- package/dist/line-flow/types.js +2 -0
- package/dist/line-flow/types.js.map +1 -0
- package/dist/line-flow/utils.d.ts +24 -0
- package/dist/line-flow/utils.js +53 -0
- package/dist/line-flow/utils.js.map +1 -0
- package/dist/paramsSerializer.d.ts +87 -0
- package/dist/paramsSerializer.js +138 -0
- package/dist/paramsSerializer.js.map +1 -0
- package/dist/registry.d.ts +10 -0
- package/dist/registry.js +115 -0
- package/dist/registry.js.map +1 -0
- package/dist/runtime.d.ts +80 -0
- package/dist/runtime.js +442 -0
- package/dist/runtime.js.map +1 -0
- package/dist/schemas.d.ts +88 -0
- package/dist/schemas.js +146 -0
- package/dist/schemas.js.map +1 -0
- package/dist/services.d.ts +35 -0
- package/dist/services.js +65 -0
- package/dist/services.js.map +1 -0
- package/dist/shared-types/file.types.d.ts +12 -0
- package/dist/shared-types/file.types.js +2 -0
- package/dist/shared-types/file.types.js.map +1 -0
- package/dist/shared-types/gallery.types.d.ts +22 -0
- package/dist/shared-types/gallery.types.js +2 -0
- package/dist/shared-types/gallery.types.js.map +1 -0
- package/dist/shared-types/governorates.types.d.ts +12 -0
- package/dist/shared-types/governorates.types.js +2 -0
- package/dist/shared-types/governorates.types.js.map +1 -0
- package/dist/shared-types/grade.types.d.ts +7 -0
- package/dist/shared-types/grade.types.js +2 -0
- package/dist/shared-types/grade.types.js.map +1 -0
- package/dist/shared-types/index.d.ts +13 -0
- package/dist/shared-types/index.js +14 -0
- package/dist/shared-types/index.js.map +1 -0
- package/dist/shared-types/metadata.types.d.ts +61 -0
- package/dist/shared-types/metadata.types.js +3 -0
- package/dist/shared-types/metadata.types.js.map +1 -0
- package/dist/shared-types/table.types.d.ts +33 -0
- package/dist/shared-types/table.types.js +2 -0
- package/dist/shared-types/table.types.js.map +1 -0
- package/dist/shared-types/viewCard.types.d.ts +78 -0
- package/dist/shared-types/viewCard.types.js +3 -0
- package/dist/shared-types/viewCard.types.js.map +1 -0
- package/dist/styles.css +347 -0
- package/dist/types.d.ts +126 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/conditionCompiler.d.ts +11 -0
- package/dist/utils/conditionCompiler.js +18 -0
- package/dist/utils/conditionCompiler.js.map +1 -0
- package/dist/utils/fileUtils.d.ts +50 -0
- package/dist/utils/fileUtils.js +266 -0
- package/dist/utils/fileUtils.js.map +1 -0
- package/dist/utils/metadataUtils.d.ts +35 -0
- package/dist/utils/metadataUtils.js +176 -0
- package/dist/utils/metadataUtils.js.map +1 -0
- package/dist/utils/normalizeTime.d.ts +1 -0
- package/dist/utils/normalizeTime.js +25 -0
- package/dist/utils/normalizeTime.js.map +1 -0
- package/dist/utils/tableUtils.d.ts +9 -0
- package/dist/utils/tableUtils.js +92 -0
- package/dist/utils/tableUtils.js.map +1 -0
- package/dist/utils/toFormData.d.ts +152 -0
- package/dist/utils/toFormData.js +250 -0
- package/dist/utils/toFormData.js.map +1 -0
- package/dist/utils/wizard.utils.d.ts +420 -0
- package/dist/utils/wizard.utils.js +596 -0
- package/dist/utils/wizard.utils.js.map +1 -0
- package/package.json +49 -3
- package/README.md +0 -3
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { type AxiosInstance, type AxiosRequestConfig } from "axios";
|
|
2
|
+
export { serializeParams } from "./paramsSerializer";
|
|
3
|
+
export { toFormData } from "./utils/toFormData";
|
|
4
|
+
export type ValidationErrors = Record<string, string[]>;
|
|
5
|
+
export declare class ApiError extends Error {
|
|
6
|
+
status?: number | undefined;
|
|
7
|
+
validationErrors: ValidationErrors;
|
|
8
|
+
cause?: unknown | undefined;
|
|
9
|
+
constructor(message: string, status?: number | undefined, validationErrors?: ValidationErrors, cause?: unknown | undefined);
|
|
10
|
+
}
|
|
11
|
+
export declare function normalizeApiError(error: unknown): ApiError;
|
|
12
|
+
export interface RequestOptions extends Omit<AxiosRequestConfig, "url" | "method" | "data" | "auth"> {
|
|
13
|
+
auth?: "required" | "optional" | "none";
|
|
14
|
+
}
|
|
15
|
+
export interface HttpClient {
|
|
16
|
+
request<T = unknown>(method: string, url: string, data?: unknown, options?: RequestOptions): Promise<T>;
|
|
17
|
+
get<T = unknown>(url: string, options?: RequestOptions): Promise<T>;
|
|
18
|
+
post<T = unknown>(url: string, data?: unknown, options?: RequestOptions): Promise<T>;
|
|
19
|
+
put<T = unknown>(url: string, data?: unknown, options?: RequestOptions): Promise<T>;
|
|
20
|
+
patch<T = unknown>(url: string, data?: unknown, options?: RequestOptions): Promise<T>;
|
|
21
|
+
delete<T = unknown>(url: string, options?: RequestOptions): Promise<T>;
|
|
22
|
+
subscribeUnauthorized(listener: () => void): () => void;
|
|
23
|
+
resetUnauthorized(): void;
|
|
24
|
+
}
|
|
25
|
+
export interface HttpConfig {
|
|
26
|
+
baseURL: string;
|
|
27
|
+
timeout?: number;
|
|
28
|
+
withCredentials?: boolean;
|
|
29
|
+
getToken?: () => string | null | undefined | Promise<string | null | undefined>;
|
|
30
|
+
getLanguage?: () => string;
|
|
31
|
+
headers?: () => Record<string, string>;
|
|
32
|
+
onUnauthorized?: () => void;
|
|
33
|
+
onError?: (error: ApiError) => void;
|
|
34
|
+
instance?: AxiosInstance;
|
|
35
|
+
}
|
|
36
|
+
export declare function createHttpClient(config: HttpConfig): HttpClient;
|
|
37
|
+
export interface PaginationMeta {
|
|
38
|
+
currentPage: number;
|
|
39
|
+
lastPage: number;
|
|
40
|
+
perPage: number;
|
|
41
|
+
total: number;
|
|
42
|
+
}
|
|
43
|
+
export interface PaginatedResponse<T> {
|
|
44
|
+
items: T[];
|
|
45
|
+
meta: PaginationMeta;
|
|
46
|
+
}
|
|
47
|
+
export interface ListQueryParams {
|
|
48
|
+
page?: number;
|
|
49
|
+
perPage?: number;
|
|
50
|
+
search?: string;
|
|
51
|
+
sortBy?: string;
|
|
52
|
+
sortOrder?: "asc" | "desc";
|
|
53
|
+
[key: string]: unknown;
|
|
54
|
+
}
|
|
55
|
+
export interface ResponseAdapter {
|
|
56
|
+
entity<T>(body: unknown): T;
|
|
57
|
+
list<T>(body: unknown): PaginatedResponse<T>;
|
|
58
|
+
params?: (params: ListQueryParams) => Record<string, unknown>;
|
|
59
|
+
}
|
|
60
|
+
export declare const standardAdapter: ResponseAdapter;
|
|
61
|
+
export declare const itsmAdapter: ResponseAdapter;
|
|
62
|
+
export interface CrudApi<T, Create = Partial<T>, Update = Partial<T>> {
|
|
63
|
+
getList(params?: ListQueryParams, signal?: AbortSignal): Promise<PaginatedResponse<T>>;
|
|
64
|
+
getById(id: string | number, signal?: AbortSignal): Promise<T>;
|
|
65
|
+
create(payload: Create): Promise<T>;
|
|
66
|
+
update(id: string | number, payload: Update): Promise<T>;
|
|
67
|
+
delete(id: string | number): Promise<void>;
|
|
68
|
+
}
|
|
69
|
+
export declare function createCrudApi<T, Create = Partial<T>, Update = Partial<T>>(config: {
|
|
70
|
+
client: HttpClient;
|
|
71
|
+
baseUrl: string;
|
|
72
|
+
adapter?: ResponseAdapter;
|
|
73
|
+
updateMethod?: "put" | "patch";
|
|
74
|
+
transformRequest?: (value: Create | Update) => unknown;
|
|
75
|
+
}): CrudApi<T, Create, Update>;
|
|
76
|
+
export declare function readApiConfig(env: Record<string, string | boolean | undefined>): {
|
|
77
|
+
BASE_URL: string;
|
|
78
|
+
TIMEOUT: number;
|
|
79
|
+
PROJECT_NAME: string;
|
|
80
|
+
ENV_MODE: string;
|
|
81
|
+
USE_MOCK_DATA: boolean;
|
|
82
|
+
TENANT_IDENTIFIER: string;
|
|
83
|
+
};
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { serializeParams } from "./paramsSerializer.js";
|
|
3
|
+
export { serializeParams } from "./paramsSerializer.js";
|
|
4
|
+
export { toFormData } from "./utils/toFormData.js";
|
|
5
|
+
export class ApiError extends Error {
|
|
6
|
+
status;
|
|
7
|
+
validationErrors;
|
|
8
|
+
cause;
|
|
9
|
+
constructor(message, status, validationErrors = {}, cause) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.status = status;
|
|
12
|
+
this.validationErrors = validationErrors;
|
|
13
|
+
this.cause = cause;
|
|
14
|
+
this.name = "ApiError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function normalizeApiError(error) {
|
|
18
|
+
if (error instanceof ApiError)
|
|
19
|
+
return error;
|
|
20
|
+
if (axios.isAxiosError(error)) {
|
|
21
|
+
const data = error.response?.data;
|
|
22
|
+
const fields = Object.fromEntries(Object.entries(data?.validationErrors ?? data?.errors ?? {}).map(([key, value]) => [key, Array.isArray(value) ? value : [String(value)]]));
|
|
23
|
+
return new ApiError(data?.message ?? error.message, error.response?.status, fields, error);
|
|
24
|
+
}
|
|
25
|
+
return new ApiError(error instanceof Error ? error.message : String(error), undefined, {}, error);
|
|
26
|
+
}
|
|
27
|
+
export function createHttpClient(config) {
|
|
28
|
+
const instance = config.instance ??
|
|
29
|
+
axios.create({
|
|
30
|
+
baseURL: config.baseURL,
|
|
31
|
+
timeout: config.timeout ?? 30000,
|
|
32
|
+
withCredentials: config.withCredentials ?? false,
|
|
33
|
+
paramsSerializer: {
|
|
34
|
+
serialize: (params) => serializeParams(params),
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
const listeners = new Set();
|
|
38
|
+
let unauthorizedNotified = false;
|
|
39
|
+
const request = async (method, url, data, options = {}) => {
|
|
40
|
+
const { auth = "required", ...rest } = options;
|
|
41
|
+
const token = auth === "none" ? null : await config.getToken?.();
|
|
42
|
+
const headers = {
|
|
43
|
+
Accept: "application/json",
|
|
44
|
+
...config.headers?.(),
|
|
45
|
+
...(config.getLanguage
|
|
46
|
+
? { "Accept-Language": config.getLanguage() }
|
|
47
|
+
: {}),
|
|
48
|
+
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
49
|
+
...rest.headers,
|
|
50
|
+
};
|
|
51
|
+
try {
|
|
52
|
+
const response = await instance.request({
|
|
53
|
+
...rest,
|
|
54
|
+
method,
|
|
55
|
+
url,
|
|
56
|
+
data,
|
|
57
|
+
headers,
|
|
58
|
+
});
|
|
59
|
+
if (auth === "required")
|
|
60
|
+
unauthorizedNotified = false;
|
|
61
|
+
return response.data;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (axios.isCancel(error))
|
|
65
|
+
throw error;
|
|
66
|
+
const normalized = normalizeApiError(error);
|
|
67
|
+
if (normalized.status === 401 &&
|
|
68
|
+
auth === "required" &&
|
|
69
|
+
!unauthorizedNotified) {
|
|
70
|
+
unauthorizedNotified = true;
|
|
71
|
+
config.onUnauthorized?.();
|
|
72
|
+
listeners.forEach((listener) => listener());
|
|
73
|
+
}
|
|
74
|
+
config.onError?.(normalized);
|
|
75
|
+
throw normalized;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
return {
|
|
79
|
+
request,
|
|
80
|
+
get: (url, options) => request("GET", url, undefined, options),
|
|
81
|
+
post: (url, data, options) => request("POST", url, data, options),
|
|
82
|
+
put: (url, data, options) => request("PUT", url, data, options),
|
|
83
|
+
patch: (url, data, options) => request("PATCH", url, data, options),
|
|
84
|
+
delete: (url, options) => request("DELETE", url, undefined, options),
|
|
85
|
+
resetUnauthorized() {
|
|
86
|
+
unauthorizedNotified = false;
|
|
87
|
+
},
|
|
88
|
+
subscribeUnauthorized(listener) {
|
|
89
|
+
listeners.add(listener);
|
|
90
|
+
return () => {
|
|
91
|
+
listeners.delete(listener);
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export const standardAdapter = {
|
|
97
|
+
entity: (body) => body,
|
|
98
|
+
list(body) {
|
|
99
|
+
const value = body;
|
|
100
|
+
if (!Array.isArray(value?.items) || !value?.meta)
|
|
101
|
+
throw new ApiError("Expected { items, meta } list response. Configure a response adapter.");
|
|
102
|
+
return value;
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
export const itsmAdapter = {
|
|
106
|
+
entity(body) {
|
|
107
|
+
return body.data;
|
|
108
|
+
},
|
|
109
|
+
list(body) {
|
|
110
|
+
const data = body.data;
|
|
111
|
+
if (!data)
|
|
112
|
+
throw new ApiError("Expected an ITSM data response.");
|
|
113
|
+
const items = data.items ?? data.data;
|
|
114
|
+
if (!Array.isArray(items))
|
|
115
|
+
throw new ApiError("Expected ITSM data.items or data.data array.");
|
|
116
|
+
return {
|
|
117
|
+
items: items,
|
|
118
|
+
meta: {
|
|
119
|
+
currentPage: Number(data.currentPage ?? data.current_page ?? 1),
|
|
120
|
+
lastPage: Number(data.lastPage ?? data.last_page ?? 1),
|
|
121
|
+
perPage: Number(data.perPage ?? data.per_page ?? items.length),
|
|
122
|
+
total: Number(data.total ?? items.length),
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
},
|
|
126
|
+
params({ perPage, ...params }) {
|
|
127
|
+
return {
|
|
128
|
+
...params,
|
|
129
|
+
...(perPage === undefined ? {} : { per_page: perPage }),
|
|
130
|
+
};
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
export function createCrudApi(config) {
|
|
134
|
+
const { client, baseUrl, adapter = standardAdapter } = config;
|
|
135
|
+
const detail = (id) => `${baseUrl.replace(/\/$/, "")}/${encodeURIComponent(String(id))}`;
|
|
136
|
+
return {
|
|
137
|
+
async getList(params = {}, signal) {
|
|
138
|
+
return adapter.list(await client.get(baseUrl, {
|
|
139
|
+
params: adapter.params?.(params) ?? params,
|
|
140
|
+
signal,
|
|
141
|
+
}));
|
|
142
|
+
},
|
|
143
|
+
async getById(id, signal) {
|
|
144
|
+
return adapter.entity(await client.get(detail(id), { signal }));
|
|
145
|
+
},
|
|
146
|
+
async create(payload) {
|
|
147
|
+
return adapter.entity(await client.post(baseUrl, config.transformRequest?.(payload) ?? payload));
|
|
148
|
+
},
|
|
149
|
+
async update(id, payload) {
|
|
150
|
+
return adapter.entity(await client[config.updateMethod ?? "put"](detail(id), config.transformRequest?.(payload) ?? payload));
|
|
151
|
+
},
|
|
152
|
+
async delete(id) {
|
|
153
|
+
await client.delete(detail(id));
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
export function readApiConfig(env) {
|
|
158
|
+
const timeout = Number(env.VITE_API_TIMEOUT ?? 30000);
|
|
159
|
+
if (!Number.isFinite(timeout) || timeout <= 0)
|
|
160
|
+
throw new Error("VITE_API_TIMEOUT must be a positive number.");
|
|
161
|
+
return {
|
|
162
|
+
BASE_URL: String(env.VITE_API_URL ?? "/api"),
|
|
163
|
+
TIMEOUT: timeout,
|
|
164
|
+
PROJECT_NAME: String(env.VITE_PROJECT_NAME ?? "gostack"),
|
|
165
|
+
ENV_MODE: String(env.MODE ?? "development"),
|
|
166
|
+
USE_MOCK_DATA: env.DEV === true && env.VITE_USE_MOCK_DATA === "true",
|
|
167
|
+
TENANT_IDENTIFIER: String(env.VITE_TENANT_IDENTIFIER ?? ""),
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { HttpClient } from "./api";
|
|
3
|
+
import { type AccessRule } from "./types";
|
|
4
|
+
export interface AuthSession {
|
|
5
|
+
user: {
|
|
6
|
+
id: string | number;
|
|
7
|
+
name: string;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
};
|
|
10
|
+
roles: string[];
|
|
11
|
+
permissions: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface AuthAdapter {
|
|
14
|
+
getSession: (signal?: AbortSignal) => Promise<AuthSession | null>;
|
|
15
|
+
login: (credentials: {
|
|
16
|
+
email: string;
|
|
17
|
+
password: string;
|
|
18
|
+
}) => Promise<AuthSession>;
|
|
19
|
+
logout: () => Promise<void>;
|
|
20
|
+
subscribe?: (callback: () => void) => () => void;
|
|
21
|
+
}
|
|
22
|
+
interface AuthState {
|
|
23
|
+
session: AuthSession | null;
|
|
24
|
+
status: "loading" | "authenticated" | "anonymous";
|
|
25
|
+
error: Error | null;
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
login: AuthAdapter["login"];
|
|
28
|
+
logout: () => Promise<void>;
|
|
29
|
+
expire: () => void;
|
|
30
|
+
}
|
|
31
|
+
export declare function AuthProvider({ adapter, children, onSessionChange, }: {
|
|
32
|
+
adapter?: AuthAdapter;
|
|
33
|
+
children: ReactNode;
|
|
34
|
+
onSessionChange?: () => void;
|
|
35
|
+
}): import("react").JSX.Element;
|
|
36
|
+
export declare function useAuth(): AuthState;
|
|
37
|
+
export declare function usePermissions(): {
|
|
38
|
+
permissions: string[];
|
|
39
|
+
hasPermission: (p: string) => boolean;
|
|
40
|
+
hasAnyPermission: (p: string[]) => boolean;
|
|
41
|
+
hasAllPermissions: (p: string[]) => boolean;
|
|
42
|
+
hasRole: (r: string) => boolean;
|
|
43
|
+
can: (rule: AccessRule) => boolean;
|
|
44
|
+
};
|
|
45
|
+
export declare function HasPermission({ permissions, children, fallback, ...rule }: AccessRule & {
|
|
46
|
+
children: ReactNode;
|
|
47
|
+
fallback?: ReactNode;
|
|
48
|
+
}): import("react").JSX.Element;
|
|
49
|
+
export declare function createRestAuth(options: {
|
|
50
|
+
client: HttpClient;
|
|
51
|
+
endpoints: {
|
|
52
|
+
session: string;
|
|
53
|
+
login: string;
|
|
54
|
+
logout: string;
|
|
55
|
+
};
|
|
56
|
+
mapSession: (body: unknown) => AuthSession | null;
|
|
57
|
+
onLogin?: (body: unknown) => void | Promise<void>;
|
|
58
|
+
onLogout?: () => void | Promise<void>;
|
|
59
|
+
}): AuthAdapter;
|
|
60
|
+
export {};
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useEffect, useRef, useState, } from "react";
|
|
3
|
+
import { canAccess } from "./types.js";
|
|
4
|
+
const AuthContext = createContext(null);
|
|
5
|
+
export function AuthProvider({ adapter, children, onSessionChange, }) {
|
|
6
|
+
const [session, setSession] = useState(null);
|
|
7
|
+
const [status, setStatus] = useState(adapter ? "loading" : "anonymous");
|
|
8
|
+
const [error, setError] = useState(null);
|
|
9
|
+
const epoch = useRef(0);
|
|
10
|
+
const expire = () => {
|
|
11
|
+
epoch.current++;
|
|
12
|
+
setSession(null);
|
|
13
|
+
setStatus("anonymous");
|
|
14
|
+
onSessionChange?.();
|
|
15
|
+
};
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!adapter)
|
|
18
|
+
return;
|
|
19
|
+
const controller = new AbortController();
|
|
20
|
+
const restore = async () => {
|
|
21
|
+
const generation = ++epoch.current;
|
|
22
|
+
setStatus("loading");
|
|
23
|
+
try {
|
|
24
|
+
const value = await adapter.getSession(controller.signal);
|
|
25
|
+
if (!controller.signal.aborted && generation === epoch.current) {
|
|
26
|
+
setSession(value);
|
|
27
|
+
setStatus(value ? "authenticated" : "anonymous");
|
|
28
|
+
setError(null);
|
|
29
|
+
onSessionChange?.();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
if (!controller.signal.aborted && generation === epoch.current) {
|
|
34
|
+
setError(e instanceof Error ? e : new Error(String(e)));
|
|
35
|
+
setSession(null);
|
|
36
|
+
setStatus("anonymous");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
void restore();
|
|
41
|
+
const unsubscribe = adapter.subscribe?.(() => {
|
|
42
|
+
void restore();
|
|
43
|
+
});
|
|
44
|
+
return () => {
|
|
45
|
+
controller.abort();
|
|
46
|
+
unsubscribe?.();
|
|
47
|
+
};
|
|
48
|
+
}, [adapter]);
|
|
49
|
+
const login = async (credentials) => {
|
|
50
|
+
if (!adapter)
|
|
51
|
+
throw new Error("GoStack: authentication is not configured.");
|
|
52
|
+
const generation = ++epoch.current;
|
|
53
|
+
setError(null);
|
|
54
|
+
const value = await adapter.login(credentials);
|
|
55
|
+
if (generation === epoch.current) {
|
|
56
|
+
onSessionChange?.();
|
|
57
|
+
setSession(value);
|
|
58
|
+
setStatus("authenticated");
|
|
59
|
+
}
|
|
60
|
+
return value;
|
|
61
|
+
};
|
|
62
|
+
const logout = async () => {
|
|
63
|
+
try {
|
|
64
|
+
await adapter?.logout();
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
expire();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
return (_jsx(AuthContext.Provider, { value: {
|
|
71
|
+
session,
|
|
72
|
+
status,
|
|
73
|
+
error,
|
|
74
|
+
enabled: !!adapter,
|
|
75
|
+
login,
|
|
76
|
+
logout,
|
|
77
|
+
expire,
|
|
78
|
+
}, children: children }));
|
|
79
|
+
}
|
|
80
|
+
export function useAuth() {
|
|
81
|
+
const value = useContext(AuthContext);
|
|
82
|
+
if (!value)
|
|
83
|
+
throw new Error("useAuth requires GoStack AuthProvider.");
|
|
84
|
+
return value;
|
|
85
|
+
}
|
|
86
|
+
export function usePermissions() {
|
|
87
|
+
const { session } = useAuth();
|
|
88
|
+
return {
|
|
89
|
+
permissions: session?.permissions ?? [],
|
|
90
|
+
hasPermission: (p) => !!session?.permissions.includes(p),
|
|
91
|
+
hasAnyPermission: (p) => p.some((v) => session?.permissions.includes(v)),
|
|
92
|
+
hasAllPermissions: (p) => p.every((v) => session?.permissions.includes(v)),
|
|
93
|
+
hasRole: (r) => !!session?.roles.includes(r),
|
|
94
|
+
can: (rule) => canAccess(rule, session),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export function HasPermission({ permissions, children, fallback = null, ...rule }) {
|
|
98
|
+
const { can } = usePermissions();
|
|
99
|
+
return _jsx(_Fragment, { children: can({ ...rule, permissions }) ? children : fallback });
|
|
100
|
+
}
|
|
101
|
+
export function createRestAuth(options) {
|
|
102
|
+
return {
|
|
103
|
+
async getSession(signal) {
|
|
104
|
+
try {
|
|
105
|
+
return options.mapSession(await options.client.get(options.endpoints.session, {
|
|
106
|
+
signal,
|
|
107
|
+
auth: "optional",
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
if (e.status === 401)
|
|
112
|
+
return null;
|
|
113
|
+
throw e;
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
async login(credentials) {
|
|
117
|
+
const body = await options.client.post(options.endpoints.login, credentials, { auth: "none" });
|
|
118
|
+
await options.onLogin?.(body);
|
|
119
|
+
const session = options.mapSession(body);
|
|
120
|
+
if (!session)
|
|
121
|
+
throw new Error("GoStack: login response did not produce a session.");
|
|
122
|
+
return session;
|
|
123
|
+
},
|
|
124
|
+
async logout() {
|
|
125
|
+
try {
|
|
126
|
+
await options.client.post(options.endpoints.logout, undefined, {
|
|
127
|
+
auth: "optional",
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
await options.onLogout?.();
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.tsx"],"names":[],"mappings":"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"}
|
package/dist/data.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
2
|
+
import type { CrudApi, ListQueryParams } from "./api";
|
|
3
|
+
export declare const createQueryClient: () => QueryClient;
|
|
4
|
+
export declare const createQueryKeys: (entity: string) => {
|
|
5
|
+
all: readonly [string];
|
|
6
|
+
lists: () => readonly [string, "list"];
|
|
7
|
+
list: (params?: ListQueryParams) => readonly [string, "list", ListQueryParams];
|
|
8
|
+
infinite: (params?: ListQueryParams) => readonly [string, "infinite", ListQueryParams];
|
|
9
|
+
details: () => readonly [string, "detail"];
|
|
10
|
+
detail: (id: string | number) => readonly [string, "detail", string | number];
|
|
11
|
+
};
|
|
12
|
+
export declare function createCrudHooks<T, Create = Partial<T>, Update = Partial<T>>({ api, keys, }: {
|
|
13
|
+
api: CrudApi<T, Create, Update>;
|
|
14
|
+
keys: ReturnType<typeof createQueryKeys>;
|
|
15
|
+
}): {
|
|
16
|
+
useList(params?: ListQueryParams): import("@tanstack/react-query").UseQueryResult<import("./api").PaginatedResponse<T>, Error>;
|
|
17
|
+
useDetail(id?: string | number | null): import("@tanstack/react-query").UseQueryResult<T, Error>;
|
|
18
|
+
useInfinite(params?: ListQueryParams): import("@tanstack/react-query").UseInfiniteQueryResult<import("@tanstack/query-core").InfiniteData<import("./api").PaginatedResponse<T>, unknown>, Error>;
|
|
19
|
+
useCreate(): import("@tanstack/react-query").UseMutationResult<T, Error, Create, unknown>;
|
|
20
|
+
useUpdate(): import("@tanstack/react-query").UseMutationResult<T, Error, {
|
|
21
|
+
id: string | number;
|
|
22
|
+
data: Update;
|
|
23
|
+
}, unknown>;
|
|
24
|
+
useDelete(): import("@tanstack/react-query").UseMutationResult<void, Error, string | number, unknown>;
|
|
25
|
+
};
|
package/dist/data.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { QueryClient, useQuery, useInfiniteQuery, useMutation, useQueryClient, } from "@tanstack/react-query";
|
|
2
|
+
export const createQueryClient = () => new QueryClient({
|
|
3
|
+
defaultOptions: {
|
|
4
|
+
queries: {
|
|
5
|
+
staleTime: 300000,
|
|
6
|
+
gcTime: 600000,
|
|
7
|
+
refetchOnWindowFocus: false,
|
|
8
|
+
retry: (count, error) => count < 2 &&
|
|
9
|
+
!(error && "status" in error && Number(error.status) < 500),
|
|
10
|
+
},
|
|
11
|
+
mutations: { retry: false },
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
export const createQueryKeys = (entity) => ({
|
|
15
|
+
all: [entity],
|
|
16
|
+
lists: () => [entity, "list"],
|
|
17
|
+
list: (params = {}) => [entity, "list", params],
|
|
18
|
+
infinite: (params = {}) => [entity, "infinite", params],
|
|
19
|
+
details: () => [entity, "detail"],
|
|
20
|
+
detail: (id) => [entity, "detail", id],
|
|
21
|
+
});
|
|
22
|
+
export function createCrudHooks({ api, keys, }) {
|
|
23
|
+
return {
|
|
24
|
+
useList(params = {}) {
|
|
25
|
+
return useQuery({
|
|
26
|
+
queryKey: keys.list(params),
|
|
27
|
+
queryFn: ({ signal }) => api.getList(params, signal),
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
useDetail(id) {
|
|
31
|
+
return useQuery({
|
|
32
|
+
queryKey: keys.detail(id ?? ""),
|
|
33
|
+
queryFn: ({ signal }) => api.getById(id, signal),
|
|
34
|
+
enabled: id !== null && id !== undefined && id !== "",
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
useInfinite(params = {}) {
|
|
38
|
+
return useInfiniteQuery({
|
|
39
|
+
queryKey: keys.infinite(params),
|
|
40
|
+
initialPageParam: 1,
|
|
41
|
+
queryFn: ({ pageParam, signal }) => api.getList({ ...params, page: pageParam }, signal),
|
|
42
|
+
getNextPageParam: (page) => page.meta.currentPage < page.meta.lastPage
|
|
43
|
+
? page.meta.currentPage + 1
|
|
44
|
+
: undefined,
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
useCreate() {
|
|
48
|
+
const client = useQueryClient();
|
|
49
|
+
return useMutation({
|
|
50
|
+
mutationFn: (payload) => api.create(payload),
|
|
51
|
+
onSuccess: () => client.invalidateQueries({ queryKey: keys.all }),
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
useUpdate() {
|
|
55
|
+
const client = useQueryClient();
|
|
56
|
+
return useMutation({
|
|
57
|
+
mutationFn: ({ id, data }) => api.update(id, data),
|
|
58
|
+
onSuccess: () => client.invalidateQueries({ queryKey: keys.all }),
|
|
59
|
+
});
|
|
60
|
+
},
|
|
61
|
+
useDelete() {
|
|
62
|
+
const client = useQueryClient();
|
|
63
|
+
return useMutation({
|
|
64
|
+
mutationFn: (id) => api.delete(id),
|
|
65
|
+
onSuccess: (_, id) => {
|
|
66
|
+
client.removeQueries({ queryKey: keys.detail(id) });
|
|
67
|
+
return client.invalidateQueries({ queryKey: keys.all });
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=data.js.map
|
package/dist/data.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../src/data.ts"],"names":[],"mappings":"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"}
|
package/dist/examples.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ApiError } from "./api.js";
|
|
2
|
+
/** Explicit in-memory example source, never a fallback for remote failures. */
|
|
3
|
+
export function createExampleApi(initial) {
|
|
4
|
+
let items = structuredClone(initial);
|
|
5
|
+
return {
|
|
6
|
+
async getList(params = {}, signal) {
|
|
7
|
+
signal?.throwIfAborted();
|
|
8
|
+
const page = Number(params.page ?? 1), perPage = Number(params.perPage ?? 25);
|
|
9
|
+
const filtered = items.filter((item) => !params.search ||
|
|
10
|
+
item.name
|
|
11
|
+
?.toLowerCase()
|
|
12
|
+
.includes(String(params.search).toLowerCase()));
|
|
13
|
+
return {
|
|
14
|
+
items: structuredClone(filtered.slice((page - 1) * perPage, page * perPage)),
|
|
15
|
+
meta: {
|
|
16
|
+
currentPage: page,
|
|
17
|
+
perPage,
|
|
18
|
+
lastPage: Math.max(1, Math.ceil(filtered.length / perPage)),
|
|
19
|
+
total: filtered.length,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
async getById(id, signal) {
|
|
24
|
+
signal?.throwIfAborted();
|
|
25
|
+
const item = items.find((value) => value.id === String(id));
|
|
26
|
+
if (!item)
|
|
27
|
+
throw new ApiError("Example item not found", 404);
|
|
28
|
+
return structuredClone(item);
|
|
29
|
+
},
|
|
30
|
+
async create(payload) {
|
|
31
|
+
const item = { ...payload, id: crypto.randomUUID() };
|
|
32
|
+
items.push(item);
|
|
33
|
+
return structuredClone(item);
|
|
34
|
+
},
|
|
35
|
+
async update(id, payload) {
|
|
36
|
+
const index = items.findIndex((item) => item.id === String(id));
|
|
37
|
+
if (index < 0)
|
|
38
|
+
throw new ApiError("Example item not found", 404);
|
|
39
|
+
items[index] = { ...items[index], ...payload, id: String(id) };
|
|
40
|
+
return structuredClone(items[index]);
|
|
41
|
+
},
|
|
42
|
+
async delete(id) {
|
|
43
|
+
items = items.filter((item) => item.id !== String(id));
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=examples.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"examples.js","sourceRoot":"","sources":["../src/examples.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAgB,MAAM,OAAO,CAAC;AAC/C,+EAA+E;AAC/E,MAAM,UAAU,gBAAgB,CAC9B,OAAY;IAEZ,IAAI,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,MAAM;YAC/B,MAAM,EAAE,cAAc,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,EACnC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;YACzC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAC3B,CAAC,IAAI,EAAE,EAAE,CACP,CAAC,MAAM,CAAC,MAAM;gBACd,IAAI,CAAC,IAAI;oBACP,EAAE,WAAW,EAAE;qBACd,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,CACnD,CAAC;YACF,OAAO;gBACL,KAAK,EAAE,eAAe,CACpB,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,CACrD;gBACD,IAAI,EAAE;oBACJ,WAAW,EAAE,IAAI;oBACjB,OAAO;oBACP,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC;oBAC3D,KAAK,EAAE,QAAQ,CAAC,MAAM;iBACvB;aACF,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM;YACtB,MAAM,EAAE,cAAc,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5D,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,QAAQ,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;YAC7D,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,OAAO;YAClB,MAAM,IAAI,GAAG,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE,EAAO,CAAC;YAC1D,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjB,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO;YACtB,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;YAChE,IAAI,KAAK,GAAG,CAAC;gBAAE,MAAM,IAAI,QAAQ,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;YACjE,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;YAC/D,OAAO,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACvC,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,EAAE;YACb,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,CAAC;KACF,CAAC;AACJ,CAAC"}
|