@archlast/client 0.0.1

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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +60 -0
  3. package/dist/admin/index.cjs +93 -0
  4. package/dist/admin/index.cjs.map +1 -0
  5. package/dist/admin/index.d.cts +51 -0
  6. package/dist/admin/index.d.ts +51 -0
  7. package/dist/admin/index.js +59 -0
  8. package/dist/admin/index.js.map +1 -0
  9. package/dist/auth/index.cjs +174 -0
  10. package/dist/auth/index.cjs.map +1 -0
  11. package/dist/auth/index.d.cts +128 -0
  12. package/dist/auth/index.d.ts +128 -0
  13. package/dist/auth/index.js +141 -0
  14. package/dist/auth/index.js.map +1 -0
  15. package/dist/client.cjs +677 -0
  16. package/dist/client.cjs.map +1 -0
  17. package/dist/client.d.cts +84 -0
  18. package/dist/client.d.ts +84 -0
  19. package/dist/client.js +642 -0
  20. package/dist/client.js.map +1 -0
  21. package/dist/function-reference.cjs +50 -0
  22. package/dist/function-reference.cjs.map +1 -0
  23. package/dist/function-reference.d.cts +22 -0
  24. package/dist/function-reference.d.ts +22 -0
  25. package/dist/function-reference.js +24 -0
  26. package/dist/function-reference.js.map +1 -0
  27. package/dist/index.cjs +1163 -0
  28. package/dist/index.cjs.map +1 -0
  29. package/dist/index.d.cts +12 -0
  30. package/dist/index.d.ts +12 -0
  31. package/dist/index.js +1111 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/react.cjs +455 -0
  34. package/dist/react.cjs.map +1 -0
  35. package/dist/react.d.cts +137 -0
  36. package/dist/react.d.ts +137 -0
  37. package/dist/react.js +410 -0
  38. package/dist/react.js.map +1 -0
  39. package/dist/storage/index.cjs +150 -0
  40. package/dist/storage/index.cjs.map +1 -0
  41. package/dist/storage/index.d.cts +59 -0
  42. package/dist/storage/index.d.ts +59 -0
  43. package/dist/storage/index.js +117 -0
  44. package/dist/storage/index.js.map +1 -0
  45. package/dist/trpc.cjs +66 -0
  46. package/dist/trpc.cjs.map +1 -0
  47. package/dist/trpc.d.cts +59 -0
  48. package/dist/trpc.d.ts +59 -0
  49. package/dist/trpc.js +41 -0
  50. package/dist/trpc.js.map +1 -0
  51. package/package.json +90 -0
@@ -0,0 +1,59 @@
1
+ type StorageFile = {
2
+ id: string;
3
+ url: string;
4
+ downloadUrl: string;
5
+ name: string;
6
+ fileName: string | null;
7
+ hash: string;
8
+ refCount: number;
9
+ contentType: string;
10
+ size: number;
11
+ createdAt: number;
12
+ updatedAt: number;
13
+ };
14
+ type StorageListResponse = {
15
+ items: StorageFile[];
16
+ };
17
+ type StorageClientOptions = {
18
+ /**
19
+ * Better-Auth API key for authentication
20
+ * When provided, uses x-api-key header instead of cookies
21
+ */
22
+ apiKey?: string;
23
+ };
24
+ declare class StorageClient {
25
+ private readonly axios;
26
+ constructor(baseUrl: string, appId?: string, options?: StorageClientOptions);
27
+ /**
28
+ * Upload a file
29
+ */
30
+ upload(file: Blob | Uint8Array | ReadableStream | File, contentType?: string): Promise<StorageFile>;
31
+ /**
32
+ * List files
33
+ */
34
+ list(limit?: number, offset?: number): Promise<StorageListResponse>;
35
+ /**
36
+ * Get file metadata
37
+ */
38
+ getMetadata(id: string): Promise<StorageFile>;
39
+ /**
40
+ * Generate a presigned download URL
41
+ */
42
+ presign(id: string, expiresInSeconds?: number): Promise<{
43
+ url: string;
44
+ }>;
45
+ /**
46
+ * Delete file
47
+ */
48
+ delete(id: string): Promise<{
49
+ success: boolean;
50
+ }>;
51
+ /**
52
+ * Get public URL for a file
53
+ */
54
+ getPublicUrl(id: string): string;
55
+ getDownloadUrl(id: string): string;
56
+ private hydrate;
57
+ }
58
+
59
+ export { StorageClient, type StorageClientOptions, type StorageFile, type StorageListResponse };
@@ -0,0 +1,59 @@
1
+ type StorageFile = {
2
+ id: string;
3
+ url: string;
4
+ downloadUrl: string;
5
+ name: string;
6
+ fileName: string | null;
7
+ hash: string;
8
+ refCount: number;
9
+ contentType: string;
10
+ size: number;
11
+ createdAt: number;
12
+ updatedAt: number;
13
+ };
14
+ type StorageListResponse = {
15
+ items: StorageFile[];
16
+ };
17
+ type StorageClientOptions = {
18
+ /**
19
+ * Better-Auth API key for authentication
20
+ * When provided, uses x-api-key header instead of cookies
21
+ */
22
+ apiKey?: string;
23
+ };
24
+ declare class StorageClient {
25
+ private readonly axios;
26
+ constructor(baseUrl: string, appId?: string, options?: StorageClientOptions);
27
+ /**
28
+ * Upload a file
29
+ */
30
+ upload(file: Blob | Uint8Array | ReadableStream | File, contentType?: string): Promise<StorageFile>;
31
+ /**
32
+ * List files
33
+ */
34
+ list(limit?: number, offset?: number): Promise<StorageListResponse>;
35
+ /**
36
+ * Get file metadata
37
+ */
38
+ getMetadata(id: string): Promise<StorageFile>;
39
+ /**
40
+ * Generate a presigned download URL
41
+ */
42
+ presign(id: string, expiresInSeconds?: number): Promise<{
43
+ url: string;
44
+ }>;
45
+ /**
46
+ * Delete file
47
+ */
48
+ delete(id: string): Promise<{
49
+ success: boolean;
50
+ }>;
51
+ /**
52
+ * Get public URL for a file
53
+ */
54
+ getPublicUrl(id: string): string;
55
+ getDownloadUrl(id: string): string;
56
+ private hydrate;
57
+ }
58
+
59
+ export { StorageClient, type StorageClientOptions, type StorageFile, type StorageListResponse };
@@ -0,0 +1,117 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+
5
+ // src/storage/index.ts
6
+ import axios from "axios";
7
+ var StorageClient = class {
8
+ constructor(baseUrl, appId, options) {
9
+ __publicField(this, "axios");
10
+ this.axios = axios.create({
11
+ baseURL: baseUrl,
12
+ withCredentials: !options?.apiKey,
13
+ // Only use cookies if no API key
14
+ headers: {
15
+ ...appId ? { "x-archlast-app-id": appId } : {},
16
+ ...options?.apiKey ? { "x-api-key": options.apiKey } : {}
17
+ }
18
+ });
19
+ }
20
+ /**
21
+ * Upload a file
22
+ */
23
+ async upload(file, contentType) {
24
+ let body = file;
25
+ let headers = {};
26
+ if (file instanceof File) {
27
+ const formData = new FormData();
28
+ formData.append("file", file);
29
+ body = formData;
30
+ } else {
31
+ if (contentType) {
32
+ headers["Content-Type"] = contentType;
33
+ }
34
+ if (file instanceof Uint8Array) {
35
+ }
36
+ }
37
+ const response = await this.axios.post(
38
+ "/_archlast/storage/upload",
39
+ body,
40
+ {
41
+ headers
42
+ }
43
+ );
44
+ const data = response.data;
45
+ if (!data.id) throw new Error("Upload failed: No ID returned");
46
+ return this.hydrate(data);
47
+ }
48
+ /**
49
+ * List files
50
+ */
51
+ async list(limit = 20, offset = 0) {
52
+ const response = await this.axios.get("/_archlast/storage/list", {
53
+ params: { limit, offset }
54
+ });
55
+ return {
56
+ items: response.data.items.map((item) => this.hydrate(item))
57
+ };
58
+ }
59
+ /**
60
+ * Get file metadata
61
+ */
62
+ async getMetadata(id) {
63
+ const response = await this.axios.get(`/_archlast/storage/files/${id}`);
64
+ return this.hydrate(response.data);
65
+ }
66
+ /**
67
+ * Generate a presigned download URL
68
+ */
69
+ async presign(id, expiresInSeconds = 300) {
70
+ const response = await this.axios.post("/_archlast/storage/presign", {
71
+ id,
72
+ expiresInSeconds
73
+ });
74
+ return response.data;
75
+ }
76
+ /**
77
+ * Delete file
78
+ */
79
+ async delete(id) {
80
+ const response = await this.axios.delete(
81
+ `/_archlast/storage/files/${id}`
82
+ );
83
+ return response.data;
84
+ }
85
+ /**
86
+ * Get public URL for a file
87
+ */
88
+ getPublicUrl(id) {
89
+ const base = this.axios.defaults.baseURL?.replace(/\/+$/, "") || "";
90
+ return `${base}/_storage/${id}`;
91
+ }
92
+ getDownloadUrl(id) {
93
+ const base = this.axios.defaults.baseURL?.replace(/\/+$/, "") || "";
94
+ return `${base}/_archlast/storage/files/${id}/download`;
95
+ }
96
+ hydrate(file) {
97
+ if (!file.id) throw new Error("Invalid file object: missing id");
98
+ return {
99
+ id: file.id,
100
+ name: file.name ?? file.fileName ?? "Untitled",
101
+ // Handle aliasing
102
+ fileName: file.fileName ?? file.name ?? null,
103
+ url: file.url ?? this.getPublicUrl(file.id),
104
+ downloadUrl: file.downloadUrl ?? this.getDownloadUrl(file.id),
105
+ hash: file.hash ?? "",
106
+ contentType: file.contentType ?? "application/octet-stream",
107
+ size: file.size ?? 0,
108
+ createdAt: file.createdAt ?? Date.now(),
109
+ updatedAt: file.updatedAt ?? Date.now(),
110
+ refCount: file.refCount ?? 1
111
+ };
112
+ }
113
+ };
114
+ export {
115
+ StorageClient
116
+ };
117
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/storage/index.ts"],"sourcesContent":["import axios, { AxiosInstance } from \"axios\";\n\nexport type StorageFile = {\n id: string; // The storage key/path\n url: string; // Public URL\n downloadUrl: string; // Authenticated download URL\n name: string;\n fileName: string | null;\n hash: string;\n refCount: number;\n contentType: string;\n size: number;\n createdAt: number;\n updatedAt: number;\n};\n\nexport type StorageListResponse = {\n items: StorageFile[];\n};\n\nexport type StorageClientOptions = {\n /**\n * Better-Auth API key for authentication\n * When provided, uses x-api-key header instead of cookies\n */\n apiKey?: string;\n};\n\nexport class StorageClient {\n private readonly axios: AxiosInstance;\n\n constructor(baseUrl: string, appId?: string, options?: StorageClientOptions) {\n this.axios = axios.create({\n baseURL: baseUrl,\n withCredentials: !options?.apiKey, // Only use cookies if no API key\n headers: {\n ...(appId ? { \"x-archlast-app-id\": appId } : {}),\n ...(options?.apiKey ? { \"x-api-key\": options.apiKey } : {}),\n },\n });\n }\n\n /**\n * Upload a file\n */\n async upload(\n file: Blob | Uint8Array | ReadableStream | File,\n contentType?: string\n ): Promise<StorageFile> {\n let body: FormData | Blob | Uint8Array | ReadableStream = file;\n let headers: Record<string, string> = {};\n\n if (file instanceof File) {\n const formData = new FormData();\n formData.append(\"file\", file);\n body = formData;\n } else {\n // Raw binary upload\n if (contentType) {\n headers[\"Content-Type\"] = contentType;\n }\n\n // Convert ReadableStream if needed, or pass through if supported by axios/adapter\n // For browser axios, usually Blob/ArrayBuffer/FormData\n if (file instanceof Uint8Array) {\n // wrap in Blob if possible or send directly\n }\n }\n\n const response = await this.axios.post<Partial<StorageFile>>(\n \"/_archlast/storage/upload\",\n body,\n {\n headers,\n }\n );\n\n // Hydrate URLs\n const data = response.data;\n if (!data.id) throw new Error(\"Upload failed: No ID returned\");\n\n return this.hydrate(data as StorageFile);\n }\n\n /**\n * List files\n */\n async list(limit = 20, offset = 0): Promise<StorageListResponse> {\n const response = await this.axios.get<StorageListResponse>(\"/_archlast/storage/list\", {\n params: { limit, offset },\n });\n return {\n items: response.data.items.map((item) => this.hydrate(item)),\n };\n }\n\n /**\n * Get file metadata\n */\n async getMetadata(id: string): Promise<StorageFile> {\n const response = await this.axios.get<StorageFile>(`/_archlast/storage/files/${id}`);\n return this.hydrate(response.data);\n }\n\n /**\n * Generate a presigned download URL\n */\n async presign(id: string, expiresInSeconds: number = 300): Promise<{ url: string }> {\n const response = await this.axios.post<{ url: string }>(\"/_archlast/storage/presign\", {\n id,\n expiresInSeconds,\n });\n return response.data;\n }\n\n /**\n * Delete file\n */\n async delete(id: string): Promise<{ success: boolean }> {\n const response = await this.axios.delete<{ success: boolean }>(\n `/_archlast/storage/files/${id}`\n );\n return response.data;\n }\n\n /**\n * Get public URL for a file\n */\n getPublicUrl(id: string): string {\n const base = this.axios.defaults.baseURL?.replace(/\\/+$/, \"\") || \"\";\n // If base is relative (starts with /), assumes same origin\n return `${base}/_storage/${id}`;\n }\n\n getDownloadUrl(id: string): string {\n // Direct authenticated download endpoint\n const base = this.axios.defaults.baseURL?.replace(/\\/+$/, \"\") || \"\";\n return `${base}/_archlast/storage/files/${id}/download`;\n }\n\n private hydrate(file: Partial<StorageFile>): StorageFile {\n if (!file.id) throw new Error(\"Invalid file object: missing id\");\n return {\n id: file.id,\n name: file.name ?? file.fileName ?? \"Untitled\", // Handle aliasing\n fileName: file.fileName ?? file.name ?? null,\n url: file.url ?? this.getPublicUrl(file.id),\n downloadUrl: file.downloadUrl ?? this.getDownloadUrl(file.id),\n hash: file.hash ?? \"\",\n contentType: file.contentType ?? \"application/octet-stream\",\n size: file.size ?? 0,\n createdAt: file.createdAt ?? Date.now(),\n updatedAt: file.updatedAt ?? Date.now(),\n refCount: file.refCount ?? 1,\n };\n }\n}\n"],"mappings":"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","names":[]}
package/dist/trpc.cjs ADDED
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/trpc.ts
21
+ var trpc_exports = {};
22
+ __export(trpc_exports, {
23
+ createArchlastTRPCClient: () => createArchlastTRPCClient
24
+ });
25
+ module.exports = __toCommonJS(trpc_exports);
26
+ var import_client = require("@trpc/client");
27
+ var BETTER_AUTH_API_KEY_PREFIX = "arch_";
28
+ function isBetterAuthApiKey(token) {
29
+ return token.startsWith(BETTER_AUTH_API_KEY_PREFIX);
30
+ }
31
+ function createArchlastTRPCClient(options = {}) {
32
+ const {
33
+ baseUrl = "http://localhost:4000",
34
+ apiKey,
35
+ sessionToken,
36
+ batch = true,
37
+ headers: customHeaders = {}
38
+ } = options;
39
+ const headers = {
40
+ "Content-Type": "application/json",
41
+ ...customHeaders
42
+ };
43
+ if (apiKey) {
44
+ if (isBetterAuthApiKey(apiKey)) {
45
+ headers["x-api-key"] = apiKey;
46
+ } else {
47
+ headers["Authorization"] = `Bearer ${apiKey}`;
48
+ }
49
+ }
50
+ if (sessionToken) {
51
+ headers["Cookie"] = `archlast-session=${sessionToken}`;
52
+ }
53
+ return (0, import_client.createTRPCClient)({
54
+ links: [
55
+ (0, import_client.httpBatchLink)({
56
+ url: `${baseUrl}/api/trpc`,
57
+ headers
58
+ })
59
+ ]
60
+ });
61
+ }
62
+ // Annotate the CommonJS export names for ESM import in node:
63
+ 0 && (module.exports = {
64
+ createArchlastTRPCClient
65
+ });
66
+ //# sourceMappingURL=trpc.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/trpc.ts"],"sourcesContent":["/**\r\n * tRPC Client Factory\r\n * Provides a type-safe tRPC client for calling Archlast RPC procedures\r\n */\r\n\r\nimport { createTRPCClient, httpBatchLink } from \"@trpc/client\";\r\nimport type { AnyRouter } from \"@trpc/server\";\r\n\r\nconst BETTER_AUTH_API_KEY_PREFIX = \"arch_\";\r\n\r\n/**\r\n * Check if a token is a Better-Auth API key\r\n */\r\nfunction isBetterAuthApiKey(token: string): boolean {\r\n return token.startsWith(BETTER_AUTH_API_KEY_PREFIX);\r\n}\r\n\r\n/**\r\n * Options for creating the tRPC client\r\n */\r\nexport interface CreateTRPCClientOptions {\r\n /**\r\n * Base URL of the Archlast server\r\n * @default http://localhost:4000\r\n */\r\n baseUrl?: string;\r\n\r\n /**\r\n * API key for authentication\r\n * Better-Auth API keys (arch_* prefix) use x-api-key header\r\n * Legacy tokens use Authorization: Bearer header\r\n */\r\n apiKey?: string;\r\n\r\n /**\r\n * Session token for authentication\r\n */\r\n sessionToken?: string;\r\n\r\n /**\r\n * Whether to use batching for multiple requests\r\n * @default true\r\n */\r\n batch?: boolean;\r\n\r\n /**\r\n * Custom headers to include in requests\r\n */\r\n headers?: Record<string, string>;\r\n}\r\n\r\n/**\r\n * Create a typed tRPC client for the Archlast server\r\n *\r\n * @example\r\n * ```ts\r\n * import { createArchlastTRPCClient } from \"@archlast/client/trpc\";\r\n * import type { AppRouter } from \"./_generated/rpc\";\r\n *\r\n * const client = createArchlastTRPCClient<AppRouter>({\r\n * baseUrl: \"http://localhost:4000\",\r\n * apiKey: \"arch_your-api-key\" // Better-Auth API key\r\n * });\r\n *\r\n * // Call RPC procedures\r\n * const result = await client.tasks.list.query();\r\n * const created = await client.tasks.create.mutate({ text: \"New task\" });\r\n * ```\r\n */\r\nexport function createArchlastTRPCClient<TRouter extends AnyRouter>(\r\n options: CreateTRPCClientOptions = {}\r\n): any {\r\n const {\r\n baseUrl = \"http://localhost:4000\",\r\n apiKey,\r\n sessionToken,\r\n batch = true,\r\n headers: customHeaders = {},\r\n } = options;\r\n\r\n // Build headers\r\n const headers: Record<string, string> = {\r\n \"Content-Type\": \"application/json\",\r\n ...customHeaders,\r\n };\r\n\r\n if (apiKey) {\r\n if (isBetterAuthApiKey(apiKey)) {\r\n // Better-Auth API key - use x-api-key header\r\n headers[\"x-api-key\"] = apiKey;\r\n } else {\r\n // Legacy token - use Authorization: Bearer header\r\n headers[\"Authorization\"] = `Bearer ${apiKey}`;\r\n }\r\n }\r\n\r\n if (sessionToken) {\r\n headers[\"Cookie\"] = `archlast-session=${sessionToken}`;\r\n }\r\n\r\n return createTRPCClient<TRouter>({\r\n links: [\r\n httpBatchLink({\r\n url: `${baseUrl}/api/trpc`,\r\n headers: headers as any,\r\n } as any),\r\n ],\r\n });\r\n}\r\n\r\n/**\r\n * Re-export tRPC types for convenience\r\n */\r\nexport type { TRPCClientError, createTRPCClient, httpBatchLink } from \"@trpc/client\";\r\nexport type { AnyRouter } from \"@trpc/server\";\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,oBAAgD;AAGhD,IAAM,6BAA6B;AAKnC,SAAS,mBAAmB,OAAwB;AAChD,SAAO,MAAM,WAAW,0BAA0B;AACtD;AAsDO,SAAS,yBACZ,UAAmC,CAAC,GACjC;AACH,QAAM;AAAA,IACF,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,SAAS,gBAAgB,CAAC;AAAA,EAC9B,IAAI;AAGJ,QAAM,UAAkC;AAAA,IACpC,gBAAgB;AAAA,IAChB,GAAG;AAAA,EACP;AAEA,MAAI,QAAQ;AACR,QAAI,mBAAmB,MAAM,GAAG;AAE5B,cAAQ,WAAW,IAAI;AAAA,IAC3B,OAAO;AAEH,cAAQ,eAAe,IAAI,UAAU,MAAM;AAAA,IAC/C;AAAA,EACJ;AAEA,MAAI,cAAc;AACd,YAAQ,QAAQ,IAAI,oBAAoB,YAAY;AAAA,EACxD;AAEA,aAAO,gCAA0B;AAAA,IAC7B,OAAO;AAAA,UACH,6BAAc;AAAA,QACV,KAAK,GAAG,OAAO;AAAA,QACf;AAAA,MACJ,CAAQ;AAAA,IACZ;AAAA,EACJ,CAAC;AACL;","names":[]}
@@ -0,0 +1,59 @@
1
+ import { AnyRouter } from '@trpc/server';
2
+ export { AnyRouter } from '@trpc/server';
3
+ export { TRPCClientError, createTRPCClient, httpBatchLink } from '@trpc/client';
4
+
5
+ /**
6
+ * tRPC Client Factory
7
+ * Provides a type-safe tRPC client for calling Archlast RPC procedures
8
+ */
9
+
10
+ /**
11
+ * Options for creating the tRPC client
12
+ */
13
+ interface CreateTRPCClientOptions {
14
+ /**
15
+ * Base URL of the Archlast server
16
+ * @default http://localhost:4000
17
+ */
18
+ baseUrl?: string;
19
+ /**
20
+ * API key for authentication
21
+ * Better-Auth API keys (arch_* prefix) use x-api-key header
22
+ * Legacy tokens use Authorization: Bearer header
23
+ */
24
+ apiKey?: string;
25
+ /**
26
+ * Session token for authentication
27
+ */
28
+ sessionToken?: string;
29
+ /**
30
+ * Whether to use batching for multiple requests
31
+ * @default true
32
+ */
33
+ batch?: boolean;
34
+ /**
35
+ * Custom headers to include in requests
36
+ */
37
+ headers?: Record<string, string>;
38
+ }
39
+ /**
40
+ * Create a typed tRPC client for the Archlast server
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * import { createArchlastTRPCClient } from "@archlast/client/trpc";
45
+ * import type { AppRouter } from "./_generated/rpc";
46
+ *
47
+ * const client = createArchlastTRPCClient<AppRouter>({
48
+ * baseUrl: "http://localhost:4000",
49
+ * apiKey: "arch_your-api-key" // Better-Auth API key
50
+ * });
51
+ *
52
+ * // Call RPC procedures
53
+ * const result = await client.tasks.list.query();
54
+ * const created = await client.tasks.create.mutate({ text: "New task" });
55
+ * ```
56
+ */
57
+ declare function createArchlastTRPCClient<TRouter extends AnyRouter>(options?: CreateTRPCClientOptions): any;
58
+
59
+ export { type CreateTRPCClientOptions, createArchlastTRPCClient };
package/dist/trpc.d.ts ADDED
@@ -0,0 +1,59 @@
1
+ import { AnyRouter } from '@trpc/server';
2
+ export { AnyRouter } from '@trpc/server';
3
+ export { TRPCClientError, createTRPCClient, httpBatchLink } from '@trpc/client';
4
+
5
+ /**
6
+ * tRPC Client Factory
7
+ * Provides a type-safe tRPC client for calling Archlast RPC procedures
8
+ */
9
+
10
+ /**
11
+ * Options for creating the tRPC client
12
+ */
13
+ interface CreateTRPCClientOptions {
14
+ /**
15
+ * Base URL of the Archlast server
16
+ * @default http://localhost:4000
17
+ */
18
+ baseUrl?: string;
19
+ /**
20
+ * API key for authentication
21
+ * Better-Auth API keys (arch_* prefix) use x-api-key header
22
+ * Legacy tokens use Authorization: Bearer header
23
+ */
24
+ apiKey?: string;
25
+ /**
26
+ * Session token for authentication
27
+ */
28
+ sessionToken?: string;
29
+ /**
30
+ * Whether to use batching for multiple requests
31
+ * @default true
32
+ */
33
+ batch?: boolean;
34
+ /**
35
+ * Custom headers to include in requests
36
+ */
37
+ headers?: Record<string, string>;
38
+ }
39
+ /**
40
+ * Create a typed tRPC client for the Archlast server
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * import { createArchlastTRPCClient } from "@archlast/client/trpc";
45
+ * import type { AppRouter } from "./_generated/rpc";
46
+ *
47
+ * const client = createArchlastTRPCClient<AppRouter>({
48
+ * baseUrl: "http://localhost:4000",
49
+ * apiKey: "arch_your-api-key" // Better-Auth API key
50
+ * });
51
+ *
52
+ * // Call RPC procedures
53
+ * const result = await client.tasks.list.query();
54
+ * const created = await client.tasks.create.mutate({ text: "New task" });
55
+ * ```
56
+ */
57
+ declare function createArchlastTRPCClient<TRouter extends AnyRouter>(options?: CreateTRPCClientOptions): any;
58
+
59
+ export { type CreateTRPCClientOptions, createArchlastTRPCClient };
package/dist/trpc.js ADDED
@@ -0,0 +1,41 @@
1
+ // src/trpc.ts
2
+ import { createTRPCClient, httpBatchLink } from "@trpc/client";
3
+ var BETTER_AUTH_API_KEY_PREFIX = "arch_";
4
+ function isBetterAuthApiKey(token) {
5
+ return token.startsWith(BETTER_AUTH_API_KEY_PREFIX);
6
+ }
7
+ function createArchlastTRPCClient(options = {}) {
8
+ const {
9
+ baseUrl = "http://localhost:4000",
10
+ apiKey,
11
+ sessionToken,
12
+ batch = true,
13
+ headers: customHeaders = {}
14
+ } = options;
15
+ const headers = {
16
+ "Content-Type": "application/json",
17
+ ...customHeaders
18
+ };
19
+ if (apiKey) {
20
+ if (isBetterAuthApiKey(apiKey)) {
21
+ headers["x-api-key"] = apiKey;
22
+ } else {
23
+ headers["Authorization"] = `Bearer ${apiKey}`;
24
+ }
25
+ }
26
+ if (sessionToken) {
27
+ headers["Cookie"] = `archlast-session=${sessionToken}`;
28
+ }
29
+ return createTRPCClient({
30
+ links: [
31
+ httpBatchLink({
32
+ url: `${baseUrl}/api/trpc`,
33
+ headers
34
+ })
35
+ ]
36
+ });
37
+ }
38
+ export {
39
+ createArchlastTRPCClient
40
+ };
41
+ //# sourceMappingURL=trpc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/trpc.ts"],"sourcesContent":["/**\r\n * tRPC Client Factory\r\n * Provides a type-safe tRPC client for calling Archlast RPC procedures\r\n */\r\n\r\nimport { createTRPCClient, httpBatchLink } from \"@trpc/client\";\r\nimport type { AnyRouter } from \"@trpc/server\";\r\n\r\nconst BETTER_AUTH_API_KEY_PREFIX = \"arch_\";\r\n\r\n/**\r\n * Check if a token is a Better-Auth API key\r\n */\r\nfunction isBetterAuthApiKey(token: string): boolean {\r\n return token.startsWith(BETTER_AUTH_API_KEY_PREFIX);\r\n}\r\n\r\n/**\r\n * Options for creating the tRPC client\r\n */\r\nexport interface CreateTRPCClientOptions {\r\n /**\r\n * Base URL of the Archlast server\r\n * @default http://localhost:4000\r\n */\r\n baseUrl?: string;\r\n\r\n /**\r\n * API key for authentication\r\n * Better-Auth API keys (arch_* prefix) use x-api-key header\r\n * Legacy tokens use Authorization: Bearer header\r\n */\r\n apiKey?: string;\r\n\r\n /**\r\n * Session token for authentication\r\n */\r\n sessionToken?: string;\r\n\r\n /**\r\n * Whether to use batching for multiple requests\r\n * @default true\r\n */\r\n batch?: boolean;\r\n\r\n /**\r\n * Custom headers to include in requests\r\n */\r\n headers?: Record<string, string>;\r\n}\r\n\r\n/**\r\n * Create a typed tRPC client for the Archlast server\r\n *\r\n * @example\r\n * ```ts\r\n * import { createArchlastTRPCClient } from \"@archlast/client/trpc\";\r\n * import type { AppRouter } from \"./_generated/rpc\";\r\n *\r\n * const client = createArchlastTRPCClient<AppRouter>({\r\n * baseUrl: \"http://localhost:4000\",\r\n * apiKey: \"arch_your-api-key\" // Better-Auth API key\r\n * });\r\n *\r\n * // Call RPC procedures\r\n * const result = await client.tasks.list.query();\r\n * const created = await client.tasks.create.mutate({ text: \"New task\" });\r\n * ```\r\n */\r\nexport function createArchlastTRPCClient<TRouter extends AnyRouter>(\r\n options: CreateTRPCClientOptions = {}\r\n): any {\r\n const {\r\n baseUrl = \"http://localhost:4000\",\r\n apiKey,\r\n sessionToken,\r\n batch = true,\r\n headers: customHeaders = {},\r\n } = options;\r\n\r\n // Build headers\r\n const headers: Record<string, string> = {\r\n \"Content-Type\": \"application/json\",\r\n ...customHeaders,\r\n };\r\n\r\n if (apiKey) {\r\n if (isBetterAuthApiKey(apiKey)) {\r\n // Better-Auth API key - use x-api-key header\r\n headers[\"x-api-key\"] = apiKey;\r\n } else {\r\n // Legacy token - use Authorization: Bearer header\r\n headers[\"Authorization\"] = `Bearer ${apiKey}`;\r\n }\r\n }\r\n\r\n if (sessionToken) {\r\n headers[\"Cookie\"] = `archlast-session=${sessionToken}`;\r\n }\r\n\r\n return createTRPCClient<TRouter>({\r\n links: [\r\n httpBatchLink({\r\n url: `${baseUrl}/api/trpc`,\r\n headers: headers as any,\r\n } as any),\r\n ],\r\n });\r\n}\r\n\r\n/**\r\n * Re-export tRPC types for convenience\r\n */\r\nexport type { TRPCClientError, createTRPCClient, httpBatchLink } from \"@trpc/client\";\r\nexport type { AnyRouter } from \"@trpc/server\";\r\n"],"mappings":";AAKA,SAAS,kBAAkB,qBAAqB;AAGhD,IAAM,6BAA6B;AAKnC,SAAS,mBAAmB,OAAwB;AAChD,SAAO,MAAM,WAAW,0BAA0B;AACtD;AAsDO,SAAS,yBACZ,UAAmC,CAAC,GACjC;AACH,QAAM;AAAA,IACF,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,SAAS,gBAAgB,CAAC;AAAA,EAC9B,IAAI;AAGJ,QAAM,UAAkC;AAAA,IACpC,gBAAgB;AAAA,IAChB,GAAG;AAAA,EACP;AAEA,MAAI,QAAQ;AACR,QAAI,mBAAmB,MAAM,GAAG;AAE5B,cAAQ,WAAW,IAAI;AAAA,IAC3B,OAAO;AAEH,cAAQ,eAAe,IAAI,UAAU,MAAM;AAAA,IAC/C;AAAA,EACJ;AAEA,MAAI,cAAc;AACd,YAAQ,QAAQ,IAAI,oBAAoB,YAAY;AAAA,EACxD;AAEA,SAAO,iBAA0B;AAAA,IAC7B,OAAO;AAAA,MACH,cAAc;AAAA,QACV,KAAK,GAAG,OAAO;AAAA,QACf;AAAA,MACJ,CAAQ;AAAA,IACZ;AAAA,EACJ,CAAC;AACL;","names":[]}
package/package.json ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "@archlast/client",
3
+ "version": "0.0.1",
4
+ "description": "Archlast client SDK for React and API access",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/algochad/archlast-sync.git"
9
+ },
10
+ "type": "module",
11
+ "main": "./dist/index.cjs",
12
+ "module": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js",
18
+ "require": "./dist/index.cjs"
19
+ },
20
+ "./client": {
21
+ "types": "./dist/client.d.ts",
22
+ "import": "./dist/client.js",
23
+ "require": "./dist/client.cjs"
24
+ },
25
+ "./react": {
26
+ "types": "./dist/react.d.ts",
27
+ "import": "./dist/react.js",
28
+ "require": "./dist/react.cjs"
29
+ },
30
+ "./trpc": {
31
+ "types": "./dist/trpc.d.ts",
32
+ "import": "./dist/trpc.js",
33
+ "require": "./dist/trpc.cjs"
34
+ },
35
+ "./function-reference": {
36
+ "types": "./dist/function-reference.d.ts",
37
+ "import": "./dist/function-reference.js",
38
+ "require": "./dist/function-reference.cjs"
39
+ },
40
+ "./auth": {
41
+ "types": "./dist/auth/index.d.ts",
42
+ "import": "./dist/auth/index.js",
43
+ "require": "./dist/auth/index.cjs"
44
+ },
45
+ "./storage": {
46
+ "types": "./dist/storage/index.d.ts",
47
+ "import": "./dist/storage/index.js",
48
+ "require": "./dist/storage/index.cjs"
49
+ },
50
+ "./admin": {
51
+ "types": "./dist/admin/index.d.ts",
52
+ "import": "./dist/admin/index.js",
53
+ "require": "./dist/admin/index.cjs"
54
+ }
55
+ },
56
+ "files": [
57
+ "dist",
58
+ "README.md",
59
+ "LICENSE"
60
+ ],
61
+ "scripts": {
62
+ "build": "tsup",
63
+ "prepublishOnly": "npm run build",
64
+ "test": "bun test",
65
+ "test:trpc": "bun test tests/trpc.test.ts",
66
+ "format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"",
67
+ "format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,json,md}\"",
68
+ "clean": "rm -rf dist"
69
+ },
70
+ "peerDependencies": {
71
+ "react": "^18.0.0 || ^19.0.0",
72
+ "react-dom": "^18.0.0 || ^19.0.0",
73
+ "@tanstack/react-query": "^5.0.0"
74
+ },
75
+ "optionalDependencies": {
76
+ "@trpc/server": "^11.8.1"
77
+ },
78
+ "devDependencies": {
79
+ "typescript": "^5.0.0",
80
+ "@types/react": "^19",
81
+ "@types/react-dom": "^19",
82
+ "@tanstack/react-query": "^5.62.11",
83
+ "@trpc/server": "^11.8.1",
84
+ "tsup": "^8.5.1"
85
+ },
86
+ "dependencies": {
87
+ "@trpc/client": "^11.8.1",
88
+ "axios": "^1.13.2"
89
+ }
90
+ }