@diphyx/harlemify 2.0.0 → 4.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 +64 -119
- package/dist/module.d.mts +24 -13
- package/dist/module.d.ts +24 -13
- package/dist/module.json +1 -1
- package/dist/module.mjs +8 -10
- package/dist/runtime/composables/action.d.ts +4 -0
- package/dist/runtime/composables/action.js +8 -0
- package/dist/runtime/config.d.ts +10 -0
- package/dist/runtime/config.js +7 -0
- package/dist/runtime/core/layers/action.d.ts +4 -0
- package/dist/runtime/core/layers/action.js +102 -0
- package/dist/runtime/core/layers/model.d.ts +3 -0
- package/dist/runtime/core/layers/model.js +31 -0
- package/dist/runtime/core/layers/shape.d.ts +45 -0
- package/dist/runtime/core/layers/shape.js +56 -0
- package/dist/runtime/core/layers/view.d.ts +4 -0
- package/dist/runtime/core/layers/view.js +21 -0
- package/dist/runtime/core/store.d.ts +20 -72
- package/dist/runtime/core/store.js +49 -317
- package/dist/runtime/core/types/action.d.ts +162 -0
- package/dist/runtime/core/types/action.js +38 -0
- package/dist/runtime/core/types/model.d.ts +70 -0
- package/dist/runtime/core/types/model.js +5 -0
- package/dist/runtime/core/types/shape.d.ts +46 -0
- package/dist/runtime/core/types/shape.js +0 -0
- package/dist/runtime/core/types/view.d.ts +29 -0
- package/dist/runtime/core/types/view.js +0 -0
- package/dist/runtime/core/utils/action.d.ts +4 -0
- package/dist/runtime/core/utils/action.js +294 -0
- package/dist/runtime/core/utils/model.d.ts +12 -0
- package/dist/runtime/core/utils/model.js +224 -0
- package/dist/runtime/core/utils/shape.d.ts +3 -0
- package/dist/runtime/core/utils/shape.js +29 -0
- package/dist/runtime/core/utils/view.d.ts +5 -0
- package/dist/runtime/core/utils/view.js +19 -0
- package/dist/runtime/index.d.ts +9 -13
- package/dist/runtime/index.js +5 -7
- package/dist/runtime/plugin.js +2 -5
- package/package.json +5 -2
- package/dist/runtime/composables/use.d.ts +0 -30
- package/dist/runtime/composables/use.js +0 -25
- package/dist/runtime/core/adapter.d.ts +0 -33
- package/dist/runtime/core/adapter.js +0 -33
- package/dist/runtime/core/api.d.ts +0 -37
- package/dist/runtime/core/api.js +0 -62
- package/dist/runtime/core/errors.d.ts +0 -22
- package/dist/runtime/core/errors.js +0 -33
- package/dist/runtime/shared.d.ts +0 -9
- package/dist/runtime/shared.js +0 -3
- package/dist/runtime/utils/endpoint.d.ts +0 -40
- package/dist/runtime/utils/endpoint.js +0 -47
- package/dist/runtime/utils/schema.d.ts +0 -17
- package/dist/runtime/utils/schema.js +0 -26
- package/dist/runtime/utils/transform.d.ts +0 -6
- package/dist/runtime/utils/transform.js +0 -20
package/README.md
CHANGED
|
@@ -1,159 +1,104 @@
|
|
|
1
1
|
# Harlemify
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
|
|
5
|
-

|
|
6
|
-
|
|
7
|
-
Define your data schema once with Zod, and Harlemify handles the rest: type-safe API calls, reactive state, request monitoring, and automatic memory management. Your schema becomes the single source of truth for types, validation, and API payloads.
|
|
3
|
+
> Factory-driven state management for Nuxt powered by [Harlem](https://harlemjs.com/)
|
|
8
4
|
|
|
9
5
|
## Features
|
|
10
6
|
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
7
|
+
- **Shape-Driven** - Zod shapes define types and identifiers
|
|
8
|
+
- **Three-Layer Architecture** - Model (state), View (computed), Action (async operations)
|
|
9
|
+
- **Chainable Action Builders** - Fluent `api`, `handle`, `commit` chains
|
|
10
|
+
- **Per-Action Status Tracking** - Built-in `loading`, `status`, `error`, `data` on every action
|
|
11
|
+
- **Concurrency Control** - Block, skip, cancel, or allow concurrent calls
|
|
12
|
+
- **SSR Support** - Server-side rendering with automatic hydration
|
|
16
13
|
|
|
17
|
-
##
|
|
14
|
+
## Install
|
|
18
15
|
|
|
19
16
|
```bash
|
|
20
17
|
npm install @diphyx/harlemify
|
|
21
18
|
```
|
|
22
19
|
|
|
23
|
-
##
|
|
20
|
+
## Setup
|
|
24
21
|
|
|
25
22
|
```typescript
|
|
26
23
|
// nuxt.config.ts
|
|
27
24
|
export default defineNuxtConfig({
|
|
28
25
|
modules: ["@diphyx/harlemify"],
|
|
29
26
|
harlemify: {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
baseURL: "https://api.example.com",
|
|
33
|
-
timeout: 10000,
|
|
34
|
-
},
|
|
27
|
+
action: {
|
|
28
|
+
endpoint: "https://api.example.com",
|
|
35
29
|
},
|
|
36
30
|
},
|
|
37
31
|
});
|
|
38
32
|
```
|
|
39
33
|
|
|
40
|
-
|
|
41
|
-
// stores/user.ts
|
|
42
|
-
import { z } from "zod";
|
|
43
|
-
import { createStore, Endpoint, EndpointMethod } from "@diphyx/harlemify";
|
|
44
|
-
|
|
45
|
-
const UserSchema = z.object({
|
|
46
|
-
id: z.number().meta({ indicator: true }),
|
|
47
|
-
name: z.string().meta({
|
|
48
|
-
methods: [EndpointMethod.POST, EndpointMethod.PATCH],
|
|
49
|
-
}),
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
export type User = z.infer<typeof UserSchema>;
|
|
53
|
-
|
|
54
|
-
export const userStore = createStore("user", UserSchema, {
|
|
55
|
-
[Endpoint.GET_UNITS]: { method: EndpointMethod.GET, url: "/users" },
|
|
56
|
-
[Endpoint.POST_UNITS]: { method: EndpointMethod.POST, url: "/users" },
|
|
57
|
-
[Endpoint.PATCH_UNITS]: { method: EndpointMethod.PATCH, url: (p) => `/users/${p.id}` },
|
|
58
|
-
[Endpoint.DELETE_UNITS]: { method: EndpointMethod.DELETE, url: (p) => `/users/${p.id}` },
|
|
59
|
-
});
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## Custom Adapters
|
|
63
|
-
|
|
64
|
-
Harlemify supports custom HTTP adapters for advanced use cases like streaming responses, file uploads with progress, or custom authentication.
|
|
65
|
-
|
|
66
|
-
### Adapter Hierarchy
|
|
67
|
-
|
|
68
|
-
Adapters are resolved in the following order (highest to lowest priority):
|
|
69
|
-
|
|
70
|
-
1. **Endpoint adapter** - Per-endpoint custom adapter
|
|
71
|
-
2. **Store adapter** - Store-level adapter option
|
|
72
|
-
3. **Module adapter** - Global config in `nuxt.config.ts`
|
|
73
|
-
4. **Default adapter** - Built-in fetch adapter
|
|
74
|
-
|
|
75
|
-
### Built-in Adapter
|
|
76
|
-
|
|
77
|
-
Use `defineApiAdapter` to create an adapter with custom options:
|
|
34
|
+
## Usage
|
|
78
35
|
|
|
79
36
|
```typescript
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
37
|
+
// stores/user.ts
|
|
38
|
+
import { createStore, shape, ActionOneMode, ActionManyMode, type ShapeInfer } from "@diphyx/harlemify";
|
|
39
|
+
|
|
40
|
+
const userShape = shape((factory) => {
|
|
41
|
+
return {
|
|
42
|
+
id: factory.number().meta({
|
|
43
|
+
identifier: true,
|
|
44
|
+
}),
|
|
45
|
+
name: factory.string(),
|
|
46
|
+
email: factory.email(),
|
|
47
|
+
};
|
|
88
48
|
});
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Custom Adapter
|
|
92
|
-
|
|
93
|
-
Create a fully custom adapter for advanced scenarios:
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
import type { ApiAdapter, ApiAdapterRequest } from "@diphyx/harlemify";
|
|
97
|
-
|
|
98
|
-
const streamingAdapter: ApiAdapter<MyType> = async (request: ApiAdapterRequest) => {
|
|
99
|
-
// Custom fetch logic with streaming, progress, etc.
|
|
100
|
-
const response = await fetch(request.url, {
|
|
101
|
-
method: request.method,
|
|
102
|
-
headers: request.headers,
|
|
103
|
-
body: JSON.stringify(request.body),
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
const data = await response.json();
|
|
107
|
-
return { data, status: response.status };
|
|
108
|
-
};
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### Using Adapters
|
|
112
49
|
|
|
113
|
-
|
|
50
|
+
export type User = ShapeInfer<typeof userShape>;
|
|
114
51
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
{
|
|
123
|
-
adapter: customAdapter, // Used for all endpoints in this store
|
|
52
|
+
export const userStore = createStore({
|
|
53
|
+
name: "users",
|
|
54
|
+
model({ one, many }) {
|
|
55
|
+
return {
|
|
56
|
+
current: one(userShape),
|
|
57
|
+
list: many(userShape),
|
|
58
|
+
};
|
|
124
59
|
},
|
|
125
|
-
)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
```typescript
|
|
131
|
-
export const userStore = createStore("user", UserSchema, {
|
|
132
|
-
[Endpoint.GET_UNIT]: {
|
|
133
|
-
method: EndpointMethod.GET,
|
|
134
|
-
url: (p) => `/users/${p.id}`,
|
|
135
|
-
adapter: detailAdapter, // Custom adapter for this endpoint only
|
|
60
|
+
view({ from }) {
|
|
61
|
+
return {
|
|
62
|
+
user: from("current"),
|
|
63
|
+
users: from("list"),
|
|
64
|
+
};
|
|
136
65
|
},
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
66
|
+
action({ api, commit }) {
|
|
67
|
+
return {
|
|
68
|
+
list: api
|
|
69
|
+
.get({
|
|
70
|
+
url: "/users",
|
|
71
|
+
})
|
|
72
|
+
.commit("list", ActionManyMode.SET),
|
|
73
|
+
create: api
|
|
74
|
+
.post({
|
|
75
|
+
url: "/users",
|
|
76
|
+
})
|
|
77
|
+
.commit("list", ActionManyMode.ADD),
|
|
78
|
+
clear: commit("list", ActionManyMode.RESET),
|
|
79
|
+
};
|
|
141
80
|
},
|
|
142
81
|
});
|
|
143
82
|
```
|
|
144
83
|
|
|
145
|
-
|
|
84
|
+
```vue
|
|
85
|
+
<script setup>
|
|
86
|
+
const { view, action } = userStore;
|
|
146
87
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
88
|
+
await action.list();
|
|
89
|
+
</script>
|
|
90
|
+
|
|
91
|
+
<template>
|
|
92
|
+
<div v-if="action.list.loading.value">Loading...</div>
|
|
93
|
+
<ul v-else>
|
|
94
|
+
<li v-for="user in view.users.value" :key="user.id">{{ user.name }}</li>
|
|
95
|
+
</ul>
|
|
96
|
+
</template>
|
|
97
|
+
```
|
|
153
98
|
|
|
154
99
|
## Documentation
|
|
155
100
|
|
|
156
|
-
|
|
101
|
+
[https://diphyx.github.io/harlemify/](https://diphyx.github.io/harlemify/)
|
|
157
102
|
|
|
158
103
|
## License
|
|
159
104
|
|
package/dist/module.d.mts
CHANGED
|
@@ -1,22 +1,33 @@
|
|
|
1
1
|
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
2
|
|
|
3
|
-
interface
|
|
4
|
-
|
|
3
|
+
interface RuntimeModelConfig {
|
|
4
|
+
identifier?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface RuntimeViewConfig {
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface RuntimeActionConfig {
|
|
11
|
+
endpoint?: string;
|
|
12
|
+
headers?: Record<string, string>;
|
|
13
|
+
query?: Record<string, unknown>;
|
|
5
14
|
timeout?: number;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
15
|
+
concurrent?: ActionConcurrent;
|
|
16
|
+
}
|
|
17
|
+
declare enum ActionConcurrent {
|
|
18
|
+
BLOCK = "block",
|
|
19
|
+
SKIP = "skip",
|
|
20
|
+
CANCEL = "cancel",
|
|
21
|
+
ALLOW = "allow"
|
|
10
22
|
}
|
|
11
23
|
|
|
12
|
-
type
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
};
|
|
24
|
+
type RuntimeConfig = {
|
|
25
|
+
model?: RuntimeModelConfig;
|
|
26
|
+
view?: RuntimeViewConfig;
|
|
27
|
+
action?: RuntimeActionConfig;
|
|
28
|
+
logger?: number;
|
|
18
29
|
};
|
|
19
30
|
|
|
20
|
-
declare const _default: _nuxt_schema.NuxtModule<
|
|
31
|
+
declare const _default: _nuxt_schema.NuxtModule<RuntimeConfig, RuntimeConfig, false>;
|
|
21
32
|
|
|
22
33
|
export { _default as default };
|
package/dist/module.d.ts
CHANGED
|
@@ -1,22 +1,33 @@
|
|
|
1
1
|
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
2
|
|
|
3
|
-
interface
|
|
4
|
-
|
|
3
|
+
interface RuntimeModelConfig {
|
|
4
|
+
identifier?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface RuntimeViewConfig {
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface RuntimeActionConfig {
|
|
11
|
+
endpoint?: string;
|
|
12
|
+
headers?: Record<string, string>;
|
|
13
|
+
query?: Record<string, unknown>;
|
|
5
14
|
timeout?: number;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
15
|
+
concurrent?: ActionConcurrent;
|
|
16
|
+
}
|
|
17
|
+
declare enum ActionConcurrent {
|
|
18
|
+
BLOCK = "block",
|
|
19
|
+
SKIP = "skip",
|
|
20
|
+
CANCEL = "cancel",
|
|
21
|
+
ALLOW = "allow"
|
|
10
22
|
}
|
|
11
23
|
|
|
12
|
-
type
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
};
|
|
24
|
+
type RuntimeConfig = {
|
|
25
|
+
model?: RuntimeModelConfig;
|
|
26
|
+
view?: RuntimeViewConfig;
|
|
27
|
+
action?: RuntimeActionConfig;
|
|
28
|
+
logger?: number;
|
|
18
29
|
};
|
|
19
30
|
|
|
20
|
-
declare const _default: _nuxt_schema.NuxtModule<
|
|
31
|
+
declare const _default: _nuxt_schema.NuxtModule<RuntimeConfig, RuntimeConfig, false>;
|
|
21
32
|
|
|
22
33
|
export { _default as default };
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineNuxtModule, createResolver, addTemplate, addPlugin, addImportsDir } from '@nuxt/kit';
|
|
1
|
+
import { defineNuxtModule, createResolver, addTemplate, addPlugin, addImportsDir, addImports } from '@nuxt/kit';
|
|
2
2
|
|
|
3
3
|
const module = defineNuxtModule({
|
|
4
4
|
meta: {
|
|
@@ -8,13 +8,7 @@ const module = defineNuxtModule({
|
|
|
8
8
|
nuxt: ">=3.0.0 || >=4.0.0"
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
|
-
defaults: {
|
|
12
|
-
api: {
|
|
13
|
-
headers: {},
|
|
14
|
-
query: {},
|
|
15
|
-
adapter: {}
|
|
16
|
-
}
|
|
17
|
-
},
|
|
11
|
+
defaults: {},
|
|
18
12
|
setup(options, nuxt) {
|
|
19
13
|
const { resolve } = createResolver(import.meta.url);
|
|
20
14
|
addTemplate({
|
|
@@ -25,9 +19,13 @@ const module = defineNuxtModule({
|
|
|
25
19
|
}
|
|
26
20
|
});
|
|
27
21
|
addPlugin(resolve("./runtime", "plugin"));
|
|
28
|
-
addImportsDir(resolve("./runtime", "core"));
|
|
29
22
|
addImportsDir(resolve("./runtime", "composables"));
|
|
30
|
-
|
|
23
|
+
addImports([
|
|
24
|
+
{
|
|
25
|
+
name: "createStore",
|
|
26
|
+
from: resolve("./runtime/core/store")
|
|
27
|
+
}
|
|
28
|
+
]);
|
|
31
29
|
nuxt.options.build.transpile.push(/@harlem\//);
|
|
32
30
|
}
|
|
33
31
|
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RuntimeModelConfig } from "./core/types/model.js";
|
|
2
|
+
import type { RuntimeViewConfig } from "./core/types/view.js";
|
|
3
|
+
import type { RuntimeActionConfig } from "./core/types/action.js";
|
|
4
|
+
export type RuntimeConfig = {
|
|
5
|
+
model?: RuntimeModelConfig;
|
|
6
|
+
view?: RuntimeViewConfig;
|
|
7
|
+
action?: RuntimeActionConfig;
|
|
8
|
+
logger?: number;
|
|
9
|
+
};
|
|
10
|
+
export declare const runtimeConfig: RuntimeConfig;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ConsolaInstance } from "consola";
|
|
2
|
+
import type { Model } from "../types/model.js";
|
|
3
|
+
import { type RuntimeActionConfig, type ActionFactory } from "../types/action.js";
|
|
4
|
+
export declare function createActionFactory<M extends Model, V>(config?: RuntimeActionConfig, logger?: ConsolaInstance, _model?: M, _view?: V): ActionFactory<M, V>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { buildCommitMethod } from "../utils/action.js";
|
|
2
|
+
import {
|
|
3
|
+
ActionApiMethod,
|
|
4
|
+
DEFINITION
|
|
5
|
+
} from "../types/action.js";
|
|
6
|
+
export function createActionFactory(config, logger, _model, _view) {
|
|
7
|
+
function apiCall(apiDefinition) {
|
|
8
|
+
apiDefinition = {
|
|
9
|
+
endpoint: config?.endpoint,
|
|
10
|
+
headers: config?.headers,
|
|
11
|
+
query: config?.query,
|
|
12
|
+
timeout: config?.timeout,
|
|
13
|
+
concurrent: config?.concurrent,
|
|
14
|
+
...apiDefinition
|
|
15
|
+
};
|
|
16
|
+
const actionDefinition = {
|
|
17
|
+
api: apiDefinition,
|
|
18
|
+
logger
|
|
19
|
+
};
|
|
20
|
+
return {
|
|
21
|
+
handle(callback) {
|
|
22
|
+
const handleDefinition = {
|
|
23
|
+
api: apiDefinition,
|
|
24
|
+
handle: callback,
|
|
25
|
+
logger
|
|
26
|
+
};
|
|
27
|
+
return {
|
|
28
|
+
commit: buildCommitMethod(handleDefinition),
|
|
29
|
+
get [DEFINITION]() {
|
|
30
|
+
return handleDefinition;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
commit: buildCommitMethod(actionDefinition),
|
|
35
|
+
get [DEFINITION]() {
|
|
36
|
+
return actionDefinition;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function apiGet(definition) {
|
|
41
|
+
return apiCall({
|
|
42
|
+
...definition,
|
|
43
|
+
method: ActionApiMethod.GET
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function apiHead(definition) {
|
|
47
|
+
return apiCall({
|
|
48
|
+
...definition,
|
|
49
|
+
method: ActionApiMethod.HEAD
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function apiPost(definition) {
|
|
53
|
+
return apiCall({
|
|
54
|
+
...definition,
|
|
55
|
+
method: ActionApiMethod.POST
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function apiPut(definition) {
|
|
59
|
+
return apiCall({
|
|
60
|
+
...definition,
|
|
61
|
+
method: ActionApiMethod.PUT
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function apiPatch(definition) {
|
|
65
|
+
return apiCall({
|
|
66
|
+
...definition,
|
|
67
|
+
method: ActionApiMethod.PATCH
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function apiDelete(definition) {
|
|
71
|
+
return apiCall({
|
|
72
|
+
...definition,
|
|
73
|
+
method: ActionApiMethod.DELETE
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const api = Object.assign(apiCall, {
|
|
77
|
+
get: apiGet,
|
|
78
|
+
head: apiHead,
|
|
79
|
+
post: apiPost,
|
|
80
|
+
put: apiPut,
|
|
81
|
+
patch: apiPatch,
|
|
82
|
+
delete: apiDelete
|
|
83
|
+
});
|
|
84
|
+
function handle(callback) {
|
|
85
|
+
const definition = {
|
|
86
|
+
handle: callback,
|
|
87
|
+
logger
|
|
88
|
+
};
|
|
89
|
+
return {
|
|
90
|
+
commit: buildCommitMethod(definition),
|
|
91
|
+
get [DEFINITION]() {
|
|
92
|
+
return definition;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
const commit = buildCommitMethod({ logger });
|
|
97
|
+
return {
|
|
98
|
+
api,
|
|
99
|
+
handle,
|
|
100
|
+
commit
|
|
101
|
+
};
|
|
102
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ModelKind
|
|
3
|
+
} from "../types/model.js";
|
|
4
|
+
export function createModelFactory(config, logger) {
|
|
5
|
+
function one(shape, options) {
|
|
6
|
+
return {
|
|
7
|
+
shape,
|
|
8
|
+
kind: ModelKind.OBJECT,
|
|
9
|
+
options: {
|
|
10
|
+
identifier: config?.identifier,
|
|
11
|
+
...options
|
|
12
|
+
},
|
|
13
|
+
logger
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function many(shape, options) {
|
|
17
|
+
return {
|
|
18
|
+
shape,
|
|
19
|
+
kind: ModelKind.ARRAY,
|
|
20
|
+
options: {
|
|
21
|
+
identifier: config?.identifier,
|
|
22
|
+
...options
|
|
23
|
+
},
|
|
24
|
+
logger
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
one,
|
|
29
|
+
many
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ShapeFactory } from "../types/shape.js";
|
|
3
|
+
export declare const primitiveField: {
|
|
4
|
+
string: typeof z.string;
|
|
5
|
+
number: typeof z.number;
|
|
6
|
+
boolean: typeof z.boolean;
|
|
7
|
+
bigint: typeof z.bigint;
|
|
8
|
+
date: typeof z.date;
|
|
9
|
+
};
|
|
10
|
+
export declare const structureField: {
|
|
11
|
+
object: typeof z.object;
|
|
12
|
+
array: typeof z.array;
|
|
13
|
+
tuple: typeof z.tuple;
|
|
14
|
+
record: typeof z.record;
|
|
15
|
+
map: typeof z.map;
|
|
16
|
+
set: typeof z.set;
|
|
17
|
+
enum: typeof z.enum;
|
|
18
|
+
union: typeof z.union;
|
|
19
|
+
literal: typeof z.literal;
|
|
20
|
+
};
|
|
21
|
+
export declare const formatField: {
|
|
22
|
+
email: typeof z.email;
|
|
23
|
+
url: typeof z.url;
|
|
24
|
+
uuid: typeof z.uuid;
|
|
25
|
+
cuid: typeof z.cuid;
|
|
26
|
+
cuid2: typeof z.cuid2;
|
|
27
|
+
ulid: typeof z.ulid;
|
|
28
|
+
nanoid: typeof z.nanoid;
|
|
29
|
+
jwt: typeof z.jwt;
|
|
30
|
+
emoji: typeof z.emoji;
|
|
31
|
+
ipv4: typeof z.ipv4;
|
|
32
|
+
ipv6: typeof z.ipv6;
|
|
33
|
+
mac: typeof z.mac;
|
|
34
|
+
base64: typeof z.base64;
|
|
35
|
+
base64url: typeof z.base64url;
|
|
36
|
+
hex: typeof z.hex;
|
|
37
|
+
};
|
|
38
|
+
export declare const specialField: {
|
|
39
|
+
any: typeof z.any;
|
|
40
|
+
unknown: typeof z.unknown;
|
|
41
|
+
never: typeof z.never;
|
|
42
|
+
nullable: typeof z.nullable;
|
|
43
|
+
optional: typeof z.optional;
|
|
44
|
+
};
|
|
45
|
+
export declare function shape<T extends z.ZodRawShape>(definition: T | ((factory: ShapeFactory) => T)): z.ZodObject<T>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const primitiveField = {
|
|
3
|
+
string: z.string,
|
|
4
|
+
number: z.number,
|
|
5
|
+
boolean: z.boolean,
|
|
6
|
+
bigint: z.bigint,
|
|
7
|
+
date: z.date
|
|
8
|
+
};
|
|
9
|
+
export const structureField = {
|
|
10
|
+
object: z.object,
|
|
11
|
+
array: z.array,
|
|
12
|
+
tuple: z.tuple,
|
|
13
|
+
record: z.record,
|
|
14
|
+
map: z.map,
|
|
15
|
+
set: z.set,
|
|
16
|
+
enum: z.enum,
|
|
17
|
+
union: z.union,
|
|
18
|
+
literal: z.literal
|
|
19
|
+
};
|
|
20
|
+
export const formatField = {
|
|
21
|
+
email: z.email,
|
|
22
|
+
url: z.url,
|
|
23
|
+
uuid: z.uuid,
|
|
24
|
+
cuid: z.cuid,
|
|
25
|
+
cuid2: z.cuid2,
|
|
26
|
+
ulid: z.ulid,
|
|
27
|
+
nanoid: z.nanoid,
|
|
28
|
+
jwt: z.jwt,
|
|
29
|
+
emoji: z.emoji,
|
|
30
|
+
ipv4: z.ipv4,
|
|
31
|
+
ipv6: z.ipv6,
|
|
32
|
+
mac: z.mac,
|
|
33
|
+
base64: z.base64,
|
|
34
|
+
base64url: z.base64url,
|
|
35
|
+
hex: z.hex
|
|
36
|
+
};
|
|
37
|
+
export const specialField = {
|
|
38
|
+
any: z.any,
|
|
39
|
+
unknown: z.unknown,
|
|
40
|
+
never: z.never,
|
|
41
|
+
nullable: z.nullable,
|
|
42
|
+
optional: z.optional
|
|
43
|
+
};
|
|
44
|
+
export function shape(definition) {
|
|
45
|
+
if (typeof definition === "function") {
|
|
46
|
+
return z.object(
|
|
47
|
+
definition({
|
|
48
|
+
...primitiveField,
|
|
49
|
+
...structureField,
|
|
50
|
+
...formatField,
|
|
51
|
+
...specialField
|
|
52
|
+
})
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return z.object(definition);
|
|
56
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ConsolaInstance } from "consola";
|
|
2
|
+
import type { Model } from "../types/model.js";
|
|
3
|
+
import type { RuntimeViewConfig, ViewFactory } from "../types/view.js";
|
|
4
|
+
export declare function createViewFactory<M extends Model>(config?: RuntimeViewConfig, logger?: ConsolaInstance, _model?: M): ViewFactory<M>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function createViewFactory(config, logger, _model) {
|
|
2
|
+
function from(source, resolver) {
|
|
3
|
+
const definition = {
|
|
4
|
+
sources: [source],
|
|
5
|
+
resolver,
|
|
6
|
+
logger
|
|
7
|
+
};
|
|
8
|
+
return definition;
|
|
9
|
+
}
|
|
10
|
+
function merge(sources, resolver) {
|
|
11
|
+
return {
|
|
12
|
+
sources,
|
|
13
|
+
resolver,
|
|
14
|
+
logger
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
from,
|
|
19
|
+
merge
|
|
20
|
+
};
|
|
21
|
+
}
|