apixa 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/LICENSE +21 -0
- package/README.md +257 -2
- package/dist/chunk-6ZX7GAWG.js +10 -0
- package/dist/chunk-A3QU5MFP.js +907 -0
- package/dist/chunk-DGSIZXRI.js +247 -0
- package/dist/chunk-GWZTJ7LM.js +2410 -0
- package/dist/chunk-IAQ5YOVE.js +10 -0
- package/dist/chunk-KE7UM4VW.js +707 -0
- package/dist/chunk-LARJYKRJ.js +117 -0
- package/dist/chunk-MLPW6EET.js +10 -0
- package/dist/chunk-QVKMZELC.js +10 -0
- package/dist/chunk-QY5YMHHN.js +607 -0
- package/dist/chunk-QZIU7J3G.js +10 -0
- package/dist/chunk-R4FXTZWU.js +10 -0
- package/dist/chunk-SIFGLE22.js +794 -0
- package/dist/chunk-WNJUPR6P.js +707 -0
- package/dist/chunk-ZSLMMDUX.js +727 -0
- package/dist/data-3HVQ54F3.js +2550 -0
- package/dist/data-ADLKYCN6.js +2211 -0
- package/dist/data-B47EIZXW.js +6 -0
- package/dist/data-DL4IKJCX.js +6 -0
- package/dist/data-GNCSLYM4.js +6 -0
- package/dist/data-GTTIEVFI.js +6 -0
- package/dist/data-HWX62BTJ.js +4772 -0
- package/dist/data-JR6F6HSR.js +6 -0
- package/dist/data-OKVHGTXW.js +3544 -0
- package/dist/data-PQPSE56A.js +1308 -0
- package/dist/data-QF32LRM4.js +3506 -0
- package/dist/data-UIVRJ77R.js +2456 -0
- package/dist/data-UZVNJUNM.js +2256 -0
- package/dist/data-WRWVXGYD.js +6 -0
- package/dist/data-Y6374BIT.js +3350 -0
- package/dist/index.d.ts +305 -0
- package/dist/index.js +80 -0
- package/dist/inference-BGj3DlzE.d.ts +1220 -0
- package/dist/loader-hhMdppVZ.d.ts +32 -0
- package/dist/mock-datasets-Xa9NXK9n.d.ts +178 -0
- package/dist/mocking/datasets/comments.d.ts +6 -0
- package/dist/mocking/datasets/comments.js +7 -0
- package/dist/mocking/datasets/companies.d.ts +6 -0
- package/dist/mocking/datasets/companies.js +7 -0
- package/dist/mocking/datasets/index.d.ts +18 -0
- package/dist/mocking/datasets/index.js +265 -0
- package/dist/mocking/datasets/orders.d.ts +6 -0
- package/dist/mocking/datasets/orders.js +7 -0
- package/dist/mocking/datasets/posts.d.ts +6 -0
- package/dist/mocking/datasets/posts.js +7 -0
- package/dist/mocking/datasets/products.d.ts +6 -0
- package/dist/mocking/datasets/products.js +7 -0
- package/dist/mocking/datasets/users.d.ts +6 -0
- package/dist/mocking/datasets/users.js +7 -0
- package/dist/mocking/index.d.ts +317 -0
- package/dist/mocking/index.js +366 -0
- package/dist/mocking/node.d.ts +33 -0
- package/dist/mocking/node.js +189 -0
- package/dist/mocking/register.d.ts +2 -0
- package/dist/mocking/register.js +9 -0
- package/dist/mutation-controller-BjCOn42y.d.ts +476 -0
- package/dist/react/advanced.d.ts +111 -0
- package/dist/react/advanced.js +119 -0
- package/dist/react/index.d.ts +283 -0
- package/dist/react/index.js +303 -0
- package/dist/types-mSoi1qGP.d.ts +46 -0
- package/package.json +128 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Abdalrahman bani younes
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,258 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Apixa
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Define your API once. Use it everywhere.**
|
|
4
|
+
|
|
5
|
+
Apixa is an open-source, TypeScript-first library for defining APIs and generating fully typed API clients from a single source of truth.
|
|
6
|
+
|
|
7
|
+
Instead of repeatedly writing request functions, types, URL construction, and response handling for every resource, Apixa aims to let you define your API once and handle the repetitive mechanics automatically.
|
|
8
|
+
|
|
9
|
+
## Why Apixa?
|
|
10
|
+
|
|
11
|
+
Working with APIs often means repeating the same patterns across resources and projects:
|
|
12
|
+
|
|
13
|
+
- Writing request functions for every endpoint.
|
|
14
|
+
- Maintaining request and response types separately.
|
|
15
|
+
- Reimplementing headers, parsing, and error handling.
|
|
16
|
+
- Repeating common resource operations.
|
|
17
|
+
- Integrating API calls with different data-fetching libraries.
|
|
18
|
+
|
|
19
|
+
Apixa aims to reduce this duplication while preserving TypeScript's type safety and flexibility.
|
|
20
|
+
|
|
21
|
+
## npm package
|
|
22
|
+
|
|
23
|
+
The `apixa` package is prepared for publication but has not been published yet. After publication,
|
|
24
|
+
install it with `npm install apixa`. Core has no framework dependency:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { defineApi, defineApis } from "apixa";
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Mocking is included under `apixa/mocking`; named datasets use `apixa/mocking/register` and
|
|
31
|
+
`apixa/mocking/datasets`. For the optional React integration, install `react` and
|
|
32
|
+
`@tanstack/react-query`, then import hooks from `apixa/react` and server-safe helpers from
|
|
33
|
+
`apixa/react/advanced`. The existing scoped `@apixa/*` package entry points remain available
|
|
34
|
+
for current consumers.
|
|
35
|
+
|
|
36
|
+
## Core Principles
|
|
37
|
+
|
|
38
|
+
- **Define once:** Keep API definitions in a single source of truth.
|
|
39
|
+
- **Type-safe by design:** Infer request arguments and response types from definitions.
|
|
40
|
+
- **Convention-driven:** Generate common resource operations where appropriate.
|
|
41
|
+
- **Fully customizable:** Support custom endpoints and override generated behavior.
|
|
42
|
+
- **Framework-agnostic:** Keep the core independent of UI frameworks and data-fetching libraries.
|
|
43
|
+
- **Composable:** Allow additional capabilities through optional packages.
|
|
44
|
+
|
|
45
|
+
## Usage (implemented)
|
|
46
|
+
|
|
47
|
+
Minimal resource — built-in CRUD is generated from `path`:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { defineApi } from "apixa";
|
|
51
|
+
const api = defineApi({
|
|
52
|
+
baseURL: "https://api.example.com",
|
|
53
|
+
headers: { Accept: "application/json" },
|
|
54
|
+
resources: { users: { path: "/users" } },
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
await api.users.getAll();
|
|
58
|
+
await api.users.getById("123");
|
|
59
|
+
await api.users.create({ name: "Ada", email: "ada@example.com" });
|
|
60
|
+
await api.users.update("123", { name: "Ada Lovelace" });
|
|
61
|
+
await api.users.delete("123");
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Typed payloads use a Zustand-style **resource-only** state generic (no `type()` helper).
|
|
65
|
+
`create` / `update` are derived from `entity` (`Omit<Entity,"id">` / `Partial<Entity>`).
|
|
66
|
+
Root config (`baseURL`, `headers`, …) is typed by Core — not listed on `AppApi`:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { defineApi } from "apixa";
|
|
70
|
+
|
|
71
|
+
type User = { id: string; name: string; email: string };
|
|
72
|
+
|
|
73
|
+
type AppApi = {
|
|
74
|
+
users: {
|
|
75
|
+
entity: User;
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const api = defineApi<AppApi>()({
|
|
80
|
+
baseURL: "https://api.example.com",
|
|
81
|
+
headers: { Accept: "application/json", "X-Client": "dashboard" },
|
|
82
|
+
resources: {
|
|
83
|
+
users: {
|
|
84
|
+
path: "/users",
|
|
85
|
+
operations: {
|
|
86
|
+
getAll: { path: "/active" },
|
|
87
|
+
patch: { path: "/:id" },
|
|
88
|
+
archive: { kind: "write", method: "POST", path: "/:id/archive" },
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Operations return native `Promise<T>` (response data is unwrapped). A resource path generates 16
|
|
96
|
+
builtins by default. The runtime resource config chooses paths and enabled methods; the optional
|
|
97
|
+
generic supplies payload types. `operations` can disable a builtin with `false`, restore it with
|
|
98
|
+
`true`, override it with a partial config, or define a custom operation with an explicit
|
|
99
|
+
`kind: "read" | "write"`. Custom functions use `{ kind, run }`. HTTP methods must agree with
|
|
100
|
+
the operation kind. `createMany` and
|
|
101
|
+
`deleteMany` replace the former `bulkCreate` and `bulkDelete` names while retaining `/bulk` as
|
|
102
|
+
their default wire path.
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
const api = defineApi<AppApi>()({
|
|
106
|
+
baseURL: "https://api.example.com",
|
|
107
|
+
resources: {
|
|
108
|
+
users: {
|
|
109
|
+
path: "/users",
|
|
110
|
+
readOnly: true,
|
|
111
|
+
operationGroups: { many: true },
|
|
112
|
+
operations: { create: true, getById: false },
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
// TypeScript exposes only the methods generated by these settings.
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Set `defaultOperations: false` to start with no builtins, then enable individual operations or
|
|
120
|
+
groups. `writeOnly: true` filters read defaults. Group precedence and all default wire conventions
|
|
121
|
+
are documented in [docs/conventions.md](docs/conventions.md#selection-order).
|
|
122
|
+
|
|
123
|
+
Pass `transport` to inject a custom HTTP implementation (used in tests). The default is Fetch, shipped inside `@apixa/core`.
|
|
124
|
+
|
|
125
|
+
### Request reliability (implemented)
|
|
126
|
+
|
|
127
|
+
Per-call cancel and timeout via `RequestOptions` (call → operation → resource → api). Abort → `AbortError`; timeout → `TimeoutError`.
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
const controller = new AbortController();
|
|
131
|
+
await api.users.getAll({ signal: controller.signal, timeout: 5_000 });
|
|
132
|
+
controller.abort();
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Opt-in retries (default methods `GET` / `HEAD`; network errors, `408` / `429` / `5xx`):
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
const api = defineApi({
|
|
139
|
+
baseURL: "https://api.example.com",
|
|
140
|
+
timeout: 10_000,
|
|
141
|
+
retry: { retries: 2, baseDelayMs: 200 },
|
|
142
|
+
resources: { users: { path: "/users" } },
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Middleware hooks, request middleware, and response middleware run inside Core's request
|
|
147
|
+
pipeline. See [`packages/core/README.md`](./packages/core/README.md) for the current API.
|
|
148
|
+
|
|
149
|
+
See [`packages/core/README.md`](./packages/core/README.md) and CHANGELOG v0.7.0 migration notes.
|
|
150
|
+
|
|
151
|
+
### Simple Mocking (implemented)
|
|
152
|
+
|
|
153
|
+
Standalone, in-memory mock API from local datasets — no `defineApi()`, no network, no backend:
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
import { defineMockApi } from "apixa/mocking";
|
|
157
|
+
|
|
158
|
+
const mockApi = defineMockApi({
|
|
159
|
+
resources: {
|
|
160
|
+
users: { type: "users-mock" },
|
|
161
|
+
products: { type: "products-mock", slice: 50, pagination: true },
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const { data, total } = await mockApi.products.getAll({ page: 1, pageSize: 10 });
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Typed data: `import { users, type User } from "apixa/mocking/datasets"`.
|
|
169
|
+
|
|
170
|
+
Or mock individual resources of a Core client (register the included lazy dataset loader):
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
import { defineApi } from "apixa";
|
|
174
|
+
import "apixa/mocking/register";
|
|
175
|
+
|
|
176
|
+
const api = defineApi({
|
|
177
|
+
baseURL: "https://api.example.com",
|
|
178
|
+
resources: {
|
|
179
|
+
users: { path: "/users", mock: "users-mock", pagination: "page" },
|
|
180
|
+
payments: { path: "/payments" }, // real network
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
See [`datasets/`](./datasets/) and [`packages/mocking`](./packages/mocking).
|
|
186
|
+
|
|
187
|
+
See [`examples/next`](./examples/next) for the primary real-app playground (Next.js). Other frontends and a Node CLI live under [`examples/`](./examples/). Platform run scripts: [`scripts/README.md`](./scripts/README.md).
|
|
188
|
+
|
|
189
|
+
## Vision
|
|
190
|
+
|
|
191
|
+
Apixa is being designed around a small, extensible core that can grow into a broader API development ecosystem.
|
|
192
|
+
|
|
193
|
+
**Implemented:** `defineApi()` with default-first CRUD (v0.2.0), resource-only `defineApi<T>()(config)` (v0.4.0), `@apixa/mocking` + datasets (v0.5.0), request reliability (v0.6.0), thin Core + plugin seams — path-param concat, `full` / middleware re-call, extension interfaces, structured error codes (v0.7.0).
|
|
194
|
+
|
|
195
|
+
**Planned later:**
|
|
196
|
+
|
|
197
|
+
- `crud<>()` preset.
|
|
198
|
+
- Runtime schema validation hooks (no schema library in Core).
|
|
199
|
+
- Live pagination, filtering, sorting, and search conventions.
|
|
200
|
+
- Online dataset catalog (browse/download) — local datasets only today.
|
|
201
|
+
- Other data-fetching integrations beyond the implemented TanStack Query package.
|
|
202
|
+
- Browser and server packages.
|
|
203
|
+
- OpenAPI interoperability.
|
|
204
|
+
- Additional transports extracted from Core.
|
|
205
|
+
|
|
206
|
+
These planned items are not currently implemented.
|
|
207
|
+
|
|
208
|
+
## Design Philosophy
|
|
209
|
+
|
|
210
|
+
Apixa Core will provide API definitions, type inference, and request execution without requiring React, TanStack Query, or a particular runtime framework.
|
|
211
|
+
|
|
212
|
+
Integrations will build on the core rather than become dependencies of it.
|
|
213
|
+
|
|
214
|
+
API methods are intended to return native promises, allowing them to work naturally with `async`/`await` and libraries such as TanStack Query.
|
|
215
|
+
|
|
216
|
+
## Project Structure
|
|
217
|
+
|
|
218
|
+
```text
|
|
219
|
+
packages/
|
|
220
|
+
core/ # API definitions and execution
|
|
221
|
+
mocking/ # Local datasets and standalone mock APIs
|
|
222
|
+
tanstack-query/ # Optional React Query integration
|
|
223
|
+
datasets/ # Version-controlled JSON fixtures
|
|
224
|
+
examples/
|
|
225
|
+
next/ # Primary frontend playground (Next.js)
|
|
226
|
+
react-vite/ vue/ vanilla/ angular/ react-native/ basic/
|
|
227
|
+
scripts/ # Frontend run scripts (macOS / Linux / Windows)
|
|
228
|
+
tests/ # Vitest suite for core, mocking, and query
|
|
229
|
+
docs/ # Living context, architecture, roadmap, ADRs
|
|
230
|
+
versions/
|
|
231
|
+
v1.0.0/ # Active Query workstream
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Planned later packages (not created yet): `transport-fetch`, `client`, `server`, `openapi`.
|
|
235
|
+
|
|
236
|
+
## Documentation
|
|
237
|
+
|
|
238
|
+
| Doc | Purpose |
|
|
239
|
+
| ---------------------------------------------- | ---------------------------------------------------- |
|
|
240
|
+
| [docs/context.md](./docs/context.md) | Project identity, principles, constraints |
|
|
241
|
+
| [docs/architecture.md](./docs/architecture.md) | Core shape and request flow |
|
|
242
|
+
| [docs/roadmap.md](./docs/roadmap.md) | Milestones and future phases |
|
|
243
|
+
| [docs/conventions.md](./docs/conventions.md) | How we build and document |
|
|
244
|
+
| [versions/v1.0.0/](./versions/v1.0.0/) | **Active coding contract** (scope, plan, acceptance) |
|
|
245
|
+
|
|
246
|
+
## Project Status
|
|
247
|
+
|
|
248
|
+
Apixa is in early development. Last shipped: **v0.11.0**. The v1.0.0 TanStack Query workstream is in progress. `@apixa/core` exposes `defineApi()` with default-first CRUD, reliability, re-callable middleware, and extension seams. `@apixa/mocking` augments Core for resource mocks.
|
|
249
|
+
|
|
250
|
+
See [versions/v1.0.0/acceptance-criteria.md](./versions/v1.0.0/acceptance-criteria.md) for the active milestone checklist.
|
|
251
|
+
|
|
252
|
+
## Author
|
|
253
|
+
|
|
254
|
+
Created and maintained by **Abdalrahman bani younes** ([a2mby](https://github.com/a2mby)).
|
|
255
|
+
|
|
256
|
+
## License
|
|
257
|
+
|
|
258
|
+
Apixa is licensed under the MIT License. See [LICENSE](./LICENSE) for details.
|