katanakit-js 5.0.0 → 5.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/README.md +35 -1
- package/dist/adapters/insforge/index.d.ts +3 -0
- package/dist/adapters/insforge/index.d.ts.map +1 -0
- package/dist/adapters/insforge/index.js +2 -0
- package/dist/adapters/insforge/index.js.map +1 -0
- package/dist/adapters/insforge/insforge.service.d.ts +116 -0
- package/dist/adapters/insforge/insforge.service.d.ts.map +1 -0
- package/dist/adapters/insforge/insforge.service.js +449 -0
- package/dist/adapters/insforge/insforge.service.js.map +1 -0
- package/dist/adapters/notion/notion.service.d.ts.map +1 -1
- package/dist/adapters/notion/notion.service.js +58 -19
- package/dist/adapters/notion/notion.service.js.map +1 -1
- package/dist/adapters/wordpress/wordpress.service.d.ts.map +1 -1
- package/dist/adapters/wordpress/wordpress.service.js +161 -44
- package/dist/adapters/wordpress/wordpress.service.js.map +1 -1
- package/dist/config/seo.service.d.ts.map +1 -1
- package/dist/config/seo.service.js +42 -4
- package/dist/config/seo.service.js.map +1 -1
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/services/media.service.d.ts +97 -0
- package/dist/core/services/media.service.d.ts.map +1 -0
- package/dist/core/services/media.service.js +239 -0
- package/dist/core/services/media.service.js.map +1 -0
- package/dist/core/services/validation.service.d.ts +22 -0
- package/dist/core/services/validation.service.d.ts.map +1 -0
- package/dist/core/services/validation.service.js +41 -0
- package/dist/core/services/validation.service.js.map +1 -0
- package/dist/core/services/youtube.service.d.ts +79 -0
- package/dist/core/services/youtube.service.d.ts.map +1 -0
- package/dist/core/services/youtube.service.js +388 -0
- package/dist/core/services/youtube.service.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +1 -0
- package/dist/infrastructure/index.d.ts.map +1 -1
- package/dist/infrastructure/index.js +1 -0
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/infrastructure/media/media.service.d.ts +15 -0
- package/dist/infrastructure/media/media.service.d.ts.map +1 -0
- package/dist/infrastructure/media/media.service.js +44 -0
- package/dist/infrastructure/media/media.service.js.map +1 -0
- package/dist/schemas/access.schema.d.ts +69 -0
- package/dist/schemas/access.schema.d.ts.map +1 -0
- package/dist/schemas/access.schema.js +36 -0
- package/dist/schemas/access.schema.js.map +1 -0
- package/dist/schemas/ai.schema.d.ts +53 -0
- package/dist/schemas/ai.schema.d.ts.map +1 -0
- package/dist/schemas/ai.schema.js +34 -0
- package/dist/schemas/ai.schema.js.map +1 -0
- package/dist/schemas/common.schema.d.ts +49 -0
- package/dist/schemas/common.schema.d.ts.map +1 -0
- package/dist/schemas/common.schema.js +23 -0
- package/dist/schemas/common.schema.js.map +1 -0
- package/dist/schemas/core.schema.d.ts +164 -0
- package/dist/schemas/core.schema.d.ts.map +1 -0
- package/dist/schemas/core.schema.js +109 -0
- package/dist/schemas/core.schema.js.map +1 -0
- package/dist/schemas/index.d.ts +11 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +11 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/insforge.schema.d.ts +69 -0
- package/dist/schemas/insforge.schema.d.ts.map +1 -0
- package/dist/schemas/insforge.schema.js +82 -0
- package/dist/schemas/insforge.schema.js.map +1 -0
- package/dist/schemas/media.schema.d.ts +51 -0
- package/dist/schemas/media.schema.d.ts.map +1 -0
- package/dist/schemas/media.schema.js +50 -0
- package/dist/schemas/media.schema.js.map +1 -0
- package/dist/schemas/notion.schema.d.ts +1058 -0
- package/dist/schemas/notion.schema.d.ts.map +1 -0
- package/dist/schemas/notion.schema.js +248 -0
- package/dist/schemas/notion.schema.js.map +1 -0
- package/dist/schemas/rss.schema.d.ts +35 -0
- package/dist/schemas/rss.schema.d.ts.map +1 -0
- package/dist/schemas/rss.schema.js +44 -0
- package/dist/schemas/rss.schema.js.map +1 -0
- package/dist/schemas/wordpress.schema.d.ts +1304 -0
- package/dist/schemas/wordpress.schema.d.ts.map +1 -0
- package/dist/schemas/wordpress.schema.js +404 -0
- package/dist/schemas/wordpress.schema.js.map +1 -0
- package/dist/schemas/youtube.schema.d.ts +122 -0
- package/dist/schemas/youtube.schema.d.ts.map +1 -0
- package/dist/schemas/youtube.schema.js +113 -0
- package/dist/schemas/youtube.schema.js.map +1 -0
- package/dist/types/index.d.ts +150 -770
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +23 -3
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ A sharp, framework-agnostic TypeScript service toolkit organized with hexagonal
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install katanakit-js
|
|
9
9
|
# or
|
|
10
|
-
|
|
10
|
+
pnpm add katanakit-js
|
|
11
11
|
# or
|
|
12
12
|
bun add katanakit-js
|
|
13
13
|
```
|
|
@@ -324,6 +324,7 @@ const stop = useKatanaWatch(newProduct, () => checkValidations(), { deep: true }
|
|
|
324
324
|
## Features
|
|
325
325
|
|
|
326
326
|
- **Safe Results** — HTTP (and other fallible) operations return `{ data, error, ok }` instead of throwing
|
|
327
|
+
- **Zod validation everywhere** — `types/` is the single source of truth, inferred from Zod schemas via `z.infer`; `useValidate()` turns any schema into a Safe Result and API adapters validate every response at the boundary
|
|
327
328
|
- **Zero side effects** — importing any module is safe. No `fetch` calls, no `console.log`, no storage writes
|
|
328
329
|
- **Hexagonal architecture** — pure core, infrastructure adapters, framework adapters
|
|
329
330
|
- **Tree-shakeable** — destructured re-exports from Singleton facades
|
|
@@ -652,6 +653,11 @@ All functions return `FetchResult<T>` — the same Safe Result pattern used by t
|
|
|
652
653
|
| ------------- | --------------------------------- | ----------------------------------------------------------------- |
|
|
653
654
|
| **Notion** | `katanakit-js/adapters/notion` | Pages, databases, blocks, search with cursor pagination |
|
|
654
655
|
| **WordPress** | `katanakit-js/adapters/wordpress` | Posts, pages, media, categories, tags, comments, users, batch ops |
|
|
656
|
+
| **InsForge** | `katanakit-js/adapters/insforge` | Database fallback, storage buckets and edge functions |
|
|
657
|
+
|
|
658
|
+
All REST adapters validate responses with Zod: malformed payloads return a typed `502`
|
|
659
|
+
Safe Result instead of untyped garbage, and invalid inputs are rejected with `400`
|
|
660
|
+
before any network call.
|
|
655
661
|
|
|
656
662
|
### Notion
|
|
657
663
|
|
|
@@ -1217,6 +1223,34 @@ const full = await useWpGetPosts({
|
|
|
1217
1223
|
| **Next.js** | [`examples/wordpress/next-[slug].tsx`](https://github.com/senseikatana/katanakit-js/tree/main/examples/wordpress/next-[slug].tsx) | Dynamic `[slug]` page |
|
|
1218
1224
|
| **Node.js** | [`examples/wordpress/demo.ts`](https://github.com/senseikatana/katanakit-js/tree/main/examples/wordpress/demo.ts) | Runnable demo covering all WP operations, `_fields`, `_embed`, ACF |
|
|
1219
1225
|
|
|
1226
|
+
### InsForge (database fallback)
|
|
1227
|
+
|
|
1228
|
+
InsForge is supported as the **database fallback** (the primary data layer is Cloudflare),
|
|
1229
|
+
plus object storage and edge functions. The adapter wraps the official SDK in the same
|
|
1230
|
+
Safe Result contract, validates every input, and refuses mass writes (update/delete
|
|
1231
|
+
require non-empty filters).
|
|
1232
|
+
|
|
1233
|
+
```ts
|
|
1234
|
+
import { useInitInsforge, useIfSelect, useIfInsert } from "katanakit-js/adapters/insforge";
|
|
1235
|
+
|
|
1236
|
+
// Server-only admin client (apiKey), or browser-safe client (anonKey)
|
|
1237
|
+
useInitInsforge({ baseUrl: process.env.INSFORGE_URL!, apiKey: process.env.INSFORGE_API_KEY! });
|
|
1238
|
+
|
|
1239
|
+
const posts = await useIfSelect<{ id: number; title: string }>({
|
|
1240
|
+
table: "posts",
|
|
1241
|
+
filters: { author_id: 7 },
|
|
1242
|
+
order: { column: "created_at", ascending: false },
|
|
1243
|
+
limit: 10,
|
|
1244
|
+
});
|
|
1245
|
+
if (posts.ok) console.log(posts.data);
|
|
1246
|
+
|
|
1247
|
+
const created = await useIfInsert("posts", [{ title: "Hello" }]);
|
|
1248
|
+
```
|
|
1249
|
+
|
|
1250
|
+
Storage (`useIfUpload`, `useIfDownload`, `useIfRemove`, `useIfListObjects`,
|
|
1251
|
+
`useIfGetPublicUrl`) and edge functions (`useIfInvokeFunction`) follow the same pattern.
|
|
1252
|
+
Install the optional peer with `bun add @insforge/sdk`.
|
|
1253
|
+
|
|
1220
1254
|
## Contributing
|
|
1221
1255
|
|
|
1222
1256
|
We welcome contributions from the community! Whether it's fixing a bug, adding
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type { IfConfig, IfInsertRows, IfInvokeOptions, IfListOptions, IfOrder, IfRpcCall, IfStorageRef, IfTableQuery, IfUpdatePatch, IfWriteQuery, } from "../../types/index.js";
|
|
2
|
+
export { useGetInsforgeClient, useIfDelete, useIfDownload, useIfGetPublicUrl, useIfInsert, useIfInvokeFunction, useIfListObjects, useIfRemove, useIfRpc, useIfSelect, useIfUpdate, useIfUpload, useInitInsforge, } from "./insforge.service.js";
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/insforge/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,aAAa,EACb,OAAO,EACP,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,GACZ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACN,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,QAAQ,EACR,WAAW,EACX,WAAW,EACX,WAAW,EACX,eAAe,GACf,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/insforge/index.ts"],"names":[],"mappings":"AAYA,OAAO,EACN,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,QAAQ,EACR,WAAW,EACX,WAAW,EACX,WAAW,EACX,eAAe,GACf,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { type InsForgeClient } from "@insforge/sdk";
|
|
2
|
+
import type { FetchResult, IfConfig, IfInsertRows, IfInvokeOptions, IfListOptions, IfRpcCall, IfStorageRef, IfTableQuery, IfUpdatePatch, IfWriteQuery } from "../../types/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Registers the InsForge client. Call once per app. Prefer `apiKey`
|
|
5
|
+
* (server-only, admin) or `anonKey` (browser-safe) depending on the runtime.
|
|
6
|
+
*
|
|
7
|
+
* @param config - Backend URL + credentials + optional schema.
|
|
8
|
+
* @throws {Error} If the config fails validation.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { useInitInsforge } from "katanakit-js/adapters/insforge";
|
|
13
|
+
*
|
|
14
|
+
* useInitInsforge({ baseUrl: "https://app.insforge.app", anonKey: "…" });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function useInitInsforge(config: IfConfig): void;
|
|
18
|
+
/**
|
|
19
|
+
* Returns the initialized client (or `null` before `useInitInsforge`).
|
|
20
|
+
* Exposed for advanced use — the wrappers cover the supported surface.
|
|
21
|
+
*
|
|
22
|
+
* @returns The InsForge client or `null`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function useGetInsforgeClient(): InsForgeClient | null;
|
|
25
|
+
/**
|
|
26
|
+
* Reads rows from a table with equality filters, ordering and pagination.
|
|
27
|
+
*
|
|
28
|
+
* @param query - Table, columns, filters, order, limit and offset.
|
|
29
|
+
* @returns Safe Result with the rows.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* const result = await useIfSelect<Post>({ table: "posts", filters: { author_id: 7 } });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function useIfSelect<T = Record<string, unknown>>(query: IfTableQuery): Promise<FetchResult<T[]>>;
|
|
37
|
+
/**
|
|
38
|
+
* Inserts one or more rows and returns the created rows.
|
|
39
|
+
*
|
|
40
|
+
* @param table - Table name.
|
|
41
|
+
* @param rows - Rows to insert (at least one).
|
|
42
|
+
* @param schema - Optional schema override.
|
|
43
|
+
* @returns Safe Result with the inserted rows.
|
|
44
|
+
*/
|
|
45
|
+
export declare function useIfInsert<T = Record<string, unknown>>(table: string, rows: IfInsertRows, schema?: string): Promise<FetchResult<T[]>>;
|
|
46
|
+
/**
|
|
47
|
+
* Updates rows matching the filters and returns the updated rows.
|
|
48
|
+
* Filters are REQUIRED — mass updates are refused at validation time.
|
|
49
|
+
*
|
|
50
|
+
* @param query - Table + mandatory filters (+ optional schema).
|
|
51
|
+
* @param patch - Column patch (must not be empty).
|
|
52
|
+
* @returns Safe Result with the updated rows.
|
|
53
|
+
*/
|
|
54
|
+
export declare function useIfUpdate<T = Record<string, unknown>>(query: IfWriteQuery, patch: IfUpdatePatch): Promise<FetchResult<T[]>>;
|
|
55
|
+
/**
|
|
56
|
+
* Deletes rows matching the filters and returns the deleted rows.
|
|
57
|
+
* Filters are REQUIRED — mass deletes are refused at validation time.
|
|
58
|
+
*
|
|
59
|
+
* @param query - Table + mandatory filters (+ optional schema).
|
|
60
|
+
* @returns Safe Result with the deleted rows.
|
|
61
|
+
*/
|
|
62
|
+
export declare function useIfDelete<T = Record<string, unknown>>(query: IfWriteQuery): Promise<FetchResult<T[]>>;
|
|
63
|
+
/**
|
|
64
|
+
* Calls a Postgres function (RPC).
|
|
65
|
+
*
|
|
66
|
+
* @param call - Function name, params and optional schema.
|
|
67
|
+
* @returns Safe Result with the function output.
|
|
68
|
+
*/
|
|
69
|
+
export declare function useIfRpc<T = unknown>(call: IfRpcCall): Promise<FetchResult<T>>;
|
|
70
|
+
/**
|
|
71
|
+
* Uploads a file to a bucket (standard PUT semantics: same key replaces).
|
|
72
|
+
*
|
|
73
|
+
* @param ref - Bucket + object key.
|
|
74
|
+
* @param file - File or Blob to upload.
|
|
75
|
+
* @returns Safe Result with the stored file metadata.
|
|
76
|
+
*/
|
|
77
|
+
export declare function useIfUpload(ref: IfStorageRef, file: File | Blob): Promise<FetchResult<Record<string, unknown>>>;
|
|
78
|
+
/**
|
|
79
|
+
* Downloads a file from a bucket.
|
|
80
|
+
*
|
|
81
|
+
* @param ref - Bucket + object key.
|
|
82
|
+
* @returns Safe Result with the file as a Blob.
|
|
83
|
+
*/
|
|
84
|
+
export declare function useIfDownload(ref: IfStorageRef): Promise<FetchResult<Blob>>;
|
|
85
|
+
/**
|
|
86
|
+
* Removes a file from a bucket.
|
|
87
|
+
*
|
|
88
|
+
* @param ref - Bucket + object key.
|
|
89
|
+
* @returns Safe Result with the deletion response.
|
|
90
|
+
*/
|
|
91
|
+
export declare function useIfRemove(ref: IfStorageRef): Promise<FetchResult<Record<string, unknown>>>;
|
|
92
|
+
/**
|
|
93
|
+
* Lists objects in a bucket.
|
|
94
|
+
*
|
|
95
|
+
* @param bucket - Bucket name.
|
|
96
|
+
* @param options - Prefix, search, limit and offset.
|
|
97
|
+
* @returns Safe Result with the listing.
|
|
98
|
+
*/
|
|
99
|
+
export declare function useIfListObjects(bucket: string, options?: IfListOptions): Promise<FetchResult<Record<string, unknown>>>;
|
|
100
|
+
/**
|
|
101
|
+
* Builds the public URL for an object in a public bucket (no network call).
|
|
102
|
+
*
|
|
103
|
+
* @param ref - Bucket + object key.
|
|
104
|
+
* @returns Safe Result with `{ publicUrl }`.
|
|
105
|
+
*/
|
|
106
|
+
export declare function useIfGetPublicUrl(ref: IfStorageRef): FetchResult<{
|
|
107
|
+
publicUrl: string;
|
|
108
|
+
}>;
|
|
109
|
+
/**
|
|
110
|
+
* Invokes an edge function.
|
|
111
|
+
*
|
|
112
|
+
* @param options - Function slug + optional JSON body.
|
|
113
|
+
* @returns Safe Result with the function response.
|
|
114
|
+
*/
|
|
115
|
+
export declare function useIfInvokeFunction<T = unknown>(options: IfInvokeOptions): Promise<FetchResult<T>>;
|
|
116
|
+
//# sourceMappingURL=insforge.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insforge.service.d.ts","sourceRoot":"","sources":["../../../src/adapters/insforge/insforge.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAgBrF,OAAO,KAAK,EAEX,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,aAAa,EACb,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,MAAM,sBAAsB,CAAC;AAyH9B;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CActD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,GAAG,IAAI,CAE5D;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,KAAK,EAAE,YAAY,GACjB,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAyB3B;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,YAAY,EAClB,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAgB3B;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CA0B3B;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,KAAK,EAAE,YAAY,GACjB,OAAO,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAe3B;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAapF;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAChC,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,IAAI,GAAG,IAAI,GACf,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAoB/C;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAqBjF;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAChC,GAAG,EAAE,YAAY,GACf,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAkB/C;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,aAAa,GACrB,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAoB/C;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,WAAW,CAAC;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAiBvF;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,GAAG,OAAO,EACpD,OAAO,EAAE,eAAe,GACtB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAczB"}
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
import { createAdminClient, createClient } from "@insforge/sdk";
|
|
2
|
+
import { useValidate } from "../../core/services/validation.service.js";
|
|
3
|
+
import { IfBucketSchema, IfConfigSchema, IfInsertRowsSchema, IfInvokeOptionsSchema, IfListOptionsSchema, IfRpcCallSchema, IfStorageRefSchema, IfTableNameSchema, IfTableQuerySchema, IfUpdatePatchSchema, IfWriteQuerySchema, } from "../../schemas/insforge.schema.js";
|
|
4
|
+
/** Module-level client. InsForge is the database fallback, not the default. */
|
|
5
|
+
let client = null;
|
|
6
|
+
/**
|
|
7
|
+
* Maps an SDK error (InsForgeError or unknown throw) to the shared `ApiError`.
|
|
8
|
+
*
|
|
9
|
+
* @param error - Error thrown or returned by the SDK.
|
|
10
|
+
* @returns Normalized `ApiError`.
|
|
11
|
+
*/
|
|
12
|
+
function errorFrom(error) {
|
|
13
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
14
|
+
const record = error;
|
|
15
|
+
const message = typeof record.message === "string" ? record.message : "InsForge error";
|
|
16
|
+
const status = typeof record.statusCode === "number" ? record.statusCode : 0;
|
|
17
|
+
return { message, status, details: error };
|
|
18
|
+
}
|
|
19
|
+
return { message: String(error), status: 0, details: error };
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Builds a failed Safe Result from an SDK error.
|
|
23
|
+
*
|
|
24
|
+
* @param error - Error to map.
|
|
25
|
+
* @returns `FetchResult<T>` failure branch.
|
|
26
|
+
*/
|
|
27
|
+
function fail(error) {
|
|
28
|
+
const mapped = errorFrom(error);
|
|
29
|
+
return { data: null, error: mapped, url: "", status: mapped.status, ok: false };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Builds a 400 Safe Result from a failed input validation.
|
|
33
|
+
*
|
|
34
|
+
* @param parsed - Failed validation result.
|
|
35
|
+
* @returns `FetchResult<T>` failure branch.
|
|
36
|
+
*/
|
|
37
|
+
function invalidInput(parsed) {
|
|
38
|
+
return { data: null, error: parsed.error, url: "", status: 400, ok: false };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Builds the not-configured failure branch.
|
|
42
|
+
*
|
|
43
|
+
* @returns `FetchResult<T>` failure branch.
|
|
44
|
+
*/
|
|
45
|
+
function notConfigured() {
|
|
46
|
+
return {
|
|
47
|
+
data: null,
|
|
48
|
+
error: { message: "[InsForge] Not configured. Call useInitInsforge() first.", status: 0 },
|
|
49
|
+
url: "",
|
|
50
|
+
status: 0,
|
|
51
|
+
ok: false,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Applies equality filters to a builder chain.
|
|
56
|
+
*
|
|
57
|
+
* @param builder - Awaitable PostgREST builder.
|
|
58
|
+
* @param filters - Equality filters (`column: value`).
|
|
59
|
+
* @returns The filtered builder.
|
|
60
|
+
*/
|
|
61
|
+
function applyFilters(builder, filters) {
|
|
62
|
+
let current = builder;
|
|
63
|
+
for (const [column, value] of Object.entries(filters ?? {})) {
|
|
64
|
+
current = current.eq(column, value);
|
|
65
|
+
}
|
|
66
|
+
return current;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Resolves the database module, honoring a per-query schema override.
|
|
70
|
+
*
|
|
71
|
+
* @param database - Base database module from the SDK client.
|
|
72
|
+
* @param schema - Optional schema override.
|
|
73
|
+
* @returns The database module to use.
|
|
74
|
+
*/
|
|
75
|
+
function scopedDatabase(database, schema) {
|
|
76
|
+
if (schema) {
|
|
77
|
+
return database.schema(schema);
|
|
78
|
+
}
|
|
79
|
+
return database;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Registers the InsForge client. Call once per app. Prefer `apiKey`
|
|
83
|
+
* (server-only, admin) or `anonKey` (browser-safe) depending on the runtime.
|
|
84
|
+
*
|
|
85
|
+
* @param config - Backend URL + credentials + optional schema.
|
|
86
|
+
* @throws {Error} If the config fails validation.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* import { useInitInsforge } from "katanakit-js/adapters/insforge";
|
|
91
|
+
*
|
|
92
|
+
* useInitInsforge({ baseUrl: "https://app.insforge.app", anonKey: "…" });
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export function useInitInsforge(config) {
|
|
96
|
+
const parsed = useValidate(IfConfigSchema, config);
|
|
97
|
+
if (!parsed.ok) {
|
|
98
|
+
throw new Error(`[InsForge] Invalid config: ${parsed.error.message}`);
|
|
99
|
+
}
|
|
100
|
+
const { baseUrl, anonKey, apiKey, accessToken, schema } = parsed.data;
|
|
101
|
+
client = apiKey
|
|
102
|
+
? createAdminClient({ baseUrl, apiKey })
|
|
103
|
+
: createClient({
|
|
104
|
+
baseUrl,
|
|
105
|
+
...(anonKey !== undefined ? { anonKey } : {}),
|
|
106
|
+
...(accessToken !== undefined ? { accessToken } : {}),
|
|
107
|
+
...(schema !== undefined ? { db: { schema } } : {}),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Returns the initialized client (or `null` before `useInitInsforge`).
|
|
112
|
+
* Exposed for advanced use — the wrappers cover the supported surface.
|
|
113
|
+
*
|
|
114
|
+
* @returns The InsForge client or `null`.
|
|
115
|
+
*/
|
|
116
|
+
export function useGetInsforgeClient() {
|
|
117
|
+
return client;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Reads rows from a table with equality filters, ordering and pagination.
|
|
121
|
+
*
|
|
122
|
+
* @param query - Table, columns, filters, order, limit and offset.
|
|
123
|
+
* @returns Safe Result with the rows.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* const result = await useIfSelect<Post>({ table: "posts", filters: { author_id: 7 } });
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
export async function useIfSelect(query) {
|
|
131
|
+
const parsed = useValidate(IfTableQuerySchema, query);
|
|
132
|
+
if (!parsed.ok)
|
|
133
|
+
return invalidInput(parsed);
|
|
134
|
+
if (!client)
|
|
135
|
+
return notConfigured();
|
|
136
|
+
try {
|
|
137
|
+
const database = scopedDatabase(client.database, parsed.data.schema);
|
|
138
|
+
let builder = database.from(parsed.data.table).select(parsed.data.columns ?? "*");
|
|
139
|
+
builder = applyFilters(builder, parsed.data.filters);
|
|
140
|
+
if (parsed.data.order) {
|
|
141
|
+
builder = builder.order(parsed.data.order.column, {
|
|
142
|
+
ascending: parsed.data.order.ascending ?? true,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (parsed.data.limit !== undefined)
|
|
146
|
+
builder = builder.limit(parsed.data.limit);
|
|
147
|
+
if (parsed.data.offset !== undefined) {
|
|
148
|
+
const from = parsed.data.offset;
|
|
149
|
+
builder = builder.range(from, from + (parsed.data.limit ?? 100) - 1);
|
|
150
|
+
}
|
|
151
|
+
const outcome = await builder;
|
|
152
|
+
if (outcome.error)
|
|
153
|
+
return fail(outcome.error);
|
|
154
|
+
return { data: (outcome.data ?? []), error: null, url: "", status: 200, ok: true };
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
return fail(err);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Inserts one or more rows and returns the created rows.
|
|
162
|
+
*
|
|
163
|
+
* @param table - Table name.
|
|
164
|
+
* @param rows - Rows to insert (at least one).
|
|
165
|
+
* @param schema - Optional schema override.
|
|
166
|
+
* @returns Safe Result with the inserted rows.
|
|
167
|
+
*/
|
|
168
|
+
export async function useIfInsert(table, rows, schema) {
|
|
169
|
+
const tableParsed = useValidate(IfTableNameSchema, table);
|
|
170
|
+
if (!tableParsed.ok)
|
|
171
|
+
return invalidInput(tableParsed);
|
|
172
|
+
const rowsParsed = useValidate(IfInsertRowsSchema, rows);
|
|
173
|
+
if (!rowsParsed.ok)
|
|
174
|
+
return invalidInput(rowsParsed);
|
|
175
|
+
if (!client)
|
|
176
|
+
return notConfigured();
|
|
177
|
+
try {
|
|
178
|
+
const database = scopedDatabase(client.database, schema);
|
|
179
|
+
const builder = database.from(tableParsed.data).insert(rowsParsed.data);
|
|
180
|
+
const outcome = await builder.select("*");
|
|
181
|
+
if (outcome.error)
|
|
182
|
+
return fail(outcome.error);
|
|
183
|
+
return { data: (outcome.data ?? []), error: null, url: "", status: 201, ok: true };
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
return fail(err);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Updates rows matching the filters and returns the updated rows.
|
|
191
|
+
* Filters are REQUIRED — mass updates are refused at validation time.
|
|
192
|
+
*
|
|
193
|
+
* @param query - Table + mandatory filters (+ optional schema).
|
|
194
|
+
* @param patch - Column patch (must not be empty).
|
|
195
|
+
* @returns Safe Result with the updated rows.
|
|
196
|
+
*/
|
|
197
|
+
export async function useIfUpdate(query, patch) {
|
|
198
|
+
const queryParsed = useValidate(IfWriteQuerySchema, query);
|
|
199
|
+
if (!queryParsed.ok)
|
|
200
|
+
return invalidInput(queryParsed);
|
|
201
|
+
const patchParsed = useValidate(IfUpdatePatchSchema, patch);
|
|
202
|
+
if (!patchParsed.ok)
|
|
203
|
+
return invalidInput(patchParsed);
|
|
204
|
+
if (Object.keys(patchParsed.data).length === 0) {
|
|
205
|
+
return {
|
|
206
|
+
data: null,
|
|
207
|
+
error: { message: "Validation Error: patch must not be empty", status: 400 },
|
|
208
|
+
url: "",
|
|
209
|
+
status: 400,
|
|
210
|
+
ok: false,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
if (!client)
|
|
214
|
+
return notConfigured();
|
|
215
|
+
try {
|
|
216
|
+
const database = scopedDatabase(client.database, queryParsed.data.schema);
|
|
217
|
+
const updateBuilder = database.from(queryParsed.data.table).update(patchParsed.data);
|
|
218
|
+
const filtered = applyFilters(updateBuilder, queryParsed.data.filters);
|
|
219
|
+
const outcome = await filtered.select("*");
|
|
220
|
+
if (outcome.error)
|
|
221
|
+
return fail(outcome.error);
|
|
222
|
+
return { data: (outcome.data ?? []), error: null, url: "", status: 200, ok: true };
|
|
223
|
+
}
|
|
224
|
+
catch (err) {
|
|
225
|
+
return fail(err);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Deletes rows matching the filters and returns the deleted rows.
|
|
230
|
+
* Filters are REQUIRED — mass deletes are refused at validation time.
|
|
231
|
+
*
|
|
232
|
+
* @param query - Table + mandatory filters (+ optional schema).
|
|
233
|
+
* @returns Safe Result with the deleted rows.
|
|
234
|
+
*/
|
|
235
|
+
export async function useIfDelete(query) {
|
|
236
|
+
const parsed = useValidate(IfWriteQuerySchema, query);
|
|
237
|
+
if (!parsed.ok)
|
|
238
|
+
return invalidInput(parsed);
|
|
239
|
+
if (!client)
|
|
240
|
+
return notConfigured();
|
|
241
|
+
try {
|
|
242
|
+
const database = scopedDatabase(client.database, parsed.data.schema);
|
|
243
|
+
const deleteBuilder = database.from(parsed.data.table).delete();
|
|
244
|
+
const filtered = applyFilters(deleteBuilder, parsed.data.filters);
|
|
245
|
+
const outcome = await filtered.select("*");
|
|
246
|
+
if (outcome.error)
|
|
247
|
+
return fail(outcome.error);
|
|
248
|
+
return { data: (outcome.data ?? []), error: null, url: "", status: 200, ok: true };
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
return fail(err);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Calls a Postgres function (RPC).
|
|
256
|
+
*
|
|
257
|
+
* @param call - Function name, params and optional schema.
|
|
258
|
+
* @returns Safe Result with the function output.
|
|
259
|
+
*/
|
|
260
|
+
export async function useIfRpc(call) {
|
|
261
|
+
const parsed = useValidate(IfRpcCallSchema, call);
|
|
262
|
+
if (!parsed.ok)
|
|
263
|
+
return invalidInput(parsed);
|
|
264
|
+
if (!client)
|
|
265
|
+
return notConfigured();
|
|
266
|
+
try {
|
|
267
|
+
const database = scopedDatabase(client.database, parsed.data.schema);
|
|
268
|
+
const outcome = await database.rpc(parsed.data.name, parsed.data.params ?? {});
|
|
269
|
+
if (outcome.error)
|
|
270
|
+
return fail(outcome.error);
|
|
271
|
+
return { data: outcome.data, error: null, url: "", status: 200, ok: true };
|
|
272
|
+
}
|
|
273
|
+
catch (err) {
|
|
274
|
+
return fail(err);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Uploads a file to a bucket (standard PUT semantics: same key replaces).
|
|
279
|
+
*
|
|
280
|
+
* @param ref - Bucket + object key.
|
|
281
|
+
* @param file - File or Blob to upload.
|
|
282
|
+
* @returns Safe Result with the stored file metadata.
|
|
283
|
+
*/
|
|
284
|
+
export async function useIfUpload(ref, file) {
|
|
285
|
+
const parsed = useValidate(IfStorageRefSchema, ref);
|
|
286
|
+
if (!parsed.ok)
|
|
287
|
+
return invalidInput(parsed);
|
|
288
|
+
if (!client)
|
|
289
|
+
return notConfigured();
|
|
290
|
+
try {
|
|
291
|
+
const { data, error } = await client.storage
|
|
292
|
+
.from(parsed.data.bucket)
|
|
293
|
+
.upload(parsed.data.path, file);
|
|
294
|
+
if (error)
|
|
295
|
+
return fail(error);
|
|
296
|
+
return {
|
|
297
|
+
data: (data ?? {}),
|
|
298
|
+
error: null,
|
|
299
|
+
url: "",
|
|
300
|
+
status: 200,
|
|
301
|
+
ok: true,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
catch (err) {
|
|
305
|
+
return fail(err);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Downloads a file from a bucket.
|
|
310
|
+
*
|
|
311
|
+
* @param ref - Bucket + object key.
|
|
312
|
+
* @returns Safe Result with the file as a Blob.
|
|
313
|
+
*/
|
|
314
|
+
export async function useIfDownload(ref) {
|
|
315
|
+
const parsed = useValidate(IfStorageRefSchema, ref);
|
|
316
|
+
if (!parsed.ok)
|
|
317
|
+
return invalidInput(parsed);
|
|
318
|
+
if (!client)
|
|
319
|
+
return notConfigured();
|
|
320
|
+
try {
|
|
321
|
+
const { data, error } = await client.storage.from(parsed.data.bucket).download(parsed.data.path);
|
|
322
|
+
if (error)
|
|
323
|
+
return fail(error);
|
|
324
|
+
if (!data) {
|
|
325
|
+
return {
|
|
326
|
+
data: null,
|
|
327
|
+
error: { message: "InsForge Error: object not found", status: 404 },
|
|
328
|
+
url: "",
|
|
329
|
+
status: 404,
|
|
330
|
+
ok: false,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
return { data, error: null, url: "", status: 200, ok: true };
|
|
334
|
+
}
|
|
335
|
+
catch (err) {
|
|
336
|
+
return fail(err);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Removes a file from a bucket.
|
|
341
|
+
*
|
|
342
|
+
* @param ref - Bucket + object key.
|
|
343
|
+
* @returns Safe Result with the deletion response.
|
|
344
|
+
*/
|
|
345
|
+
export async function useIfRemove(ref) {
|
|
346
|
+
const parsed = useValidate(IfStorageRefSchema, ref);
|
|
347
|
+
if (!parsed.ok)
|
|
348
|
+
return invalidInput(parsed);
|
|
349
|
+
if (!client)
|
|
350
|
+
return notConfigured();
|
|
351
|
+
try {
|
|
352
|
+
const { data, error } = await client.storage.from(parsed.data.bucket).remove(parsed.data.path);
|
|
353
|
+
if (error)
|
|
354
|
+
return fail(error);
|
|
355
|
+
return {
|
|
356
|
+
data: (data ?? {}),
|
|
357
|
+
error: null,
|
|
358
|
+
url: "",
|
|
359
|
+
status: 200,
|
|
360
|
+
ok: true,
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
catch (err) {
|
|
364
|
+
return fail(err);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Lists objects in a bucket.
|
|
369
|
+
*
|
|
370
|
+
* @param bucket - Bucket name.
|
|
371
|
+
* @param options - Prefix, search, limit and offset.
|
|
372
|
+
* @returns Safe Result with the listing.
|
|
373
|
+
*/
|
|
374
|
+
export async function useIfListObjects(bucket, options) {
|
|
375
|
+
const bucketParsed = useValidate(IfBucketSchema, bucket);
|
|
376
|
+
if (!bucketParsed.ok)
|
|
377
|
+
return invalidInput(bucketParsed);
|
|
378
|
+
const optionsParsed = useValidate(IfListOptionsSchema, options ?? {});
|
|
379
|
+
if (!optionsParsed.ok)
|
|
380
|
+
return invalidInput(optionsParsed);
|
|
381
|
+
if (!client)
|
|
382
|
+
return notConfigured();
|
|
383
|
+
try {
|
|
384
|
+
const { data, error } = await client.storage.from(bucketParsed.data).list(optionsParsed.data);
|
|
385
|
+
if (error)
|
|
386
|
+
return fail(error);
|
|
387
|
+
return {
|
|
388
|
+
data: (data ?? {}),
|
|
389
|
+
error: null,
|
|
390
|
+
url: "",
|
|
391
|
+
status: 200,
|
|
392
|
+
ok: true,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
catch (err) {
|
|
396
|
+
return fail(err);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Builds the public URL for an object in a public bucket (no network call).
|
|
401
|
+
*
|
|
402
|
+
* @param ref - Bucket + object key.
|
|
403
|
+
* @returns Safe Result with `{ publicUrl }`.
|
|
404
|
+
*/
|
|
405
|
+
export function useIfGetPublicUrl(ref) {
|
|
406
|
+
const parsed = useValidate(IfStorageRefSchema, ref);
|
|
407
|
+
if (!parsed.ok)
|
|
408
|
+
return invalidInput(parsed);
|
|
409
|
+
if (!client)
|
|
410
|
+
return notConfigured();
|
|
411
|
+
const { data, error } = client.storage.from(parsed.data.bucket).getPublicUrl(parsed.data.path);
|
|
412
|
+
if (error)
|
|
413
|
+
return fail(error);
|
|
414
|
+
if (!data) {
|
|
415
|
+
return {
|
|
416
|
+
data: null,
|
|
417
|
+
error: { message: "InsForge Error: public URL unavailable", status: 404 },
|
|
418
|
+
url: "",
|
|
419
|
+
status: 404,
|
|
420
|
+
ok: false,
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
return { data, error: null, url: "", status: 200, ok: true };
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Invokes an edge function.
|
|
427
|
+
*
|
|
428
|
+
* @param options - Function slug + optional JSON body.
|
|
429
|
+
* @returns Safe Result with the function response.
|
|
430
|
+
*/
|
|
431
|
+
export async function useIfInvokeFunction(options) {
|
|
432
|
+
const parsed = useValidate(IfInvokeOptionsSchema, options);
|
|
433
|
+
if (!parsed.ok)
|
|
434
|
+
return invalidInput(parsed);
|
|
435
|
+
if (!client)
|
|
436
|
+
return notConfigured();
|
|
437
|
+
try {
|
|
438
|
+
const { data, error } = await client.functions.invoke(parsed.data.name, {
|
|
439
|
+
body: parsed.data.body,
|
|
440
|
+
});
|
|
441
|
+
if (error)
|
|
442
|
+
return fail(error);
|
|
443
|
+
return { data: data, error: null, url: "", status: 200, ok: true };
|
|
444
|
+
}
|
|
445
|
+
catch (err) {
|
|
446
|
+
return fail(err);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
//# sourceMappingURL=insforge.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insforge.service.js","sourceRoot":"","sources":["../../../src/adapters/insforge/insforge.service.ts"],"names":[],"mappings":"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"}
|