@diphyx/harlemify 1.0.4 → 3.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/README.md +43 -31
- package/dist/module.d.mts +12 -2
- package/dist/module.d.ts +12 -2
- package/dist/module.json +1 -1
- package/dist/module.mjs +5 -1
- package/dist/runtime/composables/use.d.ts +12 -20
- package/dist/runtime/composables/use.js +6 -17
- package/dist/runtime/core/api.d.ts +17 -40
- package/dist/runtime/core/api.js +11 -71
- package/dist/runtime/core/store.d.ts +44 -49
- package/dist/runtime/core/store.js +489 -208
- package/dist/runtime/index.d.ts +14 -6
- package/dist/runtime/index.js +6 -3
- package/dist/runtime/shared.d.ts +4 -2
- package/dist/runtime/utils/adapter.d.ts +24 -0
- package/dist/runtime/utils/adapter.js +35 -0
- package/dist/runtime/utils/cache.d.ts +10 -0
- package/dist/runtime/utils/cache.js +26 -0
- package/dist/runtime/utils/endpoint.d.ts +21 -21
- package/dist/runtime/utils/endpoint.js +32 -23
- package/dist/runtime/utils/errors.d.ts +22 -0
- package/dist/runtime/utils/errors.js +33 -0
- package/dist/runtime/utils/memory.d.ts +40 -0
- package/dist/runtime/utils/memory.js +87 -0
- package/dist/runtime/utils/schema.d.ts +10 -4
- package/dist/runtime/utils/schema.js +35 -3
- package/dist/runtime/utils/transform.js +6 -4
- package/package.json +4 -2
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { defineApiAdapter } from "./utils/adapter.js";
|
|
2
|
+
export { Endpoint, EndpointMethod, EndpointStatus, resolveEndpointUrl } from "./utils/endpoint.js";
|
|
3
|
+
export { ApiErrorSource, ApiError, ApiRequestError, ApiResponseError } from "./utils/errors.js";
|
|
4
|
+
export { Memory, createMemoryBuilder } from "./utils/memory.js";
|
|
2
5
|
export { getMeta, resolveSchema } from "./utils/schema.js";
|
|
3
|
-
export { createApi
|
|
4
|
-
export { createStore
|
|
6
|
+
export { createApi } from "./core/api.js";
|
|
7
|
+
export { createStore } from "./core/store.js";
|
|
5
8
|
export { useStoreAlias } from "./composables/use.js";
|
|
6
|
-
export type {
|
|
7
|
-
export type { EndpointDefinition } from "./utils/endpoint.js";
|
|
9
|
+
export type { ApiAdapter, ApiAdapterRequest, ApiAdapterResponse, ApiFetchAdapterOptions, DefineApiAdapter, } from "./utils/adapter.js";
|
|
10
|
+
export type { EndpointBuilder, EndpointChain, EndpointDefinition, EndpointUrl } from "./utils/endpoint.js";
|
|
11
|
+
export type { ApiErrorOptions } from "./utils/errors.js";
|
|
12
|
+
export type { MemoryBuilder, MemoryDefinition, MemoryMutation, MemoryTarget, EditOptions, AddOptions, UnitMemoryBuilder, UnitsMemoryBuilder, } from "./utils/memory.js";
|
|
8
13
|
export type { SchemaMeta } from "./utils/schema.js";
|
|
9
|
-
export type {
|
|
14
|
+
export type { Api, ApiOptions, ApiRequestBody, ApiRequestHeader, ApiRequestOptions, ApiRequestQuery, EndpointMethodOptions, } from "./core/api.js";
|
|
15
|
+
export type { ActionDefinition, ActionFunction, ActionOptions, ActionStatus, ActionsConfig, Store, StoreActions, StoreHooks, StoreMemory, StoreMonitor, StoreOptions, } from "./core/store.js";
|
|
16
|
+
export type { StoreAlias } from "./composables/use.js";
|
|
17
|
+
export type { SharedConfig } from "./shared.js";
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { defineApiAdapter } from "./utils/adapter.js";
|
|
2
|
+
export { Endpoint, EndpointMethod, EndpointStatus, resolveEndpointUrl } from "./utils/endpoint.js";
|
|
3
|
+
export { ApiErrorSource, ApiError, ApiRequestError, ApiResponseError } from "./utils/errors.js";
|
|
4
|
+
export { Memory, createMemoryBuilder } from "./utils/memory.js";
|
|
2
5
|
export { getMeta, resolveSchema } from "./utils/schema.js";
|
|
3
|
-
export { createApi
|
|
4
|
-
export { createStore
|
|
6
|
+
export { createApi } from "./core/api.js";
|
|
7
|
+
export { createStore } from "./core/store.js";
|
|
5
8
|
export { useStoreAlias } from "./composables/use.js";
|
package/dist/runtime/shared.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { ApiFetchAdapterOptions } from "./utils/adapter.js";
|
|
1
2
|
export type SharedConfig = {
|
|
2
3
|
api?: {
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
headers?: Record<string, string>;
|
|
5
|
+
query?: Record<string, unknown>;
|
|
6
|
+
adapter?: ApiFetchAdapterOptions;
|
|
5
7
|
};
|
|
6
8
|
};
|
|
7
9
|
export declare const sharedConfig: SharedConfig;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { EndpointMethod } from "./endpoint.js";
|
|
2
|
+
export interface ApiAdapterRequest {
|
|
3
|
+
method: EndpointMethod;
|
|
4
|
+
url: string;
|
|
5
|
+
body?: unknown;
|
|
6
|
+
query?: Record<string, unknown>;
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
}
|
|
10
|
+
export interface ApiAdapterResponse<T = unknown> {
|
|
11
|
+
data: T;
|
|
12
|
+
status?: number;
|
|
13
|
+
}
|
|
14
|
+
export type ApiAdapter<T = unknown> = (request: ApiAdapterRequest) => Promise<ApiAdapterResponse<T>>;
|
|
15
|
+
export type DefineApiAdapter<T = unknown, O = unknown> = (options?: O) => ApiAdapter<T>;
|
|
16
|
+
export interface ApiFetchAdapterOptions {
|
|
17
|
+
baseURL?: string;
|
|
18
|
+
timeout?: number;
|
|
19
|
+
retry?: number | false;
|
|
20
|
+
retryDelay?: number;
|
|
21
|
+
retryStatusCodes?: number[];
|
|
22
|
+
responseType?: "json" | "text" | "blob" | "arrayBuffer";
|
|
23
|
+
}
|
|
24
|
+
export declare function defineApiAdapter<T = unknown>(options?: ApiFetchAdapterOptions): ApiAdapter<T>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ApiRequestError, ApiResponseError } from "./errors.js";
|
|
2
|
+
export function defineApiAdapter(options) {
|
|
3
|
+
return async (request) => {
|
|
4
|
+
const data = await $fetch(request.url, {
|
|
5
|
+
baseURL: options?.baseURL,
|
|
6
|
+
method: request.method,
|
|
7
|
+
headers: request.headers,
|
|
8
|
+
query: request.query,
|
|
9
|
+
body: request.body,
|
|
10
|
+
timeout: options?.timeout,
|
|
11
|
+
signal: request.signal,
|
|
12
|
+
retry: options?.retry,
|
|
13
|
+
retryDelay: options?.retryDelay,
|
|
14
|
+
retryStatusCodes: options?.retryStatusCodes,
|
|
15
|
+
responseType: options?.responseType,
|
|
16
|
+
onRequestError({ request: request2, options: options2, error }) {
|
|
17
|
+
throw new ApiRequestError({
|
|
18
|
+
method: options2.method,
|
|
19
|
+
url: request2.toString(),
|
|
20
|
+
message: error?.message
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
onResponseError({ request: request2, options: options2, error }) {
|
|
24
|
+
throw new ApiResponseError({
|
|
25
|
+
method: options2.method,
|
|
26
|
+
url: request2.toString(),
|
|
27
|
+
message: error?.message
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
return {
|
|
32
|
+
data
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface Cache<K, V> {
|
|
2
|
+
get(key: K): V | undefined;
|
|
3
|
+
set(key: K, value: V): void;
|
|
4
|
+
delete(key: K): boolean;
|
|
5
|
+
clear(): void;
|
|
6
|
+
size(): number;
|
|
7
|
+
has(key: K): boolean;
|
|
8
|
+
entries(): IterableIterator<[K, V]>;
|
|
9
|
+
}
|
|
10
|
+
export declare function createCache<K, V>(): Cache<K, V>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function createCache() {
|
|
2
|
+
const map = /* @__PURE__ */ new Map();
|
|
3
|
+
return {
|
|
4
|
+
get(key) {
|
|
5
|
+
return map.get(key);
|
|
6
|
+
},
|
|
7
|
+
set(key, value) {
|
|
8
|
+
map.set(key, value);
|
|
9
|
+
},
|
|
10
|
+
delete(key) {
|
|
11
|
+
return map.delete(key);
|
|
12
|
+
},
|
|
13
|
+
clear() {
|
|
14
|
+
map.clear();
|
|
15
|
+
},
|
|
16
|
+
size() {
|
|
17
|
+
return map.size;
|
|
18
|
+
},
|
|
19
|
+
has(key) {
|
|
20
|
+
return map.has(key);
|
|
21
|
+
},
|
|
22
|
+
entries() {
|
|
23
|
+
return map.entries();
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ApiAdapter } from "./adapter.js";
|
|
1
2
|
import type { Capitalize } from "./transform.js";
|
|
2
3
|
export declare enum EndpointMethod {
|
|
3
4
|
GET = "get",
|
|
@@ -6,33 +7,32 @@ export declare enum EndpointMethod {
|
|
|
6
7
|
PATCH = "patch",
|
|
7
8
|
DELETE = "delete"
|
|
8
9
|
}
|
|
9
|
-
export declare enum Endpoint {
|
|
10
|
-
GET_UNIT = "getUnit",
|
|
11
|
-
GET_UNITS = "getUnits",
|
|
12
|
-
POST_UNIT = "postUnit",
|
|
13
|
-
POST_UNITS = "postUnits",
|
|
14
|
-
PUT_UNIT = "putUnit",
|
|
15
|
-
PUT_UNITS = "putUnits",
|
|
16
|
-
PATCH_UNIT = "patchUnit",
|
|
17
|
-
PATCH_UNITS = "patchUnits",
|
|
18
|
-
DELETE_UNIT = "deleteUnit",
|
|
19
|
-
DELETE_UNITS = "deleteUnits"
|
|
20
|
-
}
|
|
21
10
|
export declare enum EndpointStatus {
|
|
22
11
|
IDLE = "idle",
|
|
23
12
|
PENDING = "pending",
|
|
24
13
|
SUCCESS = "success",
|
|
25
14
|
FAILED = "failed"
|
|
26
15
|
}
|
|
27
|
-
export
|
|
28
|
-
|
|
29
|
-
|
|
16
|
+
export type EndpointUrl<S> = string | ((params: Partial<S>) => string);
|
|
17
|
+
export interface EndpointDefinition<S = Record<string, unknown>> {
|
|
18
|
+
readonly method: EndpointMethod;
|
|
19
|
+
readonly url: EndpointUrl<S>;
|
|
20
|
+
readonly adapter?: ApiAdapter<any>;
|
|
21
|
+
}
|
|
22
|
+
export interface EndpointChain<S> {
|
|
23
|
+
readonly method: EndpointMethod;
|
|
24
|
+
readonly url: EndpointUrl<S>;
|
|
25
|
+
readonly adapter?: ApiAdapter<any>;
|
|
26
|
+
withAdapter(adapter: ApiAdapter<any>): EndpointDefinition<S>;
|
|
27
|
+
}
|
|
28
|
+
export interface EndpointBuilder {
|
|
29
|
+
get<S = Record<string, unknown>>(url: EndpointUrl<S>): EndpointChain<S>;
|
|
30
|
+
post<S = Record<string, unknown>>(url: EndpointUrl<S>): EndpointChain<S>;
|
|
31
|
+
put<S = Record<string, unknown>>(url: EndpointUrl<S>): EndpointChain<S>;
|
|
32
|
+
patch<S = Record<string, unknown>>(url: EndpointUrl<S>): EndpointChain<S>;
|
|
33
|
+
delete<S = Record<string, unknown>>(url: EndpointUrl<S>): EndpointChain<S>;
|
|
30
34
|
}
|
|
35
|
+
export declare const Endpoint: EndpointBuilder;
|
|
31
36
|
export type EndpointStatusFlag<S extends EndpointStatus = EndpointStatus> = `Is${Capitalize<S>}`;
|
|
32
|
-
export type EndpointStatusName<K extends Endpoint = Endpoint, S extends EndpointStatus = EndpointStatus> = `${K}${EndpointStatusFlag<S>}`;
|
|
33
37
|
export declare function makeEndpointStatusFlag<S extends EndpointStatus>(status: S): EndpointStatusFlag<S>;
|
|
34
|
-
export declare function
|
|
35
|
-
export declare function getEndpoint<T = Record<string, unknown>>(endpoints: Partial<Record<Endpoint, EndpointDefinition<T>>> | undefined, endpoint: Endpoint): EndpointDefinition<T>;
|
|
36
|
-
export declare function resolveEndpointUrl<T>(endpoint: EndpointDefinition<T>, params?: {
|
|
37
|
-
[key: string]: unknown;
|
|
38
|
-
}): string;
|
|
38
|
+
export declare function resolveEndpointUrl<S>(endpoint: EndpointDefinition<S>, params?: Partial<S>): string;
|
|
@@ -7,19 +7,6 @@ export var EndpointMethod = /* @__PURE__ */ ((EndpointMethod2) => {
|
|
|
7
7
|
EndpointMethod2["DELETE"] = "delete";
|
|
8
8
|
return EndpointMethod2;
|
|
9
9
|
})(EndpointMethod || {});
|
|
10
|
-
export var Endpoint = /* @__PURE__ */ ((Endpoint2) => {
|
|
11
|
-
Endpoint2["GET_UNIT"] = "getUnit";
|
|
12
|
-
Endpoint2["GET_UNITS"] = "getUnits";
|
|
13
|
-
Endpoint2["POST_UNIT"] = "postUnit";
|
|
14
|
-
Endpoint2["POST_UNITS"] = "postUnits";
|
|
15
|
-
Endpoint2["PUT_UNIT"] = "putUnit";
|
|
16
|
-
Endpoint2["PUT_UNITS"] = "putUnits";
|
|
17
|
-
Endpoint2["PATCH_UNIT"] = "patchUnit";
|
|
18
|
-
Endpoint2["PATCH_UNITS"] = "patchUnits";
|
|
19
|
-
Endpoint2["DELETE_UNIT"] = "deleteUnit";
|
|
20
|
-
Endpoint2["DELETE_UNITS"] = "deleteUnits";
|
|
21
|
-
return Endpoint2;
|
|
22
|
-
})(Endpoint || {});
|
|
23
10
|
export var EndpointStatus = /* @__PURE__ */ ((EndpointStatus2) => {
|
|
24
11
|
EndpointStatus2["IDLE"] = "idle";
|
|
25
12
|
EndpointStatus2["PENDING"] = "pending";
|
|
@@ -27,21 +14,43 @@ export var EndpointStatus = /* @__PURE__ */ ((EndpointStatus2) => {
|
|
|
27
14
|
EndpointStatus2["FAILED"] = "failed";
|
|
28
15
|
return EndpointStatus2;
|
|
29
16
|
})(EndpointStatus || {});
|
|
30
|
-
|
|
31
|
-
return
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
17
|
+
function createEndpointChain(method, url) {
|
|
18
|
+
return {
|
|
19
|
+
method,
|
|
20
|
+
url,
|
|
21
|
+
adapter: void 0,
|
|
22
|
+
withAdapter(adapter) {
|
|
23
|
+
return {
|
|
24
|
+
method,
|
|
25
|
+
url,
|
|
26
|
+
adapter
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
};
|
|
35
30
|
}
|
|
36
|
-
export
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
export const Endpoint = {
|
|
32
|
+
get(url) {
|
|
33
|
+
return createEndpointChain("get" /* GET */, url);
|
|
34
|
+
},
|
|
35
|
+
post(url) {
|
|
36
|
+
return createEndpointChain("post" /* POST */, url);
|
|
37
|
+
},
|
|
38
|
+
put(url) {
|
|
39
|
+
return createEndpointChain("put" /* PUT */, url);
|
|
40
|
+
},
|
|
41
|
+
patch(url) {
|
|
42
|
+
return createEndpointChain("patch" /* PATCH */, url);
|
|
43
|
+
},
|
|
44
|
+
delete(url) {
|
|
45
|
+
return createEndpointChain("delete" /* DELETE */, url);
|
|
39
46
|
}
|
|
40
|
-
|
|
47
|
+
};
|
|
48
|
+
export function makeEndpointStatusFlag(status) {
|
|
49
|
+
return `Is${capitalize(status)}`;
|
|
41
50
|
}
|
|
42
51
|
export function resolveEndpointUrl(endpoint, params) {
|
|
43
52
|
if (typeof endpoint.url === "function") {
|
|
44
|
-
return endpoint.url(params);
|
|
53
|
+
return endpoint.url(params ?? {});
|
|
45
54
|
}
|
|
46
55
|
return endpoint.url;
|
|
47
56
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare enum ApiErrorSource {
|
|
2
|
+
REQUEST = "request",
|
|
3
|
+
RESPONSE = "response"
|
|
4
|
+
}
|
|
5
|
+
export interface ApiErrorOptions {
|
|
6
|
+
source: ApiErrorSource;
|
|
7
|
+
method: string;
|
|
8
|
+
url: string;
|
|
9
|
+
message?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class ApiError extends Error {
|
|
12
|
+
source: ApiErrorSource;
|
|
13
|
+
method: string;
|
|
14
|
+
url: string;
|
|
15
|
+
constructor(options: ApiErrorOptions);
|
|
16
|
+
}
|
|
17
|
+
export declare class ApiRequestError extends ApiError {
|
|
18
|
+
constructor(options: Omit<ApiErrorOptions, "source">);
|
|
19
|
+
}
|
|
20
|
+
export declare class ApiResponseError extends ApiError {
|
|
21
|
+
constructor(options: Omit<ApiErrorOptions, "source">);
|
|
22
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export var ApiErrorSource = /* @__PURE__ */ ((ApiErrorSource2) => {
|
|
2
|
+
ApiErrorSource2["REQUEST"] = "request";
|
|
3
|
+
ApiErrorSource2["RESPONSE"] = "response";
|
|
4
|
+
return ApiErrorSource2;
|
|
5
|
+
})(ApiErrorSource || {});
|
|
6
|
+
export class ApiError extends Error {
|
|
7
|
+
source;
|
|
8
|
+
method;
|
|
9
|
+
url;
|
|
10
|
+
constructor(options) {
|
|
11
|
+
super(options.message ?? "Unknown error");
|
|
12
|
+
this.name = "ApiError";
|
|
13
|
+
this.source = options.source;
|
|
14
|
+
this.method = options.method;
|
|
15
|
+
this.url = options.url;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export class ApiRequestError extends ApiError {
|
|
19
|
+
constructor(options) {
|
|
20
|
+
super({
|
|
21
|
+
...options,
|
|
22
|
+
source: "request" /* REQUEST */
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export class ApiResponseError extends ApiError {
|
|
27
|
+
constructor(options) {
|
|
28
|
+
super({
|
|
29
|
+
...options,
|
|
30
|
+
source: "response" /* RESPONSE */
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type MemoryTarget = "unit" | "units";
|
|
2
|
+
export type MemoryMutation = "set" | "edit" | "drop" | "add";
|
|
3
|
+
export interface EditOptions {
|
|
4
|
+
deep?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface AddOptions {
|
|
7
|
+
prepend?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface MemoryDefinition {
|
|
10
|
+
readonly on: MemoryTarget;
|
|
11
|
+
readonly path: string[];
|
|
12
|
+
readonly mutation?: MemoryMutation;
|
|
13
|
+
readonly prepend?: boolean;
|
|
14
|
+
readonly deep?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface UnitMemoryBuilder<_S = unknown> extends MemoryDefinition {
|
|
17
|
+
set(): MemoryDefinition;
|
|
18
|
+
edit(options?: EditOptions): MemoryDefinition;
|
|
19
|
+
drop(): MemoryDefinition;
|
|
20
|
+
}
|
|
21
|
+
export interface UnitsMemoryBuilder<_S = unknown> extends MemoryDefinition {
|
|
22
|
+
set(): MemoryDefinition;
|
|
23
|
+
edit(options?: EditOptions): MemoryDefinition;
|
|
24
|
+
drop(): MemoryDefinition;
|
|
25
|
+
add(options?: AddOptions): MemoryDefinition;
|
|
26
|
+
}
|
|
27
|
+
export interface UnitFunction<S> {
|
|
28
|
+
(): UnitMemoryBuilder<S>;
|
|
29
|
+
<K extends keyof S & string>(key: K): UnitMemoryBuilder<S[K]>;
|
|
30
|
+
<K extends keyof S & string, K2 extends keyof S[K] & string>(key: K, nested: K2): UnitMemoryBuilder<S[K][K2]>;
|
|
31
|
+
}
|
|
32
|
+
export interface UnitsFunction<S> {
|
|
33
|
+
(): UnitsMemoryBuilder<S>;
|
|
34
|
+
}
|
|
35
|
+
export interface MemoryBuilder<S = unknown> {
|
|
36
|
+
unit: UnitFunction<S>;
|
|
37
|
+
units: UnitsFunction<S>;
|
|
38
|
+
}
|
|
39
|
+
export declare function createMemoryBuilder<S>(): MemoryBuilder<S>;
|
|
40
|
+
export declare const Memory: MemoryBuilder<any>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
function createUnitMemoryBuilder(path = []) {
|
|
2
|
+
const definition = {
|
|
3
|
+
on: "unit",
|
|
4
|
+
path
|
|
5
|
+
};
|
|
6
|
+
return {
|
|
7
|
+
...definition,
|
|
8
|
+
set() {
|
|
9
|
+
return {
|
|
10
|
+
on: "unit",
|
|
11
|
+
path,
|
|
12
|
+
mutation: "set"
|
|
13
|
+
};
|
|
14
|
+
},
|
|
15
|
+
edit(options) {
|
|
16
|
+
return {
|
|
17
|
+
on: "unit",
|
|
18
|
+
path,
|
|
19
|
+
mutation: "edit",
|
|
20
|
+
deep: options?.deep
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
drop() {
|
|
24
|
+
return {
|
|
25
|
+
on: "unit",
|
|
26
|
+
path,
|
|
27
|
+
mutation: "drop"
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function createUnitsMemoryBuilder() {
|
|
33
|
+
const definition = {
|
|
34
|
+
on: "units",
|
|
35
|
+
path: []
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
...definition,
|
|
39
|
+
set() {
|
|
40
|
+
return {
|
|
41
|
+
on: "units",
|
|
42
|
+
path: [],
|
|
43
|
+
mutation: "set"
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
edit(options) {
|
|
47
|
+
return {
|
|
48
|
+
on: "units",
|
|
49
|
+
path: [],
|
|
50
|
+
mutation: "edit",
|
|
51
|
+
deep: options?.deep
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
drop() {
|
|
55
|
+
return {
|
|
56
|
+
on: "units",
|
|
57
|
+
path: [],
|
|
58
|
+
mutation: "drop"
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
add(options) {
|
|
62
|
+
return {
|
|
63
|
+
on: "units",
|
|
64
|
+
path: [],
|
|
65
|
+
mutation: "add",
|
|
66
|
+
prepend: options?.prepend
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function createUnitFunction() {
|
|
72
|
+
return function unit(...keys) {
|
|
73
|
+
return createUnitMemoryBuilder(keys);
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function createUnitsFunction() {
|
|
77
|
+
return function units() {
|
|
78
|
+
return createUnitsMemoryBuilder();
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
export function createMemoryBuilder() {
|
|
82
|
+
return {
|
|
83
|
+
unit: createUnitFunction(),
|
|
84
|
+
units: createUnitsFunction()
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export const Memory = createMemoryBuilder();
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import type { z } from "zod";
|
|
2
|
-
|
|
3
|
-
export interface SchemaMeta {
|
|
2
|
+
export interface SchemaMeta<A extends string = string> {
|
|
4
3
|
indicator?: boolean;
|
|
5
|
-
|
|
4
|
+
actions?: A[];
|
|
6
5
|
}
|
|
7
6
|
export declare function getMeta(field: any): SchemaMeta | undefined;
|
|
7
|
+
export interface SchemaFieldInfo<A extends string = string> {
|
|
8
|
+
name: string;
|
|
9
|
+
indicator: boolean;
|
|
10
|
+
actions: A[];
|
|
11
|
+
}
|
|
12
|
+
export declare function getSchemaFields<T extends z.ZodRawShape, A extends string = string>(schema: z.ZodObject<T>): SchemaFieldInfo<A>[];
|
|
13
|
+
export declare function getFieldsForAction<T extends z.ZodRawShape, A extends string = string>(schema: z.ZodObject<T>, action: A): string[];
|
|
8
14
|
export interface ResolveSchemaOptions<S> {
|
|
9
15
|
indicator?: keyof S;
|
|
10
|
-
|
|
16
|
+
action?: string;
|
|
11
17
|
unit?: Partial<S>;
|
|
12
18
|
}
|
|
13
19
|
export declare function resolveSchema<T extends z.ZodRawShape, S extends z.infer<z.ZodObject<T>>>(schema: z.ZodObject<T>, options?: ResolveSchemaOptions<S>): {
|
|
@@ -1,21 +1,53 @@
|
|
|
1
1
|
export function getMeta(field) {
|
|
2
2
|
return field.meta();
|
|
3
3
|
}
|
|
4
|
+
const schemaFieldsCache = /* @__PURE__ */ new WeakMap();
|
|
5
|
+
export function getSchemaFields(schema) {
|
|
6
|
+
const cached = schemaFieldsCache.get(schema);
|
|
7
|
+
if (cached) {
|
|
8
|
+
return cached;
|
|
9
|
+
}
|
|
10
|
+
const fields = [];
|
|
11
|
+
for (const key in schema.shape) {
|
|
12
|
+
const meta = getMeta(schema.shape[key]);
|
|
13
|
+
fields.push({
|
|
14
|
+
name: key,
|
|
15
|
+
indicator: meta?.indicator ?? false,
|
|
16
|
+
actions: meta?.actions ?? []
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
schemaFieldsCache.set(schema, fields);
|
|
20
|
+
return fields;
|
|
21
|
+
}
|
|
22
|
+
export function getFieldsForAction(schema, action) {
|
|
23
|
+
const fields = [];
|
|
24
|
+
for (const key in schema.shape) {
|
|
25
|
+
const meta = getMeta(schema.shape[key]);
|
|
26
|
+
if (meta?.actions) {
|
|
27
|
+
const actionsSet = new Set(meta.actions);
|
|
28
|
+
if (actionsSet.has(action)) {
|
|
29
|
+
fields.push(key);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return fields;
|
|
34
|
+
}
|
|
4
35
|
export function resolveSchema(schema, options) {
|
|
5
36
|
const output = {
|
|
6
37
|
indicator: options?.indicator ?? "id",
|
|
7
38
|
keys: {},
|
|
8
39
|
values: {}
|
|
9
40
|
};
|
|
10
|
-
for (const key
|
|
41
|
+
for (const key in schema.shape) {
|
|
11
42
|
const meta = getMeta(schema.shape[key]);
|
|
12
43
|
if (meta?.indicator) {
|
|
13
44
|
output.indicator = key;
|
|
14
45
|
}
|
|
15
|
-
if (!options?.
|
|
46
|
+
if (!options?.action || !meta?.actions) {
|
|
16
47
|
continue;
|
|
17
48
|
}
|
|
18
|
-
|
|
49
|
+
const actionsSet = new Set(meta.actions);
|
|
50
|
+
if (actionsSet.has(options.action)) {
|
|
19
51
|
output.keys[key] = true;
|
|
20
52
|
if (options?.unit && key in options.unit) {
|
|
21
53
|
output.values[key] = options.unit[key];
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
+
const VOWELS = /* @__PURE__ */ new Set(["a", "e", "i", "o", "u"]);
|
|
2
|
+
const SIBILANTS = /* @__PURE__ */ new Set(["s", "x", "z"]);
|
|
3
|
+
const SIBILANT_PAIRS = /* @__PURE__ */ new Set(["ch", "sh"]);
|
|
1
4
|
export function pluralize(word) {
|
|
2
5
|
if (!word) return word;
|
|
3
|
-
const vowels = ["a", "e", "i", "o", "u"];
|
|
4
6
|
const lastChar = word.slice(-1).toLowerCase();
|
|
5
7
|
const lastTwo = word.slice(-2).toLowerCase();
|
|
6
8
|
const beforeLast = word.slice(-2, -1).toLowerCase();
|
|
7
|
-
if (lastChar === "y" && !
|
|
9
|
+
if (lastChar === "y" && !VOWELS.has(beforeLast)) {
|
|
8
10
|
return word.slice(0, -1) + "ies";
|
|
9
11
|
}
|
|
10
|
-
if (
|
|
12
|
+
if (SIBILANTS.has(lastChar)) {
|
|
11
13
|
return word + "es";
|
|
12
14
|
}
|
|
13
|
-
if (
|
|
15
|
+
if (SIBILANT_PAIRS.has(lastTwo)) {
|
|
14
16
|
return word + "es";
|
|
15
17
|
}
|
|
16
18
|
return word + "s";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diphyx/harlemify",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "API state management for Nuxt powered by Harlem",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nuxt",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"@nuxt/module-builder": "^0.8.0",
|
|
53
53
|
"@nuxt/schema": "^3.14.0",
|
|
54
54
|
"@nuxt/test-utils": "^3.14.0",
|
|
55
|
+
"@playwright/test": "^1.50.0",
|
|
55
56
|
"@types/node": "^22.0.0",
|
|
56
57
|
"eslint": "^9.0.0",
|
|
57
58
|
"nuxt": "^3.14.0",
|
|
@@ -64,6 +65,7 @@
|
|
|
64
65
|
"dev": "pnpm nuxt dev playground",
|
|
65
66
|
"build": "nuxt-module-build build",
|
|
66
67
|
"lint": "eslint . --fix",
|
|
67
|
-
"test": "vitest run"
|
|
68
|
+
"test": "vitest run",
|
|
69
|
+
"test:e2e": "playwright test"
|
|
68
70
|
}
|
|
69
71
|
}
|