@nexo-alpha/data 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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nexo
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 all
13
+ 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 THE
21
+ SOFTWARE.
@@ -0,0 +1,71 @@
1
+ /**
2
+ * @nexo-alpha/data — typed resource client & proxy.
3
+ *
4
+ * Provides typed, codegen-free client access to server `resource()` definitions:
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * // Using NexoClient or any HTTP adapter
9
+ * const api = createResourcesProxy<{ users: typeof User }>(client);
10
+ *
11
+ * const { items, total } = await api.users.list({ limit: 10 });
12
+ * const user = await api.users.create({ name: "Alice", email: "alice@example.com" });
13
+ * const updated = await api.users.update(user.id, { age: 30 });
14
+ * await api.users.delete(user.id);
15
+ * ```
16
+ */
17
+ import type { Fields, Infer } from "./fields.js";
18
+ import type { Entity, ListQuery, Page } from "./store.js";
19
+ import type { Resource } from "./resource.js";
20
+ export interface NexoHttpClientLike {
21
+ api?<T = unknown>(path: string, init?: RequestInit): Promise<T>;
22
+ get?<T = unknown>(path: string): Promise<T>;
23
+ post?<T = unknown>(path: string, body?: unknown, init?: RequestInit): Promise<T>;
24
+ patch?<T = unknown>(path: string, body?: unknown, init?: RequestInit): Promise<T>;
25
+ delete?<T = unknown>(path: string, init?: RequestInit): Promise<T>;
26
+ }
27
+ export interface ClientConnectionOptions {
28
+ readonly baseUrl?: string;
29
+ readonly headers?: Record<string, string>;
30
+ readonly fetch?: typeof fetch;
31
+ }
32
+ export type ClientTarget = NexoHttpClientLike | ClientConnectionOptions;
33
+ export declare function encodeListQuery<T>(query?: ListQuery<T>): string;
34
+ export interface ResourceClient<F extends Fields> {
35
+ /** The collection URL path, e.g. `"/users"`. */
36
+ readonly path: string;
37
+ /** Fetch a paginated list of records. */
38
+ list(query?: ListQuery<Infer<F>>): Promise<Page<Entity<Infer<F>>>>;
39
+ /** Fetch a single record by id. Throws on 404. */
40
+ get(id: string): Promise<Entity<Infer<F>>>;
41
+ /** Create a new record. */
42
+ create(data: Infer<F>): Promise<Entity<Infer<F>>>;
43
+ /** Partially update an existing record. */
44
+ update(id: string, patch: Partial<Infer<F>>): Promise<Entity<Infer<F>>>;
45
+ /** Delete a record by id. */
46
+ delete(id: string): Promise<void>;
47
+ }
48
+ /**
49
+ * Creates a standalone `ResourceClient` for a given `Resource` definition or path.
50
+ */
51
+ export declare function createResourceClient<F extends Fields>(resourceOrPath: Resource<F> | string, target?: ClientTarget): ResourceClient<F>;
52
+ export type ResourceRegistry = Record<string, Resource<any>>;
53
+ export type ResourcesProxy<R extends ResourceRegistry> = {
54
+ [K in keyof R]: R[K] extends Resource<infer F> ? ResourceClient<F> : never;
55
+ };
56
+ /**
57
+ * Creates a typed proxy mapping resource names to their corresponding `ResourceClient`.
58
+ *
59
+ * Can be called with generic type inference:
60
+ * ```ts
61
+ * const api = createResourcesProxy<{ users: typeof User }>(client);
62
+ * const page = await api.users.list();
63
+ * ```
64
+ *
65
+ * Or by passing runtime resource instances:
66
+ * ```ts
67
+ * const api = createResourcesProxy(client, { users: User });
68
+ * ```
69
+ */
70
+ export declare function createResourcesProxy<R extends ResourceRegistry>(target?: ClientTarget, map?: R): ResourcesProxy<R>;
71
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js ADDED
@@ -0,0 +1,192 @@
1
+ /**
2
+ * @nexo-alpha/data — typed resource client & proxy.
3
+ *
4
+ * Provides typed, codegen-free client access to server `resource()` definitions:
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * // Using NexoClient or any HTTP adapter
9
+ * const api = createResourcesProxy<{ users: typeof User }>(client);
10
+ *
11
+ * const { items, total } = await api.users.list({ limit: 10 });
12
+ * const user = await api.users.create({ name: "Alice", email: "alice@example.com" });
13
+ * const updated = await api.users.update(user.id, { age: 30 });
14
+ * await api.users.delete(user.id);
15
+ * ```
16
+ */
17
+ function resolveCaller(target) {
18
+ if (target !== undefined && ("api" in target || "get" in target)) {
19
+ const client = target;
20
+ return {
21
+ get: async (path) => {
22
+ if (typeof client.get === "function")
23
+ return client.get(path);
24
+ if (typeof client.api === "function")
25
+ return client.api(path, { method: "GET" });
26
+ throw new Error("Target client does not implement get() or api().");
27
+ },
28
+ post: async (path, body) => {
29
+ if (typeof client.post === "function")
30
+ return client.post(path, body);
31
+ if (typeof client.api === "function") {
32
+ return client.api(path, {
33
+ method: "POST",
34
+ headers: { "Content-Type": "application/json" },
35
+ body: JSON.stringify(body)
36
+ });
37
+ }
38
+ throw new Error("Target client does not implement post() or api().");
39
+ },
40
+ patch: async (path, body) => {
41
+ if (typeof client.patch === "function")
42
+ return client.patch(path, body);
43
+ if (typeof client.api === "function") {
44
+ return client.api(path, {
45
+ method: "PATCH",
46
+ headers: { "Content-Type": "application/json" },
47
+ body: JSON.stringify(body)
48
+ });
49
+ }
50
+ throw new Error("Target client does not implement patch() or api().");
51
+ },
52
+ delete: async (path) => {
53
+ if (typeof client.delete === "function")
54
+ return client.delete(path);
55
+ if (typeof client.api === "function")
56
+ return client.api(path, { method: "DELETE" });
57
+ throw new Error("Target client does not implement delete() or api().");
58
+ }
59
+ };
60
+ }
61
+ const opts = target ?? {};
62
+ const baseUrl = (opts.baseUrl ?? "").replace(/\/+$/, "");
63
+ const fetchFn = opts.fetch ?? (typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : fetch);
64
+ const defaultHeaders = {
65
+ "Accept": "application/json",
66
+ ...(opts.headers ?? {})
67
+ };
68
+ const request = async (path, init) => {
69
+ const cleanPath = path.startsWith("/") ? path : `/${path}`;
70
+ const url = /^https?:\/\//i.test(path) ? path : `${baseUrl}${cleanPath}`;
71
+ const res = await fetchFn(url, {
72
+ ...init,
73
+ headers: {
74
+ ...defaultHeaders,
75
+ ...init?.headers
76
+ }
77
+ });
78
+ if (!res.ok) {
79
+ let payload;
80
+ let msg = `HTTP ${res.status} ${res.statusText}`;
81
+ try {
82
+ payload = await res.json();
83
+ if (payload && typeof payload === "object" && "error" in payload) {
84
+ msg = String(payload.error);
85
+ }
86
+ }
87
+ catch {
88
+ // Not JSON
89
+ }
90
+ const err = new Error(msg);
91
+ err.status = res.status;
92
+ err.payload = payload;
93
+ throw err;
94
+ }
95
+ if (res.status === 204) {
96
+ return undefined;
97
+ }
98
+ return (await res.json());
99
+ };
100
+ return {
101
+ get: (path) => request(path, { method: "GET" }),
102
+ post: (path, body) => request(path, {
103
+ method: "POST",
104
+ headers: { "Content-Type": "application/json" },
105
+ body: JSON.stringify(body)
106
+ }),
107
+ patch: (path, body) => request(path, {
108
+ method: "PATCH",
109
+ headers: { "Content-Type": "application/json" },
110
+ body: JSON.stringify(body)
111
+ }),
112
+ delete: (path) => request(path, { method: "DELETE" })
113
+ };
114
+ }
115
+ // ---------------------------------------------------------------------------
116
+ // List query encoder
117
+ // ---------------------------------------------------------------------------
118
+ export function encodeListQuery(query = {}) {
119
+ const params = new URLSearchParams();
120
+ if (query.limit !== undefined)
121
+ params.set("limit", String(query.limit));
122
+ if (query.cursor !== undefined)
123
+ params.set("cursor", query.cursor);
124
+ if (query.sort !== undefined)
125
+ params.set("sort", query.sort);
126
+ if (query.where !== undefined) {
127
+ for (const [key, val] of Object.entries(query.where)) {
128
+ if (val !== undefined && val !== null) {
129
+ params.set(`where[${key}]`, String(val));
130
+ }
131
+ }
132
+ }
133
+ return params.toString();
134
+ }
135
+ /**
136
+ * Creates a standalone `ResourceClient` for a given `Resource` definition or path.
137
+ */
138
+ export function createResourceClient(resourceOrPath, target) {
139
+ const path = (typeof resourceOrPath === "string" ? resourceOrPath : resourceOrPath.path).replace(/\/+$/, "");
140
+ const caller = resolveCaller(target);
141
+ return {
142
+ path,
143
+ list: async (query) => {
144
+ const qs = query ? encodeListQuery(query) : "";
145
+ return caller.get(qs ? `${path}?${qs}` : path);
146
+ },
147
+ get: async (id) => {
148
+ return caller.get(`${path}/${encodeURIComponent(id)}`);
149
+ },
150
+ create: async (data) => {
151
+ return caller.post(path, data);
152
+ },
153
+ update: async (id, patch) => {
154
+ return caller.patch(`${path}/${encodeURIComponent(id)}`, patch);
155
+ },
156
+ delete: async (id) => {
157
+ await caller.delete(`${path}/${encodeURIComponent(id)}`);
158
+ }
159
+ };
160
+ }
161
+ /**
162
+ * Creates a typed proxy mapping resource names to their corresponding `ResourceClient`.
163
+ *
164
+ * Can be called with generic type inference:
165
+ * ```ts
166
+ * const api = createResourcesProxy<{ users: typeof User }>(client);
167
+ * const page = await api.users.list();
168
+ * ```
169
+ *
170
+ * Or by passing runtime resource instances:
171
+ * ```ts
172
+ * const api = createResourcesProxy(client, { users: User });
173
+ * ```
174
+ */
175
+ export function createResourcesProxy(target, map) {
176
+ const cache = new Map();
177
+ return new Proxy({}, {
178
+ get(_target, prop) {
179
+ if (typeof prop !== "string")
180
+ return undefined;
181
+ let cached = cache.get(prop);
182
+ if (cached)
183
+ return cached;
184
+ const resourceDef = map?.[prop];
185
+ const resourcePath = resourceDef?.path ?? `/${prop.replace(/([A-Z])/g, "-$1").toLowerCase()}`;
186
+ cached = createResourceClient(resourcePath, target);
187
+ cache.set(prop, cached);
188
+ return cached;
189
+ }
190
+ });
191
+ }
192
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAiCH,SAAS,aAAa,CAAC,MAAqB;IAC1C,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,CAAC,EAAE,CAAC;QACjE,MAAM,MAAM,GAAG,MAA4B,CAAC;QAC5C,OAAO;YACL,GAAG,EAAE,KAAK,EAAK,IAAY,EAAc,EAAE;gBACzC,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,UAAU;oBAAE,OAAO,MAAM,CAAC,GAAG,CAAI,IAAI,CAAC,CAAC;gBACjE,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,UAAU;oBAAE,OAAO,MAAM,CAAC,GAAG,CAAI,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;gBACpF,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;YACtE,CAAC;YACD,IAAI,EAAE,KAAK,EAAK,IAAY,EAAE,IAAc,EAAc,EAAE;gBAC1D,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU;oBAAE,OAAO,MAAM,CAAC,IAAI,CAAI,IAAI,EAAE,IAAI,CAAC,CAAC;gBACzE,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;oBACrC,OAAO,MAAM,CAAC,GAAG,CAAI,IAAI,EAAE;wBACzB,MAAM,EAAE,MAAM;wBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;wBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;qBAC3B,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;YACvE,CAAC;YACD,KAAK,EAAE,KAAK,EAAK,IAAY,EAAE,IAAc,EAAc,EAAE;gBAC3D,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,UAAU;oBAAE,OAAO,MAAM,CAAC,KAAK,CAAI,IAAI,EAAE,IAAI,CAAC,CAAC;gBAC3E,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;oBACrC,OAAO,MAAM,CAAC,GAAG,CAAI,IAAI,EAAE;wBACzB,MAAM,EAAE,OAAO;wBACf,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;wBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;qBAC3B,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;YACxE,CAAC;YACD,MAAM,EAAE,KAAK,EAAK,IAAY,EAAc,EAAE;gBAC5C,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,UAAU;oBAAE,OAAO,MAAM,CAAC,MAAM,CAAI,IAAI,CAAC,CAAC;gBACvE,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,UAAU;oBAAE,OAAO,MAAM,CAAC,GAAG,CAAI,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACvF,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;YACzE,CAAC;SACF,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAI,MAA8C,IAAI,EAAE,CAAC;IACnE,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,UAAU,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACnH,MAAM,cAAc,GAAG;QACrB,QAAQ,EAAE,kBAAkB;QAC5B,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;KACxB,CAAC;IAEF,MAAM,OAAO,GAAG,KAAK,EAAK,IAAY,EAAE,IAAkB,EAAc,EAAE;QACxE,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;QAC3D,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,SAAS,EAAE,CAAC;QACzE,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE;YAC7B,GAAG,IAAI;YACP,OAAO,EAAE;gBACP,GAAG,cAAc;gBACjB,GAAI,IAAI,EAAE,OAA8C;aACzD;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,OAAgB,CAAC;YACrB,IAAI,GAAG,GAAG,QAAQ,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YACjD,IAAI,CAAC;gBACH,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;gBAC3B,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;oBACjE,GAAG,GAAG,MAAM,CAAE,OAA8B,CAAC,KAAK,CAAC,CAAC;gBACtD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,WAAW;YACb,CAAC;YACD,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;YAC1B,GAAuD,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;YAC5E,GAAuD,CAAC,OAAO,GAAG,OAAO,CAAC;YAC3E,MAAM,GAAG,CAAC;QACZ,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,OAAO,SAAc,CAAC;QACxB,CAAC;QACD,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAM,CAAC;IACjC,CAAC,CAAC;IAEF,OAAO;QACL,GAAG,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QACvD,IAAI,EAAE,CAAC,IAAY,EAAE,IAAc,EAAE,EAAE,CACrC,OAAO,CAAC,IAAI,EAAE;YACZ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC;QACJ,KAAK,EAAE,CAAC,IAAY,EAAE,IAAc,EAAE,EAAE,CACtC,OAAO,CAAC,IAAI,EAAE;YACZ,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC;QACJ,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;KAC9D,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E,MAAM,UAAU,eAAe,CAAI,QAAsB,EAAE;IACzD,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;IACrC,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IACxE,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACnE,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7D,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACrD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;gBACtC,MAAM,CAAC,GAAG,CAAC,SAAS,GAAG,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC;AAC3B,CAAC;AA0BD;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,cAAoC,EACpC,MAAqB;IAErB,MAAM,IAAI,GAAG,CAAC,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC7G,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAErC,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,KAAK,EAAE,KAA2B,EAAmC,EAAE;YAC3E,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,OAAO,MAAM,CAAC,GAAG,CAAyB,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACzE,CAAC;QACD,GAAG,EAAE,KAAK,EAAE,EAAU,EAA6B,EAAE;YACnD,OAAO,MAAM,CAAC,GAAG,CAAmB,GAAG,IAAI,IAAI,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,IAAc,EAA6B,EAAE;YAC1D,OAAO,MAAM,CAAC,IAAI,CAAmB,IAAI,EAAE,IAAI,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,EAAU,EAAE,KAAwB,EAA6B,EAAE;YAChF,OAAO,MAAM,CAAC,KAAK,CAAmB,GAAG,IAAI,IAAI,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,EAAU,EAAiB,EAAE;YAC1C,MAAM,MAAM,CAAC,MAAM,CAAO,GAAG,IAAI,IAAI,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACjE,CAAC;KACF,CAAC;AACJ,CAAC;AAYD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAqB,EACrB,GAAO;IAEP,MAAM,KAAK,GAAG,IAAI,GAAG,EAA+B,CAAC;IAErD,OAAO,IAAI,KAAK,CAAC,EAAuB,EAAE;QACxC,GAAG,CAAC,OAAO,EAAE,IAAqB;YAChC,IAAI,OAAO,IAAI,KAAK,QAAQ;gBAAE,OAAO,SAAS,CAAC;YAC/C,IAAI,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAC;YAE1B,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM,YAAY,GAChB,WAAW,EAAE,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YAE3E,MAAM,GAAG,oBAAoB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YACpD,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACxB,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * @nexo-alpha/data — typed schema builder.
3
+ *
4
+ * Each `Field<T>` carries the TypeScript type as a phantom and emits a
5
+ * `NexoFieldSchema` at runtime, keeping `core`'s "schema is data" rule and
6
+ * giving full inference.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { string, email, number, boolean, Fields, Infer } from "@nexo-alpha/data";
11
+ *
12
+ * const UserFields = {
13
+ * name: string({ min: 1, max: 100 }),
14
+ * email: email(),
15
+ * age: number({ min: 0, int: true }).optional(),
16
+ * admin: boolean(),
17
+ * };
18
+ *
19
+ * type User = Infer<typeof UserFields>;
20
+ * // { name: string; email: string; age?: number; admin: boolean }
21
+ * ```
22
+ */
23
+ import type { NexoFieldSchema } from "@nexo-alpha/core";
24
+ /**
25
+ * A field descriptor: `_t` is the compile-time type (phantom, never read at
26
+ * runtime). `schema` is the `NexoFieldSchema` emitted for validation,
27
+ * OpenAPI generation, and client inference. `required` tracks whether
28
+ * `.optional()` has been called.
29
+ */
30
+ export interface Field<T> {
31
+ /** @internal — phantom, never present at runtime */
32
+ readonly _t: T;
33
+ readonly schema: NexoFieldSchema;
34
+ readonly required: boolean;
35
+ /** Returns a new `Field` where the value may be `undefined`. */
36
+ optional(): Field<T | undefined>;
37
+ }
38
+ /** A record of named field descriptors — the shape declaration for a resource. */
39
+ export type Fields = Record<string, Field<unknown>>;
40
+ /**
41
+ * Extracts required fields (those where `required` is `true`) from a
42
+ * `Fields` map. Used to build the two-part mapped type in `Infer`.
43
+ */
44
+ type RequiredKeys<F extends Fields> = {
45
+ [K in keyof F]: F[K] extends Field<infer T> ? undefined extends T ? never : K : never;
46
+ }[keyof F];
47
+ type OptionalKeys<F extends Fields> = Exclude<keyof F, RequiredKeys<F>>;
48
+ /**
49
+ * Converts a `Fields` record to the TypeScript object type it describes,
50
+ * with optional fields (those decorated with `.optional()`) as `?: T`.
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * type User = Infer<typeof UserFields>;
55
+ * ```
56
+ */
57
+ export type Infer<F extends Fields> = {
58
+ [K in RequiredKeys<F>]: F[K] extends Field<infer T> ? T : never;
59
+ } & {
60
+ [K in OptionalKeys<F>]?: F[K] extends Field<infer T> ? Exclude<T, undefined> : never;
61
+ };
62
+ export interface StringOptions {
63
+ /** Minimum character length (inclusive). */
64
+ readonly min?: number;
65
+ /** Maximum character length (inclusive). */
66
+ readonly max?: number;
67
+ /** Regex or string pattern the value must satisfy. */
68
+ readonly pattern?: string | RegExp;
69
+ /** Allowed values. */
70
+ readonly enum?: readonly string[];
71
+ /** Free-form description forwarded to OpenAPI. */
72
+ readonly description?: string;
73
+ }
74
+ /** A required `string` field. Call `.optional()` to make it optional. */
75
+ export declare function string(options?: StringOptions): Field<string>;
76
+ /** A required `string` field pre-configured with a basic e-mail pattern. */
77
+ export declare function email(options?: Pick<StringOptions, "description">): Field<string>;
78
+ export interface NumberOptions {
79
+ /** Minimum value (inclusive). */
80
+ readonly min?: number;
81
+ /** Maximum value (inclusive). */
82
+ readonly max?: number;
83
+ /** Require an integer value. */
84
+ readonly int?: boolean;
85
+ readonly description?: string;
86
+ }
87
+ /** A required `number` field. Call `.optional()` to make it optional. */
88
+ export declare function number(options?: NumberOptions): Field<number>;
89
+ /** A required `boolean` field. Call `.optional()` to make it optional. */
90
+ export declare function boolean(options?: {
91
+ readonly description?: string;
92
+ }): Field<boolean>;
93
+ /**
94
+ * Converts a `Fields` map into the `properties` object expected by a
95
+ * `NexoFieldSchema` of `type: "object"`.
96
+ *
97
+ * The `required` flag is stripped from individual property schemas for
98
+ * optional fields — the object-level `required` array (built by
99
+ * `requiredFieldNames`) is the sole authority for which properties are
100
+ * mandatory. Leaving `required: true` on an optional property schema would
101
+ * cause `validateField` to reject a valid request where that field is absent.
102
+ */
103
+ export declare function fieldsToProperties(fields: Fields): Record<string, NexoFieldSchema>;
104
+ /**
105
+ * Returns the names of all required fields (i.e. those whose `.required` is
106
+ * `true`) — used as the `required` array on the body schema.
107
+ */
108
+ export declare function requiredFieldNames(fields: Fields): readonly string[];
109
+ /**
110
+ * Returns a copy of `fields` where every field is optional — used for the
111
+ * PATCH (partial update) body schema.
112
+ */
113
+ export declare function allOptional(fields: Fields): Fields;
114
+ export {};
115
+ //# sourceMappingURL=fields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../src/fields.ts"],"names":[],"mappings":"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"}
package/dist/fields.js ADDED
@@ -0,0 +1,127 @@
1
+ /**
2
+ * @nexo-alpha/data — typed schema builder.
3
+ *
4
+ * Each `Field<T>` carries the TypeScript type as a phantom and emits a
5
+ * `NexoFieldSchema` at runtime, keeping `core`'s "schema is data" rule and
6
+ * giving full inference.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { string, email, number, boolean, Fields, Infer } from "@nexo-alpha/data";
11
+ *
12
+ * const UserFields = {
13
+ * name: string({ min: 1, max: 100 }),
14
+ * email: email(),
15
+ * age: number({ min: 0, int: true }).optional(),
16
+ * admin: boolean(),
17
+ * };
18
+ *
19
+ * type User = Infer<typeof UserFields>;
20
+ * // { name: string; email: string; age?: number; admin: boolean }
21
+ * ```
22
+ */
23
+ // ---------------------------------------------------------------------------
24
+ // Internal factory
25
+ // ---------------------------------------------------------------------------
26
+ function makeField(schema, req) {
27
+ return {
28
+ _t: undefined,
29
+ schema,
30
+ required: req,
31
+ optional() {
32
+ return makeField({ ...schema }, false);
33
+ }
34
+ };
35
+ }
36
+ /** A required `string` field. Call `.optional()` to make it optional. */
37
+ export function string(options = {}) {
38
+ const schema = {
39
+ type: "string",
40
+ required: true,
41
+ ...(options.min !== undefined ? { minLength: options.min } : {}),
42
+ ...(options.max !== undefined ? { maxLength: options.max } : {}),
43
+ ...(options.pattern !== undefined ? { pattern: options.pattern } : {}),
44
+ ...(options.enum !== undefined ? { enum: options.enum } : {}),
45
+ ...(options.description !== undefined ? { description: options.description } : {})
46
+ };
47
+ return makeField(schema, true);
48
+ }
49
+ /** A required `string` field pre-configured with a basic e-mail pattern. */
50
+ export function email(options = {}) {
51
+ return string({
52
+ // Simple RFC-5321-ish pattern — enough for a server-side sanity check.
53
+ pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
54
+ description: options.description ?? "Email address",
55
+ max: 320
56
+ });
57
+ }
58
+ /** A required `number` field. Call `.optional()` to make it optional. */
59
+ export function number(options = {}) {
60
+ const schema = {
61
+ type: "number",
62
+ required: true,
63
+ ...(options.min !== undefined ? { min: options.min } : {}),
64
+ ...(options.max !== undefined ? { max: options.max } : {}),
65
+ ...(options.int !== undefined ? { integer: options.int } : {}),
66
+ ...(options.description !== undefined ? { description: options.description } : {})
67
+ };
68
+ return makeField(schema, true);
69
+ }
70
+ /** A required `boolean` field. Call `.optional()` to make it optional. */
71
+ export function boolean(options = {}) {
72
+ const schema = {
73
+ type: "boolean",
74
+ required: true,
75
+ ...(options.description !== undefined ? { description: options.description } : {})
76
+ };
77
+ return makeField(schema, true);
78
+ }
79
+ // ---------------------------------------------------------------------------
80
+ // Helpers consumed by resource.ts
81
+ // ---------------------------------------------------------------------------
82
+ /**
83
+ * Converts a `Fields` map into the `properties` object expected by a
84
+ * `NexoFieldSchema` of `type: "object"`.
85
+ *
86
+ * The `required` flag is stripped from individual property schemas for
87
+ * optional fields — the object-level `required` array (built by
88
+ * `requiredFieldNames`) is the sole authority for which properties are
89
+ * mandatory. Leaving `required: true` on an optional property schema would
90
+ * cause `validateField` to reject a valid request where that field is absent.
91
+ */
92
+ export function fieldsToProperties(fields) {
93
+ const props = {};
94
+ for (const [key, field] of Object.entries(fields)) {
95
+ if (field.required) {
96
+ props[key] = field.schema;
97
+ }
98
+ else {
99
+ // Omit the required key entirely for optional fields.
100
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
101
+ const { required: _r, ...rest } = field.schema;
102
+ props[key] = rest;
103
+ }
104
+ }
105
+ return props;
106
+ }
107
+ /**
108
+ * Returns the names of all required fields (i.e. those whose `.required` is
109
+ * `true`) — used as the `required` array on the body schema.
110
+ */
111
+ export function requiredFieldNames(fields) {
112
+ return Object.entries(fields)
113
+ .filter(([, f]) => f.required)
114
+ .map(([k]) => k);
115
+ }
116
+ /**
117
+ * Returns a copy of `fields` where every field is optional — used for the
118
+ * PATCH (partial update) body schema.
119
+ */
120
+ export function allOptional(fields) {
121
+ const result = {};
122
+ for (const [key, field] of Object.entries(fields)) {
123
+ result[key] = field.optional();
124
+ }
125
+ return result;
126
+ }
127
+ //# sourceMappingURL=fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fields.js","sourceRoot":"","sources":["../src/fields.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @nexo-alpha/data — public surface.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import { resource, string, email, number, boolean } from "@nexo-alpha/data";
7
+ * ```
8
+ */
9
+ export { string, email, number, boolean, fieldsToProperties, requiredFieldNames, allOptional } from "./fields.js";
10
+ export type { Field, Fields, Infer } from "./fields.js";
11
+ export { memoryStore } from "./store.js";
12
+ export type { Entity, ListQuery, Page, ResourceStore } from "./store.js";
13
+ export { resource } from "./resource.js";
14
+ export type { Operation, OperationAuth, Resource, ResourceDescription, ResourceFieldDetail, ResourceEmitter, ResourceOptions } from "./resource.js";
15
+ export { createResourceClient, createResourcesProxy, encodeListQuery } from "./client.js";
16
+ export type { ClientConnectionOptions, ClientTarget, NexoHttpClientLike, ResourceClient, ResourceRegistry, ResourcesProxy } from "./client.js";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACL,MAAM,EACN,KAAK,EACL,MAAM,EACN,OAAO,EACP,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACZ,MAAM,aAAa,CAAC;AAErB,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,YAAY,EACV,MAAM,EACN,SAAS,EACT,IAAI,EACJ,aAAa,EACd,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,YAAY,EACV,SAAS,EACT,aAAa,EACb,QAAQ,EACR,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,eAAe,EAChB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,eAAe,EAChB,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,uBAAuB,EACvB,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACf,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @nexo-alpha/data — public surface.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import { resource, string, email, number, boolean } from "@nexo-alpha/data";
7
+ * ```
8
+ */
9
+ // --- Schema builder ---------------------------------------------------------
10
+ export { string, email, number, boolean, fieldsToProperties, requiredFieldNames, allOptional } from "./fields.js";
11
+ // --- Storage -----------------------------------------------------------------
12
+ export { memoryStore } from "./store.js";
13
+ // --- Resource ----------------------------------------------------------------
14
+ export { resource } from "./resource.js";
15
+ // --- Client ------------------------------------------------------------------
16
+ export { createResourceClient, createResourcesProxy, encodeListQuery } from "./client.js";
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,+EAA+E;AAC/E,OAAO,EACL,MAAM,EACN,KAAK,EACL,MAAM,EACN,OAAO,EACP,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACZ,MAAM,aAAa,CAAC;AAIrB,gFAAgF;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AASzC,gFAAgF;AAChF,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAYzC,gFAAgF;AAChF,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,eAAe,EAChB,MAAM,aAAa,CAAC"}