kyro-connect 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -49,14 +49,25 @@ async function handleResponse(res) {
49
49
  } catch {
50
50
  throw new KyroConnectError(res.statusText, res.status);
51
51
  }
52
- throw new KyroConnectError(
53
- body2?.error?.message ?? res.statusText,
54
- res.status,
55
- body2
56
- );
52
+ const message = typeof body2?.error === "string" ? body2.error : res.statusText;
53
+ throw new KyroConnectError(message, res.status, body2);
57
54
  }
58
55
  const body = await res.json();
59
- return body?.result?.data ?? body;
56
+ if (body && typeof body === "object" && "result" in body) {
57
+ return body.result.data;
58
+ }
59
+ return body;
60
+ }
61
+ function buildSearchParams(params) {
62
+ if (!params) return "";
63
+ const sp = new URLSearchParams();
64
+ for (const [key, value] of Object.entries(params)) {
65
+ if (value !== void 0 && value !== null) {
66
+ sp.set(key, typeof value === "object" ? JSON.stringify(value) : String(value));
67
+ }
68
+ }
69
+ const qs = sp.toString();
70
+ return qs ? `?${qs}` : "";
60
71
  }
61
72
  function createClient(opts) {
62
73
  const baseUrl = opts.url.replace(/\/$/, "");
@@ -76,13 +87,13 @@ function createClient(opts) {
76
87
  method: "POST",
77
88
  headers: { "Content-Type": "application/json", ...headers() },
78
89
  body: JSON.stringify(input)
79
- }).then(handleResponse);
90
+ }).then((res) => handleResponse(res));
80
91
  }
81
92
  const qs = encodeURIComponent(JSON.stringify(input));
82
93
  return doFetch(`${baseUrl}/${pathStr}?input=${qs}`, {
83
94
  method: "GET",
84
95
  headers: headers()
85
- }).then(handleResponse);
96
+ }).then((res) => handleResponse(res));
86
97
  }
87
98
  function buildProxy(path) {
88
99
  return new Proxy(function() {
@@ -95,7 +106,77 @@ function createClient(opts) {
95
106
  }
96
107
  });
97
108
  }
98
- return buildProxy([]);
109
+ const collection = (slug) => ({
110
+ async find(params) {
111
+ const res = await doFetch(`${baseUrl}/api/${slug}${buildSearchParams(params)}`, {
112
+ method: "GET",
113
+ headers: headers()
114
+ });
115
+ return handleResponse(res);
116
+ },
117
+ async findByID(id, params) {
118
+ const res = await doFetch(`${baseUrl}/api/${slug}/${id}${buildSearchParams(params)}`, {
119
+ method: "GET",
120
+ headers: headers()
121
+ });
122
+ const body = await handleResponse(res);
123
+ return body?.data ?? body;
124
+ },
125
+ async create(data, params) {
126
+ const res = await doFetch(`${baseUrl}/api/${slug}${buildSearchParams(params)}`, {
127
+ method: "POST",
128
+ headers: { "Content-Type": "application/json", ...headers() },
129
+ body: JSON.stringify(data)
130
+ });
131
+ const body = await handleResponse(res);
132
+ return body?.data ?? body;
133
+ },
134
+ async update(id, data, params) {
135
+ const res = await doFetch(`${baseUrl}/api/${slug}/${id}${buildSearchParams(params)}`, {
136
+ method: "PATCH",
137
+ headers: { "Content-Type": "application/json", ...headers() },
138
+ body: JSON.stringify(data)
139
+ });
140
+ const body = await handleResponse(res);
141
+ return body?.data ?? body;
142
+ },
143
+ async delete(id) {
144
+ const res = await doFetch(`${baseUrl}/api/${slug}/${id}`, {
145
+ method: "DELETE",
146
+ headers: headers()
147
+ });
148
+ return handleResponse(res);
149
+ }
150
+ });
151
+ const gql = async (query, variables) => {
152
+ const queryStr = typeof query === "string" ? query : query.toString();
153
+ const res = await doFetch(`${baseUrl}/api/graphql`, {
154
+ method: "POST",
155
+ headers: { "Content-Type": "application/json", ...headers() },
156
+ body: JSON.stringify({ query: queryStr, variables })
157
+ });
158
+ const body = await res.json();
159
+ if (body.errors) {
160
+ throw new KyroConnectError(body.errors[0]?.message || "GraphQL error", res.status, body);
161
+ }
162
+ return body.data;
163
+ };
164
+ const upload = async (url, file, filename) => {
165
+ const formData = new FormData();
166
+ formData.append("file", file, filename);
167
+ const res = await doFetch(`${baseUrl}${url}`, {
168
+ method: "POST",
169
+ headers: headers(),
170
+ body: formData
171
+ });
172
+ return handleResponse(res);
173
+ };
174
+ const proxy = buildProxy([]);
175
+ return Object.assign(proxy, {
176
+ collection,
177
+ gql,
178
+ upload
179
+ });
99
180
  }
100
181
  // Annotate the CommonJS export names for ESM import in node:
101
182
  0 && (module.exports = {
package/dist/index.d.cts CHANGED
@@ -12,9 +12,58 @@ type RouterClient<T> = {
12
12
  [K in keyof T]: T[K] extends {
13
13
  input: infer I;
14
14
  output: infer O;
15
- } ? ProcedureClient<I, O> : T[K] extends Record<string, any> ? RouterClient<T[K]> : T[K];
15
+ } ? ProcedureClient<I, O> : T[K] extends Record<string, unknown> ? RouterClient<T[K]> : T[K];
16
16
  };
17
- declare function createClient<TRouter extends Record<string, any> = any>(opts: ClientOptions): RouterClient<TRouter>;
17
+ interface CollectionFindResult<T> {
18
+ docs: T[];
19
+ totalDocs: number;
20
+ page: number;
21
+ totalPages: number;
22
+ hasNextPage?: boolean;
23
+ hasPrevPage?: boolean;
24
+ }
25
+ interface CollectionFindParams {
26
+ draft?: boolean;
27
+ depth?: number;
28
+ sort?: string;
29
+ page?: number;
30
+ limit?: number;
31
+ select?: string;
32
+ where?: Record<string, unknown>;
33
+ }
34
+ interface CollectionClient<T, F = CollectionFindParams> {
35
+ find(params?: F & CollectionFindParams): Promise<CollectionFindResult<T>>;
36
+ findByID(id: string, params?: {
37
+ draft?: boolean;
38
+ depth?: number;
39
+ select?: string;
40
+ }): Promise<T | null>;
41
+ create(data: Partial<T>, params?: {
42
+ draft?: boolean;
43
+ depth?: number;
44
+ }): Promise<T>;
45
+ update(id: string, data: Partial<T>, params?: {
46
+ draft?: boolean;
47
+ depth?: number;
48
+ }): Promise<T>;
49
+ delete(id: string): Promise<{
50
+ message: string;
51
+ }>;
52
+ }
53
+ interface GqlClient {
54
+ <TData = Record<string, unknown>, TVars extends Record<string, unknown> = Record<string, unknown>>(query: string | {
55
+ toString(): string;
56
+ }, variables?: TVars): Promise<TData>;
57
+ }
58
+ interface UploadClient {
59
+ <TResult = unknown>(url: string, file: File | Blob, filename?: string): Promise<TResult>;
60
+ }
61
+ type KyroClient<TRouter> = RouterClient<TRouter> & {
62
+ collection: <T, F = CollectionFindParams>(slug: string) => CollectionClient<T, F>;
63
+ gql: GqlClient;
64
+ upload: UploadClient;
65
+ };
66
+ declare function createClient<TRouter extends Record<string, unknown> = Record<string, unknown>>(opts: ClientOptions): KyroClient<TRouter>;
18
67
 
19
68
  declare class KyroConnectError extends Error {
20
69
  readonly status: number;
@@ -23,4 +72,4 @@ declare class KyroConnectError extends Error {
23
72
  constructor(message: string, status?: number, raw?: any);
24
73
  }
25
74
 
26
- export { type ClientOptions, KyroConnectError, type ProcedureClient, type RouterClient, createClient };
75
+ export { type ClientOptions, type CollectionClient, type CollectionFindParams, type CollectionFindResult, type GqlClient, type KyroClient, KyroConnectError, type ProcedureClient, type RouterClient, type UploadClient, createClient };
package/dist/index.d.ts CHANGED
@@ -12,9 +12,58 @@ type RouterClient<T> = {
12
12
  [K in keyof T]: T[K] extends {
13
13
  input: infer I;
14
14
  output: infer O;
15
- } ? ProcedureClient<I, O> : T[K] extends Record<string, any> ? RouterClient<T[K]> : T[K];
15
+ } ? ProcedureClient<I, O> : T[K] extends Record<string, unknown> ? RouterClient<T[K]> : T[K];
16
16
  };
17
- declare function createClient<TRouter extends Record<string, any> = any>(opts: ClientOptions): RouterClient<TRouter>;
17
+ interface CollectionFindResult<T> {
18
+ docs: T[];
19
+ totalDocs: number;
20
+ page: number;
21
+ totalPages: number;
22
+ hasNextPage?: boolean;
23
+ hasPrevPage?: boolean;
24
+ }
25
+ interface CollectionFindParams {
26
+ draft?: boolean;
27
+ depth?: number;
28
+ sort?: string;
29
+ page?: number;
30
+ limit?: number;
31
+ select?: string;
32
+ where?: Record<string, unknown>;
33
+ }
34
+ interface CollectionClient<T, F = CollectionFindParams> {
35
+ find(params?: F & CollectionFindParams): Promise<CollectionFindResult<T>>;
36
+ findByID(id: string, params?: {
37
+ draft?: boolean;
38
+ depth?: number;
39
+ select?: string;
40
+ }): Promise<T | null>;
41
+ create(data: Partial<T>, params?: {
42
+ draft?: boolean;
43
+ depth?: number;
44
+ }): Promise<T>;
45
+ update(id: string, data: Partial<T>, params?: {
46
+ draft?: boolean;
47
+ depth?: number;
48
+ }): Promise<T>;
49
+ delete(id: string): Promise<{
50
+ message: string;
51
+ }>;
52
+ }
53
+ interface GqlClient {
54
+ <TData = Record<string, unknown>, TVars extends Record<string, unknown> = Record<string, unknown>>(query: string | {
55
+ toString(): string;
56
+ }, variables?: TVars): Promise<TData>;
57
+ }
58
+ interface UploadClient {
59
+ <TResult = unknown>(url: string, file: File | Blob, filename?: string): Promise<TResult>;
60
+ }
61
+ type KyroClient<TRouter> = RouterClient<TRouter> & {
62
+ collection: <T, F = CollectionFindParams>(slug: string) => CollectionClient<T, F>;
63
+ gql: GqlClient;
64
+ upload: UploadClient;
65
+ };
66
+ declare function createClient<TRouter extends Record<string, unknown> = Record<string, unknown>>(opts: ClientOptions): KyroClient<TRouter>;
18
67
 
19
68
  declare class KyroConnectError extends Error {
20
69
  readonly status: number;
@@ -23,4 +72,4 @@ declare class KyroConnectError extends Error {
23
72
  constructor(message: string, status?: number, raw?: any);
24
73
  }
25
74
 
26
- export { type ClientOptions, KyroConnectError, type ProcedureClient, type RouterClient, createClient };
75
+ export { type ClientOptions, type CollectionClient, type CollectionFindParams, type CollectionFindResult, type GqlClient, type KyroClient, KyroConnectError, type ProcedureClient, type RouterClient, type UploadClient, createClient };
package/dist/index.js CHANGED
@@ -22,14 +22,25 @@ async function handleResponse(res) {
22
22
  } catch {
23
23
  throw new KyroConnectError(res.statusText, res.status);
24
24
  }
25
- throw new KyroConnectError(
26
- body2?.error?.message ?? res.statusText,
27
- res.status,
28
- body2
29
- );
25
+ const message = typeof body2?.error === "string" ? body2.error : res.statusText;
26
+ throw new KyroConnectError(message, res.status, body2);
30
27
  }
31
28
  const body = await res.json();
32
- return body?.result?.data ?? body;
29
+ if (body && typeof body === "object" && "result" in body) {
30
+ return body.result.data;
31
+ }
32
+ return body;
33
+ }
34
+ function buildSearchParams(params) {
35
+ if (!params) return "";
36
+ const sp = new URLSearchParams();
37
+ for (const [key, value] of Object.entries(params)) {
38
+ if (value !== void 0 && value !== null) {
39
+ sp.set(key, typeof value === "object" ? JSON.stringify(value) : String(value));
40
+ }
41
+ }
42
+ const qs = sp.toString();
43
+ return qs ? `?${qs}` : "";
33
44
  }
34
45
  function createClient(opts) {
35
46
  const baseUrl = opts.url.replace(/\/$/, "");
@@ -49,13 +60,13 @@ function createClient(opts) {
49
60
  method: "POST",
50
61
  headers: { "Content-Type": "application/json", ...headers() },
51
62
  body: JSON.stringify(input)
52
- }).then(handleResponse);
63
+ }).then((res) => handleResponse(res));
53
64
  }
54
65
  const qs = encodeURIComponent(JSON.stringify(input));
55
66
  return doFetch(`${baseUrl}/${pathStr}?input=${qs}`, {
56
67
  method: "GET",
57
68
  headers: headers()
58
- }).then(handleResponse);
69
+ }).then((res) => handleResponse(res));
59
70
  }
60
71
  function buildProxy(path) {
61
72
  return new Proxy(function() {
@@ -68,7 +79,77 @@ function createClient(opts) {
68
79
  }
69
80
  });
70
81
  }
71
- return buildProxy([]);
82
+ const collection = (slug) => ({
83
+ async find(params) {
84
+ const res = await doFetch(`${baseUrl}/api/${slug}${buildSearchParams(params)}`, {
85
+ method: "GET",
86
+ headers: headers()
87
+ });
88
+ return handleResponse(res);
89
+ },
90
+ async findByID(id, params) {
91
+ const res = await doFetch(`${baseUrl}/api/${slug}/${id}${buildSearchParams(params)}`, {
92
+ method: "GET",
93
+ headers: headers()
94
+ });
95
+ const body = await handleResponse(res);
96
+ return body?.data ?? body;
97
+ },
98
+ async create(data, params) {
99
+ const res = await doFetch(`${baseUrl}/api/${slug}${buildSearchParams(params)}`, {
100
+ method: "POST",
101
+ headers: { "Content-Type": "application/json", ...headers() },
102
+ body: JSON.stringify(data)
103
+ });
104
+ const body = await handleResponse(res);
105
+ return body?.data ?? body;
106
+ },
107
+ async update(id, data, params) {
108
+ const res = await doFetch(`${baseUrl}/api/${slug}/${id}${buildSearchParams(params)}`, {
109
+ method: "PATCH",
110
+ headers: { "Content-Type": "application/json", ...headers() },
111
+ body: JSON.stringify(data)
112
+ });
113
+ const body = await handleResponse(res);
114
+ return body?.data ?? body;
115
+ },
116
+ async delete(id) {
117
+ const res = await doFetch(`${baseUrl}/api/${slug}/${id}`, {
118
+ method: "DELETE",
119
+ headers: headers()
120
+ });
121
+ return handleResponse(res);
122
+ }
123
+ });
124
+ const gql = async (query, variables) => {
125
+ const queryStr = typeof query === "string" ? query : query.toString();
126
+ const res = await doFetch(`${baseUrl}/api/graphql`, {
127
+ method: "POST",
128
+ headers: { "Content-Type": "application/json", ...headers() },
129
+ body: JSON.stringify({ query: queryStr, variables })
130
+ });
131
+ const body = await res.json();
132
+ if (body.errors) {
133
+ throw new KyroConnectError(body.errors[0]?.message || "GraphQL error", res.status, body);
134
+ }
135
+ return body.data;
136
+ };
137
+ const upload = async (url, file, filename) => {
138
+ const formData = new FormData();
139
+ formData.append("file", file, filename);
140
+ const res = await doFetch(`${baseUrl}${url}`, {
141
+ method: "POST",
142
+ headers: headers(),
143
+ body: formData
144
+ });
145
+ return handleResponse(res);
146
+ };
147
+ const proxy = buildProxy([]);
148
+ return Object.assign(proxy, {
149
+ collection,
150
+ gql,
151
+ upload
152
+ });
72
153
  }
73
154
  export {
74
155
  KyroConnectError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kyro-connect",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Universal SDK for Kyro CMS. Type-safe client + codegen for any platform.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",